📄 qnp.cpp
字号:
/****************************************************************************** $Id: qt/qnp.cpp 3.2.3 edited Jun 24 17:13 $**** Implementation of Qt extension classes for Netscape Plugin support.**** Created : 970601**** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.**** This file is part of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses may use this file in accordance with the Qt Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/// Remaining Q_WS_X11 considerations:// - What if !piApp upon NPP_NewStream? Are we safe?// - Yes, but users need to know of this: that no GUI can be// done until after setWindow is called.// - Use NPN_GetValue in Communicator4.0 to get the display earlier!// - For ClientMessage events, trap them, and if they are not for us,// untrap them and retransmit them and set a timer to retrap them// after N seconds.// Remaining Q_WS_WIN considerations:// - we need to activateZeroTimers() at some time.// - we need to call winEventFilter on events// - timers:// if ( msg.message == WM_TIMER ) { // timer message received// activateTimer( msg.wParam );// return TRUE;// }// if ( msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ) {// if ( translateKeyCode(msg.wParam) == 0 ) {// TranslateMessage( &msg ); // translate to WM_CHAR// return TRUE;// }// }// - qWinProcessConfigRequests?// Remaining general stuff:// - Provide the "reason" parameter to streamDestroyed// Qt stuff#include <qapplication.h>#include <qeventloop.h>#include <qwidget.h>#include <qobjectlist.h>#include <qcursor.h>#include <qprinter.h>#include <qfile.h>#include <qpainter.h>#include "qnp.h"#include <stdlib.h> // Must be here for Borland C++#include <stdio.h>#include <string.h>#include <time.h>#include <limits.h>#ifdef Q_WS_X11#include <X11/Intrinsic.h>class QNPXtPrivate;class QNPXt : public QEventLoop{public: QNPXt( const char *applicationClass, XtAppContext context = NULL, XrmOptionDescRec *options = 0, int numOptions = 0); ~QNPXt(); XtAppContext applicationContext() const; void registerSocketNotifier( QSocketNotifier * ); void unregisterSocketNotifier( QSocketNotifier * ); static void registerWidget( QWidget* ); static void unregisterWidget( QWidget* ); static bool redeliverEvent( XEvent *event ); static XEvent* lastEvent();protected: bool processEvents( ProcessEventsFlags flags );private: void appStartingUp(); void appClosingDown(); QNPXtPrivate *d;};#define GC GC_QQQ#endifextern "C" {//// Netscape plugin API//#ifdef Q_WS_WIN#ifndef _WINDOWS#define _WINDOWS#endif#endif#ifdef Q_WS_X11#define XP_UNIX#endif// This is to allow mingw support on windows without altering the sun header files#if defined(Q_CC_GNU) && defined(Q_WS_WIN) && !defined(_MSC_VER)#define _MSC_VER 1#include "npapi.h"#undef _MSC_VER#else#include "npapi.h"#endif#ifdef Q_WS_X11#undef XP_UNIX#include "npunix.c"#endif//// Stuff for the NPP_SetWindow function://#ifdef Q_WS_X11#include <X11/Xlib.h>#include <X11/Intrinsic.h>#include <X11/IntrinsicP.h> // for XtCreateWindow#include <X11/Shell.h>#include <X11/StringDefs.h>#include <X11/Xutil.h>#include <X11/Xos.h>//#include <dlfcn.h>#endif#ifdef Q_WS_WIN#include <windows.h>#endif}#ifdef Q_WS_WIN#include "npwin.cpp"#endifstatic QEventLoop* event_loop = 0;static QApplication* application = 0;struct _NPInstance{ uint16 fMode;#ifdef Q_WS_WIN HWND window;#endif NPP npp;#ifdef Q_WS_X11 Window window; Display *display;#endif uint32 x, y; uint32 width, height; QNPWidget* widget; QNPInstance* instance; int16 argc; QString *argn; QString *argv;};// The single global pluginstatic QNPlugin *qNP=0;static int instance_count=0;// Temporary parameter passed `around the side' of calls to user functionsstatic _NPInstance* next_pi=0;// To avoid looping when browser OR plugin can delete streamsstatic int qnps_no_call_back = 0;#ifdef Q_WS_WIN// defined in qapplication_win.cppQ_EXPORT extern bool qt_win_use_simple_timers;static HHOOK hhook = 0;LRESULT CALLBACK FilterProc( int nCode, WPARAM wParam, LPARAM lParam ){ if ( qApp ) qApp->sendPostedEvents(); return CallNextHookEx( hhook, nCode, wParam, lParam );}#endif#ifdef Q_WS_X11static int (*original_x_errhandler)( Display *dpy, XErrorEvent * ) = 0;static int dummy_x_errhandler( Display *, XErrorEvent * ){ return 0;}#endif/****************************************************************************** * Plug-in Calls - these are called by Netscape *****************************************************************************/// Instance state information about the plugin.#ifdef Q_WS_X11extern "C" char*NPP_GetMIMEDescription(void){ if (!qNP) qNP = QNPlugin::create(); return (char*)qNP->getMIMEDescription();}extern "C" NPErrorNPP_GetValue(void * /*future*/, NPPVariable variable, void *value){ if (!qNP) qNP = QNPlugin::create(); NPError err = NPERR_NO_ERROR; if (variable == NPPVpluginNameString) *((const char **)value) = qNP->getPluginNameString(); else if (variable == NPPVpluginDescriptionString) *((const char **)value) = qNP->getPluginDescriptionString(); else err = NPERR_GENERIC_ERROR; return err;}#endif/*** NPP_Initialize is called when your DLL is being loaded to do any** DLL-specific initialization.*/extern "C" NPErrorNPP_Initialize(void){#ifdef Q_WS_WIN qt_win_use_simple_timers = TRUE; // Nothing more - we do it in DLLMain#endif if (!qNP) qNP = QNPlugin::create(); return NPERR_NO_ERROR;}static jref plugin_java_class = 0;/*** NPP_GetJavaClass is called during initialization to ask your plugin** what its associated Java class is. If you don't have one, just return** NULL. Otherwise, use the javah-generated "use_" function to both** initialize your class and return it. If you can't find your class, an** error will be signalled by "use_" and will cause the Navigator to** complain to the user.*/extern "C" jrefNPP_GetJavaClass(void){ if (!qNP) qNP = QNPlugin::create(); plugin_java_class = (jref)qNP->getJavaClass(); return plugin_java_class;}/*** NPP_Shutdown is called when your DLL is being unloaded to do any** DLL-specific shut-down. You should be a good citizen and declare that** you're not using your java class any more. This allows java to unload** it, freeing up memory.*/extern "C" voidNPP_Shutdown(void){ if (qNP) { if (plugin_java_class) qNP->unuseJavaClass(); delete qNP; qNP = 0; }#ifdef Q_WS_X11 if ( original_x_errhandler ) XSetErrorHandler( original_x_errhandler );#endif if ( qApp) {#ifdef Q_WS_WIN32 if ( hhook ) UnhookWindowsHookEx( hhook ); hhook = 0;#endif delete application; delete event_loop; }}struct NS_Private { uchar* a; uchar* b;};/*** NPP_New is called when your plugin is instantiated (i.e. when an EMBED** tag appears on a page).*/extern "C" NPErrorNPP_New(NPMIMEType /*pluginType*/, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* /*saved*/){ NPError result = NPERR_NO_ERROR; _NPInstance* This; if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; instance->pdata = new _NPInstance; This = (_NPInstance*) instance->pdata; if (This == NULL) return NPERR_OUT_OF_MEMORY_ERROR; This->npp = instance; /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */ This->fMode = mode; This->window = 0; This->widget = 0; This->argc = argc; This->argn = new QString[argc+1]; This->argv = new QString[argc+1]; for (int i=0; i<This->argc; i++) { This->argn[i] = argn[i]; This->argv[i] = argv[i]; } // Everything is set up - we can let QNPInstance be created now. next_pi = This; qNP->newInstance(); instance_count++; return result;}extern "C" NPErrorNPP_Destroy(NPP instance, NPSavedData** /*save*/){ _NPInstance* This; if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; This = (_NPInstance*) instance->pdata; if (This != NULL) { delete This->widget; delete This->instance; delete [] This->argn; delete [] This->argv; delete This; instance->pdata = NULL; instance_count--; } return NPERR_NO_ERROR;}extern "C" NPErrorNPP_SetWindow(NPP instance, NPWindow* window){ if (!qNP) qNP = QNPlugin::create(); NPError result = NPERR_NO_ERROR; _NPInstance* This; if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; This = (_NPInstance*) instance->pdata; // take a shortcut if all that was changed is the geometry if ( This->widget && window#ifdef Q_WS_X11 && This->window == (Window) window->window#endif#ifdef Q_WS_WIN && This->window == (HWND) window->window#endif ) { This->x = window->x; This->y = window->y; This->width = window->width; This->height = window->height; This->widget->resize( This->width, This->height ); return result; } delete This->widget; if ( !window ) return result;#ifdef Q_WS_X11 This->window = (Window) window->window; This->display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;#endif#ifdef Q_WS_WIN This->window = (HWND) window->window;#endif This->x = window->x; This->y = window->y; This->width = window->width; This->height = window->height; if (!qApp) {#ifdef Q_WS_X11 // We are the first Qt-based plugin to arrive event_loop = new QNPXt( "qnp", XtDisplayToApplicationContext(This->display) ); application = new QApplication(This->display);#endif#ifdef Q_WS_WIN static int argc=0; static char **argv={ 0 }; application = new QApplication( argc, argv );#ifdef UNICODE if ( qWinVersion() & Qt::WV_NT_based ) hhook = SetWindowsHookExW( WH_GETMESSAGE, FilterProc, 0, GetCurrentThreadId() ); else#endif hhook = SetWindowsHookExA( WH_GETMESSAGE, FilterProc, 0, GetCurrentThreadId() );#endif }#ifdef Q_WS_X11 if ( !original_x_errhandler ) original_x_errhandler = XSetErrorHandler( dummy_x_errhandler );#endif // New widget on this new window. next_pi = This; /* This->widget = */ // (happens sooner - in QNPWidget constructor) This->instance->newWindow(); if ( !This->widget ) return result;#ifdef Q_WS_X11 This->widget->resize( This->width, This->height ); XReparentWindow( This->widget->x11Display(), This->widget->winId(), This->window, 0, 0 ); XSync( This->widget->x11Display(), False );#endif#ifdef Q_WS_WIN ::SetWindowLong( This->widget->winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ); ::SetParent( This->widget->winId(), This->window ); This->widget->raise(); This->widget->setGeometry( 0, 0, This->width, This->height );#endif This->widget->show(); return result;}extern "C" NPErrorNPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -