Starting fresh with the X11 driver

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401994
This commit is contained in:
Sam Lantinga 2006-07-26 04:22:32 +00:00
parent fe52e82bd9
commit 532023bd76
21 changed files with 0 additions and 7241 deletions

View file

@ -1,185 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#define DEBUG_DYNAMIC_X11 0
#include "SDL_x11dyn.h"
#if DEBUG_DYNAMIC_X11
#include <stdio.h>
#endif
#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
#include "SDL_name.h"
#include "SDL_loadso.h"
typedef struct
{
void *lib;
const char *libname;
} x11dynlib;
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC
#define SDL_VIDEO_DRIVER_X11_DYNAMIC NULL
#endif
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT NULL
#endif
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER NULL
#endif
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL
#endif
static x11dynlib x11libs[] = {
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC},
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT},
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER},
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR},
};
static void
X11_GetSym(const char *fnname, int *rc, void **fn)
{
int i;
for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
if (x11libs[i].lib != NULL) {
*fn = SDL_LoadFunction(x11libs[i].lib, fnname);
if (*fn != NULL)
break;
}
}
#if DEBUG_DYNAMIC_X11
if (*fn != NULL)
printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname,
*fn);
else
printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
#endif
if (*fn == NULL)
*rc = 0; /* kill this module. */
}
/* Define all the function pointers and wrappers... */
#define SDL_X11_MODULE(modname)
#define SDL_X11_SYM(rc,fn,params,args,ret) \
static rc (*p##fn) params = NULL; \
rc fn params { ret p##fn args ; }
#include "SDL_x11sym.h"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM
#endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
/* Annoying varargs entry point... */
#ifdef X_HAVE_UTF8_STRING
XIC(*pXCreateIC) (XIM,...) = NULL;
#endif
/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
#define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
#define SDL_X11_SYM(rc,fn,params,args,ret)
#include "SDL_x11sym.h"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM
static int x11_load_refcount = 0;
void
SDL_X11_UnloadSymbols(void)
{
#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
/* Don't actually unload if more than one module is using the libs... */
if (x11_load_refcount > 0) {
if (--x11_load_refcount == 0) {
int i;
/* set all the function pointers to NULL. */
#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
#define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
#include "SDL_x11sym.h"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM
#ifdef X_HAVE_UTF8_STRING
pXCreateIC = NULL;
#endif
for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
if (x11libs[i].lib != NULL) {
SDL_UnloadObject(x11libs[i].lib);
x11libs[i].lib = NULL;
}
}
}
}
#endif
}
/* returns non-zero if all needed symbols were loaded. */
int
SDL_X11_LoadSymbols(void)
{
int rc = 1; /* always succeed if not using Dynamic X11 stuff. */
#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
/* deal with multiple modules (dga, x11, etc) needing these symbols... */
if (x11_load_refcount++ == 0) {
int i;
int *thismod = NULL;
for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
if (x11libs[i].libname != NULL) {
x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
}
}
#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
#define SDL_X11_SYM(a,fn,x,y,z) X11_GetSym(#fn,thismod,(void**)&p##fn);
#include "SDL_x11sym.h"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM
#ifdef X_HAVE_UTF8_STRING
X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8, (void **) &pXCreateIC);
#endif
if (!SDL_X11_HAVE_BASEXLIB) { /* some required symbol didn't load. */
SDL_X11_UnloadSymbols(); /* in case something got loaded... */
rc = 0;
}
}
#else
#ifdef X_HAVE_UTF8_STRING
pXCreateIC = XCreateIC;
#endif
#endif
return rc;
}
/* end of SDL_x11dyn.c ... */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,89 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#ifndef _SDL_x11dyn_h
#define _SDL_x11dyn_h
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/Xlibint.h>
#include <X11/Xproto.h>
#include "../Xext/extensions/Xext.h"
#include "../Xext/extensions/extutil.h"
#ifndef NO_SHARED_MEMORY
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#endif
#if SDL_VIDEO_DRIVER_X11_XRANDR
#include <X11/extensions/Xrandr.h>
#endif
/*
* When using the "dynamic X11" functionality, we duplicate all the Xlib
* symbols that would be referenced by SDL inside of SDL itself.
* These duplicated symbols just serve as passthroughs to the functions
* in Xlib, that was dynamically loaded.
*
* This allows us to use Xlib as-is when linking against it directly, but
* also handles all the strange cases where there was code in the Xlib
* headers that may or may not exist or vary on a given platform.
*/
#ifdef __cplusplus
extern "C"
{
#endif
/* evil function signatures... */
typedef Bool(*SDL_X11_XESetWireToEventRetType) (Display *, XEvent *,
xEvent *);
typedef int (*SDL_X11_XSynchronizeRetType) (Display *);
typedef Status(*SDL_X11_XESetEventToWireRetType) (Display *, XEvent *,
xEvent *);
int SDL_X11_LoadSymbols(void);
void SDL_X11_UnloadSymbols(void);
/* That's really annoying...make this a function pointer no matter what. */
#ifdef X_HAVE_UTF8_STRING
extern XIC(*pXCreateIC) (XIM, ...);
#endif
/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
#define SDL_X11_MODULE(modname) extern int SDL_X11_HAVE_##modname;
#define SDL_X11_SYM(rc,fn,params,args,ret)
#include "SDL_x11sym.h"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM
#ifdef __cplusplus
}
#endif
#endif /* !defined _SDL_x11dyn_h */
/* vi: set ts=4 sw=4 expandtab: */

File diff suppressed because it is too large Load diff

View file

