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

📄 sdl_x11video.c

📁 SDL库 在进行视频显示程序spcaview安装时必须的库文件
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997-2006 Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 of the License, or (at your option) any later version.    This library 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    Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public    License along with this library; if not, write to the Free Software    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA    Sam Lantinga    slouken@libsdl.org*/#include "SDL_config.h"/* X11 based SDL video driver implementation.   Note:  This implementation does not currently need X11 thread locking,          since the event thread uses a separate X connection and any          additional locking necessary is handled internally.  However,          if full locking is neccessary, take a look at XInitThreads().*/#include <unistd.h>#include <sys/ioctl.h>#ifdef MTRR_SUPPORT#include <asm/mtrr.h>#include <sys/fcntl.h>#endif#include "SDL_endian.h"#include "SDL_timer.h"#include "SDL_thread.h"#include "SDL_video.h"#include "SDL_mouse.h"#include "../SDL_sysvideo.h"#include "../SDL_pixels_c.h"#include "../../events/SDL_events_c.h"#include "SDL_x11video.h"#include "SDL_x11wm_c.h"#include "SDL_x11mouse_c.h"#include "SDL_x11events_c.h"#include "SDL_x11modes_c.h"#include "SDL_x11image_c.h"#include "SDL_x11yuv_c.h"#include "SDL_x11gl_c.h"#include "SDL_x11gamma_c.h"#include "../blank_cursor.h"#ifdef X_HAVE_UTF8_STRING#include <locale.h>#endif/* Initialization/Query functions */static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat);static SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);static int X11_ToggleFullScreen(_THIS, int on);static void X11_UpdateMouse(_THIS);static int X11_SetColors(_THIS, int firstcolor, int ncolors,			 SDL_Color *colors);static int X11_SetGammaRamp(_THIS, Uint16 *ramp);static void X11_VideoQuit(_THIS);/* X11 driver bootstrap functions */static int X11_Available(void){	Display *display = NULL;	if ( SDL_X11_LoadSymbols() ) {		display = XOpenDisplay(NULL);		if ( display != NULL ) {			XCloseDisplay(display);		}		SDL_X11_UnloadSymbols();	}	return(display != NULL);}static void X11_DeleteDevice(SDL_VideoDevice *device){	if ( device ) {		if ( device->hidden ) {			SDL_free(device->hidden);		}		if ( device->gl_data ) {			SDL_free(device->gl_data);		}		SDL_free(device);		SDL_X11_UnloadSymbols();	}}static SDL_VideoDevice *X11_CreateDevice(int devindex){	SDL_VideoDevice *device = NULL;	if ( SDL_X11_LoadSymbols() ) {		/* Initialize all variables that we clean on shutdown */		device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));		if ( device ) {			SDL_memset(device, 0, (sizeof *device));			device->hidden = (struct SDL_PrivateVideoData *)					SDL_malloc((sizeof *device->hidden));			SDL_memset(device->hidden, 0, (sizeof *device->hidden));			device->gl_data = (struct SDL_PrivateGLData *)					SDL_malloc((sizeof *device->gl_data));			SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));		}		if ( (device == NULL) || (device->hidden == NULL) ||		                         (device->gl_data == NULL) ) {			SDL_OutOfMemory();			X11_DeleteDevice(device); /* calls SDL_X11_UnloadSymbols(). */			return(0);		}		SDL_memset(device->hidden, 0, (sizeof *device->hidden));		SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));		/* Set the driver flags */		device->handles_any_size = 1;		/* Set the function pointers */		device->VideoInit = X11_VideoInit;		device->ListModes = X11_ListModes;		device->SetVideoMode = X11_SetVideoMode;		device->ToggleFullScreen = X11_ToggleFullScreen;		device->UpdateMouse = X11_UpdateMouse;#if SDL_VIDEO_DRIVER_X11_XV		device->CreateYUVOverlay = X11_CreateYUVOverlay;#endif		device->SetColors = X11_SetColors;		device->UpdateRects = NULL;		device->VideoQuit = X11_VideoQuit;		device->AllocHWSurface = X11_AllocHWSurface;		device->CheckHWBlit = NULL;		device->FillHWRect = NULL;		device->SetHWColorKey = NULL;		device->SetHWAlpha = NULL;		device->LockHWSurface = X11_LockHWSurface;		device->UnlockHWSurface = X11_UnlockHWSurface;		device->FlipHWSurface = X11_FlipHWSurface;		device->FreeHWSurface = X11_FreeHWSurface;		device->SetGamma = X11_SetVidModeGamma;		device->GetGamma = X11_GetVidModeGamma;		device->SetGammaRamp = X11_SetGammaRamp;		device->GetGammaRamp = NULL;#if SDL_VIDEO_OPENGL_GLX		device->GL_LoadLibrary = X11_GL_LoadLibrary;		device->GL_GetProcAddress = X11_GL_GetProcAddress;		device->GL_GetAttribute = X11_GL_GetAttribute;		device->GL_MakeCurrent = X11_GL_MakeCurrent;		device->GL_SwapBuffers = X11_GL_SwapBuffers;#endif		device->SetCaption = X11_SetCaption;		device->SetIcon = X11_SetIcon;		device->IconifyWindow = X11_IconifyWindow;		device->GrabInput = X11_GrabInput;		device->GetWMInfo = X11_GetWMInfo;		device->FreeWMCursor = X11_FreeWMCursor;		device->CreateWMCursor = X11_CreateWMCursor;		device->ShowWMCursor = X11_ShowWMCursor;		device->WarpWMCursor = X11_WarpWMCursor;		device->CheckMouseMode = X11_CheckMouseMode;		device->InitOSKeymap = X11_InitOSKeymap;		device->PumpEvents = X11_PumpEvents;		device->free = X11_DeleteDevice;	}	return device;}VideoBootStrap X11_bootstrap = {	"x11", "X Window System",	X11_Available, X11_CreateDevice};/* Normal X11 error handler routine */static int (*X_handler)(Display *, XErrorEvent *) = NULL;static int x_errhandler(Display *d, XErrorEvent *e){#if SDL_VIDEO_DRIVER_X11_VIDMODE	extern int vm_error;#endif#if SDL_VIDEO_DRIVER_X11_DGAMOUSE	extern int dga_error;#endif#if SDL_VIDEO_DRIVER_X11_VIDMODE	/* VidMode errors are non-fatal. :) */	/* Are the errors offset by one from the error base?	   e.g. the error base is 143, the code is 148, and the	        actual error is XF86VidModeExtensionDisabled (4) ?	 */        if ( (vm_error >= 0) &&	     (((e->error_code == BadRequest)&&(e->request_code == vm_error)) ||	      ((e->error_code > vm_error) &&	       (e->error_code <= (vm_error+XF86VidModeNumberErrors)))) ) {#ifdef X11_DEBUG{ char errmsg[1024];  XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg));printf("VidMode error: %s\n", errmsg);}#endif        	return(0);        }#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */#if SDL_VIDEO_DRIVER_X11_DGAMOUSE	/* DGA errors can be non-fatal. :) */        if ( (dga_error >= 0) &&	     ((e->error_code > dga_error) &&	      (e->error_code <= (dga_error+XF86DGANumberErrors))) ) {#ifdef X11_DEBUG{ char errmsg[1024];  XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg));printf("DGA error: %s\n", errmsg);}#endif        	return(0);        }#endif /* SDL_VIDEO_DRIVER_X11_DGAMOUSE */	return(X_handler(d,e));}/* X11 I/O error handler routine */static int (*XIO_handler)(Display *) = NULL;static int xio_errhandler(Display *d){	/* Ack!  Lost X11 connection! */	/* We will crash if we try to clean up our display */	if ( current_video->hidden->Ximage ) {		SDL_VideoSurface->pixels = NULL;	}	current_video->hidden->X11_Display = NULL;	/* Continue with the standard X11 error handler */	return(XIO_handler(d));}static int (*Xext_handler)(Display *, _Xconst char *, _Xconst char *) = NULL;static int xext_errhandler(Display *d, _Xconst char *ext, _Xconst char *reason){#ifdef X11_DEBUG	printf("Xext error inside SDL (may be harmless):\n");	printf("  Extension \"%s\" %s on display \"%s\".\n",	       ext, reason, XDisplayString(d));#endif	if (SDL_strcmp(reason, "missing") == 0) {		/*		 * Since the query itself, elsewhere, can handle a missing extension		 *  and the default behaviour in Xlib is to write to stderr, which		 *  generates unnecessary bug reports, we just ignore these.		 */		return 0;	}	/* Everything else goes to the default handler... */	return Xext_handler(d, ext, reason);}/* Find out what class name we should use */static char *get_classname(char *classname, int maxlen){	char *spot;#if defined(__LINUX__) || defined(__FREEBSD__)	char procfile[1024];	char linkfile[1024];	int linksize;#endif	/* First allow environment variable override */	spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS");	if ( spot ) {		SDL_strlcpy(classname, spot, maxlen);		return classname;	}	/* Next look at the application's executable name */#if defined(__LINUX__) || defined(__FREEBSD__)#if defined(__LINUX__)	SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid());#elif defined(__FREEBSD__)	SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file", getpid());#else#error Where can we find the executable name?#endif	linksize = readlink(procfile, linkfile, sizeof(linkfile)-1);	if ( linksize > 0 ) {		linkfile[linksize] = '\0';		spot = SDL_strrchr(linkfile, '/');		if ( spot ) {			SDL_strlcpy(classname, spot+1, maxlen);		} else {			SDL_strlcpy(classname, linkfile, maxlen);		}		return classname;	}#endif /* __LINUX__ */	/* Finally use the default we've used forever */	SDL_strlcpy(classname, "SDL_App", maxlen);	return classname;}/* Create auxiliary (toplevel) windows with the current visual */static void create_aux_windows(_THIS){    int x = 0, y = 0;    char classname[1024];    XSetWindowAttributes xattr;    XWMHints *hints;    unsigned long app_event_mask;    int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen));    /* Look up some useful Atoms */    WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);    /* Don't create any extra windows if we are being managed */    if ( SDL_windowid ) {	FSwindow = 0;	WMwindow = SDL_strtol(SDL_windowid, NULL, 0);        return;    }    if(FSwindow)	XDestroyWindow(SDL_Display, FSwindow);#if SDL_VIDEO_DRIVER_X11_XINERAMA    if ( use_xinerama ) {        x = xinerama_info.x_org;        y = xinerama_info.y_org;    }#endif    xattr.override_redirect = True;    xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0;    xattr.border_pixel = 0;    xattr.colormap = SDL_XColorMap;    FSwindow = XCreateWindow(SDL_Display, SDL_Root,                             x, y, 32, 32, 0,			     this->hidden->depth, InputOutput, SDL_Visual,			     CWOverrideRedirect | CWBackPixel | CWBorderPixel			     | CWColormap,			     &xattr);    XSelectInput(SDL_Display, FSwindow, StructureNotifyMask);    /* Tell KDE to keep the fullscreen window on top */    {	XEvent ev;	long mask;	SDL_memset(&ev, 0, sizeof(ev));	ev.xclient.type = ClientMessage;	ev.xclient.window = SDL_Root;	ev.xclient.message_type = XInternAtom(SDL_Display,					      "KWM_KEEP_ON_TOP", False);	ev.xclient.format = 32;	ev.xclient.data.l[0] = FSwindow;	ev.xclient.data.l[1] = CurrentTime;	mask = SubstructureRedirectMask;	XSendEvent(SDL_Display, SDL_Root, False, mask, &ev);    }    hints = NULL;    if(WMwindow) {	/* All window attributes must survive the recreation */	hints = XGetWMHints(SDL_Display, WMwindow);	XDestroyWindow(SDL_Display, WMwindow);    }    /* Create the window for windowed management */    /* (reusing the xattr structure above) */    WMwindow = XCreateWindow(SDL_Display, SDL_Root,                             x, y, 32, 32, 0,			     this->hidden->depth, InputOutput, SDL_Visual,			     CWBackPixel | CWBorderPixel | CWColormap,			     &xattr);    /* Set the input hints so we get keyboard input */    if(!hints) {	hints = XAllocWMHints();	hints->input = True;	hints->flags = InputHint;    }    XSetWMHints(SDL_Display, WMwindow, hints);    XFree(hints);    X11_SetCaptionNoLock(this, this->wm_title, this->wm_icon);    app_event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask	| PropertyChangeMask | StructureNotifyMask | KeymapStateMask;    XSelectInput(SDL_Display, WMwindow, app_event_mask);    /* Set the class hints so we can get an icon (AfterStep) */    get_classname(classname, sizeof(classname));    {	XClassHint *classhints;	classhints = XAllocClassHint();	if(classhints != NULL) {	    classhints->res_name = classname;	    classhints->res_class = classname;	    XSetClassHint(SDL_Display, WMwindow, classhints);	    XFree(classhints);	}    }	/* Setup the communication with the IM server */	/* create_aux_windows may be called several times against the same	   Display.  We should reuse the SDL_IM if one has been opened for	   the Display, so we should not simply reset SDL_IM here.  */	#ifdef X_HAVE_UTF8_STRING	if (SDL_X11_HAVE_UTF8) {		/* Discard obsolete resources if any.  */		if (SDL_IM != NULL && SDL_Display != XDisplayOfIM(SDL_IM)) {			/* Just a double check. I don't think this		           code is ever executed. */			SDL_SetError("display has changed while an IM is kept");			if (SDL_IC) {				XUnsetICFocus(SDL_IC);				XDestroyIC(SDL_IC);				SDL_IC = NULL;			}			XCloseIM(SDL_IM);			SDL_IM = NULL;		}		/* Open an input method.  */		if (SDL_IM == NULL) {			char *old_locale = NULL, *old_modifiers = NULL;			const char *p;			size_t n;			/* I'm not comfortable to do locale setup			   here.  However, we need C library locale			   (and xlib modifiers) to be set based on the			   user's preference to use XIM, and many			   existing game programs doesn't take care of			   users' locale preferences, so someone other			   than the game program should do it.			   Moreover, ones say that some game programs			   heavily rely on the C locale behaviour,			   e.g., strcol()'s, and we can't change the C			   library locale.  Given the situation, I			   couldn't find better place to do the			   job... */			/* Save the current (application program's)			   locale settings.  */			p = setlocale(LC_ALL, NULL);			if ( p ) {				n = SDL_strlen(p)+1;				old_locale = SDL_stack_alloc(char, n);				if ( old_locale ) {					SDL_strlcpy(old_locale, p, n);				}			}			p = XSetLocaleModifiers(NULL);			if ( p ) {				n = SDL_strlen(p)+1;				old_modifiers = SDL_stack_alloc(char, n);				if ( old_modifiers ) {					SDL_strlcpy(old_modifiers, p, n);				}			}			/* Fetch the user's preferences and open the			   input method with them.  */			setlocale(LC_ALL, "");			XSetLocaleModifiers("");			SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname);			/* Restore the application's locale settings			   so that we don't break the application's			   expected behaviour.  */			if ( old_locale ) {				/* We need to restore the C library				   locale first, since the				   interpretation of the X modifier				   may depend on it.  */				setlocale(LC_ALL, old_locale);				SDL_stack_free(old_locale);			}			if ( old_modifiers ) {				XSetLocaleModifiers(old_modifiers);				SDL_stack_free(old_modifiers);			}		}		/* Create a new input context for the new window just created.  */		if (SDL_IM == NULL) {			SDL_SetError("no input method could be opened");		} else {			if (SDL_IC != NULL) {				/* Discard the old IC before creating new one.  */			    XUnsetICFocus(SDL_IC);			    XDestroyIC(SDL_IC);			}			/* Theoretically we should check the current IM supports			   PreeditNothing+StatusNothing style (i.e., root window method)			   before creating the IC.  However, it is the bottom line method,			   and we supports any other options.  If the IM didn't support			   root window method, the following call fails, and SDL falls			   back to pre-XIM keyboard handling.  */			SDL_IC = pXCreateIC(SDL_IM,					XNClientWindow, WMwindow,					XNFocusWindow, WMwindow,

⌨️ 快捷键说明

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