📄 qnp.cpp
字号:
/*** 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; } if (piApp) {#ifdef _WS_X11_ qt_np_remove_timeoutcb(np_do_timers); qt_np_remove_timer_setter(np_set_timer); qt_np_remove_event_proc(np_event_proc); qt_np_count--; if (qt_np_leave_cb == PluginSDK_QApplication::removeXtEventFiltersIfOutsideQNPWidget) qt_np_leave_cb = 0; if ( qt_np_count == 0) { // We are the last Qt-based plugin to leave removeXtEventFilters(Safe); removeXtEventFilters(Dangerous); if (qt_np_timerid) { XtRemoveTimeOut( qt_np_timerid ); qt_np_timerid = 0; } qt_np_leave_cb = 0; } delete piApp;#endif piApp = 0; delete qApp; }}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->fWindow = NULL; This->fMode = mode; This->window = 0;#ifdef _WS_WIN_ This->fDefaultWindowProc = NULL;#endif 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) {#ifdef _WS_WIN_ SetWindowLong( This->window, GWL_WNDPROC, (LONG)This->fDefaultWindowProc );#endif if (This->widget) { This->widget->unsetWindow();#ifdef _WS_WIN_ // needed? if (This->window) NPP_SetWindow( instance, 0 ); // unset#endif This->window = 0; 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; if (!window) { if (This->widget) { This->widget->unsetWindow(); This->window = 0; delete This->widget; This->widget = 0; }#ifdef _WS_X11_ } else if (This->window != (Window) window->window) { This->window = (Window) window->window;#endif#ifdef _WS_WIN_ } else if (This->window != (HWND) window->window) { if (This->window) SetWindowLong( This->window, GWL_WNDPROC, (LONG)This->fDefaultWindowProc ); This->fDefaultWindowProc = (WNDPROC)GetWindowLong( (HWND)window->window, GWL_WNDPROC); This->window = (HWND) window->window;#endif This->x = window->x; This->y = window->y; This->width = window->width; This->height = window->height;#ifdef _WS_X11_ This->display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;#endif if (!piApp) {#ifdef _WS_X11_ if (!qApp) { // Thou Shalt Not Unload Qt // Increment the reference count... // dlopen("libqt.so.1", RTLD_LAZY); // ... and never close it. // Nice try. Can't get that to work. // We are the first Qt-based plugin to arrive new QApplication(This->display); // Helps debugging //XSynchronize(This->display,True); //XSetErrorHandler((int (*)(Display*dpy,XErrorEvent*))abort); ASSERT(qt_np_count == 0); } installXtEventFilters(Safe); qt_np_add_timeoutcb(np_do_timers); qt_np_add_timer_setter(np_set_timer); qt_np_add_event_proc(np_event_proc); qt_np_count++; appcon = XtDisplayToApplicationContext(This->display);#endif piApp = new PluginSDK_QApplication(); } if (!This->widget) {#ifdef _WS_WIN_ This->window = (HWND) window->window; InvalidateRect( This->window, NULL, TRUE ); UpdateWindow( This->window );#endif // New widget on this new window. next_pi = This; /* This->widget = */ // (happens sooner - in QNPWidget constructor) This->instance->newWindow(); This->widget->show(); } else { // New window for existing widget, and all its children. This->widget->setWindow(FALSE); } } else if (This->widget) { // ### Maybe need a geometry setter that bypasses some Qt code? // ### position is always (0,0), so we get by by ignoring it. if ( This->widget->width() != (int)window->width || This->widget->height() != (int)window->height ) { This->widget->setGeometry(window->x, window->y, window->width, window->height); } else { This->widget->update(); } } This->fWindow = window; return result;}extern "C" NPErrorNPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype){ _NPInstance* This; if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; This = (_NPInstance*) instance->pdata; if ( This ) { QNPStream* qnps = new QNPStream(This->instance,type,stream,seekable); stream->pdata = qnps; QNPInstance::StreamMode sm = (QNPInstance::StreamMode)*stype; if (!This->instance->newStreamCreated(qnps, sm)) { return NPERR_GENERIC_ERROR; } *stype = sm; } return NPERR_NO_ERROR;}int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile * mode so we can take any size stream in our * write call (since we ignore it) */extern "C" int32NPP_WriteReady(NPP instance, NPStream *stream){ _NPInstance* This; if (instance != NULL) { This = (_NPInstance*) instance->pdata; } else { // Yikes, that's unusual! return 0; } if (This) { return This->instance->writeReady((QNPStream*)stream->pdata); } /* Number of bytes ready to accept in NPP_Write() */ return STREAMBUFSIZE;}extern "C" int32NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer){ if (instance != NULL) { _NPInstance* This = (_NPInstance*) instance->pdata; if (This) { return This->instance->write((QNPStream*)stream->pdata, offset, len, buffer); } } return len; /* The number of bytes accepted */}extern "C" NPErrorNPP_DestroyStream(NPP instance, NPStream *stream, NPError reason){ _NPInstance* This; if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; if (!qnps_no_call_back) { This = (_NPInstance*) instance->pdata; QNPStream* qnps = (QNPStream*)stream->pdata; switch (reason) { case NPRES_DONE: qnps->setComplete(TRUE); break; case NPRES_USER_BREAK: break; case NPRES_NETWORK_ERR: qnps->setOkay(FALSE); break; } if (This) { // Give the instance a chance to do something This->instance->streamDestroyed(qnps); } qnps_no_call_back++; delete qnps; qnps_no_call_back--; } return NPERR_NO_ERROR;}extern "C" voidNPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname){ _NPInstance* This; if (instance == NULL) return; This = (_NPInstance*) instance->pdata; if ( This ) { QNPStream* qnps = (QNPStream*)stream->pdata; This->instance->streamAsFile(qnps, fname); }}typedef struct{ int32 type; FILE* fp;} NPPrintCallbackStruct;#ifdef _WS_X11_class QNPPrinter : public QPrinter { QFile file;public: QNPPrinter(FILE* fp) { file.open(IO_WriteOnly, fp); QPDevCmdParam param; param.device = &file; cmd(PdcSetdev, 0, ¶m); } void end() { QPDevCmdParam param; param.device = 0; cmd(PdcSetdev, 0, ¶m); }};#endifextern "C" voidNPP_Print(NPP instance, NPPrint* printInfo){ if(printInfo == NULL) return; if (instance != NULL) { _NPInstance* This = (_NPInstance*) instance->pdata; if (printInfo->mode == NP_FULL) { printInfo->print.fullPrint.pluginPrinted = This->instance->printFullPage(); } else if (printInfo->mode == NP_EMBED) {#ifdef _WS_X11_ void* platformPrint = printInfo->print.embedPrint.platformPrint; FILE* outfile = ((NPPrintCallbackStruct*)platformPrint)->fp; if (ftell(outfile)) { NPWindow* w = &(printInfo->print.embedPrint.window); QNPPrinter prn(outfile); QPainter painter(&prn); // #### config viewport with w->{x,y,width,height} This->instance->print(&painter); prn.end(); } else { // Why does the browser make spurious NPP_Print calls? }#endif#ifdef _WS_WIN_ NPWindow* printWindow = &(printInfo->print.embedPrint.window); void* platformPrint = printInfo->print.embedPrint.platformPrint; // #### Nothing yet.#endif } }}extern "C" voidNPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData){ if (instance != NULL) { QNPInstance::Reason r; switch (reason) { case NPRES_DONE: r = QNPInstance::ReasonDone; break; case NPRES_USER_BREAK: r = QNPInstance::ReasonBreak; break; case NPRES_NETWORK_ERR: r = QNPInstance::ReasonError; break; default: r = QNPInstance::ReasonUnknown; break; } _NPInstance* This = (_NPInstance*) instance->pdata; This->instance->notifyURL(url, r, notifyData); }}// Hackery for X11: make Qt's toplevels widgets be Xt widgets too.#ifdef _WS_X11_// Called when a top-level widget (which has an Xt widget's window) is entered.staticvoid enter_event_handler(Widget, XtPointer xtp, XEvent* event, Boolean* cont){ _NPInstance* This = (_NPInstance*)xtp; if (piApp) { installXtEventFilters(Dangerous); if ( xtp ) { if ( focussedWidget )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -