Update ooo320-m1
[ooovba.git] / extensions / source / plugin / base / nfuncs.cxx
bloba8c194b19cf0ea529acd2ac7c0ca2c42a68b6c69
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: nfuncs.cxx,v $
10 * $Revision: 1.17 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 #if STLPORT_VERSION>=321
35 #include <cstdarg>
36 #endif
38 #include <list>
40 #include <plugin/impl.hxx>
41 #include <vcl/svapp.hxx>
43 #if OSL_DEBUG_LEVEL > 1
44 #include <osl/thread.h>
45 #include <stdio.h>
46 static FILE * s_file = 0;
47 void TRACE( char const * s )
49 if (! s_file)
50 s_file = stderr;
51 if (s_file)
53 oslThreadIdentifier t = osl_getThreadIdentifier(0);
54 fprintf( s_file, "log [t_id=%"SAL_PRIuUINT32"]: %s\n", t, s );
55 fflush( s_file );
58 void TRACEN( char const * s, long n )
60 if (! s_file)
61 s_file = stderr;
62 if (s_file)
64 oslThreadIdentifier t = osl_getThreadIdentifier(0);
65 fprintf( s_file, "log [t_id=%"SAL_PRIuUINT32"]: %s%ld\n", t, s, n );
66 fflush( s_file );
69 void TRACES( char const* s, char const* s2 )
71 if (! s_file)
72 s_file = stderr;
73 if (s_file)
75 oslThreadIdentifier t = osl_getThreadIdentifier(0);
76 fprintf( s_file, "log [t_id=%"SAL_PRIuUINT32"]: %s %s\n", t, s, s2 );
77 fflush( s_file );
80 #else
81 #define TRACE(x)
82 #define TRACEN(x,n)
83 #define TRACES(x,s)
84 #endif
86 using namespace rtl;
87 using namespace com::sun::star::lang;
89 NPNetscapeFuncs aNPNFuncs =
91 sizeof( NPNetscapeFuncs ),
92 (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
93 NPN_GetURL,
94 NPN_PostURL,
95 NPN_RequestRead,
96 NPN_NewStream,
97 NPN_Write,
98 NPN_DestroyStream,
99 NPN_Status,
100 NPN_UserAgent,
101 NPN_MemAlloc,
102 NPN_MemFree,
103 NPN_MemFlush,
104 NPN_ReloadPlugins,
105 NPN_GetJavaEnv,
106 NPN_GetJavaPeer,
107 NPN_GetURLNotify,
108 NPN_PostURLNotify,
109 NPN_GetValue,
110 NPN_SetValue,
111 NPN_InvalidateRect,
112 NPN_InvalidateRegion,
113 NPN_ForceRedraw
116 static ::rtl::OString normalizeURL( XPlugin_Impl* plugin, const ::rtl::OString& url )
118 ::rtl::OString aLoadURL;
119 if( url.indexOf( ":" ) == -1 )
121 aLoadURL = ::rtl::OUStringToOString( plugin->getCreationURL(), plugin->getTextEncoding() );
122 int nPos;
123 if( ( nPos = aLoadURL.indexOf( "://" ) ) != -1 )
125 if( url.getLength() && (url.getStr()[ 0 ] == '/' || url.indexOf( '/' ) != -1) )
127 // this means same server but new path
128 nPos = aLoadURL.indexOf( '/', nPos+3 );
130 if( nPos != -1 )
131 aLoadURL = aLoadURL.copy( 0, url.getStr()[0] == '/' ? nPos : nPos+1 );
133 else
135 // same server but new file
136 nPos = aLoadURL.lastIndexOf( '/' );
137 aLoadURL = aLoadURL.copy( 0, nPos+1 );
139 aLoadURL += url;
141 else
142 aLoadURL = url;
144 else if( url.indexOf( ":/" ) != -1 )
145 aLoadURL = url;
147 return aLoadURL;
150 struct AsynchronousGetURL
152 OUString aUrl;
153 OUString aTarget;
154 Reference< XEventListener > xListener;
156 DECL_LINK( getURL, XPlugin_Impl* );
159 IMPL_LINK( AsynchronousGetURL, getURL, XPlugin_Impl*, pImpl )
163 pImpl->enterPluginCallback();
164 if( xListener.is() )
165 pImpl->getPluginContext()->
166 getURLNotify( pImpl,
167 aUrl,
168 aTarget,
169 xListener );
170 else
171 pImpl->getPluginContext()->
172 getURL( pImpl,
173 aUrl,
174 aTarget );
176 catch( ::com::sun::star::plugin::PluginException& e )
178 (void)e;
180 pImpl->leavePluginCallback();
181 delete this;
182 return 0;
186 extern "C" {
188 void* SAL_CALL NP_LOADDS NPN_MemAlloc( uint32 nBytes )
190 TRACE( "NPN_MemAlloc" );
191 void* pMem = malloc( nBytes );
192 return pMem;
195 void SAL_CALL NP_LOADDS NPN_MemFree( void* pMem )
197 TRACE( "NPN_MemFree" );
198 free( pMem );
201 uint32 SAL_CALL NP_LOADDS NPN_MemFlush( uint32 /*nSize*/ )
203 TRACE( "NPN_MemFlush" );
204 return 0;
207 NPError SAL_CALL NP_LOADDS NPN_DestroyStream( NPP instance, NPStream* stream, NPError /*reason*/ )
209 TRACE( "NPN_DestroyStream" );
210 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
211 if( ! pImpl )
212 return NPERR_INVALID_INSTANCE_ERROR;
214 PluginStream* pStream = pImpl->getStreamFromNPStream( stream );
215 if( pStream )
217 if( pStream->getStreamType() == InputStream )
218 static_cast<PluginInputStream*>(pStream)->releaseSelf();
219 else
220 delete pStream;
223 return NPERR_NO_ERROR;
226 #ifdef OJI
227 const JRIEnvInterface** SAL_CALL NP_LOADDS NPN_GetJavaEnv()
229 TRACE( "NPN_GetJavaEnv" );
230 // no java in this program
231 return NULL;
234 jref SAL_CALL NP_LOADDS NPN_GetJavaPeer( NPP /*instance*/ )
236 TRACE( "NPN_GetJavaPeer" );
237 return NULL;
239 #endif
241 NPError SAL_CALL NP_LOADDS NPN_GetURL( NPP instance, const char* url, const char* window )
243 TRACES( "NPN_GetURL", url );
244 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
245 if( ! pImpl )
246 return NPERR_INVALID_INSTANCE_ERROR;
248 AsynchronousGetURL* pAsync = new AsynchronousGetURL();
250 OString aLoadURL = normalizeURL( pImpl, url );
251 TRACES( "NPN_GetURL", aLoadURL.getStr() );
252 pAsync->aUrl = OStringToOUString( aLoadURL, pImpl->getTextEncoding() );
253 pAsync->aTarget = OStringToOUString( window, pImpl->getTextEncoding() );
254 pImpl->setLastGetUrl( aLoadURL );
255 Application::PostUserEvent( LINK( pAsync, AsynchronousGetURL, getURL ), pImpl );
256 return NPERR_NO_ERROR;
259 NPError SAL_CALL NP_LOADDS NPN_GetURLNotify( NPP instance, const char* url, const char* target,
260 void* notifyData )
262 TRACES( "NPN_GetURLNotify", url );
263 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
264 if( ! pImpl )
265 return NPERR_INVALID_INSTANCE_ERROR;
267 OString aLoadURL = normalizeURL( pImpl, url );
268 if( !aLoadURL.getLength() )
269 return NPERR_INVALID_URL;
271 AsynchronousGetURL* pAsync = new AsynchronousGetURL();
272 PluginEventListener* pListener =
273 new PluginEventListener( pImpl, url, aLoadURL.getStr(), notifyData );
274 if( ! target || ! *target )
276 // stream will be fed back to plugin,
277 // notify immediately after destruction of stream
278 pImpl->addPluginEventListener( pListener );
279 pListener = NULL;
281 pAsync->aUrl = OStringToOUString( aLoadURL, pImpl->getTextEncoding() );
282 pAsync->aTarget = OStringToOUString( target, pImpl->getTextEncoding() );
283 pAsync->xListener = pListener;
284 pImpl->setLastGetUrl( aLoadURL );
285 Application::PostUserEvent( LINK( pAsync, AsynchronousGetURL, getURL ), pImpl );
287 return NPERR_NO_ERROR;
290 NPError SAL_CALL NP_LOADDS NPN_NewStream( NPP instance, NPMIMEType type, const char* target,
291 NPStream** stream )
292 // stream is a return value
294 TRACE( "NPN_NewStream" );
295 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
296 if( ! pImpl )
297 return NPERR_INVALID_INSTANCE_ERROR;
299 PluginOutputStream* pStream = new PluginOutputStream( pImpl,
300 "", 0, 0 );
301 *stream = pStream->getStream();
305 pImpl->enterPluginCallback();
306 pImpl->getPluginContext()->
307 newStream(
308 pImpl,
309 ::rtl::OStringToOUString( type, pImpl->getTextEncoding () ),
310 ::rtl::OStringToOUString( target, pImpl->getTextEncoding() ),
311 ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > ( pStream->getOutputStream(), UNO_QUERY )
313 pImpl->leavePluginCallback();
315 catch( ::com::sun::star::plugin::PluginException& e )
317 pImpl->leavePluginCallback();
318 return e.ErrorCode;
321 return NPERR_NO_ERROR;
324 NPError SAL_CALL NP_LOADDS NPN_PostURLNotify( NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file, void* notifyData )
326 TRACE( "NPN_PostURLNotify" );
327 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
328 if( ! pImpl )
329 return NPERR_INVALID_INSTANCE_ERROR;
331 ::com::sun::star::uno::Sequence<sal_Int8> Bytes( (sal_Int8*)buf, len );
333 ::rtl::OString aPostURL = normalizeURL( pImpl, url );
334 PluginEventListener* pListener =
335 new PluginEventListener( pImpl, url, aPostURL.getStr(), notifyData );
337 if( ! target || ! *target )
339 // stream will be fed back to plugin,
340 // notify immediately after destruction of stream
341 pImpl->addPluginEventListener( pListener );
342 pListener = NULL;
347 pImpl->enterPluginCallback();
348 pImpl->getPluginContext()->
349 postURLNotify( pImpl,
350 ::rtl::OStringToOUString( aPostURL, pImpl->getTextEncoding() ),
351 ::rtl::OStringToOUString( target, pImpl->getTextEncoding() ),
352 Bytes,
353 file,
354 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > ( pListener ) );
355 pImpl->leavePluginCallback();
357 catch( ::com::sun::star::plugin::PluginException& e )
359 pImpl->leavePluginCallback();
360 return e.ErrorCode;
363 return NPERR_NO_ERROR;
366 NPError SAL_CALL NP_LOADDS NPN_PostURL( NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file )
368 TRACE( "NPN_PostURL" );
369 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
370 if( ! pImpl )
371 return NPERR_INVALID_INSTANCE_ERROR;
373 ::com::sun::star::uno::Sequence<sal_Int8> Bytes( (sal_Int8*)buf, len );
374 ::rtl::OString aPostURL = normalizeURL( pImpl, url );
377 pImpl->enterPluginCallback();
378 pImpl->getPluginContext()->
379 postURL( pImpl,
380 ::rtl::OStringToOUString( aPostURL, pImpl->getTextEncoding() ),
381 ::rtl::OStringToOUString( window, pImpl->getTextEncoding () ),
382 Bytes,
383 file );
384 pImpl->leavePluginCallback();
386 catch( ::com::sun::star::plugin::PluginException& e )
388 pImpl->leavePluginCallback();
389 return e.ErrorCode;
392 return NPERR_NO_ERROR;
395 NPError SAL_CALL NP_LOADDS NPN_RequestRead( NPStream* stream, NPByteRange* rangeList )
397 TRACE( "NPN_RequestRead" );
398 if( ! rangeList )
399 return NPERR_NO_ERROR;
401 ::std::list<XPlugin_Impl*>& rList = PluginManager::get().getPlugins();
402 ::std::list<XPlugin_Impl*>::iterator iter;
403 XPlugin_Impl* pPlugin = NULL;
404 PluginStream* pStream = NULL;
405 for( iter = rList.begin(); iter!= rList.end(); ++iter )
407 pStream = (*iter)->getStreamFromNPStream( stream );
408 if( pStream )
410 pPlugin = *iter;
411 break;
414 if( ! pPlugin )
415 return NPERR_INVALID_INSTANCE_ERROR;
416 if( ! pStream || pStream->getStreamType() != InputStream )
417 return NPERR_FILE_NOT_FOUND;
419 PluginInputStream* pInputStream = (PluginInputStream*)pStream;
420 sal_Int8* pBytes = NULL;
421 int nBytes = 0;
422 pPlugin->enterPluginCallback();
423 while( rangeList )
425 if( pBytes && nBytes < (int)rangeList->length )
427 delete [] pBytes;
428 pBytes = NULL;
430 if( ! pBytes )
431 pBytes = new sal_Int8[ nBytes = rangeList->length ];
432 int nRead =
433 pInputStream->read( rangeList->offset, pBytes, rangeList->length );
434 int nPos = 0;
435 int nNow;
438 nNow = pPlugin->getPluginComm()->
439 NPP_WriteReady( pPlugin->getNPPInstance(),
440 stream );
441 nNow = pPlugin->getPluginComm()->
442 NPP_Write( pPlugin->getNPPInstance(),
443 stream,
444 rangeList->offset + nPos,
445 nNow,
446 pBytes+nPos );
447 nPos += nNow;
448 nRead -= nNow;
449 } while( nRead > 0 && nNow );
450 rangeList = rangeList->next;
452 pPlugin->leavePluginCallback();
454 return NPERR_NO_ERROR;
457 void SAL_CALL NP_LOADDS NPN_Status( NPP instance, const char* message )
459 TRACE( "NPN_Status" );
460 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
461 if( ! pImpl )
462 return;
466 pImpl->enterPluginCallback();
467 pImpl->getPluginContext()->
468 displayStatusText( pImpl, ::rtl::OStringToOUString( message, pImpl->getTextEncoding() ) );
469 pImpl->leavePluginCallback();
471 catch( ::com::sun::star::plugin::PluginException& )
473 pImpl->leavePluginCallback();
474 return;
478 const char* SAL_CALL NP_LOADDS NPN_UserAgent( NPP instance )
480 static char* pAgent = strdup( "Mozilla 3.0" );
482 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
483 if( pImpl )
485 rtl::OUString UserAgent;
488 pImpl->enterPluginCallback();
489 UserAgent = pImpl->getPluginContext()->
490 getUserAgent( pImpl );
491 pImpl->leavePluginCallback();
492 if( pAgent )
493 free( pAgent );
494 pAgent = strdup( ::rtl::OUStringToOString( UserAgent, pImpl->getTextEncoding() ).getStr() );
496 catch( ::com::sun::star::plugin::PluginException& )
498 pImpl->leavePluginCallback();
502 TRACES( "NPN_UserAgent: returning", pAgent );
504 return pAgent;
507 void SAL_CALL NP_LOADDS NPN_Version( int* major, int* minor, int* net_major, int* net_minor )
509 TRACE( "NPN_Version" );
510 *major = 4;
511 *minor = 0;
512 *net_major = 4;
513 *net_minor = 5;
516 int32 SAL_CALL NP_LOADDS NPN_Write( NPP instance, NPStream* stream, int32 len,
517 void* buffer )
519 TRACE( "NPN_Write" );
520 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
521 if( ! pImpl )
522 return 0;
524 PluginStream* pStream = pImpl->getStreamFromNPStream( stream );
525 if( ! pStream || pStream->getStreamType() != OutputStream )
526 return 0;
528 pImpl->enterPluginCallback();
529 ::com::sun::star::uno::Sequence<sal_Int8> Bytes( (sal_Int8*)buffer, len );
530 ((PluginOutputStream*)pStream)->getOutputStream()->writeBytes( Bytes );
531 pImpl->leavePluginCallback();
533 return len;
537 NPError SAL_CALL NP_LOADDS NPN_GetValue( NPP instance, NPNVariable variable, void* value )
539 TRACEN( "NPN_GetValue: ", variable );
540 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
542 if( ! pImpl )
543 return 0;
545 NPError aResult( NPERR_NO_ERROR );
547 switch( variable )
549 case NPNVxDisplay:
550 // Unix only, handled in sysdep part
551 case NPNVxtAppContext:
552 // Unix only, handled in sysdep part
553 default:
554 aResult = NPERR_INVALID_PARAM;
555 break;
556 #ifdef QUARTZ
557 case 2000: // NPNVsupportsQuickDrawBool
558 *(NPBool*)value = false;
559 break;
560 case 2001: // NPNVsupportsCoreGraphicsBool
561 *(NPBool*)value = true;
562 break;
563 #endif
564 case NPNVjavascriptEnabledBool:
565 // no javascript
566 *(NPBool*)value = false;
567 break;
568 case NPNVasdEnabledBool:
569 // no SmartUpdate
570 *(NPBool*)value = false;
571 break;
572 case NPNVisOfflineBool:
573 // no offline browsing
574 *(NPBool*)value = false;
575 break;
578 provisional code should there ever be NPNVariables that we actually
579 want to query from the PluginContext
580 ::rtl::OUString aValue;
583 pImpl->enterPluginCallback();
584 aValue = pImpl->getPluginContext()->
585 getValue( pImpl, (::com::sun::star::plugin::PluginVariable)variable );
586 pImpl->leavePluginCallback();
588 catch( ::com::sun::star::plugin::PluginException& e )
590 pImpl->leavePluginCallback();
591 return e.ErrorCode;
595 return aResult;
598 void SAL_CALL NP_LOADDS NPN_ReloadPlugins(NPBool /*reloadPages*/)
600 TRACE( "NPN_ReloadPlugins" );
604 NPError SAL_CALL NP_LOADDS NPN_SetValue( NPP instance,
605 NPPVariable variable,
606 void* value )
608 NPError nError = NPERR_NO_ERROR;
609 TRACEN( "NPN_SetValue ", variable );
610 switch( variable )
612 #ifdef QUARTZ
613 case (NPPVariable)1000: // NPNVpluginDrawingModel
615 int nDrawingModel = (int)value; // ugly, but that's the way we need to do it
617 TRACEN( "drawing model: ", nDrawingModel );
619 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
620 if( pImpl )
621 pImpl->getSysPlugData().m_nDrawingModel = nDrawingModel;
623 break;
624 #endif
625 case NPPVpluginNameString: // make the windows compiler happy, it needs at least one case statement
626 break;
627 default:
628 break;
630 #ifndef QUARTZ
631 (void)instance;
632 (void)value;
633 #endif
634 return nError;
637 void SAL_CALL NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect* /*invalidRect*/)
639 TRACE( "NPN_InvalidateRect" );
641 #ifdef QUARTZ
642 NPN_ForceRedraw( instance );
643 #else
644 (void)instance;
645 #endif
648 void SAL_CALL NP_LOADDS NPN_InvalidateRegion(NPP instance, NPRegion /*invalidRegion*/)
650 TRACE( "NPN_InvalidateRegion" );
652 #ifdef QUARTZ
653 NPN_ForceRedraw( instance );
654 #else
655 (void)instance;
656 #endif
659 void SAL_CALL NP_LOADDS NPN_ForceRedraw(NPP instance)
661 TRACE( "NPN_ForceRedraw" );
662 #ifdef QUARTZ
663 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
664 if( pImpl )
666 SysPlugData& rPlugData( pImpl->getSysPlugData() );
667 if( rPlugData.m_pPlugView )
668 [rPlugData.m_pPlugView setNeedsDisplay: YES];
670 #else
671 (void)instance;
672 #endif