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 0 : return NPERR_GENERIC_ERROR;
292 :
293 0 : NPError aRet = pConnector->GetNPError( pMes );
294 0 : delete [] pArray;
295 0 : delete pMes;
296 0 : return aRet;
297 : }
298 :
299 0 : static void l_NPN_Status( NPP instance, const char* message )
300 : {
301 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
302 0 : if( nInstance == PluginConnector::UnknownNPPID )
303 0 : return;
304 :
305 : pConnector->Send( eNPN_Status,
306 : &nInstance, sizeof( nInstance ),
307 : POST_STRING( message ),
308 0 : NULL );
309 : }
310 :
311 0 : static const char* l_NPN_UserAgent( NPP instance )
312 : {
313 : static char* pAgent = NULL;
314 :
315 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
316 0 : if( nInstance == PluginConnector::UnknownNPPID )
317 : {
318 0 : if( instance )
319 0 : return "Mozilla 3.0";
320 : else // e.g. flashplayer calls NPN_UserAgent with NULL
321 0 : nInstance = 0;
322 : }
323 :
324 : MediatorMessage* pMes = pConnector->
325 : Transact( eNPN_UserAgent,
326 : &nInstance, sizeof( nInstance ),
327 0 : NULL );
328 :
329 0 : if( ! pMes )
330 0 : return pAgent;
331 :
332 0 : if( pAgent )
333 0 : delete [] pAgent;
334 0 : pAgent = pMes->GetString();
335 :
336 0 : delete pMes;
337 :
338 : SAL_INFO("extensions.plugin", "NPN_UserAgent returns " << pAgent);
339 :
340 0 : return pAgent;
341 : }
342 :
343 0 : static int32_t l_NPN_Write( NPP instance, NPStream* stream, int32_t len, void* buffer )
344 : {
345 0 : sal_uInt32 nFileID = pConnector->GetStreamID( stream );
346 0 : if( nFileID == PluginConnector::UnknownStreamID )
347 0 : return NPERR_GENERIC_ERROR;
348 0 : sal_uInt32 nInstance = pConnector->GetNPPID( instance );
349 0 : if( nInstance == PluginConnector::UnknownNPPID )
350 0 : return NPERR_GENERIC_ERROR;
351 :
352 : MediatorMessage* pMes = pConnector->
353 : Transact( eNPN_Write,
354 : &nInstance, sizeof( nInstance ),
355 : &nFileID, sizeof( nFileID ),
356 : &len, sizeof( len ),
357 : buffer, len,
358 0 : NULL );
359 :
360 0 : if( ! pMes )
361 0 : return 0;
362 :
363 0 : sal_Int32 nRet = pMes->GetUINT32();
364 0 : return nRet;
365 : }
366 :
367 0 : static void l_NPN_ReloadPlugins( NPBool /*reloadPages*/ )
368 : {
369 : SAL_INFO("extensions.plugin", "NPN_ReloadPlugins: SNI");
370 0 : }
371 :
372 0 : static NPError l_NPN_GetValue( NPP, NPNVariable variable, void* value )
373 : {
374 : /*
375 : * We want to handle values injected into a NPNVariable which aren't in
376 : * the old enum we build against, but that we know are in the new enum
377 : * we want to support
378 : */
379 0 : switch( (int)variable )
380 : {
381 : case NPNVxDisplay:
382 0 : *((Display**)value) = pXtAppDisplay;
383 : SAL_INFO("extensions.plugin", "Display requested");
384 0 : break;
385 : case NPNVxtAppContext:
386 0 : *((XtAppContext*)value) = app_context;
387 : SAL_INFO("extensions.plugin", "AppContext requested");
388 0 : break;
389 : case NPNVjavascriptEnabledBool:
390 : // no javascript
391 0 : *(NPBool*)value = false;
392 : SAL_INFO("extensions.plugin", "javascript enabled requested");
393 0 : break;
394 : case NPNVasdEnabledBool:
395 : // no SmartUpdate
396 0 : *(NPBool*)value = false;
397 : SAL_INFO("extensions.plugin", "smart update enabled requested");
398 0 : break;
399 : case NPNVisOfflineBool:
400 : // no offline browsing
401 0 : *(NPBool*)value = false;
402 : SAL_INFO("extensions.plugin", "offline browsing requested");
403 0 : break;
404 : case NPNVSupportsXEmbedBool:
405 : // asking xembed
406 0 : *(int*)value = true;
407 : SAL_INFO("extensions.plugin", "xembed requested");
408 0 : break;
409 : case NPNVToolkit:
410 : # ifdef ENABLE_GTK
411 0 : *(int*)value = NPNVGtk2;
412 : # else
413 : *(int*)value = 0;
414 : # endif
415 : SAL_INFO("extensions.plugin", "toolkit requested");
416 0 : break;
417 : default:
418 : SAL_WARN(
419 : "extensions.plugin",
420 : "unknown NPNVariable " << +variable << " requested");
421 0 : return NPERR_INVALID_PARAM;
422 : }
423 0 : return NPERR_NO_ERROR;
424 : }
425 :
426 0 : static NPError l_NPN_SetValue(NPP /*instance*/, NPPVariable variable, void *value)
427 : {
428 : SAL_INFO("extensions.plugin", "NPN_SetValue " << +variable << "=" << value);
429 0 : return 0;
430 : }
431 :
432 0 : static void l_NPN_InvalidateRect(NPP /*instance*/, NPRect* /*invalidRect*/)
433 : {
434 : SAL_INFO("extensions.plugin", "NPN_InvalidateRect");
435 0 : }
436 :
437 0 : static void l_NPN_InvalidateRegion(NPP /*instance*/, NPRegion /*invalidRegion*/)
438 : {
439 : SAL_INFO("extensions.plugin", "NPN_InvalidateRegion");
440 0 : }
441 :
442 0 : static void l_NPN_ForceRedraw(NPP /*instance*/)
443 : {
444 : SAL_INFO("extensions.plugin", "NPN_ForceRedraw");
445 0 : }
446 :
447 : }
448 :
449 : static NPNetscapeFuncs aNetscapeFuncs =
450 : {
451 : sizeof(aNetscapeFuncs),
452 : (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
453 : l_NPN_GetURL,
454 : l_NPN_PostURL,
455 : l_NPN_RequestRead,
456 : l_NPN_NewStream,
457 : l_NPN_Write,
458 : l_NPN_DestroyStream,
459 : l_NPN_Status,
460 : l_NPN_UserAgent,
461 : l_NPN_MemAlloc,
462 : l_NPN_MemFree,
463 : l_NPN_MemFlush,
464 : l_NPN_ReloadPlugins,
465 : # ifdef OJI
466 : l_NPN_GetJavaEnv,
467 : l_NPN_GetJavaPeer,
468 : # else
469 : NULL,
470 : NULL,
471 : # endif
472 : l_NPN_GetURLNotify,
473 : l_NPN_PostURLNotify,
474 : l_NPN_GetValue,
475 : l_NPN_SetValue,
476 : l_NPN_InvalidateRect,
477 : l_NPN_InvalidateRegion,
478 : l_NPN_ForceRedraw
479 : };
480 :
481 : static NPPluginFuncs aPluginFuncs =
482 : {
483 : sizeof(aPluginFuncs),
484 : (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
485 : NULL,
486 : NULL,
487 : NULL,
488 : NULL,
489 : NULL,
490 : NULL,
491 : NULL,
492 : NULL,
493 : NULL,
494 : NULL,
495 : NULL,
496 : NULL,
497 : NULL,
498 : NULL
499 : };
500 :
501 :
502 : oslModule pPluginLib = NULL;
503 : char*(*pNPP_GetMIMEDescription)() = NULL;
504 : NPError (*pNP_Initialize)(NPNetscapeFuncs*,NPPluginFuncs*) = NULL;
505 : NPError (*pNP_Shutdown)() = NULL;
506 :
507 0 : std::vector< PluginConnector* > PluginConnector::allConnectors;
508 :
509 0 : PluginConnector::PluginConnector( int nSocket ) :
510 0 : Mediator( nSocket )
511 : {
512 0 : SetNewMessageHdl( LINK( this, PluginConnector, NewMessageHdl ) );
513 0 : }
514 :
515 0 : PluginConnector::~PluginConnector()
516 : {
517 0 : }
518 :
519 0 : IMPL_LINK( PluginConnector, WorkOnNewMessageHdl, Mediator*, /*pMediator*/ )
520 : {
521 : MediatorMessage* pMessage;
522 : CommandAtoms nCommand;
523 0 : while( (pMessage = GetNextMessage( sal_False )) )
524 : {
525 0 : nCommand = (CommandAtoms)pMessage->GetUINT32();
526 : SAL_INFO(
527 : "extensions.plugin", "pluginapp: " << GetCommandName(nCommand));
528 0 : switch( nCommand )
529 : {
530 : case eNPP_DestroyStream:
531 : {
532 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
533 0 : NPP instance = m_aInstances[ nInstance ]->instance;
534 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
535 0 : NPStream* pStream = m_aNPWrapStreams[ nFileID ];
536 0 : NPError aReason = GetNPError( pMessage );
537 0 : m_aNPWrapStreams.erase( m_aNPWrapStreams.begin() + nFileID );
538 :
539 0 : aReason = aPluginFuncs.destroystream( instance, pStream, aReason );
540 : Respond( pMessage->m_nID,
541 : (char*)&aReason, sizeof( aReason ),
542 0 : NULL );
543 :
544 0 : delete [] pStream->url;
545 0 : delete pStream;
546 : }
547 0 : break;
548 : case eNPP_Destroy:
549 : {
550 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
551 0 : ConnectorInstance* pInst= m_aInstances[ nInstance ];
552 :
553 : // some plugin rely on old netscapes behaviour
554 : // to first destroy the widget and then destroy
555 : // the instance, so mimic that behaviour here
556 0 : if( pInst->pShell )
557 0 : XtDestroyWidget( (Widget)pInst->pShell );
558 :
559 0 : pInst->pWidget = pInst->pShell = NULL;
560 :
561 : // the other side will call eNPP_DestroyPhase2 after this
562 0 : NPError aReason = NPERR_NO_ERROR;
563 0 : Respond( pMessage->m_nID, (char*)&aReason, sizeof( aReason ), NULL );
564 : }
565 0 : break;
566 : case eNPP_DestroyPhase2:
567 : {
568 : // now really destroy the instance
569 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
570 0 : ConnectorInstance* pInst= m_aInstances[ nInstance ];
571 0 : NPP instance = pInst->instance;
572 0 : NPSavedData* pSave = NULL;
573 :
574 0 : NPError aRet = aPluginFuncs.destroy( instance, &pSave );
575 0 : if( pSave )
576 : {
577 : Respond( pMessage->m_nID,
578 : (char*)&aRet, sizeof( aRet ),
579 : pSave->buf, pSave->len,
580 0 : NULL );
581 0 : delete [] (char*)pSave->buf;
582 : }
583 : else
584 : Respond( pMessage->m_nID,
585 : (char*)&aRet, sizeof( aRet ),
586 : "0000", 4,
587 0 : NULL );
588 :
589 : #ifdef ENABLE_GTK
590 0 : if( pInst->pGtkWindow )
591 0 : g_object_unref( G_OBJECT(pInst->pGtkWindow) );
592 0 : if( pInst->pGtkWidget )
593 0 : g_object_unref( G_OBJECT(pInst->pGtkWidget) );
594 : #endif
595 :
596 0 : m_aInstances.erase( m_aInstances.begin() + nInstance );
597 0 : delete pInst;
598 0 : delete instance;
599 : SAL_INFO(
600 : "extensions.plugin",
601 : "destroyed instance (returning " << aRet << ")");
602 : }
603 0 : break;
604 : case eNPP_NewStream:
605 : {
606 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
607 0 : NPP instance = m_aInstances[ nInstance ]->instance;
608 0 : char* pType = pMessage->GetString();
609 0 : NPStream* pStream = new NPStream;
610 0 : pStream->url = pMessage->GetString();
611 0 : pStream->end = pMessage->GetUINT32();
612 0 : pStream->lastmodified = pMessage->GetUINT32();
613 0 : pStream->pdata = pStream->ndata = pStream->notifyData = NULL;
614 0 : NPBool* pSeekable = (NPBool*)pMessage->GetBytes();
615 0 : m_aNPWrapStreams.push_back( pStream );
616 0 : uint16_t nStype = NP_ASFILE;
617 : NPError aRet = aPluginFuncs.newstream( instance, pType, pStream,
618 0 : *pSeekable, &nStype );
619 : SAL_INFO(
620 : "extensions.plugin",
621 : "pluginapp: NPP_NewStream(" << instance << ", " << pType
622 : << ", " << pStream << ", "
623 : << (*pSeekable ? "seekable" : "not seekable") << ", "
624 : << &nStype << ") returns " << aRet
625 : << "; stream = { pdata = " << pStream->pdata
626 : << ", ndata = " << pStream->ndata << ", url = "
627 : << pStream->url << ", end = " << pStream->end
628 : << ", lastmodified = " << pStream->lastmodified
629 : << ", notifyData = " << pStream->notifyData << " }");
630 : Respond( pMessage->m_nID,
631 : (char*)&aRet, sizeof( aRet ),
632 : &nStype, sizeof( nStype ),
633 0 : NULL );
634 0 : delete [] pType;
635 0 : delete [] pSeekable;
636 : }
637 0 : break;
638 : case eNPP_New:
639 : {
640 0 : char* pType = pMessage->GetString();
641 0 : uint16_t* pMode = (uint16_t*)pMessage->GetBytes();
642 0 : int16_t* pArgc = (int16_t*)pMessage->GetBytes();
643 0 : NPP instance = new NPP_t;
644 0 : instance->pdata = instance->ndata = NULL;
645 : sal_uLong nArgnBytes, nArgvBytes;
646 0 : char* pArgn = (char*)pMessage->GetBytes( nArgnBytes );
647 0 : char* pArgv = (char*)pMessage->GetBytes( nArgvBytes );
648 : sal_uLong nSaveBytes;
649 0 : char* pSavedData = (char*)pMessage->GetBytes( nSaveBytes );
650 : ConnectorInstance* pInst =
651 : new ConnectorInstance( instance, pType,
652 : *pArgc,
653 : pArgn, nArgnBytes,
654 : pArgv, nArgvBytes,
655 0 : pSavedData, nSaveBytes );
656 0 : m_aInstances.push_back( pInst );
657 : NPError aRet;
658 : aRet = aPluginFuncs.newp( pInst->pMimeType, instance, *pMode, *pArgc,
659 : pInst->nArg ? pInst->argn : NULL,
660 : pInst->nArg ? pInst->argv : NULL,
661 : ( nSaveBytes == 4 && *(sal_uInt32*)pSavedData == 0 ) ?
662 0 : &(pInst->aData) : NULL );
663 : SAL_INFO(
664 : "extensions.plugin",
665 : "pluginapp: NPP_New( " << pInst->pMimeType << ", "
666 : << instance << ", " << *pMode << ", " << pInst->nArg
667 : << ", " << pInst->argn << ", " << pInst->argv << ", "
668 : << &pInst->aData << ") returns" << aRet);
669 0 : for( int i = 0; i < pInst->nArg; i++ )
670 : SAL_INFO(
671 : "extensions.plugin",
672 : " \"" << pInst->argn[i] << "\"=\"" << pInst->argv[i]
673 : << "\"");
674 :
675 : #ifdef ENABLE_GTK
676 : // check if XEMBED is to be used
677 : // ask for Bool. there seems to be no clear definition whether the
678 : // return value should be an int or unsigned char
679 : // int can hold both and will be nonzero in case of "true"
680 0 : if( aPluginFuncs.getvalue )
681 : {
682 0 : int bNeedsXEmbed = 0;
683 0 : NPError error = aPluginFuncs.getvalue( instance, NPPVpluginNeedsXEmbed, (void *)&bNeedsXEmbed );
684 0 : if( error == NPERR_NO_ERROR )
685 0 : pInst->bShouldUseXEmbed = (bNeedsXEmbed != 0);
686 : SAL_INFO(
687 : "extensions.plugin",
688 : "should use xembed = "
689 : << (pInst->bShouldUseXEmbed ? "true" : "false"));
690 : }
691 : #endif
692 :
693 : Respond( pMessage->m_nID,
694 : (char*)&aRet, sizeof( aRet ),
695 0 : NULL );
696 0 : delete [] pMode;
697 0 : delete [] pArgc;
698 0 : delete [] pType;
699 : }
700 0 : break;
701 : case eNPP_SetWindow:
702 : {
703 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
704 0 : ConnectorInstance* pInst= m_aInstances[ nInstance ];
705 0 : NPWindow* pWindow = (NPWindow*)pMessage->GetBytes();
706 :
707 0 : if( pWindow->width < 1 )
708 0 : pWindow->width = 1;
709 0 : if( pWindow->height < 1 )
710 0 : pWindow->height = 1;
711 :
712 : #ifdef ENABLE_GTK
713 0 : if( pInst->bShouldUseXEmbed )
714 : {
715 0 : if( ! pInst->pGtkWidget )
716 : {
717 : SAL_INFO(
718 : "extensions.plugin",
719 : "creating gtk plug and socket");
720 :
721 0 : pInst->pGtkWindow = gtk_plug_new((GdkNativeWindow)reinterpret_cast<sal_uIntPtr>(pWindow->window));
722 0 : gtk_widget_show( pInst->pGtkWindow );
723 0 : pInst->pGtkWidget = gtk_socket_new();
724 0 : gtk_widget_show( pInst->pGtkWidget );
725 0 : gtk_container_add( GTK_CONTAINER(pInst->pGtkWindow), pInst->pGtkWidget );
726 0 : gtk_widget_show_all( pInst->pGtkWindow );
727 0 : pInst->window.window = (void *)(sal_uIntPtr)gtk_socket_get_id( GTK_SOCKET(pInst->pGtkWidget ) );
728 :
729 0 : XSync( pAppDisplay, False );
730 :
731 0 : XMapWindow( pAppDisplay, GDK_WINDOW_XWINDOW(pInst->pGtkWindow->window) );
732 :
733 0 : XSync( pAppDisplay, False );
734 : }
735 :
736 : // update widget size; alas out parent is not yet really XEMBED conformant
737 0 : gtk_widget_set_size_request( pInst->pGtkWidget, pWindow->width, pWindow->height );
738 0 : gtk_window_resize( GTK_WINDOW(pInst->pGtkWindow), pWindow->width, pWindow->height );
739 :
740 0 : GdkScreen* pGdkScreen = gtk_widget_get_screen( pInst->pGtkWidget );
741 0 : Screen* pScreen = ScreenOfDisplay( pAppDisplay, gdk_screen_get_number( pGdkScreen ) );
742 :
743 0 : pInst->window.x = 0;
744 0 : pInst->window.y = 0;
745 0 : pInst->window.width = pWindow->width;
746 0 : pInst->window.height = pWindow->height;
747 0 : pInst->window.clipRect.left = 0;
748 0 : pInst->window.clipRect.top = 0;
749 0 : pInst->window.clipRect.right = pWindow->width;
750 0 : pInst->window.clipRect.bottom = pWindow->height;
751 0 : pInst->window.ws_info = &pInst->ws_info;
752 0 : pInst->window.type = NPWindowTypeWindow;
753 0 : pInst->ws_info.type = NP_SETWINDOW;
754 0 : pInst->ws_info.display = pAppDisplay;
755 0 : pInst->ws_info.visual = DefaultVisualOfScreen( pScreen );
756 0 : pInst->ws_info.colormap = DefaultColormapOfScreen( pScreen );
757 0 : pInst->ws_info.depth = DefaultDepthOfScreen( pScreen );
758 : }
759 : else
760 : #endif
761 : {
762 0 : if( ! pInst->pWidget )
763 : {
764 0 : pInst->pWidget = CreateNewShell( &(pInst->pShell), (XLIB_Window)pWindow->window );
765 : }
766 :
767 : // fill in NPWindow and NPCallbackStruct
768 0 : pInst->window.window = (void*)XtWindow( (Widget)pInst->pWidget );
769 0 : pInst->window.x = 0;
770 0 : pInst->window.y = 0;
771 0 : pInst->window.width = pWindow->width;
772 0 : pInst->window.height = pWindow->height;
773 0 : pInst->window.clipRect.left = 0;
774 0 : pInst->window.clipRect.top = 0;
775 0 : pInst->window.clipRect.right = pWindow->width;
776 0 : pInst->window.clipRect.bottom = pWindow->height;
777 0 : pInst->window.ws_info = &pInst->ws_info;
778 0 : pInst->window.type = NPWindowTypeWindow;
779 0 : pInst->ws_info.type = NP_SETWINDOW;
780 0 : pInst->ws_info.display = XtDisplay( (Widget)pInst->pWidget );
781 0 : pInst->ws_info.visual = DefaultVisualOfScreen( XtScreen( (Widget)pInst->pWidget ) );
782 0 : pInst->ws_info.colormap = DefaultColormapOfScreen( XtScreen( (Widget)pInst->pWidget ) );
783 0 : pInst->ws_info.depth = DefaultDepthOfScreen( XtScreen( (Widget)pInst->pWidget ) );
784 :
785 : XtResizeWidget( (Widget)pInst->pShell,
786 : pInst->window.width,
787 : pInst->window.height,
788 0 : 0 );
789 : XtResizeWidget( (Widget)pInst->pWidget,
790 : pInst->window.width,
791 : pInst->window.height,
792 0 : 0 );
793 : }
794 :
795 0 : NPError aRet = aPluginFuncs.setwindow( pInst->instance, &pInst->window );
796 : SAL_INFO(
797 : "extensions.plugin",
798 : "pluginapp: NPP_SetWindow returns " << aRet);
799 : Respond( pMessage->m_nID,
800 : (char*)&aRet, sizeof( aRet ),
801 0 : NULL );
802 0 : delete [] (char*)pWindow;
803 : }
804 0 : break;
805 : case eNPP_StreamAsFile:
806 : {
807 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
808 0 : NPP instance = m_aInstances[ nInstance ]->instance;
809 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
810 0 : NPStream* pStream = m_aNPWrapStreams[ nFileID ];
811 0 : char* fname = pMessage->GetString();
812 : SAL_INFO(
813 : "extensions.plugin",
814 : "pluginapp: NPP_StreamAsFile " << fname);
815 0 : aPluginFuncs.asfile( instance, pStream, fname );
816 0 : delete [] fname;
817 : }
818 0 : break;
819 : case eNPP_URLNotify:
820 : {
821 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
822 0 : NPP instance = m_aInstances[ nInstance ]->instance;
823 0 : char* url = pMessage->GetString();
824 0 : NPReason* pReason = (NPReason*)pMessage->GetBytes();
825 0 : void** notifyData = (void**)pMessage->GetBytes();
826 0 : aPluginFuncs.urlnotify( instance, url, *pReason, *notifyData );
827 0 : delete [] url;
828 0 : delete [] pReason;
829 0 : delete [] notifyData;
830 : }
831 0 : break;
832 : case eNPP_WriteReady:
833 : {
834 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
835 0 : NPP instance = m_aInstances[ nInstance ]->instance;
836 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
837 0 : NPStream* pStream = m_aNPWrapStreams[ nFileID ];
838 0 : int32_t nRet = aPluginFuncs.writeready( instance, pStream );
839 :
840 : SAL_INFO(
841 : "extensions.plugin",
842 : "pluginapp: NPP_WriteReady(" << instance << ", " << pStream
843 : << ") (stream id = " << nFileID << ") returns "
844 : << nRet);
845 :
846 : Respond( pMessage->m_nID,
847 : (char*)&nRet, sizeof( nRet ),
848 0 : NULL );
849 : }
850 0 : break;
851 : case eNPP_Write:
852 : {
853 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
854 0 : NPP instance = m_aInstances[ nInstance ]->instance;
855 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
856 0 : NPStream* pStream = m_aNPWrapStreams[ nFileID ];
857 0 : int32_t offset = pMessage->GetUINT32();
858 : sal_uLong len;
859 0 : char* buffer = (char*)pMessage->GetBytes( len );
860 0 : int32_t nRet = aPluginFuncs.write( instance, pStream, offset, len, buffer );
861 :
862 : SAL_INFO(
863 : "extensions.plugin",
864 : "pluginapp: NPP_Write(" << instance << ", " << pStream
865 : << ", " << offset << ", " << len << ", " << buffer
866 : << ") returns " << nRet << "; stream = { pdata = "
867 : << pStream->pdata << ", ndata = " << pStream->ndata
868 : << ", url = " << pStream->url << ", end = "
869 : << pStream->end << ", lastmodified = "
870 : << pStream->lastmodified << ", notifyData = "
871 : << pStream->notifyData << " }");
872 :
873 : Respond( pMessage->m_nID,
874 : (char*)&nRet, sizeof( nRet ),
875 0 : NULL );
876 0 : delete [] buffer;
877 : }
878 0 : break;
879 : case eNPP_GetMIMEDescription:
880 : {
881 0 : if( ! pNPP_GetMIMEDescription )
882 : pNPP_GetMIMEDescription = (char*(*)())
883 0 : osl_getAsciiFunctionSymbol( pPluginLib, "NPP_GetMIMEDescription" );
884 0 : char* pMIME = pNPP_GetMIMEDescription();
885 : Respond( pMessage->m_nID,
886 : POST_STRING( pMIME ),
887 0 : NULL );
888 : }
889 0 : break;
890 : case eNPP_Initialize:
891 : {
892 :
893 : pNP_Initialize =
894 : (NPError(*)(NPNetscapeFuncs*, NPPluginFuncs*))
895 0 : osl_getAsciiFunctionSymbol( pPluginLib, "NP_Initialize" );
896 : SAL_WARN_IF(
897 : !pNP_Initialize, "extensions.plugin",
898 : "no NP_Initialize, " << dlerror());
899 : pNP_Shutdown = (NPError(*)())
900 0 : osl_getAsciiFunctionSymbol( pPluginLib, "NP_Shutdown" );
901 : SAL_WARN_IF(
902 : !pNP_Initialize, "extensions.plugin",
903 : "no NP_Shutdown, " << dlerror());
904 :
905 : SAL_INFO("extensions.plugin", "entering NP_Initialize");
906 0 : NPError aRet = pNP_Initialize( &aNetscapeFuncs, &aPluginFuncs );
907 : SAL_INFO(
908 : "extensions.plugin",
909 : "pluginapp: NP_Initialize returns " << aRet);
910 0 : Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
911 : }
912 0 : break;
913 : case eNPP_Shutdown:
914 : {
915 0 : bool bSuccess = (4 == write(wakeup_fd[1], "xxxx", 4));
916 : SAL_WARN_IF(!bSuccess, "extensions.plugin", "short write");
917 : }
918 0 : break;
919 : default:
920 : SAL_WARN(
921 : "extensions.plugin",
922 : "caught unknown NPP request " << +nCommand);
923 0 : break;
924 : }
925 0 : delete pMessage;
926 : }
927 0 : return 0;
928 : }
929 :
930 0 : void LoadAdditionalLibs( const char* _pPluginLib )
931 : {
932 : SAL_INFO("extensions.plugin", "LoadAdditionalLibs " << _pPluginLib);
933 :
934 0 : if( ! strncmp( _pPluginLib, "libflashplayer.so", 17 ) )
935 : {
936 : /* #b4951312# flash 7 implicitly assumes a gtk application
937 : * if the API version is greater or equal to 12 (probably
938 : * because they think they run in mozilla then). In that
939 : * case they try to find gtk within the process and crash
940 : * when they don't find it.
941 : */
942 0 : aNetscapeFuncs.version = 11;
943 0 : aPluginFuncs.version = 11;
944 : }
945 0 : }
946 :
947 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|