@ -1,36 +0,0 @@
/*
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"
#include "SDL_x11video.h"
/* Functions to be exported */
extern void X11_InitOSKeymap(_THIS);
extern void X11_PumpEvents(_THIS);
extern void X11_SetKeyboardState(Display * display, const char *key_vec);
extern void X11_SaveScreenSaver(Display * display, int *saved_timeout,
BOOL * dpms);
extern void X11_DisableScreenSaver(Display * display);
extern void X11_RestoreScreenSaver(Display * display, int saved_timeout,
BOOL dpms);
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,155 +0,0 @@
/*
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"
#include "SDL.h"
#include "SDL_events.h"
#include "../../events/SDL_events_c.h"
#include "SDL_x11video.h"
/* From the X server sources... */
#define MAX_GAMMA 10.0
#define MIN_GAMMA (1.0/MAX_GAMMA)
static int
X11_SetGammaNoLock(_THIS, float red, float green, float blue)
{
#if SDL_VIDEO_DRIVER_X11_VIDMODE
if (use_vidmode >= 200) {
SDL_NAME(XF86VidModeGamma) gamma;
Bool succeeded;
/* Clamp the gamma values */
if (red < MIN_GAMMA) {
gamma.red = MIN_GAMMA;
} else if (red > MAX_GAMMA) {
gamma.red = MAX_GAMMA;
} else {
gamma.red = red;
}
if (green < MIN_GAMMA) {
gamma.green = MIN_GAMMA;
} else if (green > MAX_GAMMA) {
gamma.green = MAX_GAMMA;
} else {
gamma.green = green;
}
if (blue < MIN_GAMMA) {
gamma.blue = MIN_GAMMA;
} else if (blue > MAX_GAMMA) {
gamma.blue = MAX_GAMMA;
} else {
gamma.blue = blue;
}
if (SDL_GetAppState() & SDL_APPACTIVE) {
succeeded =
SDL_NAME(XF86VidModeSetGamma) (SDL_Display, SDL_Screen,
&gamma);
XSync(SDL_Display, False);
} else {
gamma_saved[0] = gamma.red;
gamma_saved[1] = gamma.green;
gamma_saved[2] = gamma.blue;
succeeded = True;
}
if (succeeded) {
++gamma_changed;
}
return succeeded ? 0 : -1;
}
#endif
SDL_SetError("Gamma correction not supported");
return -1;
}
int
X11_SetVidModeGamma(_THIS, float red, float green, float blue)
{
int result;
SDL_Lock_EventThread();
result = X11_SetGammaNoLock(this, red, green, blue);
SDL_Unlock_EventThread();
return (result);
}
static int
X11_GetGammaNoLock(_THIS, float *red, float *green, float *blue)
{
#if SDL_VIDEO_DRIVER_X11_VIDMODE
if (use_vidmode >= 200) {
SDL_NAME(XF86VidModeGamma) gamma;
if (SDL_NAME(XF86VidModeGetGamma)
(SDL_Display, SDL_Screen, &gamma)) {
*red = gamma.red;
*green = gamma.green;
*blue = gamma.blue;
return 0;
}
return -1;
}
#endif
return -1;
}
int
X11_GetVidModeGamma(_THIS, float *red, float *green, float *blue)
{
int result;
SDL_Lock_EventThread();
result = X11_GetGammaNoLock(this, red, green, blue);
SDL_Unlock_EventThread();
return (result);
}
void
X11_SaveVidModeGamma(_THIS)
{
/* Try to save the current gamma, otherwise disable gamma control */
if (X11_GetGammaNoLock(this,
&gamma_saved[0], &gamma_saved[1],
&gamma_saved[2]) < 0) {
this->SetGamma = 0;
this->GetGamma = 0;
}
gamma_changed = 0;
}
void
X11_SwapVidModeGamma(_THIS)
{
float new_gamma[3];
if (gamma_changed) {
new_gamma[0] = gamma_saved[0];
new_gamma[1] = gamma_saved[1];
new_gamma[2] = gamma_saved[2];
X11_GetGammaNoLock(this, &gamma_saved[0], &gamma_saved[1],
&gamma_saved[2]);
X11_SetGammaNoLock(this, new_gamma[0], new_gamma[1], new_gamma[2]);
}
}
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,33 +0,0 @@
/*
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"
#ifndef _SDL_x11gamma_h
#define _SDL_x11gamma_h
extern int X11_SetVidModeGamma(_THIS, float red, float green, float blue);
extern int X11_GetVidModeGamma(_THIS, float *red, float *green, float *blue);
extern void X11_SaveVidModeGamma(_THIS);
extern void X11_SwapVidModeGamma(_THIS);
#endif
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,572 +0,0 @@
/*
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"
#include "SDL_x11video.h"
#include "../../events/SDL_events_c.h"
#include "SDL_x11dga_c.h"
#include "SDL_x11gl_c.h"
#if defined(__IRIX__)
/* IRIX doesn't have a GL library versioning system */
#define DEFAULT_OPENGL "libGL.so"
#elif defined(__MACOSX__)
#define DEFAULT_OPENGL "/usr/X11R6/lib/libGL.1.dylib"
#elif defined(__QNXNTO__)
#define DEFAULT_OPENGL "libGL.so.3"
#else
#define DEFAULT_OPENGL "libGL.so.1"
#endif
#ifndef GLX_ARB_multisample
#define GLX_ARB_multisample
#define GLX_SAMPLE_BUFFERS_ARB 100000
#define GLX_SAMPLES_ARB 100001
#endif
#ifndef GLX_EXT_visual_rating
#define GLX_EXT_visual_rating
#define GLX_VISUAL_CAVEAT_EXT 0x20
#define GLX_NONE_EXT 0x8000
#define GLX_SLOW_VISUAL_EXT 0x8001
#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
#endif
#if SDL_VIDEO_OPENGL_GLX
static int
glXExtensionSupported(_THIS, const char *extension)
{
const char *extensions;
const char *start;
const char *where, *terminator;
/* Extension names should not have spaces. */
where = SDL_strchr(extension, ' ');
if (where || *extension == '\0') {
return 0;
}
extensions =
this->gl_data->glXQueryExtensionsString(GFX_Display, SDL_Screen);
/* It takes a bit of care to be fool-proof about parsing the
* OpenGL extensions string. Don't be fooled by sub-strings, etc.
*/
start = extensions;
for (;;) {
where = SDL_strstr(start, extension);
if (!where)
break;
terminator = where + strlen(extension);
if (where == start || *(where - 1) == ' ')
if (*terminator == ' ' || *terminator == '\0')
return 1;
start = terminator;
}
return 0;
}
#endif /* SDL_VIDEO_OPENGL_GLX */
XVisualInfo *
X11_GL_GetVisual(_THIS)
{
#if SDL_VIDEO_OPENGL_GLX
/* 64 seems nice. */
int attribs[64];
int i;
/* load the gl driver from a default path */
if (!this->gl_config.driver_loaded) {
/* no driver has been loaded, use default (ourselves) */
if (X11_GL_LoadLibrary(this, NULL) < 0) {
return NULL;
}
}
/* See if we already have a window which we must use */
if (SDL_windowid) {
XWindowAttributes a;
XVisualInfo vi_in;
int out_count;
XGetWindowAttributes(SDL_Display, SDL_Window, &a);
vi_in.screen = SDL_Screen;
vi_in.visualid = XVisualIDFromVisual(a.visual);
glx_visualinfo = XGetVisualInfo(SDL_Display,
VisualScreenMask | VisualIDMask,
&vi_in, &out_count);
return glx_visualinfo;
}
/* Setup our GLX attributes according to the gl_config. */
i = 0;
attribs[i++] = GLX_RGBA;
attribs[i++] = GLX_RED_SIZE;
attribs[i++] = this->gl_config.red_size;
attribs[i++] = GLX_GREEN_SIZE;
attribs[i++] = this->gl_config.green_size;
attribs[i++] = GLX_BLUE_SIZE;
attribs[i++] = this->gl_config.blue_size;
if (this->gl_config.alpha_size) {
attribs[i++] = GLX_ALPHA_SIZE;
attribs[i++] = this->gl_config.alpha_size;
}
if (this->gl_config.buffer_size) {
attribs[i++] = GLX_BUFFER_SIZE;
attribs[i++] = this->gl_config.buffer_size;
}
if (this->gl_config.double_buffer) {
attribs[i++] = GLX_DOUBLEBUFFER;
}
attribs[i++] = GLX_DEPTH_SIZE;
attribs[i++] = this->gl_config.depth_size;
if (this->gl_config.stencil_size) {
attribs[i++] = GLX_STENCIL_SIZE;
attribs[i++] = this->gl_config.stencil_size;
}
if (this->gl_config.accum_red_size) {
attribs[i++] = GLX_ACCUM_RED_SIZE;
attribs[i++] = this->gl_config.accum_red_size;
}
if (this->gl_config.accum_green_size) {
attribs[i++] = GLX_ACCUM_GREEN_SIZE;
attribs[i++] = this->gl_config.accum_green_size;
}
if (this->gl_config.accum_blue_size) {
attribs[i++] = GLX_ACCUM_BLUE_SIZE;
attribs[i++] = this->gl_config.accum_blue_size;
}
if (this->gl_config.accum_alpha_size) {
attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
attribs[i++] = this->gl_config.accum_alpha_size;
}
if (this->gl_config.stereo) {
attribs[i++] = GLX_STEREO;
}
if (this->gl_config.multisamplebuffers) {
attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
attribs[i++] = this->gl_config.multisamplebuffers;
}
if (this->gl_config.multisamplesamples) {
attribs[i++] = GLX_SAMPLES_ARB;
attribs[i++] = this->gl_config.multisamplesamples;
}
if (this->gl_config.accelerated >= 0 &&
glXExtensionSupported(this, "GLX_EXT_visual_rating")) {
attribs[i++] = GLX_VISUAL_CAVEAT_EXT;
attribs[i++] = GLX_NONE_EXT;
}
#ifdef GLX_DIRECT_COLOR /* Try for a DirectColor visual for gamma support */
if (!SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR")) {
attribs[i++] = GLX_X_VISUAL_TYPE;
attribs[i++] = GLX_DIRECT_COLOR;
}
#endif
attribs[i++] = None;
glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display,
SDL_Screen, attribs);
#ifdef GLX_DIRECT_COLOR
if (!glx_visualinfo && !SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR")) { /* No DirectColor visual? Try again.. */
attribs[i - 3] = None;
glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display,
SDL_Screen, attribs);
}
#endif
if (!glx_visualinfo) {
SDL_SetError("Couldn't find matching GLX visual");
return NULL;
}
/*
printf("Found GLX visual 0x%x\n", glx_visualinfo->visualid);
*/
return glx_visualinfo;
#else
SDL_SetError("X11 driver not configured with OpenGL");
return NULL;
#endif
}
int
X11_GL_CreateWindow(_THIS, int w, int h)
{
int retval;
#if SDL_VIDEO_OPENGL_GLX
XSetWindowAttributes attributes;
unsigned long mask;
unsigned long black;
black = (glx_visualinfo->visual == DefaultVisual(SDL_Display, SDL_Screen))
? BlackPixel(SDL_Display, SDL_Screen) : 0;
attributes.background_pixel = black;
attributes.border_pixel = black;
attributes.colormap = SDL_XColorMap;
mask = CWBackPixel | CWBorderPixel | CWColormap;
SDL_Window = XCreateWindow(SDL_Display, WMwindow,
0, 0, w, h, 0, glx_visualinfo->depth,
InputOutput, glx_visualinfo->visual,
mask, &attributes);
if (!SDL_Window) {
SDL_SetError("Could not create window");
return -1;
}
retval = 0;
#else
SDL_SetError("X11 driver not configured with OpenGL");
retval = -1;
#endif
return (retval);
}
int
X11_GL_CreateContext(_THIS)
{
int retval;
#if SDL_VIDEO_OPENGL_GLX
/* We do this to create a clean separation between X and GLX errors. */
XSync(SDL_Display, False);
glx_context = this->gl_data->glXCreateContext(GFX_Display,
glx_visualinfo, NULL, True);
XSync(GFX_Display, False);
if (glx_context == NULL) {
SDL_SetError("Could not create GL context");
return (-1);
}
if (X11_GL_MakeCurrent(this) < 0) {
return (-1);
}
gl_active = 1;
if (!glXExtensionSupported(this, "SGI_swap_control")) {
this->gl_data->glXSwapIntervalSGI = NULL;
}
if (!glXExtensionSupported(this, "GLX_MESA_swap_control")) {
this->gl_data->glXSwapIntervalMESA = NULL;
this->gl_data->glXGetSwapIntervalMESA = NULL;
}
if (this->gl_config.swap_control >= 0) {
if (this->gl_data->glXSwapIntervalMESA) {
this->gl_data->glXSwapIntervalMESA(this->gl_config.swap_control);
} else if (this->gl_data->glXSwapIntervalSGI) {
this->gl_data->glXSwapIntervalSGI(this->gl_config.swap_control);
}
}
#else
SDL_SetError("X11 driver not configured with OpenGL");
#endif
if (gl_active) {
retval = 0;
} else {
retval = -1;
}
return (retval);
}
void
X11_GL_Shutdown(_THIS)
{
#if SDL_VIDEO_OPENGL_GLX
/* Clean up OpenGL */
if (glx_context) {
this->gl_data->glXMakeCurrent(GFX_Display, None, NULL);
if (glx_context != NULL)
this->gl_data->glXDestroyContext(GFX_Display, glx_context);
glx_context = NULL;
}
gl_active = 0;
#endif /* SDL_VIDEO_OPENGL_GLX */
}
#if SDL_VIDEO_OPENGL_GLX
/* Make the current context active */
int
X11_GL_MakeCurrent(_THIS)
{
int retval;
retval = 0;
if (!this->gl_data->glXMakeCurrent(GFX_Display, SDL_Window, glx_context)) {
SDL_SetError("Unable to make GL context current");
retval = -1;
}
XSync(GFX_Display, False);
/* More Voodoo X server workarounds... Grr... */
SDL_Lock_EventThread();
X11_CheckDGAMouse(this);
SDL_Unlock_EventThread();
return (retval);
}
/* Get attribute data from glX. */
int
X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int *value)
{
int retval;
int glx_attrib = None;
switch (attrib) {
case SDL_GL_RED_SIZE:
glx_attrib = GLX_RED_SIZE;
break;
case SDL_GL_GREEN_SIZE:
glx_attrib = GLX_GREEN_SIZE;
break;
case SDL_GL_BLUE_SIZE:
glx_attrib = GLX_BLUE_SIZE;
break;
case SDL_GL_ALPHA_SIZE:
glx_attrib = GLX_ALPHA_SIZE;
break;
case SDL_GL_DOUBLEBUFFER:
glx_attrib = GLX_DOUBLEBUFFER;
break;
case SDL_GL_BUFFER_SIZE:
glx_attrib = GLX_BUFFER_SIZE;
break;
case SDL_GL_DEPTH_SIZE:
glx_attrib = GLX_DEPTH_SIZE;
break;
case SDL_GL_STENCIL_SIZE:
glx_attrib = GLX_STENCIL_SIZE;
break;
case SDL_GL_ACCUM_RED_SIZE:
glx_attrib = GLX_ACCUM_RED_SIZE;
break;
case SDL_GL_ACCUM_GREEN_SIZE:
glx_attrib = GLX_ACCUM_GREEN_SIZE;
break;
case SDL_GL_ACCUM_BLUE_SIZE:
glx_attrib = GLX_ACCUM_BLUE_SIZE;
break;
case SDL_GL_ACCUM_ALPHA_SIZE:
glx_attrib = GLX_ACCUM_ALPHA_SIZE;
break;
case SDL_GL_STEREO:
glx_attrib = GLX_STEREO;
break;
case SDL_GL_MULTISAMPLEBUFFERS:
glx_attrib = GLX_SAMPLE_BUFFERS_ARB;
break;
case SDL_GL_MULTISAMPLESAMPLES:
glx_attrib = GLX_SAMPLES_ARB;
break;
case SDL_GL_ACCELERATED_VISUAL:
if (glXExtensionSupported(this, "GLX_EXT_visual_rating")) {
glx_attrib = GLX_VISUAL_CAVEAT_EXT;
retval =
this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo,
glx_attrib, value);
if (*value == GLX_SLOW_VISUAL_EXT) {
*value = SDL_FALSE;
} else {
*value = SDL_TRUE;
}
return retval;
} else {
return (-1);
}
break;
case SDL_GL_SWAP_CONTROL:
if (this->gl_data->glXGetSwapIntervalMESA) {
*value = this->gl_data->glXGetSwapIntervalMESA();
return (0);
} else {
return (-1);
}
break;
default:
return (-1);
}
retval =
this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib,
value);
return retval;
}
void
X11_GL_SwapBuffers(_THIS)
{
this->gl_data->glXSwapBuffers(GFX_Display, SDL_Window);
}
#endif /* SDL_VIDEO_OPENGL_GLX */
#define OPENGL_REQUIRS_DLOPEN
#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
#include <dlfcn.h>
#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
#define GL_LoadFunction dlsym
#define GL_UnloadObject dlclose
#else
#define GL_LoadObject SDL_LoadObject
#define GL_LoadFunction SDL_LoadFunction
#define GL_UnloadObject SDL_UnloadObject
#endif
void
X11_GL_UnloadLibrary(_THIS)
{
#if SDL_VIDEO_OPENGL_GLX
if (this->gl_config.driver_loaded) {
GL_UnloadObject(this->gl_config.dll_handle);
this->gl_data->glXGetProcAddress = NULL;
this->gl_data->glXChooseVisual = NULL;
this->gl_data->glXCreateContext = NULL;
this->gl_data->glXDestroyContext = NULL;
this->gl_data->glXMakeCurrent = NULL;
this->gl_data->glXSwapBuffers = NULL;
this->gl_data->glXSwapIntervalSGI = NULL;
this->gl_data->glXSwapIntervalMESA = NULL;
this->gl_data->glXGetSwapIntervalMESA = NULL;
this->gl_config.dll_handle = NULL;
this->gl_config.driver_loaded = 0;
}
#endif
}
#if SDL_VIDEO_OPENGL_GLX
/* Passing a NULL path means load pointers from the application */
int
X11_GL_LoadLibrary(_THIS, const char *path)
{
void *handle = NULL;
if (gl_active) {
SDL_SetError("OpenGL context already created");
return -1;
}
if (path == NULL) {
path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
if (path == NULL) {
path = DEFAULT_OPENGL;
}
}
handle = GL_LoadObject(path);
if (handle == NULL) {
/* SDL_LoadObject() will call SDL_SetError() for us. */
return -1;
}
/* Unload the old driver and reset the pointers */
X11_GL_UnloadLibrary(this);
/* Load new function pointers */
this->gl_data->glXGetProcAddress =
(void *(*)(const GLubyte *)) GL_LoadFunction(handle,
"glXGetProcAddressARB");
this->gl_data->glXChooseVisual =
(XVisualInfo * (*)(Display *, int, int *)) GL_LoadFunction(handle,
"glXChooseVisual");
this->gl_data->glXCreateContext =
(GLXContext(*)(Display *, XVisualInfo *, GLXContext, int))
GL_LoadFunction(handle, "glXCreateContext");
this->gl_data->glXDestroyContext =
(void (*)(Display *, GLXContext)) GL_LoadFunction(handle,
"glXDestroyContext");
this->gl_data->glXMakeCurrent =
(int (*)(Display *, GLXDrawable, GLXContext)) GL_LoadFunction(handle,
"glXMakeCurrent");
this->gl_data->glXSwapBuffers =
(void (*)(Display *, GLXDrawable)) GL_LoadFunction(handle,
"glXSwapBuffers");
this->gl_data->glXGetConfig =
(int (*)(Display *, XVisualInfo *, int, int *))
GL_LoadFunction(handle, "glXGetConfig");
this->gl_data->glXQueryExtensionsString =
(const char *(*)(Display *, int)) GL_LoadFunction(handle,
"glXQueryExtensionsString");
this->gl_data->glXSwapIntervalSGI =
(int (*)(int)) GL_LoadFunction(handle, "glXSwapIntervalSGI");
this->gl_data->glXSwapIntervalMESA =
(GLint(*)(unsigned)) GL_LoadFunction(handle, "glXSwapIntervalMESA");
this->gl_data->glXGetSwapIntervalMESA =
(GLint(*)(void)) GL_LoadFunction(handle, "glXGetSwapIntervalMESA");
if ((this->gl_data->glXChooseVisual == NULL) ||
(this->gl_data->glXCreateContext == NULL) ||
(this->gl_data->glXDestroyContext == NULL) ||
(this->gl_data->glXMakeCurrent == NULL) ||
(this->gl_data->glXSwapBuffers == NULL) ||
(this->gl_data->glXGetConfig == NULL) ||
(this->gl_data->glXQueryExtensionsString == NULL)) {
SDL_SetError("Could not retrieve OpenGL functions");
return -1;
}
this->gl_config.dll_handle = handle;
this->gl_config.driver_loaded = 1;
if (path) {
SDL_strlcpy(this->gl_config.driver_path, path,
SDL_arraysize(this->gl_config.driver_path));
} else {
*this->gl_config.driver_path = '\0';
}
return 0;
}
void *
X11_GL_GetProcAddress(_THIS, const char *proc)
{
void *handle;
handle = this->gl_config.dll_handle;
if (this->gl_data->glXGetProcAddress) {
return this->gl_data->glXGetProcAddress((const GLubyte *) proc);
}
return GL_LoadFunction(handle, proc);
}
#endif /* SDL_VIDEO_OPENGL_GLX */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,84 +0,0 @@
/*
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"
#if SDL_VIDEO_OPENGL_GLX
#include <GL/glx.h>
#include "SDL_loadso.h"
#endif
#include "../SDL_sysvideo.h"
struct SDL_PrivateGLData
{
int gl_active; /* to stop switching drivers while we have a valid context */
#if SDL_VIDEO_OPENGL_GLX
GLXContext glx_context; /* Current GL context */
XVisualInfo *glx_visualinfo; /* XVisualInfo* returned by glXChooseVisual */
void *(*glXGetProcAddress) (const GLubyte * procName);
XVisualInfo *(*glXChooseVisual)
(Display * dpy, int screen, int *attribList);
GLXContext(*glXCreateContext)
(Display * dpy, XVisualInfo * vis, GLXContext shareList, Bool direct);
void (*glXDestroyContext) (Display * dpy, GLXContext ctx);
Bool(*glXMakeCurrent)
(Display * dpy, GLXDrawable drawable, GLXContext ctx);
void (*glXSwapBuffers) (Display * dpy, GLXDrawable drawable);
int (*glXGetConfig)
(Display * dpy, XVisualInfo * visual_info, int attrib, int *value);
const char *(*glXQueryExtensionsString) (Display * dpy, int screen);
int (*glXSwapIntervalSGI) (int interval);
GLint(*glXSwapIntervalMESA) (unsigned interval);
GLint(*glXGetSwapIntervalMESA) (void);
#endif /* SDL_VIDEO_OPENGL_GLX */
};
/* Old variable names */
#define gl_active (this->gl_data->gl_active)
#define glx_context (this->gl_data->glx_context)
#define glx_visualinfo (this->gl_data->glx_visualinfo)
/* OpenGL functions */
extern XVisualInfo *X11_GL_GetVisual(_THIS);
extern int X11_GL_CreateWindow(_THIS, int w, int h);
extern int X11_GL_CreateContext(_THIS);
extern void X11_GL_Shutdown(_THIS);
#if SDL_VIDEO_OPENGL_GLX
extern int X11_GL_MakeCurrent(_THIS);
extern int X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int *value);
extern void X11_GL_SwapBuffers(_THIS);
extern int X11_GL_LoadLibrary(_THIS, const char *path);
extern void *X11_GL_GetProcAddress(_THIS, const char *proc);
#endif
extern void X11_GL_UnloadLibrary(_THIS);
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,340 +0,0 @@
/*
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"
#include <stdio.h>
#include <unistd.h>
#include "SDL_endian.h"
#include "../../events/SDL_events_c.h"
#include "SDL_x11image_c.h"
#ifndef NO_SHARED_MEMORY
/* Shared memory error handler routine */
static int shm_error;
static int (*X_handler) (Display *, XErrorEvent *) = NULL;
static int
shm_errhandler(Display * d, XErrorEvent * e)
{
if (e->error_code == BadAccess) {
shm_error = True;
return (0);
} else
return (X_handler(d, e));
}
static void
try_mitshm(_THIS, SDL_Surface * screen)
{
/* Dynamic X11 may not have SHM entry points on this box. */
if ((use_mitshm) && (!SDL_X11_HAVE_SHM))
use_mitshm = 0;
if (!use_mitshm)
return;
shminfo.shmid = shmget(IPC_PRIVATE, screen->h * screen->pitch,
IPC_CREAT | 0777);
if (shminfo.shmid >= 0) {
shminfo.shmaddr = (char *) shmat(shminfo.shmid, 0, 0);
shminfo.readOnly = False;
if (shminfo.shmaddr != (char *) -1) {
shm_error = False;
X_handler = XSetErrorHandler(shm_errhandler);
XShmAttach(SDL_Display, &shminfo);
XSync(SDL_Display, True);
XSetErrorHandler(X_handler);
if (shm_error)
shmdt(shminfo.shmaddr);
} else {
shm_error = True;
}
shmctl(shminfo.shmid, IPC_RMID, NULL);
} else {
shm_error = True;
}
if (shm_error)
use_mitshm = 0;
if (use_mitshm)
screen->pixels = shminfo.shmaddr;
}
#endif /* ! NO_SHARED_MEMORY */
/* Various screen update functions available */
static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect * rects);
static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect * rects);
int
X11_SetupImage(_THIS, SDL_Surface * screen)
{
#ifndef NO_SHARED_MEMORY
try_mitshm(this, screen);
if (use_mitshm) {
SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual,
this->hidden->depth, ZPixmap,
shminfo.shmaddr, &shminfo,
screen->w, screen->h);
if (!SDL_Ximage) {
XShmDetach(SDL_Display, &shminfo);
XSync(SDL_Display, False);
shmdt(shminfo.shmaddr);
screen->pixels = NULL;
goto error;
}
this->UpdateRects = X11_MITSHMUpdate;
}
if (!use_mitshm)
#endif /* not NO_SHARED_MEMORY */
{
int bpp;
screen->pixels = SDL_malloc(screen->h * screen->pitch);
if (screen->pixels == NULL) {
SDL_OutOfMemory();
return -1;
}
bpp = screen->format->BytesPerPixel;
SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual,
this->hidden->depth, ZPixmap, 0,
(char *) screen->pixels,
screen->w, screen->h, 32, 0);
if (SDL_Ximage == NULL)
goto error;
/* XPutImage will convert byte sex automatically */
SDL_Ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN)
? MSBFirst : LSBFirst;
this->UpdateRects = X11_NormalUpdate;
}
screen->pitch = SDL_Ximage->bytes_per_line;
return (0);
error:
SDL_SetError("Couldn't create XImage");
return 1;
}
void
X11_DestroyImage(_THIS, SDL_Surface * screen)
{
if (SDL_Ximage) {
XDestroyImage(SDL_Ximage);
#ifndef NO_SHARED_MEMORY
if (use_mitshm) {
XShmDetach(SDL_Display, &shminfo);
XSync(SDL_Display, False);
shmdt(shminfo.shmaddr);
}
#endif /* ! NO_SHARED_MEMORY */
SDL_Ximage = NULL;
}
if (screen) {
screen->pixels = NULL;
}
}
/* Determine the number of CPUs in the system */
static int
num_CPU(void)
{
static int num_cpus = 0;
if (!num_cpus) {
#if defined(__LINUX__)
char line[BUFSIZ];
FILE *pstat = fopen("/proc/stat", "r");
if (pstat) {
while (fgets(line, sizeof(line), pstat)) {
if (SDL_memcmp(line, "cpu", 3) == 0 && line[3] != ' ') {
++num_cpus;
}
}
fclose(pstat);
}
#elif defined(__IRIX__)
num_cpus = sysconf(_SC_NPROC_ONLN);
#elif defined(_SC_NPROCESSORS_ONLN)
/* number of processors online (SVR4.0MP compliant machines) */
num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(_SC_NPROCESSORS_CONF)
/* number of processors configured (SVR4.0MP compliant machines) */
num_cpus = sysconf(_SC_NPROCESSORS_CONF);
#endif
if (num_cpus <= 0) {
num_cpus = 1;
}
}
return num_cpus;
}
int
X11_ResizeImage(_THIS, SDL_Surface * screen, Uint32 flags)
{
int retval;
X11_DestroyImage(this, screen);
if (flags & SDL_INTERNALOPENGL) { /* No image when using GL */
retval = 0;
} else {
retval = X11_SetupImage(this, screen);
/* We support asynchronous blitting on the display */
if (flags & SDL_ASYNCBLIT) {
/* This is actually slower on single-CPU systems,
probably because of CPU contention between the
X server and the application.
Note: Is this still true with XFree86 4.0?
*/
if (num_CPU() > 1) {
screen->flags |= SDL_ASYNCBLIT;
}
}
}
return (retval);
}
/* We don't actually allow hardware surfaces other than the main one */
int
X11_AllocHWSurface(_THIS, SDL_Surface * surface)
{
return (-1);
}
void
X11_FreeHWSurface(_THIS, SDL_Surface * surface)
{
return;
}
int
X11_LockHWSurface(_THIS, SDL_Surface * surface)
{
if ((surface == SDL_VideoSurface) && blit_queued) {
XSync(GFX_Display, False);
blit_queued = 0;
}
return (0);
}
void
X11_UnlockHWSurface(_THIS, SDL_Surface * surface)
{
return;
}
int
X11_FlipHWSurface(_THIS, SDL_Surface * surface)
{
return (0);
}
static void
X11_NormalUpdate(_THIS, int numrects, SDL_Rect * rects)
{
int i;
for (i = 0; i < numrects; ++i) {
if (rects[i].w == 0 || rects[i].h == 0) { /* Clipped? */
continue;
}
XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
rects[i].x, rects[i].y,
rects[i].x, rects[i].y, rects[i].w, rects[i].h);
}
if (SDL_VideoSurface->flags & SDL_ASYNCBLIT) {
XFlush(GFX_Display);
blit_queued = 1;
} else {
XSync(GFX_Display, False);
}
}
static void
X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect * rects)
{
#ifndef NO_SHARED_MEMORY
int i;
for (i = 0; i < numrects; ++i) {
if (rects[i].w == 0 || rects[i].h == 0) { /* Clipped? */
continue;
}
XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
rects[i].x, rects[i].y,
rects[i].x, rects[i].y, rects[i].w, rects[i].h, False);
}
if (SDL_VideoSurface->flags & SDL_ASYNCBLIT) {
XFlush(GFX_Display);
blit_queued = 1;
} else {
XSync(GFX_Display, False);
}
#endif /* ! NO_SHARED_MEMORY */
}
/* There's a problem with the automatic refreshing of the display.
Even though the XVideo code uses the GFX_Display to update the
video memory, it appears that updating the window asynchronously
from a different thread will cause "blackouts" of the window.
This is a sort of a hacked workaround for the problem.
*/
static int enable_autorefresh = 1;
void
X11_DisableAutoRefresh(_THIS)
{
--enable_autorefresh;
}
void
X11_EnableAutoRefresh(_THIS)
{
++enable_autorefresh;
}
void
X11_RefreshDisplay(_THIS)
{
/* Don't refresh a display that doesn't have an image (like GL)
Instead, post an expose event so the application can refresh.
*/
if (!SDL_Ximage || (enable_autorefresh <= 0)) {
SDL_PrivateExpose();
return;
}
#ifndef NO_SHARED_MEMORY
if (this->UpdateRects == X11_MITSHMUpdate) {
XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
0, 0, SDL_CurrentWindow.offset_x,
SDL_CurrentWindow.offset_y,
SDL_CurrentDisplay.current_mode.w,
SDL_CurrentDisplay.current_mode.h, False);
} else
#endif /* ! NO_SHARED_MEMORY */
{
XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
0, 0, SDL_CurrentWindow.offset_x,
SDL_CurrentWindow.offset_y,
SDL_CurrentDisplay.current_mode.w,
SDL_CurrentDisplay.current_mode.h);
}
XSync(SDL_Display, False);
}
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,39 +0,0 @@
/*
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"
#include "SDL_x11video.h"
extern int X11_SetupImage(_THIS, SDL_Surface * screen);
extern void X11_DestroyImage(_THIS, SDL_Surface * screen);
extern int X11_ResizeImage(_THIS, SDL_Surface * screen, Uint32 flags);
extern int X11_AllocHWSurface(_THIS, SDL_Surface * surface);
extern void X11_FreeHWSurface(_THIS, SDL_Surface * surface);
extern int X11_LockHWSurface(_THIS, SDL_Surface * surface);
extern void X11_UnlockHWSurface(_THIS, SDL_Surface * surface);
extern int X11_FlipHWSurface(_THIS, SDL_Surface * surface);
extern void X11_DisableAutoRefresh(_THIS);
extern void X11_EnableAutoRefresh(_THIS);
extern void X11_RefreshDisplay(_THIS);
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,965 +0,0 @@
/*
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"
/* Utilities for getting and setting the X display mode */
#include <stdio.h>
#include "SDL_timer.h"
#include "SDL_events.h"
#include "../../events/SDL_events_c.h"
#include "SDL_x11video.h"
#include "SDL_x11wm_c.h"
#include "SDL_x11modes_c.h"
#include "SDL_x11image_c.h"
/*#define X11MODES_DEBUG*/
#define MAX(a, b) (a > b ? a : b)
#if SDL_VIDEO_DRIVER_X11_VIDMODE
int
vidmode_refreshrate(SDL_NAME(XF86VidModeModeInfo) * mode)
{
return (mode->htotal
&& mode->vtotal) ? (1000 * mode->dotclock / (mode->htotal *
mode->vtotal)) : 0;
}
#endif
#if SDL_VIDEO_DRIVER_X11_VIDMODE
Bool SDL_NAME(XF86VidModeGetModeInfo) (Display * dpy, int scr,
SDL_NAME(XF86VidModeModeInfo) * info)
{
SDL_NAME(XF86VidModeModeLine) * l =
(SDL_NAME(XF86VidModeModeLine) *) ((char *) info +
sizeof info->dotclock);
return SDL_NAME(XF86VidModeGetModeLine) (dpy, scr,
(int *) &info->dotclock, l);
}
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
#if SDL_VIDEO_DRIVER_X11_VIDMODE
static void
save_mode(_THIS)
{
SDL_memset(&saved_mode, 0, sizeof(saved_mode));
SDL_NAME(XF86VidModeGetModeInfo) (SDL_Display, SDL_Screen, &saved_mode);
SDL_NAME(XF86VidModeGetViewPort) (SDL_Display, SDL_Screen, &saved_view.x,
&saved_view.y);
}
#endif
#if SDL_VIDEO_DRIVER_X11_VIDMODE
static void
restore_mode(_THIS)
{
SDL_NAME(XF86VidModeModeLine) mode;
int unused;
if (SDL_NAME(XF86VidModeGetModeLine)
(SDL_Display, SDL_Screen, &unused, &mode)) {
if ((saved_mode.hdisplay != mode.hdisplay) ||
(saved_mode.vdisplay != mode.vdisplay)) {
SDL_NAME(XF86VidModeSwitchToMode) (SDL_Display, SDL_Screen,
&saved_mode);
}
}
if ((saved_view.x != 0) || (saved_view.y != 0)) {
SDL_NAME(XF86VidModeSetViewPort) (SDL_Display, SDL_Screen,
saved_view.x, saved_view.y);
}
}
#endif
static void get_real_resolution(_THIS, int *w, int *h);
static void
set_best_resolution(_THIS, int width, int height)
{
SDL_DisplayMode mode;
mode.format = 0;
mode.w = width;
mode.h = height;
mode.refresh_rate = 0;
SDL_GetClosestDisplayMode(&mode, &mode, SDL_FULLSCREEN);
#if SDL_VIDEO_DRIVER_X11_VIDMODE
if (use_vidmode) {
SDL_NAME(XF86VidModeModeLine) vmode;
SDL_NAME(XF86VidModeModeInfo) vinfo;
SDL_NAME(XF86VidModeModeInfo) ** modes;
int i, dotclock;
int nmodes;
int best = -1;
if (SDL_NAME(XF86VidModeGetModeLine)
(SDL_Display, SDL_Screen, &dotclock, &vmode)
&& SDL_NAME(XF86VidModeGetAllModeLines) (SDL_Display,
SDL_Screen, &nmodes,
&modes)) {
vinfo.dotclock = dotclock;
SDL_memcpy(&vinfo.hdisplay, &vmode, sizeof(vmode));
for (i = 0; i < nmodes; i++) {
if ((modes[i]->hdisplay == mode.w) &&
(modes[i]->vdisplay == mode.h) &&
(vidmode_refreshrate(modes[i]) == mode.refresh_rate)) {
best = i;
break;
}
}
if (best >= 0 &&
((modes[best]->hdisplay != vmode.hdisplay) ||
(modes[best]->vdisplay != vmode.vdisplay) ||
(vidmode_refreshrate(modes[best]) !=
vidmode_refreshrate(&vinfo)))) {
#ifdef X11MODES_DEBUG
printf("Best Mode %d: %d x %d @ %d\n", best,
modes[best]->hdisplay, modes[best]->vdisplay,
vidmode_refreshrate(modes[best]));
#endif
SDL_NAME(XF86VidModeSwitchToMode) (SDL_Display,
SDL_Screen, modes[best]);
}
XFree(modes);
}
}
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
/* XiG */
#if SDL_VIDEO_DRIVER_X11_XME
if (use_xme) {
int i;
int w, h;
/* check current mode so we can avoid uneccessary mode changes */
get_real_resolution(this, &w, &h);
if ((mode.w != w) || (mode.h != h)) {
#ifdef X11MODES_DEBUG
fprintf(stderr, "XME: set_best_resolution: "
"XiGMiscChangeResolution: %d %d\n", mode.w, mode.h);
#endif
XiGMiscChangeResolution(SDL_Display, SDL_Screen, 0, /* view */
mode.w, mode.h, 0);
XSync(SDL_Display, False);
}
}
#endif /* SDL_VIDEO_DRIVER_X11_XME */
#if SDL_VIDEO_DRIVER_X11_XRANDR
if (use_xrandr) {
int i, nsizes;
XRRScreenSize *sizes;
/* find the smallest resolution that is at least as big as the user requested */
sizes = XRRConfigSizes(screen_config, &nsizes);
for (i = (nsizes - 1); i >= 0; i--) {
if ((mode.w >= width) && (mode.h >= height)) {
break;
}
}
if (i >= 0) { /* found one, lets try it */
int w, h;
/* check current mode so we can avoid uneccessary mode changes */
get_real_resolution(this, &w, &h);
if ((mode.w != w) || (mode.h != h)) {
int size_id;
#ifdef X11MODES_DEBUG
fprintf(stderr, "XRANDR: set_best_resolution: "
"XXRSetScreenConfig: %d %d\n", mode.w, mode.h);
#endif
/* find the matching size entry index */
for (size_id = 0; size_id < nsizes; ++size_id) {
if ((sizes[size_id].width == mode.w) &&
(sizes[size_id].height == mode.h))
break;
}
XRRSetScreenConfig(SDL_Display, screen_config,
SDL_Root, size_id, saved_rotation,
CurrentTime);
}
}
}
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
}
static void
get_real_resolution(_THIS, int *w, int *h)
{
#if SDL_VIDEO_DRIVER_X11_XME
if (use_xme) {
int ractive;
XiGMiscResolutionInfo *modelist;
XiGMiscQueryResolutions(SDL_Display, SDL_Screen, 0, /* view */
&ractive, &modelist);
*w = modelist[ractive].width;
*h = modelist[ractive].height;
#ifdef X11MODES_DEBUG
fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h);
#endif
XFree(modelist);
return;
}
#endif /* SDL_VIDEO_DRIVER_X11_XME */
#if SDL_VIDEO_DRIVER_X11_VIDMODE
if (use_vidmode) {
SDL_NAME(XF86VidModeModeLine) mode;
int unused;
if (SDL_NAME(XF86VidModeGetModeLine)
(SDL_Display, SDL_Screen, &unused, &mode)) {
*w = mode.hdisplay;
*h = mode.vdisplay;
return;
}
}
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
#if SDL_VIDEO_DRIVER_X11_XRANDR
if (use_xrandr) {
int nsizes;
XRRScreenSize *sizes;
sizes = XRRConfigSizes(screen_config, &nsizes);
if (nsizes > 0) {
int cur_size;
Rotation cur_rotation;
cur_size =
XRRConfigCurrentConfiguration(screen_config, &cur_rotation);
if (cur_size >= 0 && cur_size < nsizes) {
*w = sizes[cur_size].width;
*h = sizes[cur_size].height;
}
#ifdef X11MODES_DEBUG
fprintf(stderr,
"XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h);
#endif
return;
}
}
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
#if SDL_VIDEO_DRIVER_X11_XINERAMA
if (use_xinerama) {
*w = xinerama[this->current_display].width;
*h = xinerama[this->current_display].height;
return;
}
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
*w = DisplayWidth(SDL_Display, SDL_Screen);
*h = DisplayHeight(SDL_Display, SDL_Screen);
}
/* Called after mapping a window - waits until the window is mapped */
void
X11_WaitMapped(_THIS, Window win)
{
XEvent event;
do {
XMaskEvent(SDL_Display, StructureNotifyMask, &event);
}
while ((event.type != MapNotify) || (event.xmap.event != win));
}
/* Called after unmapping a window - waits until the window is unmapped */
void
X11_WaitUnmapped(_THIS, Window win)
{
XEvent event;
do {
XMaskEvent(SDL_Display, StructureNotifyMask, &event);
}
while ((event.type != UnmapNotify) || (event.xunmap.event != win));
}
static void
move_cursor_to(_THIS, int x, int y)
{
XWarpPointer(SDL_Display, None, SDL_Root, 0, 0, 0, 0, x, y);
}
static int
add_visual(_THIS, int depth, int class)
{
XVisualInfo vi;
if (XMatchVisualInfo(SDL_Display, SDL_Screen, depth, class, &vi)) {
int n = this->hidden->nvisuals;
this->hidden->visuals[n].depth = vi.depth;
this->hidden->visuals[n].visual = vi.visual;
this->hidden->nvisuals++;
}
return (this->hidden->nvisuals);
}
static int
add_visual_byid(_THIS, const char *visual_id)
{
XVisualInfo *vi, template;
int nvis;
if (visual_id) {
SDL_memset(&template, 0, (sizeof template));
template.visualid = SDL_strtol(visual_id, NULL, 0);
vi = XGetVisualInfo(SDL_Display, VisualIDMask, &template, &nvis);
if (vi) {
int n = this->hidden->nvisuals;
this->hidden->visuals[n].depth = vi->depth;
this->hidden->visuals[n].visual = vi->visual;
this->hidden->nvisuals++;
XFree(vi);
}
}
return (this->hidden->nvisuals);
}
int
X11_GetVisuals(_THIS)
{
/* It's interesting to note that if we allow 32 bit depths,
we get a visual with an alpha mask on composite servers.
static int depth_list[] = { 32, 24, 16, 15, 8 };
*/
static int depth_list[] = { 24, 16, 15, 8 };
int i, j, np;
int use_directcolor = 1;
XPixmapFormatValues *pf;
/* Search for the visuals in deepest-first order, so that the first
will be the richest one */
if (SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR")) {
use_directcolor = 0;
}
this->hidden->nvisuals = 0;
if (!add_visual_byid(this, SDL_getenv("SDL_VIDEO_X11_VISUALID"))) {
for (i = 0; i < SDL_arraysize(depth_list); ++i) {
if (depth_list[i] > 8) {
if (use_directcolor) {
add_visual(this, depth_list[i], DirectColor);
}
add_visual(this, depth_list[i], TrueColor);
} else {
add_visual(this, depth_list[i], PseudoColor);
add_visual(this, depth_list[i], StaticColor);
}
}
}
if (this->hidden->nvisuals == 0) {
SDL_SetError("Found no sufficiently capable X11 visuals");
return -1;
}
/* look up the pixel quantum for each depth */
pf = XListPixmapFormats(SDL_Display, &np);
for (i = 0; i < this->hidden->nvisuals; i++) {
int d = this->hidden->visuals[i].depth;
for (j = 0; j < np; j++)
if (pf[j].depth == d)
break;
this->hidden->visuals[i].bpp = j < np ? pf[j].bits_per_pixel : d;
}
XFree(pf);
return 0;
}
/* Global for the error handler */
int vm_event, vm_error = -1;
#if SDL_VIDEO_DRIVER_X11_XINERAMA
static int
CheckXinerama(_THIS, int *major, int *minor)
{
const char *env;
/* Default the extension not available */
*major = *minor = 0;
/* Allow environment override */
env = getenv("SDL_VIDEO_X11_XINERAMA");
if (env && !SDL_atoi(env)) {
return 0;
}
/* Query the extension version */
if (!SDL_NAME(XineramaQueryExtension) (SDL_Display, major, minor) ||
!SDL_NAME(XineramaIsActive) (SDL_Display)) {
return 0;
}
return 1;
}
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
#if SDL_VIDEO_DRIVER_X11_XRANDR
static int
CheckXRandR(_THIS, int *major, int *minor)
{
const char *env;
/* Default the extension not available */
*major = *minor = 0;
/* Allow environment override */
env = getenv("SDL_VIDEO_X11_XRANDR");
if (env && !SDL_atoi(env)) {
return 0;
}
/* This defaults off now, due to KDE window maximize problems */
if (!env) {
return 0;
}
if (!SDL_X11_HAVE_XRANDR) {
return 0;
}
/* Query the extension version */
if (!XRRQueryVersion(SDL_Display, major, minor)) {
return 0;
}
return 1;
}
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
#if SDL_VIDEO_DRIVER_X11_VIDMODE
static int
CheckVidMode(_THIS, int *major, int *minor)
{
const char *env;
/* Default the extension not available */
*major = *minor = 0;
/* Allow environment override */
env = getenv("SDL_VIDEO_X11_VIDMODE");
if (env && !SDL_atoi(env)) {
return 0;
}
/* Metro-X 4.3.0 and earlier has a broken implementation of
XF86VidModeGetAllModeLines() - it hangs the client.
*/
if (SDL_strcmp(ServerVendor(SDL_Display), "Metro Link Incorporated") == 0) {
FILE *metro_fp;
metro_fp = fopen("/usr/X11R6/lib/X11/Metro/.version", "r");
if (metro_fp != NULL) {
int major, minor, patch, version;
major = 0;
minor = 0;
patch = 0;
fscanf(metro_fp, "%d.%d.%d", &major, &minor, &patch);
fclose(metro_fp);
version = major * 100 + minor * 10 + patch;
if (version < 431) {
return 0;
}
}
}
/* Query the extension version */
vm_error = -1;
if (!SDL_NAME(XF86VidModeQueryExtension)
(SDL_Display, &vm_event, &vm_error)
|| !SDL_NAME(XF86VidModeQueryVersion) (SDL_Display, major, minor)) {
return 0;
}
return 1;
}
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
#if SDL_VIDEO_DRIVER_X11_XME
static int
CheckXME(_THIS, int *major, int *minor)
{
const char *env;
/* Default the extension not available */
*major = *minor = 0;
/* Allow environment override */
env = getenv("SDL_VIDEO_X11_VIDMODE");
if (env && !SDL_atoi(env)) {
return 0;
}
/* Query the extension version */
if (!XiGMiscQueryVersion(SDL_Display, major, minor)) {
return 0;
}
return 1;
}
#endif /* SDL_VIDEO_DRIVER_X11_XME */
int
X11_GetVideoModes(_THIS)
{
#if SDL_VIDEO_DRIVER_X11_XINERAMA
int xinerama_major, xinerama_minor;
#endif
#if SDL_VIDEO_DRIVER_X11_XRANDR
int xrandr_major, xrandr_minor;
int nsizes;
XRRScreenSize *sizes;
int nrates;
short *rates;
#endif
#if SDL_VIDEO_DRIVER_X11_VIDMODE
int vm_major, vm_minor;
int nmodes;
SDL_NAME(XF86VidModeModeInfo) ** modes;
#endif
#if SDL_VIDEO_DRIVER_X11_XME
int xme_major, xme_minor;
int ractive, nummodes;
XiGMiscResolutionInfo *modelist;
#endif
int i;
int screen_w;
int screen_h;
SDL_DisplayMode mode;
use_xinerama = 0;
use_xrandr = 0;
use_vidmode = 0;
use_xme = 0;
screen_w = DisplayWidth(SDL_Display, SDL_Screen);
screen_h = DisplayHeight(SDL_Display, SDL_Screen);
mode.format = this->displays[this->current_display].desktop_mode.format;
mode.w = screen_w;
mode.h = screen_h;
mode.refresh_rate = 0;
SDL_AddDisplayMode(0, &mode);
#if SDL_VIDEO_DRIVER_X11_XINERAMA
/* Query Xinerama extention */
if (CheckXinerama(this, &xinerama_major, &xinerama_minor)) {
int screens;
#ifdef X11MODES_DEBUG
printf("X11 detected Xinerama:\n");
#endif
xinerama = SDL_NAME(XineramaQueryScreens) (SDL_Display, &screens);
for (i = 0; i < screens; i++) {
#ifdef X11MODES_DEBUG
printf("xinerama %d: %dx%d+%d+%d\n",
xinerama[i].screen_number,
xinerama[i].width, xinerama[i].height,
xinerama[i].x_org, xinerama[i].y_org);
#endif
if (xinerama[i].screen_number != 0) {
SDL_AddVideoDisplay(&mode);
}
mode.w = xinerama[i].width;
mode.h = xinerama[i].height;
SDL_AddDisplayMode(xinerama[i].screen_number, &mode);
}
use_xinerama = 1;
}
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
#if SDL_VIDEO_DRIVER_X11_XRANDR
/* XRandR */
/* require at least XRandR v1.0 (arbitrary) */
if (CheckXRandR(this, &xrandr_major, &xrandr_minor)
&& (xrandr_major >= 1)) {
#ifdef X11MODES_DEBUG
fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n",
xrandr_major, xrandr_minor);
#endif
/* save the screen configuration since we must reference it
each time we toggle modes.
*/
screen_config = XRRGetScreenInfo(SDL_Display, SDL_Root);
/* retrieve the list of resolution */
sizes = XRRConfigSizes(screen_config, &nsizes);
if (nsizes > 0) {
for (i = 0; i < nsizes; i++) {
mode.w = sizes[i].width;
mode.h = sizes[i].height;
rates = XRRConfigRates(screen_config, i, &nrates);
if (nrates == 0) {
mode.refresh_rate = 0;
SDL_AddDisplayMode(0, &mode);
} else {
int j;
for (j = 0; j < nrates; ++j) {
mode.refresh_rate = rates[j];
SDL_AddDisplayMode(0, &mode);
}
}
}
use_xrandr = xrandr_major * 100 + xrandr_minor;
saved_size_id =
XRRConfigCurrentConfiguration(screen_config, &saved_rotation);
}
}
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
#if SDL_VIDEO_DRIVER_X11_VIDMODE
/* XVidMode */
if (!use_xrandr &&
CheckVidMode(this, &vm_major, &vm_minor) &&
SDL_NAME(XF86VidModeGetAllModeLines) (SDL_Display, SDL_Screen,
&nmodes, &modes)) {
#ifdef X11MODES_DEBUG
printf("VidMode modes: (unsorted)\n");
for (i = 0; i < nmodes; ++i) {
printf("Mode %d: %d x %d @ %d\n", i,
modes[i]->hdisplay, modes[i]->vdisplay,
vidmode_refreshrate(modes[i]));
}
#endif
for (i = 0; i < nmodes; ++i) {
mode.w = modes[i]->hdisplay;
mode.h = modes[i]->vdisplay;
mode.refresh_rate = vidmode_refreshrate(modes[i]);
SDL_AddDisplayMode(0, &mode);
}
XFree(modes);
use_vidmode = vm_major * 100 + vm_minor;
save_mode(this);
}
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
#if SDL_VIDEO_DRIVER_X11_XME
/* XiG */
modelist = NULL;
/* first lets make sure we have the extension, and it's at least v2.0 */
if (CheckXME(this, &xme_major, &xme_minor) && xme_major >= 2 && (nummodes = XiGMiscQueryResolutions(SDL_Display, SDL_Screen, 0, /* view */
&ractive,
&modelist))
> 1) { /* then we actually have some */
/* We get the list already sorted in descending order.
We'll copy it in reverse order so SDL is happy */
#ifdef X11MODES_DEBUG
fprintf(stderr, "XME: nummodes = %d, active mode = %d\n",
nummodes, ractive);
#endif
mode.refresh_rate = 0;
for (i = 0; i < nummodes; ++i) {
#ifdef X11MODES_DEBUG
fprintf(stderr, "XME: mode = %4d, w = %4d, h = %4d\n",
i, modelist[i].width, modelist[i].height);
#endif
mode.w = modelist[i].width;
mode.h = modelist[i].height;
SDL_AddDisplayMode(0, &mode);
}
use_xme = xme_major * 100 + xme_minor;
saved_res = modelist[ractive]; /* save the current resolution */
}
if (modelist) {
XFree(modelist);
}
#endif /* SDL_VIDEO_DRIVER_X11_XME */
#ifdef X11MODES_DEBUG
if (use_xinerama) {
printf("Xinerama is enabled\n");
}
if (use_xrandr) {
printf("XRandR is enabled\n");
}
if (use_vidmode) {
printf("VidMode is enabled\n");
}
if (use_xme) {
printf("Xi Graphics XME fullscreen is enabled\n");
}
#endif /* X11MODES_DEBUG */
return 0;
}
void
X11_FreeVideoModes(_THIS)
{
#if SDL_VIDEO_DRIVER_X11_XRANDR
/* Free the Xrandr screen configuration */
if (screen_config) {
XRRFreeScreenConfigInfo(screen_config);
screen_config = NULL;
}
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
}
int
X11_ResizeFullScreen(_THIS)
{
int x = 0, y = 0;
int real_w, real_h;
int screen_w;
int screen_h;
screen_w = DisplayWidth(SDL_Display, SDL_Screen);
screen_h = DisplayHeight(SDL_Display, SDL_Screen);
#if SDL_VIDEO_DRIVER_X11_XINERAMA
if (use_xinerama &&
window_w <= xinerama[this->current_display].width &&
window_h <= xinerama[this->current_display].height) {
x = xinerama[this->current_display].x_org;
y = xinerama[this->current_display].y_org;
}
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
if (currently_fullscreen) {
/* Switch resolution and cover it with the FSwindow */
move_cursor_to(this, x, y);
set_best_resolution(this, window_w, window_h);
move_cursor_to(this, x, y);
get_real_resolution(this, &real_w, &real_h);
if (window_w > real_w) {
real_w = MAX(real_w, screen_w);
}
if (window_h > real_h) {
real_h = MAX(real_h, screen_h);
}
XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h);
move_cursor_to(this, real_w / 2, real_h / 2);
/* Center and reparent the drawing window */
x = (real_w - window_w) / 2;
y = (real_h - window_h) / 2;
XReparentWindow(SDL_Display, SDL_Window, FSwindow, x, y);
/* FIXME: move the mouse to the old relative location */
XSync(SDL_Display, True); /* Flush spurious mode change events */
}
return (1);
}
void
X11_QueueEnterFullScreen(_THIS)
{
switch_waiting = 0x01 | SDL_FULLSCREEN;
switch_time = SDL_GetTicks() + 1500;
#if 0 /* This causes a BadMatch error if the window is iconified (not needed) */
XSetInputFocus(SDL_Display, WMwindow, RevertToNone, CurrentTime);
#endif
}
int
X11_EnterFullScreen(_THIS)
{
int okay;
#if 0
Window tmpwin, *windows;
int i, nwindows;
#endif
int x = 0, y = 0;
int real_w, real_h;
int screen_w;
int screen_h;
okay = 1;
if (currently_fullscreen) {
return (okay);
}
/* Ungrab the input so that we can move the mouse around */
X11_GrabInputNoLock(this, SDL_GRAB_OFF);
#if SDL_VIDEO_DRIVER_X11_XINERAMA
if (use_xinerama &&
window_w <= xinerama[this->current_display].width &&
window_h <= xinerama[this->current_display].height) {
x = xinerama[this->current_display].x_org;
y = xinerama[this->current_display].y_org;
}
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
/* Map the fullscreen window to blank the screen */
screen_w = DisplayWidth(SDL_Display, SDL_Screen);
screen_h = DisplayHeight(SDL_Display, SDL_Screen);
get_real_resolution(this, &real_w, &real_h);
if (window_w > real_w) {
real_w = MAX(real_w, screen_w);
}
if (window_h > real_h) {
real_h = MAX(real_h, screen_h);
}
XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h);
XMapRaised(SDL_Display, FSwindow);
X11_WaitMapped(this, FSwindow);
#if 0 /* This seems to break WindowMaker in focus-follows-mouse mode */
/* Make sure we got to the top of the window stack */
if (XQueryTree(SDL_Display, SDL_Root, &tmpwin, &tmpwin,
&windows, &nwindows) && windows) {
/* If not, try to put us there - if fail... oh well */
if (windows[nwindows - 1] != FSwindow) {
tmpwin = windows[nwindows - 1];
for (i = 0; i < nwindows; ++i) {
if (windows[i] == FSwindow) {
SDL_memcpy(&windows[i], &windows[i + 1],
(nwindows - i - 1) * sizeof(windows[i]));
break;
}
}
windows[nwindows - 1] = FSwindow;
XRestackWindows(SDL_Display, windows, nwindows);
XSync(SDL_Display, False);
}
XFree(windows);
}
#else
XRaiseWindow(SDL_Display, FSwindow);
#endif
#if SDL_VIDEO_DRIVER_X11_VIDMODE
/* Save the current video mode */
if (use_vidmode) {
SDL_NAME(XF86VidModeLockModeSwitch) (SDL_Display, SDL_Screen, True);
}
#endif
currently_fullscreen = 1;
/* Set the new resolution */
okay = X11_ResizeFullScreen(this);
if (!okay) {
X11_LeaveFullScreen(this);
}
/* Set the colormap */
if (SDL_XColorMap) {
XInstallColormap(SDL_Display, SDL_XColorMap);
}
if (okay) {
X11_GrabInputNoLock(this,
SDL_CurrentWindow.
input_grab | SDL_GRAB_FULLSCREEN);
}
/* We may need to refresh the screen at this point (no backing store)
We also don't get an event, which is why we explicitly refresh. */
if (SDL_VideoSurface) {
if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) {
SDL_PrivateExpose();
} else {
X11_RefreshDisplay(this);
}
}
return (okay);
}
int
X11_LeaveFullScreen(_THIS)
{
if (currently_fullscreen) {
XReparentWindow(SDL_Display, SDL_Window, WMwindow, 0, 0);
#if SDL_VIDEO_DRIVER_X11_VIDMODE
if (use_vidmode) {
restore_mode(this);
SDL_NAME(XF86VidModeLockModeSwitch) (SDL_Display, SDL_Screen,
False);
}
#endif
#if SDL_VIDEO_DRIVER_X11_XME
if (use_xme) {
int rw, rh;
/* check current mode so we can avoid uneccessary mode changes */
get_real_resolution(this, &rw, &rh);
if (rw != saved_res.width || rh != saved_res.height) {
XiGMiscChangeResolution(SDL_Display, SDL_Screen, 0, /* view */
saved_res.width, saved_res.height, 0);
XSync(SDL_Display, False);
}
}
#endif
#if SDL_VIDEO_DRIVER_X11_XRANDR
if (use_xrandr) {
XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
saved_size_id, saved_rotation, CurrentTime);
}
#endif
XUnmapWindow(SDL_Display, FSwindow);
X11_WaitUnmapped(this, FSwindow);
XSync(SDL_Display, True); /* Flush spurious mode change events */
currently_fullscreen = 0;
}
/* If we get popped out of fullscreen mode for some reason, input_grab
will still have the SDL_GRAB_FULLSCREEN flag set, since this is only
temporary. In this case, release the grab unless the input has been
explicitly grabbed.
*/
X11_GrabInputNoLock(this,
SDL_CurrentWindow.input_grab & ~SDL_GRAB_FULLSCREEN);
/* We may need to refresh the screen at this point (no backing store)
We also don't get an event, which is why we explicitly refresh. */
if (SDL_VideoSurface) {
if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) {
SDL_PrivateExpose();
} else {
X11_RefreshDisplay(this);
}
}
return (0);
}
Uint32
X11_VisualToFormat(const Visual * visual, int depth, int bpp)
{
Uint32 Rmask = visual->red_mask;
Uint32 Gmask = visual->green_mask;
Uint32 Bmask = visual->blue_mask;
Uint32 Amask;
if (depth == 32) {
Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
} else {
Amask = 0;
}
return (SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask));
}
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,44 +0,0 @@
/*
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"
/* Utilities for getting and setting the X display mode */
#include "SDL_x11video.h"
/* Define this if you want to grab the keyboard in fullscreen mode.
If you do not define this, SDL will return from SDL_SetVideoMode()
immediately, but will not actually go fullscreen until the window
manager is idle.
*/
#define GRAB_FULLSCREEN
extern int X11_GetVisuals(_THIS);
extern int X11_GetVideoModes(_THIS);
extern int X11_ResizeFullScreen(_THIS);
extern void X11_WaitMapped(_THIS, Window win);
extern void X11_WaitUnmapped(_THIS, Window win);
extern void X11_QueueEnterFullScreen(_THIS);
extern int X11_EnterFullScreen(_THIS);
extern int X11_LeaveFullScreen(_THIS);
extern Uint32 X11_VisualToFormat(const Visual * visual, int depth, int bpp);
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,297 +0,0 @@
/*
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"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "SDL_mouse.h"
#include "../../events/SDL_events_c.h"
#include "../SDL_cursor_c.h"
#include "SDL_x11dga_c.h"
#include "SDL_x11mouse_c.h"
/* The implementation dependent data for the window manager cursor */
struct WMcursor
{
Cursor x_cursor;
};
void
X11_FreeWMCursor(_THIS, WMcursor * cursor)
{
if (SDL_Display != NULL) {
SDL_Lock_EventThread();
XFreeCursor(SDL_Display, cursor->x_cursor);
XSync(SDL_Display, False);
SDL_Unlock_EventThread();
}
SDL_free(cursor);
}
WMcursor *
X11_CreateWMCursor(_THIS,
Uint8 * data, Uint8 * mask, int w, int h, int hot_x,
int hot_y)
{
WMcursor *cursor;
XGCValues GCvalues;
GC GCcursor;
XImage *data_image, *mask_image;
Pixmap data_pixmap, mask_pixmap;
int clen, i;
char *x_data, *x_mask;
static XColor black = { 0, 0, 0, 0 };
static XColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
/* Allocate the cursor memory */
cursor = (WMcursor *) SDL_malloc(sizeof(WMcursor));
if (cursor == NULL) {
SDL_OutOfMemory();
return (NULL);
}
/* Mix the mask and the data */
clen = (w / 8) * h;
x_data = (char *) SDL_malloc(clen);
if (x_data == NULL) {
SDL_free(cursor);
SDL_OutOfMemory();
return (NULL);
}
x_mask = (char *) SDL_malloc(clen);
if (x_mask == NULL) {
SDL_free(cursor);
SDL_free(x_data);
SDL_OutOfMemory();
return (NULL);
}
for (i = 0; i < clen; ++i) {
/* The mask is OR'd with the data to turn inverted color
pixels black since inverted color cursors aren't supported
under X11.
*/
x_mask[i] = data[i] | mask[i];
x_data[i] = data[i];
}
/* Prevent the event thread from running while we use the X server */
SDL_Lock_EventThread();
/* Create the data image */
data_image = XCreateImage(SDL_Display,
DefaultVisual(SDL_Display, SDL_Screen),
1, XYBitmap, 0, x_data, w, h, 8, w / 8);
data_image->byte_order = MSBFirst;
data_image->bitmap_bit_order = MSBFirst;
data_pixmap = XCreatePixmap(SDL_Display, SDL_Root, w, h, 1);
/* Create the data mask */
mask_image = XCreateImage(SDL_Display,
DefaultVisual(SDL_Display, SDL_Screen),
1, XYBitmap, 0, x_mask, w, h, 8, w / 8);
mask_image->byte_order = MSBFirst;
mask_image->bitmap_bit_order = MSBFirst;
mask_pixmap = XCreatePixmap(SDL_Display, SDL_Root, w, h, 1);
/* Create the graphics context */
GCvalues.function = GXcopy;
GCvalues.foreground = ~0;
GCvalues.background = 0;
GCvalues.plane_mask = AllPlanes;
GCcursor = XCreateGC(SDL_Display, data_pixmap,
(GCFunction | GCForeground | GCBackground |
GCPlaneMask), &GCvalues);
/* Blit the images to the pixmaps */
XPutImage(SDL_Display, data_pixmap, GCcursor, data_image,
0, 0, 0, 0, w, h);
XPutImage(SDL_Display, mask_pixmap, GCcursor, mask_image,
0, 0, 0, 0, w, h);
XFreeGC(SDL_Display, GCcursor);
/* These free the x_data and x_mask memory pointers */
XDestroyImage(data_image);
XDestroyImage(mask_image);
/* Create the cursor */
cursor->x_cursor = XCreatePixmapCursor(SDL_Display, data_pixmap,
mask_pixmap, &black, &white,
hot_x, hot_y);
XFreePixmap(SDL_Display, data_pixmap);
XFreePixmap(SDL_Display, mask_pixmap);
/* Release the event thread */
XSync(SDL_Display, False);
SDL_Unlock_EventThread();
return (cursor);
}
int
X11_ShowWMCursor(_THIS, WMcursor * cursor)
{
/* Don't do anything if the display is gone */
if (SDL_Display == NULL) {
return (0);
}
/* Set the X11 cursor cursor, or blank if cursor is NULL */
if (SDL_Window) {
SDL_Lock_EventThread();
if (cursor == NULL) {
if (SDL_BlankCursor != NULL) {
XDefineCursor(SDL_Display, SDL_Window,
SDL_BlankCursor->x_cursor);
}
} else {
XDefineCursor(SDL_Display, SDL_Window, cursor->x_cursor);
}
XSync(SDL_Display, False);
SDL_Unlock_EventThread();
}
return (1);
}
void
X11_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
{
if (using_dga & DGA_MOUSE) {
SDL_PrivateMouseMotion(0, 0, x, y);
} else if (mouse_relative) {
/* RJR: March 28, 2000
leave physical cursor at center of screen if
mouse hidden and grabbed */
SDL_PrivateMouseMotion(0, 0, x, y);
} else {
SDL_Lock_EventThread();
XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, x, y);
XSync(SDL_Display, False);
SDL_Unlock_EventThread();
}
}
/* Sets the mouse acceleration from a string of the form:
2/1/0
The first number is the numerator, followed by the acceleration
denumenator and threshold.
*/
static void
SetMouseAccel(_THIS, const char *accel_param)
{
int i;
size_t len;
int accel_value[3];
char *mouse_param, *mouse_param_buf, *pin;
len = SDL_strlen(accel_param) + 1;
mouse_param_buf = SDL_stack_alloc(char, len);
if (!mouse_param_buf) {
return;
}
SDL_strlcpy(mouse_param_buf, accel_param, len);
mouse_param = mouse_param_buf;
for (i = 0; (i < 3) && mouse_param; ++i) {
pin = SDL_strchr(mouse_param, '/');
if (pin) {
*pin = '\0';
}
accel_value[i] = atoi(mouse_param);
if (pin) {
mouse_param = pin + 1;
} else {
mouse_param = NULL;
}
}
if (mouse_param_buf) {
XChangePointerControl(SDL_Display, True, True,
accel_value[0], accel_value[1], accel_value[2]);
SDL_free(mouse_param_buf);
}
}
/* Check to see if we need to enter or leave mouse relative mode */
void
X11_CheckMouseModeNoLock(_THIS)
{
const Uint8 full_focus =
(SDL_APPACTIVE | SDL_APPINPUTFOCUS | SDL_APPMOUSEFOCUS);
char *env_override;
int enable_relative = 1;
/* Allow the user to override the relative mouse mode.
They almost never want to do this, as it seriously affects
applications that rely on continuous relative mouse motion.
*/
env_override = SDL_getenv("SDL_MOUSE_RELATIVE");
if (env_override) {
enable_relative = atoi(env_override);
}
/* If the mouse is hidden and input is grabbed, we use relative mode */
if (enable_relative &&
!(SDL_cursorstate & CURSOR_VISIBLE) &&
(SDL_CurrentWindow.input_grab != SDL_GRAB_OFF) &&
(SDL_GetAppState() & full_focus) == full_focus) {
if (!mouse_relative) {
X11_EnableDGAMouse(this);
if (!(using_dga & DGA_MOUSE)) {
char *xmouse_accel;
SDL_GetMouseState(&mouse_last.x, &mouse_last.y);
/* Use as raw mouse mickeys as possible */
XGetPointerControl(SDL_Display,
&mouse_accel.numerator,
&mouse_accel.denominator,
&mouse_accel.threshold);
xmouse_accel = SDL_getenv("SDL_VIDEO_X11_MOUSEACCEL");
if (xmouse_accel) {
SetMouseAccel(this, xmouse_accel);
}
}
mouse_relative = 1;
}
} else {
if (mouse_relative) {
if (using_dga & DGA_MOUSE) {
X11_DisableDGAMouse(this);
} else {
XChangePointerControl(SDL_Display, True, True,
mouse_accel.numerator,
mouse_accel.denominator,
mouse_accel.threshold);
}
mouse_relative = 0;
}
}
}
void
X11_CheckMouseMode(_THIS)
{
SDL_Lock_EventThread();
X11_CheckMouseModeNoLock(this);
SDL_Unlock_EventThread();
}
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,35 +0,0 @@
/*
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"
#include "SDL_x11video.h"
/* Functions to be exported */
extern void X11_FreeWMCursor(_THIS, WMcursor * cursor);
extern WMcursor *X11_CreateWMCursor(_THIS,
Uint8 * data, Uint8 * mask, int w, int h,
int hot_x, int hot_y);
extern int X11_ShowWMCursor(_THIS, WMcursor * cursor);
extern void X11_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
extern void X11_CheckMouseModeNoLock(_THIS);
extern void X11_CheckMouseMode(_THIS);
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,518 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
SDL_X11_MODULE(BASEXLIB)
SDL_X11_SYM(XClassHint *, XAllocClassHint, (void), (), return)
SDL_X11_SYM(Status, XAllocColor, (Display * a, Colormap b, XColor * c),
(a, b, c), return) SDL_X11_SYM(XSizeHints *, XAllocSizeHints,
(void), (),
return) SDL_X11_SYM(XWMHints *,
XAllocWMHints,
(void), (),
return)
SDL_X11_SYM(int, XChangePointerControl,
(Display * a, Bool b, Bool c, int d, int e, int f), (a, b, c, d,
e, f),
return) SDL_X11_SYM(int, XChangeProperty, (Display * a,
Window b, Atom c,
Atom d, int e, int f,
_Xconst unsigned char
*g, int h), (a, b, c,
d, e, f,
g, h),
return) SDL_X11_SYM(int,
XChangeWindowAttributes,
(Display * a, Window b,
unsigned long c,
XSetWindowAttributes *
d), (a, b, c, d), return)
SDL_X11_SYM(Bool, XCheckTypedEvent, (Display * a, int b, XEvent * c),
(a, b, c), return) SDL_X11_SYM(int, XClearWindow, (Display * a,
Window b),
(a, b), return) SDL_X11_SYM(int,
XCloseDisplay,
(Display
*
a),
(a),
return)
SDL_X11_SYM(Colormap, XCreateColormap,
(Display * a, Window b, Visual * c, int d), (a, b, c, d),
return) SDL_X11_SYM(Cursor, XCreatePixmapCursor, (Display * a,
Pixmap b,
Pixmap c,
XColor * d,
XColor * e,
unsigned int
f,
unsigned int
g), (a, b, c,
d, e, f,
g),
return) SDL_X11_SYM(GC, XCreateGC,
(Display * a,
Drawable b,
unsigned long c,
XGCValues * d), (a, b,
c,
d),
return)
SDL_X11_SYM(XImage *, XCreateImage,
(Display * a, Visual * b, unsigned int c, int d, int e, char *f,
unsigned int g, unsigned int h, int i, int j), (a, b, c, d, e,
f, g, h, i, j),
return) SDL_X11_SYM(Pixmap, XCreatePixmap, (Display * a,
Drawable b,
unsigned int c,
unsigned int d,
unsigned int e), (a,
b,
c,
d,
e),
return) SDL_X11_SYM(Pixmap,
XCreatePixmapFromBitmapData,
(Display * a,
Drawable b, char *c,
unsigned int d,
unsigned int e,
unsigned long f, unsigned long g, unsigned int h), (a, b, c, d, e, f, g, h), return)
SDL_X11_SYM(Window, XCreateSimpleWindow,
(Display * a, Window b, int c, int d, unsigned int e,
unsigned int f, unsigned int g, unsigned long h,
unsigned long i), (a, b, c, d, e, f, g, h, i),
return) SDL_X11_SYM(Window, XCreateWindow, (Display * a,
Window b, int c,
int d,
unsigned int e,
unsigned int f,
unsigned int g,
int h,
unsigned int i,
Visual * j,
unsigned long k,
XSetWindowAttributes
* l), (a, b, c, d,
e, f, g, h,
i, j, k, l),
return) SDL_X11_SYM(int, XDefineCursor, (Display * a, Window b, Cursor c), (a, b, c), return)
SDL_X11_SYM(int, XDeleteProperty, (Display * a, Window b, Atom c), (a, b, c),
return) SDL_X11_SYM(int, XDestroyWindow, (Display * a,
Window b), (a, b),
return) SDL_X11_SYM(char *, XDisplayName,
(_Xconst char *a), (a),
return)
SDL_X11_SYM(int, XEventsQueued, (Display * a, int b), (a, b),
return) SDL_X11_SYM(Bool, XFilterEvent, (XEvent * event,
Window w), (event, w),
return) SDL_X11_SYM(int, XFlush,
(Display * a), (a),
return)
SDL_X11_SYM(int, XFree, (void *a), (a), return) SDL_X11_SYM(int,
XFreeColormap,
(Display *
a,
Colormap
b), (a, b),
return)
SDL_X11_SYM(int, XFreeColors,
(Display * a, Colormap b, unsigned long *c, int d, unsigned long e),
(a, b, c, d, e), return) SDL_X11_SYM(int, XFreeCursor,
(Display * a, Cursor b),
(a, b), return)
SDL_X11_SYM(int, XFreeGC, (Display * a, GC b), (a, b),
return) SDL_X11_SYM(int, XFreeModifiermap,
(XModifierKeymap * a), (a),
return) SDL_X11_SYM(int, XFreePixmap,
(Display * a,
Pixmap b), (a, b),
return)
SDL_X11_SYM(int, XGetErrorDatabaseText,
(Display * a, _Xconst char *b, _Xconst char *c, _Xconst char *d,
char *e, int f), (a, b, c, d, e, f),
return) SDL_X11_SYM(XModifierKeymap *, XGetModifierMapping, (Display * a), (a), return) SDL_X11_SYM(int, XGetPointerControl,
(Display * a, int *b, int *c,
int *d), (a, b, c, d), return)
SDL_X11_SYM(int, XGetScreenSaver,
(Display * a, int *b, int *c, int *d, int *e), (a, b, c, d, e),
return) SDL_X11_SYM(XVisualInfo *, XGetVisualInfo, (Display * a,
long b,
XVisualInfo
* c,
int *d), (a,
b,
c,
d),
return) SDL_X11_SYM(XWMHints *,
XGetWMHints,
(Display * a,
Window b), (a, b),
return)
SDL_X11_SYM(Status, XGetWindowAttributes,
(Display * a, Window b, XWindowAttributes * c), (a, b, c),
return) SDL_X11_SYM(int, XGrabKeyboard, (Display * a, Window b,
Bool c, int d, int e,
Time f), (a, b, c, d,
e, f),
return) SDL_X11_SYM(int, XGrabPointer,
(Display * a, Window b,
Bool c,
unsigned int d, int e,
int f, Window g,
Cursor h, Time i), (a,
b,
c,
d,
e,
f,
g,
h,
i),
return)
SDL_X11_SYM(Status, XIconifyWindow, (Display * a, Window b, int c),
(a, b, c), return) SDL_X11_SYM(int, XInstallColormap,
(Display * a, Colormap b), (a,
b),
return) SDL_X11_SYM(KeyCode,
XKeysymToKeycode,
(Display *
a,
KeySym b),
(a, b), return)
SDL_X11_SYM(Atom, XInternAtom, (Display * a, _Xconst char *b, Bool c),
(a, b, c), return) SDL_X11_SYM(XPixmapFormatValues *,
XListPixmapFormats, (Display * a,
int *b), (a,
b),
return) SDL_X11_SYM(int,
XLookupString,
(XKeyEvent *
a, char *b,
int c,
KeySym * d,
XComposeStatus
* e), (a,
b,
c,
d,
e),
return)
SDL_X11_SYM(int, XMapRaised, (Display * a, Window b), (a, b),
return) SDL_X11_SYM(int, XMapWindow, (Display * a, Window b),
(a, b), return) SDL_X11_SYM(int,
XMaskEvent,
(Display * a,
long b,
XEvent * c),
(a, b, c), return)
SDL_X11_SYM(Status, XMatchVisualInfo,
(Display * a, int b, int c, int d, XVisualInfo * e), (a, b, c, d, e),
return) SDL_X11_SYM(int, XMissingExtension, (Display * a,
_Xconst char *b),
(a, b), return) SDL_X11_SYM(int,
XMoveResizeWindow,
(Display * a,
Window b,
int c, int d,
unsigned int
e,
unsigned int
f), (a, b, c,
d, e, f),
return)
SDL_X11_SYM(int, XMoveWindow, (Display * a, Window b, int c, int d),
(a, b, c, d), return) SDL_X11_SYM(int, XNextEvent, (Display * a,
XEvent * b),
(a, b),
return) SDL_X11_SYM(Display
*,
XOpenDisplay,
(_Xconst
char
*a),
(a), return)
SDL_X11_SYM(int, XPeekEvent, (Display * a, XEvent * b), (a, b),
return) SDL_X11_SYM(int, XPending, (Display * a), (a),
return) SDL_X11_SYM(int, XPutImage,
(Display * a,
Drawable b, GC c,
XImage * d, int e,
int f, int g, int h,
unsigned int i,
unsigned int j), (a,
b,
c,
d,
e,
f,
g,
h,
i,
j),
return)
SDL_X11_SYM(int, XQueryColors, (Display * a, Colormap b, XColor * c, int d),
(a, b, c, d), return) SDL_X11_SYM(int, XQueryKeymap,
(Display * a, char *b), (a,
b),
return) SDL_X11_SYM(Bool,
XQueryPointer,
(Display
* a,
Window
b,
Window *
c,
Window *
d,
int *e,
int *f,
int *g,
int *h,
unsigned
int *i),
(a, b, c,
d, e, f,
g, h,
i), return)
SDL_X11_SYM(int, XRaiseWindow, (Display * a, Window b), (a, b),
return) SDL_X11_SYM(int, XReparentWindow, (Display * a,
Window b, Window c,
int d, int e), (a, b,
c, d,
e),
return) SDL_X11_SYM(int, XResizeWindow,
(Display * a, Window b,
unsigned int c,
unsigned int d), (a,
b,
c,
d),
return)
SDL_X11_SYM(int, XSelectInput, (Display * a, Window b, long c), (a, b, c),
return) SDL_X11_SYM(Status, XSendEvent, (Display * a, Window b,
Bool c, long d,
XEvent * e), (a, b, c,
d, e),
return) SDL_X11_SYM(int, XSetClassHint,
(Display * a, Window b,
XClassHint * c), (a,
b,
c),
return)
SDL_X11_SYM(XErrorHandler, XSetErrorHandler, (XErrorHandler a), (a),
return) SDL_X11_SYM(XIOErrorHandler, XSetIOErrorHandler,
(XIOErrorHandler a), (a),
return) SDL_X11_SYM(int, XSetScreenSaver,
(Display * a, int b,
int c, int d, int e),
(a, b, c, d, e), return)
SDL_X11_SYM(int, XSetTransientForHint, (Display * a, Window b, Window c),
(a, b, c), return) SDL_X11_SYM(int, XSetWMHints, (Display * a,
Window b,
XWMHints * c),
(a, b, c),
return) SDL_X11_SYM(void,
XSetTextProperty,
(Display *
a,
Window b,
XTextProperty
* c,
Atom d),
(a, b, c, d),)
SDL_X11_SYM(void, XSetWMNormalHints, (Display * a, Window b, XSizeHints * c),
(a, b, c),)
SDL_X11_SYM(Status, XSetWMProtocols,
(Display * a, Window b, Atom * c, int d), (a, b, c, d), return)
SDL_X11_SYM(int, XSetWindowBackground,
(Display * a, Window b, unsigned long c), (a, b, c), return)
SDL_X11_SYM(int, XSetWindowBackgroundPixmap,
(Display * a, Window b, Pixmap c), (a, b, c), return)
SDL_X11_SYM(int, XSetWindowColormap, (Display * a, Window b, Colormap c),
(a, b, c), return)
SDL_X11_SYM(int, XStoreColors, (Display * a, Colormap b, XColor * c, int d),
(a, b, c, d), return)
SDL_X11_SYM(Status, XStringListToTextProperty,
(char **a, int b, XTextProperty * c), (a, b, c), return)
SDL_X11_SYM(int, XSync, (Display * a, Bool b), (a, b), return)
SDL_X11_SYM(int, XUngrabKeyboard, (Display * a, Time b), (a, b), return)
SDL_X11_SYM(int, XUngrabPointer, (Display * a, Time b), (a, b), return)
SDL_X11_SYM(int, XUnmapWindow, (Display * a, Window b), (a, b), return)
SDL_X11_SYM(int, XWarpPointer,
(Display * a, Window b, Window c, int d, int e, unsigned int f,
unsigned int g, int h, int i), (a, b, c, d, e, f, g, h, i),
return)
SDL_X11_SYM(VisualID, XVisualIDFromVisual, (Visual * a), (a), return)
SDL_X11_SYM(XExtDisplayInfo *, XextAddDisplay,
(XExtensionInfo * a, Display * b, char *c, XExtensionHooks * d,
int e, XPointer f), (a, b, c, d, e, f), return)
SDL_X11_SYM(XExtensionInfo *, XextCreateExtension, (void), (), return)
SDL_X11_SYM(void, XextDestroyExtension, (XExtensionInfo * a), (a),)
SDL_X11_SYM(XExtDisplayInfo *, XextFindDisplay,
(XExtensionInfo * a, Display * b), (a, b), return)
SDL_X11_SYM(int, XextRemoveDisplay, (XExtensionInfo * a, Display * b),
(a, b), return)
SDL_X11_SYM(Bool, XQueryExtension,
(Display * a, _Xconst char *b, int *c, int *d, int *e), (a, b, c,
d, e),
return)
SDL_X11_SYM(char *, XDisplayString, (Display * a), (a), return)
SDL_X11_SYM(int, XGetErrorText, (Display * a, int b, char *c, int d),
(a, b, c, d), return)
SDL_X11_SYM(void, _XEatData, (Display * a, unsigned long b), (a, b),)
SDL_X11_SYM(void, _XFlush, (Display * a), (a),)
SDL_X11_SYM(void, _XFlushGCCache, (Display * a, GC b), (a, b),)
SDL_X11_SYM(int, _XRead, (Display * a, char *b, long c), (a, b, c), return)
SDL_X11_SYM(void, _XReadPad, (Display * a, char *b, long c), (a, b, c),)
SDL_X11_SYM(void, _XSend, (Display * a, _Xconst char *b, long c), (a, b, c),)
SDL_X11_SYM(Status, _XReply, (Display * a, xReply * b, int c, Bool d),
(a, b, c, d), return)
SDL_X11_SYM(unsigned long, _XSetLastRequestRead,
(Display * a, xGenericReply * b), (a, b), return)
SDL_X11_SYM(SDL_X11_XSynchronizeRetType, XSynchronize, (Display * a, Bool b),
(a, b), return)
SDL_X11_SYM(SDL_X11_XESetWireToEventRetType, XESetWireToEvent,
(Display * a, int b, SDL_X11_XESetWireToEventRetType c), (a, b,
c),
return)
SDL_X11_SYM(SDL_X11_XESetEventToWireRetType, XESetEventToWire,
(Display * a, int b, SDL_X11_XESetEventToWireRetType c), (a, b,
c),
return)
SDL_X11_SYM(XExtensionErrorHandler, XSetExtensionErrorHandler,
(XExtensionErrorHandler a), (a), return)
#if NeedWidePrototypes
SDL_X11_SYM(KeySym, XKeycodeToKeysym, (Display * a, unsigned int b, int c),
(a, b, c), return)
#else
SDL_X11_SYM(KeySym, XKeycodeToKeysym, (Display * a, KeyCode b, int c),
(a, b, c), return)
#endif
#ifdef X_HAVE_UTF8_STRING
SDL_X11_MODULE(UTF8)
SDL_X11_SYM(int, Xutf8TextListToTextProperty,
(Display * a, char **b, int c, XICCEncodingStyle d,
XTextProperty * e), (a, b, c, d, e), return)
SDL_X11_SYM(int, Xutf8LookupString,
(XIC a, XKeyPressedEvent * b, char *c, int d, KeySym * e,
Status * f), (a, b, c, d, e, f), return)
/*SDL_X11_SYM(XIC,XCreateIC,(XIM, ...),return) !!! ARGH! */
SDL_X11_SYM(void, XDestroyIC, (XIC a), (a),)
SDL_X11_SYM(void, XSetICFocus, (XIC a), (a),)
SDL_X11_SYM(void, XUnsetICFocus, (XIC a), (a),)
SDL_X11_SYM(XIM, XOpenIM,
(Display * a, struct _XrmHashBucketRec * b, char *c, char *d),
(a, b, c, d), return)
SDL_X11_SYM(Status, XCloseIM, (XIM a), (a), return)
#endif
#ifndef NO_SHARED_MEMORY
SDL_X11_MODULE(SHM)
SDL_X11_SYM(Status, XShmAttach, (Display * a, XShmSegmentInfo * b), (a, b),
return)
SDL_X11_SYM(Status, XShmDetach, (Display * a, XShmSegmentInfo * b), (a, b),
return)
SDL_X11_SYM(Status, XShmPutImage,
(Display * a, Drawable b, GC c, XImage * d, int e, int f, int g,
int h, unsigned int i, unsigned int j, Bool k), (a, b, c, d, e,
f, g, h, i, j,
k), return)
SDL_X11_SYM(XImage *, XShmCreateImage,
(Display * a, Visual * b, unsigned int c, int d, char *e,
XShmSegmentInfo * f, unsigned int g, unsigned int h), (a, b, c,
d, e, f,
g, h),
return)
SDL_X11_SYM(Bool, XShmQueryExtension, (Display * a), (a), return)
#endif
/*
* Not required...these only exist in code in headers on some 64-bit platforms,
* and are removed via macros elsewhere, so it's safe for them to be missing.
*/
#ifdef LONG64
SDL_X11_MODULE(IO_32BIT)
SDL_X11_SYM(int, _XData32,
(Display * dpy, register long *data, unsigned len), (dpy, data,
len), return)
SDL_X11_SYM(void, _XRead32, (Display * dpy, register long *data, long len),
(dpy, data, len),)
#endif
/*
* These only show up on some variants of Unix.
*/
#if defined(__osf__)
SDL_X11_MODULE(OSF_ENTRY_POINTS)
SDL_X11_SYM(void, _SmtBufferOverflow,
(Display * dpy, register smtDisplayPtr p), (dpy, p),)
SDL_X11_SYM(void, _SmtIpError,
(Display * dpy, register smtDisplayPtr p, int i), (dpy, p, i),)
SDL_X11_SYM(int, ipAllocateData, (ChannelPtr a, IPCard b, IPDataPtr * c),
(a, b, c), return)
SDL_X11_SYM(int, ipUnallocateAndSendData, (ChannelPtr a, IPCard b), (a, b),
return)
#endif
/* Xrandr support. */
#if SDL_VIDEO_DRIVER_X11_XRANDR
SDL_X11_MODULE(XRANDR)
SDL_X11_SYM(Status, XRRQueryVersion,
(Display * dpy, int *major_versionp, int *minor_versionp), (dpy,
major_versionp,
minor_versionp),
return)
SDL_X11_SYM(XRRScreenConfiguration *, XRRGetScreenInfo,
(Display * dpy, Drawable draw), (dpy, draw), return)
SDL_X11_SYM(SizeID, XRRConfigCurrentConfiguration,
(XRRScreenConfiguration * config, Rotation * rotation), (config,
rotation),
return)
SDL_X11_SYM(XRRScreenSize *, XRRConfigSizes,
(XRRScreenConfiguration * config, int *nsizes), (config, nsizes),
return)
SDL_X11_SYM(short *, XRRConfigRates,
(XRRScreenConfiguration * config, int sizeID, int *nrates),
(config, sizeID, nrates), return)
SDL_X11_SYM(Status, XRRSetScreenConfig,
(Display * dpy, XRRScreenConfiguration * config, Drawable draw,
int size_index, Rotation rotation, Time timestamp), (dpy,
config,
draw,
size_index,
rotation,
timestamp),
return)
SDL_X11_SYM(void, XRRFreeScreenConfigInfo, (XRRScreenConfiguration * config),
(config),)
#endif
/* DPMS support */
#if SDL_VIDEO_DRIVER_X11_DPMS
SDL_X11_MODULE(DPMS)
SDL_X11_SYM(Status, DPMSQueryExtension,
(Display * dpy, int *major_versionp, int *minor_versionp), (dpy,
major_versionp,
minor_versionp),
return)
SDL_X11_SYM(Status, DPMSInfo, (Display * dpy, CARD16 * state, BOOL * onoff),
(dpy, state, onoff), return)
SDL_X11_SYM(Status, DPMSEnable, (Display * dpy), (dpy), return)
SDL_X11_SYM(Status, DPMSDisable, (Display * dpy), (dpy), return)
#endif
/* end of SDL_x11sym.h ... */
/* vi: set ts=4 sw=4 expandtab: */

File diff suppressed because it is too large Load diff

View file

@ -1,221 +0,0 @@
/*
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"
#ifndef _SDL_x11video_h
#define _SDL_x11video_h
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
#if SDL_VIDEO_DRIVER_X11_DGAMOUSE
#include "../Xext/extensions/xf86dga.h"
#endif
#if SDL_VIDEO_DRIVER_X11_XINERAMA
#include "../Xext/extensions/Xinerama.h"
#endif
#if SDL_VIDEO_DRIVER_X11_XRANDR
#include <X11/extensions/Xrandr.h>
#endif
#if SDL_VIDEO_DRIVER_X11_VIDMODE
#include "../Xext/extensions/xf86vmode.h"
#endif
#if SDL_VIDEO_DRIVER_X11_XME
#include "../Xext/extensions/xme.h"
#endif
#if SDL_VIDEO_DRIVER_X11_DPMS
#include <X11/extensions/dpms.h>
#endif
#include "SDL_x11dyn.h"
/* Hidden "this" pointer for the video functions */
#define _THIS SDL_VideoDevice *this
/* Private display data */
struct SDL_PrivateVideoData
{
int local_X11; /* Flag: true if local display */
Display *X11_Display; /* Used for events and window management */
Display *GFX_Display; /* Used for graphics and colormap stuff */
Visual *SDL_Visual; /* The visual used by our window */
Window WMwindow; /* Input window, managed by window manager */
Window FSwindow; /* Fullscreen window, completely unmanaged */
Window SDL_Window; /* Shared by both displays (no X security?) */
Atom WM_DELETE_WINDOW; /* "close-window" protocol atom */
WMcursor *BlankCursor; /* The invisible cursor */
XIM X11_IM; /* Used to communicate with the input method (IM) server */
XIC X11_IC; /* Used for retaining the state, properties, and semantics of communication with the input method (IM) server */
char *SDL_windowid; /* Flag: true if we have been passed a window */
/* Direct Graphics Access extension information */
int using_dga;
#ifndef NO_SHARED_MEMORY
/* MIT shared memory extension information */
int use_mitshm;
XShmSegmentInfo shminfo;
#endif
/* The variables used for displaying graphics */
XImage *Ximage; /* The X image for our window */
GC gc; /* The graphic context for drawing */
/* The current width and height of the fullscreen mode */
int window_w;
int window_h;
/* Support for internal mouse warping */
struct
{
int x;
int y;
} mouse_last;
struct
{
int numerator;
int denominator;
int threshold;
} mouse_accel;
int mouse_relative;
/* available visuals of interest to us, sorted deepest first */
struct
{
Visual *visual;
int depth; /* number of significant bits/pixel */
int bpp; /* pixel quantum in bits */
} visuals[2 * 5]; /* at most 2 entries for 8, 15, 16, 24, 32 */
int nvisuals;
Visual *vis; /* current visual in use */
int depth; /* current visual depth (not bpp) */
/* Variables used by the X11 video mode code */
#if SDL_VIDEO_DRIVER_X11_XINERAMA
SDL_NAME(XineramaScreenInfo) * xinerama;
#endif
#if SDL_VIDEO_DRIVER_X11_XRANDR
XRRScreenConfiguration *screen_config;
int saved_size_id;
Rotation saved_rotation;
#endif
#if SDL_VIDEO_DRIVER_X11_VIDMODE
SDL_NAME(XF86VidModeModeInfo) saved_mode;
struct
{
int x, y;
} saved_view;
#endif
#if SDL_VIDEO_DRIVER_X11_XME /* XiG XME fullscreen */
XiGMiscResolutionInfo saved_res;
#endif
int use_xinerama;
int use_xrandr;
int use_vidmode;
int use_xme;
int currently_fullscreen;
/* Automatic mode switching support (entering/leaving fullscreen) */
Uint32 switch_waiting;
Uint32 switch_time;
/* Prevent too many XSync() calls */
int blit_queued;
/* Colormap handling */
Colormap DisplayColormap; /* The default display colormap */
Colormap XColorMap; /* The current window colormap */
int *XPixels; /* pixels value allocation counts */
float gamma_saved[3]; /* Saved gamma values for VidMode gamma */
int gamma_changed; /* flag: has VidMode gamma been modified? */
short *iconcolors; /* List of colors used by the icon */
/* Screensaver settings */
int screensaver_timeout;
BOOL dpms_enabled;
};
/* Old variable names */
#define local_X11 (this->hidden->local_X11)
#define SDL_Display (this->hidden->X11_Display)
#define GFX_Display (this->hidden->GFX_Display)
#define SDL_Screen DefaultScreen(this->hidden->X11_Display)
#define SDL_Visual (this->hidden->vis)
#define SDL_Root RootWindow(SDL_Display, SDL_Screen)
#define WMwindow (this->hidden->WMwindow)
#define FSwindow (this->hidden->FSwindow)
#define SDL_Window (this->hidden->SDL_Window)
#define WM_DELETE_WINDOW (this->hidden->WM_DELETE_WINDOW)
#define SDL_BlankCursor (this->hidden->BlankCursor)
#define SDL_IM (this->hidden->X11_IM)
#define SDL_IC (this->hidden->X11_IC)
#define SDL_windowid (this->hidden->SDL_windowid)
#define using_dga (this->hidden->using_dga)
#define use_mitshm (this->hidden->use_mitshm)
#define shminfo (this->hidden->shminfo)
#define SDL_Ximage (this->hidden->Ximage)
#define SDL_GC (this->hidden->gc)
#define window_w (this->hidden->window_w)
#define window_h (this->hidden->window_h)
#define mouse_last (this->hidden->mouse_last)
#define mouse_accel (this->hidden->mouse_accel)
#define mouse_relative (this->hidden->mouse_relative)
#define SDL_modelist (this->hidden->modelist)
#define xinerama (this->hidden->xinerama)
#define saved_mode (this->hidden->saved_mode)
#define saved_view (this->hidden->saved_view)
#define saved_res (this->hidden->saved_res)
#define screen_config (this->hidden->screen_config)
#define saved_size_id (this->hidden->saved_size_id)
#define saved_rotation (this->hidden->saved_rotation)
#define use_xinerama (this->hidden->use_xinerama)
#define use_vidmode (this->hidden->use_vidmode)
#define use_xrandr (this->hidden->use_xrandr)
#define use_xme (this->hidden->use_xme)
#define currently_fullscreen (this->hidden->currently_fullscreen)
#define switch_waiting (this->hidden->switch_waiting)
#define switch_time (this->hidden->switch_time)
#define blit_queued (this->hidden->blit_queued)
#define SDL_DisplayColormap (this->hidden->DisplayColormap)
#define SDL_PrivateColormap (this->hidden->PrivateColormap)
#define SDL_XColorMap (this->hidden->XColorMap)
#define SDL_XPixels (this->hidden->XPixels)
#define gamma_saved (this->hidden->gamma_saved)
#define gamma_changed (this->hidden->gamma_changed)
#define SDL_iconcolors (this->hidden->iconcolors)
#define screensaver_timeout (this->hidden->screensaver_timeout)
#define dpms_enabled (this->hidden->dpms_enabled)
/* Some versions of XFree86 have bugs - detect if this is one of them */
#define BUGGY_XFREE86(condition, buggy_version) \
((SDL_strcmp(ServerVendor(SDL_Display), "The XFree86 Project, Inc") == 0) && \
(VendorRelease(SDL_Display) condition buggy_version))
#endif /* _SDL_x11video_h */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,436 +0,0 @@
/*
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"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "SDL_version.h"
#include "SDL_timer.h"
#include "SDL_video.h"
#include "SDL_syswm.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
#include "SDL_x11modes_c.h"
#include "SDL_x11wm_c.h"
static Uint8
reverse_byte(Uint8 x)
{
x = (x & 0xaa) >> 1 | (x & 0x55) << 1;
x = (x & 0xcc) >> 2 | (x & 0x33) << 2;
x = (x & 0xf0) >> 4 | (x & 0x0f) << 4;
return x;
}
void
X11_SetIcon(_THIS, SDL_Surface * icon, Uint8 * mask)
{
SDL_Surface *sicon;
XWMHints *wmhints;
XImage *icon_image;
Pixmap icon_pixmap;
Pixmap mask_pixmap;
Window icon_window = None;
GC gc;
XGCValues GCvalues;
int i, dbpp;
SDL_Rect bounds;
Uint8 *LSBmask;
Visual *dvis;
char *p;
int masksize;
SDL_Lock_EventThread();
/* The icon must use the default visual, depth and colormap of the
screen, so it might need a conversion */
dvis = DefaultVisual(SDL_Display, SDL_Screen);
dbpp = DefaultDepth(SDL_Display, SDL_Screen);
for (i = 0; i < this->hidden->nvisuals; i++) {
if (this->hidden->visuals[i].visual == dvis) {
dbpp = this->hidden->visuals[i].bpp;
break;
}
}
/* The Visual struct is supposed to be opaque but we cheat a little */
sicon = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
dbpp,
dvis->red_mask, dvis->green_mask,
dvis->blue_mask, 0);
if (sicon == NULL)
goto done;
if (dbpp == 8) {
/* Default visual is 8bit; we need to allocate colours from
the default colormap */
SDL_Color want[256], got[256];
int nwant;
Colormap dcmap;
int missing;
dcmap = DefaultColormap(SDL_Display, SDL_Screen);
if (icon->format->palette) {
/* The icon has a palette as well - we just have to
find those colours */
nwant = icon->format->palette->ncolors;
SDL_memcpy(want, icon->format->palette->colors,
nwant * sizeof want[0]);
} else {
/* try the standard 6x6x6 cube for lack of better
ideas */
int r, g, b, i;
for (r = i = 0; r < 256; r += 0x33)
for (g = 0; g < 256; g += 0x33)
for (b = 0; b < 256; b += 0x33, i++) {
want[i].r = r;
want[i].g = g;
want[i].b = b;
}
nwant = 216;
}
if (SDL_iconcolors) {
/* free already allocated colours first */
unsigned long freelist[512];
int nfree = 0;
for (i = 0; i < 256; i++) {
while (SDL_iconcolors[i]) {
freelist[nfree++] = i;
SDL_iconcolors[i]--;
}
}
XFreeColors(GFX_Display, dcmap, freelist, nfree, 0);
}
if (!SDL_iconcolors)
SDL_iconcolors = SDL_malloc(256 * sizeof *SDL_iconcolors);
SDL_memset(SDL_iconcolors, 0, 256 * sizeof *SDL_iconcolors);
/* try to allocate the colours */
SDL_memset(got, 0, sizeof got);
missing = 0;
for (i = 0; i < nwant; i++) {
XColor c;
c.red = want[i].r << 8;
c.green = want[i].g << 8;
c.blue = want[i].b << 8;
c.flags = DoRed | DoGreen | DoBlue;
if (XAllocColor(GFX_Display, dcmap, &c)) {
/* got the colour */
SDL_iconcolors[c.pixel]++;
got[c.pixel] = want[i];
} else {
missing = 1;
}
}
if (missing) {
/* Some colours were apparently missing, so we just
allocate all the rest as well */
XColor cols[256];
for (i = 0; i < 256; i++)
cols[i].pixel = i;
XQueryColors(GFX_Display, dcmap, cols, 256);
for (i = 0; i < 256; i++) {
got[i].r = cols[i].red >> 8;
got[i].g = cols[i].green >> 8;
got[i].b = cols[i].blue >> 8;
if (!SDL_iconcolors[i]) {
if (XAllocColor(GFX_Display, dcmap, cols + i)) {
SDL_iconcolors[i] = 1;
} else {
/* index not available */
got[i].r = 0;
got[i].g = 0;
got[i].b = 0;
}
}
}
}
SDL_SetColors(sicon, got, 0, 256);
}
bounds.x = 0;
bounds.y = 0;
bounds.w = icon->w;
bounds.h = icon->h;
if (SDL_LowerBlit(icon, &bounds, sicon, &bounds) < 0)
goto done;
/* We need the mask as given, except in LSBfirst format instead of
MSBfirst. Reverse the bits in each byte. */
masksize = ((sicon->w + 7) >> 3) * sicon->h;
LSBmask = SDL_malloc(masksize);
if (LSBmask == NULL) {
goto done;
}
SDL_memset(LSBmask, 0, masksize);
for (i = 0; i < masksize; i++)
LSBmask[i] = reverse_byte(mask[i]);
mask_pixmap = XCreatePixmapFromBitmapData(SDL_Display, WMwindow,
(char *) LSBmask,
sicon->w, sicon->h, 1L, 0L, 1);
/* Transfer the image to an X11 pixmap */
icon_image = XCreateImage(SDL_Display,
DefaultVisual(SDL_Display, SDL_Screen),
DefaultDepth(SDL_Display, SDL_Screen),
ZPixmap, 0, sicon->pixels,
sicon->w, sicon->h, 32, 0);
icon_image->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN)
? MSBFirst : LSBFirst;
icon_pixmap = XCreatePixmap(SDL_Display, SDL_Root, sicon->w, sicon->h,
DefaultDepth(SDL_Display, SDL_Screen));
gc = XCreateGC(SDL_Display, icon_pixmap, 0, &GCvalues);
XPutImage(SDL_Display, icon_pixmap, gc, icon_image,
0, 0, 0, 0, sicon->w, sicon->h);
XFreeGC(SDL_Display, gc);
XDestroyImage(icon_image);
SDL_free(LSBmask);
sicon->pixels = NULL;
/* Some buggy window managers (some versions of Enlightenment, it
seems) need an icon window *and* icon pixmap to work properly, while
it screws up others. The default is only to use a pixmap. */
p = SDL_getenv("SDL_VIDEO_X11_ICONWIN");
if (p && *p) {
icon_window = XCreateSimpleWindow(SDL_Display, SDL_Root,
0, 0, sicon->w, sicon->h, 0,
CopyFromParent, CopyFromParent);
XSetWindowBackgroundPixmap(SDL_Display, icon_window, icon_pixmap);
XClearWindow(SDL_Display, icon_window);
}
/* Set the window icon to the icon pixmap (and icon window) */
wmhints = XAllocWMHints();
wmhints->flags = (IconPixmapHint | IconMaskHint);
wmhints->icon_pixmap = icon_pixmap;
wmhints->icon_mask = mask_pixmap;
if (icon_window != None) {
wmhints->flags |= IconWindowHint;
wmhints->icon_window = icon_window;
}
XSetWMHints(SDL_Display, WMwindow, wmhints);
XFree(wmhints);
XSync(SDL_Display, False);
done:
SDL_Unlock_EventThread();
SDL_FreeSurface(sicon);
}
void
X11_SetCaptionNoLock(_THIS, const char *title, const char *icon)
{
XTextProperty titleprop, iconprop;
Status status;
#ifdef X_HAVE_UTF8_STRING
Atom _NET_WM_NAME;
Atom _NET_WM_ICON_NAME;
/* Look up some useful Atoms */
if (SDL_X11_HAVE_UTF8) {
_NET_WM_NAME = XInternAtom(SDL_Display, "_NET_WM_NAME", False);
_NET_WM_ICON_NAME =
XInternAtom(SDL_Display, "_NET_WM_ICON_NAME", False);
}
#endif
if (title != NULL) {
char *title_latin1 = SDL_iconv_utf8_latin1((char *) title);
if (!title_latin1) {
SDL_OutOfMemory();
return;
}
status = XStringListToTextProperty(&title_latin1, 1, &titleprop);
SDL_free(title_latin1);
if (status) {
XSetTextProperty(SDL_Display, WMwindow, &titleprop, XA_WM_NAME);
XFree(titleprop.value);
}
#ifdef X_HAVE_UTF8_STRING
if (SDL_X11_HAVE_UTF8) {
status = Xutf8TextListToTextProperty(SDL_Display,
(char **) &title, 1,
XUTF8StringStyle,
&titleprop);
if (status == Success) {
XSetTextProperty(SDL_Display, WMwindow, &titleprop,
_NET_WM_NAME);
XFree(titleprop.value);
}
}
#endif
}
if (icon != NULL) {
char *icon_latin1 = SDL_iconv_utf8_latin1((char *) icon);
if (!icon_latin1) {
SDL_OutOfMemory();
return;
}
status = XStringListToTextProperty(&icon_latin1, 1, &iconprop);
SDL_free(icon_latin1);
if (status) {
XSetTextProperty(SDL_Display, WMwindow, &iconprop,
XA_WM_ICON_NAME);
XFree(iconprop.value);
}
#ifdef X_HAVE_UTF8_STRING
if (SDL_X11_HAVE_UTF8) {
status = Xutf8TextListToTextProperty(SDL_Display,
(char **) &icon, 1,
XUTF8StringStyle, &iconprop);
if (status == Success) {
XSetTextProperty(SDL_Display, WMwindow, &iconprop,
_NET_WM_ICON_NAME);
XFree(iconprop.value);
}
}
#endif
}
XSync(SDL_Display, False);
}
void
X11_SetCaption(_THIS, const char *title, const char *icon)
{
SDL_Lock_EventThread();
X11_SetCaptionNoLock(this, title, icon);
SDL_Unlock_EventThread();
}
/* Iconify the window */
int
X11_IconifyWindow(_THIS)
{
int result;
SDL_Lock_EventThread();
result = XIconifyWindow(SDL_Display, WMwindow, SDL_Screen);
XSync(SDL_Display, False);
SDL_Unlock_EventThread();
return (result);
}
SDL_GrabMode
X11_GrabInputNoLock(_THIS, SDL_GrabMode mode)
{
int result;
if (SDL_VideoSurface == NULL) {
return (SDL_GRAB_OFF);
}
if (!SDL_Window) {
return (mode); /* Will be set later on mode switch */
}
if (mode == SDL_GRAB_OFF) {
XUngrabPointer(SDL_Display, CurrentTime);
XUngrabKeyboard(SDL_Display, CurrentTime);
} else {
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
/* Unbind the mouse from the fullscreen window */
XUngrabPointer(SDL_Display, CurrentTime);
}
/* Try to grab the mouse */
#if 0 /* We'll wait here until we actually grab, otherwise behavior undefined */
for (numtries = 0; numtries < 10; ++numtries) {
#else
for (;;) {
#endif
result = XGrabPointer(SDL_Display, SDL_Window, True, 0,
GrabModeAsync, GrabModeAsync,
SDL_Window, None, CurrentTime);
if (result == GrabSuccess) {
break;
}
SDL_Delay(100);
}
if (result != GrabSuccess) {
/* Uh, oh, what do we do here? */ ;
}
/* Now grab the keyboard */
XGrabKeyboard(SDL_Display, WMwindow, True,
GrabModeAsync, GrabModeAsync, CurrentTime);
/* Raise the window if we grab the mouse */
if (!(SDL_VideoSurface->flags & SDL_FULLSCREEN))
XRaiseWindow(SDL_Display, WMwindow);
/* Make sure we register input focus */
SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
}
XSync(SDL_Display, False);
return (mode);
}
SDL_GrabMode
X11_GrabInput(_THIS, SDL_GrabMode mode)
{
SDL_Lock_EventThread();
mode = X11_GrabInputNoLock(this, mode);
SDL_Unlock_EventThread();
return (mode);
}
/* If 'info' is the right version, this function fills it and returns 1.
Otherwise, in case of a version mismatch, it returns -1.
*/
static void
lock_display(void)
{
SDL_Lock_EventThread();
}
static void
unlock_display(void)
{
/* Make sure any X11 transactions are completed */
SDL_VideoDevice *this = current_video;
XSync(SDL_Display, False);
SDL_Unlock_EventThread();
}
int
X11_GetWMInfo(_THIS, SDL_SysWMinfo * info)
{
if (info->version.major <= SDL_MAJOR_VERSION) {
info->subsystem = SDL_SYSWM_X11;
info->info.x11.display = SDL_Display;
info->info.x11.window = SDL_Window;
if (SDL_VERSIONNUM(info->version.major,
info->version.minor,
info->version.patch) >= 1002) {
info->info.x11.fswindow = FSwindow;
info->info.x11.wmwindow = WMwindow;
}
info->info.x11.lock_func = lock_display;
info->info.x11.unlock_func = unlock_display;
return (1);
} else {
SDL_SetError("Application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return (-1);
}
}
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,34 +0,0 @@
/*
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"
#include "SDL_x11video.h"
/* Functions to be exported */
extern void X11_SetCaptionNoLock(_THIS, const char *title, const char *icon);
extern void X11_SetCaption(_THIS, const char *title, const char *icon);
extern void X11_SetIcon(_THIS, SDL_Surface * icon, Uint8 * mask);
extern int X11_IconifyWindow(_THIS);
extern SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode);
extern SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode);
extern int X11_GetWMInfo(_THIS, SDL_SysWMinfo * info);
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,438 +0,0 @@
/*
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"
/* This is the XFree86 Xv extension implementation of YUV video overlays */
#if SDL_VIDEO_DRIVER_X11_XV
#include <X11/Xlib.h>
#ifndef NO_SHARED_MEMORY
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#endif
#include "../Xext/extensions/Xvlib.h"
#include "SDL_x11yuv_c.h"
#include "../SDL_yuvfuncs.h"
#define XFREE86_REFRESH_HACK
#ifdef XFREE86_REFRESH_HACK
#include "SDL_x11image_c.h"
#endif
/* Workaround when pitch != width */
#define PITCH_WORKAROUND
/* Fix for the NVidia GeForce 2 - use the last available adaptor */
#if 0 /* Apparently the NVidia drivers are fixed */
#define USE_LAST_ADAPTOR
#endif
/* The functions used to manipulate software video overlays */
static struct private_yuvhwfuncs x11_yuvfuncs = {
X11_LockYUVOverlay,
X11_UnlockYUVOverlay,
X11_DisplayYUVOverlay,
X11_FreeYUVOverlay
};
struct private_yuvhwdata
{
int port;
#ifndef NO_SHARED_MEMORY
int yuv_use_mitshm;
XShmSegmentInfo yuvshm;
#endif
SDL_NAME(XvImage) * image;
};
static int (*X_handler) (Display *, XErrorEvent *) = NULL;
#ifndef NO_SHARED_MEMORY
/* Shared memory error handler routine */
static int shm_error;
static int
shm_errhandler(Display * d, XErrorEvent * e)
{
if (e->error_code == BadAccess) {
shm_error = True;
return (0);
} else
return (X_handler(d, e));
}
#endif /* !NO_SHARED_MEMORY */
static int xv_error;
static int
xv_errhandler(Display * d, XErrorEvent * e)
{
if (e->error_code == BadMatch) {
xv_error = True;
return (0);
} else
return (X_handler(d, e));
}
SDL_Overlay *
X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format,
SDL_Surface * display)
{
SDL_Overlay *overlay;
struct private_yuvhwdata *hwdata;
int xv_port;
unsigned int i, j, k;
unsigned int adaptors;
SDL_NAME(XvAdaptorInfo) * ainfo;
int bpp;
#ifndef NO_SHARED_MEMORY
XShmSegmentInfo *yuvshm;
#endif
/* Look for the XVideo extension with a valid port for this format */
xv_port = -1;
if ((Success ==
SDL_NAME(XvQueryExtension) (GFX_Display, &j, &j, &j, &j, &j))
&& (Success ==
SDL_NAME(XvQueryAdaptors) (GFX_Display,
RootWindow(GFX_Display, SDL_Screen),
&adaptors, &ainfo))) {
#ifdef USE_LAST_ADAPTOR
for (i = 0; i < adaptors; ++i)
#else
for (i = 0; (i < adaptors) && (xv_port == -1); ++i)
#endif /* USE_LAST_ADAPTOR */
{
/* Check to see if the visual can be used */
if (BUGGY_XFREE86(<=, 4001)) {
int visual_ok = 0;
for (j = 0; j < ainfo[i].num_formats; ++j) {
if (ainfo[i].formats[j].visual_id == SDL_Visual->visualid) {
visual_ok = 1;
break;
}
}
if (!visual_ok) {
continue;
}
}
if ((ainfo[i].type & XvInputMask) &&
(ainfo[i].type & XvImageMask)) {
int num_formats;
SDL_NAME(XvImageFormatValues) * formats;
formats = SDL_NAME(XvListImageFormats) (GFX_Display,
ainfo[i].
base_id,
&num_formats);
#ifdef USE_LAST_ADAPTOR
for (j = 0; j < num_formats; ++j)
#else
for (j = 0; (j < num_formats) && (xv_port == -1); ++j)
#endif /* USE_LAST_ADAPTOR */
{
if ((Uint32) formats[j].id == format) {
for (k = 0; k < ainfo[i].num_ports; ++k) {
if (Success == SDL_NAME(XvGrabPort)
(GFX_Display,
ainfo[i].base_id + k, CurrentTime)) {
xv_port = ainfo[i].base_id + k;
break;
}
}
}
}
if (formats) {
XFree(formats);
}
}
}
SDL_NAME(XvFreeAdaptorInfo) (ainfo);
}
/* Precalculate the bpp for the pitch workaround below */
switch (format) {
/* Add any other cases we need to support... */
case SDL_YUY2_OVERLAY:
case SDL_UYVY_OVERLAY:
case SDL_YVYU_OVERLAY:
bpp = 2;
break;
default:
bpp = 1;
break;
}
#if 0
/*
* !!! FIXME:
* "Here are some diffs for X11 and yuv. Note that the last part 2nd
* diff should probably be a new call to XvQueryAdaptorFree with ainfo
* and the number of adaptors, instead of the loop through like I did."
*
* ACHTUNG: This is broken! It looks like XvFreeAdaptorInfo does this
* for you, so we end up with a double-free. I need to look at this
* more closely... --ryan.
*/
for (i = 0; i < adaptors; ++i) {
if (ainfo[i].name != NULL)
Xfree(ainfo[i].name);
if (ainfo[i].formats != NULL)
Xfree(ainfo[i].formats);
}
Xfree(ainfo);
#endif
if (xv_port == -1) {
SDL_SetError("No available video ports for requested format");
return (NULL);
}
/* Enable auto-painting of the overlay colorkey */
{
static const char *attr[] =
{ "XV_AUTOPAINT_COLORKEY", "XV_AUTOPAINT_COLOURKEY" };
unsigned int i;
SDL_NAME(XvSelectPortNotify) (GFX_Display, xv_port, True);
X_handler = XSetErrorHandler(xv_errhandler);
for (i = 0; i < sizeof(attr) / (sizeof attr[0]); ++i) {
Atom a;
xv_error = False;
a = XInternAtom(GFX_Display, attr[i], True);
if (a != None) {
SDL_NAME(XvSetPortAttribute) (GFX_Display, xv_port, a, 1);
XSync(GFX_Display, True);
if (!xv_error) {
break;
}
}
}
XSetErrorHandler(X_handler);
SDL_NAME(XvSelectPortNotify) (GFX_Display, xv_port, False);
}
/* Create the overlay structure */
overlay = (SDL_Overlay *) SDL_malloc(sizeof *overlay);
if (overlay == NULL) {
SDL_NAME(XvUngrabPort) (GFX_Display, xv_port, CurrentTime);
SDL_OutOfMemory();
return (NULL);
}
SDL_memset(overlay, 0, (sizeof *overlay));
/* Fill in the basic members */
overlay->format = format;
overlay->w = width;
overlay->h = height;
/* Set up the YUV surface function structure */
overlay->hwfuncs = &x11_yuvfuncs;
overlay->hw_overlay = 1;
/* Create the pixel data and lookup tables */
hwdata = (struct private_yuvhwdata *) SDL_malloc(sizeof *hwdata);
overlay->hwdata = hwdata;
if (hwdata == NULL) {
SDL_NAME(XvUngrabPort) (GFX_Display, xv_port, CurrentTime);
SDL_OutOfMemory();
SDL_FreeYUVOverlay(overlay);
return (NULL);
}
hwdata->port = xv_port;
#ifndef NO_SHARED_MEMORY
yuvshm = &hwdata->yuvshm;
SDL_memset(yuvshm, 0, sizeof(*yuvshm));
hwdata->image = SDL_NAME(XvShmCreateImage) (GFX_Display, xv_port, format,
0, width, height, yuvshm);
#ifdef PITCH_WORKAROUND
if (hwdata->image != NULL && hwdata->image->pitches[0] != (width * bpp)) {
/* Ajust overlay width according to pitch */
XFree(hwdata->image);
width = hwdata->image->pitches[0] / bpp;
hwdata->image =
SDL_NAME(XvShmCreateImage) (GFX_Display, xv_port, format, 0,
width, height, yuvshm);
}
#endif /* PITCH_WORKAROUND */
hwdata->yuv_use_mitshm = (hwdata->image != NULL);
if (hwdata->yuv_use_mitshm) {
yuvshm->shmid = shmget(IPC_PRIVATE, hwdata->image->data_size,
IPC_CREAT | 0777);
if (yuvshm->shmid >= 0) {
yuvshm->shmaddr = (char *) shmat(yuvshm->shmid, 0, 0);
yuvshm->readOnly = False;
if (yuvshm->shmaddr != (char *) -1) {
shm_error = False;
X_handler = XSetErrorHandler(shm_errhandler);
XShmAttach(GFX_Display, yuvshm);
XSync(GFX_Display, True);
XSetErrorHandler(X_handler);
if (shm_error)
shmdt(yuvshm->shmaddr);
} else {
shm_error = True;
}
shmctl(yuvshm->shmid, IPC_RMID, NULL);
} else {
shm_error = True;
}
if (shm_error) {
XFree(hwdata->image);
hwdata->yuv_use_mitshm = 0;
} else {
hwdata->image->data = yuvshm->shmaddr;
}
}
if (!hwdata->yuv_use_mitshm)
#endif /* NO_SHARED_MEMORY */
{
hwdata->image =
SDL_NAME(XvCreateImage) (GFX_Display, xv_port, format, 0,
width, height);
#ifdef PITCH_WORKAROUND
if (hwdata->image != NULL
&& hwdata->image->pitches[0] != (width * bpp)) {
/* Ajust overlay width according to pitch */
XFree(hwdata->image);
width = hwdata->image->pitches[0] / bpp;
hwdata->image =
SDL_NAME(XvCreateImage) (GFX_Display, xv_port, format, 0,
width, height);
}
#endif /* PITCH_WORKAROUND */
if (hwdata->image == NULL) {
SDL_SetError("Couldn't create XVideo image");
SDL_FreeYUVOverlay(overlay);
return (NULL);
}
hwdata->image->data = SDL_malloc(hwdata->image->data_size);
if (hwdata->image->data == NULL) {
SDL_OutOfMemory();
SDL_FreeYUVOverlay(overlay);
return (NULL);
}
}
/* Find the pitch and offset values for the overlay */
overlay->planes = hwdata->image->num_planes;
overlay->pitches =
(Uint16 *) SDL_malloc(overlay->planes * sizeof(Uint16));
overlay->pixels =
(Uint8 **) SDL_malloc(overlay->planes * sizeof(Uint8 *));
if (!overlay->pitches || !overlay->pixels) {
SDL_OutOfMemory();
SDL_FreeYUVOverlay(overlay);
return (NULL);
}
for (i = 0; i < overlay->planes; ++i) {
overlay->pitches[i] = hwdata->image->pitches[i];
overlay->pixels[i] = (Uint8 *) hwdata->image->data +
hwdata->image->offsets[i];
}
#ifdef XFREE86_REFRESH_HACK
/* Work around an XFree86 X server bug (?)
We can't perform normal updates in windows that have video
being output to them. See SDL_x11image.c for more details.
*/
X11_DisableAutoRefresh(this);
#endif
/* We're all done.. */
return (overlay);
}
int
X11_LockYUVOverlay(_THIS, SDL_Overlay * overlay)
{
return (0);
}
void
X11_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay)
{
return;
}
int
X11_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
SDL_Rect * dst)
{
struct private_yuvhwdata *hwdata;
hwdata = overlay->hwdata;
#ifndef NO_SHARED_MEMORY
if (hwdata->yuv_use_mitshm) {
SDL_NAME(XvShmPutImage) (GFX_Display, hwdata->port, SDL_Window,
SDL_GC, hwdata->image, src->x, src->y,
src->w, src->h, dst->x, dst->y, dst->w,
dst->h, False);
} else
#endif
{
SDL_NAME(XvPutImage) (GFX_Display, hwdata->port, SDL_Window,
SDL_GC, hwdata->image, src->x, src->y,
src->w, src->h, dst->x, dst->y, dst->w, dst->h);
}
XSync(GFX_Display, False);
return (0);
}
void
X11_FreeYUVOverlay(_THIS, SDL_Overlay * overlay)
{
struct private_yuvhwdata *hwdata;
hwdata = overlay->hwdata;
if (hwdata) {
SDL_NAME(XvUngrabPort) (GFX_Display, hwdata->port, CurrentTime);
#ifndef NO_SHARED_MEMORY
if (hwdata->yuv_use_mitshm) {
XShmDetach(GFX_Display, &hwdata->yuvshm);
shmdt(hwdata->yuvshm.shmaddr);
}
#endif
if (hwdata->image) {
XFree(hwdata->image);
}
SDL_free(hwdata);
}
if (overlay->pitches) {
SDL_free(overlay->pitches);
overlay->pitches = NULL;
}
if (overlay->pixels) {
SDL_free(overlay->pixels);
overlay->pixels = NULL;
}
#ifdef XFREE86_REFRESH_HACK
X11_EnableAutoRefresh(this);
#endif
}
#endif /* SDL_VIDEO_DRIVER_X11_XV */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,45 +0,0 @@
/*
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"
/* This is the XFree86 Xv extension implementation of YUV video overlays */
#include "SDL_video.h"
#include "SDL_x11video.h"
#if SDL_VIDEO_DRIVER_X11_XV
extern SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height,
Uint32 format,
SDL_Surface * display);
extern int X11_LockYUVOverlay(_THIS, SDL_Overlay * overlay);
extern void X11_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay);
extern int X11_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay,
SDL_Rect * src, SDL_Rect * dst);
extern void X11_FreeYUVOverlay(_THIS, SDL_Overlay * overlay);
#endif /* SDL_VIDEO_DRIVER_X11_XV */
/* vi: set ts=4 sw=4 expandtab: */