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 ************************************************************************/
31 #define _LINUX_SOURCE_COMPAT
32 #include <sys/timer.h>
33 #undef _LINUX_SOURCE_COMPAT
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>
52 static FILE * s_file
= 0;
53 void TRACE( char const * s
)
59 oslThreadIdentifier t
= osl::Thread::getCurrentIdentifier();
60 fprintf( s_file
, "log [t_id=%" SAL_PRIuUINT32
"]: %s\n", t
, s
);
64 void TRACEN( char const * s
, long n
)
70 oslThreadIdentifier t
= osl::Thread::getCurrentIdentifier();
71 fprintf( s_file
, "log [t_id=%" SAL_PRIuUINT32
"]: %s%ld\n", t
, s
, n
);
75 void TRACES( char const* s
, char const* s2
)
81 oslThreadIdentifier t
= osl::Thread::getCurrentIdentifier();
82 fprintf( s_file
, "log [t_id=%" SAL_PRIuUINT32
"]: %s %s\n", t
, s
, s2
);
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
99 const JRIEnvInterface
** SAL_CALL NP_LOADDS
NPN_GetJavaEnv()
101 TRACE( "NPN_GetJavaEnv" );
102 // no java in this program
106 jref SAL_CALL NP_LOADDS
NPN_GetJavaPeer( NPP
/*instance*/ )
108 TRACE( "NPN_GetJavaPeer" );
113 NPNetscapeFuncs aNPNFuncs
=
115 sizeof( NPNetscapeFuncs
),
116 (NP_VERSION_MAJOR
<< 8) | NP_VERSION_MINOR
,
136 NPN_InvalidateRegion
,
140 static OString
normalizeURL( XPlugin_Impl
* plugin
, const OString
& url
)
143 if( url
.indexOf( ':' ) == -1 )
145 aLoadURL
= OUStringToOString( plugin
->getCreationURL(), plugin
->getTextEncoding() );
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 );
155 aLoadURL
= aLoadURL
.copy( 0, url
.startsWith("/") ? nPos
: nPos
+1 );
159 // same server but new file
160 nPos
= aLoadURL
.lastIndexOf( '/' );
161 aLoadURL
= aLoadURL
.copy( 0, nPos
+1 );
168 else if( url
.indexOf( ":/" ) != -1 )
174 struct AsynchronousGetURL
178 Reference
< XEventListener
> xListener
;
180 DECL_LINK( getURL
, XPlugin_Impl
* );
183 IMPL_LINK( AsynchronousGetURL
, getURL
, XPlugin_Impl
*, pImpl
)
187 pImpl
->enterPluginCallback();
189 pImpl
->getPluginContext()->
195 pImpl
->getPluginContext()->
200 catch(const ::com::sun::star::plugin::PluginException
&)
203 pImpl
->leavePluginCallback();
211 void* SAL_CALL NP_LOADDS
NPN_MemAlloc( uint32_t nBytes
)
213 TRACE( "NPN_MemAlloc" );
214 void* pMem
= malloc( nBytes
);
218 void SAL_CALL NP_LOADDS
NPN_MemFree( void* pMem
)
220 TRACE( "NPN_MemFree" );
224 uint32_t SAL_CALL NP_LOADDS
NPN_MemFlush( uint32_t /*nSize*/ )
226 TRACE( "NPN_MemFlush" );
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
);
235 return NPERR_INVALID_INSTANCE_ERROR
;
237 PluginStream
* pStream
= pImpl
->getStreamFromNPStream( stream
);
240 if( pStream
->getStreamType() == InputStream
)
241 static_cast<PluginInputStream
*>(pStream
)->releaseSelf();
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
);
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
,
270 TRACES( "NPN_GetURLNotify", url
);
271 XPlugin_Impl
* pImpl
= XPluginManager_Impl::getXPluginFromNPP( instance
);
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
);
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
,
300 // stream is a return value
302 TRACE( "NPN_NewStream" );
303 XPlugin_Impl
* pImpl
= XPluginManager_Impl::getXPluginFromNPP( instance
);
305 return NPERR_INVALID_INSTANCE_ERROR
;
307 PluginOutputStream
* pStream
= new PluginOutputStream( pImpl
,
309 *stream
= &pStream
->getStream();
313 pImpl
->enterPluginCallback();
314 pImpl
->getPluginContext()->
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();
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
);
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
);
355 pImpl
->enterPluginCallback();
356 pImpl
->getPluginContext()->
357 postURLNotify( pImpl
,
358 OStringToOUString( aPostURL
, pImpl
->getTextEncoding() ),
359 OStringToOUString( target
, pImpl
->getTextEncoding() ),
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();
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
);
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()->
388 OStringToOUString( aPostURL
, pImpl
->getTextEncoding() ),
389 OStringToOUString( window
, pImpl
->getTextEncoding () ),
392 pImpl
->leavePluginCallback();
394 catch( const ::com::sun::star::plugin::PluginException
& e
)
396 pImpl
->leavePluginCallback();
400 return NPERR_NO_ERROR
;
403 NPError SAL_CALL NP_LOADDS
NPN_RequestRead( NPStream
* stream
, NPByteRange
* rangeList
)
405 TRACE( "NPN_RequestRead" );
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
);
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
;
430 pPlugin
->enterPluginCallback();
433 if( pBytes
&& nBytes
< (int)rangeList
->length
)
436 nBytes
= rangeList
->length
;
437 pBytes
.reset(new sal_Int8
[ nBytes
]);
440 pInputStream
->read( rangeList
->offset
, pBytes
.get(), rangeList
->length
);
445 nNow
= pPlugin
->getPluginComm()->
446 NPP_WriteReady( &pPlugin
->getNPPInstance(),
448 nNow
= pPlugin
->getPluginComm()->
449 NPP_Write( &pPlugin
->getNPPInstance(),
451 rangeList
->offset
+ nPos
,
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
);
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();
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
);
495 pImpl
->enterPluginCallback();
496 UserAgent
= pImpl
->getPluginContext()->
497 getUserAgent( pImpl
);
498 pImpl
->leavePluginCallback();
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
);
514 void SAL_CALL NP_LOADDS
NPN_Version( int* major
, int* minor
, int* net_major
, int* net_minor
)
516 TRACE( "NPN_Version" );
523 int32_t SAL_CALL NP_LOADDS
NPN_Write( NPP instance
, NPStream
* stream
, int32_t len
,
526 TRACE( "NPN_Write" );
527 XPlugin_Impl
* pImpl
= XPluginManager_Impl::getXPluginFromNPP( instance
);
531 PluginStream
* pStream
= pImpl
->getStreamFromNPStream( stream
);
532 if( ! pStream
|| pStream
->getStreamType() != OutputStream
)
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();
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
);
552 NPError
aResult( NPERR_NO_ERROR
);
557 // Unix only, handled in sysdep part
558 case NPNVxtAppContext
:
559 // Unix only, handled in sysdep part
561 aResult
= NPERR_INVALID_PARAM
;
564 case 2000: // NPNVsupportsQuickDrawBool
565 *(NPBool
*)value
= false;
567 case 2001: // NPNVsupportsCoreGraphicsBool
568 *(NPBool
*)value
= true;
571 case NPNVjavascriptEnabledBool
:
573 *static_cast<NPBool
*>(value
) = false;
575 case NPNVasdEnabledBool
:
577 *static_cast<NPBool
*>(value
) = false;
579 case NPNVisOfflineBool
:
580 // no offline browsing
581 *static_cast<NPBool
*>(value
) = false;
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
,
598 NPError nError
= NPERR_NO_ERROR
;
599 TRACEN( "NPN_SetValue ", variable
);
601 NPN_SetValue_Impl(instance
, variable
, value
);
610 void SAL_CALL NP_LOADDS
NPN_InvalidateRect(NPP instance
, NPRect
* /*invalidRect*/)
612 TRACE( "NPN_InvalidateRect" );
615 NPN_ForceRedraw( instance
);
621 void SAL_CALL NP_LOADDS
NPN_InvalidateRegion(NPP instance
, NPRegion
/*invalidRegion*/)
623 TRACE( "NPN_InvalidateRegion" );
626 NPN_ForceRedraw( instance
);
632 void SAL_CALL NP_LOADDS
NPN_ForceRedraw(NPP instance
)
634 TRACE( "NPN_ForceRedraw" );
636 NPN_ForceRedraw_Impl(instance
);
644 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */