diff options
author | Philipp Lohmann <pl@openoffice.org> | 2001-10-23 16:31:20 +0000 |
---|---|---|
committer | Philipp Lohmann <pl@openoffice.org> | 2001-10-23 16:31:20 +0000 |
commit | 50baf21528dfa8238b18da217eaa745e0344082a (patch) | |
tree | 61e513485740f4f067345eee2cab40a9891937da /extensions/source | |
parent | d80064e3ae94899765e8a61b0fe6057b15addbe2 (diff) |
#92403# move plugins into own executable like SO5.2
Diffstat (limited to 'extensions/source')
-rw-r--r-- | extensions/source/plugin/base/nfuncs.cxx | 28 | ||||
-rw-r--r-- | extensions/source/plugin/base/xplugin.cxx | 34 | ||||
-rw-r--r-- | extensions/source/plugin/inc/plugin/impl.hxx | 13 | ||||
-rw-r--r-- | extensions/source/plugin/inc/plugin/unx/mediator.hxx | 229 | ||||
-rw-r--r-- | extensions/source/plugin/inc/plugin/unx/plugcon.hxx | 226 | ||||
-rw-r--r-- | extensions/source/plugin/inc/plugin/unx/sysplug.hxx | 31 | ||||
-rw-r--r-- | extensions/source/plugin/unx/makefile.mk | 24 | ||||
-rw-r--r-- | extensions/source/plugin/unx/mediator.cxx | 308 | ||||
-rw-r--r-- | extensions/source/plugin/unx/npnapi.cxx | 686 | ||||
-rw-r--r-- | extensions/source/plugin/unx/nppapi.cxx | 576 | ||||
-rw-r--r-- | extensions/source/plugin/unx/npwrap.cxx | 242 | ||||
-rw-r--r-- | extensions/source/plugin/unx/plugcon.cxx | 253 | ||||
-rw-r--r-- | extensions/source/plugin/unx/sysplug.cxx | 254 | ||||
-rw-r--r-- | extensions/source/plugin/unx/unxmgr.cxx | 142 |
14 files changed, 2719 insertions, 327 deletions
diff --git a/extensions/source/plugin/base/nfuncs.cxx b/extensions/source/plugin/base/nfuncs.cxx index 847d34928..0abc781c7 100644 --- a/extensions/source/plugin/base/nfuncs.cxx +++ b/extensions/source/plugin/base/nfuncs.cxx @@ -2,9 +2,9 @@ * * $RCSfile: nfuncs.cxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: pl $ $Date: 2000-12-07 19:29:01 $ + * last change: $Author: pl $ $Date: 2001-10-23 17:31:19 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -501,30 +501,6 @@ NPError SAL_CALL NP_LOADDS NPN_GetValue( NPP instance, NPNVariable variable, vo TRACE( "NPN_GetValue" ); XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance ); -#ifdef UNX - // some special unix variables - XPlugin_Impl* pInstance = pImpl ? pImpl : XPluginManager_Impl::getFirstXPlugin(); - if( ! pInstance ) - return NULL; - - switch( variable ) - { - case NPNVxDisplay: - *((Display**)value) = pInstance->getAppDisplay(); -#ifdef DEBUG - fprintf( stderr, "NPN_GetValue of display\n" ); -#endif - return NPERR_NO_ERROR; - break; - case NPNVxtAppContext: - *((XtAppContext*)value) = pInstance->getAppContext(); -#ifdef DEBUG - fprintf( stderr, "NPN_GetValue of application context\n" ); -#endif - return NPERR_NO_ERROR; - } -#endif - if( ! pImpl ) return 0; diff --git a/extensions/source/plugin/base/xplugin.cxx b/extensions/source/plugin/base/xplugin.cxx index eb71a751d..8a037e5e5 100644 --- a/extensions/source/plugin/base/xplugin.cxx +++ b/extensions/source/plugin/base/xplugin.cxx @@ -2,9 +2,9 @@ * * $RCSfile: xplugin.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: pl $ $Date: 2001-09-11 12:06:16 $ + * last change: $Author: pl $ $Date: 2001-10-23 17:31:19 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -80,6 +80,11 @@ #include <vcl/svapp.hxx> #include <vos/timer.hxx> +#ifdef UNX +#include <sys/types.h> +#include <sys/socket.h> +#endif + #ifdef DEBUG #include <stdio.h> #endif @@ -147,11 +152,6 @@ XPlugin_Impl::XPlugin_Impl( const Reference< ::com::sun::star::lang::XMultiServi { memset( &m_aInstance, 0, sizeof( m_aInstance ) ); memset( &m_aNPWindow, 0, sizeof( m_aNPWindow ) ); -#ifdef UNX - m_aAppContext = NULL; - m_pDisplay = NULL; - memset( &m_aWSInfo, 0, sizeof( m_aWSInfo ) ); -#endif m_xModel = new PluginModel(); Reference< ::com::sun::star::beans::XPropertySet > xPS( m_xModel, UNO_QUERY ); @@ -428,10 +428,16 @@ void XPlugin_Impl::loadPlugin() if( ! getPluginComm() ) { #ifdef UNX - m_pDisplay = (Display*)pEnvData->pDisplay; - m_aAppContext = (XtAppContext)pEnvData->pAppContext; // need a new PluginComm - PluginComm* pComm = new UnxPluginComm( ::rtl::OUStringToOString( m_aDescription.PluginName, gsl_getSystemTextEncoding() ) ); + PluginComm* pComm = NULL; + int sv[2]; + if( !socketpair( AF_UNIX, SOCK_STREAM, 0, sv ) ) + pComm = new UnxPluginComm( m_aDescription.Mimetype, + m_aDescription.PluginName, + (XLIB_Window)pEnvData->aWindow, + sv[0], + sv[1] + ); #elif (defined WNT || defined OS2) PluginComm* pComm = new PluginComm_Impl( m_aDescription.Mimetype, m_aDescription.PluginName, @@ -455,13 +461,7 @@ void XPlugin_Impl::loadPlugin() #endif #ifdef UNX m_aNPWindow.window = (void*)pEnvData->aWindow; - m_aNPWindow.ws_info = &m_aWSInfo; - - m_aWSInfo.type = NP_SETWINDOW; - m_aWSInfo.display = (Display*)pEnvData->pDisplay; - m_aWSInfo.visual = (Visual*)pEnvData->pVisual; - m_aWSInfo.colormap = (Colormap)pEnvData->aColormap; - m_aWSInfo.depth = pEnvData->nDepth; + m_aNPWindow.ws_info = NULL; #else m_aNPWindow.window = (void*)pEnvData->hWnd; #endif diff --git a/extensions/source/plugin/inc/plugin/impl.hxx b/extensions/source/plugin/inc/plugin/impl.hxx index 6b6bf96b9..94b0ca835 100644 --- a/extensions/source/plugin/inc/plugin/impl.hxx +++ b/extensions/source/plugin/inc/plugin/impl.hxx @@ -2,9 +2,9 @@ * * $RCSfile: impl.hxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: pl $ $Date: 2001-09-11 12:06:16 $ + * last change: $Author: pl $ $Date: 2001-10-23 17:31:19 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -202,11 +202,6 @@ private: NPP_t m_aInstance; NPWindow m_aNPWindow; rtl_TextEncoding m_aEncoding; -#ifdef UNX - NPSetWindowCallbackStruct m_aWSInfo; - Display* m_pDisplay; - XtAppContext m_aAppContext; -#endif const char** m_pArgv; const char** m_pArgn; @@ -252,10 +247,6 @@ public: m_pPluginComm->addRef(); } } -#ifdef UNX - Display* getAppDisplay() { return m_pDisplay; } - XtAppContext getAppContext() { return m_aAppContext; } -#endif Reference< ::com::sun::star::lang::XMultiServiceFactory > getServiceManager() { return m_xSMgr; } rtl_TextEncoding getTextEncoding() { return m_aEncoding; } NPP getNPPInstance() { return &m_aInstance; } diff --git a/extensions/source/plugin/inc/plugin/unx/mediator.hxx b/extensions/source/plugin/inc/plugin/unx/mediator.hxx new file mode 100644 index 000000000..3f546e44f --- /dev/null +++ b/extensions/source/plugin/inc/plugin/unx/mediator.hxx @@ -0,0 +1,229 @@ +/************************************************************************* + * + * $RCSfile: mediator.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: pl $ $Date: 2001-10-23 17:31:20 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _MEDIATOR_HXX +#define _MEDIATOR_HXX + +#include <string.h> +#include <stdarg.h> + +#ifndef _STRING_HXX +#include <tools/string.hxx> +#endif +#ifndef _LIST_HXX +#include <tools/list.hxx> +#endif +#ifndef _LINK_HXX +#include <tools/link.hxx> +#endif +#ifndef _VOS_PIPE_HXX_ +#include <vos/pipe.hxx> +#endif +#ifndef _VOS_MUTEX_HXX_ +#include <vos/mutex.hxx> +#endif +#ifndef _VOS_CONDITN_HXX_ +#include <vos/conditn.hxx> +#endif +#ifndef _VOS_THREAD_HXX_ +#include <vos/thread.hxx> +#endif +#ifdef DEBUG +#include <stdio.h> +#endif + +struct MediatorMessage +{ + ULONG m_nID; + ULONG m_nBytes; + char* m_pBytes; + char* m_pRun; + + MediatorMessage() : m_nID( 0 ), m_nBytes( 0 ), + m_pBytes( NULL ), m_pRun( NULL ) {} + MediatorMessage( ULONG nID, ULONG nBytes, char* pBytes ) : + m_nID( nID ),m_nBytes( nBytes ), m_pRun( NULL ) + { + m_pBytes = new char[ m_nBytes ]; + memcpy( m_pBytes, pBytes, (size_t)m_nBytes ); + } + + ~MediatorMessage() + { + if( m_pBytes ) + delete m_pBytes; + } + + void Set( ULONG nBytes, char* pBytes ) + { + if( m_pBytes ) + delete m_pBytes; + m_nBytes = nBytes; + m_pBytes = new char[ m_nBytes ]; + memcpy( m_pBytes, pBytes, (size_t)m_nBytes ); + } + + ULONG ExtractULONG(); + char* GetString(); + UINT32 GetUINT32(); + void* GetBytes( ULONG& ); + void* GetBytes() { ULONG nBytes; return GetBytes( nBytes ); } + + void Rewind() { m_pRun = NULL; } +}; + +DECLARE_LIST( MediatorMessageList, MediatorMessage* ); + +class MediatorListener; + +class Mediator +{ + friend class MediatorListener; +protected: + int m_nSocket; + + MediatorMessageList m_aMessageQueue; + NAMESPACE_VOS(OMutex) m_aQueueMutex; + NAMESPACE_VOS(OMutex) m_aSendMutex; + // only one thread can send a message at any given time + NAMESPACE_VOS(OCondition) m_aNewMessageCdtn; + MediatorListener* m_pListener; + // thread to fill the queue + + ULONG m_nCurrentID; + // will be constantly increased with each message sent + bool m_bValid; + + Link m_aConnectionLostHdl; + Link m_aNewMessageHdl; +public: + Mediator( int nSocket ); + ~Mediator(); + + // mark mediator as invalid. No more messages will be processed, + // SendMessage, WaitForMessage, TransactMessage will return immediatly + // with error + void invalidate() { m_bValid = false; } + + ULONG SendMessage( ULONG nBytes, const char* pBytes, ULONG nMessageID = 0 ); + ULONG SendMessage( const ByteString& rMessage, ULONG nMessageID = 0 ) + { + return SendMessage( rMessage.Len(), rMessage.GetBuffer(), nMessageID ); + } + + BOOL WaitForMessage( ULONG nTimeOut = 5000 ); + // timeout in ms + // TRUE: Message came in + // FALSE: timed out + // if timeout is set, WaitForMessage will wait even if there are messages + // in the queue + + virtual MediatorMessage* WaitForAnswer( ULONG nMessageID ); + // wait for an answer message ( ID >= 1 << 24 ) + // the message will be removed from the queue and returned + + MediatorMessage* TransactMessage( ULONG nBytes, char* pBytes ); + // sends a message and waits for an answer + + MediatorMessage* GetNextMessage( BOOL bWait = FALSE ); + + + Link SetConnectionLostHdl( const Link& rLink ) + { + Link aRet = m_aConnectionLostHdl; + m_aConnectionLostHdl = rLink; + return aRet; + } + + Link SetNewMessageHdl( const Link& rLink ) + { + Link aRet = m_aNewMessageHdl; + m_aNewMessageHdl = rLink; + return aRet; + } +}; + +class MediatorListener : public NAMESPACE_VOS( OThread ) +{ + friend class Mediator; + private: + Mediator* m_pMediator; + + MediatorListener( Mediator* ); + ~MediatorListener(); + + virtual void run(); + virtual void onTerminated(); +}; + +inline void medDebug( int condition, char* pFormat, ... ) +{ +#if defined DEBUG + if( condition ) + { + va_list ap; + va_start( ap, pFormat ); + vfprintf( stderr, pFormat, ap ); + va_end( ap ); + } +#endif +} + +#endif // _MEDIATOR_HXX diff --git a/extensions/source/plugin/inc/plugin/unx/plugcon.hxx b/extensions/source/plugin/inc/plugin/unx/plugcon.hxx new file mode 100644 index 000000000..ce19ea029 --- /dev/null +++ b/extensions/source/plugin/inc/plugin/unx/plugcon.hxx @@ -0,0 +1,226 @@ +/************************************************************************* + * + * $RCSfile: plugcon.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: pl $ $Date: 2001-10-23 17:31:20 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _PLUGCON_HXX +#define _PLUGCON_HXX + +#include <stdarg.h> +#include <string.h> + +#include <stl/list> + +#ifndef _LIST_HXX +#include <tools/list.hxx> +#endif + +#ifndef _MEDIATOR_HXX +#include <plugin/unx/mediator.hxx> +#endif + +#if defined SOLARIS +#define USE_MOTIF +#endif + +#define Window XLIB_Window +#define Font XLIB_Font +#define KeyCode XLIB_KeyCode +#define Time XLIB_Time +#define Cursor XLIB_Cursor +#define Region XLIB_Region +#define String XLIB_String +#define Boolean XLIB_Boolean +#define XPointer XLIB_XPointer +#include <X11/Xlib.h> +#include <X11/Intrinsic.h> +#include <X11/Shell.h> +#include <X11/IntrinsicP.h> /* Intrinsics Definitions*/ +#include <X11/StringDefs.h> /* Standard Name-String definitions*/ +#if defined USE_MOTIF +#include <Xm/DrawingA.h> +#else +#include <X11/Xaw/Label.h> +#endif +#include <X11/Xatom.h> +#define XP_UNIX +#ifndef _NPAPI_H_ +#include <npsdk/npupp.h> +#include <npsdk/npapi.h> +#endif +#undef Window +#undef Font +#undef KeyCode +#undef Time +#undef Cursor +#undef String +#undef Region +#undef Boolean +#undef XPointer + +class ConnectorInstance +{ +public: + NPP instance; + NPWindow window; + NPSetWindowCallbackStruct ws_info; + char* pMimeType; + void* pShell; + void* pWidget; + + int nArg; + char** argn; + char** argv; + char* pArgnBuf; + char* pArgvBuf; + NPSavedData aData; + + ConnectorInstance( NPP inst, char* type, + int args, char* pargnbuf, ULONG nargnbytes, + char* pargvbuf, ULONG nargvbytes, + char* savedata, ULONG savebytes ); + ~ConnectorInstance(); +}; + +class PluginConnector; + +DECLARE_LIST( NPStreamList, NPStream* ); +DECLARE_LIST( InstanceList, ConnectorInstance* ); +DECLARE_LIST( PluginConnectorList, PluginConnector* ); + +class PluginConnector : public Mediator +{ + friend NPError NPN_DestroyStream( NPP, NPStream*, NPError ); + friend NPError NPN_NewStream( NPP, NPMIMEType, const char*, + NPStream** ); +protected: + NAMESPACE_VOS(OMutex) m_aUserEventMutex; + + static PluginConnectorList allConnectors; + + DECL_LINK( NewMessageHdl, Mediator* ); + DECL_LINK( WorkOnNewMessageHdl, Mediator* ); + + NPStreamList m_aNPWrapStreams; + InstanceList m_aInstances; + + ULONG FillBuffer( char*&, char*, ULONG, va_list ); +public: + PluginConnector( int nSocket ); + ~PluginConnector(); + + virtual MediatorMessage* WaitForAnswer( ULONG nMessageID ); + MediatorMessage* Transact( char*, ULONG, ... ); + MediatorMessage* Transact( UINT32, ... ); + void Respond( ULONG nID, char*, ULONG, ... ); + ULONG Send( UINT32, ... ); + + UINT32 GetStreamID( NPStream* pStream ); + UINT32 GetNPPID( NPP ); + + NPError GetNPError( MediatorMessage* pMes ) + { + NPError* pErr = (NPError*)pMes->GetBytes(); + NPError aErr = *pErr; + delete pErr; + return aErr; + } + + void CallWorkHandler() + { + LINK( this, PluginConnector, WorkOnNewMessageHdl ). + Call( (Mediator*)this ); + } +}; + +enum CommandAtoms +{ + eNPN_GetURL, + eNPN_GetURLNotify, + eNPN_DestroyStream, + eNPN_NewStream, + eNPN_PostURLNotify, + eNPN_PostURL, + eNPN_RequestRead, + eNPN_Status, + eNPN_Version, + eNPN_Write, + eNPN_UserAgent, + + eNPP_DestroyStream, + eNPP_Destroy, + eNPP_NewStream, + eNPP_New, + eNPP_SetWindow, + eNPP_StreamAsFile, + eNPP_URLNotify, + eNPP_WriteReady, + eNPP_Write, + eNPP_GetMIMEDescription, + eNPP_Initialize, + eNPP_Shutdown, + + eMaxCommand +}; + +char* GetCommandName( CommandAtoms ); +void resizePlugin( NPP, UINT32, UINT32 ); + +#define POST_STRING( x ) x ? x : "", x ? strlen(x) : 1 + +#endif // _PLUGCON_HXX diff --git a/extensions/source/plugin/inc/plugin/unx/sysplug.hxx b/extensions/source/plugin/inc/plugin/unx/sysplug.hxx index db7a8ea95..9d3906325 100644 --- a/extensions/source/plugin/inc/plugin/unx/sysplug.hxx +++ b/extensions/source/plugin/inc/plugin/unx/sysplug.hxx @@ -2,9 +2,9 @@ * * $RCSfile: sysplug.hxx,v $ * - * $Revision: 1.1.1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: hr $ $Date: 2000-09-18 16:16:51 $ + * last change: $Author: pl $ $Date: 2001-10-23 17:31:20 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -61,31 +61,31 @@ #ifndef __PLUGIN_INC_UNXPLUG_HXX #define __PLUGIN_INC_UNXPLUG_HXX -#include <cstdio> - -#include <prex.h> -#define XP_UNIX -#include <npsdk/npupp.h> -#include <npsdk/npapi.h> -#include <postx.h> +#include <unistd.h> +#include <plugin/unx/plugcon.hxx> #include <plugin/plcom.hxx> #include <vcl/sysdata.hxx> -class UnxPluginComm : public PluginComm +class UnxPluginComm : public PluginComm, public PluginConnector { private: - void* m_pLibrary; - NPPluginFuncs m_aFuncs; - BOOL m_bInit; + static int nConnCounter; + + pid_t m_nCommPID; public: - UnxPluginComm( const ::rtl::OString& library ); + UnxPluginComm( const String& mimetype, + const String& library, + XLIB_Window aParent, + int nDescriptor1, + int nDescriptor2 + ); virtual ~UnxPluginComm(); virtual NPError NPP_Destroy( NPP instance, NPSavedData** save ); virtual NPError NPP_DestroyStream( NPP instance, NPStream* stream, NPError reason ); - virtual void* NPP_GetJavaClass(); + virtual jref NPP_GetJavaClass(); virtual NPError NPP_Initialize(); virtual NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, @@ -103,6 +103,7 @@ public: virtual int32 NPP_Write( NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer ); virtual int32 NPP_WriteReady( NPP instance, NPStream* stream ); + virtual char* NPP_GetMIMEDescription(); virtual NPError NPP_GetValue( NPP instance, NPPVariable variable, void* value ); virtual NPError NPP_SetValue( NPP instance, NPNVariable variable, void *value); diff --git a/extensions/source/plugin/unx/makefile.mk b/extensions/source/plugin/unx/makefile.mk index 58a4c2353..822111230 100644 --- a/extensions/source/plugin/unx/makefile.mk +++ b/extensions/source/plugin/unx/makefile.mk @@ -2,9 +2,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.1.1.1 $ +# $Revision: 1.2 $ # -# last change: $Author: hr $ $Date: 2000-09-18 16:16:51 $ +# last change: $Author: pl $ $Date: 2001-10-23 17:31:20 $ # # The Contents of this file are made available subject to the terms of # either of the following licenses @@ -70,9 +70,29 @@ TARGETTYPE=CUI # --- Files -------------------------------------------------------- SLOFILES=\ + $(SLO)$/nppapi.obj \ $(SLO)$/sysplug.obj \ + $(SLO)$/mediator.obj \ + $(SLO)$/plugcon.obj \ $(SLO)$/unxmgr.obj +OBJFILES=\ + $(OBJ)$/npwrap.obj \ + $(OBJ)$/npnapi.obj \ + $(OBJ)$/mediator.obj \ + $(OBJ)$/plugcon.obj + +APP1TARGET=pluginapp.bin +APP1OBJS=$(OBJFILES) +APP1STDLIBS=\ + $(TOOLSLIB) \ + $(VOSLIB) \ + $(SALLIB) +.IF "$(OS)"=="SOLARIS" || "$(OS)"=="SCO" || "$(OS)"=="HPUX" +APP1STDLIBS+=-lXm -lXt -lX11 -ldl +.ELSE +APP1STDLIBS+=-lXaw -lXt -lX11 -ldl +.ENDIF APP1DEF= $(MISC)$/$(TARGET).def diff --git a/extensions/source/plugin/unx/mediator.cxx b/extensions/source/plugin/unx/mediator.cxx new file mode 100644 index 000000000..679bac280 --- /dev/null +++ b/extensions/source/plugin/unx/mediator.cxx @@ -0,0 +1,308 @@ +/************************************************************************* + * + * $RCSfile: mediator.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: pl $ $Date: 2001-10-23 17:31:20 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <errno.h> +#include <unistd.h> + +#include <plugin/unx/mediator.hxx> +#include <vcl/svapp.hxx> + +Mediator::Mediator( int nSocket ) : + m_nSocket( nSocket ), + m_pListener( NULL ), + m_nCurrentID( 1 ), + m_bValid( true ) +{ + m_pListener = new MediatorListener( this ); + m_pListener->create(); +} + +Mediator::~Mediator() +{ + if( m_pListener ) + { + m_pListener->m_pMediator = NULL; + m_pListener = NULL; + if( m_bValid ) + { + ULONG aHeader[2]; + aHeader[0] = 0; + aHeader[1] = 0; + write( m_nSocket, aHeader, sizeof( aHeader ) ); + } + // kick the thread out of its run method; it deletes itself + close( m_nSocket ); + } + else + close( m_nSocket ); + while( m_aMessageQueue.Count() ) + delete m_aMessageQueue.Remove( (ULONG)0 ); +} + + +ULONG Mediator::SendMessage( ULONG nBytes, const char* pBytes, ULONG nMessageID ) +{ + NAMESPACE_VOS(OGuard) aGuard( m_aSendMutex ); + if( ! nMessageID ) + nMessageID = m_nCurrentID; + + m_nCurrentID++; + if( m_nCurrentID >= 1 << 24 ) // protection against overflow + m_nCurrentID = 1; + + if( ! m_bValid ) + return nMessageID; + + ULONG* pBuffer = new ULONG[ (nBytes/sizeof(ULONG)) + 3 ]; + pBuffer[ 0 ] = nMessageID; + pBuffer[ 1 ] = nBytes; + memcpy( &pBuffer[2], pBytes, (size_t)nBytes ); + write( m_nSocket, pBuffer, nBytes + 2*sizeof( ULONG ) ); + delete pBuffer; + + return nMessageID; +} + +BOOL Mediator::WaitForMessage( ULONG nTimeOut ) +{ + int nItems = m_aMessageQueue.Count(); + + if( ! nTimeOut && nItems > 0 ) + return TRUE; + + TimeValue aValue; + aValue.Seconds = nTimeOut/1000; + aValue.Nanosec = ( nTimeOut % 1000 ) * 1000; + + while( m_aMessageQueue.Count() == nItems ) + { + m_aNewMessageCdtn.wait( & aValue ); + m_aNewMessageCdtn.reset(); + if( nTimeOut && m_aMessageQueue.Count() == nItems ) + return FALSE; + } + return TRUE; +} + +MediatorMessage* Mediator::WaitForAnswer( ULONG nMessageID ) +{ + nMessageID &= 0x00ffffff; + while( m_pListener ) + { + { + NAMESPACE_VOS(OGuard) aGuard( m_aQueueMutex ); + for( int i = 0; i < m_aMessageQueue.Count(); i++ ) + { + ULONG nID = m_aMessageQueue.GetObject( i )->m_nID; + if( ( nID & 0xff000000 ) && + ( ( nID & 0x00ffffff ) == nMessageID ) ) + return m_aMessageQueue.Remove( i ); + } + } + WaitForMessage( 10 ); + } + return NULL; +} + +MediatorMessage* Mediator::GetNextMessage( BOOL bWait ) +{ + while( 1 ) + { + { + // guard must be after WaitForMessage, else the listener + // cannot insert a new one -> deadlock + NAMESPACE_VOS(OGuard) aGuard( m_aQueueMutex ); + for( int i = 0; i < m_aMessageQueue.Count(); i++ ) + if( ! ( m_aMessageQueue.GetObject( i )->m_nID & 0xff000000 ) ) + return m_aMessageQueue.Remove( i ); + if( ! bWait ) + return NULL; + } + WaitForMessage(); + } +} + +MediatorMessage* Mediator::TransactMessage( ULONG nBytes, char* pBytes ) +{ + ULONG nID = SendMessage( nBytes, pBytes ); + return WaitForAnswer( nID ); +} + +MediatorListener::MediatorListener( Mediator* pMediator ) : + m_pMediator( pMediator ) +{ +} + +MediatorListener::~MediatorListener() +{ +} + +void MediatorListener::run() +{ + while( schedule() && m_pMediator ) + { + ULONG nHeader[ 2 ]; + int nBytes; + + if( m_pMediator && ( nBytes = read( m_pMediator->m_nSocket, nHeader, sizeof( nHeader ) ) ) == sizeof( nHeader ) ) + { + if( nHeader[ 0 ] == 0 && nHeader[ 1 ] == 0 ) + return; + char* pBuffer = new char[ nHeader[ 1 ] ]; + if( m_pMediator && read( m_pMediator->m_nSocket, pBuffer, nHeader[ 1 ] ) == nHeader[ 1 ] ) + { + { + NAMESPACE_VOS(OGuard) + aGuard( m_pMediator->m_aQueueMutex ); + MediatorMessage* pMessage = + new MediatorMessage( nHeader[ 0 ], nHeader[ 1 ], pBuffer ); + m_pMediator->m_aMessageQueue.Insert( pMessage, LIST_APPEND ); + } + m_pMediator->m_aNewMessageCdtn.set(); + m_pMediator->m_aNewMessageHdl.Call( m_pMediator ); + } + else + medDebug( 1, "got incomplete MediatorMessage: { %d, %d, %*s }\n", + nHeader[0], nHeader[1], nHeader[1], pBuffer ); + delete pBuffer; + } + else + { + medDebug( 1, "got incomplete message header of %d bytes ( nHeader = [ %u, %u ] ), errno is %d\n", + nBytes, nHeader[ 0 ], nHeader[ 1 ], (int)errno ); + break; + } + } +} + +void MediatorListener::onTerminated() +{ + if( m_pMediator ) + { + m_pMediator->m_aConnectionLostHdl.Call( m_pMediator ); + m_pMediator->m_pListener = NULL; + } + delete this; +} + +ULONG MediatorMessage::ExtractULONG() +{ + if( ! m_pRun ) + m_pRun = m_pBytes; + + medDebug( (ULONG)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::ExtractULONG\n" ); + ULONG nCount; + memcpy( &nCount, m_pRun, sizeof( ULONG ) ); + m_pRun += sizeof( ULONG ); + return nCount; +} + +void* MediatorMessage::GetBytes( ULONG& rBytes ) +{ + if( ! m_pRun ) + m_pRun = m_pBytes; + + medDebug( (ULONG)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetBytes\n" ); + ULONG nBytes = ExtractULONG(); + + if( nBytes == 0 ) + return NULL; + + medDebug( (ULONG)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetBytes\n" ); + char* pBuffer = new char[ nBytes ]; + memcpy( pBuffer, m_pRun, nBytes ); + m_pRun += nBytes; + rBytes = nBytes; + return pBuffer; +} + +char* MediatorMessage::GetString() +{ + if( ! m_pRun ) + m_pRun = m_pBytes; + + medDebug( (ULONG)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetString\n" ); + ULONG nBytes = ExtractULONG(); + + if( nBytes == 0 ) + return NULL; + + medDebug( (ULONG)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetString\n" ); + char* pBuffer = new char[ nBytes+1 ]; + memcpy( pBuffer, m_pRun, nBytes ); + pBuffer[ nBytes ] = 0; + m_pRun += nBytes; + return pBuffer; +} + +UINT32 MediatorMessage::GetUINT32() +{ + if( ! m_pRun ) + m_pRun = m_pBytes; + + medDebug( (ULONG)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetUINT32\n" ); + ULONG nBytes = ExtractULONG(); + medDebug( nBytes != sizeof( UINT32 ), "No UINT32 in MediatorMessage::GetUINT32\n" ); + medDebug( (ULONG)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetUINT32\n" ); + UINT32 nRet; + memcpy( &nRet, m_pRun, sizeof( nRet ) ); + m_pRun += sizeof( UINT32 ); + return nRet; +} diff --git a/extensions/source/plugin/unx/npnapi.cxx b/extensions/source/plugin/unx/npnapi.cxx new file mode 100644 index 000000000..017db2764 --- /dev/null +++ b/extensions/source/plugin/unx/npnapi.cxx @@ -0,0 +1,686 @@ +/************************************************************************* + + Source Code Control System - Header + + $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/extensions/source/plugin/unx/npnapi.cxx,v 1.1 2001-10-23 17:31:20 pl Exp $ + + + Source Code Control System - Update + + $Log: not supported by cvs2svn $ + Revision 1.5 2000/02/17 09:41:24 pl + #73121# use mozilla header instead of netscape header + + Revision 1.4 1999/11/12 11:59:56 hr + #65293#: syntax + + Revision 1.3 1999/02/22 17:53:02 pl + #55825# Servicename geandert, OS/2 Implementation, NPP_SetWindow oefter rufen + + Revision 1.2 1999/02/15 16:12:22 pl + #55825# Model fuers Plugin + + Revision 1.1 1999/02/08 18:10:49 dbo + #55825# Netscape Plugins + + Revision 1.4 1999/02/05 13:57:23 pl + Stabilisierung des Mediators (Unix), streams verbessert + + Revision 1.3 1999/02/04 15:30:05 pl + Mediator verbessert + + Revision 1.2 1999/02/03 13:31:00 pl + Umstieg auf neue Revision der Plugin API + + Revision 1.1.1.1 1999/02/02 17:52:37 nup + Unterstuetzung fuer Netscape Plugins + + +*************************************************************************/ +#include <plugin/unx/plugcon.hxx> + +#include <dlfcn.h> + +extern PluginConnector* pConnector; +extern NPWindow aNPWindow; +extern NPSetWindowCallbackStruct aNPSetWindowCallbackStruct; +extern XtAppContext app_context; +extern Widget topLevel; +extern Display* pAppDisplay; +extern int nAppArguments; +extern char** pAppArguments; +void* CreateNewShell( void** ); + +NPNetscapeFuncs aNetscapeFuncs = +{ + sizeof(aNetscapeFuncs), + (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR, + NPN_GetURL, + NPN_PostURL, + NPN_RequestRead, + NPN_NewStream, + NPN_Write, + NPN_DestroyStream, + NPN_Status, + NPN_UserAgent, + NPN_MemAlloc, + NPN_MemFree, + NPN_MemFlush, + NPN_ReloadPlugins, + NPN_GetJavaEnv, + NPN_GetJavaPeer, + NPN_GetURLNotify, + NPN_PostURLNotify, + NPN_GetValue, + NPN_SetValue, + NPN_InvalidateRect, + NPN_InvalidateRegion, + NPN_ForceRedraw +}; + +NPPluginFuncs aPluginFuncs = +{ + sizeof(aPluginFuncs), + (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + + +void* pPluginLib = NULL; +char*(*pNPP_GetMIMEDescription)() = NULL; +NPError (*pNP_Initialize)(NPNetscapeFuncs*,NPPluginFuncs*) = NULL; +NPError (*pNP_Shutdown)() = NULL; + +PluginConnectorList PluginConnector::allConnectors; + +PluginConnector::PluginConnector( int nSocket ) : + Mediator( nSocket ) +{ + SetNewMessageHdl( LINK( this, PluginConnector, NewMessageHdl ) ); +} + +PluginConnector::~PluginConnector() +{ +} + +IMPL_LINK( PluginConnector, WorkOnNewMessageHdl, Mediator*, pMediator ) +{ + MediatorMessage* pMessage; + CommandAtoms nCommand; + if( pMessage = GetNextMessage( FALSE ) ) + { + nCommand = (CommandAtoms)pMessage->GetUINT32(); + medDebug( 1, "%s\n", GetCommandName( nCommand ) ); + switch( nCommand ) + { + case eNPP_DestroyStream: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + UINT32 nFileID = pMessage->GetUINT32(); + NPStream* pStream = m_aNPWrapStreams.GetObject( nFileID ); + NPError aReason = GetNPError( pMessage ); + aReason = aPluginFuncs.destroystream( instance, pStream, aReason ); + Respond( pMessage->m_nID, + (char*)&aReason, sizeof( aReason ), + NULL ); + } + break; + case eNPP_Destroy: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + NPSavedData* pSave = NULL; + NPError aRet = aPluginFuncs.destroy( instance, &pSave ); + if( pSave ) + Respond( pMessage->m_nID, + (char*)&aRet, sizeof( aRet ), + pSave->buf, pSave->len, + NULL ); + else + Respond( pMessage->m_nID, + (char*)&aRet, sizeof( aRet ), + "0000", 4, + NULL ); + delete pSave->buf; + delete m_aInstances.Remove( nInstance ); + delete instance; + } + break; + case eNPP_NewStream: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + char* pType = pMessage->GetString(); + NPStream* pStream = new NPStream; + pStream->url = pMessage->GetString(); + pStream->end = pMessage->GetUINT32(); + pStream->lastmodified = pMessage->GetUINT32(); + NPBool* pSeekable = (NPBool*)pMessage->GetBytes(); + m_aNPWrapStreams.Insert( pStream, LIST_APPEND ); + uint16 nStype; + NPError aRet = aPluginFuncs.newstream( instance, pType, pStream, + *pSeekable, &nStype ); + medDebug( aRet, "xhello: NPP_NewStream returns %d\n", (int) aRet ); + Respond( pMessage->m_nID, + (char*)&aRet, sizeof( aRet ), + &nStype, sizeof( nStype ), + NULL ); + delete pType; + } + break; + case eNPP_New: + { + char* pType = pMessage->GetString(); + uint16* pMode = (uint16*)pMessage->GetBytes(); + int16* pArgc = (int16*)pMessage->GetBytes(); + NPP instance = new NPP_t; + instance->pdata = NULL; + ULONG nArgnBytes, nArgvBytes; + char* pArgn = (char*)pMessage->GetBytes( nArgnBytes ); + char* pArgv = (char*)pMessage->GetBytes( nArgvBytes ); + ULONG nSaveBytes; + char* pSavedData = (char*)pMessage->GetBytes( nSaveBytes ); + ConnectorInstance* pInst = + new ConnectorInstance( instance, pType, + *pArgc, + pArgn, nArgnBytes, + pArgv, nArgvBytes, + pSavedData, nSaveBytes ); + m_aInstances.Insert( pInst, LIST_APPEND ); + NPError aRet; + aRet = aPluginFuncs.newp( pInst->pMimeType, instance, *pMode, *pArgc, + *pArgc ? pInst->argn : NULL, + *pArgc ? pInst->argv : NULL, + ( nSaveBytes == 4 && *(UINT32*)pSavedData == '0000' ) ? + &(pInst->aData) : NULL ); + medDebug( aRet, "xhello: NPP_New returns %d\n", (int) aRet ); + Respond( pMessage->m_nID, + (char*)&aRet, sizeof( aRet ), + NULL ); + delete pMode; + delete pArgc; + delete pType; + } + break; + case eNPP_SetWindow: + { + UINT32 nInstance = pMessage->GetUINT32(); + ConnectorInstance* pInst= m_aInstances.GetObject( nInstance ); + NPWindow* pWindow = (NPWindow*)pMessage->GetBytes(); + memcpy( &pInst->window, pWindow, sizeof( NPWindow ) ); + pInst->window.ws_info = &pInst->ws_info; + memcpy( &pInst->ws_info, &aNPSetWindowCallbackStruct, + sizeof( NPSetWindowCallbackStruct ) ); + pInst->ws_info.type = 1; + if( ! pInst->pWidget ) + { + pInst->pWidget = CreateNewShell( &(pInst->pShell) ); + + medDebug( 1, "Reparenting new widget %x to %x\n", + XtWindow( (Widget)pInst->pWidget ), + (XLIB_Window)pWindow->window ); + XReparentWindow( pAppDisplay, + XtWindow( (Widget)pInst->pWidget ), + (XLIB_Window)pWindow->window, + 0, 0 ); + XEvent aEvent; + while( ! XCheckTypedWindowEvent( + pAppDisplay, + XtWindow( (Widget)pInst->pShell ), + ReparentNotify, + &aEvent ) ); + + + XtRealizeWidget( (Widget)pInst->pWidget ); + XtResizeWidget( (Widget)pInst->pShell, + pWindow->width, pWindow->height, 0 ); + XWithdrawWindow( pAppDisplay, + XtWindow( (Widget)pInst->pShell ), + DefaultScreen( pAppDisplay ) + ); + XWithdrawWindow( pAppDisplay, + XtWindow( topLevel ), + DefaultScreen( pAppDisplay ) + ); + XtMapWidget( (Widget)pInst->pWidget ); + XRaiseWindow( pAppDisplay, XtWindow((Widget)pInst->pWidget) ); + XSync( pAppDisplay, False ); + } + + pInst->window.window = + (void*)XtWindow( (Widget)pInst->pWidget ); + XtResizeWidget( (Widget)pInst->pShell, + pInst->window.width, + pInst->window.height, + 0 ); + NPError aRet = aPluginFuncs.setwindow( pInst->instance, &pInst->window ); + medDebug( aRet, "xhello: NPP_SetWindow returns %d\n", (int) aRet ); + Respond( pMessage->m_nID, + (char*)&aRet, sizeof( aRet ), + NULL ); + delete pWindow; + } + break; + case eNPP_StreamAsFile: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + UINT32 nFileID = pMessage->GetUINT32(); + NPStream* pStream = m_aNPWrapStreams.GetObject( nFileID ); + char* fname = pMessage->GetString(); + medDebug( 1, "NPP_StreamAsFile %s\n", fname ); + aPluginFuncs.asfile( instance, pStream, fname ); + delete fname; + } + break; + case eNPP_URLNotify: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + char* url = pMessage->GetString(); + NPReason* pReason = (NPReason*)pMessage->GetBytes(); + void** notifyData = (void**)pMessage->GetBytes(); + aPluginFuncs.urlnotify( instance, url, *pReason, *notifyData ); + delete url; + delete pReason; + delete notifyData; + } + break; + case eNPP_WriteReady: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + UINT32 nFileID = pMessage->GetUINT32(); + NPStream* pStream = m_aNPWrapStreams.GetObject( nFileID ); + int32 nRet = aPluginFuncs.writeready( instance, pStream ); + Respond( pMessage->m_nID, + (char*)&nRet, sizeof( nRet ), + NULL ); + } + break; + case eNPP_Write: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + UINT32 nFileID = pMessage->GetUINT32(); + NPStream* pStream = m_aNPWrapStreams.GetObject( nFileID ); + int32 offset = pMessage->GetUINT32(); + ULONG len; + char* buffer = (char*)pMessage->GetBytes( len ); + int32 nRet = aPluginFuncs.write( instance, pStream, offset, len, buffer ); + Respond( pMessage->m_nID, + (char*)&nRet, sizeof( nRet ), + NULL ); + delete buffer; + } + break; + case eNPP_GetMIMEDescription: + { + if( ! pNPP_GetMIMEDescription ) + pNPP_GetMIMEDescription = (char*(*)()) + dlsym( pPluginLib, "NPP_GetMIMEDescription" ); + char* pMIME = pNPP_GetMIMEDescription(); + Respond( pMessage->m_nID, + POST_STRING( pMIME ), + NULL ); + } + break; + case eNPP_Initialize: + { + + pNP_Initialize = + (NPError(*)(NPNetscapeFuncs*, NPPluginFuncs*)) + dlsym( pPluginLib, "NP_Initialize" ); + pNP_Shutdown = (NPError(*)()) + dlsym( pPluginLib, "NP_Shutdown" ); + + medDebug( 1, "entering NP_Initialize\n" ); + NPError aRet = pNP_Initialize( &aNetscapeFuncs, &aPluginFuncs ); + medDebug( 1, "xhello: NP_Initialize returns %d\n", (int) aRet ); + Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL ); + } + break; + case eNPP_Shutdown: + { + pNP_Shutdown(); + dlclose( pPluginLib ); + exit( 0 ); + } + break; + default: + medDebug( 1, "caught unknown NPP request %d\n", nCommand ); + } + delete pMessage; + } + return 0; +} + +// begin Netscape plugin api calls +extern "C" { + + void* NPN_MemAlloc( UINT32 nBytes ) + { + void* pMem = malloc( nBytes ); + return pMem; + } + + void NPN_MemFree( void* pMem ) +{ + free( pMem ); +} + + UINT32 NPN_MemFlush( UINT32 nSize ) +{ + return 0; +} + +NPError NPN_DestroyStream( NPP instance, NPStream* stream, NPError reason ) +{ + UINT32 nInstance = pConnector->GetNPPID( instance ); + MediatorMessage* pMes= + pConnector-> + Transact( eNPN_DestroyStream, + &nInstance, sizeof( nInstance ), + pConnector->GetStreamID( stream ), sizeof( int ), + POST_STRING( stream->url ), + reason, sizeof( reason ), + NULL ); + + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + pConnector->m_aNPWrapStreams.Remove( stream ); + delete stream->url; + delete stream; + // returns NPError + NPError aRet = pConnector->GetNPError( pMes ); + delete pMes; + return aRet; +} + + JRIEnv* NPN_GetJavaEnv() +{ + // no java in this program + return NULL; +} + + jref NPN_GetJavaPeer( NPP instance ) +{ + return NULL; +} + + NPError NPN_GetURL( NPP instance, const char* url, const char* window ) +{ + UINT32 nInstance = pConnector->GetNPPID( instance ); + MediatorMessage* pMes= + pConnector-> + Transact( eNPN_GetURL, + &nInstance, sizeof( nInstance ), + POST_STRING(url), + POST_STRING(window), + NULL ); + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + // returns NPError + NPError aRet = pConnector->GetNPError( pMes ); + delete pMes; + return aRet; +} + + NPError NPN_GetURLNotify( NPP instance, const char* url, const char* target, + void* notifyData ) +{ + UINT32 nInstance = pConnector->GetNPPID( instance ); + MediatorMessage* pMes= + pConnector-> + Transact( eNPN_GetURLNotify, + &nInstance, sizeof( nInstance ), + POST_STRING(url), + POST_STRING(target), + ¬ifyData, sizeof( void* ), // transmit the actual pointer + // since it is a pointer to private data fed back + // by NPP_URLNotify; this can be thought of as an ID + NULL ); + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + // returns NPError + NPError aRet = pConnector->GetNPError( pMes ); + delete pMes; + return aRet; +} + + NPError NPN_NewStream( NPP instance, NPMIMEType type, const char* target, + NPStream** stream ) + // stream is a return value +{ + UINT32 nInstance = pConnector->GetNPPID( instance ); + MediatorMessage* pMes= + pConnector-> + Transact( eNPN_NewStream, + &nInstance, sizeof( nInstance ), + POST_STRING(type), + POST_STRING(target), + NULL ); + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + // returns a new NPStream and an error + NPError aRet = pConnector->GetNPError( pMes ); + if( ! aRet ) + { + NPStream* pStream = new NPStream; + pStream->url = pMes->GetString(); + pStream->end = pMes->GetUINT32(); + pStream->lastmodified = pMes->GetUINT32(); + pConnector->m_aNPWrapStreams.Insert( pStream, LIST_APPEND ); + *stream = pStream; + } + + delete pMes; + return aRet; +} + + NPError NPN_PostURLNotify( NPP instance, const char* url, const char* target, UINT32 len, const char* buf, NPBool file, void* notifyData ) +{ + UINT32 nInstance = pConnector->GetNPPID( instance ); + MediatorMessage* pMes = pConnector-> + Transact( eNPN_PostURLNotify, + &nInstance, sizeof( nInstance ), + POST_STRING( url ), + POST_STRING( target ), + &len, sizeof( len ), + buf, len, + &file, sizeof( NPBool ), + ¬ifyData, sizeof( void* ), // send the real pointer + NULL ); + + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + NPError aRet = pConnector->GetNPError( pMes ); + delete pMes; + return aRet; +} + +NPError NPN_PostURL( NPP instance, const char* url, const char* window, UINT32 len, const char* buf, NPBool file ) +{ + UINT32 nInstance = pConnector->GetNPPID( instance ); + MediatorMessage* pMes = pConnector-> + Transact( eNPN_PostURL, + &nInstance, sizeof( nInstance ), + POST_STRING( url ), + POST_STRING( window ), + &len, sizeof( len ), + buf, len, + &file, sizeof( NPBool ), + NULL ); + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + NPError aRet = pConnector->GetNPError( pMes ); + delete pMes; + return aRet; +} + +NPError NPN_RequestRead( NPStream* stream, NPByteRange* rangeList ) +{ + NPByteRange* pRange = rangeList; + UINT32 nRanges = 0; + while( pRange ) + { + nRanges++; + pRange = pRange->next; + } + + UINT32* pArray = new UINT32[ 2 * nRanges ]; + pRange = rangeList; + UINT32 n = 0; + while( pRange ) + { + pArray[ 2*n ] = (UINT32)pRange->offset; + pArray[ 2*n + 1] = (UINT32)pRange->length; + n++; + pRange = pRange->next; + } + UINT32 nFileID = pConnector->GetStreamID( stream ); + MediatorMessage* pMes = pConnector-> + Transact( eNPN_RequestRead, + &nFileID, sizeof( nFileID ), + &nRanges, sizeof( nRanges ), + pArray, sizeof( UINT32 ) * 2 * nRanges, + NULL ); + + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + NPError aRet = pConnector->GetNPError( pMes ); + delete pArray; + delete pMes; + return aRet; +} + +void NPN_Status( NPP instance, const char* message ) +{ + UINT32 nInstance = pConnector->GetNPPID( instance ); + pConnector->Send( eNPN_Status, + &nInstance, sizeof( nInstance ), + POST_STRING( message ), + NULL ); +} + +const char* NPN_UserAgent( NPP instance ) +{ + static char* pAgent = NULL; + + UINT32 nInstance = pConnector->GetNPPID( instance ); + MediatorMessage* pMes = pConnector-> + Transact( eNPN_UserAgent, + &nInstance, sizeof( nInstance ), + NULL ); + if( ! pMes ) + return pAgent; + + if( pAgent ) + delete pAgent; + pAgent = pMes->GetString(); + + delete pMes; + return pAgent; +} + +void NPN_Version( int* major, int* minor, int* net_major, int* net_minor ) +{ + MediatorMessage* pMes = pConnector-> + Transact( eNPN_Version, + NULL ); + + if( ! pMes ) + return; + + *major = pMes->GetUINT32(); + *minor = pMes->GetUINT32(); + *net_major = pMes->GetUINT32(); + *net_minor = pMes->GetUINT32(); + delete pMes; +} + +int32 NPN_Write( NPP instance, NPStream* stream, int32 len, + void* buffer ) +{ + UINT32 nFileID = pConnector->GetStreamID( stream ); + UINT32 nInstance = pConnector->GetNPPID( instance ); + MediatorMessage* pMes = pConnector-> + Transact( eNPN_Write, + &nInstance, sizeof( nInstance ), + &nFileID, sizeof( nFileID ), + &len, sizeof( len ), + buffer, len, + NULL ); + + if( ! pMes ) + return 0; + + INT32 nRet = pMes->GetUINT32(); + return nRet; +} + +void NPN_ReloadPlugins( NPBool reloadPages ) +{ + medDebug( 1, "NPN_ReloadPlugins: SNI\n" ); +} + +NPError NPN_GetValue( NPP instance, NPNVariable variable, void* value ) +{ + switch( variable ) + { + case NPNVxDisplay: + *((Display**)value) = pAppDisplay; + medDebug( 1, "Display requested\n" ); + break; + case NPNVxtAppContext: + *((XtAppContext*)value) = app_context; + medDebug( 1, "AppContext requested\n" ); + break; + default: + medDebug( 1, "unknown NPNVariable %d requested\n", variable ); + return 1; + } + return 0; +} + +NPError NPN_SetValue(NPP instance, NPPVariable variable, + void *value) +{ + return 0; +} + +void NPN_InvalidateRect(NPP instance, NPRect *invalidRect) +{ +} + +void NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion) +{ +} + +void NPN_ForceRedraw(NPP instance) +{ +} + +} + diff --git a/extensions/source/plugin/unx/nppapi.cxx b/extensions/source/plugin/unx/nppapi.cxx new file mode 100644 index 000000000..43d81b582 --- /dev/null +++ b/extensions/source/plugin/unx/nppapi.cxx @@ -0,0 +1,576 @@ +/************************************************************************* + + Source Code Control System - Header + + $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/extensions/source/plugin/unx/nppapi.cxx,v 1.1 2001-10-23 17:31:20 pl Exp $ + + + Source Code Control System - Update + + $Log: not supported by cvs2svn $ + Revision 1.5 1999/11/12 11:59:57 hr + #65293#: syntax + + Revision 1.4 1999/02/26 17:47:47 pl + #55825# Einige Bugs gefixed + + Revision 1.3 1999/02/22 17:53:03 pl + #55825# Servicename geandert, OS/2 Implementation, NPP_SetWindow oefter rufen + + Revision 1.2 1999/02/15 16:12:22 pl + #55825# Model fuers Plugin + + Revision 1.1 1999/02/08 18:10:49 dbo + #55825# Netscape Plugins + + Revision 1.4 1999/02/04 15:30:05 pl + Mediator verbessert + + Revision 1.3 1999/02/03 14:29:11 dbo + windows aenderungen + + Revision 1.2 1999/02/03 13:31:00 pl + Umstieg auf neue Revision der Plugin API + + Revision 1.1.1.1 1999/02/02 17:52:37 nup + Unterstuetzung fuer Netscape Plugins + + +*************************************************************************/ + +#if STLPORT_VERSION>=321 +#include <cstdarg> +#endif + +#include <plugin/impl.hxx> +#include <vcl/svapp.hxx> + +PluginConnectorList PluginConnector::allConnectors; + +PluginConnector::PluginConnector( int nSocket ) : + Mediator( nSocket ) +{ + allConnectors.Insert( this, LIST_APPEND ); + SetNewMessageHdl( LINK( this, PluginConnector, NewMessageHdl ) ); +} + +PluginConnector::~PluginConnector() +{ + NAMESPACE_VOS(OGuard) aGuard( m_aUserEventMutex ); + allConnectors.Remove( this ); +} + +IMPL_LINK( PluginConnector, NewMessageHdl, Mediator*, pMediator ) +{ + if( allConnectors.GetPos( this ) == LIST_ENTRY_NOTFOUND ) + return 0; + NAMESPACE_VOS(OGuard) aGuard( m_aUserEventMutex ); + return 0; +} + +IMPL_LINK( PluginConnector, WorkOnNewMessageHdl, Mediator*, pMediator ) +{ + if( allConnectors.GetPos( this ) == LIST_ENTRY_NOTFOUND ) + return 0; +/* + { + NAMESPACE_VOS(OGuard) aGuard( m_aUserEventMutex ); + m_aUserEventIDs.pop_front(); + } +*/ + + MediatorMessage* pMessage; + CommandAtoms nCommand; + char* pRun; + while( pMessage = GetNextMessage( FALSE ) ) + { + nCommand = (CommandAtoms)pMessage->GetUINT32(); + medDebug( 1, "%s\n", GetCommandName( nCommand ) ); + switch( nCommand ) + { + case eNPN_GetURL: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + char* pUrl = pMessage->GetString(); + char* pWindow = pMessage->GetString(); + NPError aRet = NPN_GetURL( instance, pUrl, pWindow ); + Respond( pMessage->m_nID, + (char*)(&aRet), sizeof( NPError ), NULL ); + delete pUrl; + delete pWindow; + } + break; + case eNPN_GetURLNotify: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + char* pUrl = pMessage->GetString(); + char* pWindow = pMessage->GetString(); + void** pNotifyData = (void**)pMessage->GetBytes(); + NPError aRet = NPN_GetURLNotify( instance, pUrl, pWindow, + *pNotifyData ); + Respond( pMessage->m_nID, + (char*)(&aRet), sizeof( NPError ), NULL ); + delete pUrl; + delete pWindow; + delete pNotifyData; + } + break; + case eNPN_DestroyStream: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + UINT32 nFileID = pMessage->GetUINT32(); + char* pUrl = pMessage->GetString(); + NPError* pReason = (NPError*)pMessage->GetBytes(); + NPError aRet = NPERR_FILE_NOT_FOUND; + if( nFileID < m_aNPWrapStreams.Count() ) + { + if( ! strcmp( m_aNPWrapStreams.GetObject( nFileID )->url, pUrl ) ) + { + aRet = + NPN_DestroyStream( instance, m_aNPWrapStreams.GetObject( nFileID ), + *pReason ); + m_aNPWrapStreams.Remove( nFileID ); + } + else + medDebug( 1, "StreamID %d has incoherent urls %s and %s\n", + nFileID, pUrl, m_aNPWrapStreams.GetObject( nFileID )->url ); + } + else + medDebug( 1, "Nonexistent StreamID %d\n", nFileID ); + + Respond( pMessage->m_nID, + (char*)(&aRet), sizeof( NPError ), NULL ); + + delete pUrl; + delete pReason; + } + break; + case eNPN_NewStream: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + NPMIMEType pType = pMessage->GetString(); + char* pTarget = pMessage->GetString(); + NPStream* pStream = new NPStream; + + NPError aRet = NPN_NewStream( instance, pType, pTarget, &pStream ); + + if( aRet != NPERR_NO_ERROR ) + { + pStream->url = ""; + pStream->end = 0; + pStream->lastmodified = 0; + } + else + m_aNPWrapStreams.Insert( pStream, LIST_APPEND ); + + ULONG nLen = strlen( pStream->url ); + Respond( pMessage->m_nID, + (char*)&aRet, sizeof( aRet ), + pStream->url, nLen, + &pStream->end, sizeof(UINT32), + &pStream->lastmodified, sizeof(UINT32), + NULL ); + + delete pTarget; + delete pType; + } + break; + case eNPN_PostURLNotify: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + char* pUrl = pMessage->GetString(); + char* pTarget = pMessage->GetString(); + UINT32 nLen = pMessage->GetUINT32(); + char* pBuf = (char*)pMessage->GetBytes(); + NPBool* pFile = (NPBool*)pMessage->GetBytes(); + void** pNData = (void**)pMessage->GetBytes(); + NPError aRet = + NPN_PostURLNotify( instance, pUrl, pTarget, nLen, pBuf, *pFile, *pNData ); + Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL ); + delete pUrl; + delete pTarget; + delete pBuf; + delete pFile; + delete pNData; + } + break; + case eNPN_PostURL: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + char* pUrl = pMessage->GetString(); + char* pWindow = pMessage->GetString(); + UINT32 nLen = pMessage->GetUINT32(); + char* pBuf = (char*)pMessage->GetBytes(); + NPBool* pFile = (NPBool*)pMessage->GetBytes(); + NPError aRet = + NPN_PostURL( instance, pUrl, pWindow, nLen, pBuf, *pFile ); + Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL ); + delete pUrl; + delete pWindow; + delete pBuf; + delete pFile; + } + break; + case eNPN_RequestRead: + { + UINT32 nFileID = pMessage->GetUINT32(); + NPStream* pStream = m_aNPWrapStreams.GetObject( nFileID ); + UINT32 nRanges = pMessage->GetUINT32(); + UINT32* pArray = (UINT32*)pMessage->GetBytes(); + // build ranges table + NPByteRange* pFirst = new NPByteRange; + NPByteRange* pRun = pFirst; + for( UINT32 n = 0; n < nRanges; n++ ) + { + pRun->offset = pArray[ 2*n ]; + pRun->length = pArray[ 2*n+1 ]; + pRun->next = n < nRanges-1 ? new NPByteRange : NULL; + pRun = pRun->next; + } + NPError aRet = NPN_RequestRead( pStream, pFirst ); + Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL ); + while( pFirst ) + { + pRun = pFirst->next; + delete pFirst; + pFirst = pRun; + } + delete pArray; + } + break; + case eNPN_Status: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + char* pString = pMessage->GetString(); + NPN_Status( instance, pString ); + delete pString; + } + break; + case eNPN_Version: + { + int major, minor, net_major, net_minor; + NPN_Version( &major, &minor, &net_major, &net_minor ); + Respond( pMessage->m_nID, + (char*)&major, sizeof( int ), + &minor, sizeof( int ), + &net_major, sizeof( int ), + &net_minor, sizeof( int ), + NULL ); + } + break; + case eNPN_Write: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + UINT32 nFileID = pMessage->GetUINT32(); + NPStream* pStream = m_aNPWrapStreams.GetObject( nFileID ); + INT32 nLen = pMessage->GetUINT32(); + void* pBuffer = pMessage->GetBytes(); + INT32 nRet = NPN_Write( instance, pStream, nLen, pBuffer ); + Respond( pMessage->m_nID, + (char*)&nRet, sizeof( nRet ), + NULL ); + delete pBuffer; + delete instance; + } + break; + case eNPN_UserAgent: + { + UINT32 nInstance = pMessage->GetUINT32(); + NPP instance = m_aInstances.GetObject( nInstance )->instance; + const char* pAnswer = NPN_UserAgent( instance ); + Respond( pMessage->m_nID, + (char*)pAnswer, strlen( pAnswer ), + NULL ); + } + break; + default: + medDebug( 1, "caught unknown NPN request %d\n", nCommand ); + } + + delete pMessage; + } + return 0; +} + +#define GET_INSTANCE() \ + UINT32 nInstance; \ + nInstance = GetNPPID( instance ) + + +#define POST_INSTANCE() (char*)&nInstance, sizeof( nInstance ) + +NPError UnxPluginComm::NPP_Destroy( NPP instance, NPSavedData** save ) +{ + NPError aRet = NPERR_GENERIC_ERROR; + GET_INSTANCE(); + MediatorMessage* pMes = + Transact( eNPP_Destroy, + POST_INSTANCE(), + NULL ); + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + aRet = GetNPError( pMes ); + ULONG nSaveBytes; + void* pSaveData = pMes->GetBytes( nSaveBytes ); + if( nSaveBytes == 4 && *(UINT32*)pSaveData == '0000' ) + *save = NULL; + else + { + *save = new NPSavedData; + (*save)->len = nSaveBytes; + (*save)->buf = pSaveData; + } + delete pMes; + + return aRet; +} + +NPError UnxPluginComm::NPP_DestroyStream( NPP instance, NPStream* stream, NPError reason ) +{ + NPError aRet = NPERR_GENERIC_ERROR; + GET_INSTANCE(); + UINT32 nFileID = GetStreamID( stream ); + MediatorMessage* pMes = + Transact( eNPP_DestroyStream, + POST_INSTANCE(), + &nFileID, sizeof( nFileID ), + &reason, sizeof( reason ), + NULL ); + m_aNPWrapStreams.Remove( stream ); + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + aRet = GetNPError( pMes ); + delete pMes; + return aRet; +} + +jref UnxPluginComm::NPP_GetJavaClass() +{ + return NULL; +} + +NPError UnxPluginComm::NPP_Initialize() +{ + MediatorMessage* pMes = + Transact( eNPP_Initialize, + NULL ); + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + NPError aRet = GetNPError( pMes ); + delete pMes; + return aRet; +} + +NPError UnxPluginComm::NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, + char* argn[], char* argv[], NPSavedData *saved ) +{ + m_aInstances.Insert( + new ConnectorInstance( instance, pluginType, 0, + NULL, 0, NULL, 0, + saved ? (char*)saved->buf : NULL, + saved ? saved->len : 0 ), + LIST_APPEND ); + + char *pArgnBuf, *pArgvBuf; + int nArgnLen = 0, nArgvLen = 0; + int i; + for( i = 0; i < argc; i++ ) + { + nArgnLen += strlen( argn[i] ) +1; + nArgvLen += strlen( argv[i] ) +1; + } + pArgnBuf = new char[ nArgnLen ]; + pArgvBuf = new char[ nArgvLen ]; + char* pRunArgn = pArgnBuf; + char* pRunArgv = pArgvBuf; + for( i = 0; i < argc; i++ ) + { + strcpy( pRunArgn, argn[i] ); + strcpy( pRunArgv, argv[i] ); + pRunArgn += strlen( argn[i] ) +1; + pRunArgv += strlen( argv[i] ) +1; + } + + MediatorMessage* pMes; + if( saved ) + pMes = + Transact( eNPP_New, + pluginType, strlen( pluginType ), + &mode, sizeof( mode ), + &argc, sizeof( argc ), + pArgnBuf, nArgnLen, + pArgvBuf, nArgvLen, + saved->buf, saved->len, + NULL ); + else + pMes = + Transact( eNPP_New, + pluginType, strlen( pluginType ), + &mode, sizeof( mode ), + &argc, sizeof( argc ), + pArgnBuf, nArgnLen, + pArgvBuf, nArgvLen, + "0000", 4, + NULL ); + delete pArgnBuf; + delete pArgvBuf; + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + NPError aRet = GetNPError( pMes ); + delete pMes; + + return aRet; +} + +NPError UnxPluginComm::NPP_NewStream( NPP instance, NPMIMEType type, NPStream* stream, + NPBool seekable, uint16* stype ) +{ + NPError aRet = NPERR_GENERIC_ERROR; + GET_INSTANCE(); + + m_aNPWrapStreams.Insert( stream, LIST_APPEND ); + MediatorMessage* pMes = + Transact( eNPP_NewStream, + POST_INSTANCE(), + type, strlen( type ), + stream->url, strlen( stream->url ), + &stream->end, sizeof( stream->end ), + &stream->lastmodified, sizeof( stream->lastmodified ), + &seekable, sizeof( seekable ), + NULL ); + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + aRet = GetNPError( pMes ); + uint16* pSType = (uint16*)pMes->GetBytes(); + *stype = *pSType; + delete pSType; + delete pMes; + return aRet; +} + +void UnxPluginComm::NPP_Print( NPP instance, NPPrint* platformPrint ) +{ +} + +NPError UnxPluginComm::NPP_SetWindow( NPP instance, NPWindow* window ) +{ + NPError aRet = NPERR_GENERIC_ERROR; + GET_INSTANCE(); + + MediatorMessage* pMes = + Transact( eNPP_SetWindow, + POST_INSTANCE(), + window, sizeof( NPWindow ), + NULL ); + if( ! pMes ) + return NPERR_GENERIC_ERROR; + + aRet = GetNPError( pMes ); + delete pMes; + return aRet; +} + +void UnxPluginComm::NPP_Shutdown() +{ + Send( eNPP_Shutdown, NULL ); +} + +void UnxPluginComm::NPP_StreamAsFile( NPP instance, NPStream* stream, const char* fname ) +{ + GET_INSTANCE(); + UINT32 nFileID = GetStreamID( stream ); + + Send( eNPP_StreamAsFile, + POST_INSTANCE(), + &nFileID, sizeof( nFileID ), + fname, strlen( fname ), + NULL ); +} + +void UnxPluginComm::NPP_URLNotify( NPP instance, const char* url, NPReason reason, void* notifyData ) +{ + GET_INSTANCE(); + + Send( eNPP_URLNotify, + POST_INSTANCE(), + url, strlen( url ), + &reason, sizeof( reason ), + ¬ifyData, sizeof( void* ), + NULL ); +} + +int32 UnxPluginComm::NPP_Write( NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer ) +{ + GET_INSTANCE(); + UINT32 nFileID = GetStreamID( stream ); + MediatorMessage* pMes = + Transact( eNPP_Write, + POST_INSTANCE(), + &nFileID, sizeof( nFileID ), + &offset, sizeof( offset ), + buffer, len, + NULL ); + if( ! pMes ) + return 0; + + int32 aRet = pMes->GetUINT32(); + delete pMes; + return aRet; +} + +int32 UnxPluginComm::NPP_WriteReady( NPP instance, NPStream* stream ) +{ + GET_INSTANCE(); + UINT32 nFileID = GetStreamID( stream ); + MediatorMessage* pMes = + Transact( eNPP_WriteReady, + POST_INSTANCE(), + &nFileID, sizeof( nFileID ), + NULL ); + + if( ! pMes ) + return 0; + + int32 aRet = pMes->GetUINT32(); + delete pMes; + return aRet; +} + +char* UnxPluginComm::NPP_GetMIMEDescription() +{ + static char* pDesc = NULL; + MediatorMessage* pMes = + Transact( eNPP_GetMIMEDescription, + NULL ); + if( ! pMes ) + return ""; + + if( pDesc ) + delete pDesc; + pDesc = pMes->GetString(); + delete pMes; + return pDesc; +} + +NPError UnxPluginComm::NPP_GetValue( NPP instance, NPPVariable variable, void* value ) +{ + return 0; +} + +NPError UnxPluginComm::NPP_SetValue( NPP instance, NPNVariable variable, void* value ) +{ + return 0; +} diff --git a/extensions/source/plugin/unx/npwrap.cxx b/extensions/source/plugin/unx/npwrap.cxx new file mode 100644 index 000000000..afbdf4c97 --- /dev/null +++ b/extensions/source/plugin/unx/npwrap.cxx @@ -0,0 +1,242 @@ +/************************************************************************* + * + * $RCSfile: npwrap.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: pl $ $Date: 2001-10-23 17:31:20 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <errno.h> +#include <dlfcn.h> + +#include <plugin/unx/plugcon.hxx> + + +PluginConnector* pConnector = NULL; + +NPWindow aNPWindow; +NPSetWindowCallbackStruct aNPSetWindowCallbackStruct; + +int nAppArguments = 0; +char** pAppArguments = NULL; +Display* pAppDisplay = NULL; + +extern void* pPluginLib; + +static long GlobalConnectionLostHdl( void* pInst, void* pArg ) +{ +#ifdef DEBUG + fprintf( stderr, "xhello exiting due to connection lost\n" ); +#endif + exit( 0 ); + return 0; +} + +XtAppContext app_context; +Widget topLevel, hello; + +void ThreadEventHandler( Widget widget, XtPointer closure, + XEvent* pEvent, XLIB_Boolean* dispatch_further ) +{ + if( pEvent->type == ClientMessage && + pEvent->xclient.format == 32 && + pEvent->xclient.data.l[0] == 1 && + pEvent->xclient.data.l[1] == 2 && + pEvent->xclient.data.l[2] == 3 && + pEvent->xclient.data.l[3] == 4 && + pEvent->xclient.data.l[4] == 5 ) + { + *dispatch_further = False; + pConnector->CallWorkHandler(); + } + else + *dispatch_further = True; +} + +IMPL_LINK( PluginConnector, NewMessageHdl, Mediator*, pMediator ) +{ + XEvent aEvent; + aEvent.type = ClientMessage; + aEvent.xclient.display = XtDisplay( topLevel ); + aEvent.xclient.message_type = XA_STRING; + aEvent.xclient.window = XtWindow( topLevel ); + aEvent.xclient.format = 32; + aEvent.xclient.data.l[0] = 1; + aEvent.xclient.data.l[1] = 2; + aEvent.xclient.data.l[2] = 3; + aEvent.xclient.data.l[3] = 4; + aEvent.xclient.data.l[4] = 5; + XSendEvent( XtDisplay( topLevel ), + XtWindow( topLevel ), False, + 0, &aEvent ); + XFlush( XtDisplay( topLevel ) ); + return 0; +} + +#if defined USE_MOTIF +Widget createSubWidget( char* pPluginText, Widget shell ) +{ + Widget newWidget; + newWidget = XtVaCreateManagedWidget( + "hello", + xmDrawingAreaWidgetClass, + shell, + NULL ); + + return newWidget; +} +#else +Widget createSubWidget( char* pPluginText, Widget shell ) +{ + hello = XtVaCreateManagedWidget( + pPluginText, + labelWidgetClass, + shell, + NULL ); + + return hello; +} +#endif + +void* CreateNewShell( void** pShellReturn ) +{ + Widget newShell = + XtVaAppCreateShell( "SOPluginApp", "SOPluginApp", + applicationShellWidgetClass, + pAppDisplay, + NULL ); + char pText[1024]; + sprintf( pText, "starting plugin %s ...", pAppArguments[2] ); + Widget newWidget = createSubWidget( pText, newShell ); + + XtRealizeWidget( newShell ); + + *pShellReturn = newShell; + return newWidget; +} + +main( int argc, char **argv) +{ +#if ! ( defined DEBUG || defined DBG_UTIL ) + fclose( stdout ); + fclose( stderr ); +#endif + nAppArguments = argc; + pAppArguments = argv; + + XInitThreads(); + + pPluginLib = dlopen( argv[2], RTLD_NOW ); + if( ! pPluginLib ) + { + medDebug( 1, "dlopen on %s failed because of:\n\t%s\n", + argv[2], dlerror() ); + exit(255); + } + int nSocket = atol( argv[1] ); + + pConnector = new PluginConnector( nSocket ); + pConnector->SetConnectionLostHdl( Link( NULL, GlobalConnectionLostHdl ) ); + + XtSetLanguageProc( NULL, NULL, NULL ); + + topLevel = XtVaAppInitialize( + &app_context, /* Application context */ + "SOPlugin", /* Application class */ + NULL, 0, /* command line option list */ + &argc, argv, /* command line args */ + NULL, /* for missing app-defaults file */ + NULL); /* terminate varargs list */ + pAppDisplay = XtDisplay( topLevel ); + XtAddRawEventHandler( topLevel, 0, True, ThreadEventHandler, NULL ); + + char pText[1024]; + sprintf( pText, "starting plugin %s ...", pAppArguments[2] ); + hello = createSubWidget( pText, topLevel ); + + /* + * Create windows for widgets and map them. + */ + XtRealizeWidget(topLevel); + + INT32 nWindow; + sscanf( argv[3], "%d", &nWindow ); + medDebug( 1, "Reparenting topLevel to %x\n", nWindow ); + XReparentWindow( pAppDisplay, + XtWindow( topLevel ), + (XLIB_Window)nWindow, + 0, 0 ); + + XSync( XtDisplay( hello ), False ); + + // send that we are ready to go + MediatorMessage* pMessage = + pConnector->Transact( "init req", 8, + NULL ); + delete pMessage; + + aNPSetWindowCallbackStruct.display = pAppDisplay; + aNPSetWindowCallbackStruct.visual = (Visual*) + XDefaultVisual( pAppDisplay, XDefaultScreen( pAppDisplay ) ); + aNPSetWindowCallbackStruct.colormap = (Colormap) + XDefaultColormap( pAppDisplay, XDefaultScreen( pAppDisplay ) ); + aNPSetWindowCallbackStruct.depth = + DefaultDepth( pAppDisplay, XDefaultScreen( pAppDisplay ) ); + + /* + * Loop for events. + */ + XtAppMainLoop(app_context); +} diff --git a/extensions/source/plugin/unx/plugcon.cxx b/extensions/source/plugin/unx/plugcon.cxx new file mode 100644 index 000000000..3a4c16393 --- /dev/null +++ b/extensions/source/plugin/unx/plugcon.cxx @@ -0,0 +1,253 @@ +/************************************************************************* + + Source Code Control System - Header + + $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/extensions/source/plugin/unx/plugcon.cxx,v 1.1 2001-10-23 17:31:20 pl Exp $ + + + Source Code Control System - Update + + $Log: not supported by cvs2svn $ + Revision 1.5 2000/03/22 12:01:07 pl + #74086# do not wait indefinitely on dead mediators + + Revision 1.4 1999/02/26 17:47:47 pl + #55825# Einige Bugs gefixed + + Revision 1.3 1999/02/22 17:53:03 pl + #55825# Servicename geandert, OS/2 Implementation, NPP_SetWindow oefter rufen + + Revision 1.2 1999/02/15 16:12:22 pl + #55825# Model fuers Plugin + + Revision 1.1 1999/02/08 18:10:49 dbo + #55825# Netscape Plugins + + Revision 1.1.1.1 1999/02/02 17:52:37 nup + Unterstuetzung fuer Netscape Plugins + + +*************************************************************************/ +#include <plugin/unx/plugcon.hxx> + +UINT32 PluginConnector::GetStreamID( NPStream* pStream ) +{ + for( ULONG i = 0; i < m_aNPWrapStreams.Count(); i++ ) + if( m_aNPWrapStreams.GetObject( i ) == pStream ) + return i; + medDebug( 1, "Error: NPStream has no ID\n" ); + return ~0; +} + +UINT32 PluginConnector::GetNPPID( NPP instance ) +{ + for( ULONG i=0; i < m_aInstances.Count(); i++ ) + if( m_aInstances.GetObject( i )->instance == instance ) + return i; + medDebug( 1, "Error: NPP has no ID\n" ); + return ~0; +} + +struct PtrStruct +{ + char* pData; + ULONG nBytes; +}; + +DECLARE_LIST( PtrStructList, PtrStruct* ); + +ULONG PluginConnector::FillBuffer( char*& rpBuffer, + char* pFunction, + ULONG nFunctionLen, + va_list ap ) +{ + PtrStructList aList; + PtrStruct* pPtrStruct; + ULONG nDataSize = nFunctionLen + sizeof( ULONG ); + char* pNext; + + do { + pNext = va_arg( ap, char* ); + if( pNext ) + { + pPtrStruct = new PtrStruct; + pPtrStruct->pData = pNext; + pPtrStruct->nBytes = va_arg( ap, ULONG ); + nDataSize += pPtrStruct->nBytes + sizeof(ULONG); + aList.Insert( pPtrStruct, LIST_APPEND ); + } + } while( pNext ); + + rpBuffer = new char[ nDataSize ]; + char* pRun = rpBuffer; + memcpy( pRun, &nFunctionLen, sizeof( nFunctionLen ) ); + pRun += sizeof( nFunctionLen ); + memcpy( pRun, pFunction, nFunctionLen ); + pRun += nFunctionLen; + + while( pPtrStruct = aList.Remove( (ULONG) 0 ) ) + { + memcpy( pRun, &pPtrStruct->nBytes, sizeof( ULONG ) ); + pRun += sizeof( ULONG ); + memcpy( pRun, pPtrStruct->pData, pPtrStruct->nBytes ); + pRun += pPtrStruct->nBytes; + delete pPtrStruct; + } + return nDataSize; +} + +MediatorMessage* PluginConnector::Transact( char* pFunction, + ULONG nFunctionLen, ... ) +{ + va_list ap; + char* pBuffer; + + va_start( ap, nFunctionLen ); + ULONG nSize = FillBuffer( pBuffer, pFunction, nFunctionLen, ap ); + va_end( ap ); + return TransactMessage( nSize, pBuffer ); +} + +MediatorMessage* PluginConnector::Transact( UINT32 nFunction, ... ) +{ + va_list ap; + char* pBuffer; + + va_start( ap, nFunction ); + ULONG nSize = FillBuffer( pBuffer, (char*)&nFunction, sizeof( nFunction ), ap ); + va_end( ap ); + return TransactMessage( nSize, pBuffer ); +} + +ULONG PluginConnector::Send( UINT32 nFunction, ... ) +{ + va_list ap; + char* pBuffer; + + va_start( ap, nFunction ); + ULONG nSize = FillBuffer( pBuffer, (char*)&nFunction, sizeof( nFunction ), ap ); + va_end( ap ); + return SendMessage( nSize, pBuffer ); +} + +void PluginConnector::Respond( ULONG nID, + char* pFunction, + ULONG nFunctionLen, ... ) +{ + va_list ap; + char* pBuffer; + + va_start( ap, nFunctionLen ); + ULONG nSize = FillBuffer( pBuffer, pFunction, nFunctionLen, ap ); + va_end( ap ); + SendMessage( nSize, pBuffer, nID | ( 1 << 24 ) ); +} + +MediatorMessage* PluginConnector::WaitForAnswer( ULONG nMessageID ) +{ + if( ! m_bValid ) + return NULL; + + nMessageID &= 0x00ffffff; + while( m_pListener ) + { + { + NAMESPACE_VOS(OGuard) aGuard( m_aQueueMutex ); + for( int i = 0; i < m_aMessageQueue.Count(); i++ ) + { + ULONG nID = m_aMessageQueue.GetObject( i )->m_nID; + if( ( nID & 0xff000000 ) && + ( ( nID & 0x00ffffff ) == nMessageID ) ) + return m_aMessageQueue.Remove( i ); + } + } + if( m_aMessageQueue.Count() ) + CallWorkHandler(); + WaitForMessage( 2000 ); + } + return NULL; +} + +ConnectorInstance::ConnectorInstance( NPP inst, char* type, + int args, char* pargnbuf, ULONG nargnbytes, + char* pargvbuf, ULONG nargvbytes, + char* savedata, ULONG savebytes ) : + instance( inst ), + nArg( args ), + pArgnBuf( pargnbuf ), + pArgvBuf( pargvbuf ), + pShell( NULL ), + pWidget( NULL ) +{ + memset( &window, 0, sizeof(window) ); + pMimeType = new char[ strlen( type ) + 1 ]; + strcpy( pMimeType, type ); + aData.len = savebytes; + aData.buf = savedata; + argn = new char*[ nArg ]; + argv = new char*[ nArg ]; + int i; + char* pRun = pArgnBuf; + for( i = 0; i < nArg; i++ ) + { + argn[i] = pRun; + while( *pRun != 0 && (ULONG)(pRun - pArgnBuf) < nargnbytes ) + pRun++; + if( (ULONG)(pRun - pArgnBuf) < nargnbytes ) + pRun++; + } + pRun = pArgvBuf; + for( i = 0; i < nArg; i++ ) + { + argv[i] = pRun; + while( *pRun != 0 && (ULONG)(pRun - pArgvBuf) < nargvbytes ) + pRun++; + if( (ULONG)(pRun - pArgvBuf) < nargvbytes ) + pRun++; + } +} + +ConnectorInstance::~ConnectorInstance() +{ + delete pMimeType; + delete argn; + delete argv; + delete pArgnBuf; + delete pArgvBuf; + delete aData.buf; +} + +char* GetCommandName( CommandAtoms eCommand ) +{ + switch( eCommand ) + { + case eNPN_GetURL: return "NPN_GetURL"; + case eNPN_GetURLNotify: return "NPN_GetURLNotify"; + case eNPN_DestroyStream: return "NPN_DestroyStream"; + case eNPN_NewStream: return "NPN_NewStream"; + case eNPN_PostURLNotify: return "NPN_PostURLNotify"; + case eNPN_PostURL: return "NPN_PostURL"; + case eNPN_RequestRead: return "NPN_RequestRead"; + case eNPN_Status: return "NPN_Status"; + case eNPN_Version: return "NPN_Version"; + case eNPN_Write: return "NPN_Write"; + case eNPN_UserAgent: return "NPN_UserAgent"; + + case eNPP_DestroyStream: return "NPP_DestroyStream"; + case eNPP_Destroy: return "NPP_Destroy"; + case eNPP_NewStream: return "NPP_NewStream"; + case eNPP_New: return "NPP_New"; + case eNPP_SetWindow: return "NPP_SetWindow"; + case eNPP_StreamAsFile: return "NPP_StreamAsFile"; + case eNPP_URLNotify: return "NPP_URLNotify"; + case eNPP_WriteReady: return "NPP_WriteReady"; + case eNPP_Write: return "NPP_Write"; + case eNPP_GetMIMEDescription: return "NPP_GetMIMEDescription"; + case eNPP_Initialize: return "NPP_Initialize"; + case eNPP_Shutdown: return "NPP_Shutdown"; + + case eMaxCommand: return "eMaxCommand"; + default: return "unknown command"; + } + return NULL; +} diff --git a/extensions/source/plugin/unx/sysplug.cxx b/extensions/source/plugin/unx/sysplug.cxx index 7cec283fe..301a413c7 100644 --- a/extensions/source/plugin/unx/sysplug.cxx +++ b/extensions/source/plugin/unx/sysplug.cxx @@ -2,9 +2,9 @@ * * $RCSfile: sysplug.cxx,v $ * - * $Revision: 1.1.1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: hr $ $Date: 2000-09-18 16:16:51 $ + * last change: $Author: pl $ $Date: 2001-10-23 17:31:20 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -58,212 +58,74 @@ * * ************************************************************************/ +#include <cstdarg> -#include <string> // workaround for SUNPRO workshop include conflicts +#include <sys/types.h> +#include <signal.h> +#include <osl/thread.h> #include <plugin/impl.hxx> -#include <dlfcn.h> +int UnxPluginComm::nConnCounter = 0; + +UnxPluginComm::UnxPluginComm( + const String& mimetype, + const String& library, + XLIB_Window aParent, + int nDescriptor1, + int nDescriptor2 + ) : + PluginComm( ::rtl::OUStringToOString( library, osl_getThreadTextEncoding() ) ), + PluginConnector( nDescriptor2 ) +{ + char pDesc[32]; + char pWindow[32]; + sprintf( pWindow, "%d", aParent ); + sprintf( pDesc, "%d", nDescriptor1 ); + ByteString aLib( library, osl_getThreadTextEncoding() ); + + char* pArgs[5]; + pArgs[0] = "pluginapp.bin"; + pArgs[1] = pDesc; + pArgs[2] = const_cast<char*>(aLib.GetBuffer()); + pArgs[3] = pWindow; + pArgs[4] = NULL; -extern NPNetscapeFuncs aNPNFuncs; - -UnxPluginComm::UnxPluginComm( const ::rtl::OString& library ) : - PluginComm( library ), - m_pLibrary( NULL ), - m_bInit( FALSE ) -{ - m_pLibrary = dlopen( library.getStr(), RTLD_NOW ); - - // initialize plugin function table - memset( &m_aFuncs, 0, sizeof( m_aFuncs ) ); - m_aFuncs.size = sizeof( m_aFuncs ); - m_aFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; - - if( m_pLibrary ) - { - NPError (*initFunc)(NPNetscapeFuncs*, NPPluginFuncs* ); - NPError (*initPlugin)(); - - initFunc = (NPError(*)(NPNetscapeFuncs*,NPPluginFuncs*))dlsym( m_pLibrary, "NP_Initialize" ); - initPlugin = (NPError(*)())dlsym( m_pLibrary, "NPP_Initialize" ); -#ifdef DEBUG - if( ! initFunc ) - fprintf( stderr, "could not get Symbol NP_Initialize\n" ); - if( ! initPlugin ) - fprintf( stderr, "could not get Symbol NPP_Initialize\n" ); -#endif - if( initFunc && initPlugin ) - { - NPError aErr = initFunc( &aNPNFuncs, &m_aFuncs ); #ifdef DEBUG - fprintf( stderr, "NP_Initialize returns %d\n", aErr ); + m_nCommPID = 10; + fprintf( stderr, "Try to launch: %s %s %s %s, descriptors are %d, %d\n", pArgs[0], pArgs[1], pArgs[2], pArgs[3], nDescriptor1, nDescriptor2 ); #endif - if( aErr ) - { - aErr = initPlugin(); -#ifdef DEBUG - fprintf( stderr, "NPP_Initialize returns %d\n", aErr ); -#endif - } - m_aFuncs.newp = (NPP_NewUPP)dlsym( m_pLibrary, "NPP_New" ); - m_aFuncs.destroy = (NPP_DestroyUPP)dlsym( m_pLibrary, "NPP_Destroy" ); - m_aFuncs.setwindow = (NPP_SetWindowUPP)dlsym( m_pLibrary, "NPP_SetWindow" ); - m_aFuncs.newstream = (NPP_NewStreamUPP)dlsym( m_pLibrary, "NPP_NewStream" ); - m_aFuncs.destroystream = (NPP_DestroyStreamUPP)dlsym( m_pLibrary, "NPP_DestroyStream" ); - m_aFuncs.asfile = (NPP_StreamAsFileUPP)dlsym( m_pLibrary, "NPP_StreamAsFile" ); - m_aFuncs.writeready = (NPP_WriteReadyUPP)dlsym( m_pLibrary, "NPP_WriteReady" ); - m_aFuncs.write = (NPP_WriteUPP)dlsym( m_pLibrary, "NPP_Write" ); - m_aFuncs.print = (NPP_PrintUPP)dlsym( m_pLibrary, "NPP_Print" ); - m_aFuncs.event = NULL; - m_aFuncs.javaClass = NULL; - m_aFuncs.urlnotify = (NPP_URLNotifyUPP)dlsym( m_pLibrary, "NPP_URLNotify" ); - m_aFuncs.getvalue =(NPP_GetValueUPP)dlsym( m_pLibrary, "NPP_GetValue" ); - m_aFuncs.setvalue =(NPP_SetValueUPP)dlsym( m_pLibrary, "NPP_SetValue" ); - - m_bInit = TRUE; - } - } - if( ! m_bInit ) + if( ! ( m_nCommPID = fork() ) ) + { + execvp( pArgs[0], pArgs ); + fprintf( stderr, "Error: could not exec %s\n", pArgs[0] ); + exit(255); + } + + if( m_nCommPID != -1 ) { - dlclose( m_pLibrary ); - m_pLibrary = NULL; + // wait for pluginapp.bin to start up + if( ! WaitForMessage( 5000 ) ) + { + fprintf( stderr, "Timeout on command: %s %s %s %s\n", pArgs[0], pArgs[1], pArgs[2], pArgs[3] ); + invalidate(); + } + else + { + MediatorMessage* pMessage = GetNextMessage( TRUE ); + Respond( pMessage->m_nID, + "init ack",8, + NULL ); + delete pMessage; + NPP_Initialize(); + } } } UnxPluginComm::~UnxPluginComm() { - if( m_bInit && m_pLibrary ) - { - NPP_ShutdownUPP pFunc = (NPP_ShutdownUPP)dlsym( m_pLibrary,"NPP_Shutdown"); - if( pFunc) - pFunc(); - dlclose( m_pLibrary ); - } -} - -//-------------------------------------------------------------------------------------------------- -NPError UnxPluginComm::NPP_Destroy( NPP instance, NPSavedData** save ) -{ - DBG_ASSERT( m_aFuncs.destroy, "### NPP_Destroy(): null pointer in NPP functions table!" ); - return (m_aFuncs.destroy - ? m_aFuncs.destroy( instance, save ) - : NPERR_GENERIC_ERROR); -} - -//-------------------------------------------------------------------------------------------------- -NPError UnxPluginComm::NPP_DestroyStream( NPP instance, NPStream* stream, NPError reason ) -{ - DBG_ASSERT( m_aFuncs.destroystream, "### NPP_DestroyStream(): null pointer in NPP functions table!" ); - return (m_aFuncs.destroystream - ? m_aFuncs.destroystream( instance, stream, reason ) - : NPERR_GENERIC_ERROR); -} - -//-------------------------------------------------------------------------------------------------- -NPError UnxPluginComm::NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, - char* argn[], char* argv[], NPSavedData *saved ) -{ - DBG_ASSERT( m_aFuncs.newp, "### NPP_New(): null pointer in NPP functions table!" ); - return (m_aFuncs.newp - ? m_aFuncs.newp( pluginType, instance, mode, argc, argn, argv, saved ) - : NPERR_GENERIC_ERROR); + NPP_Shutdown(); + if( m_nCommPID != -1 && m_nCommPID != 0 ) + kill( m_nCommPID, 9 ); } - -//-------------------------------------------------------------------------------------------------- -NPError UnxPluginComm::NPP_NewStream( NPP instance, NPMIMEType type, NPStream* stream, - NPBool seekable, uint16* stype ) -{ - DBG_ASSERT( m_aFuncs.newstream, "### NPP_NewStream(): null pointer in NPP functions table!" ); - return (m_aFuncs.newstream - ? m_aFuncs.newstream( instance, type, stream, seekable, stype ) - : NPERR_GENERIC_ERROR); -} - -//-------------------------------------------------------------------------------------------------- -void UnxPluginComm::NPP_Print( NPP instance, NPPrint* platformPrint ) -{ - DBG_ASSERT( m_aFuncs.print, "### NPP_Print(): null pointer in NPP functions table!" ); - if (m_aFuncs.print) - m_aFuncs.print( instance, platformPrint ); -} - -//-------------------------------------------------------------------------------------------------- -NPError UnxPluginComm::NPP_SetWindow( NPP instance, NPWindow* window ) -{ - DBG_ASSERT( m_aFuncs.setwindow, "### NPP_SetWindow(): null pointer in NPP functions table!" ); - return (m_aFuncs.setwindow - ? m_aFuncs.setwindow( instance, window ) - : NPERR_GENERIC_ERROR); -} - -//-------------------------------------------------------------------------------------------------- -void UnxPluginComm::NPP_StreamAsFile( NPP instance, NPStream* stream, const char* fname ) -{ - DBG_ASSERT( m_aFuncs.asfile, "### NPP_StreamAsFile(): null pointer in NPP functions table!" ); - if (m_aFuncs.asfile) - m_aFuncs.asfile( instance, stream, fname ); -} - -//-------------------------------------------------------------------------------------------------- -void UnxPluginComm::NPP_URLNotify( NPP instance, const char* url, NPReason reason, void* notifyData ) -{ - DBG_ASSERT( m_aFuncs.urlnotify, "### NPP_URLNotify(): null pointer in NPP functions table!" ); - if (m_aFuncs.urlnotify) - m_aFuncs.urlnotify( instance, url, reason, notifyData ); -} - -//-------------------------------------------------------------------------------------------------- -int32 UnxPluginComm::NPP_Write( NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer ) -{ - DBG_ASSERT( m_aFuncs.write, "### NPP_Write(): null pointer in NPP functions table!" ); - return (m_aFuncs.write - ? m_aFuncs.write( instance, stream, offset, len, buffer ) - : 0); -} - -//-------------------------------------------------------------------------------------------------- -int32 UnxPluginComm::NPP_WriteReady( NPP instance, NPStream* stream ) -{ - DBG_ASSERT( m_aFuncs.writeready, "### NPP_WriteReady(): null pointer in NPP functions table!" ); - return (m_aFuncs.writeready - ? m_aFuncs.writeready( instance, stream ) - : 0); -} - -//-------------------------------------------------------------------------------------------------- -NPError UnxPluginComm::NPP_GetValue( NPP instance, NPPVariable variable, void *ret_alue ) -{ - DBG_ASSERT( m_aFuncs.getvalue, "### NPP_GetValue(): null pointer in NPP functions table!" ); - return (m_aFuncs.getvalue - ? m_aFuncs.getvalue( instance, variable, ret_alue ) - : NPERR_GENERIC_ERROR); -} - -//-------------------------------------------------------------------------------------------------- -NPError UnxPluginComm::NPP_SetValue( NPP instance, NPNVariable variable, void *ret_alue ) -{ - DBG_ASSERT( m_aFuncs.setvalue, "### NPP_SetValue(): null pointer in NPP functions table!" ); - return (m_aFuncs.setvalue - ? m_aFuncs.setvalue( instance, variable, ret_alue ) - : NPERR_GENERIC_ERROR); -} - -//-------------------------------------------------------------------------------------------------- -void* UnxPluginComm::NPP_GetJavaClass() -{ - DBG_ERROR( "no java class available!" ); - return 0; -} - -//-------------------------------------------------------------------------------------------------- -NPError UnxPluginComm::NPP_Initialize() -{ - return NPERR_NO_ERROR; -} - -//-------------------------------------------------------------------------------------------------- -void UnxPluginComm::NPP_Shutdown() -{ -} - diff --git a/extensions/source/plugin/unx/unxmgr.cxx b/extensions/source/plugin/unx/unxmgr.cxx index 87029a9e8..a4a6cdec5 100644 --- a/extensions/source/plugin/unx/unxmgr.cxx +++ b/extensions/source/plugin/unx/unxmgr.cxx @@ -2,9 +2,9 @@ * * $RCSfile: unxmgr.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: pl $ $Date: 2001-06-07 09:56:27 $ + * last change: $Author: pl $ $Date: 2001-10-23 17:31:20 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -58,31 +58,26 @@ * * ************************************************************************/ -#ifdef SOLARIS -#include <limits> -#endif - -#if STLPORT_VERSION>=321 #include <cstdarg> -#endif - #include <sys/stat.h> +#include <sys/types.h> +#include <dirent.h> #include <dlfcn.h> +#include <osl/thread.h> #include <vcl/svapp.hxx> #include <plugin/impl.hxx> -#include <dirent.h> +using namespace com::sun::star::uno; +using namespace com::sun::star::plugin; // Unix specific implementation -static ::com::sun::star::plugin::PluginDescription** CheckPlugin( const ByteString& rPath, int& rDescriptions ) +static PluginDescription** CheckPlugin( const ByteString& rPath, int& rDescriptions ) { - ::com::sun::star::plugin::PluginDescription** pRet = NULL; + rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); + PluginDescription** pRet = NULL; rDescriptions = 0; - struct stat aStat; - if( stat( rPath.GetBuffer(), &aStat ) ) - return NULL; void *pLib = dlopen( rPath.GetBuffer(), RTLD_LAZY ); if( ! pLib ) return NULL; @@ -99,94 +94,121 @@ static ::com::sun::star::plugin::PluginDescription** CheckPlugin( const ByteStri cTok = ':'; ByteString aExtension = aMIME.GetToken( 1, cTok ); int nExtensions = aExtension.GetTokenCount( ',' ); - pRet = new ::com::sun::star::plugin::PluginDescription*[ nExtensions ]; + pRet = new PluginDescription*[ nExtensions ]; for( int i = 0; i < nExtensions; i++ ) { - pRet[i] = new ::com::sun::star::plugin::PluginDescription; - pRet[i]->PluginName = String( rPath, gsl_getSystemTextEncoding() ); - pRet[i]->Mimetype = String( aMIME.GetToken( 0, cTok ), gsl_getSystemTextEncoding() ); - String aExt( RTL_CONSTASCII_USTRINGPARAM( "*." ) ); - aExt += String( aExtension.GetToken( i, ',' ).EraseLeadingChars().EraseTrailingChars(), gsl_getSystemTextEncoding() ); - pRet[i]->Extension = aExt; - pRet[i]->Description= String( aMIME.GetToken( 2, cTok ), gsl_getSystemTextEncoding() ); + pRet[i] = new PluginDescription; + pRet[i]->PluginName = String( rPath, aEncoding ); + pRet[i]->Mimetype = String( aMIME.GetToken( 0, cTok ), aEncoding ); + ByteString aExt( "*." ); + aExt += aExtension.GetToken( i, ',' ).EraseLeadingChars().EraseTrailingChars(); + pRet[i]->Extension = String( aExt, aEncoding ); + pRet[i]->Description= String( aMIME.GetToken( 2, cTok ), aEncoding ); } rDescriptions = nExtensions; } // some libraries register atexit handlers when loaded // (e.g. g++ made libraries register global destructors) - // not closing them does prevent them to be called when already unloaded + // not closing them does prevent this // dlclose( pLib ); return pRet; } -Sequence< ::com::sun::star::plugin::PluginDescription > XPluginManager_Impl::getPluginDescriptions() +Sequence<PluginDescription> XPluginManager_Impl::getPluginDescriptions() throw() { - static Sequence< ::com::sun::star::plugin::PluginDescription > aDescriptions; + static Sequence<PluginDescription> aDescriptions; static BOOL bHavePlugins = FALSE; if( ! bHavePlugins ) { - NAMESPACE_STD(list)< ::com::sun::star::plugin::PluginDescription* > aPlugins; + rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); + NAMESPACE_STD(list)<PluginDescription*> aPlugins; int i; // unix: search for plugins in /usr/lib/netscape/plugins, // ~/.netscape/plugins und NPX_PLUGIN_PATH // additionally: search in PluginsPath + static const char* pHome = getenv( "HOME" ); + static const char* pNPXPluginPath = getenv( "NPX_PLUGIN_PATH" ); - const char* pEnv = getenv( "HOME" ); - - String aSearchPath( RTL_CONSTASCII_USTRINGPARAM( "/usr/lib/netscape/plugins:" ) ); - aSearchPath += String( pEnv ? pEnv : "", gsl_getSystemTextEncoding() ); - aSearchPath += String( RTL_CONSTASCII_USTRINGPARAM( "/.netscape/plugins:" ) ); - pEnv = getenv( "NPX_PLUGIN_PATH" ); - aSearchPath += String( pEnv ? pEnv : "", gsl_getSystemTextEncoding() ); + ByteString aSearchPath( "/usr/lib/netscape/plugins" ); + if( pHome ) + { + aSearchPath.Append( ':' ); + aSearchPath.Append( pHome ); + aSearchPath += "/.netscape/plugins"; + } + if( pNPXPluginPath ) + { + aSearchPath.Append( ':' ); + aSearchPath += pNPXPluginPath; + } - const Sequence< ::rtl::OUString >& rPaths = PluginManager::getAdditionalSearchPaths(); + const Sequence< ::rtl::OUString >& rPaths( PluginManager::getAdditionalSearchPaths() ); for( i = 0; i < rPaths.getLength(); i++ ) { - aSearchPath += ':'; - aSearchPath += String( rPaths.getConstArray()[i] ); + aSearchPath += ":"; + aSearchPath += ByteString( String( rPaths.getConstArray()[i] ), aEncoding ); } + long aBuffer[ sizeof( struct dirent ) + _PC_NAME_MAX +1 ]; int nPaths = aSearchPath.GetTokenCount( ':' ); for( i = 0; i < nPaths; i++ ) { - ByteString aPath( aSearchPath.GetToken( i, ':' ), gsl_getSystemTextEncoding() ); + ByteString aPath( aSearchPath.GetToken( i, ':' ) ); if( aPath.Len() ) { DIR* pDIR = opendir( aPath.GetBuffer() ); - struct dirent aEntry; - struct dirent* pEntry; - - while( pDIR && readdir_r( pDIR, &aEntry, &pEntry ) ) + struct dirent* pDirEnt = NULL; + while( pDIR && ! readdir_r( pDIR, (struct dirent*)aBuffer, &pDirEnt ) && pDirEnt ) { - if( strncmp( aEntry.d_name, "libnullplugin", 13 ) && - strcmp( aEntry.d_name, "npnrvp.so" ) && - strcmp( aEntry.d_name, "libnprvp.so" ) ) + struct stat aStat; + ByteString aFileName( aPath ); + aFileName += "/"; + aFileName += ((struct dirent*)aBuffer)->d_name; + if( ! stat( aFileName.GetBuffer(), &aStat ) + && S_ISREG( aStat.st_mode ) + && strncmp( ((struct dirent*)aBuffer)->d_name, "libnullplugin", 13 ) + ) { - struct stat aStat; - ByteString aFile( aPath ); - aFile += '/'; - aFile += aEntry.d_name; - if( ! stat( aFile.GetBuffer(), &aStat ) && - S_ISREG( aStat.st_mode ) ) +#if defined DEBUG + fprintf( stderr, "Trying plugin %s ... ", aFileName.GetBuffer() ); +#endif + int nStructs; + PluginDescription** pStructs = + CheckPlugin( aFileName, nStructs ); + if( pStructs ) { - int nStructs; - ::com::sun::star::plugin::PluginDescription** pStructs = - CheckPlugin( aFile, nStructs ); - if( pStructs ) +#if defined DEBUG + fprintf( stderr, "success: %d\n", nStructs ); +#endif + for( int i = 0; i < nStructs; i++ ) { - for( int i = 0; i < nStructs; i++ ) - aPlugins.push_back( pStructs[i] ); - delete pStructs; + aPlugins.push_back( pStructs[i] ); +#if defined DEBUG + fprintf( stderr, "Mimetype: %s\nExtension: %s\n" + "Description: %s\n", + ::rtl::OUStringToOString( pStructs[i]->Mimetype, aEncoding ).getStr(), + ::rtl::OUStringToOString( pStructs[i]->Extension, aEncoding ).getStr(), + ::rtl::OUStringToOString( pStructs[i]->Description, aEncoding ).getStr() + ); +#endif } + delete pStructs; } +#if defined DEBUG + else + fprintf(stderr, "failed\n" ); +#endif } } + if( pDIR ) + closedir( pDIR ); } } - aDescriptions = Sequence< ::com::sun::star::plugin::PluginDescription >( aPlugins.size() ); - NAMESPACE_STD(list)< ::com::sun::star::plugin::PluginDescription* >::iterator iter; + aDescriptions = Sequence<PluginDescription>( aPlugins.size() ); + DBG_ASSERT( aPlugins.size(), "No Plugins Found !!\n" ); + NAMESPACE_STD(list)<PluginDescription*>::iterator iter; for( iter = aPlugins.begin(), i=0; iter != aPlugins.end(); ++iter ,i++ ) { aDescriptions.getArray()[ i ] = **iter; |