Mercurial > sdl-ios-xcode
changeset 1948:d646f6e1a439
Starting fresh with the X11 driver
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 26 Jul 2006 04:22:32 +0000 |
parents | 180f563d72a8 |
children | 44b6f09a07d8 |
files | src/video/x11/SDL_x11dyn.c src/video/x11/SDL_x11dyn.h src/video/x11/SDL_x11events.c src/video/x11/SDL_x11events_c.h src/video/x11/SDL_x11gamma.c src/video/x11/SDL_x11gamma_c.h src/video/x11/SDL_x11gl.c src/video/x11/SDL_x11gl_c.h src/video/x11/SDL_x11image.c src/video/x11/SDL_x11image_c.h src/video/x11/SDL_x11modes.c src/video/x11/SDL_x11modes_c.h src/video/x11/SDL_x11mouse.c src/video/x11/SDL_x11mouse_c.h src/video/x11/SDL_x11sym.h src/video/x11/SDL_x11video.c src/video/x11/SDL_x11video.h src/video/x11/SDL_x11wm.c src/video/x11/SDL_x11wm_c.h src/video/x11/SDL_x11yuv.c src/video/x11/SDL_x11yuv_c.h |
diffstat | 21 files changed, 0 insertions(+), 7241 deletions(-) [+] |
line wrap: on
line diff
--- a/src/video/x11/SDL_x11dyn.c Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11dyn.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11events.c Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1217 +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" - -/* Handle the event stream, converting X11 events into SDL events */ - -#include <setjmp.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/keysym.h> -#ifdef __SVR4 -#include <X11/Sunkeysym.h> -#endif -#include <sys/types.h> -#include <sys/time.h> -#include <unistd.h> - -#include "SDL_timer.h" -#include "SDL_syswm.h" -#include "../SDL_sysvideo.h" -#include "../../events/SDL_sysevents.h" -#include "../../events/SDL_events_c.h" -#include "SDL_x11video.h" -#include "SDL_x11dga_c.h" -#include "SDL_x11modes_c.h" -#include "SDL_x11image_c.h" -#include "SDL_x11gamma_c.h" -#include "SDL_x11wm_c.h" -#include "SDL_x11mouse_c.h" -#include "SDL_x11events_c.h" - - -/* Define this if you want to debug X11 events */ -/*#define DEBUG_XEVENTS*/ - -/* The translation tables from an X11 keysym to a SDL keysym */ -static SDLKey ODD_keymap[256]; -static SDLKey MISC_keymap[256]; -SDLKey X11_TranslateKeycode(Display * display, KeyCode kc); - - -#ifdef X_HAVE_UTF8_STRING -Uint32 -Utf8ToUcs4(const Uint8 * utf8) -{ - Uint32 c; - int i = 1; - int noOctets = 0; - int firstOctetMask = 0; - unsigned char firstOctet = utf8[0]; - if (firstOctet < 0x80) { - /* - Characters in the range: - 00000000 to 01111111 (ASCII Range) - are stored in one octet: - 0xxxxxxx (The same as its ASCII representation) - The least 6 significant bits of the first octet is the most 6 significant nonzero bits - of the UCS4 representation. - */ - noOctets = 1; - firstOctetMask = 0x7F; /* 0(1111111) - The most significant bit is ignored */ - } else if ((firstOctet & 0xE0) /* get the most 3 significant bits by AND'ing with 11100000 */ - == 0xC0) { /* see if those 3 bits are 110. If so, the char is in this range */ - /* - Characters in the range: - 00000000 10000000 to 00000111 11111111 - are stored in two octets: - 110xxxxx 10xxxxxx - The least 5 significant bits of the first octet is the most 5 significant nonzero bits - of the UCS4 representation. - */ - noOctets = 2; - firstOctetMask = 0x1F; /* 000(11111) - The most 3 significant bits are ignored */ - } else if ((firstOctet & 0xF0) /* get the most 4 significant bits by AND'ing with 11110000 */ - == 0xE0) { /* see if those 4 bits are 1110. If so, the char is in this range */ - /* - Characters in the range: - 00001000 00000000 to 11111111 11111111 - are stored in three octets: - 1110xxxx 10xxxxxx 10xxxxxx - The least 4 significant bits of the first octet is the most 4 significant nonzero bits - of the UCS4 representation. - */ - noOctets = 3; - firstOctetMask = 0x0F; /* 0000(1111) - The most 4 significant bits are ignored */ - } else if ((firstOctet & 0xF8) /* get the most 5 significant bits by AND'ing with 11111000 */ - == 0xF0) { /* see if those 5 bits are 11110. If so, the char is in this range */ - /* - Characters in the range: - 00000001 00000000 00000000 to 00011111 11111111 11111111 - are stored in four octets: - 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - The least 3 significant bits of the first octet is the most 3 significant nonzero bits - of the UCS4 representation. - */ - noOctets = 4; - firstOctetMask = 0x07; /* 11110(111) - The most 5 significant bits are ignored */ - } else if ((firstOctet & 0xFC) /* get the most 6 significant bits by AND'ing with 11111100 */ - == 0xF8) { /* see if those 6 bits are 111110. If so, the char is in this range */ - /* - Characters in the range: - 00000000 00100000 00000000 00000000 to - 00000011 11111111 11111111 11111111 - are stored in five octets: - 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - The least 2 significant bits of the first octet is the most 2 significant nonzero bits - of the UCS4 representation. - */ - noOctets = 5; - firstOctetMask = 0x03; /* 111110(11) - The most 6 significant bits are ignored */ - } else if ((firstOctet & 0xFE) /* get the most 7 significant bits by AND'ing with 11111110 */ - == 0xFC) { /* see if those 7 bits are 1111110. If so, the char is in this range */ - /* - Characters in the range: - 00000100 00000000 00000000 00000000 to - 01111111 11111111 11111111 11111111 - are stored in six octets: - 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - The least significant bit of the first octet is the most significant nonzero bit - of the UCS4 representation. - */ - noOctets = 6; - firstOctetMask = 0x01; /* 1111110(1) - The most 7 significant bits are ignored */ - } else - return 0; /* The given chunk is not a valid UTF-8 encoded Unicode character */ - - /* - The least noOctets significant bits of the first octet is the most 2 significant nonzero bits - of the UCS4 representation. - The first 6 bits of the UCS4 representation is the least 8-noOctets-1 significant bits of - firstOctet if the character is not ASCII. If so, it's the least 7 significant bits of firstOctet. - This done by AND'ing firstOctet with its mask to trim the bits used for identifying the - number of continuing octets (if any) and leave only the free bits (the x's) - Sample: - 1-octet: 0xxxxxxx & 01111111 = 0xxxxxxx - 2-octets: 110xxxxx & 00011111 = 000xxxxx - */ - c = firstOctet & firstOctetMask; - - /* Now, start filling c.ucs4 with the bits from the continuing octets from utf8. */ - for (i = 1; i < noOctets; i++) { - /* A valid continuing octet is of the form 10xxxxxx */ - if ((utf8[i] & 0xC0) /* get the most 2 significant bits by AND'ing with 11000000 */ - !=0x80) - /* see if those 2 bits are 10. If not, the is a malformed sequence. */ - /*The given chunk is a partial sequence at the end of a string that could - begin a valid character */ - return 0; - - /* Make room for the next 6-bits */ - c <<= 6; - - /* - Take only the least 6 significance bits of the current octet (utf8[i]) and fill the created room - of c.ucs4 with them. - This done by AND'ing utf8[i] with 00111111 and the OR'ing the result with c.ucs4. - */ - c |= utf8[i] & 0x3F; - } - return c; -} -#endif - -/* Check to see if this is a repeated key. - (idea shamelessly lifted from GII -- thanks guys! :) - */ -static int -X11_KeyRepeat(Display * display, XEvent * event) -{ - XEvent peekevent; - int repeated; - - repeated = 0; - if (XPending(display)) { - XPeekEvent(display, &peekevent); - if ((peekevent.type == KeyPress) && - (peekevent.xkey.keycode == event->xkey.keycode) && - ((peekevent.xkey.time - event->xkey.time) < 2)) { - repeated = 1; - XNextEvent(display, &peekevent); - } - } - return (repeated); -} - -/* Note: The X server buffers and accumulates mouse motion events, so - the motion event generated by the warp may not appear exactly as we - expect it to. We work around this (and improve performance) by only - warping the pointer when it reaches the edge, and then wait for it. -*/ -#define MOUSE_FUDGE_FACTOR 8 - -static __inline__ int -X11_WarpedMotion(_THIS, XEvent * xevent) -{ - int w, h, i; - int deltax, deltay; - int posted; - - w = SDL_VideoSurface->w; - h = SDL_VideoSurface->h; - deltax = xevent->xmotion.x - mouse_last.x; - deltay = xevent->xmotion.y - mouse_last.y; -#ifdef DEBUG_MOTION - printf("Warped mouse motion: %d,%d\n", deltax, deltay); -#endif - mouse_last.x = xevent->xmotion.x; - mouse_last.y = xevent->xmotion.y; - posted = SDL_PrivateMouseMotion(0, 1, deltax, deltay); - - if ((xevent->xmotion.x < MOUSE_FUDGE_FACTOR) || - (xevent->xmotion.x > (w - MOUSE_FUDGE_FACTOR)) || - (xevent->xmotion.y < MOUSE_FUDGE_FACTOR) || - (xevent->xmotion.y > (h - MOUSE_FUDGE_FACTOR))) { - /* Get the events that have accumulated */ - while (XCheckTypedEvent(SDL_Display, MotionNotify, xevent)) { - deltax = xevent->xmotion.x - mouse_last.x; - deltay = xevent->xmotion.y - mouse_last.y; -#ifdef DEBUG_MOTION - printf("Extra mouse motion: %d,%d\n", deltax, deltay); -#endif - mouse_last.x = xevent->xmotion.x; - mouse_last.y = xevent->xmotion.y; - posted += SDL_PrivateMouseMotion(0, 1, deltax, deltay); - } - mouse_last.x = w / 2; - mouse_last.y = h / 2; - XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, - mouse_last.x, mouse_last.y); - for (i = 0; i < 10; ++i) { - XMaskEvent(SDL_Display, PointerMotionMask, xevent); - if ((xevent->xmotion.x > - (mouse_last.x - MOUSE_FUDGE_FACTOR)) && - (xevent->xmotion.x < - (mouse_last.x + MOUSE_FUDGE_FACTOR)) && - (xevent->xmotion.y > - (mouse_last.y - MOUSE_FUDGE_FACTOR)) && - (xevent->xmotion.y < (mouse_last.y + MOUSE_FUDGE_FACTOR))) { - break; - } -#ifdef DEBUG_XEVENTS - printf("Lost mouse motion: %d,%d\n", xevent->xmotion.x, - xevent->xmotion.y); -#endif - } -#ifdef DEBUG_XEVENTS - if (i == 10) { - printf("Warning: didn't detect mouse warp motion\n"); - } -#endif - } - return (posted); -} - -static int -X11_DispatchEvent(_THIS) -{ - int posted; - XEvent xevent; - - SDL_memset(&xevent, '\0', sizeof(XEvent)); /* valgrind fix. --ryan. */ - XNextEvent(SDL_Display, &xevent); - - posted = 0; - switch (xevent.type) { - - /* Gaining mouse coverage? */ - case EnterNotify: - { -#ifdef DEBUG_XEVENTS - printf("EnterNotify! (%d,%d)\n", xevent.xcrossing.x, - xevent.xcrossing.y); - if (xevent.xcrossing.mode == NotifyGrab) - printf("Mode: NotifyGrab\n"); - if (xevent.xcrossing.mode == NotifyUngrab) - printf("Mode: NotifyUngrab\n"); -#endif - if ((xevent.xcrossing.mode != NotifyGrab) && - (xevent.xcrossing.mode != NotifyUngrab)) { - if (SDL_CurrentWindow.input_grab == SDL_GRAB_OFF) { - posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); - } - posted = SDL_PrivateMouseMotion(0, 0, - xevent.xcrossing.x, - xevent.xcrossing.y); - } - } - break; - - /* Losing mouse coverage? */ - case LeaveNotify: - { -#ifdef DEBUG_XEVENTS - printf("LeaveNotify! (%d,%d)\n", xevent.xcrossing.x, - xevent.xcrossing.y); - if (xevent.xcrossing.mode == NotifyGrab) - printf("Mode: NotifyGrab\n"); - if (xevent.xcrossing.mode == NotifyUngrab) - printf("Mode: NotifyUngrab\n"); -#endif - if ((xevent.xcrossing.mode != NotifyGrab) && - (xevent.xcrossing.mode != NotifyUngrab) && - (xevent.xcrossing.detail != NotifyInferior)) { - if (SDL_CurrentWindow.input_grab == SDL_GRAB_OFF) { - posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - } else { - posted = SDL_PrivateMouseMotion(0, 0, - xevent.xcrossing.x, - xevent.xcrossing.y); - } - } - } - break; - - /* Gaining input focus? */ - case FocusIn: - { -#ifdef DEBUG_XEVENTS - printf("FocusIn!\n"); -#endif - posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); - -#ifdef X_HAVE_UTF8_STRING - if (SDL_IC != NULL) { - XSetICFocus(SDL_IC); - } -#endif - /* Queue entry into fullscreen mode */ - switch_waiting = 0x01 | SDL_FULLSCREEN; - switch_time = SDL_GetTicks() + 1500; - } - break; - - /* Losing input focus? */ - case FocusOut: - { -#ifdef DEBUG_XEVENTS - printf("FocusOut!\n"); -#endif - posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); - -#ifdef X_HAVE_UTF8_STRING - if (SDL_IC != NULL) { - XUnsetICFocus(SDL_IC); - } -#endif - /* Queue leaving fullscreen mode */ - switch_waiting = 0x01; - switch_time = SDL_GetTicks() + 200; - } - break; - - /* Generated upon EnterWindow and FocusIn */ - case KeymapNotify: - { -#ifdef DEBUG_XEVENTS - printf("KeymapNotify!\n"); -#endif - X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector); - } - break; - - /* Mouse motion? */ - case MotionNotify: - { - if (SDL_VideoSurface) { - if (mouse_relative) { - if (using_dga & DGA_MOUSE) { -#ifdef DEBUG_MOTION - printf("DGA motion: %d,%d\n", - xevent.xmotion.x_root, xevent.xmotion.y_root); -#endif - posted = SDL_PrivateMouseMotion(0, 1, - xevent. - xmotion. - x_root, - xevent. - xmotion.y_root); - } else { - posted = X11_WarpedMotion(_this, &xevent); - } - } else { -#ifdef DEBUG_MOTION - printf("X11 motion: %d,%d\n", xevent.xmotion.x, - xevent.xmotion.y); -#endif - posted = SDL_PrivateMouseMotion(0, 0, - xevent.xmotion.x, - xevent.xmotion.y); - } - } - } - break; - - /* Mouse button press? */ - case ButtonPress: - { - posted = SDL_PrivateMouseButton(SDL_PRESSED, - xevent.xbutton.button, 0, 0); - } - break; - - /* Mouse button release? */ - case ButtonRelease: - { - posted = SDL_PrivateMouseButton(SDL_RELEASED, - xevent.xbutton.button, 0, 0); - } - break; - - /* Key press? */ - case KeyPress: - { - static SDL_keysym saved_keysym; - SDL_keysym keysym; - KeyCode keycode = xevent.xkey.keycode; - -#ifdef DEBUG_XEVENTS - printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); -#endif - /* Get the translated SDL virtual keysym */ - if (keycode) { - keysym.scancode = keycode; - keysym.sym = X11_TranslateKeycode(SDL_Display, keycode); - keysym.mod = KMOD_NONE; - keysym.unicode = 0; - } else { - keysym = saved_keysym; - } - - /* If we're not doing translation, we're done! */ - if (!SDL_TranslateUNICODE) { - posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); - break; - } - - if (XFilterEvent(&xevent, None)) { - if (xevent.xkey.keycode) { - posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); - } else { - /* Save event to be associated with IM text - In 1.3 we'll have a text event instead.. */ - saved_keysym = keysym; - } - break; - } - - /* Look up the translated value for the key event */ -#ifdef X_HAVE_UTF8_STRING - if (SDL_IC != NULL) { - static Status state; - /* A UTF-8 character can be at most 6 bytes */ - char keybuf[6]; - if (Xutf8LookupString(SDL_IC, &xevent.xkey, - keybuf, sizeof(keybuf), NULL, &state)) { - keysym.unicode = Utf8ToUcs4((Uint8 *) keybuf); - } - } else -#endif - { - static XComposeStatus state; - char keybuf[32]; - - if (XLookupString(&xevent.xkey, - keybuf, sizeof(keybuf), NULL, &state)) { - /* - * FIXME: XLookupString() may yield more than one - * character, so we need a mechanism to allow for - * this (perhaps null keypress events with a - * unicode value) - */ - keysym.unicode = (Uint8) keybuf[0]; - } - } - posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); - } - break; - - /* Key release? */ - case KeyRelease: - { - SDL_keysym keysym; - KeyCode keycode = xevent.xkey.keycode; - -#ifdef DEBUG_XEVENTS - printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode); -#endif - /* Check to see if this is a repeated key */ - if (X11_KeyRepeat(SDL_Display, &xevent)) { - break; - } - - /* Get the translated SDL virtual keysym */ - keysym.scancode = keycode; - keysym.sym = X11_TranslateKeycode(SDL_Display, keycode); - keysym.mod = KMOD_NONE; - keysym.unicode = 0; - - posted = SDL_PrivateKeyboard(SDL_RELEASED, &keysym); - } - break; - - /* Have we been iconified? */ - case UnmapNotify: - { -#ifdef DEBUG_XEVENTS - printf("UnmapNotify!\n"); -#endif - /* If we're active, make ourselves inactive */ - if (SDL_GetAppState() & SDL_APPACTIVE) { - /* Swap out the gamma before we go inactive */ - X11_SwapVidModeGamma(_this); - - /* Send an internal deactivate event */ - posted = SDL_PrivateAppActive(0, - SDL_APPACTIVE | - SDL_APPINPUTFOCUS); - } - } - break; - - /* Have we been restored? */ - case MapNotify: - { -#ifdef DEBUG_XEVENTS - printf("MapNotify!\n"); -#endif - /* If we're not active, make ourselves active */ - if (!(SDL_GetAppState() & SDL_APPACTIVE)) { - /* Send an internal activate event */ - posted = SDL_PrivateAppActive(1, SDL_APPACTIVE); - - /* Now that we're active, swap the gamma back */ - X11_SwapVidModeGamma(_this); - } - - if (SDL_VideoSurface && - (SDL_VideoSurface->flags & SDL_FULLSCREEN)) { - X11_EnterFullScreen(_this); - } else { - X11_GrabInputNoLock(_this, SDL_CurrentWindow.input_grab); - } - X11_CheckMouseModeNoLock(_this); - - if (SDL_VideoSurface) { - X11_RefreshDisplay(_this); - } - } - break; - - /* Have we been resized or moved? */ - case ConfigureNotify: - { -#ifdef DEBUG_XEVENTS - printf("ConfigureNotify! (resize: %dx%d)\n", - xevent.xconfigure.width, xevent.xconfigure.height); -#endif - if (SDL_VideoSurface) { - if ((xevent.xconfigure.width != SDL_VideoSurface->w) || - (xevent.xconfigure.height != SDL_VideoSurface->h)) { - /* FIXME: Find a better fix for the bug with KDE 1.2 */ - if (!((xevent.xconfigure.width == 32) && - (xevent.xconfigure.height == 32))) { - SDL_PrivateResize(xevent.xconfigure.width, - xevent.xconfigure.height); - } - } else { - /* OpenGL windows need to know about the change */ - if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) { - SDL_PrivateExpose(); - } - } - } - } - break; - - /* Have we been requested to quit (or another client message?) */ - case ClientMessage: - { - if ((xevent.xclient.format == 32) && - (xevent.xclient.data.l[0] == WM_DELETE_WINDOW)) { - posted = SDL_PrivateQuit(); - } else if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) { - SDL_SysWMmsg wmmsg; - - SDL_VERSION(&wmmsg.version); - wmmsg.subsystem = SDL_SYSWM_X11; - wmmsg.event.xevent = xevent; - posted = SDL_PrivateSysWMEvent(&wmmsg); - } - } - break; - - /* Do we need to refresh ourselves? */ - case Expose: - { -#ifdef DEBUG_XEVENTS - printf("Expose (count = %d)\n", xevent.xexpose.count); -#endif - if (SDL_VideoSurface && (xevent.xexpose.count == 0)) { - X11_RefreshDisplay(_this); - } - } - break; - - default: - { -#ifdef DEBUG_XEVENTS - printf("Unhandled event %d\n", xevent.type); -#endif - /* Only post the event if we're watching for it */ - if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) { - SDL_SysWMmsg wmmsg; - - SDL_VERSION(&wmmsg.version); - wmmsg.subsystem = SDL_SYSWM_X11; - wmmsg.event.xevent = xevent; - posted = SDL_PrivateSysWMEvent(&wmmsg); - } - } - break; - } - return (posted); -} - -/* Ack! XPending() actually performs a blocking read if no events available */ -int -X11_Pending(Display * display) -{ - /* Flush the display connection and look to see if events are queued */ - XFlush(display); - if (XEventsQueued(display, QueuedAlready)) { - return (1); - } - - /* More drastic measures are required -- see if X is ready to talk */ - { - static struct timeval zero_time; /* static == 0 */ - int x11_fd; - fd_set fdset; - - x11_fd = ConnectionNumber(display); - FD_ZERO(&fdset); - FD_SET(x11_fd, &fdset); - if (select(x11_fd + 1, &fdset, NULL, NULL, &zero_time) == 1) { - return (XPending(display)); - } - } - - /* Oh well, nothing is ready .. */ - return (0); -} - -void -X11_PumpEvents(_THIS) -{ - int pending; - - /* Keep processing pending events */ - pending = 0; - while (X11_Pending(SDL_Display)) { - X11_DispatchEvent(_this); - ++pending; - } - if (switch_waiting) { - Uint32 now; - - now = SDL_GetTicks(); - if (pending || !SDL_VideoSurface) { - /* Try again later... */ - if (switch_waiting & SDL_FULLSCREEN) { - switch_time = now + 1500; - } else { - switch_time = now + 200; - } - } else if ((int) (switch_time - now) <= 0) { - Uint32 go_fullscreen; - - go_fullscreen = switch_waiting & SDL_FULLSCREEN; - switch_waiting = 0; - if (SDL_VideoSurface->flags & SDL_FULLSCREEN) { - if (go_fullscreen) { - X11_EnterFullScreen(_this); - } else { - X11_LeaveFullScreen(_this); - } - } - /* Handle focus in/out when grabbed */ - if (go_fullscreen) { - X11_GrabInputNoLock(_this, SDL_CurrentWindow.input_grab); - } else { - X11_GrabInputNoLock(_this, SDL_GRAB_OFF); - } - X11_CheckMouseModeNoLock(_this); - } - } -} - -void -X11_InitKeymap(void) -{ - int i; - - /* Odd keys used in international keyboards */ - for (i = 0; i < SDL_arraysize(ODD_keymap); ++i) - ODD_keymap[i] = SDLK_UNKNOWN; - - /* Some of these might be mappable to an existing SDLK_ code */ - ODD_keymap[XK_dead_grave & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_acute & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_tilde & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_macron & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_breve & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_abovedot & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_diaeresis & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_abovering & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_doubleacute & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_caron & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_cedilla & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_ogonek & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_iota & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_voiced_sound & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_semivoiced_sound & 0xFF] = SDLK_COMPOSE; - ODD_keymap[XK_dead_belowdot & 0xFF] = SDLK_COMPOSE; -#ifdef XK_dead_hook - ODD_keymap[XK_dead_hook & 0xFF] = SDLK_COMPOSE; -#endif -#ifdef XK_dead_horn - ODD_keymap[XK_dead_horn & 0xFF] = SDLK_COMPOSE; -#endif - -#ifdef XK_dead_circumflex - /* These X keysyms have 0xFE as the high byte */ - ODD_keymap[XK_dead_circumflex & 0xFF] = SDLK_CARET; -#endif -#ifdef XK_ISO_Level3_Shift - ODD_keymap[XK_ISO_Level3_Shift & 0xFF] = SDLK_MODE; /* "Alt Gr" key */ -#endif - - /* Map the miscellaneous keys */ - for (i = 0; i < SDL_arraysize(MISC_keymap); ++i) - MISC_keymap[i] = SDLK_UNKNOWN; - - /* These X keysyms have 0xFF as the high byte */ - MISC_keymap[XK_BackSpace & 0xFF] = SDLK_BACKSPACE; - MISC_keymap[XK_Tab & 0xFF] = SDLK_TAB; - MISC_keymap[XK_Clear & 0xFF] = SDLK_CLEAR; - MISC_keymap[XK_Return & 0xFF] = SDLK_RETURN; - MISC_keymap[XK_Pause & 0xFF] = SDLK_PAUSE; - MISC_keymap[XK_Escape & 0xFF] = SDLK_ESCAPE; - MISC_keymap[XK_Delete & 0xFF] = SDLK_DELETE; - - MISC_keymap[XK_KP_0 & 0xFF] = SDLK_KP0; /* Keypad 0-9 */ - MISC_keymap[XK_KP_1 & 0xFF] = SDLK_KP1; - MISC_keymap[XK_KP_2 & 0xFF] = SDLK_KP2; - MISC_keymap[XK_KP_3 & 0xFF] = SDLK_KP3; - MISC_keymap[XK_KP_4 & 0xFF] = SDLK_KP4; - MISC_keymap[XK_KP_5 & 0xFF] = SDLK_KP5; - MISC_keymap[XK_KP_6 & 0xFF] = SDLK_KP6; - MISC_keymap[XK_KP_7 & 0xFF] = SDLK_KP7; - MISC_keymap[XK_KP_8 & 0xFF] = SDLK_KP8; - MISC_keymap[XK_KP_9 & 0xFF] = SDLK_KP9; - MISC_keymap[XK_KP_Insert & 0xFF] = SDLK_KP0; - MISC_keymap[XK_KP_End & 0xFF] = SDLK_KP1; - MISC_keymap[XK_KP_Down & 0xFF] = SDLK_KP2; - MISC_keymap[XK_KP_Page_Down & 0xFF] = SDLK_KP3; - MISC_keymap[XK_KP_Left & 0xFF] = SDLK_KP4; - MISC_keymap[XK_KP_Begin & 0xFF] = SDLK_KP5; - MISC_keymap[XK_KP_Right & 0xFF] = SDLK_KP6; - MISC_keymap[XK_KP_Home & 0xFF] = SDLK_KP7; - MISC_keymap[XK_KP_Up & 0xFF] = SDLK_KP8; - MISC_keymap[XK_KP_Page_Up & 0xFF] = SDLK_KP9; - MISC_keymap[XK_KP_Delete & 0xFF] = SDLK_KP_PERIOD; - MISC_keymap[XK_KP_Decimal & 0xFF] = SDLK_KP_PERIOD; - MISC_keymap[XK_KP_Divide & 0xFF] = SDLK_KP_DIVIDE; - MISC_keymap[XK_KP_Multiply & 0xFF] = SDLK_KP_MULTIPLY; - MISC_keymap[XK_KP_Subtract & 0xFF] = SDLK_KP_MINUS; - MISC_keymap[XK_KP_Add & 0xFF] = SDLK_KP_PLUS; - MISC_keymap[XK_KP_Enter & 0xFF] = SDLK_KP_ENTER; - MISC_keymap[XK_KP_Equal & 0xFF] = SDLK_KP_EQUALS; - - MISC_keymap[XK_Up & 0xFF] = SDLK_UP; - MISC_keymap[XK_Down & 0xFF] = SDLK_DOWN; - MISC_keymap[XK_Right & 0xFF] = SDLK_RIGHT; - MISC_keymap[XK_Left & 0xFF] = SDLK_LEFT; - MISC_keymap[XK_Insert & 0xFF] = SDLK_INSERT; - MISC_keymap[XK_Home & 0xFF] = SDLK_HOME; - MISC_keymap[XK_End & 0xFF] = SDLK_END; - MISC_keymap[XK_Page_Up & 0xFF] = SDLK_PAGEUP; - MISC_keymap[XK_Page_Down & 0xFF] = SDLK_PAGEDOWN; - - MISC_keymap[XK_F1 & 0xFF] = SDLK_F1; - MISC_keymap[XK_F2 & 0xFF] = SDLK_F2; - MISC_keymap[XK_F3 & 0xFF] = SDLK_F3; - MISC_keymap[XK_F4 & 0xFF] = SDLK_F4; - MISC_keymap[XK_F5 & 0xFF] = SDLK_F5; - MISC_keymap[XK_F6 & 0xFF] = SDLK_F6; - MISC_keymap[XK_F7 & 0xFF] = SDLK_F7; - MISC_keymap[XK_F8 & 0xFF] = SDLK_F8; - MISC_keymap[XK_F9 & 0xFF] = SDLK_F9; - MISC_keymap[XK_F10 & 0xFF] = SDLK_F10; - MISC_keymap[XK_F11 & 0xFF] = SDLK_F11; - MISC_keymap[XK_F12 & 0xFF] = SDLK_F12; - MISC_keymap[XK_F13 & 0xFF] = SDLK_F13; - MISC_keymap[XK_F14 & 0xFF] = SDLK_F14; - MISC_keymap[XK_F15 & 0xFF] = SDLK_F15; - - MISC_keymap[XK_Num_Lock & 0xFF] = SDLK_NUMLOCK; - MISC_keymap[XK_Caps_Lock & 0xFF] = SDLK_CAPSLOCK; - MISC_keymap[XK_Scroll_Lock & 0xFF] = SDLK_SCROLLOCK; - MISC_keymap[XK_Shift_R & 0xFF] = SDLK_RSHIFT; - MISC_keymap[XK_Shift_L & 0xFF] = SDLK_LSHIFT; - MISC_keymap[XK_Control_R & 0xFF] = SDLK_RCTRL; - MISC_keymap[XK_Control_L & 0xFF] = SDLK_LCTRL; - MISC_keymap[XK_Alt_R & 0xFF] = SDLK_RALT; - MISC_keymap[XK_Alt_L & 0xFF] = SDLK_LALT; - MISC_keymap[XK_Meta_R & 0xFF] = SDLK_RMETA; - MISC_keymap[XK_Meta_L & 0xFF] = SDLK_LMETA; - MISC_keymap[XK_Super_L & 0xFF] = SDLK_LSUPER; /* Left "Windows" */ - MISC_keymap[XK_Super_R & 0xFF] = SDLK_RSUPER; /* Right "Windows */ - MISC_keymap[XK_Mode_switch & 0xFF] = SDLK_MODE; /* "Alt Gr" key */ - MISC_keymap[XK_Multi_key & 0xFF] = SDLK_COMPOSE; /* Multi-key compose */ - - MISC_keymap[XK_Help & 0xFF] = SDLK_HELP; - MISC_keymap[XK_Print & 0xFF] = SDLK_PRINT; - MISC_keymap[XK_Sys_Req & 0xFF] = SDLK_SYSREQ; - MISC_keymap[XK_Break & 0xFF] = SDLK_BREAK; - MISC_keymap[XK_Menu & 0xFF] = SDLK_MENU; - MISC_keymap[XK_Hyper_R & 0xFF] = SDLK_MENU; /* Windows "Menu" key */ -} - -/* Get the translated SDL virtual keysym */ -SDLKey -X11_TranslateKeycode(Display * display, KeyCode kc) -{ - KeySym xsym; - SDLKey key; - - xsym = XKeycodeToKeysym(display, kc, 0); -#ifdef DEBUG_KEYS - fprintf(stderr, "Translating key code %d -> 0x%.4x\n", kc, xsym); -#endif - key = SDLK_UNKNOWN; - if (xsym) { - switch (xsym >> 8) { - case 0x1005FF: -#ifdef SunXK_F36 - if (xsym == SunXK_F36) - key = SDLK_F11; -#endif -#ifdef SunXK_F37 - if (xsym == SunXK_F37) - key = SDLK_F12; -#endif - break; - case 0x00: /* Latin 1 */ - key = (SDLKey) (xsym & 0xFF); - break; - case 0x01: /* Latin 2 */ - case 0x02: /* Latin 3 */ - case 0x03: /* Latin 4 */ - case 0x04: /* Katakana */ - case 0x05: /* Arabic */ - case 0x06: /* Cyrillic */ - case 0x07: /* Greek */ - case 0x08: /* Technical */ - case 0x0A: /* Publishing */ - case 0x0C: /* Hebrew */ - case 0x0D: /* Thai */ - /* These are wrong, but it's better than nothing */ - key = (SDLKey) (xsym & 0xFF); - break; - case 0xFE: - key = ODD_keymap[xsym & 0xFF]; - break; - case 0xFF: - key = MISC_keymap[xsym & 0xFF]; - break; - default: - /* - fprintf(stderr, "X11: Unhandled xsym, sym = 0x%04x\n", - (unsigned int)xsym); - */ - break; - } - } else { - /* X11 doesn't know how to translate the key! */ - switch (kc) { - /* Caution: - These keycodes are from the Microsoft Keyboard - */ - case 115: - key = SDLK_LSUPER; - break; - case 116: - key = SDLK_RSUPER; - break; - case 117: - key = SDLK_MENU; - break; - default: - /* - * no point in an error message; happens for - * several keys when we get a keymap notify - */ - break; - } - } - return key; -} - -/* X11 modifier masks for various keys */ -static unsigned meta_l_mask, meta_r_mask, alt_l_mask, alt_r_mask; -static unsigned num_mask, mode_switch_mask; - -static void -get_modifier_masks(Display * display) -{ - static unsigned got_masks; - int i, j; - XModifierKeymap *xmods; - unsigned n; - - if (got_masks) - return; - - xmods = XGetModifierMapping(display); - n = xmods->max_keypermod; - for (i = 3; i < 8; i++) { - for (j = 0; j < n; j++) { - KeyCode kc = xmods->modifiermap[i * n + j]; - KeySym ks = XKeycodeToKeysym(display, kc, 0); - unsigned mask = 1 << i; - switch (ks) { - case XK_Num_Lock: - num_mask = mask; - break; - case XK_Alt_L: - alt_l_mask = mask; - break; - case XK_Alt_R: - alt_r_mask = mask; - break; - case XK_Meta_L: - meta_l_mask = mask; - break; - case XK_Meta_R: - meta_r_mask = mask; - break; - case XK_Mode_switch: - mode_switch_mask = mask; - break; - } - } - } - XFreeModifiermap(xmods); - got_masks = 1; -} - - -/* - * This function is semi-official; it is not officially exported and should - * not be considered part of the SDL API, but may be used by client code - * that *really* needs it (including legacy code). - * It is slow, though, and should be avoided if possible. - * - * Note that it isn't completely accurate either; in particular, multi-key - * sequences (dead accents, compose key sequences) will not work since the - * state has been irrevocably lost. - */ -Uint16 -X11_KeyToUnicode(SDLKey keysym, SDLMod modifiers) -{ - SDL_VideoDevice *_this = SDL_GetVideoDevice(); - char keybuf[32]; - int i; - KeySym xsym = 0; - XKeyEvent xkey; - Uint16 unicode; - - if (!_this || !SDL_Display) { - return 0; - } - - SDL_memset(&xkey, 0, sizeof(xkey)); - xkey.display = SDL_Display; - - xsym = keysym; /* last resort if not found */ - for (i = 0; i < 256; ++i) { - if (MISC_keymap[i] == keysym) { - xsym = 0xFF00 | i; - break; - } else if (ODD_keymap[i] == keysym) { - xsym = 0xFE00 | i; - break; - } - } - - xkey.keycode = XKeysymToKeycode(xkey.display, xsym); - - get_modifier_masks(SDL_Display); - if (modifiers & KMOD_SHIFT) - xkey.state |= ShiftMask; - if (modifiers & KMOD_CAPS) - xkey.state |= LockMask; - if (modifiers & KMOD_CTRL) - xkey.state |= ControlMask; - if (modifiers & KMOD_MODE) - xkey.state |= mode_switch_mask; - if (modifiers & KMOD_LALT) - xkey.state |= alt_l_mask; - if (modifiers & KMOD_RALT) - xkey.state |= alt_r_mask; - if (modifiers & KMOD_LMETA) - xkey.state |= meta_l_mask; - if (modifiers & KMOD_RMETA) - xkey.state |= meta_r_mask; - if (modifiers & KMOD_NUM) - xkey.state |= num_mask; - - unicode = 0; - if (XLookupString(&xkey, keybuf, sizeof(keybuf), NULL, NULL)) - unicode = (unsigned char) keybuf[0]; - return (unicode); -} - - -/* - * Called when focus is regained, to read the keyboard state and generate - * synthetic keypress/release events. - * key_vec is a bit vector of keycodes (256 bits) - */ -void -X11_SetKeyboardState(Display * display, const char *key_vec) -{ - char keys_return[32]; - int i; - Uint8 *kstate = SDL_GetKeyState(NULL); - SDLMod modstate; - Window junk_window; - int x, y; - unsigned int mask; - - /* The first time the window is mapped, we initialize key state */ - if (!key_vec) { - XQueryKeymap(display, keys_return); - key_vec = keys_return; - } - - /* Get the keyboard modifier state */ - modstate = 0; - get_modifier_masks(display); - if (XQueryPointer(display, DefaultRootWindow(display), - &junk_window, &junk_window, &x, &y, &x, &y, &mask)) { - if (mask & LockMask) { - modstate |= KMOD_CAPS; - } - if (mask & mode_switch_mask) { - modstate |= KMOD_MODE; - } - if (mask & num_mask) { - modstate |= KMOD_NUM; - } - } - - /* Zero the new keyboard state and generate it */ - SDL_memset(kstate, 0, SDLK_LAST); - /* - * An obvious optimisation is to check entire longwords at a time in - * both loops, but we can't be sure the arrays are aligned so it's not - * worth the extra complexity - */ - for (i = 0; i < 32; i++) { - int j; - if (!key_vec[i]) - continue; - for (j = 0; j < 8; j++) { - if (key_vec[i] & (1 << j)) { - SDLKey key; - KeyCode kc = (i << 3 | j); - key = X11_TranslateKeycode(display, kc); - if (key == SDLK_UNKNOWN) { - continue; - } - kstate[key] = SDL_PRESSED; - switch (key) { - case SDLK_LSHIFT: - modstate |= KMOD_LSHIFT; - break; - case SDLK_RSHIFT: - modstate |= KMOD_RSHIFT; - break; - case SDLK_LCTRL: - modstate |= KMOD_LCTRL; - break; - case SDLK_RCTRL: - modstate |= KMOD_RCTRL; - break; - case SDLK_LALT: - modstate |= KMOD_LALT; - break; - case SDLK_RALT: - modstate |= KMOD_RALT; - break; - case SDLK_LMETA: - modstate |= KMOD_LMETA; - break; - case SDLK_RMETA: - modstate |= KMOD_RMETA; - break; - default: - break; - } - } - } - } - - /* Hack - set toggle key state */ - if (modstate & KMOD_CAPS) { - kstate[SDLK_CAPSLOCK] = SDL_PRESSED; - } else { - kstate[SDLK_CAPSLOCK] = SDL_RELEASED; - } - if (modstate & KMOD_NUM) { - kstate[SDLK_NUMLOCK] = SDL_PRESSED; - } else { - kstate[SDLK_NUMLOCK] = SDL_RELEASED; - } - - /* Set the final modifier state */ - SDL_SetModState(modstate); -} - -void -X11_InitOSKeymap(_THIS) -{ - X11_InitKeymap(); -} - -void -X11_SaveScreenSaver(Display * display, int *saved_timeout, BOOL * dpms) -{ - int timeout, interval, prefer_blank, allow_exp; - XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp); - *saved_timeout = timeout; - -#if SDL_VIDEO_DRIVER_X11_DPMS - if (SDL_X11_HAVE_DPMS) { - int dummy; - if (DPMSQueryExtension(display, &dummy, &dummy)) { - CARD16 state; - DPMSInfo(display, &state, dpms); - } - } -#else - *dpms = 0; -#endif /* SDL_VIDEO_DRIVER_X11_DPMS */ -} - -void -X11_DisableScreenSaver(Display * display) -{ - int timeout, interval, prefer_blank, allow_exp; - XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp); - timeout = 0; - XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp); - -#if SDL_VIDEO_DRIVER_X11_DPMS - if (SDL_X11_HAVE_DPMS) { - int dummy; - if (DPMSQueryExtension(display, &dummy, &dummy)) { - DPMSDisable(display); - } - } -#endif /* SDL_VIDEO_DRIVER_X11_DPMS */ -} - -void -X11_RestoreScreenSaver(Display * display, int saved_timeout, BOOL dpms) -{ - int timeout, interval, prefer_blank, allow_exp; - XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp); - timeout = saved_timeout; - XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp); - -#if SDL_VIDEO_DRIVER_X11_DPMS - if (SDL_X11_HAVE_DPMS) { - int dummy; - if (DPMSQueryExtension(display, &dummy, &dummy)) { - if (dpms) { - DPMSEnable(display); - } - } - } -#endif /* SDL_VIDEO_DRIVER_X11_DPMS */ -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/x11/SDL_x11events_c.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11gamma.c Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11gamma_c.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11gl.c Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11gl_c.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11image.c Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11image_c.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11modes.c Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11modes_c.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11mouse.c Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11mouse_c.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11sym.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11video.c Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1458 +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" - -/* X11 based SDL video driver implementation. - Note: This implementation does not currently need X11 thread locking, - since the event thread uses a separate X connection and any - additional locking necessary is handled internally. However, - if full locking is neccessary, take a look at XInitThreads(). -*/ - -#include <unistd.h> -#include <sys/ioctl.h> -#ifdef MTRR_SUPPORT -#include <asm/mtrr.h> -#include <sys/fcntl.h> -#endif - -#include "SDL_endian.h" -#include "SDL_timer.h" -#include "SDL_thread.h" -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "../../events/SDL_events_c.h" -#include "SDL_x11video.h" -#include "SDL_x11wm_c.h" -#include "SDL_x11mouse_c.h" -#include "SDL_x11events_c.h" -#include "SDL_x11modes_c.h" -#include "SDL_x11image_c.h" -#include "SDL_x11yuv_c.h" -#include "SDL_x11gl_c.h" -#include "SDL_x11gamma_c.h" -#include "../blank_cursor.h" - -/* Initialization/Query functions */ -static int X11_VideoInit(_THIS); -static SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface * current, - const SDL_DisplayMode * mode, - Uint32 flags); -static int X11_ToggleFullScreen(_THIS, int on); -static void X11_UpdateMouse(_THIS); -static int X11_SetColors(_THIS, int firstcolor, int ncolors, - SDL_Color * colors); -static int X11_SetGammaRamp(_THIS, Uint16 * ramp); -static void X11_VideoQuit(_THIS); - - -/* X11 driver bootstrap functions */ - -static int -X11_Available(void) -{ - Display *display = NULL; - if (SDL_X11_LoadSymbols()) { - display = XOpenDisplay(NULL); - if (display != NULL) { - XCloseDisplay(display); - } - SDL_X11_UnloadSymbols(); - } - return (display != NULL); -} - -static void -X11_DeleteDevice(SDL_VideoDevice * device) -{ - if (device) { - if (device->hidden) { - SDL_free(device->hidden); - } - if (device->gl_data) { - SDL_free(device->gl_data); - } - SDL_free(device); - SDL_X11_UnloadSymbols(); - } -} - -static SDL_VideoDevice * -X11_CreateDevice(int devindex) -{ - SDL_VideoDevice *device = NULL; - - if (SDL_X11_LoadSymbols()) { - /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice)); - if (device) { - SDL_memset(device, 0, (sizeof *device)); - device->hidden = (struct SDL_PrivateVideoData *) - SDL_malloc((sizeof *device->hidden)); - device->gl_data = (struct SDL_PrivateGLData *) - SDL_malloc((sizeof *device->gl_data)); - } - if ((device == NULL) || (device->hidden == NULL) || - (device->gl_data == NULL)) { - SDL_OutOfMemory(); - X11_DeleteDevice(device); /* calls SDL_X11_UnloadSymbols(). */ - return (0); - } - SDL_memset(device->hidden, 0, (sizeof *device->hidden)); - SDL_memset(device->gl_data, 0, (sizeof *device->gl_data)); - - /* Set the driver flags */ - device->handles_any_size = 1; - - /* Set the function pointers */ - device->VideoInit = X11_VideoInit; - device->SetVideoMode = X11_SetVideoMode; - device->ToggleFullScreen = X11_ToggleFullScreen; - device->UpdateMouse = X11_UpdateMouse; -#if SDL_VIDEO_DRIVER_X11_XV - device->CreateYUVOverlay = X11_CreateYUVOverlay; -#endif - device->SetColors = X11_SetColors; - device->UpdateRects = NULL; - device->VideoQuit = X11_VideoQuit; - device->AllocHWSurface = X11_AllocHWSurface; - device->CheckHWBlit = NULL; - device->FillHWRect = NULL; - device->SetHWColorKey = NULL; - device->SetHWAlpha = NULL; - device->LockHWSurface = X11_LockHWSurface; - device->UnlockHWSurface = X11_UnlockHWSurface; - device->FlipHWSurface = X11_FlipHWSurface; - device->FreeHWSurface = X11_FreeHWSurface; - device->SetGamma = X11_SetVidModeGamma; - device->GetGamma = X11_GetVidModeGamma; - device->SetGammaRamp = X11_SetGammaRamp; - device->GetGammaRamp = NULL; -#if SDL_VIDEO_OPENGL_GLX - device->GL_LoadLibrary = X11_GL_LoadLibrary; - device->GL_GetProcAddress = X11_GL_GetProcAddress; - device->GL_GetAttribute = X11_GL_GetAttribute; - device->GL_MakeCurrent = X11_GL_MakeCurrent; - device->GL_SwapBuffers = X11_GL_SwapBuffers; -#endif - device->SetCaption = X11_SetCaption; - device->SetIcon = X11_SetIcon; - device->IconifyWindow = X11_IconifyWindow; - device->GrabInput = X11_GrabInput; - device->GetWMInfo = X11_GetWMInfo; - device->FreeWMCursor = X11_FreeWMCursor; - device->CreateWMCursor = X11_CreateWMCursor; - device->ShowWMCursor = X11_ShowWMCursor; - device->WarpWMCursor = X11_WarpWMCursor; - device->CheckMouseMode = X11_CheckMouseMode; - device->InitOSKeymap = X11_InitOSKeymap; - device->PumpEvents = X11_PumpEvents; - - device->free = X11_DeleteDevice; - } - - return device; -} - -VideoBootStrap X11_bootstrap = { - "x11", "X Window System", - X11_Available, X11_CreateDevice -}; - -/* Normal X11 error handler routine */ -static int (*X_handler) (Display *, XErrorEvent *) = NULL; -static int -x_errhandler(Display * d, XErrorEvent * e) -{ -#if SDL_VIDEO_DRIVER_X11_VIDMODE - extern int vm_error; -#endif -#if SDL_VIDEO_DRIVER_X11_DGAMOUSE - extern int dga_error; -#endif - -#if SDL_VIDEO_DRIVER_X11_VIDMODE - /* VidMode errors are non-fatal. :) */ - /* Are the errors offset by one from the error base? - e.g. the error base is 143, the code is 148, and the - actual error is XF86VidModeExtensionDisabled (4) ? - */ - if ((vm_error >= 0) && - (((e->error_code == BadRequest) && (e->request_code == vm_error)) || - ((e->error_code > vm_error) && - (e->error_code <= (vm_error + XF86VidModeNumberErrors))))) { -#ifdef X11_DEBUG - { - char errmsg[1024]; - XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg)); - printf("VidMode error: %s\n", errmsg); - } -#endif - return (0); - } -#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ - -#if SDL_VIDEO_DRIVER_X11_DGAMOUSE - /* DGA errors can be non-fatal. :) */ - if ((dga_error >= 0) && - ((e->error_code > dga_error) && - (e->error_code <= (dga_error + XF86DGANumberErrors)))) { -#ifdef X11_DEBUG - { - char errmsg[1024]; - XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg)); - printf("DGA error: %s\n", errmsg); - } -#endif - return (0); - } -#endif /* SDL_VIDEO_DRIVER_X11_DGAMOUSE */ - - return (X_handler(d, e)); -} - -/* X11 I/O error handler routine */ -static int (*XIO_handler) (Display *) = NULL; -static int -xio_errhandler(Display * d) -{ - /* Ack! Lost X11 connection! */ - - /* We will crash if we try to clean up our display */ - if (current_video->hidden->Ximage) { - SDL_VideoSurface->pixels = NULL; - } - current_video->hidden->X11_Display = NULL; - - /* Continue with the standard X11 error handler */ - return (XIO_handler(d)); -} - -static int (*Xext_handler) (Display *, _Xconst char *, _Xconst char *) = NULL; -static int -xext_errhandler(Display * d, _Xconst char *ext, _Xconst char *reason) -{ -#ifdef X11_DEBUG - printf("Xext error inside SDL (may be harmless):\n"); - printf(" Extension \"%s\" %s on display \"%s\".\n", - ext, reason, XDisplayString(d)); -#endif - - if (SDL_strcmp(reason, "missing") == 0) { - /* - * Since the query itself, elsewhere, can handle a missing extension - * and the default behaviour in Xlib is to write to stderr, which - * generates unnecessary bug reports, we just ignore these. - */ - return 0; - } - - /* Everything else goes to the default handler... */ - return Xext_handler(d, ext, reason); -} - -/* Find out what class name we should use */ -static char * -get_classname(char *classname, int maxlen) -{ - char *spot; -#if defined(__LINUX__) || defined(__FREEBSD__) - char procfile[1024]; - char linkfile[1024]; - int linksize; -#endif - - /* First allow environment variable override */ - spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS"); - if (spot) { - SDL_strlcpy(classname, spot, maxlen); - return classname; - } - - /* Next look at the application's executable name */ -#if defined(__LINUX__) || defined(__FREEBSD__) -#if defined(__LINUX__) - SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid()); -#elif defined(__FREEBSD__) - SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file", - getpid()); -#else -#error Where can we find the executable name? -#endif - linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1); - if (linksize > 0) { - linkfile[linksize] = '\0'; - spot = SDL_strrchr(linkfile, '/'); - if (spot) { - SDL_strlcpy(classname, spot + 1, maxlen); - } else { - SDL_strlcpy(classname, linkfile, maxlen); - } - return classname; - } -#endif /* __LINUX__ */ - - /* Finally use the default we've used forever */ - SDL_strlcpy(classname, "SDL_App", maxlen); - return classname; -} - -/* Create auxiliary (toplevel) windows with the current visual */ -static void -create_aux_windows(_THIS) -{ - int x = 0, y = 0; - char classname[1024]; - XSetWindowAttributes xattr; - XWMHints *hints; - int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen)); - - /* Look up some useful Atoms */ - WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False); - - /* Don't create any extra windows if we are being managed */ - if (SDL_windowid) { - FSwindow = 0; - WMwindow = SDL_strtol(SDL_windowid, NULL, 0); - return; - } - - if (FSwindow) - XDestroyWindow(SDL_Display, FSwindow); - -#if SDL_VIDEO_DRIVER_X11_XINERAMA - if (use_xinerama) { - x = xinerama[this->current_display].x_org; - y = xinerama[this->current_display].y_org; - } -#endif - xattr.override_redirect = True; - xattr.background_pixel = - def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0; - xattr.border_pixel = 0; - xattr.colormap = SDL_XColorMap; - - FSwindow = XCreateWindow(SDL_Display, SDL_Root, - x, y, 32, 32, 0, - this->hidden->depth, InputOutput, SDL_Visual, - CWOverrideRedirect | CWBackPixel | CWBorderPixel - | CWColormap, &xattr); - - XSelectInput(SDL_Display, FSwindow, StructureNotifyMask); - - /* Tell KDE to keep the fullscreen window on top */ - { - XEvent ev; - long mask; - - SDL_memset(&ev, 0, sizeof(ev)); - ev.xclient.type = ClientMessage; - ev.xclient.window = SDL_Root; - ev.xclient.message_type = XInternAtom(SDL_Display, - "KWM_KEEP_ON_TOP", False); - ev.xclient.format = 32; - ev.xclient.data.l[0] = FSwindow; - ev.xclient.data.l[1] = CurrentTime; - mask = SubstructureRedirectMask; - XSendEvent(SDL_Display, SDL_Root, False, mask, &ev); - } - - hints = NULL; - if (WMwindow) { - /* All window attributes must survive the recreation */ - hints = XGetWMHints(SDL_Display, WMwindow); - XDestroyWindow(SDL_Display, WMwindow); - } - - /* Create the window for windowed management */ - /* (reusing the xattr structure above) */ - WMwindow = XCreateWindow(SDL_Display, SDL_Root, - x, y, 32, 32, 0, - this->hidden->depth, InputOutput, SDL_Visual, - CWBackPixel | CWBorderPixel | CWColormap, - &xattr); - - /* Set the input hints so we get keyboard input */ - if (!hints) { - hints = XAllocWMHints(); - hints->input = True; - hints->flags = InputHint; - } - XSetWMHints(SDL_Display, WMwindow, hints); - XFree(hints); - X11_SetCaptionNoLock(this, SDL_CurrentWindow.wm_title, - SDL_CurrentWindow.wm_icon); - - XSelectInput(SDL_Display, WMwindow, - FocusChangeMask | KeyPressMask | KeyReleaseMask - | PropertyChangeMask | StructureNotifyMask | - KeymapStateMask); - - /* Set the class hints so we can get an icon (AfterStep) */ - get_classname(classname, sizeof(classname)); - { - XClassHint *classhints; - classhints = XAllocClassHint(); - if (classhints != NULL) { - classhints->res_name = classname; - classhints->res_class = classname; - XSetClassHint(SDL_Display, WMwindow, classhints); - XFree(classhints); - } - } - - /* Setup the communication with the IM server */ - SDL_IM = NULL; - SDL_IC = NULL; - -#ifdef X_HAVE_UTF8_STRING - if (SDL_X11_HAVE_UTF8) { - SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname); - if (SDL_IM == NULL) { - SDL_SetError("no input method could be opened"); - } else { - SDL_IC = pXCreateIC(SDL_IM, - XNClientWindow, WMwindow, - XNFocusWindow, WMwindow, - XNInputStyle, - XIMPreeditNothing | XIMStatusNothing, - XNResourceName, classname, - XNResourceClass, classname, NULL); - - if (SDL_IC == NULL) { - SDL_SetError("no input context could be created"); - XCloseIM(SDL_IM); - SDL_IM = NULL; - } - } - } -#endif - - /* Allow the window to be deleted by the window manager */ - XSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1); -} - -static int -X11_VideoInit(_THIS) -{ - char *display; - int i; - SDL_DisplayMode desktop_mode; - - /* Open the X11 display */ - display = NULL; /* Get it from DISPLAY environment variable */ - - if ((SDL_strncmp(XDisplayName(display), ":", 1) == 0) || - (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0)) { - local_X11 = 1; - } else { - local_X11 = 0; - } - SDL_Display = XOpenDisplay(display); -#if defined(__osf__) && defined(SDL_VIDEO_DRIVER_X11_DYNAMIC) - /* On Tru64 if linking without -lX11, it fails and you get following message. - * Xlib: connection to ":0.0" refused by server - * Xlib: XDM authorization key matches an existing client! - * - * It succeeds if retrying 1 second later - * or if running xhost +localhost on shell. - * - */ - if (SDL_Display == NULL) { - SDL_Delay(1000); - SDL_Display = XOpenDisplay(display); - } -#endif - if (SDL_Display == NULL) { - SDL_SetError("Couldn't open X11 display"); - return (-1); - } -#ifdef X11_DEBUG - XSynchronize(SDL_Display, True); -#endif - - /* Create an alternate X display for graphics updates -- allows us - to do graphics updates in a separate thread from event handling. - Thread-safe X11 doesn't seem to exist. - */ - GFX_Display = XOpenDisplay(display); - if (GFX_Display == NULL) { - SDL_SetError("Couldn't open X11 display"); - return (-1); - } - - /* Set the normal X error handler */ - X_handler = XSetErrorHandler(x_errhandler); - - /* Set the error handler if we lose the X display */ - XIO_handler = XSetIOErrorHandler(xio_errhandler); - - /* Set the X extension error handler */ - Xext_handler = XSetExtensionErrorHandler(xext_errhandler); - - /* use default screen (from $DISPLAY) */ - SDL_Screen = DefaultScreen(SDL_Display); - -#ifndef NO_SHARED_MEMORY - /* Check for MIT shared memory extension */ - use_mitshm = 0; - if (local_X11) { - use_mitshm = XShmQueryExtension(SDL_Display); - } -#endif /* NO_SHARED_MEMORY */ - - /* Get the available visuals */ - if (X11_GetVisuals(this) < 0) - return -1; - - /* Determine the default screen mode: - Use the default visual (or at least one with the same depth) */ - SDL_DisplayColormap = DefaultColormap(SDL_Display, SDL_Screen); - for (i = 0; i < this->hidden->nvisuals; i++) - if (this->hidden->visuals[i].depth == DefaultDepth(SDL_Display, - SDL_Screen)) - break; - if (i == this->hidden->nvisuals) { - /* default visual was useless, take the deepest one instead */ - i = 0; - } - SDL_Visual = this->hidden->visuals[i].visual; - if (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen)) { - SDL_XColorMap = SDL_DisplayColormap; - } else { - SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, - SDL_Visual, AllocNone); - } - desktop_mode.format = - X11_VisualToFormat(this->hidden->visuals[i].visual, - this->hidden->visuals[i].depth, - this->hidden->visuals[i].bpp); - desktop_mode.w = DisplayWidth(SDL_Display, SDL_Screen); - desktop_mode.h = DisplayHeight(SDL_Display, SDL_Screen); - desktop_mode.refresh_rate = 0; - SDL_AddVideoDisplay(&desktop_mode); - - /* Get the available video modes */ - if (X11_GetVideoModes(this) < 0) - return -1; - - X11_SaveVidModeGamma(this); - - /* Save DPMS and screensaver settings */ - X11_SaveScreenSaver(SDL_Display, &screensaver_timeout, &dpms_enabled); - X11_DisableScreenSaver(SDL_Display); - - /* See if we have been passed a window to use */ - SDL_windowid = SDL_getenv("SDL_WINDOWID"); - - /* Create the fullscreen and managed windows */ - create_aux_windows(this); - - /* Create the blank cursor */ - SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask, - BLANK_CWIDTH, BLANK_CHEIGHT, - BLANK_CHOTX, BLANK_CHOTY); - - /* Fill in some window manager capabilities */ - this->info.wm_available = 1; - - /* We're done! */ - XFlush(SDL_Display); - return (0); -} - -static void -X11_DestroyWindow(_THIS, SDL_Surface * screen) -{ - /* Clean up OpenGL */ - if (screen) { - screen->flags &= ~SDL_INTERNALOPENGL; - } - X11_GL_Shutdown(this); - - if (!SDL_windowid) { - /* Hide the managed window */ - if (WMwindow) { - XUnmapWindow(SDL_Display, WMwindow); - } - if (screen && (screen->flags & SDL_FULLSCREEN)) { - screen->flags &= ~SDL_FULLSCREEN; - X11_LeaveFullScreen(this); - } - - /* Destroy the output window */ - if (SDL_Window) { - XDestroyWindow(SDL_Display, SDL_Window); - } - - /* Free the colormap entries */ - if (SDL_XPixels) { - int numcolors; - unsigned long pixel; - numcolors = SDL_Visual->map_entries; - for (pixel = 0; pixel < numcolors; ++pixel) { - while (SDL_XPixels[pixel] > 0) { - XFreeColors(GFX_Display, - SDL_DisplayColormap, &pixel, 1, 0); - --SDL_XPixels[pixel]; - } - } - SDL_free(SDL_XPixels); - SDL_XPixels = NULL; - } - - /* Free the graphics context */ - if (SDL_GC) { - XFreeGC(SDL_Display, SDL_GC); - SDL_GC = 0; - } - } -} - -static SDL_bool -X11_WindowPosition(_THIS, int *x, int *y, int w, int h) -{ - const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); - const char *center = SDL_getenv("SDL_VIDEO_CENTERED"); - if (window) { - if (SDL_sscanf(window, "%d,%d", x, y) == 2) { - return SDL_TRUE; - } - if (SDL_strcmp(window, "center") == 0) { - center = window; - } - } - if (center) { - *x = (DisplayWidth(SDL_Display, SDL_Screen) - w) / 2; - *y = (DisplayHeight(SDL_Display, SDL_Screen) - h) / 2; - return SDL_TRUE; - } - return SDL_FALSE; -} - -static void -X11_SetSizeHints(_THIS, int w, int h, Uint32 flags) -{ - XSizeHints *hints; - - hints = XAllocSizeHints(); - if (hints) { - if (flags & SDL_RESIZABLE) { - hints->min_width = 32; - hints->min_height = 32; - hints->max_height = 4096; - hints->max_width = 4096; - } else { - hints->min_width = hints->max_width = w; - hints->min_height = hints->max_height = h; - } - hints->flags = PMaxSize | PMinSize; - if (flags & SDL_FULLSCREEN) { - hints->x = 0; - hints->y = 0; - hints->flags |= USPosition; - } else - /* Center it, if desired */ - if (X11_WindowPosition(this, &hints->x, &hints->y, w, h)) { - hints->flags |= USPosition; - XMoveWindow(SDL_Display, WMwindow, hints->x, hints->y); - - /* Flush the resize event so we don't catch it later */ - XSync(SDL_Display, True); - } - XSetWMNormalHints(SDL_Display, WMwindow, hints); - XFree(hints); - } - - /* Respect the window caption style */ - if (flags & SDL_NOFRAME) { - SDL_bool set; - Atom WM_HINTS; - - /* We haven't modified the window manager hints yet */ - set = SDL_FALSE; - - /* First try to set MWM hints */ - WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True); - if (WM_HINTS != None) { - /* Hints used by Motif compliant window managers */ - struct - { - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long input_mode; - unsigned long status; - } MWMHints = { - (1L << 1), 0, 0, 0, 0}; - - XChangeProperty(SDL_Display, WMwindow, - WM_HINTS, WM_HINTS, 32, - PropModeReplace, - (unsigned char *) &MWMHints, - sizeof(MWMHints) / sizeof(long)); - set = SDL_TRUE; - } - /* Now try to set KWM hints */ - WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True); - if (WM_HINTS != None) { - long KWMHints = 0; - - XChangeProperty(SDL_Display, WMwindow, - WM_HINTS, WM_HINTS, 32, - PropModeReplace, - (unsigned char *) &KWMHints, - sizeof(KWMHints) / sizeof(long)); - set = SDL_TRUE; - } - /* Now try to set GNOME hints */ - WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True); - if (WM_HINTS != None) { - long GNOMEHints = 0; - - XChangeProperty(SDL_Display, WMwindow, - WM_HINTS, WM_HINTS, 32, - PropModeReplace, - (unsigned char *) &GNOMEHints, - sizeof(GNOMEHints) / sizeof(long)); - set = SDL_TRUE; - } - /* Finally set the transient hints if necessary */ - if (!set) { - XSetTransientForHint(SDL_Display, WMwindow, SDL_Root); - } - } else { - SDL_bool set; - Atom WM_HINTS; - - /* We haven't modified the window manager hints yet */ - set = SDL_FALSE; - - /* First try to unset MWM hints */ - WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True); - if (WM_HINTS != None) { - XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); - set = SDL_TRUE; - } - /* Now try to unset KWM hints */ - WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True); - if (WM_HINTS != None) { - XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); - set = SDL_TRUE; - } - /* Now try to unset GNOME hints */ - WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True); - if (WM_HINTS != None) { - XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); - set = SDL_TRUE; - } - /* Finally unset the transient hints if necessary */ - if (!set) { - /* NOTE: Does this work? */ - XSetTransientForHint(SDL_Display, WMwindow, None); - } - } -} - -static int -X11_CreateWindow(_THIS, SDL_Surface * screen, - const SDL_DisplayMode * mode, Uint32 flags) -{ - int i, depth; - Visual *vis; - int vis_change; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - - SDL_PixelFormatEnumToMasks(mode->format, &bpp, &Rmask, &Gmask, &Bmask, - &Amask); - - /* If a window is already present, destroy it and start fresh */ - if (SDL_Window) { - X11_DestroyWindow(this, screen); - switch_waiting = 0; /* Prevent jump back to now-meaningless state. */ - } - - /* See if we have been given a window id */ - if (SDL_windowid) { - SDL_Window = SDL_strtol(SDL_windowid, NULL, 0); - } else { - SDL_Window = 0; - } - - /* find out which visual we are going to use */ - if (flags & SDL_INTERNALOPENGL) { - XVisualInfo *vi; - - vi = X11_GL_GetVisual(this); - if (!vi) { - return -1; - } - vis = vi->visual; - depth = vi->depth; - } else if (SDL_windowid) { - XWindowAttributes a; - - XGetWindowAttributes(SDL_Display, SDL_Window, &a); - vis = a.visual; - depth = a.depth; - } else { - for (i = 0; i < this->hidden->nvisuals; i++) { - if (this->hidden->visuals[i].bpp == bpp && - this->hidden->visuals[i].visual->red_mask == Rmask && - this->hidden->visuals[i].visual->green_mask == Gmask && - this->hidden->visuals[i].visual->blue_mask == Bmask) - break; - } - if (i == this->hidden->nvisuals) { - SDL_SetError("No matching visual for requested depth"); - return -1; /* should never happen */ - } - vis = this->hidden->visuals[i].visual; - depth = this->hidden->visuals[i].depth; - } -#ifdef X11_DEBUG - printf("Choosing %s visual at %d bpp - %d colormap entries\n", - vis->class == PseudoColor ? "PseudoColor" : (vis->class == - TrueColor ? - "TrueColor" : (vis-> - class - == - DirectColor - ? - "DirectColor" - : - "Unknown")), - depth, vis->map_entries); -#endif - vis_change = (vis != SDL_Visual); - SDL_Visual = vis; - this->hidden->depth = depth; - - /* Allocate the new pixel format for this video mode */ - if (!SDL_ReallocFormat(screen, bpp, Rmask, Gmask, Bmask, Amask)) { - return -1; - } - - /* Create the appropriate colormap */ - if (SDL_XColorMap != SDL_DisplayColormap) { - XFreeColormap(SDL_Display, SDL_XColorMap); - } - if (SDL_Visual->class == PseudoColor) { - int ncolors; - - /* Allocate the pixel flags */ - ncolors = SDL_Visual->map_entries; - SDL_XPixels = SDL_malloc(ncolors * sizeof(int)); - if (SDL_XPixels == NULL) { - SDL_OutOfMemory(); - return -1; - } - SDL_memset(SDL_XPixels, 0, ncolors * sizeof(*SDL_XPixels)); - - /* always allocate a private colormap on non-default visuals */ - if (SDL_Visual != DefaultVisual(SDL_Display, SDL_Screen)) { - flags |= SDL_HWPALETTE; - } - if (flags & SDL_HWPALETTE) { - screen->flags |= SDL_HWPALETTE; - SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, - SDL_Visual, AllocAll); - } else { - SDL_XColorMap = SDL_DisplayColormap; - } - } else if (SDL_Visual->class == DirectColor) { - - /* Create a colormap which we can manipulate for gamma */ - SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, - SDL_Visual, AllocAll); - XSync(SDL_Display, False); - - /* Initialize the colormap to the identity mapping */ - SDL_GetGammaRamp(0, 0, 0); - SDL_VideoSurface = screen; - X11_SetGammaRamp(this, SDL_CurrentWindow.gamma); - SDL_VideoSurface = NULL; - } else { - /* Create a read-only colormap for our window */ - SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, - SDL_Visual, AllocNone); - } - - /* Recreate the auxiliary windows, if needed (required for GL) */ - if (vis_change) - create_aux_windows(this); - - if (screen->flags & SDL_HWPALETTE) { - /* Since the full-screen window might have got a nonzero background - colour (0 is white on some displays), we should reset the - background to 0 here since that is what the user expects - with a private colormap */ - XSetWindowBackground(SDL_Display, FSwindow, 0); - XClearWindow(SDL_Display, FSwindow); - } - - /* resize the (possibly new) window manager window */ - if (!SDL_windowid) { - X11_SetSizeHints(this, mode->w, mode->h, flags); - window_w = mode->w; - window_h = mode->h; - XResizeWindow(SDL_Display, WMwindow, mode->w, mode->h); - } - - /* Create (or use) the X11 display window */ - if (!SDL_windowid) { - if (flags & SDL_INTERNALOPENGL) { - if (X11_GL_CreateWindow(this, mode->w, mode->h) < 0) { - return (-1); - } - } else { - XSetWindowAttributes swa; - - swa.background_pixel = 0; - swa.border_pixel = 0; - swa.colormap = SDL_XColorMap; - SDL_Window = XCreateWindow(SDL_Display, WMwindow, - 0, 0, mode->w, mode->h, 0, depth, - InputOutput, SDL_Visual, - CWBackPixel | CWBorderPixel - | CWColormap, &swa); - } - /* Only manage our input if we own the window */ - XSelectInput(SDL_Display, SDL_Window, - (EnterWindowMask | LeaveWindowMask - | ButtonPressMask | ButtonReleaseMask - | PointerMotionMask | ExposureMask)); - } - /* Create the graphics context here, once we have a window */ - if (flags & SDL_INTERNALOPENGL) { - if (X11_GL_CreateContext(this) < 0) { - return (-1); - } else { - screen->flags |= SDL_INTERNALOPENGL; - } - } else { - XGCValues gcv; - - gcv.graphics_exposures = False; - SDL_GC = XCreateGC(SDL_Display, SDL_Window, - GCGraphicsExposures, &gcv); - if (!SDL_GC) { - SDL_SetError("Couldn't create graphics context"); - return (-1); - } - } - - /* Set our colormaps when not setting a GL mode */ - if (!(flags & SDL_INTERNALOPENGL)) { - XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap); - if (!SDL_windowid) { - XSetWindowColormap(SDL_Display, FSwindow, SDL_XColorMap); - XSetWindowColormap(SDL_Display, WMwindow, SDL_XColorMap); - } - } -#if 0 /* This is an experiment - are the graphics faster now? - nope. */ - if (SDL_getenv("SDL_VIDEO_X11_BACKINGSTORE")) -#endif - /* Cache the window in the server, when possible */ - { - Screen *xscreen; - XSetWindowAttributes a; - - xscreen = ScreenOfDisplay(SDL_Display, SDL_Screen); - a.backing_store = DoesBackingStore(xscreen); - if (a.backing_store != NotUseful) { - XChangeWindowAttributes(SDL_Display, SDL_Window, - CWBackingStore, &a); - } - } - - /* Update the internal keyboard state */ - X11_SetKeyboardState(SDL_Display, NULL); - - /* When the window is first mapped, ignore non-modifier keys */ - { - Uint8 *keys = SDL_GetKeyState(NULL); - for (i = 0; i < SDLK_LAST; ++i) { - switch (i) { - case SDLK_NUMLOCK: - case SDLK_CAPSLOCK: - case SDLK_LCTRL: - case SDLK_RCTRL: - case SDLK_LSHIFT: - case SDLK_RSHIFT: - case SDLK_LALT: - case SDLK_RALT: - case SDLK_LMETA: - case SDLK_RMETA: - case SDLK_MODE: - break; - default: - keys[i] = SDL_RELEASED; - break; - } - } - } - - /* Map them both and go fullscreen, if requested */ - if (!SDL_windowid) { - XMapWindow(SDL_Display, SDL_Window); - XMapWindow(SDL_Display, WMwindow); - X11_WaitMapped(this, WMwindow); - if (flags & SDL_FULLSCREEN) { - screen->flags |= SDL_FULLSCREEN; - X11_EnterFullScreen(this); - } else { - screen->flags &= ~SDL_FULLSCREEN; - } - } - - return (0); -} - -static int -X11_ResizeWindow(_THIS, SDL_Surface * screen, int w, int h, Uint32 flags) -{ - if (!SDL_windowid) { - /* Resize the window manager window */ - X11_SetSizeHints(this, w, h, flags); - window_w = w; - window_h = h; - XResizeWindow(SDL_Display, WMwindow, w, h); - - /* Resize the fullscreen and display windows */ - if (flags & SDL_FULLSCREEN) { - if (screen->flags & SDL_FULLSCREEN) { - X11_ResizeFullScreen(this); - } else { - screen->flags |= SDL_FULLSCREEN; - X11_EnterFullScreen(this); - } - } else { - if (screen->flags & SDL_FULLSCREEN) { - screen->flags &= ~SDL_FULLSCREEN; - X11_LeaveFullScreen(this); - } - } - XResizeWindow(SDL_Display, SDL_Window, w, h); - } - return (0); -} - -SDL_Surface * -X11_SetVideoMode(_THIS, SDL_Surface * current, - const SDL_DisplayMode * mode, Uint32 flags) -{ - Uint32 saved_flags; - - /* Lock the event thread, in multi-threading environments */ - SDL_Lock_EventThread(); - - /* Check the combination of flags we were passed */ - if (flags & SDL_FULLSCREEN) { - /* Clear fullscreen flag if not supported */ - if (SDL_windowid) { - flags &= ~SDL_FULLSCREEN; - } - } - - /* Flush any delayed updates */ - XSync(GFX_Display, False); - - /* Set up the X11 window */ - saved_flags = current->flags; - if ((SDL_Window) - && ((saved_flags & SDL_INTERNALOPENGL) == - (flags & SDL_INTERNALOPENGL)) - && (mode->format == SDL_CurrentDisplay.current_mode.format) - && ((saved_flags & SDL_NOFRAME) == (flags & SDL_NOFRAME))) { - if (X11_ResizeWindow(this, current, mode->w, mode->h, flags) < 0) { - current = NULL; - goto done; - } - } else { - if (X11_CreateWindow(this, current, mode, flags) < 0) { - current = NULL; - goto done; - } - } - - /* Set up the new mode framebuffer */ - if (((current->w != mode->w) || (current->h != mode->h)) || - ((saved_flags & SDL_INTERNALOPENGL) != (flags & SDL_INTERNALOPENGL))) - { - current->w = mode->w; - current->h = mode->h; - current->pitch = SDL_CalculatePitch(current); - X11_ResizeImage(this, current, flags); - } - current->flags |= (flags & (SDL_RESIZABLE | SDL_NOFRAME)); - - done: - /* Release the event thread */ - XSync(SDL_Display, False); - SDL_Unlock_EventThread(); - - /* We're done! */ - return (current); -} - -static int -X11_ToggleFullScreen(_THIS, int on) -{ - Uint32 event_thread; - - /* Don't switch if we don't own the window */ - if (SDL_windowid) { - return (0); - } - - /* Don't lock if we are the event thread */ - event_thread = SDL_EventThreadID(); - if (event_thread && (SDL_ThreadID() == event_thread)) { - event_thread = 0; - } - if (event_thread) { - SDL_Lock_EventThread(); - } - if (on) { - SDL_VideoSurface->flags |= SDL_FULLSCREEN; - X11_EnterFullScreen(this); - } else { - SDL_VideoSurface->flags &= ~SDL_FULLSCREEN; - X11_LeaveFullScreen(this); - } - X11_RefreshDisplay(this); - if (event_thread) { - SDL_Unlock_EventThread(); - } - SDL_ResetKeyboard(); - return (1); -} - -/* Update the current mouse state and position */ -static void -X11_UpdateMouse(_THIS) -{ - Window u1; - int u2; - Window current_win; - int x, y; - unsigned int mask; - - /* Lock the event thread, in multi-threading environments */ - SDL_Lock_EventThread(); - if (XQueryPointer(SDL_Display, SDL_Window, &u1, ¤t_win, - &u2, &u2, &x, &y, &mask)) { - if ((x >= 0) && (x < SDL_VideoSurface->w) && - (y >= 0) && (y < SDL_VideoSurface->h)) { - SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); - SDL_PrivateMouseMotion(0, 0, x, y); - } else { - SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - } - } - SDL_Unlock_EventThread(); -} - -/* simple colour distance metric. Supposed to be better than a plain - Euclidian distance anyway. */ -#define COLOUR_FACTOR 3 -#define LIGHT_FACTOR 1 -#define COLOUR_DIST(r1, g1, b1, r2, g2, b2) \ - (COLOUR_FACTOR * (abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2)) \ - + LIGHT_FACTOR * abs(r1 + g1 + b1 - (r2 + g2 + b2))) - -static void -allocate_nearest(_THIS, SDL_Color * colors, SDL_Color * want, int nwant) -{ - /* - * There is no way to know which ones to choose from, so we retrieve - * the entire colormap and try the nearest possible, until we find one - * that is shared. - */ - XColor all[256]; - int i; - for (i = 0; i < 256; i++) - all[i].pixel = i; - /* - * XQueryColors sets the flags in the XColor struct, so we use - * that to keep track of which colours are available - */ - XQueryColors(GFX_Display, SDL_XColorMap, all, 256); - - for (i = 0; i < nwant; i++) { - XColor *c; - int j; - int best = 0; - int mindist = 0x7fffffff; - int ri = want[i].r; - int gi = want[i].g; - int bi = want[i].b; - for (j = 0; j < 256; j++) { - int rj, gj, bj, d2; - if (!all[j].flags) - continue; /* unavailable colour cell */ - rj = all[j].red >> 8; - gj = all[j].green >> 8; - bj = all[j].blue >> 8; - d2 = COLOUR_DIST(ri, gi, bi, rj, gj, bj); - if (d2 < mindist) { - mindist = d2; - best = j; - } - } - if (SDL_XPixels[best]) - continue; /* already allocated, waste no more time */ - c = all + best; - if (XAllocColor(GFX_Display, SDL_XColorMap, c)) { - /* got it */ - colors[c->pixel].r = c->red >> 8; - colors[c->pixel].g = c->green >> 8; - colors[c->pixel].b = c->blue >> 8; - ++SDL_XPixels[c->pixel]; - } else { - /* - * The colour couldn't be allocated, probably being - * owned as a r/w cell by another client. Flag it as - * unavailable and try again. The termination of the - * loop is guaranteed since at least black and white - * are always there. - */ - c->flags = 0; - i--; - } - } -} - -int -X11_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors) -{ - int nrej = 0; - - /* Check to make sure we have a colormap allocated */ - if (SDL_XPixels == NULL) { - return (0); - } - if ((SDL_VideoSurface->flags & SDL_HWPALETTE) == SDL_HWPALETTE) { - /* private writable colormap: just set the colours we need */ - XColor *xcmap; - int i; - xcmap = SDL_stack_alloc(XColor, ncolors); - if (xcmap == NULL) - return 0; - for (i = 0; i < ncolors; ++i) { - xcmap[i].pixel = i + firstcolor; - xcmap[i].red = (colors[i].r << 8) | colors[i].r; - xcmap[i].green = (colors[i].g << 8) | colors[i].g; - xcmap[i].blue = (colors[i].b << 8) | colors[i].b; - xcmap[i].flags = (DoRed | DoGreen | DoBlue); - } - XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors); - XSync(GFX_Display, False); - SDL_stack_free(xcmap); - } else { - /* - * Shared colormap: We only allocate read-only cells, which - * increases the likelyhood of colour sharing with other - * clients. The pixel values will almost certainly be - * different from the requested ones, so the user has to - * walk the colormap and see which index got what colour. - * - * We can work directly with the logical palette since it - * has already been set when we get here. - */ - SDL_Color *want, *reject; - unsigned long *freelist; - int i; - int nfree = 0; - int nc = SDL_VideoSurface->format->palette->ncolors; - colors = SDL_VideoSurface->format->palette->colors; - freelist = SDL_stack_alloc(unsigned long, nc); - /* make sure multiple allocations of the same cell are freed */ - for (i = 0; i < ncolors; i++) { - int pixel = firstcolor + i; - while (SDL_XPixels[pixel]) { - freelist[nfree++] = pixel; - --SDL_XPixels[pixel]; - } - } - XFreeColors(GFX_Display, SDL_XColorMap, freelist, nfree, 0); - SDL_stack_free(freelist); - - want = SDL_stack_alloc(SDL_Color, ncolors); - reject = SDL_stack_alloc(SDL_Color, ncolors); - SDL_memcpy(want, colors + firstcolor, ncolors * sizeof(SDL_Color)); - /* make sure the user isn't fooled by her own wishes - (black is safe, always available in the default colormap) */ - SDL_memset(colors + firstcolor, 0, ncolors * sizeof(SDL_Color)); - - /* now try to allocate the colours */ - for (i = 0; i < ncolors; i++) { - XColor col; - col.red = want[i].r << 8; - col.green = want[i].g << 8; - col.blue = want[i].b << 8; - col.flags = DoRed | DoGreen | DoBlue; - if (XAllocColor(GFX_Display, SDL_XColorMap, &col)) { - /* We got the colour, or at least the nearest - the hardware could get. */ - colors[col.pixel].r = col.red >> 8; - colors[col.pixel].g = col.green >> 8; - colors[col.pixel].b = col.blue >> 8; - ++SDL_XPixels[col.pixel]; - } else { - /* - * no more free cells, add it to the list - * of rejected colours - */ - reject[nrej++] = want[i]; - } - } - if (nrej) - allocate_nearest(this, colors, reject, nrej); - SDL_stack_free(reject); - SDL_stack_free(want); - } - return nrej == 0; -} - -int -X11_SetGammaRamp(_THIS, Uint16 * ramp) -{ - int i, ncolors; - XColor xcmap[256]; - - /* See if actually setting the gamma is supported */ - if (SDL_Visual->class != DirectColor) { - SDL_SetError("Gamma correction not supported on this visual"); - return (-1); - } - - /* Calculate the appropriate palette for the given gamma ramp */ - ncolors = SDL_Visual->map_entries; - for (i = 0; i < ncolors; ++i) { - Uint8 c = (256 * i / ncolors); - xcmap[i].pixel = SDL_MapRGB(SDL_VideoSurface->format, c, c, c); - xcmap[i].red = ramp[0 * 256 + c]; - xcmap[i].green = ramp[1 * 256 + c]; - xcmap[i].blue = ramp[2 * 256 + c]; - xcmap[i].flags = (DoRed | DoGreen | DoBlue); - } - XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors); - XSync(GFX_Display, False); - return (0); -} - -/* Note: If we are terminated, this could be called in the middle of - another SDL video routine -- notably UpdateRects. -*/ -void -X11_VideoQuit(_THIS) -{ - /* Shutdown everything that's still up */ - /* The event thread should be done, so we can touch SDL_Display */ - if (SDL_Display != NULL) { - /* Flush any delayed updates */ - XSync(GFX_Display, False); - - /* Close the connection with the IM server */ -#ifdef X_HAVE_UTF8_STRING - if (SDL_IC != NULL) { - XDestroyIC(SDL_IC); - SDL_IC = NULL; - } - if (SDL_IM != NULL) { - XCloseIM(SDL_IM); - SDL_IM = NULL; - } -#endif - - /* Start shutting down the windows */ - X11_DestroyImage(this, SDL_VideoSurface); - X11_DestroyWindow(this, SDL_VideoSurface); - X11_FreeVideoModes(this); - if (SDL_XColorMap != SDL_DisplayColormap) { - XFreeColormap(SDL_Display, SDL_XColorMap); - } - if (SDL_iconcolors) { - unsigned long pixel; - Colormap dcmap = DefaultColormap(SDL_Display, - SDL_Screen); - for (pixel = 0; pixel < 256; ++pixel) { - while (SDL_iconcolors[pixel] > 0) { - XFreeColors(GFX_Display, dcmap, &pixel, 1, 0); - --SDL_iconcolors[pixel]; - } - } - SDL_free(SDL_iconcolors); - SDL_iconcolors = NULL; - } - if (xinerama) { - XFree(xinerama); - } - - /* Restore gamma settings if they've changed */ - if (SDL_GetAppState() & SDL_APPACTIVE) { - X11_SwapVidModeGamma(this); - } - - /* Restore DPMS and screensaver settings */ - X11_RestoreScreenSaver(SDL_Display, screensaver_timeout, - dpms_enabled); - - /* Free that blank cursor */ - if (SDL_BlankCursor != NULL) { - this->FreeWMCursor(this, SDL_BlankCursor); - SDL_BlankCursor = NULL; - } - - /* Close the X11 graphics connection */ - if (GFX_Display != NULL) { - XCloseDisplay(GFX_Display); - GFX_Display = NULL; - } - - /* Close the X11 display connection */ - XCloseDisplay(SDL_Display); - SDL_Display = NULL; - - /* Reset the X11 error handlers */ - if (XIO_handler) { - XSetIOErrorHandler(XIO_handler); - } - if (X_handler) { - XSetErrorHandler(X_handler); - } - - /* Unload GL library after X11 shuts down */ - X11_GL_UnloadLibrary(this); - } - if (SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_HWSURFACE)) { - /* Direct screen access, no memory buffer */ - SDL_VideoSurface->pixels = NULL; - } -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/x11/SDL_x11video.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11wm.c Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11wm_c.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11yuv.c Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */
--- a/src/video/x11/SDL_x11yuv_c.h Wed Jul 26 04:20:59 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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: */