1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #define _LINUX_SOURCE_COMPAT
32 #include <sys/timer.h>
33 #undef _LINUX_SOURCE_COMPAT
38 #include <vcl/svapp.hxx>
40 #include <plugin/unx/plugcon.hxx>
41 #include <plugin/impl.hxx>
43 std::vector
<PluginConnector
*> PluginConnector::allConnectors
;
45 PluginConnector::PluginConnector( int nSocket
) :
48 allConnectors
.push_back( this );
49 SetNewMessageHdl( LINK( this, PluginConnector
, NewMessageHdl
) );
52 PluginConnector::~PluginConnector()
54 osl::MutexGuard
aGuard( m_aUserEventMutex
);
55 for( std::vector
< PluginConnector
* >::iterator it
= allConnectors
.begin();
56 it
!= allConnectors
.end(); ++it
)
60 allConnectors
.erase( it
);
66 IMPL_LINK( PluginConnector
, NewMessageHdl
, Mediator
*, /*pMediator*/ )
68 osl::MutexGuard
aGuard( m_aUserEventMutex
);
70 for( std::vector
< PluginConnector
* >::iterator it
= allConnectors
.begin();
71 it
!= allConnectors
.end() && bFound
== false; ++it
)
78 Application::PostUserEvent( LINK( this, PluginConnector
, WorkOnNewMessageHdl
) );
82 IMPL_LINK( PluginConnector
, WorkOnNewMessageHdl
, Mediator
*, /*pMediator*/ )
85 for( std::vector
< PluginConnector
* >::iterator it
= allConnectors
.begin();
86 it
!= allConnectors
.end() && bFound
== false; ++it
)
94 MediatorMessage
* pMessage
;
95 CommandAtoms nCommand
;
96 while( (pMessage
= GetNextMessage( sal_False
)) )
98 nCommand
= (CommandAtoms
)pMessage
->GetUINT32();
99 SAL_INFO("extensions.plugin", GetCommandName(nCommand
));
104 sal_uInt32 nInstance
= pMessage
->GetUINT32();
105 NPP instance
= m_aInstances
[ nInstance
]->instance
;
106 char* pUrl
= pMessage
->GetString();
107 char* pWindow
= pMessage
->GetString();
108 NPError aRet
= NPN_GetURL( instance
, pUrl
, pWindow
);
109 Respond( pMessage
->m_nID
,
110 (char*)(&aRet
), sizeof( NPError
), NULL
);
115 case eNPN_GetURLNotify
:
117 sal_uInt32 nInstance
= pMessage
->GetUINT32();
118 NPP instance
= m_aInstances
[ nInstance
]->instance
;
119 char* pUrl
= pMessage
->GetString();
120 char* pWindow
= pMessage
->GetString();
121 void** pNotifyData
= (void**)pMessage
->GetBytes();
122 NPError aRet
= NPN_GetURLNotify( instance
, pUrl
, pWindow
,
124 Respond( pMessage
->m_nID
,
125 (char*)(&aRet
), sizeof( NPError
), NULL
);
128 delete [] pNotifyData
;
131 case eNPN_DestroyStream
:
133 sal_uInt32 nInstance
= pMessage
->GetUINT32();
134 NPP instance
= m_aInstances
[ nInstance
]->instance
;
135 sal_uInt32 nFileID
= pMessage
->GetUINT32();
136 char* pUrl
= pMessage
->GetString();
137 NPError
* pReason
= (NPError
*)pMessage
->GetBytes();
138 NPError aRet
= NPERR_FILE_NOT_FOUND
;
139 if( nFileID
< static_cast<sal_uInt32
>(m_aNPWrapStreams
.size()) )
141 if( ! strcmp( m_aNPWrapStreams
[ nFileID
]->url
, pUrl
) )
144 NPN_DestroyStream( instance
, m_aNPWrapStreams
[ nFileID
],
146 m_aNPWrapStreams
.erase( m_aNPWrapStreams
.begin() + nFileID
);
151 "StreamID " << nFileID
<< " has incoherent urls "
153 << m_aNPWrapStreams
[nFileID
]->url
);
158 "nonexistent StreamID " << nFileID
);
160 Respond( pMessage
->m_nID
,
161 (char*)(&aRet
), sizeof( NPError
), NULL
);
169 sal_uInt32 nInstance
= pMessage
->GetUINT32();
170 NPP instance
= m_aInstances
[ nInstance
]->instance
;
171 NPMIMEType pType
= pMessage
->GetString();
172 char* pTarget
= pMessage
->GetString();
174 NPStream
* pStream
= NULL
;
176 NPError aRet
= NPN_NewStream( instance
, pType
, pTarget
, &pStream
);
178 if( aRet
!= NPERR_NO_ERROR
)
180 sal_uInt32 nDummy
= 0;
181 Respond( pMessage
->m_nID
,
182 (char*)&aRet
, sizeof( aRet
),
184 &nDummy
, sizeof(sal_uInt32
),
185 &nDummy
, sizeof(sal_uInt32
),
190 m_aNPWrapStreams
.push_back( pStream
);
192 sal_uLong nLen
= strlen( pStream
->url
);
193 Respond( pMessage
->m_nID
,
194 (char*)&aRet
, sizeof( aRet
),
196 &pStream
->end
, sizeof(sal_uInt32
),
197 &pStream
->lastmodified
, sizeof(sal_uInt32
),
205 case eNPN_PostURLNotify
:
207 sal_uInt32 nInstance
= pMessage
->GetUINT32();
208 NPP instance
= m_aInstances
[ nInstance
]->instance
;
209 char* pUrl
= pMessage
->GetString();
210 char* pTarget
= pMessage
->GetString();
211 sal_uInt32 nLen
= pMessage
->GetUINT32();
212 char* pBuf
= (char*)pMessage
->GetBytes();
213 NPBool
* pFile
= (NPBool
*)pMessage
->GetBytes();
214 void** pNData
= (void**)pMessage
->GetBytes();
216 NPN_PostURLNotify( instance
, pUrl
, pTarget
, nLen
, pBuf
, *pFile
, *pNData
);
217 Respond( pMessage
->m_nID
, (char*)&aRet
, sizeof( aRet
), NULL
);
227 sal_uInt32 nInstance
= pMessage
->GetUINT32();
228 NPP instance
= m_aInstances
[ nInstance
]->instance
;
229 char* pUrl
= pMessage
->GetString();
230 char* pWindow
= pMessage
->GetString();
231 sal_uInt32 nLen
= pMessage
->GetUINT32();
232 char* pBuf
= (char*)pMessage
->GetBytes();
233 NPBool
* pFile
= (NPBool
*)pMessage
->GetBytes();
235 NPN_PostURL( instance
, pUrl
, pWindow
, nLen
, pBuf
, *pFile
);
236 Respond( pMessage
->m_nID
, (char*)&aRet
, sizeof( aRet
), NULL
);
243 case eNPN_RequestRead
:
245 sal_uInt32 nFileID
= pMessage
->GetUINT32();
246 NPStream
* pStream
= m_aNPWrapStreams
[ nFileID
];
247 sal_uInt32 nRanges
= pMessage
->GetUINT32();
248 sal_uInt32
* pArray
= (sal_uInt32
*)pMessage
->GetBytes();
249 // build ranges table
250 NPByteRange
* pFirst
= new NPByteRange
;
251 NPByteRange
* pRun
= pFirst
;
252 for( sal_uInt32 n
= 0; n
< nRanges
; n
++ )
254 pRun
->offset
= pArray
[ 2*n
];
255 pRun
->length
= pArray
[ 2*n
+1 ];
256 pRun
->next
= n
< nRanges
-1 ? new NPByteRange
: NULL
;
259 NPError aRet
= NPN_RequestRead( pStream
, pFirst
);
260 Respond( pMessage
->m_nID
, (char*)&aRet
, sizeof( aRet
), NULL
);
272 sal_uInt32 nInstance
= pMessage
->GetUINT32();
273 NPP instance
= m_aInstances
[ nInstance
]->instance
;
274 char* pString
= pMessage
->GetString();
275 NPN_Status( instance
, pString
);
281 int major
, minor
, net_major
, net_minor
;
282 NPN_Version( &major
, &minor
, &net_major
, &net_minor
);
283 Respond( pMessage
->m_nID
,
284 (char*)&major
, sizeof( int ),
285 &minor
, sizeof( int ),
286 &net_major
, sizeof( int ),
287 &net_minor
, sizeof( int ),
293 sal_uInt32 nInstance
= pMessage
->GetUINT32();
294 NPP instance
= m_aInstances
[ nInstance
]->instance
;
295 sal_uInt32 nFileID
= pMessage
->GetUINT32();
296 NPStream
* pStream
= m_aNPWrapStreams
[ nFileID
];
297 sal_Int32 nLen
= pMessage
->GetUINT32();
298 void* pBuffer
= pMessage
->GetBytes();
299 sal_Int32 nRet
= NPN_Write( instance
, pStream
, nLen
, pBuffer
);
300 Respond( pMessage
->m_nID
,
301 (char*)&nRet
, sizeof( nRet
),
303 delete [] (char*)pBuffer
;
309 sal_uInt32 nInstance
= pMessage
->GetUINT32();
310 NPP instance
= m_aInstances
[ nInstance
]->instance
;
311 const char* pAnswer
= NPN_UserAgent( instance
);
312 Respond( pMessage
->m_nID
,
313 (char*)pAnswer
, strlen( pAnswer
),
320 "caught unknown NPN request " << +nCommand
);
328 #define GET_INSTANCE() \
329 sal_uInt32 nInstance; \
330 nInstance = GetNPPID( instance );
332 #define GET_INSTANCE_RET( err ) \
334 if( nInstance == PluginConnector::UnknownNPPID ) \
338 #define POST_INSTANCE() (char*)&nInstance, sizeof( nInstance )
340 NPError
UnxPluginComm::NPP_Destroy( NPP instance
, NPSavedData
** save
)
342 NPError aRet
= NPERR_GENERIC_ERROR
;
343 GET_INSTANCE_RET( aRet
);
344 MediatorMessage
* pMes
=
345 Transact( eNPP_Destroy
,
349 return NPERR_GENERIC_ERROR
;
352 pMes
= Transact( eNPP_DestroyPhase2
,
356 return NPERR_GENERIC_ERROR
;
358 aRet
= GetNPError( pMes
);
359 sal_uLong nSaveBytes
;
360 void* pSaveData
= pMes
->GetBytes( nSaveBytes
);
361 if( nSaveBytes
== 4 && *(sal_uInt32
*)pSaveData
== 0 )
365 *save
= new NPSavedData
;
366 (*save
)->len
= nSaveBytes
;
367 (*save
)->buf
= pSaveData
;
374 NPError
UnxPluginComm::NPP_DestroyStream( NPP instance
, NPStream
* stream
, NPError reason
)
376 NPError aRet
= NPERR_GENERIC_ERROR
;
377 GET_INSTANCE_RET( aRet
);
378 sal_uInt32 nFileID
= GetStreamID( stream
);
379 if( nFileID
== PluginConnector::UnknownStreamID
)
380 return NPERR_GENERIC_ERROR
;
382 MediatorMessage
* pMes
=
383 Transact( eNPP_DestroyStream
,
385 &nFileID
, sizeof( nFileID
),
386 &reason
, sizeof( reason
),
388 m_aNPWrapStreams
.erase( m_aNPWrapStreams
.begin() + nFileID
);
390 return NPERR_GENERIC_ERROR
;
392 aRet
= GetNPError( pMes
);
397 void* UnxPluginComm::NPP_GetJavaClass()
402 NPError
UnxPluginComm::NPP_Initialize()
404 MediatorMessage
* pMes
=
405 Transact( eNPP_Initialize
,
408 return NPERR_GENERIC_ERROR
;
410 NPError aRet
= GetNPError( pMes
);
415 NPError
UnxPluginComm::NPP_New( NPMIMEType pluginType
, NPP instance
, uint16_t mode
, int16_t argc
,
416 char* argn
[], char* argv
[], NPSavedData
*saved
)
418 m_aInstances
.push_back(
419 new ConnectorInstance( instance
, pluginType
, 0,
421 saved
? (char*)saved
->buf
: NULL
,
422 saved
? saved
->len
: 0 ) );
424 char *pArgnBuf
, *pArgvBuf
;
425 size_t nArgnLen
= 0, nArgvLen
= 0;
427 for( i
= 0; i
< argc
; i
++ )
429 nArgnLen
+= strlen( argn
[i
] ) +1;
430 nArgvLen
+= strlen( argv
[i
] ) +1;
432 pArgnBuf
= new char[ nArgnLen
];
433 pArgvBuf
= new char[ nArgvLen
];
434 char* pRunArgn
= pArgnBuf
;
435 char* pRunArgv
= pArgvBuf
;
436 for( i
= 0; i
< argc
; i
++ )
438 strcpy( pRunArgn
, argn
[i
] );
439 strcpy( pRunArgv
, argv
[i
] );
440 pRunArgn
+= strlen( argn
[i
] ) +1;
441 pRunArgv
+= strlen( argv
[i
] ) +1;
444 MediatorMessage
* pMes
;
448 pluginType
, strlen( pluginType
),
449 &mode
, sizeof( mode
),
450 &argc
, sizeof( argc
),
453 saved
->buf
, static_cast<size_t>(saved
->len
),
458 pluginType
, strlen( pluginType
),
459 &mode
, sizeof( mode
),
460 &argc
, sizeof( argc
),
468 return NPERR_GENERIC_ERROR
;
470 NPError aRet
= GetNPError( pMes
);
476 NPError
UnxPluginComm::NPP_NewStream( NPP instance
, NPMIMEType type
, NPStream
* stream
,
477 NPBool seekable
, uint16_t* stype
)
479 NPError aRet
= NPERR_GENERIC_ERROR
;
480 GET_INSTANCE_RET( aRet
);
482 m_aNPWrapStreams
.push_back( stream
);
483 MediatorMessage
* pMes
=
484 Transact( eNPP_NewStream
,
486 type
, strlen( type
),
487 stream
->url
, strlen( stream
->url
),
488 &stream
->end
, sizeof( stream
->end
),
489 &stream
->lastmodified
, sizeof( stream
->lastmodified
),
490 &seekable
, sizeof( seekable
),
494 return NPERR_GENERIC_ERROR
;
496 aRet
= GetNPError( pMes
);
497 uint16_t* pSType
= (uint16_t*)pMes
->GetBytes();
505 void UnxPluginComm::NPP_Print( NPP
/*instance*/, NPPrint
* /*platformPrint*/ )
509 NPError
UnxPluginComm::NPP_SetWindow( NPP instance
, NPWindow
* window
)
511 NPError aRet
= NPERR_GENERIC_ERROR
;
512 GET_INSTANCE_RET( aRet
);
514 MediatorMessage
* pMes
=
515 Transact( eNPP_SetWindow
,
517 window
, sizeof( NPWindow
),
520 return NPERR_GENERIC_ERROR
;
522 aRet
= GetNPError( pMes
);
527 void UnxPluginComm::NPP_Shutdown()
529 Send( eNPP_Shutdown
, NULL
);
532 void UnxPluginComm::NPP_StreamAsFile( NPP instance
, NPStream
* stream
, const char* fname
)
535 sal_uInt32 nFileID
= GetStreamID( stream
);
536 if( nFileID
== PluginConnector::UnknownStreamID
)
539 Send( eNPP_StreamAsFile
,
541 &nFileID
, sizeof( nFileID
),
542 fname
, strlen( fname
),
546 void UnxPluginComm::NPP_URLNotify( NPP instance
, const char* url
, NPReason reason
, void* notifyData
)
550 Send( eNPP_URLNotify
,
553 &reason
, sizeof( reason
),
554 ¬ifyData
, sizeof( void* ),
558 int32_t UnxPluginComm::NPP_Write( NPP instance
, NPStream
* stream
, int32_t offset
, int32_t len
, void* buffer
)
560 GET_INSTANCE_RET( -1 );
561 sal_uInt32 nFileID
= GetStreamID( stream
);
562 if( nFileID
== PluginConnector::UnknownStreamID
)
565 MediatorMessage
* pMes
=
566 Transact( eNPP_Write
,
568 &nFileID
, sizeof( nFileID
),
569 &offset
, sizeof( offset
),
570 buffer
, static_cast<size_t>(len
),
575 int32_t aRet
= pMes
->GetUINT32();
581 int32_t UnxPluginComm::NPP_WriteReady( NPP instance
, NPStream
* stream
)
583 GET_INSTANCE_RET( -1 );
584 sal_uInt32 nFileID
= GetStreamID( stream
);
585 if( nFileID
== PluginConnector::UnknownStreamID
)
588 MediatorMessage
* pMes
=
589 Transact( eNPP_WriteReady
,
591 &nFileID
, sizeof( nFileID
),
597 int32_t aRet
= pMes
->GetUINT32();
603 char* UnxPluginComm::NPP_GetMIMEDescription()
605 static char* pDesc
= NULL
;
606 MediatorMessage
* pMes
=
607 Transact( eNPP_GetMIMEDescription
,
614 pDesc
= pMes
->GetString();
619 NPError
UnxPluginComm::NPP_GetValue( NPP
/*instance*/, NPPVariable
/*variable*/, void* /*value*/ )
624 NPError
UnxPluginComm::NPP_SetValue( NPP
/*instance*/, NPNVariable
/*variable*/, void* /*value*/ )
629 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */