Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
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.
15 : *
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).
21 : *
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.
26 : *
27 : ************************************************************************/
28 :
29 :
30 : #ifdef AIX
31 : #define _LINUX_SOURCE_COMPAT
32 : #include <sys/timer.h>
33 : #undef _LINUX_SOURCE_COMPAT
34 : #endif
35 :
36 : #include <plugin/unx/plugcon.hxx>
37 :
38 : #include <unistd.h>
39 : #include <dlfcn.h>
40 :
41 : #include <osl/module.h>
42 :
43 : #include <config_vclplug.h>
44 :
45 : extern PluginConnector* pConnector;
46 : extern XtAppContext app_context;
47 : extern int wakeup_fd[];
48 : extern Widget topLevel, topBox;
49 : extern Display* pAppDisplay;
50 : extern Display* pXtAppDisplay;
51 : extern int nAppArguments;
52 : extern char** pAppArguments;
53 :
54 : void* CreateNewShell( void**, XLIB_Window );
55 :
56 : // begin Netscape plugin api calls
57 : extern "C" {
58 :
59 0 : static void* l_NPN_MemAlloc( uint32_t nBytes )
60 : {
61 0 : void* pMem = new char[nBytes];
62 0 : return pMem;
63 : }
64 :
65 0 : static void l_NPN_MemFree( void* pMem )
66 : {
67 0 : delete [] (char*)pMem;
68 0 : }
69 :
70 0 : static uint32_t l_NPN_MemFlush( uint32_t /*nSize*/ )
71 : {
72 0 : return 0;
73 : }
74 :
75 0 : static NPError l_NPN_DestroyStream( NPP instance, NPStream* stream, NPError reason )
76 : {
77 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
78 0 : if( nInstance == PluginConnector::UnknownNPPID )
79 0 : return NPERR_GENERIC_ERROR;
80 :
81 0 : sal_uInt32 nFileID = pConnector->GetStreamID( stream );
82 : MediatorMessage* pMes=
83 : pConnector->
84 : Transact( eNPN_DestroyStream,
85 : &nInstance, sizeof( nInstance ),
86 : &nFileID, sizeof( nFileID ),
87 0 : POST_STRING( stream->url ),
88 : &reason, sizeof( reason ),
89 0 : NULL );
90 :
91 0 : if( ! pMes )
92 0 : return NPERR_GENERIC_ERROR;
93 :
94 0 : for( std::vector< NPStream* >::iterator it = pConnector->getStreamList().begin();
95 0 : it != pConnector->getStreamList().end(); ++it )
96 : {
97 0 : if( *it == stream )
98 : {
99 0 : pConnector->getStreamList().erase( it );
100 0 : break;
101 : }
102 : }
103 0 : delete [] stream->url;
104 0 : delete stream;
105 : // returns NPError
106 0 : NPError aRet = pConnector->GetNPError( pMes );
107 0 : delete pMes;
108 0 : return aRet;
109 : }
110 :
111 : #ifdef OJI
112 : static JRIEnv* l_NPN_GetJavaEnv()
113 : {
114 : // no java in this program
115 : SAL_INFO("extensions.plugin", "SNI: NPN_GetJavaEnv");
116 : return NULL;
117 : }
118 :
119 : static jref l_NPN_GetJavaPeer( NPP /*instance*/ )
120 : {
121 : SAL_INFO("extensions.plugin", "SNI: NPN_GetJavaPeer");
122 : return NULL;
123 : }
124 : #endif
125 :
126 0 : static NPError l_NPN_GetURL( NPP instance, const char* url, const char* window )
127 : {
128 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
129 0 : if( nInstance == PluginConnector::UnknownNPPID )
130 0 : return NPERR_GENERIC_ERROR;
131 :
132 : MediatorMessage* pMes=
133 : pConnector->
134 : Transact( eNPN_GetURL,
135 : &nInstance, sizeof( nInstance ),
136 : POST_STRING(url),
137 : POST_STRING(window),
138 0 : NULL );
139 : SAL_WARN_IF(!pMes, "extensions.plugin", "geturl: message unanswered");
140 0 : if( ! pMes )
141 0 : return NPERR_GENERIC_ERROR;
142 :
143 : // returns NPError
144 0 : NPError aRet = pConnector->GetNPError( pMes );
145 : SAL_WARN_IF(aRet, "extensions.plugin", "geturl returns " << aRet);
146 0 : delete pMes;
147 0 : return aRet;
148 : }
149 :
150 0 : static NPError l_NPN_GetURLNotify( NPP instance, const char* url, const char* target,
151 : void* notifyData )
152 : {
153 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
154 0 : if( nInstance == PluginConnector::UnknownNPPID )
155 0 : return NPERR_GENERIC_ERROR;
156 :
157 : MediatorMessage* pMes=
158 : pConnector->
159 : Transact( eNPN_GetURLNotify,
160 : &nInstance, sizeof( nInstance ),
161 : POST_STRING(url),
162 : POST_STRING(target),
163 : ¬ifyData, sizeof( void* ), // transmit the actual pointer
164 : // since it is a pointer to private data fed back
165 : // by NPP_URLNotify; this can be thought of as an ID
166 0 : NULL );
167 0 : if( ! pMes )
168 0 : return NPERR_GENERIC_ERROR;
169 :
170 : // returns NPError
171 0 : NPError aRet = pConnector->GetNPError( pMes );
172 0 : delete pMes;
173 0 : return aRet;
174 : }
175 :
176 0 : static NPError l_NPN_NewStream( NPP instance, NPMIMEType type, const char* target,
177 : NPStream** stream )
178 : // stream is a return value
179 : {
180 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
181 0 : if( nInstance == PluginConnector::UnknownNPPID )
182 0 : return NPERR_GENERIC_ERROR;
183 :
184 : MediatorMessage* pMes=
185 : pConnector->
186 : Transact( eNPN_NewStream,
187 : &nInstance, sizeof( nInstance ),
188 : POST_STRING(type),
189 : POST_STRING(target),
190 0 : NULL );
191 0 : if( ! pMes )
192 0 : return NPERR_GENERIC_ERROR;
193 :
194 : // returns a new NPStream and an error
195 0 : NPError aRet = pConnector->GetNPError( pMes );
196 0 : if( ! aRet )
197 : {
198 0 : NPStream* pStream = new NPStream;
199 0 : pStream->url = pMes->GetString();
200 0 : pStream->end = pMes->GetUINT32();
201 0 : pStream->lastmodified = pMes->GetUINT32();
202 0 : pStream->ndata = pStream->pdata = pStream->notifyData = NULL;
203 :
204 0 : pConnector->getStreamList().push_back( pStream );
205 0 : *stream = pStream;
206 : }
207 :
208 0 : delete pMes;
209 0 : return aRet;
210 : }
211 :
212 0 : static NPError l_NPN_PostURLNotify( NPP instance, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData )
213 : {
214 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
215 0 : if( nInstance == PluginConnector::UnknownNPPID )
216 0 : return NPERR_GENERIC_ERROR;
217 :
218 : MediatorMessage* pMes = pConnector->
219 : Transact( eNPN_PostURLNotify,
220 : &nInstance, sizeof( nInstance ),
221 : POST_STRING( url ),
222 : POST_STRING( target ),
223 : &len, sizeof( len ),
224 : buf, len,
225 : &file, sizeof( NPBool ),
226 : ¬ifyData, sizeof( void* ), // send the real pointer
227 0 : NULL );
228 :
229 0 : if( ! pMes )
230 0 : return NPERR_GENERIC_ERROR;
231 :
232 0 : NPError aRet = pConnector->GetNPError( pMes );
233 0 : delete pMes;
234 0 : return aRet;
235 : }
236 :
237 0 : static NPError l_NPN_PostURL( NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file )
238 : {
239 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
240 0 : if( nInstance == PluginConnector::UnknownNPPID )
241 0 : return NPERR_GENERIC_ERROR;
242 :
243 : MediatorMessage* pMes = pConnector->
244 : Transact( eNPN_PostURL,
245 : &nInstance, sizeof( nInstance ),
246 : POST_STRING( url ),
247 : POST_STRING( window ),
248 : &len, sizeof( len ),
249 : buf, len,
250 : &file, sizeof( NPBool ),
251 0 : NULL );
252 0 : if( ! pMes )
253 0 : return NPERR_GENERIC_ERROR;
254 :
255 0 : NPError aRet = pConnector->GetNPError( pMes );
256 0 : delete pMes;
257 0 : return aRet;
258 : }
259 :
260 0 : static NPError l_NPN_RequestRead( NPStream* stream, NPByteRange* rangeList )
261 : {
262 : SAL_INFO("extensions.plugin", "pluginapp: NPN_RequestRead");
263 :
264 0 : NPByteRange* pRange = rangeList;
265 0 : sal_uInt32 nRanges = 0;
266 0 : while( pRange )
267 : {
268 0 : nRanges++;
269 0 : pRange = pRange->next;
270 : }
271 :
272 0 : sal_uInt32* pArray = new sal_uInt32[ 2 * nRanges ];
273 0 : pRange = rangeList;
274 0 : sal_uInt32 n = 0;
275 0 : while( pRange )
276 : {
277 0 : pArray[ 2*n ] = (sal_uInt32)pRange->offset;
278 0 : pArray[ 2*n + 1] = (sal_uInt32)pRange->length;
279 0 : n++;
280 0 : pRange = pRange->next;
281 : }
282 0 : sal_uInt32 nFileID = pConnector->GetStreamID( stream );
283 : MediatorMessage* pMes = pConnector->
284 : Transact( eNPN_RequestRead,
285 : &nFileID, sizeof( nFileID ),
286 : &nRanges, sizeof( nRanges ),
287 : pArray, sizeof( sal_uInt32 ) * 2 * nRanges,
288 0 : NULL );
289 :
290 0 : if( ! pMes )
291 : {
292 0 : delete[] pArray;
293 0 : return NPERR_GENERIC_ERROR;
294 : }
295 :
296 0 : NPError aRet = pConnector->GetNPError( pMes );
297 0 : delete [] pArray;
298 0 : delete pMes;
299 0 : return aRet;
300 : }
301 :
302 0 : static void l_NPN_Status( NPP instance, const char* message )
303 : {
304 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
305 0 : if( nInstance == PluginConnector::UnknownNPPID )
306 0 : return;
307 :
308 : pConnector->Send( eNPN_Status,
309 : &nInstance, sizeof( nInstance ),
310 : POST_STRING( message ),
311 0 : NULL );
312 : }
313 :
314 0 : static const char* l_NPN_UserAgent( NPP instance )
315 : {
316 : static char* pAgent = NULL;
317 :
318 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
319 0 : if( nInstance == PluginConnector::UnknownNPPID )
320 : {
321 0 : if( instance )
322 0 : return "Mozilla 3.0";
323 : else // e.g. flashplayer calls NPN_UserAgent with NULL
324 0 : nInstance = 0;
325 : }
326 :
327 : MediatorMessage* pMes = pConnector->
328 : Transact( eNPN_UserAgent,
329 : &nInstance, sizeof( nInstance ),
330 0 : NULL );
331 :
332 0 : if( ! pMes )
333 0 : return pAgent;
334 :
335 0 : if( pAgent )
336 0 : delete [] pAgent;
337 0 : pAgent = pMes->GetString();
338 :
339 0 : delete pMes;
340 :
341 : SAL_INFO("extensions.plugin", "NPN_UserAgent returns " << pAgent);
342 :
343 0 : return pAgent;
344 : }
345 :
346 0 : static int32_t l_NPN_Write( NPP instance, NPStream* stream, int32_t len, void* buffer )
347 : {
348 0 : sal_uInt32 nFileID = pConnector->GetStreamID( stream );
349 0 : if( nFileID == PluginConnector::UnknownStreamID )
350 0 : return NPERR_GENERIC_ERROR;
351 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
352 0 : if( nInstance == PluginConnector::UnknownNPPID )
353 0 : return NPERR_GENERIC_ERROR;
354 :
355 : MediatorMessage* pMes = pConnector->
356 : Transact( eNPN_Write,
357 : &nInstance, sizeof( nInstance ),
358 : &nFileID, sizeof( nFileID ),
359 : &len, sizeof( len ),
360 : buffer, len,
361 0 : NULL );
362 :
363 0 : if( ! pMes )
364 0 : return 0;
365 :
366 0 : sal_Int32 nRet = pMes->GetUINT32();
367 0 : return nRet;
368 : }
369 :
370 0 : static void l_NPN_ReloadPlugins( NPBool /*reloadPages*/ )
371 : {
372 : SAL_INFO("extensions.plugin", "NPN_ReloadPlugins: SNI");
373 0 : }
374 :
375 0 : static NPError l_NPN_GetValue( NPP, NPNVariable variable, void* value )
376 : {
377 : /*
378 : * We want to handle values injected into a NPNVariable which aren't in
379 : * the old enum we build against, but that we know are in the new enum
380 : * we want to support
381 : */
382 0 : switch( (int)variable )
383 : {
384 : case NPNVxDisplay:
385 0 : *((Display**)value) = pXtAppDisplay;
386 : SAL_INFO("extensions.plugin", "Display requested");
387 0 : break;
388 : case NPNVxtAppContext:
389 0 : *((XtAppContext*)value) = app_context;
390 : SAL_INFO("extensions.plugin", "AppContext requested");
391 0 : break;
392 : case NPNVjavascriptEnabledBool:
393 : // no javascript
394 0 : *(NPBool*)value = false;
395 : SAL_INFO("extensions.plugin", "javascript enabled requested");
396 0 : break;
397 : case NPNVasdEnabledBool:
398 : // no SmartUpdate
399 0 : *(NPBool*)value = false;
400 : SAL_INFO("extensions.plugin", "smart update enabled requested");
401 0 : break;
402 : case NPNVisOfflineBool:
403 : // no offline browsing
404 0 : *(NPBool*)value = false;
405 : SAL_INFO("extensions.plugin", "offline browsing requested");
406 0 : break;
407 : case NPNVSupportsXEmbedBool:
408 : // asking xembed
409 0 : *(int*)value = int(true);
410 : SAL_INFO("extensions.plugin", "xembed requested");
411 0 : break;
412 : case NPNVToolkit:
413 : # if ENABLE_GTK
414 0 : *(int*)value = NPNVGtk2;
415 : # else
416 : *(int*)value = 0;
417 : # endif
418 : SAL_INFO("extensions.plugin", "toolkit requested");
419 0 : break;
420 : default:
421 : SAL_WARN(
422 : "extensions.plugin",
423 : "unknown NPNVariable " << +variable << " requested");
424 0 : return NPERR_INVALID_PARAM;
425 : }
426 0 : return NPERR_NO_ERROR;
427 : }
428 :
429 0 : static NPError l_NPN_SetValue(NPP /*instance*/, NPPVariable variable, void *value)
430 : {
431 : SAL_INFO("extensions.plugin", "NPN_SetValue " << +variable << "=" << value);
432 0 : return 0;
433 : }
434 :
435 0 : static void l_NPN_InvalidateRect(NPP /*instance*/, NPRect* /*invalidRect*/)
436 : {
437 : SAL_INFO("extensions.plugin", "NPN_InvalidateRect");
438 0 : }
439 :
440 0 : static void l_NPN_InvalidateRegion(NPP /*instance*/, NPRegion /*invalidRegion*/)
441 : {
442 : SAL_INFO("extensions.plugin", "NPN_InvalidateRegion");
443 0 : }
444 :
445 0 : static void l_NPN_ForceRedraw(NPP /*instance*/)
446 : {
447 : SAL_INFO("extensions.plugin", "NPN_ForceRedraw");
448 0 : }
449 :
450 : }
451 :
452 : static NPNetscapeFuncs aNetscapeFuncs =
453 : {
454 : sizeof(aNetscapeFuncs),
455 : (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
456 : l_NPN_GetURL,
457 : l_NPN_PostURL,
458 : l_NPN_RequestRead,
459 : l_NPN_NewStream,
460 : l_NPN_Write,
461 : l_NPN_DestroyStream,
462 : l_NPN_Status,
463 : l_NPN_UserAgent,
464 : l_NPN_MemAlloc,
465 : l_NPN_MemFree,
466 : l_NPN_MemFlush,
467 : l_NPN_ReloadPlugins,
468 : # ifdef OJI
469 : l_NPN_GetJavaEnv,
470 : l_NPN_GetJavaPeer,
471 : # else
472 : NULL,
473 : NULL,
474 : # endif
475 : l_NPN_GetURLNotify,
476 : l_NPN_PostURLNotify,
477 : l_NPN_GetValue,
478 : l_NPN_SetValue,
479 : l_NPN_InvalidateRect,
480 : l_NPN_InvalidateRegion,
481 : l_NPN_ForceRedraw
482 : };
483 :
484 : static NPPluginFuncs aPluginFuncs =
485 : {
486 : sizeof(aPluginFuncs),
487 : (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
488 : NULL,
489 : NULL,
490 : NULL,
491 : NULL,
492 : NULL,
493 : NULL,
494 : NULL,
495 : NULL,
496 : NULL,
497 : NULL,
498 : NULL,
499 : NULL,
500 : NULL,
501 : NULL
502 : };
503 :
504 :
505 : oslModule pPluginLib = NULL;
506 : char*(*pNPP_GetMIMEDescription)() = NULL;
507 : NPError (*pNP_Initialize)(NPNetscapeFuncs*,NPPluginFuncs*) = NULL;
508 : NPError (*pNP_Shutdown)() = NULL;
509 :
510 0 : std::vector< PluginConnector* > PluginConnector::allConnectors;
511 :
512 0 : PluginConnector::PluginConnector( int nSocket ) :
513 0 : Mediator( nSocket )
514 : {
515 0 : SetNewMessageHdl( LINK( this, PluginConnector, NewMessageHdl ) );
516 0 : }
517 :
518 0 : PluginConnector::~PluginConnector()
519 : {
520 0 : }
521 :
522 0 : IMPL_LINK( PluginConnector, WorkOnNewMessageHdl, Mediator*, /*pMediator*/ )
523 : {
524 : MediatorMessage* pMessage;
525 : CommandAtoms nCommand;
526 0 : while( (pMessage = GetNextMessage( sal_False )) )
527 : {
528 0 : nCommand = (CommandAtoms)pMessage->GetUINT32();
529 : SAL_INFO(
530 : "extensions.plugin", "pluginapp: " << GetCommandName(nCommand));
531 0 : switch( nCommand )
532 : {
533 : case eNPP_DestroyStream:
534 : {
535 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
536 0 : NPP instance = m_aInstances[ nInstance ]->instance;
537 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
538 0 : NPStream* pStream = m_aNPWrapStreams[ nFileID ];
539 0 : NPError aReason = GetNPError( pMessage );
540 0 : m_aNPWrapStreams.erase( m_aNPWrapStreams.begin() + nFileID );
541 :
542 0 : aReason = aPluginFuncs.destroystream( instance, pStream, aReason );
543 : Respond( pMessage->m_nID,
544 : (char*)&aReason, sizeof( aReason ),
545 0 : NULL );
546 :
547 0 : delete [] pStream->url;
548 0 : delete pStream;
549 : }
550 0 : break;
551 : case eNPP_Destroy:
552 : {
553 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
554 0 : ConnectorInstance* pInst= m_aInstances[ nInstance ];
555 :
556 : // some plugin rely on old netscapes behaviour
557 : // to first destroy the widget and then destroy
558 : // the instance, so mimic that behaviour here
559 0 : if( pInst->pShell )
560 0 : XtDestroyWidget( (Widget)pInst->pShell );
561 :
562 0 : pInst->pWidget = pInst->pShell = NULL;
563 :
564 : // the other side will call eNPP_DestroyPhase2 after this
565 0 : NPError aReason = NPERR_NO_ERROR;
566 0 : Respond( pMessage->m_nID, (char*)&aReason, sizeof( aReason ), NULL );
567 : }
568 0 : break;
569 : case eNPP_DestroyPhase2:
570 : {
571 : // now really destroy the instance
572 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
573 0 : ConnectorInstance* pInst= m_aInstances[ nInstance ];
574 0 : NPP instance = pInst->instance;
575 0 : NPSavedData* pSave = NULL;
576 :
577 0 : NPError aRet = aPluginFuncs.destroy( instance, &pSave );
578 0 : if( pSave )
579 : {
580 : Respond( pMessage->m_nID,
581 : (char*)&aRet, sizeof( aRet ),
582 : pSave->buf, pSave->len,
583 0 : NULL );
584 0 : delete [] (char*)pSave->buf;
585 : }
586 : else
587 : Respond( pMessage->m_nID,
588 : (char*)&aRet, sizeof( aRet ),
589 : "0000", 4,
590 0 : NULL );
591 :
592 : #if ENABLE_GTK
593 0 : if( pInst->pGtkWindow )
594 0 : g_object_unref( G_OBJECT(pInst->pGtkWindow) );
595 0 : if( pInst->pGtkWidget )
596 0 : g_object_unref( G_OBJECT(pInst->pGtkWidget) );
597 : #endif
598 :
599 0 : m_aInstances.erase( m_aInstances.begin() + nInstance );
600 0 : delete pInst;
601 0 : delete instance;
602 : SAL_INFO(
603 : "extensions.plugin",
604 : "destroyed instance (returning " << aRet << ")");
605 : }
606 0 : break;
607 : case eNPP_NewStream:
608 : {
609 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
610 0 : NPP instance = m_aInstances[ nInstance ]->instance;
611 0 : char* pType = pMessage->GetString();
612 0 : NPStream* pStream = new NPStream;
613 0 : pStream->url = pMessage->GetString();
614 0 : pStream->end = pMessage->GetUINT32();
615 0 : pStream->lastmodified = pMessage->GetUINT32();
616 0 : pStream->pdata = pStream->ndata = pStream->notifyData = NULL;
617 0 : NPBool* pSeekable = (NPBool*)pMessage->GetBytes();
618 0 : m_aNPWrapStreams.push_back( pStream );
619 0 : uint16_t nStype = NP_ASFILE;
620 : NPError aRet = aPluginFuncs.newstream( instance, pType, pStream,
621 0 : *pSeekable, &nStype );
622 : SAL_INFO(
623 : "extensions.plugin",
624 : "pluginapp: NPP_NewStream(" << instance << ", " << pType
625 : << ", " << pStream << ", "
626 : << (*pSeekable ? "seekable" : "not seekable") << ", "
627 : << &nStype << ") returns " << aRet
628 : << "; stream = { pdata = " << pStream->pdata
629 : << ", ndata = " << pStream->ndata << ", url = "
630 : << pStream->url << ", end = " << pStream->end
631 : << ", lastmodified = " << pStream->lastmodified
632 : << ", notifyData = " << pStream->notifyData << " }");
633 : Respond( pMessage->m_nID,
634 : (char*)&aRet, sizeof( aRet ),
635 : &nStype, sizeof( nStype ),
636 0 : NULL );
637 0 : delete [] pType;
638 0 : delete [] pSeekable;
639 : }
640 0 : break;
641 : case eNPP_New:
642 : {
643 0 : char* pType = pMessage->GetString();
644 0 : uint16_t* pMode = (uint16_t*)pMessage->GetBytes();
645 0 : int16_t* pArgc = (int16_t*)pMessage->GetBytes();
646 0 : NPP instance = new NPP_t;
647 0 : instance->pdata = instance->ndata = NULL;
648 : sal_uLong nArgnBytes, nArgvBytes;
649 0 : char* pArgn = (char*)pMessage->GetBytes( nArgnBytes );
650 0 : char* pArgv = (char*)pMessage->GetBytes( nArgvBytes );
651 : sal_uLong nSaveBytes;
652 0 : char* pSavedData = (char*)pMessage->GetBytes( nSaveBytes );
653 : ConnectorInstance* pInst =
654 : new ConnectorInstance( instance, pType,
655 : *pArgc,
656 : pArgn, nArgnBytes,
657 : pArgv, nArgvBytes,
658 0 : pSavedData, nSaveBytes );
659 0 : m_aInstances.push_back( pInst );
660 : NPError aRet;
661 : aRet = aPluginFuncs.newp( pInst->pMimeType, instance, *pMode, *pArgc,
662 : pInst->nArg ? pInst->argn : NULL,
663 : pInst->nArg ? pInst->argv : NULL,
664 0 : ( nSaveBytes == 4 && *(sal_uInt32*)pSavedData == 0 ) ?
665 0 : &(pInst->aData) : NULL );
666 : SAL_INFO(
667 : "extensions.plugin",
668 : "pluginapp: NPP_New( " << pInst->pMimeType << ", "
669 : << instance << ", " << *pMode << ", " << pInst->nArg
670 : << ", " << pInst->argn << ", " << pInst->argv << ", "
671 : << &pInst->aData << ") returns" << aRet);
672 0 : for( int i = 0; i < pInst->nArg; i++ )
673 : SAL_INFO(
674 : "extensions.plugin",
675 : " \"" << pInst->argn[i] << "\"=\"" << pInst->argv[i]
676 : << "\"");
677 :
678 : #if ENABLE_GTK
679 : // check if XEMBED is to be used
680 : // ask for Bool. there seems to be no clear definition whether the
681 : // return value should be an int or unsigned char
682 : // int can hold both and will be nonzero in case of "true"
683 0 : if( aPluginFuncs.getvalue )
684 : {
685 0 : int bNeedsXEmbed = 0;
686 0 : NPError error = aPluginFuncs.getvalue( instance, NPPVpluginNeedsXEmbed, (void *)&bNeedsXEmbed );
687 0 : if( error == NPERR_NO_ERROR )
688 0 : pInst->bShouldUseXEmbed = (bNeedsXEmbed != 0);
689 : SAL_INFO(
690 : "extensions.plugin",
691 : "should use xembed = "
692 : << (pInst->bShouldUseXEmbed ? "true" : "false"));
693 : }
694 : #endif
695 :
696 : Respond( pMessage->m_nID,
697 : (char*)&aRet, sizeof( aRet ),
698 0 : NULL );
699 0 : delete [] pMode;
700 0 : delete [] pArgc;
701 0 : delete [] pType;
702 : }
703 0 : break;
704 : case eNPP_SetWindow:
705 : {
706 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
707 0 : ConnectorInstance* pInst= m_aInstances[ nInstance ];
708 0 : NPWindow* pWindow = (NPWindow*)pMessage->GetBytes();
709 :
710 0 : if( pWindow->width < 1 )
711 0 : pWindow->width = 1;
712 0 : if( pWindow->height < 1 )
713 0 : pWindow->height = 1;
714 :
715 : #if ENABLE_GTK
716 0 : if( pInst->bShouldUseXEmbed )
717 : {
718 0 : if( ! pInst->pGtkWidget )
719 : {
720 : SAL_INFO(
721 : "extensions.plugin",
722 : "creating gtk plug and socket");
723 :
724 0 : pInst->pGtkWindow = gtk_plug_new((GdkNativeWindow)reinterpret_cast<sal_uIntPtr>(pWindow->window));
725 0 : gtk_widget_show( pInst->pGtkWindow );
726 0 : pInst->pGtkWidget = gtk_socket_new();
727 0 : gtk_widget_show( pInst->pGtkWidget );
728 0 : gtk_container_add( GTK_CONTAINER(pInst->pGtkWindow), pInst->pGtkWidget );
729 0 : gtk_widget_show_all( pInst->pGtkWindow );
730 0 : pInst->window.window = (void *)(sal_uIntPtr)gtk_socket_get_id( GTK_SOCKET(pInst->pGtkWidget ) );
731 :
732 0 : XSync( pAppDisplay, False );
733 :
734 0 : XMapWindow( pAppDisplay, GDK_WINDOW_XWINDOW(pInst->pGtkWindow->window) );
735 :
736 0 : XSync( pAppDisplay, False );
737 : }
738 :
739 : // update widget size; alas out parent is not yet really XEMBED conformant
740 0 : gtk_widget_set_size_request( pInst->pGtkWidget, pWindow->width, pWindow->height );
741 0 : gtk_window_resize( GTK_WINDOW(pInst->pGtkWindow), pWindow->width, pWindow->height );
742 :
743 0 : GdkScreen* pGdkScreen = gtk_widget_get_screen( pInst->pGtkWidget );
744 0 : Screen* pScreen = ScreenOfDisplay( pAppDisplay, gdk_screen_get_number( pGdkScreen ) );
745 :
746 0 : pInst->window.x = 0;
747 0 : pInst->window.y = 0;
748 0 : pInst->window.width = pWindow->width;
749 0 : pInst->window.height = pWindow->height;
750 0 : pInst->window.clipRect.left = 0;
751 0 : pInst->window.clipRect.top = 0;
752 0 : pInst->window.clipRect.right = pWindow->width;
753 0 : pInst->window.clipRect.bottom = pWindow->height;
754 0 : pInst->window.ws_info = &pInst->ws_info;
755 0 : pInst->window.type = NPWindowTypeWindow;
756 0 : pInst->ws_info.type = NP_SETWINDOW;
757 0 : pInst->ws_info.display = pAppDisplay;
758 0 : pInst->ws_info.visual = DefaultVisualOfScreen( pScreen );
759 0 : pInst->ws_info.colormap = DefaultColormapOfScreen( pScreen );
760 0 : pInst->ws_info.depth = DefaultDepthOfScreen( pScreen );
761 : }
762 : else
763 : #endif
764 : {
765 0 : if( ! pInst->pWidget )
766 : {
767 0 : pInst->pWidget = CreateNewShell( &(pInst->pShell), (XLIB_Window)pWindow->window );
768 : }
769 :
770 : // fill in NPWindow and NPCallbackStruct
771 0 : pInst->window.window = (void*)XtWindow( (Widget)pInst->pWidget );
772 0 : pInst->window.x = 0;
773 0 : pInst->window.y = 0;
774 0 : pInst->window.width = pWindow->width;
775 0 : pInst->window.height = pWindow->height;
776 0 : pInst->window.clipRect.left = 0;
777 0 : pInst->window.clipRect.top = 0;
778 0 : pInst->window.clipRect.right = pWindow->width;
779 0 : pInst->window.clipRect.bottom = pWindow->height;
780 0 : pInst->window.ws_info = &pInst->ws_info;
781 0 : pInst->window.type = NPWindowTypeWindow;
782 0 : pInst->ws_info.type = NP_SETWINDOW;
783 0 : pInst->ws_info.display = XtDisplay( (Widget)pInst->pWidget );
784 0 : pInst->ws_info.visual = DefaultVisualOfScreen( XtScreen( (Widget)pInst->pWidget ) );
785 0 : pInst->ws_info.colormap = DefaultColormapOfScreen( XtScreen( (Widget)pInst->pWidget ) );
786 0 : pInst->ws_info.depth = DefaultDepthOfScreen( XtScreen( (Widget)pInst->pWidget ) );
787 :
788 : XtResizeWidget( (Widget)pInst->pShell,
789 : pInst->window.width,
790 : pInst->window.height,
791 0 : 0 );
792 : XtResizeWidget( (Widget)pInst->pWidget,
793 : pInst->window.width,
794 : pInst->window.height,
795 0 : 0 );
796 : }
797 :
798 0 : NPError aRet = aPluginFuncs.setwindow( pInst->instance, &pInst->window );
799 : SAL_INFO(
800 : "extensions.plugin",
801 : "pluginapp: NPP_SetWindow returns " << aRet);
802 : Respond( pMessage->m_nID,
803 : (char*)&aRet, sizeof( aRet ),
804 0 : NULL );
805 0 : delete [] (char*)pWindow;
806 : }
807 0 : break;
808 : case eNPP_StreamAsFile:
809 : {
810 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
811 0 : NPP instance = m_aInstances[ nInstance ]->instance;
812 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
813 0 : NPStream* pStream = m_aNPWrapStreams[ nFileID ];
814 0 : char* fname = pMessage->GetString();
815 : SAL_INFO(
816 : "extensions.plugin",
817 : "pluginapp: NPP_StreamAsFile " << fname);
818 0 : aPluginFuncs.asfile( instance, pStream, fname );
819 0 : delete [] fname;
820 : }
821 0 : break;
822 : case eNPP_URLNotify:
823 : {
824 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
825 0 : NPP instance = m_aInstances[ nInstance ]->instance;
826 0 : char* url = pMessage->GetString();
827 0 : NPReason* pReason = (NPReason*)pMessage->GetBytes();
828 0 : void** notifyData = (void**)pMessage->GetBytes();
829 0 : aPluginFuncs.urlnotify( instance, url, *pReason, *notifyData );
830 0 : delete [] url;
831 0 : delete [] pReason;
832 0 : delete [] notifyData;
833 : }
834 0 : break;
835 : case eNPP_WriteReady:
836 : {
837 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
838 0 : NPP instance = m_aInstances[ nInstance ]->instance;
839 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
840 0 : NPStream* pStream = m_aNPWrapStreams[ nFileID ];
841 0 : int32_t nRet = aPluginFuncs.writeready( instance, pStream );
842 :
843 : SAL_INFO(
844 : "extensions.plugin",
845 : "pluginapp: NPP_WriteReady(" << instance << ", " << pStream
846 : << ") (stream id = " << nFileID << ") returns "
847 : << nRet);
848 :
849 : Respond( pMessage->m_nID,
850 : (char*)&nRet, sizeof( nRet ),
851 0 : NULL );
852 : }
853 0 : break;
854 : case eNPP_Write:
855 : {
856 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
857 0 : NPP instance = m_aInstances[ nInstance ]->instance;
858 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
859 0 : NPStream* pStream = m_aNPWrapStreams[ nFileID ];
860 0 : int32_t offset = pMessage->GetUINT32();
861 : sal_uLong len;
862 0 : char* buffer = (char*)pMessage->GetBytes( len );
863 0 : int32_t nRet = aPluginFuncs.write( instance, pStream, offset, len, buffer );
864 :
865 : SAL_INFO(
866 : "extensions.plugin",
867 : "pluginapp: NPP_Write(" << instance << ", " << pStream
868 : << ", " << offset << ", " << len << ", " << buffer
869 : << ") returns " << nRet << "; stream = { pdata = "
870 : << pStream->pdata << ", ndata = " << pStream->ndata
871 : << ", url = " << pStream->url << ", end = "
872 : << pStream->end << ", lastmodified = "
873 : << pStream->lastmodified << ", notifyData = "
874 : << pStream->notifyData << " }");
875 :
876 : Respond( pMessage->m_nID,
877 : (char*)&nRet, sizeof( nRet ),
878 0 : NULL );
879 0 : delete [] buffer;
880 : }
881 0 : break;
882 : case eNPP_GetMIMEDescription:
883 : {
884 0 : if( ! pNPP_GetMIMEDescription )
885 : pNPP_GetMIMEDescription = (char*(*)())
886 0 : osl_getAsciiFunctionSymbol( pPluginLib, "NPP_GetMIMEDescription" );
887 0 : char* pMIME = pNPP_GetMIMEDescription();
888 : Respond( pMessage->m_nID,
889 : POST_STRING( pMIME ),
890 0 : NULL );
891 : }
892 0 : break;
893 : case eNPP_Initialize:
894 : {
895 :
896 : pNP_Initialize =
897 : (NPError(*)(NPNetscapeFuncs*, NPPluginFuncs*))
898 0 : osl_getAsciiFunctionSymbol( pPluginLib, "NP_Initialize" );
899 : SAL_WARN_IF(
900 : !pNP_Initialize, "extensions.plugin",
901 : "no NP_Initialize, " << dlerror());
902 : pNP_Shutdown = (NPError(*)())
903 0 : osl_getAsciiFunctionSymbol( pPluginLib, "NP_Shutdown" );
904 : SAL_WARN_IF(
905 : !pNP_Initialize, "extensions.plugin",
906 : "no NP_Shutdown, " << dlerror());
907 :
908 : SAL_INFO("extensions.plugin", "entering NP_Initialize");
909 0 : NPError aRet = pNP_Initialize( &aNetscapeFuncs, &aPluginFuncs );
910 : SAL_INFO(
911 : "extensions.plugin",
912 : "pluginapp: NP_Initialize returns " << aRet);
913 0 : Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
914 : }
915 0 : break;
916 : case eNPP_Shutdown:
917 : {
918 0 : bool bSuccess = (4 == write(wakeup_fd[1], "xxxx", 4));
919 : SAL_WARN_IF(!bSuccess, "extensions.plugin", "short write");
920 : }
921 0 : break;
922 : default:
923 : SAL_WARN(
924 : "extensions.plugin",
925 : "caught unknown NPP request " << +nCommand);
926 0 : break;
927 : }
928 0 : delete pMessage;
929 : }
930 0 : return 0;
931 : }
932 :
933 0 : void LoadAdditionalLibs( const char* _pPluginLib )
934 : {
935 : SAL_INFO("extensions.plugin", "LoadAdditionalLibs " << _pPluginLib);
936 :
937 0 : if( ! strncmp( _pPluginLib, "libflashplayer.so", 17 ) )
938 : {
939 : /* #b4951312# flash 7 implicitly assumes a gtk application
940 : * if the API version is greater or equal to 12 (probably
941 : * because they think they run in mozilla then). In that
942 : * case they try to find gtk within the process and crash
943 : * when they don't find it.
944 : */
945 0 : aNetscapeFuncs.version = 11;
946 0 : aPluginFuncs.version = 11;
947 : }
948 0 : }
949 :
950 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|