?? 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.10 1998/12/06 18:31:53 olivier Exp olivier $";
#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;
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;
}
#endif
char*
NPP_GetMIMEDescription(void)
{
return("application/x-shockwave-flash:swf:Flash Plugin;application/x-futuresplash:spl:Future Splash");
}
NPError
NPP_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;
}
NPError
NPP_Initialize(void)
{
freopen("/dev/tty","w",stdout);
freopen("/dev/tty","w",stderr);
return NPERR_NO_ERROR;
}
jref
NPP_GetJavaClass()
{
return NULL;
}
void
NPP_Shutdown(void)
{
}
NPError
NPP_New(NPMIMEType pluginType,
NPP instance,
uint16 mode,
int16 argc,
char* argn[],
char* argv[],
NPSavedData* saved)
{
PluginInstance* This;
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);
FlashSoundInit(This->fh, "/dev/dsp");
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) {
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 void
updateTimer(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 void
flashEvent(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 void
flashWakeUp(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;
return 0;
}
if (status & FLASH_PARSE_START) {
if (!This->gInitDone && This->dpy) {
FlashGraphicInitX11(This);
XtAddEventHandler(This->widget, FLASH_XEVENT_MASK,
True, (XtEventHandler) flashEvent, (XtPointer)This);
This->gInitDone = 1;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -