⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Evc编的一个在wince5.0上运行的flash播放器
💻 C
字号:
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
// 
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
// 
///////////////////////////////////////////////////////////////
//  Author : Olivier Debon  <odebon@club-internet.fr>
//  

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.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>

static char *rcsid = "$Id: main.c,v 1.9 1998/12/27 23:07:18 olivier Exp $";

typedef struct {
    FlashDisplay fd;
    Display			*dpy;		// X11 Display
    Window			 target;	// Target window
    GC		 	 gc;		// X11 Graphic context
    Pixmap			 canvas;	// Graphic buffer
} X11Context;

X11Context xc1, *xc=&xc1;

int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb;

/* memory function for the plugin */

void *flash_malloc(unsigned long size)
{
    return malloc(size);
}

void flash_free(void *p)
{
    free(p);
}

void *flash_realloc(void *p, unsigned long size)
{
    return realloc(p, size);
}

#define FLASH_XEVENT_MASK (ExposureMask|ButtonReleaseMask|ButtonPressMask|PointerMotionMask)

long FlashExecX11(FlashHandle fh, long flag, XEvent *event, struct timeval *wakeDate)
{
    FlashEvent fe;

    if (flag & FLASH_EVENT) {
        // X to Flash event structure conversion
        switch (event->type) {
        case ButtonPress:
            fe.type = FeButtonPress;
            break;
        case ButtonRelease:
            fe.type = FeButtonRelease;
            break;
        case MotionNotify:
            fe.type = FeMouseMove;
            fe.x = event->xmotion.x;
            fe.y = event->xmotion.y;
            break;
        case Expose:
            fe.type = FeRefresh;
            break;
        default:
            fe.type = FeNone;
            break;
        }
    }
    
    return FlashExec(fh,flag,&fe,wakeDate);
}

long FlashGraphicInitX11(FlashHandle fh, Display *d, Window w)
{
    XWindowAttributes wattr;
    XPixmapFormatValues *pf;
    Visual *visual;
    int nItems;
    int n;
    struct shmid_ds buf;
    int			 targetWidth;
    int 			 targetHeight;
    long			 bpl;	// Bytes per line
    long			 bpp;	// Bytes per pixel
    long			 pad;	// Scanline pad in byte
    // Platform dependent members
    Window			 target;	// Target window
    Cursor		 	 buttonCursor;	// Window cursor (a hand if over a button)
    Display			*dpy;		// X11 Display
    GC		 	 gc;		// X11 Graphic context
    Pixmap			 canvas;	// Graphic buffer
    XShmSegmentInfo		 segInfo;	// Shared memory information

    dpy = d;
    target = w;

    // Get Window dimension
    XGetWindowAttributes(dpy, target, &wattr);

    // Get first visual, don't care about others, really !
    visual = wattr.visual;

#if PRINT
	printf("BitmapPad  = %d\n", BitmapPad(dpy));
	printf("BitmapUnit = %d\n", BitmapUnit(dpy));
	printf("Depth      = %d\n", DefaultDepth(dpy,DefaultScreen(dpy)));
	printf("RedMask    = %x\n", visual->red_mask);
	printf("GreenMask  = %x\n", visual->green_mask);
	printf("BlueMask   = %x\n", visual->blue_mask);
	printf("Bits/RGB   = %d\n", visual->bits_per_rgb);
#endif

#if 0
	redMask = visual->red_mask;
	greenMask = visual->green_mask;
	blueMask = visual->blue_mask;
#endif

	// Get screen info

	for(pf=XListPixmapFormats(dpy, &n); n--; pf++) {
		if (pf->depth == DefaultDepth(dpy, DefaultScreen(dpy))) {
			bpp = pf->bits_per_pixel/8;
			pad = pf->scanline_pad/8;
		}
#if PRINT
		printf("----------------\n");
		printf("Depth          = %d\n", pf->depth);
		printf("Bits Per Pixel = %d\n", pf->bits_per_pixel);
		printf("Scanline Pad   = %d\n", pf->scanline_pad);
#endif
	}

	gc = DefaultGC(dpy, DefaultScreen(dpy));

	targetWidth = wattr.width;
	targetHeight = wattr.height;

#if PRINT
	printf("Target Width  = %d\n", targetWidth);
	printf("Target Height = %d\n", targetHeight);
#endif

	if (bpp) {
		bpl = (targetWidth*bpp + pad-1)/pad*pad;
	} else {
		bpl = (targetWidth/8 + pad-1)/pad*pad;
	}

	XSelectInput(dpy, target, ExposureMask|ButtonReleaseMask|ButtonPressMask|PointerMotionMask);

	// Prepare data for Direct Graphics
	segInfo.readOnly = False;
	segInfo.shmid = shmget (IPC_PRIVATE,targetHeight*bpl,IPC_CREAT|0777);
	if (segInfo.shmid <0) {
		perror("shmget");
		fprintf(stderr,"Size = %d x %d\n", targetWidth, targetHeight);
	}
	segInfo.shmaddr = (char*)shmat (segInfo.shmid, 0, 0);
	if ((long)segInfo.shmaddr == -1) {
		perror("shmat");
	}
	XShmAttach(dpy, &segInfo);
#ifdef linux
	// Warning : this does NOT work properly on Solaris
	// Special Linux shm behaviour is used here
	// When number of attached clients falls down to zero
	// the shm is removed. This is convenient when it crashes.
	if (shmctl(segInfo.shmid, IPC_RMID, &buf) < 0) {
		perror("shmctl");
	}
#endif
	XSync(dpy, False);

	xc->fd.pixels = (char*)segInfo.shmaddr;
        xc->fd.width = targetWidth;
        xc->fd.height = targetHeight;
        xc->fd.bpl = bpl;
        xc->fd.depth = pf->depth;

	canvas = XShmCreatePixmap(dpy,target,segInfo.shmaddr,&segInfo,targetWidth,targetHeight,DefaultDepth(dpy, DefaultScreen(dpy)));
	XSync(dpy, False);

	buttonCursor = XCreateFontCursor(dpy, XC_hand2);
	XFlush(dpy);

        xc->dpy = dpy;
        xc->target = target;
        xc->canvas = canvas;
        xc->gc = gc;

        return FlashGraphicInit(fh, &xc->fd);
}

