bump product version to 5.0.4.1
[LibreOffice.git] / extensions / source / plugin / base / nfuncs.cxx
blobdfeff975ff0713098d669eed9768d40491afff91
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #ifdef AIX
31 #define _LINUX_SOURCE_COMPAT
32 #include <sys/timer.h>
33 #undef _LINUX_SOURCE_COMPAT
34 #endif
36 #ifdef WNT
37 #include <prewin.h>
38 #include <postwin.h>
39 #endif
41 #include <cstdarg>
42 #include <list>
44 #include <plugin/impl.hxx>
45 #include <vcl/svapp.hxx>
46 #include <boost/scoped_array.hpp>
48 #if OSL_DEBUG_LEVEL > 1
49 #include <osl/thread.h>
50 #include <osl/thread.hxx>
51 #include <stdio.h>
52 static FILE * s_file = 0;
53 void TRACE( char const * s )
55 if (! s_file)
56 s_file = stderr;
57 if (s_file)
59 oslThreadIdentifier t = osl::Thread::getCurrentIdentifier();
60 fprintf( s_file, "log [t_id=%" SAL_PRIuUINT32 "]: %s\n", t, s );
61 fflush( s_file );
64 void TRACEN( char const * s, long n )
66 if (! s_file)
67 s_file = stderr;
68 if (s_file)
70 oslThreadIdentifier t = osl::Thread::getCurrentIdentifier();
71 fprintf( s_file, "log [t_id=%" SAL_PRIuUINT32 "]: %s%ld\n", t, s, n );
72 fflush( s_file );
75 void TRACES( char const* s, char const* s2 )
77 if (! s_file)
78 s_file = stderr;
79 if (s_file)
81 oslThreadIdentifier t = osl::Thread::getCurrentIdentifier();
82 fprintf( s_file, "log [t_id=%" SAL_PRIuUINT32 "]: %s %s\n", t, s, s2 );
83 fflush( s_file );
86 #else
87 #define TRACE(x)
88 #define TRACEN(x,n)
89 #define TRACES(x,s)
90 #endif
92 using namespace com::sun::star::lang;
95 // Move deprecated functions which no longer appear in npapi.h before
96 // their use to avoid errors that they're undeclared at point of use
97 extern "C"
99 const JRIEnvInterface** SAL_CALL NP_LOADDS NPN_GetJavaEnv()
101 TRACE( "NPN_GetJavaEnv" );
102 // no java in this program
103 return NULL;
106 jref SAL_CALL NP_LOADDS NPN_GetJavaPeer( NPP /*instance*/ )
108 TRACE( "NPN_GetJavaPeer" );
109 return NULL;
113 NPNetscapeFuncs aNPNFuncs =
115 sizeof( NPNetscapeFuncs ),
116 (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
117 NPN_GetURL,
118 NPN_PostURL,
119 NPN_RequestRead,
120 NPN_NewStream,
121 NPN_Write,
122 NPN_DestroyStream,
123 NPN_Status,
124 NPN_UserAgent,
125 NPN_MemAlloc,
126 NPN_MemFree,
127 NPN_MemFlush,
128 NPN_ReloadPlugins,
129 NPN_GetJavaEnv,
130 NPN_GetJavaPeer,
131 NPN_GetURLNotify,
132 NPN_PostURLNotify,
133 NPN_GetValue,
134 NPN_SetValue,
135 NPN_InvalidateRect,
136 NPN_InvalidateRegion,
137 NPN_ForceRedraw
140 static OString normalizeURL( XPlugin_Impl* plugin, const OString& url )
142 OString aLoadURL;
143 if( url.indexOf( ':' ) == -1 )
145 aLoadURL = OUStringToOString( plugin->getCreationURL(), plugin->getTextEncoding() );
146 int nPos;
147 if( ( nPos = aLoadURL.indexOf( "://" ) ) != -1 )
149 if( url.indexOf( '/' ) != -1 )
151 // this means same server but new path
152 nPos = aLoadURL.indexOf( '/', nPos+3 );
154 if( nPos != -1 )
155 aLoadURL = aLoadURL.copy( 0, url.startsWith("/") ? nPos : nPos+1 );
157 else
159 // same server but new file
160 nPos = aLoadURL.lastIndexOf( '/' );
161 aLoadURL = aLoadURL.copy( 0, nPos+1 );
163 aLoadURL += url;
165 else
166 aLoadURL = url;
168 else if( url.indexOf( ":/" ) != -1 )
169 aLoadURL = url;
171 return aLoadURL;
174 struct AsynchronousGetURL
176 OUString aUrl;
177 OUString aTarget;
178 Reference< XEventListener > xListener;
180 DECL_LINK( getURL, XPlugin_Impl* );
183 IMPL_LINK( AsynchronousGetURL, getURL, XPlugin_Impl*, pImpl )
187 pImpl->enterPluginCallback();
188 if( xListener.is() )
189 pImpl->getPluginContext()->
190 getURLNotify( pImpl,
191 aUrl,
192 aTarget,
193 xListener );
194 else
195 pImpl->getPluginContext()->
196 getURL( pImpl,
197 aUrl,
198 aTarget );
200 catch(const ::com::sun::star::plugin::PluginException&)
203 pImpl->leavePluginCallback();
204 delete this;
205 return 0;
209 extern "C" {
211 void* SAL_CALL NP_LOADDS NPN_MemAlloc( uint32_t nBytes )
213 TRACE( "NPN_MemAlloc" );
214 void* pMem = malloc( nBytes );
215 return pMem;
218 void SAL_CALL NP_LOADDS NPN_MemFree( void* pMem )
220 TRACE( "NPN_MemFree" );
221 free( pMem );
224 uint32_t SAL_CALL NP_LOADDS NPN_MemFlush( uint32_t /*nSize*/ )
226 TRACE( "NPN_MemFlush" );
227 return 0;
230 NPError SAL_CALL NP_LOADDS NPN_DestroyStream( NPP instance, NPStream* stream, NPError /*reason*/ )
232 TRACE( "NPN_DestroyStream" );
233 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
234 if( ! pImpl )
235 return NPERR_INVALID_INSTANCE_ERROR;
237 PluginStream* pStream = pImpl->getStreamFromNPStream( stream );
238 if( pStream )
240 if( pStream->getStreamType() == InputStream )
241 static_cast<PluginInputStream*>(pStream)->releaseSelf();
242 else
243 delete pStream;
246 return NPERR_NO_ERROR;
249 NPError SAL_CALL NP_LOADDS NPN_GetURL( NPP instance, const char* url, const char* window )
251 TRACES( "NPN_GetURL", url );
252 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
253 if( ! pImpl )
254 return NPERR_INVALID_INSTANCE_ERROR;
256 AsynchronousGetURL* pAsync = new AsynchronousGetURL();
258 OString aLoadURL = normalizeURL( pImpl, url );
259 TRACES( "NPN_GetURL", aLoadURL.getStr() );
260 pAsync->aUrl = OStringToOUString( aLoadURL, pImpl->getTextEncoding() );
261 pAsync->aTarget = OStringToOUString( window, pImpl->getTextEncoding() );
262 pImpl->setLastGetUrl( aLoadURL );
263 Application::PostUserEvent( LINK( pAsync, AsynchronousGetURL, getURL ), pImpl );
264 return NPERR_NO_ERROR;
267 NPError SAL_CALL NP_LOADDS NPN_GetURLNotify( NPP instance, const char* url, const char* target,
268 void* notifyData )
270 TRACES( "NPN_GetURLNotify", url );
271 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
272 if( ! pImpl )
273 return NPERR_INVALID_INSTANCE_ERROR;
275 OString aLoadURL = normalizeURL( pImpl, url );
276 if( aLoadURL.isEmpty() )
277 return NPERR_INVALID_URL;
279 AsynchronousGetURL* pAsync = new AsynchronousGetURL();
280 PluginEventListener* pListener =
281 new PluginEventListener( pImpl, url, aLoadURL.getStr(), notifyData );
282 if( ! target || ! *target )
284 // stream will be fed back to plugin,
285 // notify immediately after destruction of stream
286 pImpl->addPluginEventListener( pListener );
287 pListener = NULL;
289 pAsync->aUrl = OStringToOUString( aLoadURL, pImpl->getTextEncoding() );
290 pAsync->aTarget = OStringToOUString( target, pImpl->getTextEncoding() );
291 pAsync->xListener = pListener;
292 pImpl->setLastGetUrl( aLoadURL );
293 Application::PostUserEvent( LINK( pAsync, AsynchronousGetURL, getURL ), pImpl );
295 return NPERR_NO_ERROR;
298 NPError SAL_CALL NP_LOADDS NPN_NewStream( NPP instance, NPMIMEType type, const char* target,
299 NPStream** stream )
300 // stream is a return value
302 TRACE( "NPN_NewStream" );
303 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
304 if( ! pImpl )
305 return NPERR_INVALID_INSTANCE_ERROR;
307 PluginOutputStream* pStream = new PluginOutputStream( pImpl,
308 "", 0, 0 );
309 *stream = &pStream->getStream();
313 pImpl->enterPluginCallback();
314 pImpl->getPluginContext()->
315 newStream(
316 pImpl,
317 OStringToOUString( type, pImpl->getTextEncoding () ),
318 OStringToOUString( target, pImpl->getTextEncoding() ),
319 ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > ( pStream->getOutputStream(), UNO_QUERY )
321 pImpl->leavePluginCallback();
323 catch( const ::com::sun::star::plugin::PluginException& e )
325 pImpl->leavePluginCallback();
326 return e.ErrorCode;
329 return NPERR_NO_ERROR;
332 NPError SAL_CALL NP_LOADDS NPN_PostURLNotify( NPP instance, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData )
334 TRACE( "NPN_PostURLNotify" );
335 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
336 if( ! pImpl )
337 return NPERR_INVALID_INSTANCE_ERROR;
339 ::com::sun::star::uno::Sequence<sal_Int8> Bytes( reinterpret_cast<sal_Int8 const *>(buf), len );
341 OString aPostURL = normalizeURL( pImpl, url );
342 PluginEventListener* pListener =
343 new PluginEventListener( pImpl, url, aPostURL.getStr(), notifyData );
345 if( ! target || ! *target )
347 // stream will be fed back to plugin,
348 // notify immediately after destruction of stream
349 pImpl->addPluginEventListener( pListener );
350 pListener = NULL;
355 pImpl->enterPluginCallback();
356 pImpl->getPluginContext()->
357 postURLNotify( pImpl,
358 OStringToOUString( aPostURL, pImpl->getTextEncoding() ),
359 OStringToOUString( target, pImpl->getTextEncoding() ),
360 Bytes,
361 file,
362 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > ( pListener ) );
363 pImpl->leavePluginCallback();
365 catch( const ::com::sun::star::plugin::PluginException& e )
367 pImpl->leavePluginCallback();
368 return e.ErrorCode;
371 return NPERR_NO_ERROR;
374 NPError SAL_CALL NP_LOADDS NPN_PostURL( NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file )
376 TRACE( "NPN_PostURL" );
377 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
378 if( ! pImpl )
379 return NPERR_INVALID_INSTANCE_ERROR;
381 ::com::sun::star::uno::Sequence<sal_Int8> Bytes( reinterpret_cast<sal_Int8 const *>(buf), len );
382 OString aPostURL = normalizeURL( pImpl, url );
385 pImpl->enterPluginCallback();
386 pImpl->getPluginContext()->
387 postURL( pImpl,
388 OStringToOUString( aPostURL, pImpl->getTextEncoding() ),
389 OStringToOUString( window, pImpl->getTextEncoding () ),
390 Bytes,
391 file );
392 pImpl->leavePluginCallback();
394 catch( const ::com::sun::star::plugin::PluginException& e )
396 pImpl->leavePluginCallback();
397 return e.ErrorCode;
400 return NPERR_NO_ERROR;
403 NPError SAL_CALL NP_LOADDS NPN_RequestRead( NPStream* stream, NPByteRange* rangeList )
405 TRACE( "NPN_RequestRead" );
406 if( ! rangeList )
407 return NPERR_NO_ERROR;
409 ::std::list<XPlugin_Impl*>& rList = PluginManager::get().getPlugins();
410 ::std::list<XPlugin_Impl*>::iterator iter;
411 XPlugin_Impl* pPlugin = NULL;
412 PluginStream* pStream = NULL;
413 for( iter = rList.begin(); iter!= rList.end(); ++iter )
415 pStream = (*iter)->getStreamFromNPStream( stream );
416 if( pStream )
418 pPlugin = *iter;
419 break;
422 if( ! pPlugin )
423 return NPERR_INVALID_INSTANCE_ERROR;
424 if( ! pStream || pStream->getStreamType() != InputStream )
425 return NPERR_FILE_NOT_FOUND;
427 PluginInputStream* pInputStream = static_cast<PluginInputStream*>(pStream);
428 boost::scoped_array<sal_Int8> pBytes;
429 int nBytes = 0;
430 pPlugin->enterPluginCallback();
431 while( rangeList )
433 if( pBytes && nBytes < (int)rangeList->length )
434 pBytes.reset();
435 if( ! pBytes ) {
436 nBytes = rangeList->length;
437 pBytes.reset(new sal_Int8[ nBytes ]);
439 int nRead =
440 pInputStream->read( rangeList->offset, pBytes.get(), rangeList->length );
441 int nPos = 0;
442 int nNow;
445 nNow = pPlugin->getPluginComm()->
446 NPP_WriteReady( &pPlugin->getNPPInstance(),
447 stream );
448 nNow = pPlugin->getPluginComm()->
449 NPP_Write( &pPlugin->getNPPInstance(),
450 stream,
451 rangeList->offset + nPos,
452 nNow,
453 pBytes.get()+nPos );
454 nPos += nNow;
455 nRead -= nNow;
456 } while( nRead > 0 && nNow );
457 rangeList = rangeList->next;
459 pPlugin->leavePluginCallback();
461 return NPERR_NO_ERROR;
464 void SAL_CALL NP_LOADDS NPN_Status( NPP instance, const char* message )
466 TRACE( "NPN_Status" );
467 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
468 if( ! pImpl )
469 return;
473 pImpl->enterPluginCallback();
474 pImpl->getPluginContext()->
475 displayStatusText( pImpl, OStringToOUString( message, pImpl->getTextEncoding() ) );
476 pImpl->leavePluginCallback();
478 catch( const ::com::sun::star::plugin::PluginException& )
480 pImpl->leavePluginCallback();
481 return;
485 const char* SAL_CALL NP_LOADDS NPN_UserAgent( NPP instance )
487 static char* pAgent = strdup( "Mozilla 3.0" );
489 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
490 if( pImpl )
492 OUString UserAgent;
495 pImpl->enterPluginCallback();
496 UserAgent = pImpl->getPluginContext()->
497 getUserAgent( pImpl );
498 pImpl->leavePluginCallback();
499 if( pAgent )
500 free( pAgent );
501 pAgent = strdup( OUStringToOString( UserAgent, pImpl->getTextEncoding() ).getStr() );
503 catch( const ::com::sun::star::plugin::PluginException& )
505 pImpl->leavePluginCallback();
509 TRACES( "NPN_UserAgent: returning", pAgent );
511 return pAgent;
514 void SAL_CALL NP_LOADDS NPN_Version( int* major, int* minor, int* net_major, int* net_minor )
516 TRACE( "NPN_Version" );
517 *major = 4;
518 *minor = 0;
519 *net_major = 4;
520 *net_minor = 5;
523 int32_t SAL_CALL NP_LOADDS NPN_Write( NPP instance, NPStream* stream, int32_t len,
524 void* buffer )
526 TRACE( "NPN_Write" );
527 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
528 if( ! pImpl )
529 return 0;
531 PluginStream* pStream = pImpl->getStreamFromNPStream( stream );
532 if( ! pStream || pStream->getStreamType() != OutputStream )
533 return 0;
535 pImpl->enterPluginCallback();
536 ::com::sun::star::uno::Sequence<sal_Int8> Bytes( static_cast<sal_Int8*>(buffer), len );
537 static_cast<PluginOutputStream*>(pStream)->getOutputStream()->writeBytes( Bytes );
538 pImpl->leavePluginCallback();
540 return len;
544 NPError SAL_CALL NP_LOADDS NPN_GetValue( NPP instance, NPNVariable variable, void* value )
546 TRACEN( "NPN_GetValue: ", variable );
547 XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
549 if( ! pImpl )
550 return 0;
552 NPError aResult( NPERR_NO_ERROR );
554 switch( variable )
556 case NPNVxDisplay:
557 // Unix only, handled in sysdep part
558 case NPNVxtAppContext:
559 // Unix only, handled in sysdep part
560 default:
561 aResult = NPERR_INVALID_PARAM;
562 break;
563 #ifdef MACOSX
564 case 2000: // NPNVsupportsQuickDrawBool
565 *(NPBool*)value = false;
566 break;
567 case 2001: // NPNVsupportsCoreGraphicsBool
568 *(NPBool*)value = true;
569 break;
570 #endif
571 case NPNVjavascriptEnabledBool:
572 // no javascript
573 *static_cast<NPBool*>(value) = false;
574 break;
575 case NPNVasdEnabledBool:
576 // no SmartUpdate
577 *static_cast<NPBool*>(value) = false;
578 break;
579 case NPNVisOfflineBool:
580 // no offline browsing
581 *static_cast<NPBool*>(value) = false;
582 break;
585 return aResult;
588 void SAL_CALL NP_LOADDS NPN_ReloadPlugins(NPBool /*reloadPages*/)
590 TRACE( "NPN_ReloadPlugins" );
594 NPError SAL_CALL NP_LOADDS NPN_SetValue( NPP instance,
595 NPPVariable variable,
596 void* value )
598 NPError nError = NPERR_NO_ERROR;
599 TRACEN( "NPN_SetValue ", variable );
600 #ifdef MACOSX
601 NPN_SetValue_Impl(instance, variable, value);
602 #else
603 (void)instance;
604 (void)variable;
605 (void)value;
606 #endif
607 return nError;
610 void SAL_CALL NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect* /*invalidRect*/)
612 TRACE( "NPN_InvalidateRect" );
614 #ifdef MACOSX
615 NPN_ForceRedraw( instance );
616 #else
617 (void)instance;
618 #endif
621 void SAL_CALL NP_LOADDS NPN_InvalidateRegion(NPP instance, NPRegion /*invalidRegion*/)
623 TRACE( "NPN_InvalidateRegion" );
625 #ifdef MACOSX
626 NPN_ForceRedraw( instance );
627 #else
628 (void)instance;
629 #endif
632 void SAL_CALL NP_LOADDS NPN_ForceRedraw(NPP instance)
634 TRACE( "NPN_ForceRedraw" );
635 #ifdef MACOSX
636 NPN_ForceRedraw_Impl(instance);
637 #else
638 (void)instance;
639 #endif
644 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */