📄 plugin.c
字号:
/****************************************************************************** * Copyright (c) 1996 Netscape Communications. All rights reserved. ******************************************************************************//* * Modifications for the Linux Flash Plugin * by Olivier Debon <odebon@club-internet.fr> */static char *rcsid = "$Id: plugin.c,v 1.1 2003/09/08 19:42:00 jasonk Exp $";#include <stdio.h>#include <string.h>#include <sys/time.h>#include <sys/ipc.h>#include <sys/shm.h>#include "npapi.h"#include "flash.h"#include <X11/Xlib.h>#include <X11/keysym.h>#include <X11/cursorfont.h>#include <X11/Xutil.h>#include <X11/extensions/XShm.h>#include <X11/Intrinsic.h>#include <X11/IntrinsicP.h>#include <X11/Core.h>#include <X11/CoreP.h>#define PRINT 0#define FLASH_XEVENT_MASK (ExposureMask|ButtonReleaseMask|ButtonPressMask|PointerMotionMask|KeyPressMask|KeyReleaseMask)typedef struct _load { char *url; int level; char *data; long size; struct _load *next;} LoadCtxt;typedef struct _PluginInstance{ long gInitDone; Display *dpy; GC gc; Window win; Pixmap canvas; XShmSegmentInfo segInfo; /* Shared memory information */ Widget widget; XtIntervalId timer; struct timeval wd; long attributes; FlashHandle fh; FlashDisplay fd; int cursorOver; Cursor buttonCursor; LoadCtxt *loading;} PluginInstance;static void updateTimer(PluginInstance* This);static void flashEvent(Widget w, XtPointer client_data, XEvent *event, Boolean *dispatch);static void flashWakeUp(XtPointer client_data, XtIntervalId *id);static void getUrl( char * url, char *target, void *client_data);static void getSwf(char *url, int level, void *client_data);static void cursorOnOff(int, void *client_data);static long parseAttributes(int16 n, char *argn[], char *argv[]);static long FlashExecX11(PluginInstance *, long , XEvent *, struct timeval *);static long FlashGraphicInitX11(PluginInstance* This);static void FlashCopyX11(PluginInstance* This);#ifdef C6R5/* Ugly but it makes it work if it is compiled on *//* a libc6 system and running with a libc5-netscape */int __sigsetjmp(){ return 0;}#endifchar*NPP_GetMIMEDescription(void){ return("application/x-shockwave-flash:swf:Flash Plugin;application/x-futuresplash:spl:Future Splash");}NPErrorNPP_GetValue(void *future, NPPVariable variable, void *value){ NPError err = NPERR_NO_ERROR; switch (variable) { case NPPVpluginNameString: *((char **)value) = PLUGIN_NAME; break; case NPPVpluginDescriptionString: *((char **)value) = "Flash Movie player " FLASH_VERSION_STRING " compatible with Shockwave Flash 4.0 " "<P>Shockwave is a trademark of <A HREF=\"http://www.macromedia.com\">Macromedia®</A>" "<P>Author : <A HREF=mailto:odebon@club-internet.fr>Olivier Debon </A>"; break; default: err = NPERR_GENERIC_ERROR; } return err;}NPErrorNPP_Initialize(void){ freopen("/dev/tty","w",stdout); freopen("/dev/tty","w",stderr); return NPERR_NO_ERROR;}jrefNPP_GetJavaClass(){ return NULL;}voidNPP_Shutdown(void){}NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved){ PluginInstance* This; char *audiodev; if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; instance->pdata = NPN_MemAlloc(sizeof(PluginInstance)); This = (PluginInstance*) instance->pdata; if (This != NULL) { This->fh = FlashNew(); This->gInitDone = 0; This->dpy = 0; This->win = 0; This->timer = 0; This->attributes = parseAttributes(argc, argn, argv); This->loading = 0; FlashSetGetUrlMethod(This->fh, getUrl, (void*)instance); FlashSetGetSwfMethod(This->fh, getSwf, (void*)instance); FlashSetCursorOnOffMethod(This->fh, cursorOnOff, (void*)instance); audiodev = getenv("AUDIODEV"); if (audiodev == NULL) {#if SUN_SOUND audiodev = "/dev/audio";#else audiodev = "/dev/dsp";#endif } FlashSoundInit(This->fh, audiodev); return NPERR_NO_ERROR; } else return NPERR_OUT_OF_MEMORY_ERROR;}NPError NPP_Destroy(NPP instance, NPSavedData** save){ PluginInstance* This; if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; This = (PluginInstance*) instance->pdata; if (This != NULL) { LoadCtxt *l,*prev; if (This->timer) { XtRemoveTimeOut(This->timer); This->timer = 0; } if (This->fh) { XShmDetach(This->dpy, &This->segInfo); XSync(This->dpy,False); XFreePixmap(This->dpy, This->canvas); shmdt(This->segInfo.shmaddr); FlashClose(This->fh); This->fh = 0; } XtRemoveEventHandler(This->widget, FLASH_XEVENT_MASK, True, (XtEventHandler) flashEvent, (XtPointer)This); prev = 0; for(l = This->loading; l; prev = l, l = l->next) { free(l->data); free(l->url); free(prev); } free(prev); NPN_MemFree(instance->pdata); instance->pdata = NULL; } return NPERR_NO_ERROR;}static voidupdateTimer(PluginInstance* This){ XtAppContext ctxt; struct timeval now; long delay; if (This->timer) { XtRemoveTimeOut(This->timer); } gettimeofday(&now,0); delay = (This->wd.tv_sec-now.tv_sec)*1000 + (This->wd.tv_usec-now.tv_usec)/1000; /*fprintf(stderr,"Wakeup in %d ms\n", delay); */ if (delay < 20) { /* OVERRUN !!! */ delay = 20; /* Leave 20 ms */ } ctxt = XtWidgetToApplicationContext(This->widget); This->timer = XtAppAddTimeOut(ctxt, delay, (XtTimerCallbackProc) flashWakeUp, (XtPointer) This);}static voidflashEvent(Widget w, XtPointer client_data, XEvent *event, Boolean *dispatch){ PluginInstance* This; long cmd; long wakeUp; This = (PluginInstance*)client_data; if (This->fh) { cmd = FLASH_EVENT; wakeUp = FlashExecX11(This, cmd, event, &This->wd); if (This->fd.flash_refresh) { FlashCopyX11(This); } if (wakeUp) { updateTimer(This); } }}static voidflashWakeUp(XtPointer client_data, XtIntervalId *id){ PluginInstance* This; long cmd; long wakeUp; This = (PluginInstance*)client_data; if (This->fh) { cmd = FLASH_WAKEUP; wakeUp = FlashExecX11(This, cmd, 0, &This->wd); if (This->fd.flash_refresh) { FlashCopyX11(This); } /* If have to wake up next time */ if (wakeUp) { updateTimer(This); } else { if (This->timer) { XtRemoveTimeOut(This->timer); } This->timer = 0; } }}NPError NPP_SetWindow(NPP instance, NPWindow* window){ PluginInstance* This; NPSetWindowCallbackStruct *ws; Window frame; XWindowAttributes xwa; if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; if (window == NULL) return NPERR_NO_ERROR; This = (PluginInstance*) instance->pdata; This->win = (Window) window->window; ws = (NPSetWindowCallbackStruct *)window->ws_info; This->dpy = ws->display; This->gc = DefaultGC(This->dpy, DefaultScreen(This->dpy)); This->widget = XtWindowToWidget(This->dpy,This->win); XGetWindowAttributes(This->dpy, This->win, &xwa); return NPERR_NO_ERROR;}NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype){ NPByteRange range; PluginInstance* This; LoadCtxt *l; if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; This = (PluginInstance*) instance->pdata; /* This is only for the very first movie */ if (This->loading == 0) { l = (LoadCtxt *)malloc(sizeof(LoadCtxt)); This->loading = l; l->next = 0; l->level = 0; l->data = 0; l->size = 0; l->url = strdup(stream->url); } return NPERR_NO_ERROR;}#define BUFFERSIZE (16*1024)int32 NPP_WriteReady(NPP instance, NPStream *stream){ PluginInstance* This; if (instance != NULL) { return BUFFERSIZE; } return 0;}int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer){ PluginInstance* This; if (instance != NULL) { int status; LoadCtxt *l; This = (PluginInstance*) instance->pdata; for(l = This->loading; l != 0; l = l->next) { if (l->url && strstr(stream->url, l->url)) { break; } } if (l == 0) return 0; /* Should not happen */ if (l->data == 0) { l->data = (char *) malloc(len); } else { l->data = (char *) realloc(l->data, l->size+len); } memcpy(&l->data[offset], buffer, len); l->size += len; status = FlashParse(This->fh, l->level, l->data, l->size); if (status == FLASH_PARSE_ERROR) { free(l->data); l->data = 0; free(l->url); l->url = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -