Files
loongoffice/extensions/source/plugin/unx/npnapi.cxx
Noel Grandin 7ae4102f17 extensions: sal_Bool->bool
Change-Id: I1730f99c08690138e9aa7aba54304fd7bc51491d
2014-05-02 08:49:22 +02:00

951 lines
34 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org 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 version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifdef AIX
#define _LINUX_SOURCE_COMPAT
#include <sys/timer.h>
#undef _LINUX_SOURCE_COMPAT
#endif
#include <plugin/unx/plugcon.hxx>
#include <unistd.h>
#include <dlfcn.h>
#include <osl/module.h>
#include <config_vclplug.h>
#include <npwrap.hxx>
extern PluginConnector* pConnector;
extern XtAppContext app_context;
extern int wakeup_fd[];
extern Widget topLevel, topBox;
extern Display* pAppDisplay;
extern Display* pXtAppDisplay;
extern int nAppArguments;
extern char** pAppArguments;
// begin Netscape plugin api calls
extern "C" {
static void* l_NPN_MemAlloc( uint32_t nBytes )
{
void* pMem = new char[nBytes];
return pMem;
}
static void l_NPN_MemFree( void* pMem )
{
delete [] (char*)pMem;
}
static uint32_t l_NPN_MemFlush( uint32_t /*nSize*/ )
{
return 0;
}
static NPError l_NPN_DestroyStream( NPP instance, NPStream* stream, NPError reason )
{
sal_uInt32 nInstance = pConnector->GetNPPID( instance );
if( nInstance == PluginConnector::UnknownNPPID )
return NPERR_GENERIC_ERROR;
sal_uInt32 nFileID = pConnector->GetStreamID( stream );
MediatorMessage* pMes=
pConnector->
Transact( eNPN_DestroyStream,
&nInstance, sizeof( nInstance ),
&nFileID, sizeof( nFileID ),
POST_STRING( stream->url ),
&reason, sizeof( reason ),
NULL );
if( ! pMes )
return NPERR_GENERIC_ERROR;
for( std::vector< NPStream* >::iterator it = pConnector->getStreamList().begin();
it != pConnector->getStreamList().end(); ++it )
{
if( *it == stream )
{
pConnector->getStreamList().erase( it );
break;
}
}
delete [] stream->url;
delete stream;
// returns NPError
NPError aRet = pConnector->GetNPError( pMes );
delete pMes;
return aRet;
}
#ifdef OJI
static JRIEnv* l_NPN_GetJavaEnv()
{
// no java in this program
SAL_INFO("extensions.plugin", "SNI: NPN_GetJavaEnv");
return NULL;
}
static jref l_NPN_GetJavaPeer( NPP /*instance*/ )
{
SAL_INFO("extensions.plugin", "SNI: NPN_GetJavaPeer");
return NULL;
}
#endif
static NPError l_NPN_GetURL( NPP instance, const char* url, const char* window )
{
sal_uInt32 nInstance = pConnector->GetNPPID( instance );
if( nInstance == PluginConnector::UnknownNPPID )
return NPERR_GENERIC_ERROR;
MediatorMessage* pMes=
pConnector->
Transact( eNPN_GetURL,
&nInstance, sizeof( nInstance ),
POST_STRING(url),
POST_STRING(window),
NULL );
SAL_WARN_IF(!pMes, "extensions.plugin", "geturl: message unanswered");
if( ! pMes )
return NPERR_GENERIC_ERROR;
// returns NPError
NPError aRet = pConnector->GetNPError( pMes );
SAL_WARN_IF(aRet, "extensions.plugin", "geturl returns " << aRet);
delete pMes;
return aRet;
}
static NPError l_NPN_GetURLNotify( NPP instance, const char* url, const char* target,
void* notifyData )
{
sal_uInt32 nInstance = pConnector->GetNPPID( instance );
if( nInstance == PluginConnector::UnknownNPPID )
return NPERR_GENERIC_ERROR;
MediatorMessage* pMes=
pConnector->
Transact( eNPN_GetURLNotify,
&nInstance, sizeof( nInstance ),
POST_STRING(url),
POST_STRING(target),
&notifyData, 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;
}
static NPError l_NPN_NewStream( NPP instance, NPMIMEType type, const char* target,
NPStream** stream )
// stream is a return value
{
sal_uInt32 nInstance = pConnector->GetNPPID( instance );
if( nInstance == PluginConnector::UnknownNPPID )
return NPERR_GENERIC_ERROR;
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();
pStream->ndata = pStream->pdata = pStream->notifyData = NULL;
pConnector->getStreamList().push_back( pStream );
*stream = pStream;
}
delete pMes;
return aRet;
}
static NPError l_NPN_PostURLNotify( NPP instance, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData )
{
sal_uInt32 nInstance = pConnector->GetNPPID( instance );
if( nInstance == PluginConnector::UnknownNPPID )
return NPERR_GENERIC_ERROR;
MediatorMessage* pMes = pConnector->
Transact( eNPN_PostURLNotify,
&nInstance, sizeof( nInstance ),
POST_STRING( url ),
POST_STRING( target ),
&len, sizeof( len ),
buf, len,
&file, sizeof( NPBool ),
&notifyData, sizeof( void* ), // send the real pointer
NULL );
if( ! pMes )
return NPERR_GENERIC_ERROR;
NPError aRet = pConnector->GetNPError( pMes );
delete pMes;
return aRet;
}
static NPError l_NPN_PostURL( NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file )
{
sal_uInt32 nInstance = pConnector->GetNPPID( instance );
if( nInstance == PluginConnector::UnknownNPPID )
return NPERR_GENERIC_ERROR;
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;
}
static NPError l_NPN_RequestRead( NPStream* stream, NPByteRange* rangeList )
{
SAL_INFO("extensions.plugin", "pluginapp: NPN_RequestRead");
NPByteRange* pRange = rangeList;
sal_uInt32 nRanges = 0;
while( pRange )
{
nRanges++;
pRange = pRange->next;
}
sal_uInt32* pArray = new sal_uInt32[ 2 * nRanges ];
pRange = rangeList;
sal_uInt32 n = 0;
while( pRange )
{
pArray[ 2*n ] = (sal_uInt32)pRange->offset;
pArray[ 2*n + 1] = (sal_uInt32)pRange->length;
n++;
pRange = pRange->next;
}
sal_uInt32 nFileID = pConnector->GetStreamID( stream );
MediatorMessage* pMes = pConnector->
Transact( eNPN_RequestRead,
&nFileID, sizeof( nFileID ),
&nRanges, sizeof( nRanges ),
pArray, sizeof( sal_uInt32 ) * 2 * nRanges,
NULL );
if( ! pMes )
{
delete[] pArray;
return NPERR_GENERIC_ERROR;
}
NPError aRet = pConnector->GetNPError( pMes );
delete [] pArray;
delete pMes;
return aRet;
}
static void l_NPN_Status( NPP instance, const char* message )
{
sal_uInt32 nInstance = pConnector->GetNPPID( instance );
if( nInstance == PluginConnector::UnknownNPPID )
return;
pConnector->Send( eNPN_Status,
&nInstance, sizeof( nInstance ),
POST_STRING( message ),
NULL );
}
static const char* l_NPN_UserAgent( NPP instance )
{
static char* pAgent = NULL;
sal_uInt32 nInstance = pConnector->GetNPPID( instance );
if( nInstance == PluginConnector::UnknownNPPID )
{
if( instance )
return "Mozilla 3.0";
else // e.g. flashplayer calls NPN_UserAgent with NULL
nInstance = 0;
}
MediatorMessage* pMes = pConnector->
Transact( eNPN_UserAgent,
&nInstance, sizeof( nInstance ),
NULL );
if( ! pMes )
return pAgent;
if( pAgent )
delete [] pAgent;
pAgent = pMes->GetString();
delete pMes;
SAL_INFO("extensions.plugin", "NPN_UserAgent returns " << pAgent);
return pAgent;
}
static int32_t l_NPN_Write( NPP instance, NPStream* stream, int32_t len, void* buffer )
{
sal_uInt32 nFileID = pConnector->GetStreamID( stream );
if( nFileID == PluginConnector::UnknownStreamID )
return NPERR_GENERIC_ERROR;
sal_uInt32 nInstance = pConnector->GetNPPID( instance );
if( nInstance == PluginConnector::UnknownNPPID )
return NPERR_GENERIC_ERROR;
MediatorMessage* pMes = pConnector->
Transact( eNPN_Write,
&nInstance, sizeof( nInstance ),
&nFileID, sizeof( nFileID ),
&len, sizeof( len ),
buffer, len,
NULL );
if( ! pMes )
return 0;
sal_Int32 nRet = pMes->GetUINT32();
return nRet;
}
static void l_NPN_ReloadPlugins( NPBool /*reloadPages*/ )
{
SAL_INFO("extensions.plugin", "NPN_ReloadPlugins: SNI");
}
static NPError l_NPN_GetValue( NPP, NPNVariable variable, void* value )
{
/*
* We want to handle values injected into a NPNVariable which aren't in
* the old enum we build against, but that we know are in the new enum
* we want to support
*/
switch( (int)variable )
{
case NPNVxDisplay:
*((Display**)value) = pXtAppDisplay;
SAL_INFO("extensions.plugin", "Display requested");
break;
case NPNVxtAppContext:
*((XtAppContext*)value) = app_context;
SAL_INFO("extensions.plugin", "AppContext requested");
break;
case NPNVjavascriptEnabledBool:
// no javascript
*(NPBool*)value = false;
SAL_INFO("extensions.plugin", "javascript enabled requested");
break;
case NPNVasdEnabledBool:
// no SmartUpdate
*(NPBool*)value = false;
SAL_INFO("extensions.plugin", "smart update enabled requested");
break;
case NPNVisOfflineBool:
// no offline browsing
*(NPBool*)value = false;
SAL_INFO("extensions.plugin", "offline browsing requested");
break;
case NPNVSupportsXEmbedBool:
// asking xembed
*(int*)value = int(true);
SAL_INFO("extensions.plugin", "xembed requested");
break;
case NPNVToolkit:
# if ENABLE_GTK
*(int*)value = NPNVGtk2;
# else
*(int*)value = 0;
# endif
SAL_INFO("extensions.plugin", "toolkit requested");
break;
default:
SAL_WARN(
"extensions.plugin",
"unknown NPNVariable " << +variable << " requested");
return NPERR_INVALID_PARAM;
}
return NPERR_NO_ERROR;
}
static NPError l_NPN_SetValue(NPP /*instance*/, NPPVariable variable, void *value)
{
SAL_INFO("extensions.plugin", "NPN_SetValue " << +variable << "=" << value);
return 0;
}
static void l_NPN_InvalidateRect(NPP /*instance*/, NPRect* /*invalidRect*/)
{
SAL_INFO("extensions.plugin", "NPN_InvalidateRect");
}
static void l_NPN_InvalidateRegion(NPP /*instance*/, NPRegion /*invalidRegion*/)
{
SAL_INFO("extensions.plugin", "NPN_InvalidateRegion");
}
static void l_NPN_ForceRedraw(NPP /*instance*/)
{
SAL_INFO("extensions.plugin", "NPN_ForceRedraw");
}
}
static NPNetscapeFuncs aNetscapeFuncs =
{
sizeof(aNetscapeFuncs),
(NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
l_NPN_GetURL,
l_NPN_PostURL,
l_NPN_RequestRead,
l_NPN_NewStream,
l_NPN_Write,
l_NPN_DestroyStream,
l_NPN_Status,
l_NPN_UserAgent,
l_NPN_MemAlloc,
l_NPN_MemFree,
l_NPN_MemFlush,
l_NPN_ReloadPlugins,
# ifdef OJI
l_NPN_GetJavaEnv,
l_NPN_GetJavaPeer,
# else
NULL,
NULL,
# endif
l_NPN_GetURLNotify,
l_NPN_PostURLNotify,
l_NPN_GetValue,
l_NPN_SetValue,
l_NPN_InvalidateRect,
l_NPN_InvalidateRegion,
l_NPN_ForceRedraw
};
static 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
};
oslModule pPluginLib = NULL;
char*(*pNPP_GetMIMEDescription)() = NULL;
NPError (*pNP_Initialize)(NPNetscapeFuncs*,NPPluginFuncs*) = NULL;
NPError (*pNP_Shutdown)() = NULL;
std::vector< PluginConnector* > 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;
while( (pMessage = GetNextMessage( false )) )
{
nCommand = (CommandAtoms)pMessage->GetUINT32();
SAL_INFO(
"extensions.plugin", "pluginapp: " << GetCommandName(nCommand));
switch( nCommand )
{
case eNPP_DestroyStream:
{
sal_uInt32 nInstance = pMessage->GetUINT32();
NPP instance = m_aInstances[ nInstance ]->instance;
sal_uInt32 nFileID = pMessage->GetUINT32();
NPStream* pStream = m_aNPWrapStreams[ nFileID ];
NPError aReason = GetNPError( pMessage );
m_aNPWrapStreams.erase( m_aNPWrapStreams.begin() + nFileID );
aReason = aPluginFuncs.destroystream( instance, pStream, aReason );
Respond( pMessage->m_nID,
(char*)&aReason, sizeof( aReason ),
NULL );
delete [] pStream->url;
delete pStream;
}
break;
case eNPP_Destroy:
{
sal_uInt32 nInstance = pMessage->GetUINT32();
ConnectorInstance* pInst= m_aInstances[ nInstance ];
// some plugin rely on old netscapes behaviour
// to first destroy the widget and then destroy
// the instance, so mimic that behaviour here
if( pInst->pShell )
XtDestroyWidget( (Widget)pInst->pShell );
pInst->pWidget = pInst->pShell = NULL;
// the other side will call eNPP_DestroyPhase2 after this
NPError aReason = NPERR_NO_ERROR;
Respond( pMessage->m_nID, (char*)&aReason, sizeof( aReason ), NULL );
}
break;
case eNPP_DestroyPhase2:
{
// now really destroy the instance
sal_uInt32 nInstance = pMessage->GetUINT32();
ConnectorInstance* pInst= m_aInstances[ nInstance ];
NPP instance = pInst->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 );
delete [] (char*)pSave->buf;
}
else
Respond( pMessage->m_nID,
(char*)&aRet, sizeof( aRet ),
"0000", 4,
NULL );
#if ENABLE_GTK
if( pInst->pGtkWindow )
g_object_unref( G_OBJECT(pInst->pGtkWindow) );
if( pInst->pGtkWidget )
g_object_unref( G_OBJECT(pInst->pGtkWidget) );
#endif
m_aInstances.erase( m_aInstances.begin() + nInstance );
delete pInst;
delete instance;
SAL_INFO(
"extensions.plugin",
"destroyed instance (returning " << aRet << ")");
}
break;
case eNPP_NewStream:
{
sal_uInt32 nInstance = pMessage->GetUINT32();
NPP instance = m_aInstances[ nInstance ]->instance;
char* pType = pMessage->GetString();
NPStream* pStream = new NPStream;
pStream->url = pMessage->GetString();
pStream->end = pMessage->GetUINT32();
pStream->lastmodified = pMessage->GetUINT32();
pStream->pdata = pStream->ndata = pStream->notifyData = NULL;
NPBool* pSeekable = (NPBool*)pMessage->GetBytes();
m_aNPWrapStreams.push_back( pStream );
uint16_t nStype = NP_ASFILE;
NPError aRet = aPluginFuncs.newstream( instance, pType, pStream,
*pSeekable, &nStype );
SAL_INFO(
"extensions.plugin",
"pluginapp: NPP_NewStream(" << instance << ", " << pType
<< ", " << pStream << ", "
<< (*pSeekable ? "seekable" : "not seekable") << ", "
<< &nStype << ") returns " << aRet
<< "; stream = { pdata = " << pStream->pdata
<< ", ndata = " << pStream->ndata << ", url = "
<< pStream->url << ", end = " << pStream->end
<< ", lastmodified = " << pStream->lastmodified
<< ", notifyData = " << pStream->notifyData << " }");
Respond( pMessage->m_nID,
(char*)&aRet, sizeof( aRet ),
&nStype, sizeof( nStype ),
NULL );
delete [] pType;
delete [] pSeekable;
}
break;
case eNPP_New:
{
char* pType = pMessage->GetString();
uint16_t* pMode = (uint16_t*)pMessage->GetBytes();
int16_t* pArgc = (int16_t*)pMessage->GetBytes();
NPP instance = new NPP_t;
instance->pdata = instance->ndata = NULL;
sal_uLong nArgnBytes, nArgvBytes;
char* pArgn = (char*)pMessage->GetBytes( nArgnBytes );
char* pArgv = (char*)pMessage->GetBytes( nArgvBytes );
sal_uLong nSaveBytes;
char* pSavedData = (char*)pMessage->GetBytes( nSaveBytes );
ConnectorInstance* pInst =
new ConnectorInstance( instance, pType,
*pArgc,
pArgn, nArgnBytes,
pArgv, nArgvBytes,
pSavedData, nSaveBytes );
m_aInstances.push_back( pInst );
NPError aRet;
aRet = aPluginFuncs.newp( pInst->pMimeType, instance, *pMode, *pArgc,
pInst->nArg ? pInst->argn : NULL,
pInst->nArg ? pInst->argv : NULL,
( nSaveBytes == 4 && *(sal_uInt32*)pSavedData == 0 ) ?
&(pInst->aData) : NULL );
SAL_INFO(
"extensions.plugin",
"pluginapp: NPP_New( " << pInst->pMimeType << ", "
<< instance << ", " << *pMode << ", " << pInst->nArg
<< ", " << pInst->argn << ", " << pInst->argv << ", "
<< &pInst->aData << ") returns" << aRet);
for( int i = 0; i < pInst->nArg; i++ )
SAL_INFO(
"extensions.plugin",
" \"" << pInst->argn[i] << "\"=\"" << pInst->argv[i]
<< "\"");
#if ENABLE_GTK
// check if XEMBED is to be used
// ask for Bool. there seems to be no clear definition whether the
// return value should be an int or unsigned char
// int can hold both and will be nonzero in case of "true"
if( aPluginFuncs.getvalue )
{
int bNeedsXEmbed = 0;
NPError error = aPluginFuncs.getvalue( instance, NPPVpluginNeedsXEmbed, (void *)&bNeedsXEmbed );
if( error == NPERR_NO_ERROR )
pInst->bShouldUseXEmbed = (bNeedsXEmbed != 0);
SAL_INFO(
"extensions.plugin",
"should use xembed = "
<< (pInst->bShouldUseXEmbed ? "true" : "false"));
}
#endif
Respond( pMessage->m_nID,
(char*)&aRet, sizeof( aRet ),
NULL );
delete [] pMode;
delete [] pArgc;
delete [] pType;
}
break;
case eNPP_SetWindow:
{
sal_uInt32 nInstance = pMessage->GetUINT32();
ConnectorInstance* pInst= m_aInstances[ nInstance ];
NPWindow* pWindow = (NPWindow*)pMessage->GetBytes();
if( pWindow->width < 1 )
pWindow->width = 1;
if( pWindow->height < 1 )
pWindow->height = 1;
#if ENABLE_GTK
if( pInst->bShouldUseXEmbed )
{
if( ! pInst->pGtkWidget )
{
SAL_INFO(
"extensions.plugin",
"creating gtk plug and socket");
pInst->pGtkWindow = gtk_plug_new((GdkNativeWindow)reinterpret_cast<sal_uIntPtr>(pWindow->window));
gtk_widget_show( pInst->pGtkWindow );
pInst->pGtkWidget = gtk_socket_new();
gtk_widget_show( pInst->pGtkWidget );
gtk_container_add( GTK_CONTAINER(pInst->pGtkWindow), pInst->pGtkWidget );
gtk_widget_show_all( pInst->pGtkWindow );
pInst->window.window = (void *)(sal_uIntPtr)gtk_socket_get_id( GTK_SOCKET(pInst->pGtkWidget ) );
XSync( pAppDisplay, False );
XMapWindow( pAppDisplay, GDK_WINDOW_XWINDOW(pInst->pGtkWindow->window) );
XSync( pAppDisplay, False );
}
// update widget size; alas out parent is not yet really XEMBED conformant
gtk_widget_set_size_request( pInst->pGtkWidget, pWindow->width, pWindow->height );
gtk_window_resize( GTK_WINDOW(pInst->pGtkWindow), pWindow->width, pWindow->height );
GdkScreen* pGdkScreen = gtk_widget_get_screen( pInst->pGtkWidget );
Screen* pScreen = ScreenOfDisplay( pAppDisplay, gdk_screen_get_number( pGdkScreen ) );
pInst->window.x = 0;
pInst->window.y = 0;
pInst->window.width = pWindow->width;
pInst->window.height = pWindow->height;
pInst->window.clipRect.left = 0;
pInst->window.clipRect.top = 0;
pInst->window.clipRect.right = pWindow->width;
pInst->window.clipRect.bottom = pWindow->height;
pInst->window.ws_info = &pInst->ws_info;
pInst->window.type = NPWindowTypeWindow;
pInst->ws_info.type = NP_SETWINDOW;
pInst->ws_info.display = pAppDisplay;
pInst->ws_info.visual = DefaultVisualOfScreen( pScreen );
pInst->ws_info.colormap = DefaultColormapOfScreen( pScreen );
pInst->ws_info.depth = DefaultDepthOfScreen( pScreen );
}
else
#endif
{
if( ! pInst->pWidget )
{
pInst->pWidget = CreateNewShell( &(pInst->pShell), (XLIB_Window)pWindow->window );
}
// fill in NPWindow and NPCallbackStruct
pInst->window.window = (void*)XtWindow( (Widget)pInst->pWidget );
pInst->window.x = 0;
pInst->window.y = 0;
pInst->window.width = pWindow->width;
pInst->window.height = pWindow->height;
pInst->window.clipRect.left = 0;
pInst->window.clipRect.top = 0;
pInst->window.clipRect.right = pWindow->width;
pInst->window.clipRect.bottom = pWindow->height;
pInst->window.ws_info = &pInst->ws_info;
pInst->window.type = NPWindowTypeWindow;
pInst->ws_info.type = NP_SETWINDOW;
pInst->ws_info.display = XtDisplay( (Widget)pInst->pWidget );
pInst->ws_info.visual = DefaultVisualOfScreen( XtScreen( (Widget)pInst->pWidget ) );
pInst->ws_info.colormap = DefaultColormapOfScreen( XtScreen( (Widget)pInst->pWidget ) );
pInst->ws_info.depth = DefaultDepthOfScreen( XtScreen( (Widget)pInst->pWidget ) );
XtResizeWidget( (Widget)pInst->pShell,
pInst->window.width,
pInst->window.height,
0 );
XtResizeWidget( (Widget)pInst->pWidget,
pInst->window.width,
pInst->window.height,
0 );
}
NPError aRet = aPluginFuncs.setwindow( pInst->instance, &pInst->window );
SAL_INFO(
"extensions.plugin",
"pluginapp: NPP_SetWindow returns " << aRet);
Respond( pMessage->m_nID,
(char*)&aRet, sizeof( aRet ),
NULL );
delete [] (char*)pWindow;
}
break;
case eNPP_StreamAsFile:
{
sal_uInt32 nInstance = pMessage->GetUINT32();
NPP instance = m_aInstances[ nInstance ]->instance;
sal_uInt32 nFileID = pMessage->GetUINT32();
NPStream* pStream = m_aNPWrapStreams[ nFileID ];
char* fname = pMessage->GetString();
SAL_INFO(
"extensions.plugin",
"pluginapp: NPP_StreamAsFile " << fname);
aPluginFuncs.asfile( instance, pStream, fname );
delete [] fname;
}
break;
case eNPP_URLNotify:
{
sal_uInt32 nInstance = pMessage->GetUINT32();
NPP instance = m_aInstances[ 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:
{
sal_uInt32 nInstance = pMessage->GetUINT32();
NPP instance = m_aInstances[ nInstance ]->instance;
sal_uInt32 nFileID = pMessage->GetUINT32();
NPStream* pStream = m_aNPWrapStreams[ nFileID ];
int32_t nRet = aPluginFuncs.writeready( instance, pStream );
SAL_INFO(
"extensions.plugin",
"pluginapp: NPP_WriteReady(" << instance << ", " << pStream
<< ") (stream id = " << nFileID << ") returns "
<< nRet);
Respond( pMessage->m_nID,
(char*)&nRet, sizeof( nRet ),
NULL );
}
break;
case eNPP_Write:
{
sal_uInt32 nInstance = pMessage->GetUINT32();
NPP instance = m_aInstances[ nInstance ]->instance;
sal_uInt32 nFileID = pMessage->GetUINT32();
NPStream* pStream = m_aNPWrapStreams[ nFileID ];
int32_t offset = pMessage->GetUINT32();
sal_uLong len;
char* buffer = (char*)pMessage->GetBytes( len );
int32_t nRet = aPluginFuncs.write( instance, pStream, offset, len, buffer );
SAL_INFO(
"extensions.plugin",
"pluginapp: NPP_Write(" << instance << ", " << pStream
<< ", " << offset << ", " << len << ", " << buffer
<< ") returns " << nRet << "; stream = { pdata = "
<< pStream->pdata << ", ndata = " << pStream->ndata
<< ", url = " << pStream->url << ", end = "
<< pStream->end << ", lastmodified = "
<< pStream->lastmodified << ", notifyData = "
<< pStream->notifyData << " }");
Respond( pMessage->m_nID,
(char*)&nRet, sizeof( nRet ),
NULL );
delete [] buffer;
}
break;
case eNPP_GetMIMEDescription:
{
if( ! pNPP_GetMIMEDescription )
pNPP_GetMIMEDescription = (char*(*)())
osl_getAsciiFunctionSymbol( pPluginLib, "NPP_GetMIMEDescription" );
char* pMIME = pNPP_GetMIMEDescription();
Respond( pMessage->m_nID,
POST_STRING( pMIME ),
NULL );
}
break;
case eNPP_Initialize:
{
pNP_Initialize =
(NPError(*)(NPNetscapeFuncs*, NPPluginFuncs*))
osl_getAsciiFunctionSymbol( pPluginLib, "NP_Initialize" );
SAL_WARN_IF(
!pNP_Initialize, "extensions.plugin",
"no NP_Initialize, " << dlerror());
pNP_Shutdown = (NPError(*)())
osl_getAsciiFunctionSymbol( pPluginLib, "NP_Shutdown" );
SAL_WARN_IF(
!pNP_Initialize, "extensions.plugin",
"no NP_Shutdown, " << dlerror());
SAL_INFO("extensions.plugin", "entering NP_Initialize");
NPError aRet = pNP_Initialize( &aNetscapeFuncs, &aPluginFuncs );
SAL_INFO(
"extensions.plugin",
"pluginapp: NP_Initialize returns " << aRet);
Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
}
break;
case eNPP_Shutdown:
{
bool bSuccess = (4 == write(wakeup_fd[1], "xxxx", 4));
SAL_WARN_IF(!bSuccess, "extensions.plugin", "short write");
}
break;
default:
SAL_WARN(
"extensions.plugin",
"caught unknown NPP request " << +nCommand);
break;
}
delete pMessage;
}
return 0;
}
void LoadAdditionalLibs( const char* _pPluginLib )
{
SAL_INFO("extensions.plugin", "LoadAdditionalLibs " << _pPluginLib);
if( ! strncmp( _pPluginLib, "libflashplayer.so", 17 ) )
{
/* #b4951312# flash 7 implicitly assumes a gtk application
* if the API version is greater or equal to 12 (probably
* because they think they run in mozilla then). In that
* case they try to find gtk within the process and crash
* when they don't find it.
*/
aNetscapeFuncs.version = 11;
aPluginFuncs.version = 11;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */