merged tag ooo/OOO330_m14
[LibreOffice.git] / extensions / source / plugin / unx / npnapi.cxx
blob4a88577c5b7183cedcbfa9c9e91ea0240bbfac50
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 #include <plugin/unx/plugcon.hxx>
32 #include <unistd.h>
33 #include <dlfcn.h>
35 #include <osl/module.h>
37 extern PluginConnector* pConnector;
38 extern XtAppContext app_context;
39 extern int wakeup_fd[];
40 extern Widget topLevel, topBox;
41 extern Display* pAppDisplay;
42 extern Display* pXtAppDisplay;
43 extern int nAppArguments;
44 extern char** pAppArguments;
46 void* CreateNewShell( void**, XLIB_Window );
48 // begin Netscape plugin api calls
49 extern "C" {
51 static void* l_NPN_MemAlloc( uint32 nBytes )
53 void* pMem = new char[nBytes];
54 return pMem;
57 static void l_NPN_MemFree( void* pMem )
59 delete [] (char*)pMem;
62 static uint32 l_NPN_MemFlush( uint32 /*nSize*/ )
64 return 0;
67 static NPError l_NPN_DestroyStream( NPP instance, NPStream* stream, NPError reason )
69 UINT32 nInstance = pConnector->GetNPPID( instance );
70 if( nInstance == PluginConnector::UnknownNPPID )
71 return NPERR_GENERIC_ERROR;
73 UINT32 nFileID = pConnector->GetStreamID( stream );
74 MediatorMessage* pMes=
75 pConnector->
76 Transact( eNPN_DestroyStream,
77 &nInstance, sizeof( nInstance ),
78 &nFileID, sizeof( nFileID ),
79 POST_STRING( stream->url ),
80 &reason, sizeof( reason ),
81 NULL );
83 if( ! pMes )
84 return NPERR_GENERIC_ERROR;
86 for( std::vector< NPStream* >::iterator it = pConnector->getStreamList().begin();
87 it != pConnector->getStreamList().end(); ++it )
89 if( *it == stream )
91 pConnector->getStreamList().erase( it );
92 break;
95 delete [] stream->url;
96 delete stream;
97 // returns NPError
98 NPError aRet = pConnector->GetNPError( pMes );
99 delete pMes;
100 return aRet;
103 #ifdef OJI
104 static JRIEnv* l_NPN_GetJavaEnv()
106 // no java in this program
107 medDebug( 1, "SNI: NPN_GetJavaEnv\n" );
108 return NULL;
111 static jref l_NPN_GetJavaPeer( NPP /*instance*/ )
113 medDebug( 1, "SNI: NPN_GetJavaPeer\n" );
114 return NULL;
116 #endif
118 static NPError l_NPN_GetURL( NPP instance, const char* url, const char* window )
120 UINT32 nInstance = pConnector->GetNPPID( instance );
121 if( nInstance == PluginConnector::UnknownNPPID )
122 return NPERR_GENERIC_ERROR;
124 MediatorMessage* pMes=
125 pConnector->
126 Transact( eNPN_GetURL,
127 &nInstance, sizeof( nInstance ),
128 POST_STRING(url),
129 POST_STRING(window),
130 NULL );
131 medDebug( !pMes, "geturl: message unaswered\n" );
132 if( ! pMes )
133 return NPERR_GENERIC_ERROR;
135 // returns NPError
136 NPError aRet = pConnector->GetNPError( pMes );
137 medDebug( aRet, "geturl returns %d\n", (int)aRet );
138 delete pMes;
139 return aRet;
142 static NPError l_NPN_GetURLNotify( NPP instance, const char* url, const char* target,
143 void* notifyData )
145 UINT32 nInstance = pConnector->GetNPPID( instance );
146 if( nInstance == PluginConnector::UnknownNPPID )
147 return NPERR_GENERIC_ERROR;
149 MediatorMessage* pMes=
150 pConnector->
151 Transact( eNPN_GetURLNotify,
152 &nInstance, sizeof( nInstance ),
153 POST_STRING(url),
154 POST_STRING(target),
155 &notifyData, sizeof( void* ), // transmit the actual pointer
156 // since it is a pointer to private data fed back
157 // by NPP_URLNotify; this can be thought of as an ID
158 NULL );
159 if( ! pMes )
160 return NPERR_GENERIC_ERROR;
162 // returns NPError
163 NPError aRet = pConnector->GetNPError( pMes );
164 delete pMes;
165 return aRet;
168 static NPError l_NPN_NewStream( NPP instance, NPMIMEType type, const char* target,
169 NPStream** stream )
170 // stream is a return value
172 UINT32 nInstance = pConnector->GetNPPID( instance );
173 if( nInstance == PluginConnector::UnknownNPPID )
174 return NPERR_GENERIC_ERROR;
176 MediatorMessage* pMes=
177 pConnector->
178 Transact( eNPN_NewStream,
179 &nInstance, sizeof( nInstance ),
180 POST_STRING(type),
181 POST_STRING(target),
182 NULL );
183 if( ! pMes )
184 return NPERR_GENERIC_ERROR;
186 // returns a new NPStream and an error
187 NPError aRet = pConnector->GetNPError( pMes );
188 if( ! aRet )
190 NPStream* pStream = new NPStream;
191 pStream->url = pMes->GetString();
192 pStream->end = pMes->GetUINT32();
193 pStream->lastmodified = pMes->GetUINT32();
194 pStream->ndata = pStream->pdata = pStream->notifyData = NULL;
196 pConnector->getStreamList().push_back( pStream );
197 *stream = pStream;
200 delete pMes;
201 return aRet;
204 static NPError l_NPN_PostURLNotify( NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file, void* notifyData )
206 UINT32 nInstance = pConnector->GetNPPID( instance );
207 if( nInstance == PluginConnector::UnknownNPPID )
208 return NPERR_GENERIC_ERROR;
210 MediatorMessage* pMes = pConnector->
211 Transact( eNPN_PostURLNotify,
212 &nInstance, sizeof( nInstance ),
213 POST_STRING( url ),
214 POST_STRING( target ),
215 &len, sizeof( len ),
216 buf, len,
217 &file, sizeof( NPBool ),
218 &notifyData, sizeof( void* ), // send the real pointer
219 NULL );
221 if( ! pMes )
222 return NPERR_GENERIC_ERROR;
224 NPError aRet = pConnector->GetNPError( pMes );
225 delete pMes;
226 return aRet;
229 static NPError l_NPN_PostURL( NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file )
231 UINT32 nInstance = pConnector->GetNPPID( instance );
232 if( nInstance == PluginConnector::UnknownNPPID )
233 return NPERR_GENERIC_ERROR;
235 MediatorMessage* pMes = pConnector->
236 Transact( eNPN_PostURL,
237 &nInstance, sizeof( nInstance ),
238 POST_STRING( url ),
239 POST_STRING( window ),
240 &len, sizeof( len ),
241 buf, len,
242 &file, sizeof( NPBool ),
243 NULL );
244 if( ! pMes )
245 return NPERR_GENERIC_ERROR;
247 NPError aRet = pConnector->GetNPError( pMes );
248 delete pMes;
249 return aRet;
252 static NPError l_NPN_RequestRead( NPStream* stream, NPByteRange* rangeList )
254 medDebug( 1, "pluginapp: NPN_RequestRead\n" );
256 NPByteRange* pRange = rangeList;
257 UINT32 nRanges = 0;
258 while( pRange )
260 nRanges++;
261 pRange = pRange->next;
264 UINT32* pArray = new UINT32[ 2 * nRanges ];
265 pRange = rangeList;
266 UINT32 n = 0;
267 while( pRange )
269 pArray[ 2*n ] = (UINT32)pRange->offset;
270 pArray[ 2*n + 1] = (UINT32)pRange->length;
271 n++;
272 pRange = pRange->next;
274 UINT32 nFileID = pConnector->GetStreamID( stream );
275 MediatorMessage* pMes = pConnector->
276 Transact( eNPN_RequestRead,
277 &nFileID, sizeof( nFileID ),
278 &nRanges, sizeof( nRanges ),
279 pArray, sizeof( UINT32 ) * 2 * nRanges,
280 NULL );
282 if( ! pMes )
283 return NPERR_GENERIC_ERROR;
285 NPError aRet = pConnector->GetNPError( pMes );
286 delete [] pArray;
287 delete pMes;
288 return aRet;
291 static void l_NPN_Status( NPP instance, const char* message )
293 UINT32 nInstance = pConnector->GetNPPID( instance );
294 if( nInstance == PluginConnector::UnknownNPPID )
295 return;
297 pConnector->Send( eNPN_Status,
298 &nInstance, sizeof( nInstance ),
299 POST_STRING( message ),
300 NULL );
303 static const char* l_NPN_UserAgent( NPP instance )
305 static char* pAgent = NULL;
307 UINT32 nInstance = pConnector->GetNPPID( instance );
308 if( nInstance == PluginConnector::UnknownNPPID )
310 if( instance )
311 return "Mozilla 3.0";
312 else // e.g. flashplayer calls NPN_UserAgent with NULL
313 nInstance = 0;
316 MediatorMessage* pMes = pConnector->
317 Transact( eNPN_UserAgent,
318 &nInstance, sizeof( nInstance ),
319 NULL );
321 if( ! pMes )
322 return pAgent;
324 if( pAgent )
325 delete [] pAgent;
326 pAgent = pMes->GetString();
328 delete pMes;
330 medDebug( 1, "NPN_UserAgent returns %s\n", pAgent );
332 return pAgent;
335 #if 0
336 static void l_NPN_Version( int* major, int* minor, int* net_major, int* net_minor )
338 MediatorMessage* pMes = pConnector->
339 Transact( eNPN_Version,
340 NULL );
342 if( ! pMes )
343 return;
345 *major = pMes->GetUINT32();
346 *minor = pMes->GetUINT32();
347 *net_major = pMes->GetUINT32();
348 *net_minor = pMes->GetUINT32();
350 medDebug( 1, "pluginapp: NPN_Version: results %d %d, %d %d\n", *major, *minor, *net_major, *net_minor );
352 delete pMes;
354 #endif
356 static int32 l_NPN_Write( NPP instance, NPStream* stream, int32 len, void* buffer )
358 UINT32 nFileID = pConnector->GetStreamID( stream );
359 if( nFileID == PluginConnector::UnknownStreamID )
360 return NPERR_GENERIC_ERROR;
361 UINT32 nInstance = pConnector->GetNPPID( instance );
362 if( nInstance == PluginConnector::UnknownNPPID )
363 return NPERR_GENERIC_ERROR;
365 MediatorMessage* pMes = pConnector->
366 Transact( eNPN_Write,
367 &nInstance, sizeof( nInstance ),
368 &nFileID, sizeof( nFileID ),
369 &len, sizeof( len ),
370 buffer, len,
371 NULL );
373 if( ! pMes )
374 return 0;
376 INT32 nRet = pMes->GetUINT32();
377 return nRet;
380 static void l_NPN_ReloadPlugins( NPBool /*reloadPages*/ )
382 medDebug( 1, "NPN_ReloadPlugins: SNI\n" );
385 static NPError l_NPN_GetValue( NPP, NPNVariable variable, void* value )
388 * We want to handle values injected into a NPNVariable which aren't in
389 * the old enum we build against, but that we know are in the new enum
390 * we want to support
392 switch( (int)variable )
394 case NPNVxDisplay:
395 *((Display**)value) = pXtAppDisplay;
396 medDebug( 1, "Display requested\n" );
397 break;
398 case NPNVxtAppContext:
399 *((XtAppContext*)value) = app_context;
400 medDebug( 1, "AppContext requested\n" );
401 break;
402 case NPNVjavascriptEnabledBool:
403 // no javascript
404 *(NPBool*)value = false;
405 medDebug( 1, "javascript enabled requested\n" );
406 break;
407 case NPNVasdEnabledBool:
408 // no SmartUpdate
409 *(NPBool*)value = false;
410 medDebug( 1, "smart update enabled requested\n" );
411 break;
412 case NPNVisOfflineBool:
413 // no offline browsing
414 *(NPBool*)value = false;
415 medDebug( 1, "offline browsing requested\n" );
416 break;
417 case NPNVSupportsXEmbedBool:
418 // asking xembed
419 *(int*)value = true;
420 medDebug( 1, "xembed requested\n" );
421 break;
422 case NPNVToolkit:
423 # ifdef ENABLE_GTK
424 *(int*)value = NPNVGtk2;
425 # else
426 *(int*)value = 0;
427 # endif
428 medDebug( 1, "toolkit requested\n" );
429 break;
430 default:
431 medDebug( 1, "unknown NPNVariable %x requested\n", variable );
432 return NPERR_INVALID_PARAM;
434 return NPERR_NO_ERROR;
437 static NPError l_NPN_SetValue(NPP /*instance*/, NPPVariable variable, void *value)
439 medDebug( 1, "NPN_SetValue %d=%p\n", variable, value );
440 return 0;
443 static void l_NPN_InvalidateRect(NPP /*instance*/, NPRect* /*invalidRect*/)
445 medDebug( 1, "NPN_InvalidateRect\n" );
448 static void l_NPN_InvalidateRegion(NPP /*instance*/, NPRegion /*invalidRegion*/)
450 medDebug( 1, "NPN_InvalidateRegion\n" );
453 static void l_NPN_ForceRedraw(NPP /*instance*/)
455 medDebug( 1, "NPN_ForceRedraw\n" );
460 static NPNetscapeFuncs aNetscapeFuncs =
462 sizeof(aNetscapeFuncs),
463 (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
464 l_NPN_GetURL,
465 l_NPN_PostURL,
466 l_NPN_RequestRead,
467 l_NPN_NewStream,
468 l_NPN_Write,
469 l_NPN_DestroyStream,
470 l_NPN_Status,
471 l_NPN_UserAgent,
472 l_NPN_MemAlloc,
473 l_NPN_MemFree,
474 l_NPN_MemFlush,
475 l_NPN_ReloadPlugins,
476 # ifdef OJI
477 l_NPN_GetJavaEnv,
478 l_NPN_GetJavaPeer,
479 # else
480 NULL,
481 NULL,
482 # endif
483 l_NPN_GetURLNotify,
484 l_NPN_PostURLNotify,
485 l_NPN_GetValue,
486 l_NPN_SetValue,
487 l_NPN_InvalidateRect,
488 l_NPN_InvalidateRegion,
489 l_NPN_ForceRedraw
492 static NPPluginFuncs aPluginFuncs =
494 sizeof(aPluginFuncs),
495 (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
496 NULL,
497 NULL,
498 NULL,
499 NULL,
500 NULL,
501 NULL,
502 NULL,
503 NULL,
504 NULL,
505 NULL,
506 NULL,
507 NULL,
508 NULL,
509 NULL
513 oslModule pPluginLib = NULL;
514 char*(*pNPP_GetMIMEDescription)() = NULL;
515 NPError (*pNP_Initialize)(NPNetscapeFuncs*,NPPluginFuncs*) = NULL;
516 NPError (*pNP_Shutdown)() = NULL;
518 std::vector< PluginConnector* > PluginConnector::allConnectors;
520 PluginConnector::PluginConnector( int nSocket ) :
521 Mediator( nSocket )
523 SetNewMessageHdl( LINK( this, PluginConnector, NewMessageHdl ) );
526 PluginConnector::~PluginConnector()
530 IMPL_LINK( PluginConnector, WorkOnNewMessageHdl, Mediator*, /*pMediator*/ )
532 MediatorMessage* pMessage;
533 CommandAtoms nCommand;
534 while( (pMessage = GetNextMessage( FALSE )) )
536 nCommand = (CommandAtoms)pMessage->GetUINT32();
537 medDebug( 1, "pluginapp: %s\n", GetCommandName( nCommand ) );
538 switch( nCommand )
540 case eNPP_DestroyStream:
542 UINT32 nInstance = pMessage->GetUINT32();
543 NPP instance = m_aInstances[ nInstance ]->instance;
544 UINT32 nFileID = pMessage->GetUINT32();
545 NPStream* pStream = m_aNPWrapStreams[ nFileID ];
546 NPError aReason = GetNPError( pMessage );
547 m_aNPWrapStreams.erase( m_aNPWrapStreams.begin() + nFileID );
549 aReason = aPluginFuncs.destroystream( instance, pStream, aReason );
550 Respond( pMessage->m_nID,
551 (char*)&aReason, sizeof( aReason ),
552 NULL );
554 delete [] pStream->url;
555 delete pStream;
557 break;
558 case eNPP_Destroy:
560 UINT32 nInstance = pMessage->GetUINT32();
561 ConnectorInstance* pInst= m_aInstances[ nInstance ];
563 // some plugin rely on old netscapes behaviour
564 // to first destroy the widget and then destroy
565 // the instance, so mimic that behaviour here
566 if( pInst->pShell )
567 XtDestroyWidget( (Widget)pInst->pShell );
569 pInst->pWidget = pInst->pShell = NULL;
571 // the other side will call eNPP_DestroyPhase2 after this
572 NPError aReason = NPERR_NO_ERROR;
573 Respond( pMessage->m_nID, (char*)&aReason, sizeof( aReason ), NULL );
575 break;
576 case eNPP_DestroyPhase2:
578 // now really destroy the instance
579 UINT32 nInstance = pMessage->GetUINT32();
580 ConnectorInstance* pInst= m_aInstances[ nInstance ];
581 NPP instance = pInst->instance;
582 NPSavedData* pSave = NULL;
584 NPError aRet = aPluginFuncs.destroy( instance, &pSave );
585 if( pSave )
587 Respond( pMessage->m_nID,
588 (char*)&aRet, sizeof( aRet ),
589 pSave->buf, pSave->len,
590 NULL );
591 delete [] (char*)pSave->buf;
593 else
594 Respond( pMessage->m_nID,
595 (char*)&aRet, sizeof( aRet ),
596 "0000", 4,
597 NULL );
599 #ifdef ENABLE_GTK
600 if( pInst->pGtkWindow )
601 g_object_unref( G_OBJECT(pInst->pGtkWindow) );
602 if( pInst->pGtkWidget )
603 g_object_unref( G_OBJECT(pInst->pGtkWidget) );
604 #endif
606 m_aInstances.erase( m_aInstances.begin() + nInstance );
607 delete pInst;
608 delete instance;
609 medDebug( 1, "destroyed instance (returning %d)\n", aRet );
611 break;
612 case eNPP_NewStream:
614 UINT32 nInstance = pMessage->GetUINT32();
615 NPP instance = m_aInstances[ nInstance ]->instance;
616 char* pType = pMessage->GetString();
617 NPStream* pStream = new NPStream;
618 pStream->url = pMessage->GetString();
619 pStream->end = pMessage->GetUINT32();
620 pStream->lastmodified = pMessage->GetUINT32();
621 pStream->pdata = pStream->ndata = pStream->notifyData = NULL;
622 NPBool* pSeekable = (NPBool*)pMessage->GetBytes();
623 m_aNPWrapStreams.push_back( pStream );
624 uint16 nStype = NP_ASFILE;
625 NPError aRet = aPluginFuncs.newstream( instance, pType, pStream,
626 *pSeekable, &nStype );
627 medDebug( 1, "pluginapp: NPP_NewStream( %p, %s, %p, %s, %p ) returns %d\n"
628 "stream = { pdata = %p, ndata = %p, url = %s, end = %d, lastmodified = %d, notifyData = %p }\n",
629 instance, pType, pStream, *pSeekable ? "seekable" : "not seekable", &nStype, (int)aRet,
630 pStream->pdata, pStream->ndata, pStream->url, pStream->end, pStream->lastmodified, pStream->notifyData );
631 Respond( pMessage->m_nID,
632 (char*)&aRet, sizeof( aRet ),
633 &nStype, sizeof( nStype ),
634 NULL );
635 delete [] pType;
636 delete [] pSeekable;
638 break;
639 case eNPP_New:
641 char* pType = pMessage->GetString();
642 uint16* pMode = (uint16*)pMessage->GetBytes();
643 int16* pArgc = (int16*)pMessage->GetBytes();
644 NPP instance = new NPP_t;
645 instance->pdata = instance->ndata = NULL;
646 ULONG nArgnBytes, nArgvBytes;
647 char* pArgn = (char*)pMessage->GetBytes( nArgnBytes );
648 char* pArgv = (char*)pMessage->GetBytes( nArgvBytes );
649 ULONG nSaveBytes;
650 char* pSavedData = (char*)pMessage->GetBytes( nSaveBytes );
651 ConnectorInstance* pInst =
652 new ConnectorInstance( instance, pType,
653 *pArgc,
654 pArgn, nArgnBytes,
655 pArgv, nArgvBytes,
656 pSavedData, nSaveBytes );
657 m_aInstances.push_back( pInst );
658 NPError aRet;
659 aRet = aPluginFuncs.newp( pInst->pMimeType, instance, *pMode, *pArgc,
660 pInst->nArg ? pInst->argn : NULL,
661 pInst->nArg ? pInst->argv : NULL,
662 ( nSaveBytes == 4 && *(UINT32*)pSavedData == 0 ) ?
663 &(pInst->aData) : NULL );
664 medDebug( 1, "pluginapp: NPP_New( %s, %p, %d, %d, %p, %p, %p ) returns %d\n",
665 pInst->pMimeType,
666 instance, *pMode, pInst->nArg, pInst->argn, pInst->argv, &pInst->aData,
667 (int) aRet );
668 #if OSL_DEBUG_LEVEL > 1
669 for( int i = 0; i < pInst->nArg; i++ )
670 medDebug( 1, " \"%s\"=\"%s\"\n", pInst->argn[i], pInst->argv[i] );
671 #endif
673 #ifdef ENABLE_GTK
674 // check if XEMBED is to be used
675 // ask for Bool. there seems to be no clear definition whether the
676 // return value should be an int or unsigned char
677 // int can hold both and will be nonzero in case of "true"
678 if( aPluginFuncs.getvalue )
680 int bNeedsXEmbed = 0;
681 NPError error = aPluginFuncs.getvalue( instance, NPPVpluginNeedsXEmbed, (void *)&bNeedsXEmbed );
682 if( error == NPERR_NO_ERROR )
683 pInst->bShouldUseXEmbed = (bNeedsXEmbed != 0);
684 medDebug( 1, "should use xembed = %s\n", pInst->bShouldUseXEmbed ? "true" : "false" );
686 #endif
688 Respond( pMessage->m_nID,
689 (char*)&aRet, sizeof( aRet ),
690 NULL );
691 delete [] pMode;
692 delete [] pArgc;
693 delete [] pType;
695 break;
696 case eNPP_SetWindow:
698 UINT32 nInstance = pMessage->GetUINT32();
699 ConnectorInstance* pInst= m_aInstances[ nInstance ];
700 NPWindow* pWindow = (NPWindow*)pMessage->GetBytes();
702 if( pWindow->width < 1 )
703 pWindow->width = 1;
704 if( pWindow->height < 1 )
705 pWindow->height = 1;
707 #ifdef ENABLE_GTK
708 if( pInst->bShouldUseXEmbed )
710 if( ! pInst->pGtkWidget )
712 medDebug( 1, "creating gtk plug and socket\n" );
714 pInst->pGtkWindow = gtk_plug_new((GdkNativeWindow)reinterpret_cast<sal_uIntPtr>(pWindow->window));
715 gtk_widget_show( pInst->pGtkWindow );
716 pInst->pGtkWidget = gtk_socket_new();
717 gtk_widget_show( pInst->pGtkWidget );
718 gtk_container_add( GTK_CONTAINER(pInst->pGtkWindow), pInst->pGtkWidget );
719 gtk_widget_show_all( pInst->pGtkWindow );
720 pInst->window.window = (void *)gtk_socket_get_id( GTK_SOCKET(pInst->pGtkWidget ) );
722 XSync( pAppDisplay, False );
724 XMapWindow( pAppDisplay, GDK_WINDOW_XWINDOW(pInst->pGtkWindow->window) );
726 XSync( pAppDisplay, False );
729 // update widget size; alas out parent is not yet really XEMBED conformant
730 gtk_widget_set_size_request( pInst->pGtkWidget, pWindow->width, pWindow->height );
731 gtk_window_resize( GTK_WINDOW(pInst->pGtkWindow), pWindow->width, pWindow->height );
733 GdkScreen* pGdkScreen = gtk_widget_get_screen( pInst->pGtkWidget );
734 Screen* pScreen = ScreenOfDisplay( pAppDisplay, gdk_screen_get_number( pGdkScreen ) );
736 pInst->window.x = 0;
737 pInst->window.y = 0;
738 pInst->window.width = pWindow->width;
739 pInst->window.height = pWindow->height;
740 pInst->window.clipRect.left = 0;
741 pInst->window.clipRect.top = 0;
742 pInst->window.clipRect.right = pWindow->width;
743 pInst->window.clipRect.bottom = pWindow->height;
744 pInst->window.ws_info = &pInst->ws_info;
745 pInst->window.type = NPWindowTypeWindow;
746 pInst->ws_info.type = NP_SETWINDOW;
747 pInst->ws_info.display = pAppDisplay;
748 pInst->ws_info.visual = DefaultVisualOfScreen( pScreen );
749 pInst->ws_info.colormap = DefaultColormapOfScreen( pScreen );
750 pInst->ws_info.depth = DefaultDepthOfScreen( pScreen );
752 else
753 #endif
755 if( ! pInst->pWidget )
757 pInst->pWidget = CreateNewShell( &(pInst->pShell), (XLIB_Window)pWindow->window );
760 // fill in NPWindow and NPCallbackStruct
761 pInst->window.window = (void*)XtWindow( (Widget)pInst->pWidget );
762 pInst->window.x = 0;
763 pInst->window.y = 0;
764 pInst->window.width = pWindow->width;
765 pInst->window.height = pWindow->height;
766 pInst->window.clipRect.left = 0;
767 pInst->window.clipRect.top = 0;
768 pInst->window.clipRect.right = pWindow->width;
769 pInst->window.clipRect.bottom = pWindow->height;
770 pInst->window.ws_info = &pInst->ws_info;
771 pInst->window.type = NPWindowTypeWindow;
772 pInst->ws_info.type = NP_SETWINDOW;
773 pInst->ws_info.display = XtDisplay( (Widget)pInst->pWidget );
774 pInst->ws_info.visual = DefaultVisualOfScreen( XtScreen( (Widget)pInst->pWidget ) );
775 pInst->ws_info.colormap = DefaultColormapOfScreen( XtScreen( (Widget)pInst->pWidget ) );
776 pInst->ws_info.depth = DefaultDepthOfScreen( XtScreen( (Widget)pInst->pWidget ) );
778 XtResizeWidget( (Widget)pInst->pShell,
779 pInst->window.width,
780 pInst->window.height,
781 0 );
782 XtResizeWidget( (Widget)pInst->pWidget,
783 pInst->window.width,
784 pInst->window.height,
785 0 );
788 NPError aRet = aPluginFuncs.setwindow( pInst->instance, &pInst->window );
789 medDebug( 1, "pluginapp: NPP_SetWindow returns %d\n", (int) aRet );
790 Respond( pMessage->m_nID,
791 (char*)&aRet, sizeof( aRet ),
792 NULL );
793 delete [] (char*)pWindow;
795 break;
796 case eNPP_StreamAsFile:
798 UINT32 nInstance = pMessage->GetUINT32();
799 NPP instance = m_aInstances[ nInstance ]->instance;
800 UINT32 nFileID = pMessage->GetUINT32();
801 NPStream* pStream = m_aNPWrapStreams[ nFileID ];
802 char* fname = pMessage->GetString();
803 medDebug( 1, "pluginapp: NPP_StreamAsFile %s\n", fname );
804 aPluginFuncs.asfile( instance, pStream, fname );
805 delete [] fname;
807 break;
808 case eNPP_URLNotify:
810 UINT32 nInstance = pMessage->GetUINT32();
811 NPP instance = m_aInstances[ nInstance ]->instance;
812 char* url = pMessage->GetString();
813 NPReason* pReason = (NPReason*)pMessage->GetBytes();
814 void** notifyData = (void**)pMessage->GetBytes();
815 aPluginFuncs.urlnotify( instance, url, *pReason, *notifyData );
816 delete [] url;
817 delete [] pReason;
818 delete [] notifyData;
820 break;
821 case eNPP_WriteReady:
823 UINT32 nInstance = pMessage->GetUINT32();
824 NPP instance = m_aInstances[ nInstance ]->instance;
825 UINT32 nFileID = pMessage->GetUINT32();
826 NPStream* pStream = m_aNPWrapStreams[ nFileID ];
827 int32 nRet = aPluginFuncs.writeready( instance, pStream );
829 medDebug( 1, "pluginapp: NPP_WriteReady( %p, %p ) (stream id = %d) returns %d\n",
830 instance, pStream, nFileID, nRet );
832 Respond( pMessage->m_nID,
833 (char*)&nRet, sizeof( nRet ),
834 NULL );
836 break;
837 case eNPP_Write:
839 UINT32 nInstance = pMessage->GetUINT32();
840 NPP instance = m_aInstances[ nInstance ]->instance;
841 UINT32 nFileID = pMessage->GetUINT32();
842 NPStream* pStream = m_aNPWrapStreams[ nFileID ];
843 int32 offset = pMessage->GetUINT32();
844 ULONG len;
845 char* buffer = (char*)pMessage->GetBytes( len );
846 int32 nRet = aPluginFuncs.write( instance, pStream, offset, len, buffer );
848 medDebug( 1,"pluginapp: NPP_Write( %p, %p, %d, %d, %p ) returns %d\n"
849 "stream = { pdata = %p, ndata = %p, url = %s, end = %d, lastmodified = %d, notifyData = %p }\n",
850 instance, pStream, offset, len, buffer, nRet,
851 pStream->pdata, pStream->ndata, pStream->url, pStream->end, pStream->lastmodified, pStream->notifyData );
853 Respond( pMessage->m_nID,
854 (char*)&nRet, sizeof( nRet ),
855 NULL );
856 delete [] buffer;
858 break;
859 case eNPP_GetMIMEDescription:
861 if( ! pNPP_GetMIMEDescription )
862 pNPP_GetMIMEDescription = (char*(*)())
863 osl_getAsciiFunctionSymbol( pPluginLib, "NPP_GetMIMEDescription" );
864 char* pMIME = pNPP_GetMIMEDescription();
865 Respond( pMessage->m_nID,
866 POST_STRING( pMIME ),
867 NULL );
869 break;
870 case eNPP_Initialize:
873 pNP_Initialize =
874 (NPError(*)(NPNetscapeFuncs*, NPPluginFuncs*))
875 osl_getAsciiFunctionSymbol( pPluginLib, "NP_Initialize" );
876 medDebug( !pNP_Initialize, "no NP_Initialize, %s\n", dlerror() );
877 pNP_Shutdown = (NPError(*)())
878 osl_getAsciiFunctionSymbol( pPluginLib, "NP_Shutdown" );
879 medDebug( !pNP_Initialize, "no NP_Shutdown, %s\n", dlerror() );
881 medDebug( 1, "entering NP_Initialize\n" );
882 NPError aRet = pNP_Initialize( &aNetscapeFuncs, &aPluginFuncs );
883 medDebug( 1, "pluginapp: NP_Initialize returns %d\n", (int) aRet );
884 Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
886 break;
887 case eNPP_Shutdown:
889 write( wakeup_fd[1], "xxxx", 4 );
891 break;
892 default:
893 medDebug( 1, "caught unknown NPP request %d\n", nCommand );
894 break;
896 delete pMessage;
898 return 0;
901 void LoadAdditionalLibs( const char* _pPluginLib )
903 medDebug( 1, "LoadAdditionalLibs %s\n", _pPluginLib );
905 if( ! strncmp( _pPluginLib, "libflashplayer.so", 17 ) )
907 /* #b4951312# flash 7 implicitly assumes a gtk application
908 * if the API version is greater or equal to 12 (probably
909 * because they think they run in mozilla then). In that
910 * case they try to find gtk within the process and crash
911 * when they don't find it.
913 aNetscapeFuncs.version = 11;
914 aPluginFuncs.version = 11;