PageRenderTime 58ms CodeModel.GetById 12ms app.highlight 41ms RepoModel.GetById 1ms app.codeStats 1ms

/project/jni/sdl-1.3/src/video/x11/SDL_x11video.c

https://github.com/aichunyu/FFPlayer
C | 399 lines | 298 code | 50 blank | 51 comment | 45 complexity | eb6544ecba998f5ab854310c0cbc12f1 MD5 | raw file
  1/*
  2  Simple DirectMedia Layer
  3  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
  4
  5  This software is provided 'as-is', without any express or implied
  6  warranty.  In no event will the authors be held liable for any damages
  7  arising from the use of this software.
  8
  9  Permission is granted to anyone to use this software for any purpose,
 10  including commercial applications, and to alter it and redistribute it
 11  freely, subject to the following restrictions:
 12
 13  1. The origin of this software must not be misrepresented; you must not
 14     claim that you wrote the original software. If you use this software
 15     in a product, an acknowledgment in the product documentation would be
 16     appreciated but is not required.
 17  2. Altered source versions must be plainly marked as such, and must not be
 18     misrepresented as being the original software.
 19  3. This notice may not be removed or altered from any source distribution.
 20*/
 21#include "SDL_config.h"
 22
 23#if SDL_VIDEO_DRIVER_X11
 24
 25#include <unistd.h> /* For getpid() and readlink() */
 26
 27#include "SDL_video.h"
 28#include "SDL_mouse.h"
 29#include "../SDL_sysvideo.h"
 30#include "../SDL_pixels_c.h"
 31
 32#include "SDL_x11video.h"
 33#include "SDL_x11framebuffer.h"
 34#include "SDL_x11shape.h"
 35#include "SDL_x11touch.h" 
 36
 37#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
 38#include "SDL_x11opengles.h"
 39#endif
 40
 41/* Initialization/Query functions */
 42static int X11_VideoInit(_THIS);
 43static void X11_VideoQuit(_THIS);
 44
 45/* Find out what class name we should use */
 46static char *
 47get_classname()
 48{
 49    char *spot;
 50#if defined(__LINUX__) || defined(__FREEBSD__)
 51    char procfile[1024];
 52    char linkfile[1024];
 53    int linksize;
 54#endif
 55
 56    /* First allow environment variable override */
 57    spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS");
 58    if (spot) {
 59        return SDL_strdup(spot);
 60    }
 61
 62    /* Next look at the application's executable name */
 63#if defined(__LINUX__) || defined(__FREEBSD__)
 64#if defined(__LINUX__)
 65    SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid());
 66#elif defined(__FREEBSD__)
 67    SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file",
 68                 getpid());
 69#else
 70#error Where can we find the executable name?
 71#endif
 72    linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
 73    if (linksize > 0) {
 74        linkfile[linksize] = '\0';
 75        spot = SDL_strrchr(linkfile, '/');
 76        if (spot) {
 77            return SDL_strdup(spot + 1);
 78        } else {
 79            return SDL_strdup(linkfile);
 80        }
 81    }
 82#endif /* __LINUX__ || __FREEBSD__ */
 83
 84    /* Finally use the default we've used forever */
 85    return SDL_strdup("SDL_App");
 86}
 87
 88/* X11 driver bootstrap functions */
 89
 90static int
 91X11_Available(void)
 92{
 93    Display *display = NULL;
 94    if (SDL_X11_LoadSymbols()) {
 95        display = XOpenDisplay(NULL);
 96        if (display != NULL) {
 97            XCloseDisplay(display);
 98        }
 99        SDL_X11_UnloadSymbols();
100    }
101    return (display != NULL);
102}
103
104static void
105X11_DeleteDevice(SDL_VideoDevice * device)
106{
107    SDL_VideoData *data = (SDL_VideoData *) device->driverdata;
108    if (data->display) {
109        XCloseDisplay(data->display);
110    }
111    SDL_free(data->windowlist);
112    SDL_free(device->driverdata);
113#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
114    SDL_free(device->gles_data);
115#endif
116    SDL_free(device);
117
118    SDL_X11_UnloadSymbols();
119}
120
121static SDL_VideoDevice *
122X11_CreateDevice(int devindex)
123{
124    SDL_VideoDevice *device;
125    SDL_VideoData *data;
126    const char *display = NULL; /* Use the DISPLAY environment variable */
127
128    if (!SDL_X11_LoadSymbols()) {
129        return NULL;
130    }
131
132    /* Initialize all variables that we clean on shutdown */
133    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
134    if (!device) {
135        SDL_OutOfMemory();
136        return NULL;
137    }
138    data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
139    if (!data) {
140        SDL_OutOfMemory();
141        SDL_free(device);
142        return NULL;
143    }
144    device->driverdata = data;
145
146#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
147    device->gles_data = (struct SDL_PrivateGLESData *) SDL_calloc(1, sizeof(SDL_PrivateGLESData));
148    if (!device->gles_data) {
149        SDL_OutOfMemory();
150        return NULL;
151    }
152#endif
153
154    /* FIXME: Do we need this?
155       if ( (SDL_strncmp(XDisplayName(display), ":", 1) == 0) ||
156       (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0) ) {
157       local_X11 = 1;
158       } else {
159       local_X11 = 0;
160       }
161     */
162    data->display = XOpenDisplay(display);
163#if defined(__osf__) && defined(SDL_VIDEO_DRIVER_X11_DYNAMIC)
164    /* On Tru64 if linking without -lX11, it fails and you get following message.
165     * Xlib: connection to ":0.0" refused by server
166     * Xlib: XDM authorization key matches an existing client!
167     *
168     * It succeeds if retrying 1 second later
169     * or if running xhost +localhost on shell.
170     */
171    if (data->display == NULL) {
172        SDL_Delay(1000);
173        data->display = XOpenDisplay(display);
174    }
175#endif
176    if (data->display == NULL) {
177        SDL_free(device);
178        SDL_SetError("Couldn't open X11 display");
179        return NULL;
180    }
181#ifdef X11_DEBUG
182    XSynchronize(data->display, True);
183#endif
184
185    /* Set the function pointers */
186    device->VideoInit = X11_VideoInit;
187    device->VideoQuit = X11_VideoQuit;
188    device->GetDisplayModes = X11_GetDisplayModes;
189    device->SetDisplayMode = X11_SetDisplayMode;
190    device->SuspendScreenSaver = X11_SuspendScreenSaver;
191    device->PumpEvents = X11_PumpEvents;
192
193    device->CreateWindow = X11_CreateWindow;
194    device->CreateWindowFrom = X11_CreateWindowFrom;
195    device->SetWindowTitle = X11_SetWindowTitle;
196    device->SetWindowIcon = X11_SetWindowIcon;
197    device->SetWindowPosition = X11_SetWindowPosition;
198    device->SetWindowSize = X11_SetWindowSize;
199    device->ShowWindow = X11_ShowWindow;
200    device->HideWindow = X11_HideWindow;
201    device->RaiseWindow = X11_RaiseWindow;
202    device->MaximizeWindow = X11_MaximizeWindow;
203    device->MinimizeWindow = X11_MinimizeWindow;
204    device->RestoreWindow = X11_RestoreWindow;
205    device->SetWindowFullscreen = X11_SetWindowFullscreen;
206    device->SetWindowGammaRamp = X11_SetWindowGammaRamp;
207    device->SetWindowGrab = X11_SetWindowGrab;
208    device->DestroyWindow = X11_DestroyWindow;
209    device->CreateWindowFramebuffer = X11_CreateWindowFramebuffer;
210    device->UpdateWindowFramebuffer = X11_UpdateWindowFramebuffer;
211    device->DestroyWindowFramebuffer = X11_DestroyWindowFramebuffer;
212    device->GetWindowWMInfo = X11_GetWindowWMInfo;
213
214    device->shape_driver.CreateShaper = X11_CreateShaper;
215    device->shape_driver.SetWindowShape = X11_SetWindowShape;
216    device->shape_driver.ResizeWindowShape = X11_ResizeWindowShape;
217
218#if SDL_VIDEO_OPENGL_GLX
219    device->GL_LoadLibrary = X11_GL_LoadLibrary;
220    device->GL_GetProcAddress = X11_GL_GetProcAddress;
221    device->GL_UnloadLibrary = X11_GL_UnloadLibrary;
222    device->GL_CreateContext = X11_GL_CreateContext;
223    device->GL_MakeCurrent = X11_GL_MakeCurrent;
224    device->GL_SetSwapInterval = X11_GL_SetSwapInterval;
225    device->GL_GetSwapInterval = X11_GL_GetSwapInterval;
226    device->GL_SwapWindow = X11_GL_SwapWindow;
227    device->GL_DeleteContext = X11_GL_DeleteContext;
228#endif
229#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
230    device->GL_LoadLibrary = X11_GLES_LoadLibrary;
231    device->GL_GetProcAddress = X11_GLES_GetProcAddress;
232    device->GL_UnloadLibrary = X11_GLES_UnloadLibrary;
233    device->GL_CreateContext = X11_GLES_CreateContext;
234    device->GL_MakeCurrent = X11_GLES_MakeCurrent;
235    device->GL_SetSwapInterval = X11_GLES_SetSwapInterval;
236    device->GL_GetSwapInterval = X11_GLES_GetSwapInterval;
237    device->GL_SwapWindow = X11_GLES_SwapWindow;
238    device->GL_DeleteContext = X11_GLES_DeleteContext;
239#endif
240
241    device->SetClipboardText = X11_SetClipboardText;
242    device->GetClipboardText = X11_GetClipboardText;
243    device->HasClipboardText = X11_HasClipboardText;
244
245    device->free = X11_DeleteDevice;
246
247    return device;
248}
249
250VideoBootStrap X11_bootstrap = {
251    "x11", "SDL X11 video driver",
252    X11_Available, X11_CreateDevice
253};
254
255static int (*handler) (Display *, XErrorEvent *) = NULL;
256static int
257X11_CheckWindowManagerErrorHandler(Display * d, XErrorEvent * e)
258{
259    if (e->error_code == BadWindow) {
260        return (0);
261    } else {
262        return (handler(d, e));
263    }
264}
265
266static void
267X11_CheckWindowManager(_THIS)
268{
269    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
270    Display *display = data->display;
271    Atom _NET_SUPPORTING_WM_CHECK;
272    int status, real_format;
273    Atom real_type;
274    unsigned long items_read, items_left;
275    unsigned char *propdata;
276    Window wm_window = 0;
277#ifdef DEBUG_WINDOW_MANAGER
278    char *wm_name;
279#endif
280
281    /* Set up a handler to gracefully catch errors */
282    XSync(display, False);
283    handler = XSetErrorHandler(X11_CheckWindowManagerErrorHandler);
284
285    _NET_SUPPORTING_WM_CHECK = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False);
286    status = XGetWindowProperty(display, DefaultRootWindow(display), _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
287    if (status == Success && items_read) {
288        wm_window = ((Window*)propdata)[0];
289    }
290    if (propdata) {
291        XFree(propdata);
292    }
293
294    if (wm_window) {
295        status = XGetWindowProperty(display, wm_window, _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
296        if (status != Success || !items_read || wm_window != ((Window*)propdata)[0]) {
297            wm_window = None;
298        }
299        if (propdata) {
300            XFree(propdata);
301        }
302    }
303
304    /* Reset the error handler, we're done checking */
305    XSync(display, False);
306    XSetErrorHandler(handler);
307
308    if (!wm_window) {
309#ifdef DEBUG_WINDOW_MANAGER
310        printf("Couldn't get _NET_SUPPORTING_WM_CHECK property\n");
311#endif
312        return;
313    }
314    data->net_wm = SDL_TRUE;
315
316#ifdef DEBUG_WINDOW_MANAGER
317    wm_name = X11_GetWindowTitle(_this, wm_window);
318    printf("Window manager: %s\n", wm_name);
319    SDL_free(wm_name);
320#endif
321}
322
323int
324X11_VideoInit(_THIS)
325{
326    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
327
328    /* Get the window class name, usually the name of the application */
329    data->classname = get_classname();
330
331    /* Get the process PID to be associated to the window */
332    data->pid = getpid();
333
334    /* Open a connection to the X input manager */
335#ifdef X_HAVE_UTF8_STRING
336    if (SDL_X11_HAVE_UTF8) {
337        data->im =
338            XOpenIM(data->display, NULL, data->classname, data->classname);
339    }
340#endif
341
342    /* Look up some useful Atoms */
343#define GET_ATOM(X) data->X = XInternAtom(data->display, #X, False)
344    GET_ATOM(WM_DELETE_WINDOW);
345    GET_ATOM(_NET_WM_STATE);
346    GET_ATOM(_NET_WM_STATE_HIDDEN);
347    GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
348    GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
349    GET_ATOM(_NET_WM_STATE_FULLSCREEN);
350    GET_ATOM(_NET_WM_NAME);
351    GET_ATOM(_NET_WM_ICON_NAME);
352    GET_ATOM(_NET_WM_ICON);
353    GET_ATOM(UTF8_STRING);
354
355    /* Detect the window manager */
356    X11_CheckWindowManager(_this);
357
358    if (X11_InitModes(_this) < 0) {
359        return -1;
360    }
361
362    if (X11_InitKeyboard(_this) != 0) {
363        return -1;
364    }
365    X11_InitMouse(_this);
366
367    X11_InitTouch(_this);
368    return 0;
369}
370
371void
372X11_VideoQuit(_THIS)
373{
374    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
375
376    if (data->classname) {
377        SDL_free(data->classname);
378    }
379#ifdef X_HAVE_UTF8_STRING
380    if (data->im) {
381        XCloseIM(data->im);
382    }
383#endif
384
385    X11_QuitModes(_this);
386    X11_QuitKeyboard(_this);
387    X11_QuitMouse(_this);
388    X11_QuitTouch(_this);
389}
390
391SDL_bool
392X11_UseDirectColorVisuals(void)
393{
394    return SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ? SDL_FALSE : SDL_TRUE;
395}
396
397#endif /* SDL_VIDEO_DRIVER_X11 */
398
399/* vim: set ts=4 sw=4 expandtab: */