void FlashCopyX11(void)
{
    XSetFunction(xc->dpy,xc->gc,GXcopy);
    XCopyArea(xc->dpy,xc->canvas,xc->target,xc->gc,
              xc->fd.clip_x,xc->fd.clip_y,
	      xc->fd.clip_width,xc->fd.clip_height,
              xc->fd.clip_x,xc->fd.clip_y
	      );
    /*
    XCopyArea(xc->dpy,xc->canvas,xc->target,xc->gc,
              0,0,
	      xc->fd.width,xc->fd.height,
              0,0
	      );
    */
    XFlush(xc->dpy);
}

/*
 *	This file is the entry of a very simple Flash Player
 */

Display *dpy;
GC gc;
Window frame,movie,control;
struct FlashInfo fi;
char *filename;

int
readFile(char *filename, char **buffer, long *size)
{
	FILE *in;
	char *buf;
	long length;

	in = fopen(filename,"r");
	if (in == 0) {
		perror(filename);
		return -1;
	}
	fseek(in,0,SEEK_END);
	length = ftell(in);
	rewind(in);
	buf = malloc(length);
	fread(buf,length,1,in);
	fclose(in);

	*size = length;
	*buffer = buf;

	return length;
}

void drawInfo()
{
	char msg[1024];

	sprintf(msg,"%s (Flash %d)  - Frames = %d  - Rate = %d fps",
			filename,fi.version,fi.frameCount,fi.frameRate);

	XSetForeground(dpy,gc,WhitePixel(dpy, DefaultScreen(dpy)));
	XDrawString(dpy,control,gc,10,15,msg, strlen(msg));

	sprintf(msg, "  (Q)uit (R)eplay (P)ause (C)ontinue");
	XDrawString(dpy,control,gc,10,35,msg, strlen(msg));
	XFlush(dpy);
}

void playMovie(FlashHandle flashHandle, Display *dpy, Window movie)
{
	struct timeval wd,de,now;
	XEvent event;
	long evMask, cmd;
	fd_set fdset;
	int status;
	long delay = 0;
	long wakeUp;
	long z = 1;
	long x = 0;
	long y = 0;
        FlashEvent fe;

	cmd = FLASH_WAKEUP;
	wakeUp = FlashExec(flashHandle, cmd, 0, &wd);
	XSelectInput(dpy, movie, FLASH_XEVENT_MASK|KeyPressMask);
	XSync(dpy,False);

	while(1) {
		FD_ZERO(&fdset);
		FD_SET(ConnectionNumber(dpy),&fdset);

		//printf("WakeUp = %d  Delay = %d\n", wakeUp, delay);
		if (delay < 0) {
			delay = 20;
		}

                if (xc->fd.flash_refresh) {
                    FlashCopyX11();
                    xc->fd.flash_refresh = 0;
                }
		if (wakeUp) {
			de.tv_sec = delay/1000;
			de.tv_usec = (delay%1000)*1000;
			status = select(ConnectionNumber(dpy)+1, &fdset, 0, 0, &de);
		} else {
			status = select(ConnectionNumber(dpy)+1, &fdset, 0, 0, 0);
		}

		if (status == 0) {
			cmd = FLASH_WAKEUP;
			wakeUp = FlashExec(flashHandle, cmd, 0, &wd);
		} else {
			XNextEvent(dpy, &event);
			//printf("Event %d (%d)\n",event.type,event.xany.serial);
			if (event.xany.window == movie) {
				int keycode;
				KeySym keysym;

				switch (event.type) {
				case KeyPress:
					keycode = event.xkey.keycode;
					keysym = XLookupKeysym((XKeyEvent*)&event, 0);
                                        fe.type = FeKeyPress;
                                        fe.key = 0;
					switch (keysym) {
						case XK_Up:
                            fe.key = FeKeyUp;
                            break;
						case XK_Down:
                            fe.key = FeKeyDown;
                            break;
						case XK_Left:
                            fe.key = FeKeyLeft;
                            break;
						case XK_Right:
                            fe.key = FeKeyRight;
                            break;
						case XK_Return:
                            fe.key = FeKeyEnter;
                            break;
						case XK_Tab:
                            fe.key = FeKeyNext;
                            break;
					}
					if (fe.key != 0) {
						cmd = FLASH_EVENT;
						if (FlashExec(flashHandle, cmd, &fe, &wd)) {
							wakeUp = 1;
						}
					} else {
						switch (keysym) {
#if 0
						case XK_Up:
							y -= 10;
							FlashOffset(flashHandle,x,y);
							break;
						case XK_Down:
							y += 10;
							FlashOffset(flashHandle,x,y);
							break;
						case XK_Left:
							x -= 10;
							FlashOffset(flashHandle,x,y);
							break;
						case XK_Right:
							x += 10;
							FlashOffset(flashHandle,x,y);
							break;
#endif
						case XK_KP_Add:
							FlashZoom(flashHandle,++z);
							break;
						case XK_KP_Subtract:
							FlashZoom(flashHandle,--z);
							break;
						case XK_q:
							return;
							break;
						case XK_c:
							cmd = FLASH_CONT;
							wakeUp = FlashExec(flashHandle, cmd, 0, &wd);
							break;
						case XK_p:
							cmd = FLASH_STOP;
							wakeUp = FlashExec(flashHandle, cmd, 0, &wd);
							break;
						case XK_r:
							cmd = FLASH_REWIND;
							FlashExec(flashHandle, cmd, 0, &wd);
							cmd = FLASH_CONT;
							wakeUp = FlashExec(flashHandle, cmd, 0, &wd);
							break;
                                            }
                                        }
					break;
				case NoExpose:
					break;
				default:
					cmd = FLASH_EVENT;
					if (FlashExecX11(flashHandle, cmd, &event, &wd)) {
                                            wakeUp = 1;
                                        }
					break;
				}
			}
			if (event.xany.window == control) {
				if (event.type == Expose) {
					drawInfo();
				}
			}
		}

		/* Recompute delay */
		gettimeofday(&now,0);
		delay = (wd.tv_sec-now.tv_sec)*1000 + (wd.tv_usec-now.tv_usec)/1000;
	}
}

void
showUrl(char *url, char *target, void *client_data)
{
	printf("GetURL : %s\n", url);
}

void
getSwf(char *url, int level, void *client_data)
{
	FlashHandle flashHandle;
	char *buffer;
	long size;

	flashHandle = (FlashHandle) client_data;
	printf("LoadMovie: %s @ %d\n", url, level);
	if (readFile(url, &buffer, &size) > 0) {
		FlashParse(flashHandle, level, buffer, size);
	}
}

main(int argc, char **argv)
{
	char *buffer;
	long size;
	FlashHandle flashHandle;
	int status;

	if (argc < 2) {
		fprintf(stderr,"Usage : %s <file.swf>\n", argv[0]);
		exit(1);
	}

	dpy = XOpenDisplay(getenv("DISPLAY"));
	if (dpy == 0) {
		fprintf(stderr,"Can't open X display\n");
		exit(1);
	}
	gc = DefaultGC(dpy, DefaultScreen(dpy));

	filename = argv[1];
	if (readFile(filename, &buffer, &size) < 0) {
		exit(2);
	}

	flashHandle = FlashNew();

	if (flashHandle == 0) {
		exit(1);
	}

	// Load level 0 movie
	do {
		status = FlashParse(flashHandle, 0, buffer, size);
	} while (status & FLASH_PARSE_NEED_DATA);

	free(buffer);

	FlashGetInfo(flashHandle, &fi);
        fi.frameWidth = 640 * 20;
        fi.frameHeight = 441 * 20;

	frame = XCreateSimpleWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)),
				    0, 0,
				    fi.frameWidth/20, fi.frameHeight/20+40,
				    0, WhitePixel(dpy, DefaultScreen(dpy)), BlackPixel(dpy, DefaultScreen(dpy))
				    );

	XMapWindow(dpy, frame);

	movie = XCreateSimpleWindow(dpy, frame, 0, 0, fi.frameWidth/20,fi.frameHeight/20,
				    0, WhitePixel(dpy, DefaultScreen(dpy)), BlackPixel(dpy, DefaultScreen(dpy))
				    );

	XMapWindow(dpy, movie);

	control = XCreateSimpleWindow(dpy, frame, 0, fi.frameHeight/20, fi.frameWidth/20,40,
				    0, BlackPixel(dpy, DefaultScreen(dpy)), BlackPixel(dpy, DefaultScreen(dpy))
				    );

	XMapWindow(dpy, control);
	XSelectInput(dpy, control, ExposureMask);
	drawInfo();

	XFlush(dpy);

        FlashGraphicInitX11(flashHandle, dpy, movie);

	FlashSoundInit(flashHandle, "/dev/dsp");

	FlashSetGetUrlMethod(flashHandle, showUrl, 0);

	FlashSetGetSwfMethod(flashHandle, getSwf, (void*)flashHandle);

	playMovie(flashHandle, dpy, movie);

	FlashClose(flashHandle);

	exit(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -