Initial work on X11 window code in.
authorSam Lantinga <slouken@libsdl.org>
Thu, 27 Jul 2006 06:53:23 +0000
changeset 19517177581dc9fa
parent 1950 a344e42bce3b
child 1952 420716272158
Initial work on X11 window code in.
src/video/cocoa/SDL_cocoawindow.h
src/video/cocoa/SDL_cocoawindow.m
src/video/win32/SDL_win32events.c
src/video/win32/SDL_win32window.c
src/video/win32/SDL_win32window.h
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11events.h
src/video/x11/SDL_x11modes.c
src/video/x11/SDL_x11modes.h
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
src/video/x11/SDL_x11window.c
src/video/x11/SDL_x11window.h
     1.1 --- a/src/video/cocoa/SDL_cocoawindow.h	Wed Jul 26 06:34:54 2006 +0000
     1.2 +++ b/src/video/cocoa/SDL_cocoawindow.h	Thu Jul 27 06:53:23 2006 +0000
     1.3 @@ -66,7 +66,7 @@
     1.4  {
     1.5      SDL_WindowID windowID;
     1.6      NSWindow *window;
     1.7 -    BOOL created;
     1.8 +    SDL_bool created;
     1.9      Cocoa_WindowListener *listener;
    1.10      struct SDL_VideoData *videodata;
    1.11  };
     2.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Wed Jul 26 06:34:54 2006 +0000
     2.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Thu Jul 27 06:53:23 2006 +0000
     2.3 @@ -242,9 +242,10 @@
     2.4  @end
     2.5  
     2.6  static int
     2.7 -SetupWindowData(SDL_Window * window, NSWindow *nswindow, BOOL created)
     2.8 +SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
     2.9  {
    2.10      NSAutoreleasePool *pool;
    2.11 +    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    2.12      SDL_WindowData *data;
    2.13  
    2.14      /* Allocate the window data */
    2.15 @@ -256,7 +257,7 @@
    2.16      data->windowID = window->id;
    2.17      data->window = nswindow;
    2.18      data->created = created;
    2.19 -    data->videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata;
    2.20 +    data->videodata = videodata;
    2.21  
    2.22      pool = [[NSAutoreleasePool alloc] init];
    2.23  
    2.24 @@ -380,7 +381,7 @@
    2.25  
    2.26      [pool release];
    2.27  
    2.28 -    if (SetupWindowData(window, nswindow, YES) < 0) {
    2.29 +    if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) {
    2.30          [nswindow release];
    2.31          return -1;
    2.32      }
    2.33 @@ -413,7 +414,7 @@
    2.34  
    2.35      [pool release];
    2.36  
    2.37 -    return SetupWindowData(window, nswindow, NO);
    2.38 +    return SetupWindowData(_this, window, nswindow, SDL_FALSE);
    2.39  }
    2.40  
    2.41  void
     3.1 --- a/src/video/win32/SDL_win32events.c	Wed Jul 26 06:34:54 2006 +0000
     3.2 +++ b/src/video/win32/SDL_win32events.c	Thu Jul 27 06:53:23 2006 +0000
     3.3 @@ -22,7 +22,6 @@
     3.4  #include "SDL_config.h"
     3.5  
     3.6  #include "SDL_win32video.h"
     3.7 -#include "SDL_version.h"
     3.8  #include "SDL_syswm.h"
     3.9  #include "SDL_vkeys.h"
    3.10  #include "../../events/SDL_events_c.h"
    3.11 @@ -393,6 +392,18 @@
    3.12  {
    3.13      SDL_WindowData *data;
    3.14  
    3.15 +    /* Send a SDL_SYSWMEVENT if the application wants them */
    3.16 +    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
    3.17 +        SDL_SysWMmsg wmmsg;
    3.18 +
    3.19 +        SDL_VERSION(&wmmsg.version);
    3.20 +        wmmsg.hwnd = hwnd;
    3.21 +        wmmsg.msg = msg;
    3.22 +        wmmsg.wParam = wParam;
    3.23 +        wmmsg.lParam = lParam;
    3.24 +        SDL_SendSysWMEvent(&wmmsg);
    3.25 +    }
    3.26 +
    3.27      /* Get the window data for the window */
    3.28      data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
    3.29      if (!data) {
    3.30 @@ -412,18 +423,6 @@
    3.31      }
    3.32  #endif
    3.33  
    3.34 -    /* Send a SDL_SYSWMEVENT if the application wants them */
    3.35 -    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
    3.36 -        SDL_SysWMmsg wmmsg;
    3.37 -
    3.38 -        SDL_VERSION(&wmmsg.version);
    3.39 -        wmmsg.hwnd = hwnd;
    3.40 -        wmmsg.msg = msg;
    3.41 -        wmmsg.wParam = wParam;
    3.42 -        wmmsg.lParam = lParam;
    3.43 -        SDL_SendSysWMEvent(&wmmsg);
    3.44 -    }
    3.45 -
    3.46      switch (msg) {
    3.47  
    3.48      case WM_SHOWWINDOW:
     4.1 --- a/src/video/win32/SDL_win32window.c	Wed Jul 26 06:34:54 2006 +0000
     4.2 +++ b/src/video/win32/SDL_win32window.c	Thu Jul 27 06:53:23 2006 +0000
     4.3 @@ -31,8 +31,9 @@
     4.4  
     4.5  
     4.6  static int
     4.7 -SetupWindowData(SDL_Window * window, HWND hwnd, BOOL created)
     4.8 +SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
     4.9  {
    4.10 +    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    4.11      SDL_WindowData *data;
    4.12  
    4.13      /* Allocate the window data */
    4.14 @@ -46,7 +47,7 @@
    4.15      data->hdc = GetDC(hwnd);
    4.16      data->created = created;
    4.17      data->mouse_pressed = SDL_FALSE;
    4.18 -    data->videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata;
    4.19 +    data->videodata = videodata;
    4.20  
    4.21      /* Associate the data with the window */
    4.22      if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) {
    4.23 @@ -208,7 +209,7 @@
    4.24          return -1;
    4.25      }
    4.26  
    4.27 -    if (SetupWindowData(window, hwnd, TRUE) < 0) {
    4.28 +    if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) {
    4.29          DestroyWindow(hwnd);
    4.30          return -1;
    4.31      }
    4.32 @@ -245,7 +246,7 @@
    4.33          SDL_stack_free(title);
    4.34      }
    4.35  
    4.36 -    if (SetupWindowData(window, hwnd, FALSE) < 0) {
    4.37 +    if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
    4.38          return -1;
    4.39      }
    4.40      return 0;
     5.1 --- a/src/video/win32/SDL_win32window.h	Wed Jul 26 06:34:54 2006 +0000
     5.2 +++ b/src/video/win32/SDL_win32window.h	Thu Jul 27 06:53:23 2006 +0000
     5.3 @@ -30,7 +30,7 @@
     5.4      HWND hwnd;
     5.5      HDC hdc;
     5.6      WNDPROC wndproc;
     5.7 -    BOOL created;
     5.8 +    SDL_bool created;
     5.9      int mouse_pressed;
    5.10      struct SDL_VideoData *videodata;
    5.11  } SDL_WindowData;
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/video/x11/SDL_x11events.c	Thu Jul 27 06:53:23 2006 +0000
     6.3 @@ -0,0 +1,421 @@
     6.4 +/*
     6.5 +    SDL - Simple DirectMedia Layer
     6.6 +    Copyright (C) 1997-2006 Sam Lantinga
     6.7 +
     6.8 +    This library is free software; you can redistribute it and/or
     6.9 +    modify it under the terms of the GNU Lesser General Public
    6.10 +    License as published by the Free Software Foundation; either
    6.11 +    version 2.1 of the License, or (at your option) any later version.
    6.12 +
    6.13 +    This library is distributed in the hope that it will be useful,
    6.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.16 +    Lesser General Public License for more details.
    6.17 +
    6.18 +    You should have received a copy of the GNU Lesser General Public
    6.19 +    License along with this library; if not, write to the Free Software
    6.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    6.21 +
    6.22 +    Sam Lantinga
    6.23 +    slouken@libsdl.org
    6.24 +*/
    6.25 +#include "SDL_config.h"
    6.26 +
    6.27 +#include "SDL_syswm.h"
    6.28 +#include "SDL_x11video.h"
    6.29 +#include "../../events/SDL_events_c.h"
    6.30 +
    6.31 +
    6.32 +static void
    6.33 +X11_DispatchEvent(_THIS)
    6.34 +{
    6.35 +    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    6.36 +    SDL_WindowData *data;
    6.37 +    XEvent xevent;
    6.38 +    int i;
    6.39 +
    6.40 +    SDL_zero(xevent);           /* valgrind fix. --ryan. */
    6.41 +    XNextEvent(videodata->display, &xevent);
    6.42 +
    6.43 +    /* Send a SDL_SYSWMEVENT if the application wants them */
    6.44 +    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
    6.45 +        SDL_SysWMmsg wmmsg;
    6.46 +
    6.47 +        SDL_VERSION(&wmmsg.version);
    6.48 +        wmmsg.subsystem = SDL_SYSWM_X11;
    6.49 +        wmmsg.event.xevent = xevent;
    6.50 +        SDL_SendSysWMEvent(&wmmsg);
    6.51 +    }
    6.52 +
    6.53 +    data = NULL;
    6.54 +    for (i = 0; i < videodata->numwindows; ++i) {
    6.55 +        if (videodata->windowlist[i]->window == xevent.xany.window) {
    6.56 +            data = videodata->windowlist[i];
    6.57 +        }
    6.58 +    }
    6.59 +    if (!data) {
    6.60 +        return;
    6.61 +    }
    6.62 +
    6.63 +    switch (xevent.type) {
    6.64 +
    6.65 +        /* Gaining mouse coverage? */
    6.66 +    case EnterNotify:{
    6.67 +#ifdef DEBUG_XEVENTS
    6.68 +            printf("EnterNotify! (%d,%d)\n", xevent.xcrossing.x,
    6.69 +                   xevent.xcrossing.y);
    6.70 +            if (xevent.xcrossing.mode == NotifyGrab)
    6.71 +                printf("Mode: NotifyGrab\n");
    6.72 +            if (xevent.xcrossing.mode == NotifyUngrab)
    6.73 +                printf("Mode: NotifyUngrab\n");
    6.74 +#endif
    6.75 +            if ((xevent.xcrossing.mode != NotifyGrab) &&
    6.76 +                (xevent.xcrossing.mode != NotifyUngrab)) {
    6.77 +                SDL_SetMouseFocus(videodata->mouse, data->windowID);
    6.78 +                SDL_SendMouseMotion(videodata->mouse, 0, xevent.xcrossing.x,
    6.79 +                                    xevent.xcrossing.y);
    6.80 +            }
    6.81 +        }
    6.82 +        break;
    6.83 +
    6.84 +        /* Losing mouse coverage? */
    6.85 +    case LeaveNotify:{
    6.86 +#ifdef DEBUG_XEVENTS
    6.87 +            printf("LeaveNotify! (%d,%d)\n", xevent.xcrossing.x,
    6.88 +                   xevent.xcrossing.y);
    6.89 +            if (xevent.xcrossing.mode == NotifyGrab)
    6.90 +                printf("Mode: NotifyGrab\n");
    6.91 +            if (xevent.xcrossing.mode == NotifyUngrab)
    6.92 +                printf("Mode: NotifyUngrab\n");
    6.93 +#endif
    6.94 +            if ((xevent.xcrossing.mode != NotifyGrab) &&
    6.95 +                (xevent.xcrossing.mode != NotifyUngrab) &&
    6.96 +                (xevent.xcrossing.detail != NotifyInferior)) {
    6.97 +                SDL_SendMouseMotion(videodata->mouse, 0,
    6.98 +                                    xevent.xcrossing.x, xevent.xcrossing.y);
    6.99 +                SDL_SetMouseFocus(videodata->mouse, 0);
   6.100 +            }
   6.101 +        }
   6.102 +        break;
   6.103 +
   6.104 +        /* Gaining input focus? */
   6.105 +    case FocusIn:{
   6.106 +#ifdef DEBUG_XEVENTS
   6.107 +            printf("FocusIn!\n");
   6.108 +#endif
   6.109 +            SDL_SetKeyboardFocus(videodata->keyboard, data->windowID);
   6.110 +#ifdef X_HAVE_UTF8_STRING
   6.111 +            if (data->ic) {
   6.112 +                XSetICFocus(data->ic);
   6.113 +            }
   6.114 +#endif
   6.115 +        }
   6.116 +        break;
   6.117 +
   6.118 +        /* Losing input focus? */
   6.119 +    case FocusOut:{
   6.120 +#ifdef DEBUG_XEVENTS
   6.121 +            printf("FocusOut!\n");
   6.122 +#endif
   6.123 +            SDL_SetKeyboardFocus(videodata->keyboard, 0);
   6.124 +#ifdef X_HAVE_UTF8_STRING
   6.125 +            if (data->ic) {
   6.126 +                XUnsetICFocus(data->ic);
   6.127 +            }
   6.128 +#endif
   6.129 +        }
   6.130 +        break;
   6.131 +
   6.132 +        /* Generated upon EnterWindow and FocusIn */
   6.133 +    case KeymapNotify:{
   6.134 +#ifdef DEBUG_XEVENTS
   6.135 +            printf("KeymapNotify!\n");
   6.136 +#endif
   6.137 +            /* FIXME:
   6.138 +               X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector);
   6.139 +             */
   6.140 +        }
   6.141 +        break;
   6.142 +
   6.143 +        /* Mouse motion? */
   6.144 +    case MotionNotify:{
   6.145 +#ifdef DEBUG_MOTION
   6.146 +            printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y);
   6.147 +#endif
   6.148 +            SDL_SendMouseMotion(videodata->mouse, 0, xevent.xmotion.x,
   6.149 +                                xevent.xmotion.y);
   6.150 +        }
   6.151 +        break;
   6.152 +
   6.153 +        /* Mouse button press? */
   6.154 +    case ButtonPress:{
   6.155 +            SDL_SendMouseButton(videodata->mouse, SDL_PRESSED,
   6.156 +                                xevent.xbutton.button);
   6.157 +        }
   6.158 +        break;
   6.159 +
   6.160 +        /* Mouse button release? */
   6.161 +    case ButtonRelease:{
   6.162 +            SDL_SendMouseButton(videodata->mouse, SDL_RELEASED,
   6.163 +                                xevent.xbutton.button);
   6.164 +        }
   6.165 +        break;
   6.166 +
   6.167 +        /* Key press? */
   6.168 +    case KeyPress:{
   6.169 +#if 0                           /* FIXME */
   6.170 +            static SDL_keysym saved_keysym;
   6.171 +            SDL_keysym keysym;
   6.172 +            KeyCode keycode = xevent.xkey.keycode;
   6.173 +
   6.174 +#ifdef DEBUG_XEVENTS
   6.175 +            printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
   6.176 +#endif
   6.177 +            /* Get the translated SDL virtual keysym */
   6.178 +            if (keycode) {
   6.179 +                keysym.scancode = keycode;
   6.180 +                keysym.sym = X11_TranslateKeycode(SDL_Display, keycode);
   6.181 +                keysym.mod = KMOD_NONE;
   6.182 +                keysym.unicode = 0;
   6.183 +            } else {
   6.184 +                keysym = saved_keysym;
   6.185 +            }
   6.186 +
   6.187 +            /* If we're not doing translation, we're done! */
   6.188 +            if (!SDL_TranslateUNICODE) {
   6.189 +                posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
   6.190 +                break;
   6.191 +            }
   6.192 +
   6.193 +            if (XFilterEvent(&xevent, None)) {
   6.194 +                if (xevent.xkey.keycode) {
   6.195 +                    posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
   6.196 +                } else {
   6.197 +                    /* Save event to be associated with IM text
   6.198 +                       In 1.3 we'll have a text event instead.. */
   6.199 +                    saved_keysym = keysym;
   6.200 +                }
   6.201 +                break;
   6.202 +            }
   6.203 +
   6.204 +            /* Look up the translated value for the key event */
   6.205 +#ifdef X_HAVE_UTF8_STRING
   6.206 +            if (data->ic != NULL) {
   6.207 +                static Status state;
   6.208 +                /* A UTF-8 character can be at most 6 bytes */
   6.209 +                char keybuf[6];
   6.210 +                if (Xutf8LookupString(data->ic, &xevent.xkey,
   6.211 +                                      keybuf, sizeof(keybuf), NULL, &state)) {
   6.212 +                    keysym.unicode = Utf8ToUcs4((Uint8 *) keybuf);
   6.213 +                }
   6.214 +            } else
   6.215 +#endif
   6.216 +            {
   6.217 +                static XComposeStatus state;
   6.218 +                char keybuf[32];
   6.219 +
   6.220 +                if (XLookupString(&xevent.xkey,
   6.221 +                                  keybuf, sizeof(keybuf), NULL, &state)) {
   6.222 +                    /*
   6.223 +                     * FIXME: XLookupString() may yield more than one
   6.224 +                     * character, so we need a mechanism to allow for
   6.225 +                     * this (perhaps null keypress events with a
   6.226 +                     * unicode value)
   6.227 +                     */
   6.228 +                    keysym.unicode = (Uint8) keybuf[0];
   6.229 +                }
   6.230 +            }
   6.231 +            posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
   6.232 +#endif // 0
   6.233 +        }
   6.234 +        break;
   6.235 +
   6.236 +        /* Key release? */
   6.237 +    case KeyRelease:{
   6.238 +#if 0                           /* FIXME */
   6.239 +            SDL_keysym keysym;
   6.240 +            KeyCode keycode = xevent.xkey.keycode;
   6.241 +
   6.242 +#ifdef DEBUG_XEVENTS
   6.243 +            printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
   6.244 +#endif
   6.245 +            /* Check to see if this is a repeated key */
   6.246 +            if (X11_KeyRepeat(SDL_Display, &xevent)) {
   6.247 +                break;
   6.248 +            }
   6.249 +
   6.250 +            /* Get the translated SDL virtual keysym */
   6.251 +            keysym.scancode = keycode;
   6.252 +            keysym.sym = X11_TranslateKeycode(SDL_Display, keycode);
   6.253 +            keysym.mod = KMOD_NONE;
   6.254 +            keysym.unicode = 0;
   6.255 +
   6.256 +            posted = SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
   6.257 +#endif // 0
   6.258 +        }
   6.259 +        break;
   6.260 +
   6.261 +        /* Have we been iconified? */
   6.262 +    case UnmapNotify:{
   6.263 +#ifdef DEBUG_XEVENTS
   6.264 +            printf("UnmapNotify!\n");
   6.265 +#endif
   6.266 +            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_HIDDEN, 0, 0);
   6.267 +            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MINIMIZED, 0,
   6.268 +                                0);
   6.269 +        }
   6.270 +        break;
   6.271 +
   6.272 +        /* Have we been restored? */
   6.273 +    case MapNotify:{
   6.274 +#ifdef DEBUG_XEVENTS
   6.275 +            printf("MapNotify!\n");
   6.276 +#endif
   6.277 +            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, 0, 0);
   6.278 +            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESTORED, 0,
   6.279 +                                0);
   6.280 +        }
   6.281 +        break;
   6.282 +
   6.283 +        /* Have we been resized or moved? */
   6.284 +    case ConfigureNotify:{
   6.285 +#ifdef DEBUG_XEVENTS
   6.286 +            printf("ConfigureNotify! (resize: %dx%d)\n",
   6.287 +                   xevent.xconfigure.width, xevent.xconfigure.height);
   6.288 +#endif
   6.289 +            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MOVED,
   6.290 +                                xevent.xconfigure.x, xevent.xconfigure.y);
   6.291 +            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESIZED,
   6.292 +                                xevent.xconfigure.width,
   6.293 +                                xevent.xconfigure.height);
   6.294 +        }
   6.295 +        break;
   6.296 +
   6.297 +        /* Have we been requested to quit (or another client message?) */
   6.298 +    case ClientMessage:{
   6.299 +            if ((xevent.xclient.format == 32) &&
   6.300 +                (xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) {
   6.301 +
   6.302 +                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0,
   6.303 +                                    0);
   6.304 +            }
   6.305 +        }
   6.306 +        break;
   6.307 +
   6.308 +        /* Do we need to refresh ourselves? */
   6.309 +    case Expose:{
   6.310 +#ifdef DEBUG_XEVENTS
   6.311 +            printf("Expose (count = %d)\n", xevent.xexpose.count);
   6.312 +#endif
   6.313 +            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED, 0,
   6.314 +                                0);
   6.315 +        }
   6.316 +        break;
   6.317 +
   6.318 +    default:{
   6.319 +#ifdef DEBUG_XEVENTS
   6.320 +            printf("Unhandled event %d\n", xevent.type);
   6.321 +#endif
   6.322 +        }
   6.323 +        break;
   6.324 +    }
   6.325 +}
   6.326 +
   6.327 +/* Ack!  XPending() actually performs a blocking read if no events available */
   6.328 +int
   6.329 +X11_Pending(Display * display)
   6.330 +{
   6.331 +    /* Flush the display connection and look to see if events are queued */
   6.332 +    XFlush(display);
   6.333 +    if (XEventsQueued(display, QueuedAlready)) {
   6.334 +        return (1);
   6.335 +    }
   6.336 +
   6.337 +    /* More drastic measures are required -- see if X is ready to talk */
   6.338 +    {
   6.339 +        static struct timeval zero_time;        /* static == 0 */
   6.340 +        int x11_fd;
   6.341 +        fd_set fdset;
   6.342 +
   6.343 +        x11_fd = ConnectionNumber(display);
   6.344 +        FD_ZERO(&fdset);
   6.345 +        FD_SET(x11_fd, &fdset);
   6.346 +        if (select(x11_fd + 1, &fdset, NULL, NULL, &zero_time) == 1) {
   6.347 +            return (XPending(display));
   6.348 +        }
   6.349 +    }
   6.350 +
   6.351 +    /* Oh well, nothing is ready .. */
   6.352 +    return (0);
   6.353 +}
   6.354 +
   6.355 +void
   6.356 +X11_PumpEvents(_THIS)
   6.357 +{
   6.358 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   6.359 +
   6.360 +    /* Keep processing pending events */
   6.361 +    while (X11_Pending(data->display)) {
   6.362 +        X11_DispatchEvent(_this);
   6.363 +    }
   6.364 +}
   6.365 +
   6.366 +void
   6.367 +X11_SaveScreenSaver(Display * display, int *saved_timeout, BOOL * dpms)
   6.368 +{
   6.369 +    int timeout, interval, prefer_blank, allow_exp;
   6.370 +    XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp);
   6.371 +    *saved_timeout = timeout;
   6.372 +
   6.373 +#if SDL_VIDEO_DRIVER_X11_DPMS
   6.374 +    if (SDL_X11_HAVE_DPMS) {
   6.375 +        int dummy;
   6.376 +        if (DPMSQueryExtension(display, &dummy, &dummy)) {
   6.377 +            CARD16 state;
   6.378 +            DPMSInfo(display, &state, dpms);
   6.379 +        }
   6.380 +    }
   6.381 +#else
   6.382 +    *dpms = 0;
   6.383 +#endif /* SDL_VIDEO_DRIVER_X11_DPMS */
   6.384 +}
   6.385 +
   6.386 +void
   6.387 +X11_DisableScreenSaver(Display * display)
   6.388 +{
   6.389 +    int timeout, interval, prefer_blank, allow_exp;
   6.390 +    XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp);
   6.391 +    timeout = 0;
   6.392 +    XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp);
   6.393 +
   6.394 +#if SDL_VIDEO_DRIVER_X11_DPMS
   6.395 +    if (SDL_X11_HAVE_DPMS) {
   6.396 +        int dummy;
   6.397 +        if (DPMSQueryExtension(display, &dummy, &dummy)) {
   6.398 +            DPMSDisable(display);
   6.399 +        }
   6.400 +    }
   6.401 +#endif /* SDL_VIDEO_DRIVER_X11_DPMS */
   6.402 +}
   6.403 +
   6.404 +void
   6.405 +X11_RestoreScreenSaver(Display * display, int saved_timeout, BOOL dpms)
   6.406 +{
   6.407 +    int timeout, interval, prefer_blank, allow_exp;
   6.408 +    XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp);
   6.409 +    timeout = saved_timeout;
   6.410 +    XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp);
   6.411 +
   6.412 +#if SDL_VIDEO_DRIVER_X11_DPMS
   6.413 +    if (SDL_X11_HAVE_DPMS) {
   6.414 +        int dummy;
   6.415 +        if (DPMSQueryExtension(display, &dummy, &dummy)) {
   6.416 +            if (dpms) {
   6.417 +                DPMSEnable(display);
   6.418 +            }
   6.419 +        }
   6.420 +    }
   6.421 +#endif /* SDL_VIDEO_DRIVER_X11_DPMS */
   6.422 +}
   6.423 +
   6.424 +/* vi: set ts=4 sw=4 expandtab: */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/video/x11/SDL_x11events.h	Thu Jul 27 06:53:23 2006 +0000
     7.3 @@ -0,0 +1,36 @@
     7.4 +/*
     7.5 +    SDL - Simple DirectMedia Layer
     7.6 +    Copyright (C) 1997-2006 Sam Lantinga
     7.7 +
     7.8 +    This library is free software; you can redistribute it and/or
     7.9 +    modify it under the terms of the GNU Lesser General Public
    7.10 +    License as published by the Free Software Foundation; either
    7.11 +    version 2.1 of the License, or (at your option) any later version.
    7.12 +
    7.13 +    This library is distributed in the hope that it will be useful,
    7.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    7.16 +    Lesser General Public License for more details.
    7.17 +
    7.18 +    You should have received a copy of the GNU Lesser General Public
    7.19 +    License along with this library; if not, write to the Free Software
    7.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    7.21 +
    7.22 +    Sam Lantinga
    7.23 +    slouken@libsdl.org
    7.24 +*/
    7.25 +#include "SDL_config.h"
    7.26 +
    7.27 +#ifndef _SDL_x11events_h
    7.28 +#define _SDL_x11events_h
    7.29 +
    7.30 +extern void X11_PumpEvents(_THIS);
    7.31 +extern void X11_SaveScreenSaver(Display * display, int *saved_timeout,
    7.32 +                                BOOL * dpms);
    7.33 +extern void X11_DisableScreenSaver(Display * display);
    7.34 +extern void X11_RestoreScreenSaver(Display * display, int saved_timeout,
    7.35 +                                   BOOL dpms);
    7.36 +
    7.37 +#endif /* _SDL_x11events_h */
    7.38 +
    7.39 +/* vi: set ts=4 sw=4 expandtab: */
     8.1 --- a/src/video/x11/SDL_x11modes.c	Wed Jul 26 06:34:54 2006 +0000
     8.2 +++ b/src/video/x11/SDL_x11modes.c	Thu Jul 27 06:53:23 2006 +0000
     8.3 @@ -106,6 +106,7 @@
     8.4          }
     8.5          displaydata->screen = screen;
     8.6          displaydata->visual = vinfo.visual;
     8.7 +        displaydata->depth = vinfo.depth;
     8.8  
     8.9          SDL_zero(display);
    8.10          display.desktop_mode = mode;
     9.1 --- a/src/video/x11/SDL_x11modes.h	Wed Jul 26 06:34:54 2006 +0000
     9.2 +++ b/src/video/x11/SDL_x11modes.h	Thu Jul 27 06:53:23 2006 +0000
     9.3 @@ -28,6 +28,7 @@
     9.4  {
     9.5      int screen;
     9.6      Visual *visual;
     9.7 +    int depth;
     9.8  } SDL_DisplayData;
     9.9  
    9.10  //typedef struct
    10.1 --- a/src/video/x11/SDL_x11video.c	Wed Jul 26 06:34:54 2006 +0000
    10.2 +++ b/src/video/x11/SDL_x11video.c	Thu Jul 27 06:53:23 2006 +0000
    10.3 @@ -34,6 +34,49 @@
    10.4  static int X11_VideoInit(_THIS);
    10.5  static void X11_VideoQuit(_THIS);
    10.6  
    10.7 +/* Find out what class name we should use */
    10.8 +static char *
    10.9 +get_classname()
   10.10 +{
   10.11 +    char *spot;
   10.12 +#if defined(__LINUX__) || defined(__FREEBSD__)
   10.13 +    char procfile[1024];
   10.14 +    char linkfile[1024];
   10.15 +    int linksize;
   10.16 +#endif
   10.17 +
   10.18 +    /* First allow environment variable override */
   10.19 +    spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS");
   10.20 +    if (spot) {
   10.21 +        return SDL_strdup(spot);
   10.22 +    }
   10.23 +
   10.24 +    /* Next look at the application's executable name */
   10.25 +#if defined(__LINUX__) || defined(__FREEBSD__)
   10.26 +#if defined(__LINUX__)
   10.27 +    SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid());
   10.28 +#elif defined(__FREEBSD__)
   10.29 +    SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file",
   10.30 +                 getpid());
   10.31 +#else
   10.32 +#error Where can we find the executable name?
   10.33 +#endif
   10.34 +    linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
   10.35 +    if (linksize > 0) {
   10.36 +        linkfile[linksize] = '\0';
   10.37 +        spot = SDL_strrchr(linkfile, '/');
   10.38 +        if (spot) {
   10.39 +            return SDL_strdup(spot + 1);
   10.40 +        } else {
   10.41 +            return SDL_strdup(linkfile);
   10.42 +        }
   10.43 +    }
   10.44 +#endif /* __LINUX__ || __FREEBSD__ */
   10.45 +
   10.46 +    /* Finally use the default we've used forever */
   10.47 +    return SDL_strdup("SDL_App");
   10.48 +}
   10.49 +
   10.50  /* X11 driver bootstrap functions */
   10.51  
   10.52  static int
   10.53 @@ -127,9 +170,8 @@
   10.54      device->SetDisplayMode = X11_SetDisplayMode;
   10.55  //    device->SetDisplayGammaRamp = X11_SetDisplayGammaRamp;
   10.56  //    device->GetDisplayGammaRamp = X11_GetDisplayGammaRamp;
   10.57 -//    device->PumpEvents = X11_PumpEvents;
   10.58 +    device->PumpEvents = X11_PumpEvents;
   10.59  
   10.60 -/*
   10.61      device->CreateWindow = X11_CreateWindow;
   10.62      device->CreateWindowFrom = X11_CreateWindowFrom;
   10.63      device->SetWindowTitle = X11_SetWindowTitle;
   10.64 @@ -144,6 +186,7 @@
   10.65      device->SetWindowGrab = X11_SetWindowGrab;
   10.66      device->DestroyWindow = X11_DestroyWindow;
   10.67      device->GetWindowWMInfo = X11_GetWindowWMInfo;
   10.68 +/*
   10.69  #ifdef SDL_VIDEO_OPENGL
   10.70      device->GL_LoadLibrary = X11_GL_LoadLibrary;
   10.71      device->GL_GetProcAddress = X11_GL_GetProcAddress;
   10.72 @@ -170,6 +213,28 @@
   10.73  int
   10.74  X11_VideoInit(_THIS)
   10.75  {
   10.76 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   10.77 +
   10.78 +    /* Get the window class name, usually the name of the application */
   10.79 +    data->classname = get_classname();
   10.80 +
   10.81 +    /* Open a connection to the X input manager */
   10.82 +#ifdef X_HAVE_UTF8_STRING
   10.83 +    if (SDL_X11_HAVE_UTF8) {
   10.84 +        data->im =
   10.85 +            XOpenIM(data->display, NULL, data->classname, data->classname);
   10.86 +    }
   10.87 +#endif
   10.88 +
   10.89 +    /* Save DPMS and screensaver settings */
   10.90 +    X11_SaveScreenSaver(data->display, &data->screensaver_timeout,
   10.91 +                        &data->dpms_enabled);
   10.92 +    X11_DisableScreenSaver(data->display);
   10.93 +
   10.94 +    /* Look up some useful Atoms */
   10.95 +    data->WM_DELETE_WINDOW =
   10.96 +        XInternAtom(data->display, "WM_DELETE_WINDOW", False);
   10.97 +
   10.98      X11_InitModes(_this);
   10.99  
  10.100  //#if SDL_VIDEO_RENDER_D3D
  10.101 @@ -188,6 +253,19 @@
  10.102  void
  10.103  X11_VideoQuit(_THIS)
  10.104  {
  10.105 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
  10.106 +
  10.107 +    if (data->classname) {
  10.108 +        SDL_free(data->classname);
  10.109 +    }
  10.110 +#ifdef X_HAVE_UTF8_STRING
  10.111 +    if (data->im) {
  10.112 +        XCloseIM(data->im);
  10.113 +    }
  10.114 +#endif
  10.115 +    X11_RestoreScreenSaver(data->display, data->screensaver_timeout,
  10.116 +                           data->dpms_enabled);
  10.117 +
  10.118      X11_QuitModes(_this);
  10.119      X11_QuitKeyboard(_this);
  10.120      X11_QuitMouse(_this);
    11.1 --- a/src/video/x11/SDL_x11video.h	Wed Jul 26 06:34:54 2006 +0000
    11.2 +++ b/src/video/x11/SDL_x11video.h	Thu Jul 27 06:53:23 2006 +0000
    11.3 @@ -30,14 +30,6 @@
    11.4  #include <X11/Xutil.h>
    11.5  #include <X11/Xatom.h>
    11.6  
    11.7 -//#include "SDL_x11events.h"
    11.8 -//#include "SDL_x11gamma.h"
    11.9 -#include "SDL_x11keyboard.h"
   11.10 -#include "SDL_x11modes.h"
   11.11 -#include "SDL_x11mouse.h"
   11.12 -//#include "SDL_x11opengl.h"
   11.13 -//#include "SDL_x11window.h"
   11.14 -
   11.15  #if SDL_VIDEO_DRIVER_X11_XINERAMA
   11.16  #include "../Xext/extensions/Xinerama.h"
   11.17  #endif
   11.18 @@ -56,13 +48,28 @@
   11.19  
   11.20  #include "SDL_x11dyn.h"
   11.21  
   11.22 +#include "SDL_x11events.h"
   11.23 +//#include "SDL_x11gamma.h"
   11.24 +#include "SDL_x11keyboard.h"
   11.25 +#include "SDL_x11modes.h"
   11.26 +#include "SDL_x11mouse.h"
   11.27 +//#include "SDL_x11opengl.h"
   11.28 +#include "SDL_x11window.h"
   11.29 +
   11.30  /* Private display data */
   11.31  
   11.32  typedef struct SDL_VideoData
   11.33  {
   11.34      Display *display;
   11.35 +    char *classname;
   11.36 +    XIM im;
   11.37 +    int screensaver_timeout;
   11.38 +    BOOL dpms_enabled;
   11.39 +    int numwindows;
   11.40 +    SDL_WindowData **windowlist;
   11.41      int mouse;
   11.42      int keyboard;
   11.43 +    Atom WM_DELETE_WINDOW;
   11.44  } SDL_VideoData;
   11.45  
   11.46  #endif /* _SDL_x11video_h */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/video/x11/SDL_x11window.c	Thu Jul 27 06:53:23 2006 +0000
    12.3 @@ -0,0 +1,611 @@
    12.4 +/*
    12.5 +    SDL - Simple DirectMedia Layer
    12.6 +    Copyright (C) 1997-2006 Sam Lantinga
    12.7 +
    12.8 +    This library is free software; you can redistribute it and/or
    12.9 +    modify it under the terms of the GNU Lesser General Public
   12.10 +    License as published by the Free Software Foundation; either
   12.11 +    version 2.1 of the License, or (at your option) any later version.
   12.12 +
   12.13 +    This library is distributed in the hope that it will be useful,
   12.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12.16 +    Lesser General Public License for more details.
   12.17 +
   12.18 +    You should have received a copy of the GNU Lesser General Public
   12.19 +    License along with this library; if not, write to the Free Software
   12.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   12.21 +
   12.22 +    Sam Lantinga
   12.23 +    slouken@libsdl.org
   12.24 +*/
   12.25 +#include "SDL_config.h"
   12.26 +
   12.27 +#include "SDL_syswm.h"
   12.28 +#include "../SDL_sysvideo.h"
   12.29 +#include "../../events/SDL_keyboard_c.h"
   12.30 +
   12.31 +#include "SDL_x11video.h"
   12.32 +
   12.33 +
   12.34 +static int
   12.35 +SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
   12.36 +{
   12.37 +    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
   12.38 +    SDL_WindowData *data;
   12.39 +    int numwindows = videodata->numwindows;
   12.40 +    SDL_WindowData **windowlist = videodata->windowlist;
   12.41 +
   12.42 +    /* Allocate the window data */
   12.43 +    data = (SDL_WindowData *) SDL_malloc(sizeof(*data));
   12.44 +    if (!data) {
   12.45 +        SDL_OutOfMemory();
   12.46 +        return -1;
   12.47 +    }
   12.48 +    data->windowID = window->id;
   12.49 +    data->window = w;
   12.50 +#ifdef X_HAVE_UTF8_STRING
   12.51 +    if (SDL_X11_HAVE_UTF8) {
   12.52 +        data->ic =
   12.53 +            pXCreateIC(videodata->im, XNClientWindow, w, XNFocusWindow, w,
   12.54 +                       XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
   12.55 +                       XNResourceName, videodata->classname, XNResourceClass,
   12.56 +                       videodata->classname, NULL);
   12.57 +    }
   12.58 +#endif
   12.59 +    data->created = created;
   12.60 +    data->videodata = videodata;
   12.61 +
   12.62 +    /* Associate the data with the window */
   12.63 +    windowlist =
   12.64 +        (SDL_WindowData **) SDL_realloc(windowlist,
   12.65 +                                        (numwindows +
   12.66 +                                         1) * sizeof(*windowlist));
   12.67 +    if (!windowlist) {
   12.68 +        SDL_OutOfMemory();
   12.69 +        SDL_free(data);
   12.70 +        return -1;
   12.71 +    }
   12.72 +    windowlist[numwindows++] = data;
   12.73 +    videodata->numwindows = numwindows;
   12.74 +    videodata->windowlist = windowlist;
   12.75 +
   12.76 +    /* Fill in the SDL window with the window data */
   12.77 +    {
   12.78 +        XWindowAttributes attrib;
   12.79 +
   12.80 +        XGetWindowAttributes(data->videodata->display, w, &attrib);
   12.81 +        window->x = attrib.x;
   12.82 +        window->y = attrib.y;
   12.83 +        window->w = attrib.width;
   12.84 +        window->h = attrib.height;
   12.85 +        if (attrib.map_state != IsUnmapped) {
   12.86 +            window->flags |= SDL_WINDOW_SHOWN;
   12.87 +        } else {
   12.88 +            window->flags &= ~SDL_WINDOW_SHOWN;
   12.89 +        }
   12.90 +    }
   12.91 +    /* FIXME: How can I tell?
   12.92 +       {
   12.93 +       DWORD style = GetWindowLong(hwnd, GWL_STYLE);
   12.94 +       if (style & WS_VISIBLE) {
   12.95 +       if (style & (WS_BORDER | WS_THICKFRAME)) {
   12.96 +       window->flags &= ~SDL_WINDOW_BORDERLESS;
   12.97 +       } else {
   12.98 +       window->flags |= SDL_WINDOW_BORDERLESS;
   12.99 +       }
  12.100 +       if (style & WS_THICKFRAME) {
  12.101 +       window->flags |= SDL_WINDOW_RESIZABLE;
  12.102 +       } else {
  12.103 +       window->flags &= ~SDL_WINDOW_RESIZABLE;
  12.104 +       }
  12.105 +       if (style & WS_MAXIMIZE) {
  12.106 +       window->flags |= SDL_WINDOW_MAXIMIZED;
  12.107 +       } else {
  12.108 +       window->flags &= ~SDL_WINDOW_MAXIMIZED;
  12.109 +       }
  12.110 +       if (style & WS_MINIMIZE) {
  12.111 +       window->flags |= SDL_WINDOW_MINIMIZED;
  12.112 +       } else {
  12.113 +       window->flags &= ~SDL_WINDOW_MINIMIZED;
  12.114 +       }
  12.115 +       }
  12.116 +       if (GetFocus() == hwnd) {
  12.117 +       int index = data->videodata->keyboard;
  12.118 +       window->flags |= SDL_WINDOW_INPUT_FOCUS;
  12.119 +       SDL_SetKeyboardFocus(index, data->windowID);
  12.120 +
  12.121 +       if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
  12.122 +       RECT rect;
  12.123 +       GetClientRect(hwnd, &rect);
  12.124 +       ClientToScreen(hwnd, (LPPOINT) & rect);
  12.125 +       ClientToScreen(hwnd, (LPPOINT) & rect + 1);
  12.126 +       ClipCursor(&rect);
  12.127 +       }
  12.128 +       }
  12.129 +     */
  12.130 +
  12.131 +    /* All done! */
  12.132 +    window->driverdata = data;
  12.133 +    return 0;
  12.134 +}
  12.135 +
  12.136 +int
  12.137 +X11_CreateWindow(_THIS, SDL_Window * window)
  12.138 +{
  12.139 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
  12.140 +    SDL_DisplayData *displaydata =
  12.141 +        (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
  12.142 +    Visual *visual;
  12.143 +    int depth;
  12.144 +    XSetWindowAttributes xattr;
  12.145 +    int x, y;
  12.146 +    Window w;
  12.147 +    XSizeHints *sizehints;
  12.148 +    XWMHints *wmhints;
  12.149 +    XClassHint *classhints;
  12.150 +
  12.151 +#if SDL_VIDEO_DRIVER_X11_XINERAMA
  12.152 +/* FIXME
  12.153 +    if ( use_xinerama ) {
  12.154 +        x = xinerama_info.x_org;
  12.155 +        y = xinerama_info.y_org;
  12.156 +    }
  12.157 +*/
  12.158 +#endif
  12.159 +    if (window->flags & SDL_WINDOW_OPENGL) {
  12.160 +        /* FIXME: get the glx visual */
  12.161 +    } else {
  12.162 +        visual = displaydata->visual;
  12.163 +        depth = displaydata->depth;
  12.164 +    }
  12.165 +
  12.166 +    if (window->flags & SDL_WINDOW_FULLSCREEN) {
  12.167 +        xattr.override_redirect = True;
  12.168 +    } else {
  12.169 +        xattr.override_redirect = False;
  12.170 +    }
  12.171 +    xattr.background_pixel = 0;
  12.172 +    xattr.border_pixel = 0;
  12.173 +    if (visual->class == PseudoColor || visual->class == DirectColor) {
  12.174 +        xattr.colormap =
  12.175 +            XCreateColormap(data->display,
  12.176 +                            RootWindow(data->display, displaydata->screen),
  12.177 +                            visual, AllocAll);
  12.178 +    } else {
  12.179 +        xattr.colormap =
  12.180 +            XCreateColormap(data->display,
  12.181 +                            RootWindow(data->display, displaydata->screen),
  12.182 +                            visual, AllocNone);
  12.183 +    }
  12.184 +
  12.185 +    if ((window->flags & SDL_WINDOW_FULLSCREEN) ||
  12.186 +        window->x == SDL_WINDOWPOS_CENTERED) {
  12.187 +        x = (DisplayWidth(data->display, displaydata->screen) -
  12.188 +             window->w) / 2;
  12.189 +    } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
  12.190 +        x = 0;
  12.191 +    } else {
  12.192 +        x = window->x;
  12.193 +    }
  12.194 +    if ((window->flags & SDL_WINDOW_FULLSCREEN) ||
  12.195 +        window->y == SDL_WINDOWPOS_CENTERED) {
  12.196 +        y = (DisplayHeight(data->display, displaydata->screen) -
  12.197 +             window->h) / 2;
  12.198 +    } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
  12.199 +        y = 0;
  12.200 +    } else {
  12.201 +        y = window->y;
  12.202 +    }
  12.203 +
  12.204 +    w = XCreateWindow(data->display,
  12.205 +                      RootWindow(data->display, displaydata->screen), x, y,
  12.206 +                      window->w, window->h, 0, depth, InputOutput, visual,
  12.207 +                      (CWOverrideRedirect | CWBackPixel | CWBorderPixel |
  12.208 +                       CWColormap), &xattr);
  12.209 +
  12.210 +    sizehints = XAllocSizeHints();
  12.211 +    if (sizehints) {
  12.212 +        if (window->flags & SDL_WINDOW_RESIZABLE) {
  12.213 +            sizehints->min_width = 32;
  12.214 +            sizehints->min_height = 32;
  12.215 +            sizehints->max_height = 4096;
  12.216 +            sizehints->max_width = 4096;
  12.217 +        } else {
  12.218 +            sizehints->min_width = sizehints->max_width = window->w;
  12.219 +            sizehints->min_height = sizehints->max_height = window->h;
  12.220 +        }
  12.221 +        sizehints->flags = PMaxSize | PMinSize;
  12.222 +        if (!(window->flags & SDL_WINDOW_FULLSCREEN)
  12.223 +            && window->x != SDL_WINDOWPOS_UNDEFINED
  12.224 +            && window->y != SDL_WINDOWPOS_UNDEFINED) {
  12.225 +            sizehints->x = x;
  12.226 +            sizehints->y = y;
  12.227 +            sizehints->flags |= USPosition;
  12.228 +        }
  12.229 +        XSetWMNormalHints(data->display, w, sizehints);
  12.230 +        XFree(sizehints);
  12.231 +    }
  12.232 +
  12.233 +    if (window->flags & SDL_WINDOW_BORDERLESS) {
  12.234 +        SDL_bool set;
  12.235 +        Atom WM_HINTS;
  12.236 +
  12.237 +        /* We haven't modified the window manager hints yet */
  12.238 +        set = SDL_FALSE;
  12.239 +
  12.240 +        /* First try to set MWM hints */
  12.241 +        WM_HINTS = XInternAtom(data->display, "_MOTIF_WM_HINTS", True);
  12.242 +        if (WM_HINTS != None) {
  12.243 +            /* Hints used by Motif compliant window managers */
  12.244 +            struct
  12.245 +            {
  12.246 +                unsigned long flags;
  12.247 +                unsigned long functions;
  12.248 +                unsigned long decorations;
  12.249 +                long input_mode;
  12.250 +                unsigned long status;
  12.251 +            } MWMHints = {
  12.252 +            (1L << 1), 0, 0, 0, 0};
  12.253 +
  12.254 +            XChangeProperty(data->display, w, WM_HINTS, WM_HINTS, 32,
  12.255 +                            PropModeReplace, (unsigned char *) &MWMHints,
  12.256 +                            sizeof(MWMHints) / sizeof(long));
  12.257 +            set = SDL_TRUE;
  12.258 +        }
  12.259 +        /* Now try to set KWM hints */
  12.260 +        WM_HINTS = XInternAtom(data->display, "KWM_WIN_DECORATION", True);
  12.261 +        if (WM_HINTS != None) {
  12.262 +            long KWMHints = 0;
  12.263 +
  12.264 +            XChangeProperty(data->display, w,
  12.265 +                            WM_HINTS, WM_HINTS, 32,
  12.266 +                            PropModeReplace,
  12.267 +                            (unsigned char *) &KWMHints,
  12.268 +                            sizeof(KWMHints) / sizeof(long));
  12.269 +            set = SDL_TRUE;
  12.270 +        }
  12.271 +        /* Now try to set GNOME hints */
  12.272 +        WM_HINTS = XInternAtom(data->display, "_WIN_HINTS", True);
  12.273 +        if (WM_HINTS != None) {
  12.274 +            long GNOMEHints = 0;
  12.275 +
  12.276 +            XChangeProperty(data->display, w,
  12.277 +                            WM_HINTS, WM_HINTS, 32,
  12.278 +                            PropModeReplace,
  12.279 +                            (unsigned char *) &GNOMEHints,
  12.280 +                            sizeof(GNOMEHints) / sizeof(long));
  12.281 +            set = SDL_TRUE;
  12.282 +        }
  12.283 +        /* Finally set the transient hints if necessary */
  12.284 +        if (!set) {
  12.285 +            XSetTransientForHint(data->display, w,
  12.286 +                                 RootWindow(data->display,
  12.287 +                                            displaydata->screen));
  12.288 +        }
  12.289 +    } else {
  12.290 +        SDL_bool set;
  12.291 +        Atom WM_HINTS;
  12.292 +
  12.293 +        /* We haven't modified the window manager hints yet */
  12.294 +        set = SDL_FALSE;
  12.295 +
  12.296 +        /* First try to unset MWM hints */
  12.297 +        WM_HINTS = XInternAtom(data->display, "_MOTIF_WM_HINTS", True);
  12.298 +        if (WM_HINTS != None) {
  12.299 +            XDeleteProperty(data->display, w, WM_HINTS);
  12.300 +            set = SDL_TRUE;
  12.301 +        }
  12.302 +        /* Now try to unset KWM hints */
  12.303 +        WM_HINTS = XInternAtom(data->display, "KWM_WIN_DECORATION", True);
  12.304 +        if (WM_HINTS != None) {
  12.305 +            XDeleteProperty(data->display, w, WM_HINTS);
  12.306 +            set = SDL_TRUE;
  12.307 +        }
  12.308 +        /* Now try to unset GNOME hints */
  12.309 +        WM_HINTS = XInternAtom(data->display, "_WIN_HINTS", True);
  12.310 +        if (WM_HINTS != None) {
  12.311 +            XDeleteProperty(data->display, w, WM_HINTS);
  12.312 +            set = SDL_TRUE;
  12.313 +        }
  12.314 +        /* Finally unset the transient hints if necessary */
  12.315 +        if (!set) {
  12.316 +            /* NOTE: Does this work? */
  12.317 +            XSetTransientForHint(data->display, w, None);
  12.318 +        }
  12.319 +    }
  12.320 +
  12.321 +    /* Tell KDE to keep fullscreen windows on top */
  12.322 +    if (window->flags & SDL_WINDOW_FULLSCREEN) {
  12.323 +        XEvent ev;
  12.324 +        long mask;
  12.325 +
  12.326 +        SDL_zero(ev);
  12.327 +        ev.xclient.type = ClientMessage;
  12.328 +        ev.xclient.window = RootWindow(data->display, displaydata->screen);
  12.329 +        ev.xclient.message_type =
  12.330 +            XInternAtom(data->display, "KWM_KEEP_ON_TOP", False);
  12.331 +        ev.xclient.format = 32;
  12.332 +        ev.xclient.data.l[0] = w;
  12.333 +        ev.xclient.data.l[1] = CurrentTime;
  12.334 +        XSendEvent(data->display,
  12.335 +                   RootWindow(data->display, displaydata->screen), False,
  12.336 +                   SubstructureRedirectMask, &ev);
  12.337 +    }
  12.338 +
  12.339 +    /* Set the input hints so we get keyboard input */
  12.340 +    wmhints = XAllocWMHints();
  12.341 +    if (wmhints) {
  12.342 +        wmhints->input = True;
  12.343 +        if (window->flags & SDL_WINDOW_MINIMIZED) {
  12.344 +            wmhints->initial_state = IconicState;
  12.345 +        } else if (window->flags & SDL_WINDOW_SHOWN) {
  12.346 +            wmhints->initial_state = NormalState;
  12.347 +        } else {
  12.348 +            wmhints->initial_state = WithdrawnState;
  12.349 +        }
  12.350 +        wmhints->flags = InputHint | StateHint;
  12.351 +        XSetWMHints(data->display, w, wmhints);
  12.352 +        XFree(wmhints);
  12.353 +    }
  12.354 +
  12.355 +    XSelectInput(data->display, w,
  12.356 +                 (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
  12.357 +                  ExposureMask | ButtonPressMask | ButtonReleaseMask |
  12.358 +                  PointerMotionMask | KeyPressMask | KeyReleaseMask |
  12.359 +                  PropertyChangeMask | StructureNotifyMask |
  12.360 +                  KeymapStateMask));
  12.361 +
  12.362 +    /* Set the class hints so we can get an icon (AfterStep) */
  12.363 +    classhints = XAllocClassHint();
  12.364 +    if (classhints != NULL) {
  12.365 +        classhints->res_name = data->classname;
  12.366 +        classhints->res_class = data->classname;
  12.367 +        XSetClassHint(data->display, w, classhints);
  12.368 +        XFree(classhints);
  12.369 +    }
  12.370 +
  12.371 +    /* Allow the window to be deleted by the window manager */
  12.372 +    XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1);
  12.373 +
  12.374 +    /* Finally, show the window */
  12.375 +    if (window->flags & SDL_WINDOW_SHOWN) {
  12.376 +        XMapRaised(data->display, w);
  12.377 +    }
  12.378 +    XSync(data->display, False);
  12.379 +
  12.380 +    if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) {
  12.381 +        XDestroyWindow(data->display, w);
  12.382 +        return -1;
  12.383 +    }
  12.384 +
  12.385 +    X11_SetWindowTitle(_this, window);
  12.386 +
  12.387 +#ifdef SDL_VIDEO_OPENGL
  12.388 +    /*
  12.389 +       if (window->flags & SDL_WINDOW_OPENGL) {
  12.390 +       if (X11_GL_SetupWindow(_this, window) < 0) {
  12.391 +       X11_DestroyWindow(_this, window);
  12.392 +       return -1;
  12.393 +       }
  12.394 +       }
  12.395 +     */
  12.396 +#endif
  12.397 +    return 0;
  12.398 +}
  12.399 +
  12.400 +int
  12.401 +X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
  12.402 +{
  12.403 +    Window w = (Window) data;
  12.404 +
  12.405 +    /* FIXME: Query the title from the existing window */
  12.406 +
  12.407 +    if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) {
  12.408 +        return -1;
  12.409 +    }
  12.410 +    return 0;
  12.411 +}
  12.412 +
  12.413 +void
  12.414 +X11_SetWindowTitle(_THIS, SDL_Window * window)
  12.415 +{
  12.416 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
  12.417 +    Display *display = data->videodata->display;
  12.418 +    XTextProperty titleprop, iconprop;
  12.419 +    Status status;
  12.420 +    const char *title = window->title;
  12.421 +    const char *icon = NULL;
  12.422 +
  12.423 +#ifdef X_HAVE_UTF8_STRING
  12.424 +    Atom _NET_WM_NAME = 0;
  12.425 +    Atom _NET_WM_ICON_NAME = 0;
  12.426 +
  12.427 +    /* Look up some useful Atoms */
  12.428 +    if (SDL_X11_HAVE_UTF8) {
  12.429 +        _NET_WM_NAME = XInternAtom(display, "_NET_WM_NAME", False);
  12.430 +        _NET_WM_ICON_NAME = XInternAtom(display, "_NET_WM_ICON_NAME", False);
  12.431 +    }
  12.432 +#endif
  12.433 +
  12.434 +    if (title != NULL) {
  12.435 +        char *title_latin1 = SDL_iconv_utf8_latin1((char *) title);
  12.436 +        if (!title_latin1) {
  12.437 +            SDL_OutOfMemory();
  12.438 +            return;
  12.439 +        }
  12.440 +        status = XStringListToTextProperty(&title_latin1, 1, &titleprop);
  12.441 +        SDL_free(title_latin1);
  12.442 +        if (status) {
  12.443 +            XSetTextProperty(display, data->window, &titleprop, XA_WM_NAME);
  12.444 +            XFree(titleprop.value);
  12.445 +        }
  12.446 +#ifdef X_HAVE_UTF8_STRING
  12.447 +        if (SDL_X11_HAVE_UTF8) {
  12.448 +            status =
  12.449 +                Xutf8TextListToTextProperty(display, (char **) &title, 1,
  12.450 +                                            XUTF8StringStyle, &titleprop);
  12.451 +            if (status == Success) {
  12.452 +                XSetTextProperty(display, data->window, &titleprop,
  12.453 +                                 _NET_WM_NAME);
  12.454 +                XFree(titleprop.value);
  12.455 +            }
  12.456 +        }
  12.457 +#endif
  12.458 +    }
  12.459 +    if (icon != NULL) {
  12.460 +        char *icon_latin1 = SDL_iconv_utf8_latin1((char *) icon);
  12.461 +        if (!icon_latin1) {
  12.462 +            SDL_OutOfMemory();
  12.463 +            return;
  12.464 +        }
  12.465 +        status = XStringListToTextProperty(&icon_latin1, 1, &iconprop);
  12.466 +        SDL_free(icon_latin1);
  12.467 +        if (status) {
  12.468 +            XSetTextProperty(display, data->window, &iconprop,
  12.469 +                             XA_WM_ICON_NAME);
  12.470 +            XFree(iconprop.value);
  12.471 +        }
  12.472 +#ifdef X_HAVE_UTF8_STRING
  12.473 +        if (SDL_X11_HAVE_UTF8) {
  12.474 +            status =
  12.475 +                Xutf8TextListToTextProperty(display, (char **) &icon, 1,
  12.476 +                                            XUTF8StringStyle, &iconprop);
  12.477 +            if (status == Success) {
  12.478 +                XSetTextProperty(display, data->window, &iconprop,
  12.479 +                                 _NET_WM_ICON_NAME);
  12.480 +                XFree(iconprop.value);
  12.481 +            }
  12.482 +        }
  12.483 +#endif
  12.484 +    }
  12.485 +}
  12.486 +
  12.487 +void
  12.488 +X11_SetWindowPosition(_THIS, SDL_Window * window)
  12.489 +{
  12.490 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
  12.491 +    SDL_DisplayData *displaydata =
  12.492 +        (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
  12.493 +    Display *display = data->videodata->display;
  12.494 +    int x, y;
  12.495 +
  12.496 +    if ((window->flags & SDL_WINDOW_FULLSCREEN) ||
  12.497 +        window->x == SDL_WINDOWPOS_CENTERED) {
  12.498 +        x = (DisplayWidth(display, displaydata->screen) - window->w) / 2;
  12.499 +    } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
  12.500 +        x = 0;
  12.501 +    } else {
  12.502 +        x = window->x;
  12.503 +    }
  12.504 +    if ((window->flags & SDL_WINDOW_FULLSCREEN) ||
  12.505 +        window->y == SDL_WINDOWPOS_CENTERED) {
  12.506 +        y = (DisplayHeight(display, displaydata->screen) - window->h) / 2;
  12.507 +    } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
  12.508 +        y = 0;
  12.509 +    } else {
  12.510 +        y = window->y;
  12.511 +    }
  12.512 +    XMoveWindow(display, data->window, x, y);
  12.513 +}
  12.514 +
  12.515 +void
  12.516 +X11_SetWindowSize(_THIS, SDL_Window * window)
  12.517 +{
  12.518 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
  12.519 +    Display *display = data->videodata->display;
  12.520 +
  12.521 +    XMoveWindow(display, data->window, window->w, window->h);
  12.522 +}
  12.523 +
  12.524 +void
  12.525 +X11_ShowWindow(_THIS, SDL_Window * window)
  12.526 +{
  12.527 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
  12.528 +    Display *display = data->videodata->display;
  12.529 +
  12.530 +    XMapRaised(display, data->window);
  12.531 +}
  12.532 +
  12.533 +void
  12.534 +X11_HideWindow(_THIS, SDL_Window * window)
  12.535 +{
  12.536 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
  12.537 +    Display *display = data->videodata->display;
  12.538 +
  12.539 +    XUnmapWindow(display, data->window);
  12.540 +}
  12.541 +
  12.542 +void
  12.543 +X11_RaiseWindow(_THIS, SDL_Window * window)
  12.544 +{
  12.545 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
  12.546 +    Display *display = data->videodata->display;
  12.547 +
  12.548 +    XRaiseWindow(display, data->window);
  12.549 +}
  12.550 +
  12.551 +void
  12.552 +X11_MaximizeWindow(_THIS, SDL_Window * window)
  12.553 +{
  12.554 +    /* FIXME: is this even possible? */
  12.555 +}
  12.556 +
  12.557 +void
  12.558 +X11_MinimizeWindow(_THIS, SDL_Window * window)
  12.559 +{
  12.560 +    X11_HideWindow(_this, window);
  12.561 +}
  12.562 +
  12.563 +void
  12.564 +X11_RestoreWindow(_THIS, SDL_Window * window)
  12.565 +{
  12.566 +    X11_ShowWindow(_this, window);
  12.567 +}
  12.568 +
  12.569 +void
  12.570 +X11_SetWindowGrab(_THIS, SDL_Window * window)
  12.571 +{
  12.572 +    /* FIXME */
  12.573 +}
  12.574 +
  12.575 +void
  12.576 +X11_DestroyWindow(_THIS, SDL_Window * window)
  12.577 +{
  12.578 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
  12.579 +
  12.580 +    if (data) {
  12.581 +        Display *display = data->videodata->display;
  12.582 +#ifdef SDL_VIDEO_OPENGL
  12.583 +        /*
  12.584 +           if (window->flags & SDL_WINDOW_OPENGL) {
  12.585 +           X11_GL_CleanupWindow(_this, window);
  12.586 +           }
  12.587 +         */
  12.588 +#endif
  12.589 +#ifdef X_HAVE_UTF8_STRING
  12.590 +        if (data->ic) {
  12.591 +            XDestroyIC(data->ic);
  12.592 +        }
  12.593 +#endif
  12.594 +        if (data->created) {
  12.595 +            XDestroyWindow(display, data->window);
  12.596 +        }
  12.597 +        SDL_free(data);
  12.598 +    }
  12.599 +}
  12.600 +
  12.601 +SDL_bool
  12.602 +X11_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
  12.603 +{
  12.604 +    if (info->version.major <= SDL_MAJOR_VERSION) {
  12.605 +        /* FIXME! */
  12.606 +        return SDL_TRUE;
  12.607 +    } else {
  12.608 +        SDL_SetError("Application not compiled with SDL %d.%d\n",
  12.609 +                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
  12.610 +        return SDL_FALSE;
  12.611 +    }
  12.612 +}
  12.613 +
  12.614 +/* vi: set ts=4 sw=4 expandtab: */
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/video/x11/SDL_x11window.h	Thu Jul 27 06:53:23 2006 +0000
    13.3 @@ -0,0 +1,54 @@
    13.4 +/*
    13.5 +    SDL - Simple DirectMedia Layer
    13.6 +    Copyright (C) 1997-2006 Sam Lantinga
    13.7 +
    13.8 +    This library is free software; you can redistribute it and/or
    13.9 +    modify it under the terms of the GNU Lesser General Public
   13.10 +    License as published by the Free Software Foundation; either
   13.11 +    version 2.1 of the License, or (at your option) any later version.
   13.12 +
   13.13 +    This library is distributed in the hope that it will be useful,
   13.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13.16 +    Lesser General Public License for more details.
   13.17 +
   13.18 +    You should have received a copy of the GNU Lesser General Public
   13.19 +    License along with this library; if not, write to the Free Software
   13.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   13.21 +
   13.22 +    Sam Lantinga
   13.23 +    slouken@libsdl.org
   13.24 +*/
   13.25 +#include "SDL_config.h"
   13.26 +
   13.27 +#ifndef _SDL_x11window_h
   13.28 +#define _SDL_x11window_h
   13.29 +
   13.30 +typedef struct
   13.31 +{
   13.32 +    SDL_WindowID windowID;
   13.33 +    Window window;
   13.34 +    XIC ic;
   13.35 +    SDL_bool created;
   13.36 +    struct SDL_VideoData *videodata;
   13.37 +} SDL_WindowData;
   13.38 +
   13.39 +extern int X11_CreateWindow(_THIS, SDL_Window * window);
   13.40 +extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
   13.41 +extern void X11_SetWindowTitle(_THIS, SDL_Window * window);
   13.42 +extern void X11_SetWindowPosition(_THIS, SDL_Window * window);
   13.43 +extern void X11_SetWindowSize(_THIS, SDL_Window * window);
   13.44 +extern void X11_ShowWindow(_THIS, SDL_Window * window);
   13.45 +extern void X11_HideWindow(_THIS, SDL_Window * window);
   13.46 +extern void X11_RaiseWindow(_THIS, SDL_Window * window);
   13.47 +extern void X11_MaximizeWindow(_THIS, SDL_Window * window);
   13.48 +extern void X11_MinimizeWindow(_THIS, SDL_Window * window);
   13.49 +extern void X11_RestoreWindow(_THIS, SDL_Window * window);
   13.50 +extern void X11_SetWindowGrab(_THIS, SDL_Window * window);
   13.51 +extern void X11_DestroyWindow(_THIS, SDL_Window * window);
   13.52 +extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window,
   13.53 +                                    struct SDL_SysWMinfo *info);
   13.54 +
   13.55 +#endif /* _SDL_x11window_h */
   13.56 +
   13.57 +/* vi: set ts=4 sw=4 expandtab: */