📄 qnp.cpp
字号:
/****************************************************************************** $Id: qt/extensions/nsplugin/src/qnp.cpp 2.3.8 edited 2004-08-05 $**** 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 _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 _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 <qwidget.h>#include <qobjectlist.h>#include <qprinter.h>#include <qfile.h>#include <qpainter.h>#include <q1xcompatibility.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 _WS_X11_#define GC GC_QQQ#endifextern "C" {//// Netscape plugin API//#ifdef _WS_WIN_#ifndef _WINDOWS#define _WINDOWS#endif#endif#ifdef _WS_X11_#define XP_UNIX#endif#include "npapi.h"#ifdef _WS_X11_#undef XP_UNIX#include "npunix.c"#endif//// Stuff for the NPP_SetWindow function://#ifdef _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 _WS_WIN_#include <windows.h>#endif}#ifdef _WS_WIN_#include "npwin.cpp"#endifstruct _NPInstance{ NPWindow* fWindow; uint16 fMode;#ifdef _WS_WIN_ HWND window; WNDPROC fDefaultWindowProc;#endif NPP npp;#ifdef _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;// The single global applicationstatic class PluginSDK_QApplication *piApp=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;// The currently in-focus widget. This focus tracking is an auxiliary// service which we provide, since we know it anyway.static QNPWidget* focussedWidget=0;#ifdef _WS_WIN_// defined in qapplication_win.cppQ_EXPORT extern bool qt_win_use_simple_timers;#endif#ifdef _WS_X11_static XtAppContext appcon;typedef void (*SameAsXtTimerCallbackProc)(void*,void*);typedef void (*IntervalSetter)(int);typedef void (*ForeignEventProc)(XEvent*);extern XtEventDispatchProc qt_np_cascade_event_handler[LASTEvent]; // defined in qnpsupport.cppvoid qt_reset_color_avail(); // defined in qcolor_x11.cppint qt_activate_timers(); // defined in qapplication_x11.cpptimeval *qt_wait_timer(); // defined in qapplication_x11.cppvoid qt_x11SendPostedEvents(); // defined in qapplication_x11.cppBoolean qt_event_handler( XEvent* event ); // defined in qnpsupport.cppextern int qt_np_count; // defined in qnpsupport.cppvoid qt_np_timeout( void* p, void* id ); // defined in qnpsupport.cppvoid qt_np_add_timeoutcb( SameAsXtTimerCallbackProc cb ); // defined in qnpsupport.cppvoid qt_np_remove_timeoutcb( SameAsXtTimerCallbackProc cb ); // defined in qnpsupport.cppvoid qt_np_add_timer_setter( IntervalSetter is ); // defined in qnpsupport.cppvoid qt_np_remove_timer_setter( IntervalSetter is ); // defined in qnpsupport.cppextern XtIntervalId qt_np_timerid; // defined in qnpsupport.cppextern bool qt_np_filters_installed[3]; // defined in qnpsupport.cppextern void (*qt_np_leave_cb) (XLeaveWindowEvent*); // defined in qnpsupport.cppvoid qt_np_add_event_proc( ForeignEventProc fep ); // defined in qnpsupport.cppvoid qt_np_remove_event_proc( ForeignEventProc fep ); // defined in qnpsupport.cppenum FilterType { Safe, Dangerous, Blocked };FilterType filterTypeFor(int event_type){ switch (event_type) { case KeymapNotify: case Expose: case GraphicsExpose: case NoExpose: case VisibilityNotify: case PropertyNotify: case SelectionClear: case SelectionRequest: case SelectionNotify: case ColormapNotify: case ClientMessage: // Hmm... is this safe? I want the wm_deletes return Safe; default: return Dangerous; }}staticvoid installXtEventFilters(FilterType t){ if (qt_np_filters_installed[t]) return; // Get Xt out of our face - install filter on every event type for (int et=2; et < LASTEvent; et++) { if ( filterTypeFor(et) == t ) qt_np_cascade_event_handler[et] = XtSetEventDispatcher( qt_xdisplay(), et, qt_event_handler ); } qt_np_filters_installed[t] = TRUE;}staticvoid removeXtEventFilters(FilterType t){ if (!qt_np_filters_installed[t]) return; // We aren't needed any more... slink back into the shadows. for (int et=2; et < LASTEvent; et++) { if ( filterTypeFor(et) == t ) XtSetEventDispatcher( qt_xdisplay(), et, qt_np_cascade_event_handler[et] ); } qt_np_filters_installed[t] = FALSE;}// When we are in an event loop of QApplication rather than the browser's// event loop (eg. for a modal dialog), we still send repaint events to// the browser.staticvoid np_event_proc( XEvent* e ){ Widget xtw = XtWindowToWidget( e->xany.display, e->xany.window ); if ( xtw && filterTypeFor( e->type ) == Safe ) { // Graciously allow the browser to process the event qt_np_cascade_event_handler[e->type]( e ); }}#endif#ifdef _WS_WIN_class PluginSDK_QApplication : public QApplication {#endif#ifdef _WS_X11_class PluginSDK_QApplication /* Not a QApplication */ {public: PluginSDK_QApplication() { piApp = this; } ~PluginSDK_QApplication() { piApp = 0; }#endif#ifdef _WS_WIN_private: static int argc; static char** argv;public: PluginSDK_QApplication() : QApplication(argc, argv) { } void checkFocussedWidget() { POINT curPos; if ( GetCursorPos( &curPos ) ) { QPoint p(curPos.x, curPos.y); QNPWidget *newFocussedWidget = 0; for ( QNPWidget* npw = npwidgets.first(); npw; npw = npwidgets.next() ) { QRect r = npw->rect(); r.moveTopLeft( npw->mapToGlobal(QPoint(0,0)) ); if ( r.contains(p) ) { newFocussedWidget = npw; break; } } if (newFocussedWidget != focussedWidget && focussedWidget) focussedWidget->leaveInstance(); if (newFocussedWidget) { if (newFocussedWidget != focussedWidget) newFocussedWidget->enterInstance(); } focussedWidget = newFocussedWidget; } } bool notify( QObject* obj, QEvent* event ) { if ( event->type() == QEvent::Enter || event->type() == QEvent::Leave ) { checkFocussedWidget(); } return QApplication::notify( obj, event ); }#endif void addQNPWidget(QNPWidget* w) { npwidgets.append(w); } void removeQNPWidget(QNPWidget* w) { if (w == focussedWidget) focussedWidget = 0; npwidgets.remove(w); }#ifdef _WS_X11_ static void removeXtEventFiltersIfOutsideQNPWidget(XLeaveWindowEvent* e) { // If QApplication doesn't know about the widget at the // event point, we must should remove our filters. // ### is widgetAt efficient enough? QWidget* w = QApplication::widgetAt(e->x_root, e->y_root); if ( !w ) { if ( focussedWidget ) { focussedWidget->leaveInstance(); focussedWidget = 0; } removeXtEventFilters( Dangerous ); } else if ( w->isTopLevel() ) { for ( QNPWidget* npw = npwidgets.first(); npw; npw = npwidgets.next()) { if ( npw == w ) { if ( focussedWidget != npw ) { if ( focussedWidget ) { focussedWidget->leaveInstance(); } focussedWidget = npw; focussedWidget->enterInstance(); } break; } } } }#endifprivate: static QList<QNPWidget> npwidgets;};QList<QNPWidget> PluginSDK_QApplication::npwidgets;#ifdef _WS_WIN_int PluginSDK_QApplication::argc=0;char **PluginSDK_QApplication::argv={ 0 };#endif#ifdef _WS_X11_static void np_set_timer( int interval ){ // Ensure we only have one timeout in progress - QApplication is // computing the one amount of time we need to wait. if ( qt_np_timerid ) { XtRemoveTimeOut( qt_np_timerid ); } qt_np_timerid = XtAppAddTimeOut(appcon, interval, (XtTimerCallbackProc)qt_np_timeout, 0); /* qt_np_timerid = XtAddTimeOut(interval, (XtTimerCallbackProc)qt_np_timeout, 0); */}static void np_do_timers( void*, void* ){ qt_np_timerid = 0; // It's us, and we just expired, that's why we are here. qt_activate_timers(); timeval *tm = qt_wait_timer(); if (tm) { int interval = QMIN(tm->tv_sec,INT_MAX/1000)*1000 + tm->tv_usec/1000; np_set_timer( interval ); }}#endif/****************************************************************************** * Plug-in Calls - these are called by Netscape *****************************************************************************/// Instance state information about the plugin.#ifdef _WS_X11_extern "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 _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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -