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 <sal/log.hxx>
39 #include <vcl/svapp.hxx>
41 #include <plugin/unx/plugcon.hxx>
42 #include <plugin/impl.hxx>
44 std::vector
<PluginConnector
*> PluginConnector::allConnectors
;
46 PluginConnector::PluginConnector( int nSocket
) :
49 allConnectors
.push_back( this );
50 SetNewMessageHdl( LINK( this, PluginConnector
, NewMessageHdl
) );
53 PluginConnector::~PluginConnector()
55 osl::MutexGuard
aGuard( m_aUserEventMutex
);
56 for( std::vector
< PluginConnector
* >::iterator it
= allConnectors
.begin();
57 it
!= allConnectors
.end(); ++it
)
61 allConnectors
.erase( it
);
67 IMPL_LINK( PluginConnector
, NewMessageHdl
, Mediator
*, /*pMediator*/ )
69 osl::MutexGuard
aGuard( m_aUserEventMutex
);
71 for( std::vector
< PluginConnector
* >::iterator it
= allConnectors
.begin();
72 it
!= allConnectors
.end() && !bFound
; ++it
)
79 Application::PostUserEvent( LINK( this, PluginConnector
, WorkOnNewMessageHdl
) );
83 IMPL_LINK( PluginConnector
, WorkOnNewMessageHdl
, Mediator
*, /*pMediator*/ )
86 for( std::vector
< PluginConnector
* >::iterator it
= allConnectors
.begin();
87 it
!= allConnectors
.end() && !bFound
; ++it
)
95 MediatorMessage
* pMessage
;
96 CommandAtoms nCommand
;
97 while( (pMessage
= GetNextMessage( false )) )
99 nCommand
= (CommandAtoms
)pMessage
->GetUINT32();
100 SAL_INFO("extensions.plugin", GetCommandName(nCommand
));
105 sal_uInt32 nInstance
= pMessage
->GetUINT32();
106 NPP instance
= m_aInstances
[ nInstance
]->instance
;
107 char* pUrl
= pMessage
->GetString();
108 char* pWindow
= pMessage
->GetString();
109 NPError aRet
= NPN_GetURL( instance
, pUrl
, pWindow
);
110 Respond( pMessage
->m_nID
,
111 reinterpret_cast<char*>(&aRet
), sizeof( NPError
), NULL
);
116 case eNPN_GetURLNotify
:
118 sal_uInt32 nInstance
= pMessage
->GetUINT32();
119 NPP instance
= m_aInstances
[ nInstance
]->instance
;
120 char* pUrl
= pMessage
->GetString();
121 char* pWindow
= pMessage
->GetString();
122 void** pNotifyData
= static_cast<void**>(pMessage
->GetBytes());
123 NPError aRet
= NPN_GetURLNotify( instance
, pUrl
, pWindow
,
125 Respond( pMessage
->m_nID
,
126 reinterpret_cast<char*>(&aRet
), sizeof( NPError
), NULL
);
129 delete [] pNotifyData
;
132 case eNPN_DestroyStream
:
134 sal_uInt32 nInstance
= pMessage
->GetUINT32();
135 NPP instance
= m_aInstances
[ nInstance
]->instance
;
136 sal_uInt32 nFileID
= pMessage
->GetUINT32();
137 char* pUrl
= pMessage
->GetString();
138 NPError
* pReason
= static_cast<NPError
*>(pMessage
->GetBytes());
139 NPError aRet
= NPERR_FILE_NOT_FOUND
;
140 if( nFileID
< static_cast<sal_uInt32
>(m_aNPWrapStreams
.size()) )
142 if( ! strcmp( m_aNPWrapStreams
[ nFileID
]->url
, pUrl
) )
145 NPN_DestroyStream( instance
, m_aNPWrapStreams
[ nFileID
],
147 m_aNPWrapStreams
.erase( m_aNPWrapStreams
.begin() + nFileID
);
152 "StreamID " << nFileID
<< " has incoherent urls "
154 << m_aNPWrapStreams
[nFileID
]->url
);
159 "nonexistent StreamID " << nFileID
);
161 Respond( pMessage
->m_nID
,
162 reinterpret_cast<char*>(&aRet
), sizeof( NPError
), NULL
);
170 sal_uInt32 nInstance
= pMessage
->GetUINT32();
171 NPP instance
= m_aInstances
[ nInstance
]->instance
;
172 NPMIMEType pType
= pMessage
->GetString();
173 char* pTarget
= pMessage
->GetString();
175 NPStream
* pStream
= NULL
;
177 NPError aRet
= NPN_NewStream( instance
, pType
, pTarget
, &pStream
);
179 if( aRet
!= NPERR_NO_ERROR
)
181 sal_uInt32 nDummy
= 0;
182 Respond( pMessage
->m_nID
,
183 reinterpret_cast<char*>(&aRet
), sizeof( aRet
),
185 &nDummy
, sizeof(sal_uInt32
),
186 &nDummy
, sizeof(sal_uInt32
),
191 m_aNPWrapStreams
.push_back( pStream
);
193 sal_uLong nLen
= strlen( pStream
->url
);
194 Respond( pMessage
->m_nID
,
195 reinterpret_cast<char*>(&aRet
), sizeof( aRet
),
197 &pStream
->end
, sizeof(sal_uInt32
),
198 &pStream
->lastmodified
, sizeof(sal_uInt32
),
206 case eNPN_PostURLNotify
:
208 sal_uInt32 nInstance
= pMessage
->GetUINT32();
209 NPP instance
= m_aInstances
[ nInstance
]->instance
;
210 char* pUrl
= pMessage
->GetString();
211 char* pTarget
= pMessage
->GetString();
212 sal_uInt32 nLen
= pMessage
->GetUINT32();
213 char* pBuf
= static_cast<char*>(pMessage
->GetBytes());
214 NPBool
* pFile
= static_cast<NPBool
*>(pMessage
->GetBytes());
215 void** pNData
= static_cast<void**>(pMessage
->GetBytes());
217 NPN_PostURLNotify( instance
, pUrl
, pTarget
, nLen
, pBuf
, *pFile
, *pNData
);
218 Respond( pMessage
->m_nID
, reinterpret_cast<char*>(&aRet
), sizeof( aRet
), NULL
);
228 sal_uInt32 nInstance
= pMessage
->GetUINT32();
229 NPP instance
= m_aInstances
[ nInstance
]->instance
;
230 char* pUrl
= pMessage
->GetString();
231 char* pWindow
= pMessage
->GetString();
232 sal_uInt32 nLen
= pMessage
->GetUINT32();
233 char* pBuf
= static_cast<char*>(pMessage
->GetBytes());
234 NPBool
* pFile
= static_cast<NPBool
*>(pMessage
->GetBytes());
236 NPN_PostURL( instance
, pUrl
, pWindow
, nLen
, pBuf
, *pFile
);
237 Respond( pMessage
->m_nID
, reinterpret_cast<char*>(&aRet
), sizeof( aRet
), NULL
);
244 case eNPN_RequestRead
:
246 sal_uInt32 nFileID
= pMessage
->GetUINT32();
247 NPStream
* pStream
= m_aNPWrapStreams
[ nFileID
];
248 sal_uInt32 nRanges
= pMessage
->GetUINT32();
249 sal_uInt32
* pArray
= static_cast<sal_uInt32
*>(pMessage
->GetBytes());
250 // build ranges table
251 NPByteRange
* pFirst
= new NPByteRange
;
252 NPByteRange
* pRun
= pFirst
;
253 for( sal_uInt32 n
= 0; n
< nRanges
; n
++ )
255 pRun
->offset
= pArray
[ 2*n
];
256 pRun
->length
= pArray
[ 2*n
+1 ];
257 pRun
->next
= n
< nRanges
-1 ? new NPByteRange
: NULL
;
260 NPError aRet
= NPN_RequestRead( pStream
, pFirst
);
261 Respond( pMessage
->m_nID
, reinterpret_cast<char*>(&aRet
), sizeof( aRet
), NULL
);
273 sal_uInt32 nInstance
= pMessage
->GetUINT32();
274 NPP instance
= m_aInstances
[ nInstance
]->instance
;
275 char* pString
= pMessage
->GetString();
276 NPN_Status( instance
, pString
);
282 int major
, minor
, net_major
, net_minor
;
283 NPN_Version( &major
, &minor
, &net_major
, &net_minor
);
284 Respond( pMessage
->m_nID
,
285 reinterpret_cast<char*>(&major
), sizeof( int ),
286 &minor
, sizeof( int ),
287 &net_major
, sizeof( int ),
288 &net_minor
, sizeof( int ),
294 sal_uInt32 nInstance
= pMessage
->GetUINT32();
295 NPP instance
= m_aInstances
[ nInstance
]->instance
;
296 sal_uInt32 nFileID
= pMessage
->GetUINT32();
297 NPStream
* pStream
= m_aNPWrapStreams
[ nFileID
];
298 sal_Int32 nLen
= pMessage
->GetUINT32();
299 void* pBuffer
= pMessage
->GetBytes();
300 sal_Int32 nRet
= NPN_Write( instance
, pStream
, nLen
, pBuffer
);
301 Respond( pMessage
->m_nID
,
302 reinterpret_cast<char*>(&nRet
), sizeof( nRet
),
304 delete [] static_cast<char*>(pBuffer
);
310 sal_uInt32 nInstance
= pMessage
->GetUINT32();
311 NPP instance
= m_aInstances
[ nInstance
]->instance
;
312 const char* pAnswer
= NPN_UserAgent( instance
);
313 Respond( pMessage
->m_nID
,
314 const_cast<char*>(pAnswer
), strlen( pAnswer
),
321 "caught unknown NPN request " << +nCommand
);
329 #define GET_INSTANCE() \
330 sal_uInt32 nInstance; \
331 nInstance = GetNPPID( instance );
333 #define GET_INSTANCE_RET( err ) \
335 if( nInstance == PluginConnector::UnknownNPPID ) \
339 #define POST_INSTANCE() reinterpret_cast<char*>(&nInstance), sizeof( nInstance )
341 NPError
UnxPluginComm::NPP_Destroy( NPP instance
, NPSavedData
** save
)
343 NPError aRet
= NPERR_GENERIC_ERROR
;
344 GET_INSTANCE_RET( aRet
);
345 MediatorMessage
* pMes
=
346 Transact( eNPP_Destroy
,
350 return NPERR_GENERIC_ERROR
;
353 pMes
= Transact( eNPP_DestroyPhase2
,
357 return NPERR_GENERIC_ERROR
;
359 aRet
= GetNPError( pMes
);
360 sal_uLong nSaveBytes
;
361 void* pSaveData
= pMes
->GetBytes( nSaveBytes
);
362 if( nSaveBytes
== 4 && *static_cast<sal_uInt32
*>(pSaveData
) == 0 )
366 *save
= new NPSavedData
;
367 (*save
)->len
= nSaveBytes
;
368 (*save
)->buf
= pSaveData
;
375 NPError
UnxPluginComm::NPP_DestroyStream( NPP instance
, NPStream
* stream
, NPError reason
)
377 NPError aRet
= NPERR_GENERIC_ERROR
;
378 GET_INSTANCE_RET( aRet
);
379 sal_uInt32 nFileID
= GetStreamID( stream
);
380 if( nFileID
== PluginConnector::UnknownStreamID
)
381 return NPERR_GENERIC_ERROR
;
383 MediatorMessage
* pMes
=
384 Transact( eNPP_DestroyStream
,
386 &nFileID
, sizeof( nFileID
),
387 &reason
, sizeof( reason
),
389 m_aNPWrapStreams
.erase( m_aNPWrapStreams
.begin() + nFileID
);
391 return NPERR_GENERIC_ERROR
;
393 aRet
= GetNPError( pMes
);
398 void* UnxPluginComm::NPP_GetJavaClass()
403 NPError
UnxPluginComm::NPP_Initialize()
405 MediatorMessage
* pMes
=
406 Transact( eNPP_Initialize
,
409 return NPERR_GENERIC_ERROR
;
411 NPError aRet
= GetNPError( pMes
);
416 NPError
UnxPluginComm::NPP_New( NPMIMEType pluginType
, NPP instance
, uint16_t mode
, int16_t argc
,
417 char* argn
[], char* argv
[], NPSavedData
*saved
)
419 m_aInstances
.push_back(
420 new ConnectorInstance( instance
, pluginType
, 0,
422 saved
? static_cast<char*>(saved
->buf
) : NULL
,
423 saved
? saved
->len
: 0 ) );
425 char *pArgnBuf
, *pArgvBuf
;
426 size_t nArgnLen
= 0, nArgvLen
= 0;
428 for( i
= 0; i
< argc
; i
++ )
430 nArgnLen
+= strlen( argn
[i
] ) +1;
431 nArgvLen
+= strlen( argv
[i
] ) +1;
433 pArgnBuf
= new char[ nArgnLen
];
434 pArgvBuf
= new char[ nArgvLen
];
435 char* pRunArgn
= pArgnBuf
;
436 char* pRunArgv
= pArgvBuf
;
437 for( i
= 0; i
< argc
; i
++ )
439 strcpy( pRunArgn
, argn
[i
] );
440 strcpy( pRunArgv
, argv
[i
] );
441 pRunArgn
+= strlen( argn
[i
] ) +1;
442 pRunArgv
+= strlen( argv
[i
] ) +1;
445 MediatorMessage
* pMes
;
449 pluginType
, strlen( pluginType
),
450 &mode
, sizeof( mode
),
451 &argc
, sizeof( argc
),
454 saved
->buf
, static_cast<size_t>(saved
->len
),
459 pluginType
, strlen( pluginType
),
460 &mode
, sizeof( mode
),
461 &argc
, sizeof( argc
),
469 return NPERR_GENERIC_ERROR
;
471 NPError aRet
= GetNPError( pMes
);
477 NPError
UnxPluginComm::NPP_NewStream( NPP instance
, NPMIMEType type
, NPStream
* stream
,
478 NPBool seekable
, uint16_t* stype
)
480 NPError aRet
= NPERR_GENERIC_ERROR
;
481 GET_INSTANCE_RET( aRet
);
483 m_aNPWrapStreams
.push_back( stream
);
484 MediatorMessage
* pMes
=
485 Transact( eNPP_NewStream
,
487 type
, strlen( type
),
488 stream
->url
, strlen( stream
->url
),
489 &stream
->end
, sizeof( stream
->end
),
490 &stream
->lastmodified
, sizeof( stream
->lastmodified
),
491 &seekable
, sizeof( seekable
),
495 return NPERR_GENERIC_ERROR
;
497 aRet
= GetNPError( pMes
);
498 uint16_t* pSType
= static_cast<uint16_t*>(pMes
->GetBytes());
506 void UnxPluginComm::NPP_Print( NPP
/*instance*/, NPPrint
* /*platformPrint*/ )
510 NPError
UnxPluginComm::NPP_SetWindow( NPP instance
, NPWindow
* window
)
512 NPError aRet
= NPERR_GENERIC_ERROR
;
513 GET_INSTANCE_RET( aRet
);
515 MediatorMessage
* pMes
=
516 Transact( eNPP_SetWindow
,
518 window
, sizeof( NPWindow
),
521 return NPERR_GENERIC_ERROR
;
523 aRet
= GetNPError( pMes
);
528 void UnxPluginComm::NPP_Shutdown()
530 Send( eNPP_Shutdown
, NULL
);
533 void UnxPluginComm::NPP_StreamAsFile( NPP instance
, NPStream
* stream
, const char* fname
)
536 sal_uInt32 nFileID
= GetStreamID( stream
);
537 if( nFileID
== PluginConnector::UnknownStreamID
)
540 Send( eNPP_StreamAsFile
,
542 &nFileID
, sizeof( nFileID
),
543 fname
, strlen( fname
),
547 void UnxPluginComm::NPP_URLNotify( NPP instance
, const char* url
, NPReason reason
, void* notifyData
)
551 Send( eNPP_URLNotify
,
554 &reason
, sizeof( reason
),
555 ¬ifyData
, sizeof( void* ),
559 int32_t UnxPluginComm::NPP_Write( NPP instance
, NPStream
* stream
, int32_t offset
, int32_t len
, void* buffer
)
561 GET_INSTANCE_RET( -1 );
562 sal_uInt32 nFileID
= GetStreamID( stream
);
563 if( nFileID
== PluginConnector::UnknownStreamID
)
566 MediatorMessage
* pMes
=
567 Transact( eNPP_Write
,
569 &nFileID
, sizeof( nFileID
),
570 &offset
, sizeof( offset
),
571 buffer
, static_cast<size_t>(len
),
576 int32_t aRet
= pMes
->GetUINT32();
582 int32_t UnxPluginComm::NPP_WriteReady( NPP instance
, NPStream
* stream
)
584 GET_INSTANCE_RET( -1 );
585 sal_uInt32 nFileID
= GetStreamID( stream
);
586 if( nFileID
== PluginConnector::UnknownStreamID
)
589 MediatorMessage
* pMes
=
590 Transact( eNPP_WriteReady
,
592 &nFileID
, sizeof( nFileID
),
598 int32_t aRet
= pMes
->GetUINT32();
604 NPError
UnxPluginComm::NPP_GetValue( NPP
/*instance*/, NPPVariable
/*variable*/, void* /*value*/ )
609 NPError
UnxPluginComm::NPP_SetValue( NPP
/*instance*/, NPNVariable
/*variable*/, void* /*value*/ )
614 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */