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

📄 video.c

📁 avi player 使用Linux下 GDK,GTK
💻 C
字号:
/***  Sinek (Media Player)**  Copyright (c) 2001-2002 Gurer Ozen****  This code is free software; you can redistribute it and/or**  modify it under the terms of the GNU General Public License.****  video window*/#include "common.h"#include <gdk/gdkx.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/cursorfont.h>#include <X11/Xatom.h>#include <xine/video_out_x11.h>/* missing stuff from X includes */#define MWM_HINTS_DECORATIONS (1L << 1)#define PROP_MWM_HINTS_ELEMENTS 5typedef struct _mwmhints{	uint32_t flags;	uint32_t functions;	uint32_t decorations;	int32_t input_mode;	uint32_t status;} MWMHints;static int video_visible = 42;static XClassHint *xc_hint;// static XWMHints *wm_hint;static XSizeHints xs_hint;static Atom wm_delete_window;static int depth;static Visual *visual;static Window videowin;static Display *display;static int screen;static XColor black;static Colormap colormap = 0;static int xfred;static Cursor cursor[2];static void create_bg_window(void);static void find_best_visual(void);int translate_point(int x, int y, int *vid_x, int *vid_y);static void create_window(int fs, int w, int h);static sinek_x11_type display_info;static gboolean handle_event(GIOChannel *gio, GIOCondition cond, gpointer data);static GIOChannel *lala;static void frame_out_cb(void *user_data, sinek_x11_type *di){	sinek.vid_w = di->frame_w;	sinek.vid_h = di->frame_h;	di->out_x = 0;	di->out_y = 0;	di->out_w = di->win_w;	di->out_h = di->win_h;}int video_init(void){	static unsigned char bm_no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 };	Pixmap bm_no;	XColor dummy;	int ret;	if(sinek.video_display_name)	{		display = XOpenDisplay(sinek.video_display_name);		if(!display)		{			printf("Cannot connect to display '%s'.\n", sinek.video_display_name);			return 0;		}		XLockDisplay(display);		screen = DefaultScreen(display);	}	else	{		display = XOpenDisplay(gdk_get_display());		XLockDisplay(display);		screen = gdk_x11_get_default_screen();	}	sinek.display = display;	xfred = ConnectionNumber(display);	find_best_visual();	sinek.depth = depth;	XAllocNamedColor(display, DefaultColormap(display, screen), "black", &black, &dummy);	xc_hint = XAllocClassHint();	if(xc_hint)	{		xc_hint->res_name = "video";		xc_hint->res_class = "sinek";	}/*	wm_hint = XAllocWMHints();	if(!wm_hint)	{		printf(_("XAllocWMHints failed.\n"));		return 0;	}*/	wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);	lala = g_io_channel_unix_new(xfred);	g_io_add_watch(lala, G_IO_IN, handle_event, NULL);	bm_no = XCreateBitmapFromData(display, RootWindow(display, screen), bm_no_data, 8, 8);	cursor[0] = XCreatePixmapCursor(display, bm_no, bm_no, &black, &black, 0, 0);	cursor[1] = XCreateFontCursor(display, XC_left_ptr);	sinek.vid_w = sinek.geo_w;	sinek.vid_h = sinek.geo_h;	video_set_mode(sinek.video_mode);	display_info.display = display;	display_info.screen = screen;	display_info.drawable = videowin;	display_info.frame_out_cb = frame_out_cb;	ret = sinek_video_set_output(media, &display_info);	XUnlockDisplay(display);	return ret;}void video_show(void){	XMapWindow(display, videowin);	XFlush(display);	if(video_visible != 1) sinek.nr_mapped++;	video_visible = 1;}void video_hide(void){	XUnmapWindow(display, videowin);	XFlush(display);	if(video_visible == 1) sinek.nr_mapped--;	video_visible = 0;	if(0 == sinek.nr_mapped) gtk_main_quit();}void video_cursor(int show){	static int old = 2;	if(show == old) return;	old = show;	if(show == 1) sinek.cursor_timer = 0;	XLockDisplay(display);	XDefineCursor(display, videowin, cursor[show]);	XFlush(display);	XUnlockDisplay(display);}static int try_subtitle(char *mrl, char *ext){	gchar *tmp, *tmp2;	struct stat mystat;	int ret = 0;	tmp = g_strdup_printf("%s%s", mrl, ext);	if(stat(tmp, &mystat) == 0)	{		osd_load(tmp);		ret = 1;	}	if(0 == ret)	{		tmp2 = g_strrstr(tmp, ".avi");		if(NULL == tmp2) tmp2 = g_strrstr(tmp, ".mpg");		if(NULL == tmp2) tmp2 = g_strrstr(tmp, ".mpeg");		if(NULL == tmp2) tmp2 = g_strrstr(tmp, ".mov");		if(tmp2)		{			strcpy(tmp2, ext);			if(stat(tmp, &mystat) == 0)			{				osd_load(tmp);				ret = 1;			}		}	}	free(tmp);	return ret;}int video_play(char *mrl){	int ret;	if(!mrl) return(0);	if(video_visible == 42) video_show();	if(NULL == strstr(mrl, "://"))	{		ret = try_subtitle(mrl, ".txt");		if(0 == ret) ret = try_subtitle(mrl, ".sub");		if(0 == ret) try_subtitle(mrl, ".srt");	}	if(sinek_open(media, mrl))	{		scrsaver_disable();		control_update_slider(0, xine_get_stream_length(sinek.xine));		control_mrl(mrl);		sinek.playing = -1;		return 1;	}	return 0;}void video_seek(int secs){	scrsaver_disable();	sinek_seek(media, secs);}void video_zoom(int val){	int tmp;	if(val == 0)	{		/* reset zoom */		tmp = media->vd->get_property(media->vd, VO_PROP_ASPECT_RATIO);		media->vd->set_property(media->vd, VO_PROP_ASPECT_RATIO, tmp);		return;	}	else	{		tmp = media->vd->get_property(media->vd, VO_PROP_ZOOM_FACTOR);		media->vd->set_property(media->vd, VO_PROP_ZOOM_FACTOR, tmp + val);	}}void video_scale(float factor){	int x, y;	unsigned int w, h, b, d;	Window root;	if(sinek.video_mode != VIDEO_WINDOW) return;	XLockDisplay(display);	XGetGeometry(display, videowin, &root, &x, &y, &w, &h, &b, &d);	w *= factor;	h *= factor;	XResizeWindow(display, videowin, w, h);	XUnlockDisplay(display);}void video_scale_abs(float factor){	int x, y;	unsigned int w, h, b, d;	Window root;	if(sinek.video_mode != VIDEO_WINDOW) return;	XLockDisplay(display);	XGetGeometry(display, videowin, &root, &x, &y, &w, &h, &b, &d);	w = factor * sinek.vid_w;	h = factor * sinek.vid_h;	XResizeWindow(display, videowin, w, h);	XUnlockDisplay(display);}static gboolean handle_event(GIOChannel *gio, GIOCondition cond, gpointer data){	XEvent xev;	int x, y;	XNextEvent(display, &xev);	if(videowin == 0) return TRUE;	sinek_video_event(media, (void *)&xev);	switch(xev.type)	{		case MotionNotify:			video_cursor(1);			if(sinek.osd_place && translate_point(xev.xmotion.x, xev.xmotion.y, &x, &y))			{				osd_position(0, y);			}			break;		case ButtonPress:			video_cursor(1);			sinek.osd_place = 0;			switch(xev.xbutton.button)			{				case 3:					popup_pop(xev.xbutton.time);					break;				case 4:					audio_slide_volume(5);					break;				case 5:					audio_slide_volume(-5);					break;			}			break;		case KeyPress:		{			XKeyEvent *ev = (XKeyEvent *)&xev;			KeySym key;			char buf[256];			int len;//			XLockDisplay(display);			len = XLookupString(ev, buf, sizeof(buf), &key, NULL);//			XUnlockDisplay(display);			key_handle(key, ev->state);			break;		}		case ClientMessage:			if(xev.xclient.data.l[0] == wm_delete_window)				video_hide();			break;	}	return TRUE;}void video_set_mode(enum video_modes mode){	Window win = videowin;	if(videowin && mode == sinek.video_mode) return;	XLockDisplay(display);	switch(mode)	{		case VIDEO_WINDOW:			create_window(0, sinek.vid_w, sinek.vid_h);			break;		case VIDEO_FULLSCREEN:			create_window(1, DisplayWidth(display, screen), DisplayHeight(display, screen));			break;		case VIDEO_BACKGROUND:			create_bg_window();			XLowerWindow(display, videowin);			break;	}	if(win) XDestroyWindow(display, win);	sinek.video_mode = mode;	if(video_visible != 42) video_show();	XUnlockDisplay(display);	wm_relayer_all();}static void find_best_visual(void){	XVisualInfo *vi, tmpl;	int num, i, prf, best_prf = -1;	tmpl.screen = screen;	tmpl.class = TrueColor;	vi = XGetVisualInfo(display, VisualScreenMask | VisualClassMask, &tmpl, &num);	if(vi)	{		for(i = 0; i < num; i++)		{			if(vi[i].depth > 8 && vi[i].depth <= 16)				prf = 3;			else if(vi[i].depth > 16)				prf = 2;			else				prf = 1;			if(prf > best_prf)			{				depth = vi[i].depth;				visual = vi[i].visual;			}		}		XFree(vi);	}	if(best_prf == -1)	{		XWindowAttributes attr;		XVisualInfo vinfo;		XGetWindowAttributes(display, RootWindow(display, screen), &attr);		depth = attr.depth;		if(XMatchVisualInfo(display, screen, depth, TrueColor, &vinfo))		{			visual = vinfo.visual;		} else {			printf(_("couldn't find true color visual.\n"));			depth = DefaultDepth(display, screen);			visual = DefaultVisual(display, screen);		}	}}int translate_point(int x, int y, int *vid_x, int *vid_y){	x11_rectangle_t rect;	int xwin, ywin;	unsigned int wwin, hwin, bwin, dwin;	float xf,yf;	float scale, width_scale, height_scale, aspect;	Window rootwin;	rect.x = x;	rect.y = y;	rect.w = 0;	rect.h = 0;	if(media->vd->gui_data_exchange(media->vd, GUI_DATA_EX_TRANSLATE_GUI_TO_VIDEO,  (void*)&rect) != -1)	{		*vid_x = rect.x;		*vid_y = rect.y;		return 1;	}	if(XGetGeometry(display, videowin, &rootwin, &xwin, &ywin, &wwin, &hwin, &bwin, &dwin) == BadDrawable)		return 0;	/* Scale co-ordinate to image dimensions. */	height_scale = (float)sinek.vid_h / (float)hwin;	width_scale = (float)sinek.vid_w / (float)wwin;	aspect = (float)sinek.vid_w / (float)sinek.vid_h;	if(((float)wwin / (float)hwin) < aspect)	{		scale = width_scale;		xf = (float)x * scale;		yf = (float)y * scale;		hwin = hwin * scale;		/* FIXME: The 1.25 should really come from the NAV packets. */		*vid_x = xf * 1.25 / aspect;		*vid_y = yf - ((hwin - sinek.vid_h) / 2);	}	else	{		scale = height_scale;		xf = (float)x * scale;		yf = (float)y * scale;		wwin=wwin * scale;		/* FIXME: The 1.25 should really come from the NAV packets. */		*vid_x = (xf - ((wwin - sinek.vid_w) / 2)) * 1.25 / aspect;		*vid_y = yf;	}	return 1;}static void create_window(int fs, int w, int h){	char *title;	static Atom  XA_WIN_LAYER = None;	XSetWindowAttributes attr;	Atom prop;	MWMHints	mwmhints;	long data[1];	title = _("Sinek Video Output");	attr.background_pixel = black.pixel;	attr.border_pixel = black.pixel;	attr.colormap = colormap;	videowin = XCreateWindow(display, RootWindow(display, screen),		0, 0, w, h,		0, depth, CopyFromParent, visual,		CWBackPixel | CWBorderPixel | CWColormap, &attr);	if(!videowin)	{		printf(_("Cannot create video window!\n"));		exit(5);	}	sinek.video_win = videowin;	if(media->vd) media->vd->gui_data_exchange(media->vd, GUI_DATA_EX_DRAWABLE_CHANGED, (void *)videowin);	if(!fs && xc_hint) XSetClassHint(display, videowin, xc_hint);	xs_hint.x = 0;	xs_hint.y = 0;	xs_hint.width = w;	xs_hint.height = h;	xs_hint.win_gravity = StaticGravity;	xs_hint.flags = PPosition | PSize;	if(fs) xs_hint.flags |= PWinGravity;	XSetStandardProperties(display, videowin, title, title, None, NULL, 0, 0);	XSetWMNormalHints(display, videowin, &xs_hint);//	XSetWMHints(display, videowin, wm_hint);	XSelectInput(display, videowin, StructureNotifyMask | ExposureMask | KeyPressMask | ButtonPressMask | PointerMotionMask);	if(!fs) XSetWMProtocols(display, videowin, &wm_delete_window, 1);	if(fs)	{		if(XA_WIN_LAYER == None)			XA_WIN_LAYER = XInternAtom(display, "_WIN_LAYER", False);		data[0] = 10;		XChangeProperty(display, videowin, XA_WIN_LAYER, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);		prop = XInternAtom(display, "_MOTIF_WM_HINTS", False);		mwmhints.flags = MWM_HINTS_DECORATIONS;		mwmhints.decorations = 0;		XChangeProperty(display, videowin, prop, prop, 32, PropModeReplace, (unsigned char *)&mwmhints, PROP_MWM_HINTS_ELEMENTS);		XSetTransientForHint(display, videowin, None);	}}static void create_bg_window(void){	static Atom  XA_WIN_LAYER = None;	XSetWindowAttributes attr;	Atom prop;	MWMHints	mwmhints;	long data[1];	char *title;	title = _("Sinek Video Output");	attr.background_pixel = black.pixel;	attr.override_redirect = True;	videowin = XCreateWindow(display, DefaultRootWindow(display),		0, 0, DisplayWidth(display, screen), DisplayHeight(display, screen),		0, CopyFromParent, CopyFromParent, CopyFromParent,		CWBackPixel | CWOverrideRedirect, &attr);	if(!videowin)	{		printf(_("Cannot create video window!\n"));		exit(5);	}	sinek.video_win = videowin;	if(media->vd) media->vd->gui_data_exchange(media->vd, GUI_DATA_EX_DRAWABLE_CHANGED, (void *)videowin);	xs_hint.x = 0;	xs_hint.y = 0;	xs_hint.width = DisplayWidth(display, screen);	xs_hint.height = DisplayHeight(display, screen);	xs_hint.flags = USSize | USPosition | PPosition | PSize;	XSetStandardProperties(display, videowin, title, title, None, NULL, 0, 0);	XSetWMNormalHints(display, videowin, &xs_hint);//	XSetWMHints(display, videowin, wm_hint);	XSelectInput(display, videowin, StructureNotifyMask | ExposureMask | KeyPressMask | ButtonPressMask | PointerMotionMask);	if(XA_WIN_LAYER == None)		XA_WIN_LAYER = XInternAtom(display, "_WIN_LAYER", False);	data[0] = 0;	XChangeProperty(display, videowin, XA_WIN_LAYER, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);	prop = XInternAtom(display, "_MOTIF_WM_HINTS", False);	mwmhints.flags = MWM_HINTS_DECORATIONS;	mwmhints.decorations = 0;	XChangeProperty(display, videowin, prop, prop, 32, PropModeReplace, (unsigned char *)&mwmhints, PROP_MWM_HINTS_ELEMENTS);	XSetTransientForHint(display, videowin, None);}void video_lift(GtkWidget *win){	static Atom XA_WIN_LAYER = None;	Window w = GDK_WINDOW_XWINDOW(GTK_WIDGET(win)->window);	Display *disp = gdk_x11_get_default_xdisplay();	XEvent ev;	if(XA_WIN_LAYER == None)		XA_WIN_LAYER = XInternAtom(disp, "_WIN_LAYER", False);	ev.type = ClientMessage;	ev.xclient.type = ClientMessage;	ev.xclient.window = w;	ev.xclient.message_type = XA_WIN_LAYER;	ev.xclient.format = 32;	if(sinek.video_mode == VIDEO_FULLSCREEN)		ev.xclient.data.l[0] = (long) 11;	else		ev.xclient.data.l[0] = (long) 4;	ev.xclient.data.l[1] = 0;	XSendEvent(disp, RootWindow(disp, screen), False, SubstructureNotifyMask, (XEvent *)&ev);	XRaiseWindow(disp, w);}

⌨️ 快捷键说明

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