Update ooo320-m1
[ooovba.git] / extensions / source / plugin / unx / npnapi.cxx
blob4ba43dd61e4c5ca8ab234fe079e34fe081e3f828
1 /*************************************************************************
3 Source Code Control System - Header
5 $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/extensions/source/plugin/unx/npnapi.cxx,v 1.11 2008-01-14 14:53:25 ihi Exp $
7 *************************************************************************/
9 // MARKER(update_precomp.py): autogen include statement, do not remove
10 #include "precompiled_extensions.hxx"
11 #include <plugin/unx/plugcon.hxx>
13 #include <unistd.h>
14 #include <dlfcn.h>
16 #include <osl/module.h>
18 extern PluginConnector* pConnector;
19 extern XtAppContext app_context;
20 extern int wakeup_fd[];
21 extern Widget topLevel, topBox;
22 extern Display* pAppDisplay;
23 extern Display* pXtAppDisplay;
24 extern int nAppArguments;
25 extern char** pAppArguments;
27 void* CreateNewShell( void**, XLIB_Window );
29 // begin Netscape plugin api calls
30 extern "C" {
32 static void* l_NPN_MemAlloc( uint32 nBytes )
34 void* pMem = new char[nBytes];
35 return pMem;
38 static void l_NPN_MemFree( void* pMem )
40 delete [] (char*)pMem;
43 static uint32 l_NPN_MemFlush( uint32 /*nSize*/ )
45 return 0;
48 static NPError l_NPN_DestroyStream( NPP instance, NPStream* stream, NPError reason )
50 UINT32 nInstance = pConnector->GetNPPID( instance );
51 if( nInstance == PluginConnector::UnknownNPPID )
52 return NPERR_GENERIC_ERROR;
54 UINT32 nFileID = pConnector->GetStreamID( stream );
55 MediatorMessage* pMes=
56 pConnector->
57 Transact( eNPN_DestroyStream,
58 &nInstance, sizeof( nInstance ),
59 &nFileID, sizeof( nFileID ),
60 POST_STRING( stream->url ),
61 &reason, sizeof( reason ),
62 NULL );
64 if( ! pMes )
65 return NPERR_GENERIC_ERROR;
67 for( std::vector< NPStream* >::iterator it = pConnector->getStreamList().begin();
68 it != pConnector->getStreamList().end(); ++it )
70 if( *it == stream )
72 pConnector->getStreamList().erase( it );
73 break;
76 delete [] stream->url;
77 delete stream;
78 // returns NPError
79 NPError aRet = pConnector->GetNPError( pMes );
80 delete pMes;
81 return aRet;
84 #ifdef OJI
85 static JRIEnv* l_NPN_GetJavaEnv()
87 // no java in this program
88 medDebug( 1, "SNI: NPN_GetJavaEnv\n" );
89 return NULL;
92 static jref l_NPN_GetJavaPeer( NPP /*instance*/ )
94 medDebug( 1, "SNI: NPN_GetJavaPeer\n" );
95 return NULL;
97 #endif
99 static NPError l_NPN_GetURL( NPP instance, const char* url, const char* window )
101 UINT32 nInstance = pConnector->GetNPPID( instance );
102 if( nInstance == PluginConnector::UnknownNPPID )
103 return NPERR_GENERIC_ERROR;
105 MediatorMessage* pMes=
106 pConnector->
107 Transact( eNPN_GetURL,
108 &nInstance, sizeof( nInstance ),
109 POST_STRING(url),
110 POST_STRING(window),
111 NULL );
112 medDebug( !pMes, "geturl: message unaswered\n" );
113 if( ! pMes )
114 return NPERR_GENERIC_ERROR;
116 // returns NPError
117 NPError aRet = pConnector->GetNPError( pMes );
118 medDebug( aRet, "geturl returns %d\n", (int)aRet );
119 delete pMes;
120 return aRet;
123 static NPError l_NPN_GetURLNotify( NPP instance, const char* url, const char* target,
124 void* notifyData )
126 UINT32 nInstance = pConnector->GetNPPID( instance );
127 if( nInstance == PluginConnector::UnknownNPPID )
128 return NPERR_GENERIC_ERROR;
130 MediatorMessage* pMes=
131 pConnector->
132 Transact( eNPN_GetURLNotify,
133 &nInstance, sizeof( nInstance ),
134 POST_STRING(url),
135 POST_STRING(target),
136 &notifyData, sizeof( void* ), // transmit the actual pointer
137 // since it is a pointer to private data fed back
138 // by NPP_URLNotify; this can be thought of as an ID
139 NULL );
140 if( ! pMes )
141 return NPERR_GENERIC_ERROR;
143 // returns NPError
144 NPError aRet = pConnector->GetNPError( pMes );
145 delete pMes;
146 return aRet;
149 static NPError l_NPN_NewStream( NPP instance, NPMIMEType type, const char* target,
150 NPStream** stream )
151 // stream is a return value
153 UINT32 nInstance = pConnector->GetNPPID( instance );
154 if( nInstance == PluginConnector::UnknownNPPID )
155 return NPERR_GENERIC_ERROR;
157 MediatorMessage* pMes=
158 pConnector->
159 Transact( eNPN_NewStream,
160 &nInstance, sizeof( nInstance ),
161 POST_STRING(type),
162 POST_STRING(target),
163 NULL );
164 if( ! pMes )
165 return NPERR_GENERIC_ERROR;
167 // returns a new NPStream and an error
168 NPError aRet = pConnector->GetNPError( pMes );
169 if( ! aRet )
171 NPStream* pStream = new NPStream;
172 pStream->url = pMes->GetString();
173 pStream->end = pMes->GetUINT32();
174 pStream->lastmodified = pMes->GetUINT32();
175 pStream->ndata = pStream->pdata = pStream->notifyData = NULL;
177 pConnector->getStreamList().push_back( pStream );
178 *stream = pStream;
181 delete pMes;
182 return aRet;
185 static NPError l_NPN_PostURLNotify( NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file, void* notifyData )
187 UINT32 nInstance = pConnector->GetNPPID( instance );
188 if( nInstance == PluginConnector::UnknownNPPID )
189 return NPERR_GENERIC_ERROR;
191 MediatorMessage* pMes = pConnector->
192 Transact( eNPN_PostURLNotify,
193 &nInstance, sizeof( nInstance ),
194 POST_STRING( url ),
195 POST_STRING( target ),
196 &len, sizeof( len ),
197 buf, len,
198 &file, sizeof( NPBool ),
199 &notifyData, sizeof( void* ), // send the real pointer
200 NULL );
202 if( ! pMes )
203 return NPERR_GENERIC_ERROR;
205 NPError aRet = pConnector->GetNPError( pMes );
206 delete pMes;
207 return aRet;
210 static NPError l_NPN_PostURL( NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file )
212 UINT32 nInstance = pConnector->GetNPPID( instance );
213 if( nInstance == PluginConnector::UnknownNPPID )
214 return NPERR_GENERIC_ERROR;
216 MediatorMessage* pMes = pConnector->
217 Transact( eNPN_PostURL,
218 &nInstance, sizeof( nInstance ),
219 POST_STRING( url ),
220 POST_STRING( window ),
221 &len, sizeof( len ),
222 buf, len,
223 &file, sizeof( NPBool ),
224 NULL );
225 if( ! pMes )
226 return NPERR_GENERIC_ERROR;
228 NPError aRet = pConnector->GetNPError( pMes );
229 delete pMes;
230 return aRet;
233 static NPError l_NPN_RequestRead( NPStream* stream, NPByteRange* rangeList )
235 medDebug( 1, "pluginapp: NPN_RequestRead\n" );
237 NPByteRange* pRange = rangeList;
238 UINT32 nRanges = 0;
239 while( pRange )
241 nRanges++;
242 pRange = pRange->next;
245 UINT32* pArray = new UINT32[ 2 * nRanges ];
246 pRange = rangeList;
247 UINT32 n = 0;
248 while( pRange )
250 pArray[ 2*n ] = (UINT32)pRange->offset;
251 pArray[ 2*n + 1] = (UINT32)pRange->length;
252 n++;
253 pRange = pRange->next;
255 UINT32 nFileID = pConnector->GetStreamID( stream );
256 MediatorMessage* pMes = pConnector->
257 Transact( eNPN_RequestRead,
258 &nFileID, sizeof( nFileID ),
259 &nRanges, sizeof( nRanges ),
260 pArray, sizeof( UINT32 ) * 2 * nRanges,
261 NULL );
263 if( ! pMes )
264 return NPERR_GENERIC_ERROR;
266 NPError aRet = pConnector->GetNPError( pMes );
267 delete [] pArray;
268 delete pMes;
269 return aRet;
272 static void l_NPN_Status( NPP instance, const char* message )
274 UINT32 nInstance = pConnector->GetNPPID( instance );
275 if( nInstance == PluginConnector::UnknownNPPID )
276 return;
278 pConnector->Send( eNPN_Status,
279 &nInstance, sizeof( nInstance ),
280 POST_STRING( message ),
281 NULL );
284 static const char* l_NPN_UserAgent( NPP instance )
286 static char* pAgent = NULL;
288 UINT32 nInstance = pConnector->GetNPPID( instance );
289 if( nInstance == PluginConnector::UnknownNPPID )
291 if( instance )
292 return "Mozilla 3.0";
293 else // e.g. flashplayer calls NPN_UserAgent with NULL
294 nInstance = 0;
297 MediatorMessage* pMes = pConnector->
298 Transact( eNPN_UserAgent,
299 &nInstance, sizeof( nInstance ),
300 NULL );
302 if( ! pMes )
303 return pAgent;
305 if( pAgent )
306 delete [] pAgent;
307 pAgent = pMes->GetString();
309 delete pMes;
311 medDebug( 1, "NPN_UserAgent returns %s\n", pAgent );
313 return pAgent;
316 #if 0
317 static void l_NPN_Version( int* major, int* minor, int* net_major, int* net_minor )
319 MediatorMessage* pMes = pConnector->
320 Transact( eNPN_Version,
321 NULL );
323 if( ! pMes )
324 return;
326 *major = pMes->GetUINT32();
327 *minor = pMes->GetUINT32();
328 *net_major = pMes->GetUINT32();
329 *net_minor = pMes->GetUINT32();
331 medDebug( 1, "pluginapp: NPN_Version: results %d %d, %d %d\n", *major, *minor, *net_major, *net_minor );
333 delete pMes;
335 #endif
337 static int32 l_NPN_Write( NPP instance, NPStream* stream, int32 len, void* buffer )
339 UINT32 nFileID = pConnector->GetStreamID( stream );
340 if( nFileID == PluginConnector::UnknownStreamID )
341 return NPERR_GENERIC_ERROR;
342 UINT32 nInstance = pConnector->GetNPPID( instance );
343 if( nInstance == PluginConnector::UnknownNPPID )
344 return NPERR_GENERIC_ERROR;
346 MediatorMessage* pMes = pConnector->
347 Transact( eNPN_Write,
348 &nInstance, sizeof( nInstance ),
349 &nFileID, sizeof( nFileID ),
350 &len, sizeof( len ),
351 buffer, len,
352 NULL );
354 if( ! pMes )
355 return 0;
357 INT32 nRet = pMes->GetUINT32();
358 return nRet;
361 static void l_NPN_ReloadPlugins( NPBool /*reloadPages*/ )
363 medDebug( 1, "NPN_ReloadPlugins: SNI\n" );
366 static NPError l_NPN_GetValue( NPP, NPNVariable variable, void* value )
369 * We want to handle values injected into a NPNVariable which aren't in
370 * the old enum we build against, but that we know are in the new enum
371 * we want to support
373 switch( (int)variable )
375 case NPNVxDisplay:
376 *((Display**)value) = pXtAppDisplay;
377 medDebug( 1, "Display requested\n" );
378 break;
379 case NPNVxtAppContext:
380 *((XtAppContext*)value) = app_context;
381 medDebug( 1, "AppContext requested\n" );
382 break;
383 case NPNVjavascriptEnabledBool:
384 // no javascript
385 *(NPBool*)value = false;
386 medDebug( 1, "javascript enabled requested\n" );
387 break;
388 case NPNVasdEnabledBool:
389 // no SmartUpdate
390 *(NPBool*)value = false;
391 medDebug( 1, "smart update enabled requested\n" );
392 break;
393 case NPNVisOfflineBool:
394 // no offline browsing
395 *(NPBool*)value = false;
396 medDebug( 1, "offline browsing requested\n" );
397 break;
398 case NPNVSupportsXEmbedBool:
399 // asking xembed
400 *(int*)value = true;
401 medDebug( 1, "xembed requested\n" );
402 break;
403 case NPNVToolkit:
404 # ifdef ENABLE_GTK
405 *(int*)value = NPNVGtk2;
406 # else
407 *(int*)value = 0;
408 # endif
409 medDebug( 1, "toolkit requested\n" );
410 break;
411 default:
412 medDebug( 1, "unknown NPNVariable %x requested\n", variable );
413 return NPERR_INVALID_PARAM;
415 return NPERR_NO_ERROR;
418 static NPError l_NPN_SetValue(NPP /*instance*/, NPPVariable variable, void *value)
420 medDebug( 1, "NPN_SetValue %d=%p\n", variable, value );
421 return 0;
424 static void l_NPN_InvalidateRect(NPP /*instance*/, NPRect* /*invalidRect*/)
426 medDebug( 1, "NPN_InvalidateRect\n" );
429 static void l_NPN_InvalidateRegion(NPP /*instance*/, NPRegion /*invalidRegion*/)
431 medDebug( 1, "NPN_InvalidateRegion\n" );
434 static void l_NPN_ForceRedraw(NPP /*instance*/)
436 medDebug( 1, "NPN_ForceRedraw\n" );
441 static NPNetscapeFuncs aNetscapeFuncs =
443 sizeof(aNetscapeFuncs),
444 (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
445 l_NPN_GetURL,
446 l_NPN_PostURL,
447 l_NPN_RequestRead,
448 l_NPN_NewStream,
449 l_NPN_Write,
450 l_NPN_DestroyStream,
451 l_NPN_Status,
452 l_NPN_UserAgent,
453 l_NPN_MemAlloc,
454 l_NPN_MemFree,
455 l_NPN_MemFlush,
456 l_NPN_ReloadPlugins,
457 # ifdef OJI
458 l_NPN_GetJavaEnv,
459 l_NPN_GetJavaPeer,
460 # else
461 NULL,
462 NULL,
463 # endif
464 l_NPN_GetURLNotify,
465 l_NPN_PostURLNotify,
466 l_NPN_GetValue,
467 l_NPN_SetValue,
468 l_NPN_InvalidateRect,
469 l_NPN_InvalidateRegion,
470 l_NPN_ForceRedraw
473 static NPPluginFuncs aPluginFuncs =
475 sizeof(aPluginFuncs),
476 (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
477 NULL,
478 NULL,
479 NULL,
480 NULL,
481 NULL,
482 NULL,
483 NULL,
484 NULL,
485 NULL,
486 NULL,
487 NULL,
488 NULL,
489 NULL,
490 NULL
494 oslModule pPluginLib = NULL;
495 char*(*pNPP_GetMIMEDescription)() = NULL;
496 NPError (*pNP_Initialize)(NPNetscapeFuncs*,NPPluginFuncs*) = NULL;
497 NPError (*pNP_Shutdown)() = NULL;
499 std::vector< PluginConnector* > PluginConnector::allConnectors;
501 PluginConnector::PluginConnector( int nSocket ) :
502 Mediator( nSocket )
504 SetNewMessageHdl( LINK( this, PluginConnector, NewMessageHdl ) );
507 PluginConnector::~PluginConnector()
511 IMPL_LINK( PluginConnector, WorkOnNewMessageHdl, Mediator*, /*pMediator*/ )
513 MediatorMessage* pMessage;
514 CommandAtoms nCommand;
515 while( (pMessage = GetNextMessage( FALSE )) )
517 nCommand = (CommandAtoms)pMessage->GetUINT32();
518 medDebug( 1, "pluginapp: %s\n", GetCommandName( nCommand ) );
519 switch( nCommand )
521 case eNPP_DestroyStream:
523 UINT32 nInstance = pMessage->GetUINT32();
524 NPP instance = m_aInstances[ nInstance ]->instance;
525 UINT32 nFileID = pMessage->GetUINT32();
526 NPStream* pStream = m_aNPWrapStreams[ nFileID ];
527 NPError aReason = GetNPError( pMessage );
528 m_aNPWrapStreams.erase( m_aNPWrapStreams.begin() + nFileID );
530 aReason = aPluginFuncs.destroystream( instance, pStream, aReason );
531 Respond( pMessage->m_nID,
532 (char*)&aReason, sizeof( aReason ),
533 NULL );
535 delete [] pStream->url;
536 delete pStream;
538 break;
539 case eNPP_Destroy:
541 UINT32 nInstance = pMessage->GetUINT32();
542 ConnectorInstance* pInst= m_aInstances[ nInstance ];
544 // some plugin rely on old netscapes behaviour
545 // to first destroy the widget and then destroy
546 // the instance, so mimic that behaviour here
547 if( pInst->pShell )
548 XtDestroyWidget( (Widget)pInst->pShell );
550 pInst->pWidget = pInst->pShell = NULL;
552 // the other side will call eNPP_DestroyPhase2 after this
553 NPError aReason = NPERR_NO_ERROR;
554 Respond( pMessage->m_nID, (char*)&aReason, sizeof( aReason ), NULL );
556 break;
557 case eNPP_DestroyPhase2:
559 // now really destroy the instance
560 UINT32 nInstance = pMessage->GetUINT32();
561 ConnectorInstance* pInst= m_aInstances[ nInstance ];
562 NPP instance = pInst->instance;
563 NPSavedData* pSave = NULL;
565 NPError aRet = aPluginFuncs.destroy( instance, &pSave );
566 if( pSave )
568 Respond( pMessage->m_nID,
569 (char*)&aRet, sizeof( aRet ),
570 pSave->buf, pSave->len,
571 NULL );
572 delete [] (char*)pSave->buf;
574 else
575 Respond( pMessage->m_nID,
576 (char*)&aRet, sizeof( aRet ),
577 "0000", 4,
578 NULL );
580 #ifdef ENABLE_GTK
581 if( pInst->pGtkWindow )
582 g_object_unref( G_OBJECT(pInst->pGtkWindow) );
583 if( pInst->pGtkWidget )
584 g_object_unref( G_OBJECT(pInst->pGtkWidget) );
585 #endif
587 m_aInstances.erase( m_aInstances.begin() + nInstance );
588 delete pInst;
589 delete instance;
590 medDebug( 1, "destroyed instance (returning %d)\n", aRet );
592 break;
593 case eNPP_NewStream:
595 UINT32 nInstance = pMessage->GetUINT32();
596 NPP instance = m_aInstances[ nInstance ]->instance;
597 char* pType = pMessage->GetString();
598 NPStream* pStream = new NPStream;
599 pStream->url = pMessage->GetString();
600 pStream->end = pMessage->GetUINT32();
601 pStream->lastmodified = pMessage->GetUINT32();
602 pStream->pdata = pStream->ndata = pStream->notifyData = NULL;
603 NPBool* pSeekable = (NPBool*)pMessage->GetBytes();
604 m_aNPWrapStreams.push_back( pStream );
605 uint16 nStype = NP_ASFILE;
606 NPError aRet = aPluginFuncs.newstream( instance, pType, pStream,
607 *pSeekable, &nStype );
608 medDebug( 1, "pluginapp: NPP_NewStream( %p, %s, %p, %s, %p ) returns %d\n"
609 "stream = { pdata = %p, ndata = %p, url = %s, end = %d, lastmodified = %d, notifyData = %p }\n",
610 instance, pType, pStream, *pSeekable ? "seekable" : "not seekable", &nStype, (int)aRet,
611 pStream->pdata, pStream->ndata, pStream->url, pStream->end, pStream->lastmodified, pStream->notifyData );
612 Respond( pMessage->m_nID,
613 (char*)&aRet, sizeof( aRet ),
614 &nStype, sizeof( nStype ),
615 NULL );
616 delete [] pType;
617 delete [] pSeekable;
619 break;
620 case eNPP_New:
622 char* pType = pMessage->GetString();
623 uint16* pMode = (uint16*)pMessage->GetBytes();
624 int16* pArgc = (int16*)pMessage->GetBytes();
625 NPP instance = new NPP_t;
626 instance->pdata = instance->ndata = NULL;
627 ULONG nArgnBytes, nArgvBytes;
628 char* pArgn = (char*)pMessage->GetBytes( nArgnBytes );
629 char* pArgv = (char*)pMessage->GetBytes( nArgvBytes );
630 ULONG nSaveBytes;
631 char* pSavedData = (char*)pMessage->GetBytes( nSaveBytes );
632 ConnectorInstance* pInst =
633 new ConnectorInstance( instance, pType,
634 *pArgc,
635 pArgn, nArgnBytes,
636 pArgv, nArgvBytes,
637 pSavedData, nSaveBytes );
638 m_aInstances.push_back( pInst );
639 NPError aRet;
640 aRet = aPluginFuncs.newp( pInst->pMimeType, instance, *pMode, *pArgc,
641 pInst->nArg ? pInst->argn : NULL,
642 pInst->nArg ? pInst->argv : NULL,
643 ( nSaveBytes == 4 && *(UINT32*)pSavedData == 0 ) ?
644 &(pInst->aData) : NULL );
645 medDebug( 1, "pluginapp: NPP_New( %s, %p, %d, %d, %p, %p, %p ) returns %d\n",
646 pInst->pMimeType,
647 instance, *pMode, pInst->nArg, pInst->argn, pInst->argv, &pInst->aData,
648 (int) aRet );
649 #if OSL_DEBUG_LEVEL > 1
650 for( int i = 0; i < pInst->nArg; i++ )
651 medDebug( 1, " \"%s\"=\"%s\"\n", pInst->argn[i], pInst->argv[i] );
652 #endif
654 #ifdef ENABLE_GTK
655 // check if XEMBED is to be used
656 // ask for Bool. there seems to be no clear definition whether the
657 // return value should be an int or unsigned char
658 // int can hold both and will be nonzero in case of "true"
659 if( aPluginFuncs.getvalue )
661 int bNeedsXEmbed = 0;
662 NPError error = aPluginFuncs.getvalue( instance, NPPVpluginNeedsXEmbed, (void *)&bNeedsXEmbed );
663 if( error == NPERR_NO_ERROR )
664 pInst->bShouldUseXEmbed = (bNeedsXEmbed != 0);
665 medDebug( 1, "should use xembed = %s\n", pInst->bShouldUseXEmbed ? "true" : "false" );
667 #endif
669 Respond( pMessage->m_nID,
670 (char*)&aRet, sizeof( aRet ),
671 NULL );
672 delete [] pMode;
673 delete [] pArgc;
674 delete [] pType;
676 break;
677 case eNPP_SetWindow:
679 UINT32 nInstance = pMessage->GetUINT32();
680 ConnectorInstance* pInst= m_aInstances[ nInstance ];
681 NPWindow* pWindow = (NPWindow*)pMessage->GetBytes();
683 if( pWindow->width < 1 )
684 pWindow->width = 1;
685 if( pWindow->height < 1 )
686 pWindow->height = 1;
688 #ifdef ENABLE_GTK
689 if( pInst->bShouldUseXEmbed )
691 if( ! pInst->pGtkWidget )
693 medDebug( 1, "creating gtk plug and socket\n" );
695 pInst->pGtkWindow = gtk_plug_new((GdkNativeWindow)reinterpret_cast<sal_uIntPtr>(pWindow->window));
696 gtk_widget_show( pInst->pGtkWindow );
697 pInst->pGtkWidget = gtk_socket_new();
698 gtk_widget_show( pInst->pGtkWidget );
699 gtk_container_add( GTK_CONTAINER(pInst->pGtkWindow), pInst->pGtkWidget );
700 gtk_widget_show_all( pInst->pGtkWindow );
701 pInst->window.window = (void *)gtk_socket_get_id( GTK_SOCKET(pInst->pGtkWidget ) );
703 XSync( pAppDisplay, False );
705 XMapWindow( pAppDisplay, GDK_WINDOW_XWINDOW(pInst->pGtkWindow->window) );
707 XSync( pAppDisplay, False );
710 // update widget size; alas out parent is not yet really XEMBED conformant
711 gtk_widget_set_size_request( pInst->pGtkWidget, pWindow->width, pWindow->height );
712 gtk_window_resize( GTK_WINDOW(pInst->pGtkWindow), pWindow->width, pWindow->height );
714 GdkScreen* pGdkScreen = gtk_widget_get_screen( pInst->pGtkWidget );
715 Screen* pScreen = ScreenOfDisplay( pAppDisplay, gdk_screen_get_number( pGdkScreen ) );
717 pInst->window.x = 0;
718 pInst->window.y = 0;
719 pInst->window.width = pWindow->width;
720 pInst->window.height = pWindow->height;
721 pInst->window.clipRect.left = 0;
722 pInst->window.clipRect.top = 0;
723 pInst->window.clipRect.right = pWindow->width;
724 pInst->window.clipRect.bottom = pWindow->height;
725 pInst->window.ws_info = &pInst->ws_info;
726 pInst->window.type = NPWindowTypeWindow;
727 pInst->ws_info.type = NP_SETWINDOW;
728 pInst->ws_info.display = pAppDisplay;
729 pInst->ws_info.visual = DefaultVisualOfScreen( pScreen );
730 pInst->ws_info.colormap = DefaultColormapOfScreen( pScreen );
731 pInst->ws_info.depth = DefaultDepthOfScreen( pScreen );
733 else
734 #endif
736 if( ! pInst->pWidget )
738 pInst->pWidget = CreateNewShell( &(pInst->pShell), (XLIB_Window)pWindow->window );
741 // fill in NPWindow and NPCallbackStruct
742 pInst->window.window = (void*)XtWindow( (Widget)pInst->pWidget );
743 pInst->window.x = 0;
744 pInst->window.y = 0;
745 pInst->window.width = pWindow->width;
746 pInst->window.height = pWindow->height;
747 pInst->window.clipRect.left = 0;
748 pInst->window.clipRect.top = 0;
749 pInst->window.clipRect.right = pWindow->width;
750 pInst->window.clipRect.bottom = pWindow->height;
751 pInst->window.ws_info = &pInst->ws_info;
752 pInst->window.type = NPWindowTypeWindow;
753 pInst->ws_info.type = NP_SETWINDOW;
754 pInst->ws_info.display = XtDisplay( (Widget)pInst->pWidget );
755 pInst->ws_info.visual = DefaultVisualOfScreen( XtScreen( (Widget)pInst->pWidget ) );
756 pInst->ws_info.colormap = DefaultColormapOfScreen( XtScreen( (Widget)pInst->pWidget ) );
757 pInst->ws_info.depth = DefaultDepthOfScreen( XtScreen( (Widget)pInst->pWidget ) );
759 XtResizeWidget( (Widget)pInst->pShell,
760 pInst->window.width,
761 pInst->window.height,
762 0 );
763 XtResizeWidget( (Widget)pInst->pWidget,
764 pInst->window.width,
765 pInst->window.height,
766 0 );
769 NPError aRet = aPluginFuncs.setwindow( pInst->instance, &pInst->window );
770 medDebug( 1, "pluginapp: NPP_SetWindow returns %d\n", (int) aRet );
771 Respond( pMessage->m_nID,
772 (char*)&aRet, sizeof( aRet ),
773 NULL );
774 delete [] (char*)pWindow;
776 break;
777 case eNPP_StreamAsFile:
779 UINT32 nInstance = pMessage->GetUINT32();
780 NPP instance = m_aInstances[ nInstance ]->instance;
781 UINT32 nFileID = pMessage->GetUINT32();
782 NPStream* pStream = m_aNPWrapStreams[ nFileID ];
783 char* fname = pMessage->GetString();
784 medDebug( 1, "pluginapp: NPP_StreamAsFile %s\n", fname );
785 aPluginFuncs.asfile( instance, pStream, fname );
786 delete [] fname;
788 break;
789 case eNPP_URLNotify:
791 UINT32 nInstance = pMessage->GetUINT32();
792 NPP instance = m_aInstances[ nInstance ]->instance;
793 char* url = pMessage->GetString();
794 NPReason* pReason = (NPReason*)pMessage->GetBytes();
795 void** notifyData = (void**)pMessage->GetBytes();
796 aPluginFuncs.urlnotify( instance, url, *pReason, *notifyData );
797 delete [] url;
798 delete [] pReason;
799 delete [] notifyData;
801 break;
802 case eNPP_WriteReady:
804 UINT32 nInstance = pMessage->GetUINT32();
805 NPP instance = m_aInstances[ nInstance ]->instance;
806 UINT32 nFileID = pMessage->GetUINT32();
807 NPStream* pStream = m_aNPWrapStreams[ nFileID ];
808 int32 nRet = aPluginFuncs.writeready( instance, pStream );
810 medDebug( 1, "pluginapp: NPP_WriteReady( %p, %p ) (stream id = %d) returns %d\n",
811 instance, pStream, nFileID, nRet );
813 Respond( pMessage->m_nID,
814 (char*)&nRet, sizeof( nRet ),
815 NULL );
817 break;
818 case eNPP_Write:
820 UINT32 nInstance = pMessage->GetUINT32();
821 NPP instance = m_aInstances[ nInstance ]->instance;
822 UINT32 nFileID = pMessage->GetUINT32();
823 NPStream* pStream = m_aNPWrapStreams[ nFileID ];
824 int32 offset = pMessage->GetUINT32();
825 ULONG len;
826 char* buffer = (char*)pMessage->GetBytes( len );
827 int32 nRet = aPluginFuncs.write( instance, pStream, offset, len, buffer );
829 medDebug( 1,"pluginapp: NPP_Write( %p, %p, %d, %d, %p ) returns %d\n"
830 "stream = { pdata = %p, ndata = %p, url = %s, end = %d, lastmodified = %d, notifyData = %p }\n",
831 instance, pStream, offset, len, buffer, nRet,
832 pStream->pdata, pStream->ndata, pStream->url, pStream->end, pStream->lastmodified, pStream->notifyData );
834 Respond( pMessage->m_nID,
835 (char*)&nRet, sizeof( nRet ),
836 NULL );
837 delete [] buffer;
839 break;
840 case eNPP_GetMIMEDescription:
842 if( ! pNPP_GetMIMEDescription )
843 pNPP_GetMIMEDescription = (char*(*)())
844 osl_getAsciiFunctionSymbol( pPluginLib, "NPP_GetMIMEDescription" );
845 char* pMIME = pNPP_GetMIMEDescription();
846 Respond( pMessage->m_nID,
847 POST_STRING( pMIME ),
848 NULL );
850 break;
851 case eNPP_Initialize:
854 pNP_Initialize =
855 (NPError(*)(NPNetscapeFuncs*, NPPluginFuncs*))
856 osl_getAsciiFunctionSymbol( pPluginLib, "NP_Initialize" );
857 medDebug( !pNP_Initialize, "no NP_Initialize, %s\n", dlerror() );
858 pNP_Shutdown = (NPError(*)())
859 osl_getAsciiFunctionSymbol( pPluginLib, "NP_Shutdown" );
860 medDebug( !pNP_Initialize, "no NP_Shutdown, %s\n", dlerror() );
862 medDebug( 1, "entering NP_Initialize\n" );
863 NPError aRet = pNP_Initialize( &aNetscapeFuncs, &aPluginFuncs );
864 medDebug( 1, "pluginapp: NP_Initialize returns %d\n", (int) aRet );
865 Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
867 break;
868 case eNPP_Shutdown:
870 write( wakeup_fd[1], "xxxx", 4 );
872 break;
873 default:
874 medDebug( 1, "caught unknown NPP request %d\n", nCommand );
875 break;
877 delete pMessage;
879 return 0;
882 void LoadAdditionalLibs( const char* _pPluginLib )
884 medDebug( 1, "LoadAdditionalLibs %s\n", _pPluginLib );
886 if( ! strncmp( _pPluginLib, "libflashplayer.so", 17 ) )
888 /* #b4951312# flash 7 implicitly assumes a gtk application
889 * if the API version is greater or equal to 12 (probably
890 * because they think they run in mozilla then). In that
891 * case they try to find gtk within the process and crash
892 * when they don't find it.
894 aNetscapeFuncs.version = 11;
895 aPluginFuncs.version = 11;