symbian-qemu-0.9.1-12/libsdl-trunk/src/video/x11/SDL_x11modes.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 1997-2006 Sam Lantinga
       
     4 
       
     5     This library is free software; you can redistribute it and/or
       
     6     modify it under the terms of the GNU Lesser General Public
       
     7     License as published by the Free Software Foundation; either
       
     8     version 2.1 of the License, or (at your option) any later version.
       
     9 
       
    10     This library is distributed in the hope that it will be useful,
       
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13     Lesser General Public License for more details.
       
    14 
       
    15     You should have received a copy of the GNU Lesser General Public
       
    16     License along with this library; if not, write to the Free Software
       
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    18 
       
    19     Sam Lantinga
       
    20     slouken@libsdl.org
       
    21 */
       
    22 #include "SDL_config.h"
       
    23 
       
    24 /* Utilities for getting and setting the X display mode */
       
    25 
       
    26 #include <stdio.h>
       
    27 
       
    28 #include "SDL_timer.h"
       
    29 #include "SDL_events.h"
       
    30 #include "../../events/SDL_events_c.h"
       
    31 #include "SDL_x11video.h"
       
    32 #include "SDL_x11wm_c.h"
       
    33 #include "SDL_x11modes_c.h"
       
    34 #include "SDL_x11image_c.h"
       
    35 
       
    36 /*#define X11MODES_DEBUG*/
       
    37 
       
    38 #define MAX(a, b)        (a > b ? a : b)
       
    39 
       
    40 #if SDL_VIDEO_DRIVER_X11_XRANDR
       
    41 static int cmpmodelist(const void *va, const void *vb)
       
    42 {
       
    43     const SDL_Rect *a = *(const SDL_Rect **)va;
       
    44     const SDL_Rect *b = *(const SDL_Rect **)vb;
       
    45     if ( a->w == b->w )
       
    46         return b->h - a->h;
       
    47     else
       
    48         return b->w - a->w;
       
    49 }
       
    50 #endif
       
    51 
       
    52 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
    53 Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info)
       
    54 {
       
    55     SDL_NAME(XF86VidModeModeLine) *l = (SDL_NAME(XF86VidModeModeLine)*)((char*)info + sizeof info->dotclock);
       
    56     return SDL_NAME(XF86VidModeGetModeLine)(dpy, scr, (int*)&info->dotclock, l);
       
    57 }
       
    58 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
       
    59 
       
    60 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
    61 static void save_mode(_THIS)
       
    62 {
       
    63     SDL_memset(&saved_mode, 0, sizeof(saved_mode));
       
    64     SDL_NAME(XF86VidModeGetModeInfo)(SDL_Display,SDL_Screen,&saved_mode);
       
    65     SDL_NAME(XF86VidModeGetViewPort)(SDL_Display,SDL_Screen,&saved_view.x,&saved_view.y);
       
    66 }
       
    67 #endif
       
    68 
       
    69 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
    70 static void restore_mode(_THIS)
       
    71 {
       
    72     SDL_NAME(XF86VidModeModeLine) mode;
       
    73     int unused;
       
    74 
       
    75     if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) {
       
    76         if ( (saved_mode.hdisplay != mode.hdisplay) ||
       
    77              (saved_mode.vdisplay != mode.vdisplay) ) {
       
    78             SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, &saved_mode);
       
    79         }
       
    80     }
       
    81     if ( (saved_view.x != 0) || (saved_view.y != 0) ) {
       
    82         SDL_NAME(XF86VidModeSetViewPort)(SDL_Display, SDL_Screen, saved_view.x, saved_view.y);
       
    83     }
       
    84 }
       
    85 #endif
       
    86 
       
    87 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
    88 static int cmpmodes(const void *va, const void *vb)
       
    89 {
       
    90     const SDL_NAME(XF86VidModeModeInfo) *a = *(const SDL_NAME(XF86VidModeModeInfo)**)va;
       
    91     const SDL_NAME(XF86VidModeModeInfo) *b = *(const SDL_NAME(XF86VidModeModeInfo)**)vb;
       
    92     if ( a->hdisplay == b->hdisplay )
       
    93         return b->vdisplay - a->vdisplay;
       
    94     else
       
    95         return b->hdisplay - a->hdisplay;
       
    96 }
       
    97 #endif
       
    98 
       
    99 static void get_real_resolution(_THIS, int* w, int* h);
       
   100 
       
   101 static void set_best_resolution(_THIS, int width, int height)
       
   102 {
       
   103 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
   104     if ( use_vidmode ) {
       
   105         SDL_NAME(XF86VidModeModeLine) mode;
       
   106         SDL_NAME(XF86VidModeModeInfo) **modes;
       
   107         int i;
       
   108         int nmodes;
       
   109         int best = -1;
       
   110 
       
   111         if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) &&
       
   112              SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes) ) {
       
   113             for ( i = 0; i < nmodes ; i++ ) {
       
   114                 if ( (modes[i]->hdisplay == width) &&
       
   115                      (modes[i]->vdisplay == height) ) {
       
   116                     best = i;
       
   117                     break;
       
   118                 }
       
   119                 if ( modes[i]->hdisplay >= width &&
       
   120                      modes[i]->vdisplay >= height ) {
       
   121                     if ( best < 0 ||
       
   122                          (modes[i]->hdisplay < modes[best]->hdisplay &&
       
   123                           modes[i]->vdisplay <= modes[best]->vdisplay) ||
       
   124                          (modes[i]->vdisplay < modes[best]->vdisplay &&
       
   125                           modes[i]->hdisplay <= modes[best]->hdisplay) ) {
       
   126                         best = i;
       
   127                     }
       
   128                 }
       
   129             }
       
   130             if ( best >= 0 &&
       
   131                  ((modes[best]->hdisplay != mode.hdisplay) ||
       
   132                   (modes[best]->vdisplay != mode.vdisplay)) ) {
       
   133 #ifdef X11MODES_DEBUG
       
   134                 printf("Best Mode %d: %d x %d @ %d\n", best,
       
   135                         modes[best]->hdisplay, modes[best]->vdisplay,
       
   136                         (modes[best]->htotal && modes[best]->vtotal) ? (1000 * modes[best]->dotclock / (modes[best]->htotal * modes[best]->vtotal)) : 0 );
       
   137 #endif
       
   138                 SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[best]);
       
   139             }
       
   140             XFree(modes);
       
   141         }
       
   142     }
       
   143 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
       
   144 
       
   145                                 /* XiG */
       
   146 #if SDL_VIDEO_DRIVER_X11_XME
       
   147     if ( use_xme && SDL_modelist ) {
       
   148         int i;
       
   149 
       
   150 #ifdef X11MODES_DEBUG
       
   151         fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n",
       
   152                 width, height);
       
   153 #endif
       
   154         for ( i=0; SDL_modelist[i]; ++i ) {
       
   155             if ( (SDL_modelist[i]->w >= width) &&
       
   156                  (SDL_modelist[i]->h >= height) ) {
       
   157                 break;
       
   158             }
       
   159         }
       
   160         
       
   161         if ( SDL_modelist[i] ) { /* found one, lets try it */
       
   162             int w, h;        
       
   163 
       
   164             /* check current mode so we can avoid uneccessary mode changes */
       
   165             get_real_resolution(this, &w, &h);
       
   166 
       
   167             if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
       
   168 #ifdef X11MODES_DEBUG
       
   169                 fprintf(stderr, "XME: set_best_resolution: "
       
   170                         "XiGMiscChangeResolution: %d %d\n",
       
   171                         SDL_modelist[i]->w, SDL_modelist[i]->h);
       
   172 #endif
       
   173                 XiGMiscChangeResolution(SDL_Display, 
       
   174                                         SDL_Screen,
       
   175                                         0, /* view */
       
   176                                         SDL_modelist[i]->w, 
       
   177                                         SDL_modelist[i]->h, 
       
   178                                         0);
       
   179                 XSync(SDL_Display, False);
       
   180             }
       
   181         }
       
   182     }
       
   183 #endif /* SDL_VIDEO_DRIVER_X11_XME */
       
   184 
       
   185 #if SDL_VIDEO_DRIVER_X11_XRANDR
       
   186     if ( use_xrandr && SDL_modelist ) {
       
   187 #ifdef X11MODES_DEBUG
       
   188         fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n",
       
   189                 width, height);
       
   190 #endif
       
   191         int i, nsizes;
       
   192         XRRScreenSize *sizes;
       
   193 
       
   194         /* find the smallest resolution that is at least as big as the user requested */
       
   195         sizes = XRRConfigSizes(screen_config, &nsizes);
       
   196         for ( i = (nsizes-1); i >= 0; i-- ) {
       
   197             if ( (SDL_modelist[i]->w >= width) &&
       
   198                  (SDL_modelist[i]->h >= height) ) {
       
   199                 break;
       
   200             }
       
   201         }
       
   202 
       
   203         if ( i >= 0 && SDL_modelist[i] ) { /* found one, lets try it */
       
   204             int w, h;
       
   205 
       
   206             /* check current mode so we can avoid uneccessary mode changes */
       
   207             get_real_resolution(this, &w, &h);
       
   208 
       
   209             if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
       
   210                 int size_id;
       
   211 
       
   212 #ifdef X11MODES_DEBUG
       
   213                 fprintf(stderr, "XRANDR: set_best_resolution: "
       
   214                         "XXRSetScreenConfig: %d %d\n",
       
   215                         SDL_modelist[i]->w, SDL_modelist[i]->h);
       
   216 #endif
       
   217 
       
   218                 /* find the matching size entry index */
       
   219                 for ( size_id = 0; size_id < nsizes; ++size_id ) {
       
   220                     if ( (sizes[size_id].width == SDL_modelist[i]->w) &&
       
   221                          (sizes[size_id].height == SDL_modelist[i]->h) )
       
   222                         break;
       
   223                 }
       
   224 
       
   225                 XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
       
   226                                    size_id, saved_rotation, CurrentTime);
       
   227             }
       
   228         }
       
   229     }
       
   230 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
       
   231 }
       
   232 
       
   233 static void get_real_resolution(_THIS, int* w, int* h)
       
   234 {
       
   235 #if SDL_VIDEO_DRIVER_X11_XME
       
   236     if ( use_xme ) {
       
   237         int ractive;
       
   238         XiGMiscResolutionInfo *modelist;
       
   239 
       
   240         XiGMiscQueryResolutions(SDL_Display, SDL_Screen,
       
   241                                 0, /* view */
       
   242                                 &ractive, &modelist);
       
   243         *w = modelist[ractive].width;
       
   244         *h = modelist[ractive].height;
       
   245 #ifdef X11MODES_DEBUG
       
   246         fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h);
       
   247 #endif
       
   248         XFree(modelist);
       
   249         return;
       
   250     }
       
   251 #endif /* SDL_VIDEO_DRIVER_X11_XME */
       
   252 
       
   253 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
   254     if ( use_vidmode ) {
       
   255         SDL_NAME(XF86VidModeModeLine) mode;
       
   256         int unused;
       
   257 
       
   258         if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) {
       
   259             *w = mode.hdisplay;
       
   260             *h = mode.vdisplay;
       
   261             return;
       
   262         }
       
   263     }
       
   264 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
       
   265 
       
   266 #if SDL_VIDEO_DRIVER_X11_XRANDR
       
   267     if ( use_xrandr ) {
       
   268         int nsizes;
       
   269         XRRScreenSize* sizes;
       
   270 
       
   271         sizes = XRRConfigSizes(screen_config, &nsizes);
       
   272         if ( nsizes > 0 ) {
       
   273             int cur_size;
       
   274             Rotation cur_rotation;
       
   275 
       
   276             cur_size = XRRConfigCurrentConfiguration(screen_config, &cur_rotation);
       
   277             if ( cur_size >= 0 && cur_size < nsizes ) {
       
   278                 *w = sizes[cur_size].width;
       
   279                 *h = sizes[cur_size].height;
       
   280             }
       
   281 #ifdef X11MODES_DEBUG
       
   282             fprintf(stderr, "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h);
       
   283 #endif
       
   284             return;
       
   285         }
       
   286     }
       
   287 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
       
   288 
       
   289 #if SDL_VIDEO_DRIVER_X11_XINERAMA
       
   290     if ( use_xinerama ) {
       
   291         *w = xinerama_info.width;
       
   292         *h = xinerama_info.height;
       
   293         return;
       
   294     }
       
   295 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
       
   296 
       
   297     *w = DisplayWidth(SDL_Display, SDL_Screen);
       
   298     *h = DisplayHeight(SDL_Display, SDL_Screen);
       
   299 }
       
   300 
       
   301 /* Called after mapping a window - waits until the window is mapped */
       
   302 void X11_WaitMapped(_THIS, Window win)
       
   303 {
       
   304     XEvent event;
       
   305     do {
       
   306         XMaskEvent(SDL_Display, StructureNotifyMask, &event);
       
   307     } while ( (event.type != MapNotify) || (event.xmap.event != win) );
       
   308 }
       
   309 
       
   310 /* Called after unmapping a window - waits until the window is unmapped */
       
   311 void X11_WaitUnmapped(_THIS, Window win)
       
   312 {
       
   313     XEvent event;
       
   314     do {
       
   315         XMaskEvent(SDL_Display, StructureNotifyMask, &event);
       
   316     } while ( (event.type != UnmapNotify) || (event.xunmap.event != win) );
       
   317 }
       
   318 
       
   319 static void move_cursor_to(_THIS, int x, int y)
       
   320 {
       
   321     XWarpPointer(SDL_Display, None, SDL_Root, 0, 0, 0, 0, x, y);
       
   322 }
       
   323 
       
   324 static int add_visual(_THIS, int depth, int class)
       
   325 {
       
   326     XVisualInfo vi;
       
   327     if(XMatchVisualInfo(SDL_Display, SDL_Screen, depth, class, &vi)) {
       
   328         int n = this->hidden->nvisuals;
       
   329         this->hidden->visuals[n].depth = vi.depth;
       
   330         this->hidden->visuals[n].visual = vi.visual;
       
   331         this->hidden->nvisuals++;
       
   332     }
       
   333     return(this->hidden->nvisuals);
       
   334 }
       
   335 static int add_visual_byid(_THIS, const char *visual_id)
       
   336 {
       
   337     XVisualInfo *vi, template;
       
   338     int nvis;
       
   339 
       
   340     if ( visual_id ) {
       
   341         SDL_memset(&template, 0, (sizeof template));
       
   342         template.visualid = SDL_strtol(visual_id, NULL, 0);
       
   343         vi = XGetVisualInfo(SDL_Display, VisualIDMask, &template, &nvis);
       
   344         if ( vi ) {
       
   345             int n = this->hidden->nvisuals;
       
   346             this->hidden->visuals[n].depth = vi->depth;
       
   347             this->hidden->visuals[n].visual = vi->visual;
       
   348             this->hidden->nvisuals++;
       
   349             XFree(vi);
       
   350         }
       
   351     }
       
   352     return(this->hidden->nvisuals);
       
   353 }
       
   354 
       
   355 /* Global for the error handler */
       
   356 int vm_event, vm_error = -1;
       
   357 
       
   358 #if SDL_VIDEO_DRIVER_X11_XINERAMA
       
   359 static int CheckXinerama(_THIS, int *major, int *minor)
       
   360 {
       
   361     const char *env;
       
   362 
       
   363     /* Default the extension not available */
       
   364     *major = *minor = 0;
       
   365 
       
   366     /* Allow environment override */
       
   367     env = getenv("SDL_VIDEO_X11_XINERAMA");
       
   368     if ( env && !SDL_atoi(env) ) {
       
   369         return 0;
       
   370     }
       
   371 
       
   372     /* Query the extension version */
       
   373     if ( !SDL_NAME(XineramaQueryExtension)(SDL_Display, major, minor) ||
       
   374          !SDL_NAME(XineramaIsActive)(SDL_Display) ) {
       
   375         return 0;
       
   376     }
       
   377     return 1;
       
   378 }
       
   379 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
       
   380 
       
   381 #if SDL_VIDEO_DRIVER_X11_XRANDR
       
   382 static int CheckXRandR(_THIS, int *major, int *minor)
       
   383 {
       
   384     const char *env;
       
   385 
       
   386     /* Default the extension not available */
       
   387     *major = *minor = 0;
       
   388 
       
   389     /* Allow environment override */
       
   390     env = getenv("SDL_VIDEO_X11_XRANDR");
       
   391     if ( env && !SDL_atoi(env) ) {
       
   392         return 0;
       
   393     }
       
   394 
       
   395     /* This defaults off now, due to KDE window maximize problems */
       
   396     if ( !env ) {
       
   397         return 0;
       
   398     }
       
   399 
       
   400     if ( !SDL_X11_HAVE_XRANDR ) {
       
   401         return 0;
       
   402     }
       
   403 
       
   404     /* Query the extension version */
       
   405     if ( !XRRQueryVersion(SDL_Display, major, minor) ) {
       
   406         return 0;
       
   407     }
       
   408     return 1;
       
   409 }
       
   410 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
       
   411 
       
   412 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
   413 static int CheckVidMode(_THIS, int *major, int *minor)
       
   414 {
       
   415     const char *env;
       
   416 
       
   417     /* Default the extension not available */
       
   418     *major = *minor = 0;
       
   419 
       
   420     /* Allow environment override */
       
   421     env = getenv("SDL_VIDEO_X11_VIDMODE");
       
   422     if ( env && !SDL_atoi(env) ) {
       
   423         return 0;
       
   424     }
       
   425     
       
   426     /* Metro-X 4.3.0 and earlier has a broken implementation of
       
   427        XF86VidModeGetAllModeLines() - it hangs the client.
       
   428      */
       
   429     if ( SDL_strcmp(ServerVendor(SDL_Display), "Metro Link Incorporated") == 0 ) {
       
   430         FILE *metro_fp;
       
   431 
       
   432         metro_fp = fopen("/usr/X11R6/lib/X11/Metro/.version", "r");
       
   433         if ( metro_fp != NULL ) {
       
   434             int major, minor, patch, version;
       
   435             major = 0; minor = 0; patch = 0;
       
   436             fscanf(metro_fp, "%d.%d.%d", &major, &minor, &patch);
       
   437             fclose(metro_fp);
       
   438             version = major*100+minor*10+patch;
       
   439             if ( version < 431 ) {
       
   440                 return 0;
       
   441             }
       
   442         }
       
   443     }
       
   444 
       
   445     /* Query the extension version */
       
   446     vm_error = -1;
       
   447     if ( !SDL_NAME(XF86VidModeQueryExtension)(SDL_Display, &vm_event, &vm_error) ||
       
   448          !SDL_NAME(XF86VidModeQueryVersion)(SDL_Display, major, minor) ) {
       
   449         return 0;
       
   450     }
       
   451     return 1;
       
   452 }
       
   453 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
       
   454 
       
   455 #if SDL_VIDEO_DRIVER_X11_XME
       
   456 static int CheckXME(_THIS, int *major, int *minor)
       
   457 {
       
   458     const char *env;
       
   459 
       
   460     /* Default the extension not available */
       
   461     *major = *minor = 0;
       
   462 
       
   463     /* Allow environment override */
       
   464     env = getenv("SDL_VIDEO_X11_VIDMODE");
       
   465     if ( env && !SDL_atoi(env) ) {
       
   466         return 0;
       
   467     }
       
   468     
       
   469     /* Query the extension version */
       
   470     if ( !XiGMiscQueryVersion(SDL_Display, major, minor) ) {
       
   471         return 0;
       
   472     }
       
   473     return 1;
       
   474 }
       
   475 #endif /* SDL_VIDEO_DRIVER_X11_XME */
       
   476 
       
   477 int X11_GetVideoModes(_THIS)
       
   478 {
       
   479 #if SDL_VIDEO_DRIVER_X11_XINERAMA
       
   480     int xinerama_major, xinerama_minor;
       
   481 #endif
       
   482 #if SDL_VIDEO_DRIVER_X11_XRANDR
       
   483     int xrandr_major, xrandr_minor;
       
   484     int nsizes;
       
   485     XRRScreenSize *sizes;
       
   486 #endif
       
   487 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
   488     int vm_major, vm_minor;
       
   489     int nmodes;
       
   490     SDL_NAME(XF86VidModeModeInfo) **modes;
       
   491 #endif
       
   492 #if SDL_VIDEO_DRIVER_X11_XME
       
   493     int xme_major, xme_minor;
       
   494     int ractive, nummodes;
       
   495     XiGMiscResolutionInfo *modelist;
       
   496 #endif
       
   497     int i, n;
       
   498     int screen_w;
       
   499     int screen_h;
       
   500 
       
   501     use_xinerama = 0;
       
   502     use_xrandr = 0;
       
   503     use_vidmode = 0;
       
   504     use_xme = 0;
       
   505     screen_w = DisplayWidth(SDL_Display, SDL_Screen);
       
   506     screen_h = DisplayHeight(SDL_Display, SDL_Screen);
       
   507 
       
   508 #if SDL_VIDEO_DRIVER_X11_XINERAMA
       
   509     /* Query Xinerama extention */
       
   510     if ( CheckXinerama(this, &xinerama_major, &xinerama_minor) ) {
       
   511         /* Find out which screen is the desired one */
       
   512         int desired = 0;
       
   513         int screens;
       
   514         int w, h;
       
   515         SDL_NAME(XineramaScreenInfo) *xinerama;
       
   516 
       
   517         const char *variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_HEAD");
       
   518         if ( variable ) {
       
   519                 desired = SDL_atoi(variable);
       
   520         }
       
   521 #ifdef X11MODES_DEBUG
       
   522         printf("X11 detected Xinerama:\n");
       
   523 #endif
       
   524         xinerama = SDL_NAME(XineramaQueryScreens)(SDL_Display, &screens);
       
   525         for ( i = 0; i < screens; i++ ) {
       
   526 #ifdef X11MODES_DEBUG
       
   527             printf("xinerama %d: %dx%d+%d+%d\n",
       
   528                 xinerama[i].screen_number,
       
   529                 xinerama[i].width, xinerama[i].height,
       
   530                 xinerama[i].x_org, xinerama[i].y_org);
       
   531 #endif
       
   532             if ( xinerama[i].screen_number == desired ) {
       
   533                 use_xinerama = 1;
       
   534                 xinerama_info = xinerama[i];
       
   535             }
       
   536         }
       
   537         XFree(xinerama);
       
   538 
       
   539         if ( use_xinerama ) {
       
   540             SDL_modelist = (SDL_Rect **)SDL_malloc(3*sizeof(SDL_Rect *));
       
   541             if ( !SDL_modelist ) {
       
   542                 SDL_OutOfMemory();
       
   543                 return -1;
       
   544             }
       
   545 
       
   546             /* Add the full xinerama mode */
       
   547             n = 0;
       
   548             w = xinerama_info.width;
       
   549             h = xinerama_info.height;
       
   550             if ( screen_w > w || screen_h > h) {
       
   551                 SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
       
   552                 if ( SDL_modelist[n] ) {
       
   553                     SDL_modelist[n]->x = 0;
       
   554                     SDL_modelist[n]->y = 0;
       
   555                     SDL_modelist[n]->w = screen_w;
       
   556                     SDL_modelist[n]->h = screen_h;
       
   557                     ++n;
       
   558                 }
       
   559             }
       
   560 
       
   561             /* Add the head xinerama mode */
       
   562             SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
       
   563             if ( SDL_modelist[n] ) {
       
   564                 SDL_modelist[n]->x = 0;
       
   565                 SDL_modelist[n]->y = 0;
       
   566                 SDL_modelist[n]->w = w;
       
   567                 SDL_modelist[n]->h = h;
       
   568                 ++n;
       
   569             }
       
   570             SDL_modelist[n] = NULL;
       
   571         }
       
   572     }
       
   573 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
       
   574 
       
   575 #if SDL_VIDEO_DRIVER_X11_XRANDR
       
   576     /* XRandR */
       
   577     /* require at least XRandR v1.0 (arbitrary) */
       
   578     if ( CheckXRandR(this, &xrandr_major, &xrandr_minor) && (xrandr_major >= 1) )
       
   579     {
       
   580 #ifdef X11MODES_DEBUG
       
   581         fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n",
       
   582                 xrandr_major, xrandr_minor);
       
   583 #endif
       
   584 
       
   585         /* save the screen configuration since we must reference it
       
   586            each time we toggle modes.
       
   587         */
       
   588         screen_config = XRRGetScreenInfo(SDL_Display, SDL_Root);
       
   589 
       
   590         /* retrieve the list of resolution */
       
   591         sizes = XRRConfigSizes(screen_config, &nsizes);
       
   592         if (nsizes > 0) {
       
   593             if ( SDL_modelist ) {
       
   594                 for ( i = 0; SDL_modelist[i]; ++i ) {
       
   595                     SDL_free(SDL_modelist[i]);
       
   596                 }
       
   597                 SDL_free(SDL_modelist);
       
   598             }
       
   599             SDL_modelist = (SDL_Rect **)malloc((nsizes+1)*sizeof(SDL_Rect *));
       
   600             if ( !SDL_modelist ) {
       
   601                 SDL_OutOfMemory();
       
   602                 return -1;
       
   603             }
       
   604             for ( i=0; i < nsizes; i++ ) {
       
   605                 if ((SDL_modelist[i] =
       
   606                      (SDL_Rect *)malloc(sizeof(SDL_Rect))) == NULL)
       
   607                     break;
       
   608 #ifdef X11MODES_DEBUG
       
   609                 fprintf(stderr, "XRANDR: mode = %4d, w = %4d, h = %4d\n",
       
   610                         i, sizes[i].width, sizes[i].height);
       
   611 #endif
       
   612 
       
   613                 SDL_modelist[i]->x = 0;
       
   614                 SDL_modelist[i]->y = 0;
       
   615                 SDL_modelist[i]->w = sizes[i].width;
       
   616                 SDL_modelist[i]->h = sizes[i].height;
       
   617 
       
   618             }
       
   619             /* sort the mode list descending as SDL expects */
       
   620             SDL_qsort(SDL_modelist, nsizes, sizeof *SDL_modelist, cmpmodelist);
       
   621             SDL_modelist[i] = NULL; /* terminator */
       
   622 
       
   623             use_xrandr = xrandr_major * 100 + xrandr_minor;
       
   624             saved_size_id = XRRConfigCurrentConfiguration(screen_config, &saved_rotation);
       
   625         }
       
   626     }
       
   627 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
       
   628 
       
   629 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
   630     /* XVidMode */
       
   631     if ( !use_xrandr &&
       
   632 #if SDL_VIDEO_DRIVER_X11_XINERAMA
       
   633          (!use_xinerama || xinerama_info.screen_number == 0) &&
       
   634 #endif
       
   635          CheckVidMode(this, &vm_major, &vm_minor) &&
       
   636          SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) )
       
   637     {
       
   638 #ifdef X11MODES_DEBUG
       
   639         printf("VidMode modes: (unsorted)\n");
       
   640         for ( i = 0; i < nmodes; ++i ) {
       
   641             printf("Mode %d: %d x %d @ %d\n", i,
       
   642                     modes[i]->hdisplay, modes[i]->vdisplay,
       
   643                     (modes[i]->htotal && modes[i]->vtotal) ? (1000 * modes[i]->dotclock / (modes[i]->htotal * modes[i]->vtotal)) : 0 );
       
   644         }
       
   645 #endif
       
   646         if ( SDL_modelist ) {
       
   647             for ( i = 0; SDL_modelist[i]; ++i ) {
       
   648                 SDL_free(SDL_modelist[i]);
       
   649             }
       
   650             SDL_free(SDL_modelist);
       
   651         }
       
   652         SDL_modelist = (SDL_Rect **)SDL_malloc((nmodes+2)*sizeof(SDL_Rect *));
       
   653         if ( !SDL_modelist ) {
       
   654             SDL_OutOfMemory();
       
   655             return -1;
       
   656         }
       
   657         SDL_qsort(modes, nmodes, sizeof *modes, cmpmodes);
       
   658         n = 0;
       
   659         for ( i=0; i<nmodes; ++i ) {
       
   660             int w, h;
       
   661 
       
   662             /* Eliminate duplicate modes with different refresh rates */
       
   663             if ( i > 0 &&
       
   664                  modes[i]->hdisplay == modes[i-1]->hdisplay &&
       
   665                  modes[i]->vdisplay == modes[i-1]->vdisplay ) {
       
   666                     continue;
       
   667             }
       
   668 
       
   669             /* Check to see if we should add the screen size (Xinerama) */
       
   670             w = modes[i]->hdisplay;
       
   671             h = modes[i]->vdisplay;
       
   672             if ( (screen_w * screen_h) >= (w * h) ) {
       
   673                 if ( (screen_w != w) || (screen_h != h) ) {
       
   674                     SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
       
   675                     if ( SDL_modelist[n] ) {
       
   676                         SDL_modelist[n]->x = 0;
       
   677                         SDL_modelist[n]->y = 0;
       
   678                         SDL_modelist[n]->w = screen_w;
       
   679                         SDL_modelist[n]->h = screen_h;
       
   680                         ++n;
       
   681                     }
       
   682                 }
       
   683                 screen_w = 0;
       
   684                 screen_h = 0;
       
   685             }
       
   686 
       
   687             /* Add the size from the video mode list */
       
   688             SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
       
   689             if ( SDL_modelist[n] == NULL ) {
       
   690                 break;
       
   691             }
       
   692             SDL_modelist[n]->x = 0;
       
   693             SDL_modelist[n]->y = 0;
       
   694             SDL_modelist[n]->w = w;
       
   695             SDL_modelist[n]->h = h;
       
   696             ++n;
       
   697         }
       
   698         SDL_modelist[n] = NULL;
       
   699         XFree(modes);
       
   700 
       
   701         use_vidmode = vm_major * 100 + vm_minor;
       
   702         save_mode(this);
       
   703     }
       
   704 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
       
   705 
       
   706 #if SDL_VIDEO_DRIVER_X11_XME
       
   707     /* XiG */
       
   708     modelist = NULL;
       
   709     /* first lets make sure we have the extension, and it's at least v2.0 */
       
   710     if ( CheckXME(this, &xme_major, &xme_minor) && xme_major >= 2 &&
       
   711          (nummodes = XiGMiscQueryResolutions(SDL_Display, SDL_Screen,
       
   712                                              0, /* view */
       
   713                                              &ractive, &modelist)) > 1 )
       
   714     {                                /* then we actually have some */
       
   715         int j;
       
   716 
       
   717         /* We get the list already sorted in descending order.
       
   718            We'll copy it in reverse order so SDL is happy */
       
   719 #ifdef X11MODES_DEBUG
       
   720         fprintf(stderr, "XME: nummodes = %d, active mode = %d\n",
       
   721                 nummodes, ractive);
       
   722 #endif
       
   723         if ( SDL_modelist ) {
       
   724             for ( i = 0; SDL_modelist[i]; ++i ) {
       
   725                 SDL_free(SDL_modelist[i]);
       
   726             }
       
   727             SDL_free(SDL_modelist);
       
   728         }
       
   729         SDL_modelist = (SDL_Rect **)SDL_malloc((nummodes+1)*sizeof(SDL_Rect *));
       
   730         if ( !SDL_modelist ) {
       
   731             SDL_OutOfMemory();
       
   732             return -1;
       
   733         }
       
   734         for ( i=0, j=nummodes-1; j>=0; i++, j-- ) {
       
   735             if ((SDL_modelist[i] = 
       
   736                  (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect))) == NULL)
       
   737               break;
       
   738 #ifdef X11MODES_DEBUG
       
   739             fprintf(stderr, "XME: mode = %4d, w = %4d, h = %4d\n",
       
   740                    i, modelist[i].width, modelist[i].height);
       
   741 #endif
       
   742             
       
   743             SDL_modelist[i]->x = 0;
       
   744             SDL_modelist[i]->y = 0;
       
   745             SDL_modelist[i]->w = modelist[j].width;
       
   746             SDL_modelist[i]->h = modelist[j].height;
       
   747             
       
   748         }
       
   749         SDL_modelist[i] = NULL; /* terminator */
       
   750 
       
   751         use_xme = xme_major * 100 + xme_minor;
       
   752         saved_res = modelist[ractive]; /* save the current resolution */
       
   753     }
       
   754     if ( modelist ) {
       
   755         XFree(modelist);
       
   756     }
       
   757 #endif /* SDL_VIDEO_DRIVER_X11_XME */
       
   758 
       
   759     {
       
   760 	/* It's interesting to note that if we allow 32 bit depths,
       
   761 	   we get a visual with an alpha mask on composite servers.
       
   762         static int depth_list[] = { 32, 24, 16, 15, 8 };
       
   763 	*/
       
   764         static int depth_list[] = { 24, 16, 15, 8 };
       
   765         int j, np;
       
   766         int use_directcolor = 1;
       
   767         XPixmapFormatValues *pf;
       
   768 
       
   769         /* Search for the visuals in deepest-first order, so that the first
       
   770            will be the richest one */
       
   771         if ( SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) {
       
   772                 use_directcolor = 0;
       
   773         }
       
   774         this->hidden->nvisuals = 0;
       
   775         if ( ! add_visual_byid(this, SDL_getenv("SDL_VIDEO_X11_VISUALID")) ) {
       
   776                 for ( i=0; i<SDL_arraysize(depth_list); ++i ) {
       
   777                         if ( depth_list[i] > 8 ) {
       
   778                                 if ( use_directcolor ) {
       
   779                                         add_visual(this, depth_list[i], DirectColor);
       
   780                                 }
       
   781                                 add_visual(this, depth_list[i], TrueColor);
       
   782                         } else {
       
   783                                 add_visual(this, depth_list[i], PseudoColor);
       
   784                                 add_visual(this, depth_list[i], StaticColor);
       
   785                         }
       
   786                 }
       
   787         }
       
   788         if ( this->hidden->nvisuals == 0 ) {
       
   789             SDL_SetError("Found no sufficiently capable X11 visuals");
       
   790             return -1;
       
   791         }
       
   792             
       
   793         /* look up the pixel quantum for each depth */
       
   794         pf = XListPixmapFormats(SDL_Display, &np);
       
   795         for(i = 0; i < this->hidden->nvisuals; i++) {
       
   796             int d = this->hidden->visuals[i].depth;
       
   797             for(j = 0; j < np; j++)
       
   798                 if(pf[j].depth == d)
       
   799                     break;
       
   800             this->hidden->visuals[i].bpp = j < np ? pf[j].bits_per_pixel : d;
       
   801         }
       
   802 
       
   803         XFree(pf);
       
   804     }
       
   805 
       
   806     if ( SDL_modelist == NULL ) {
       
   807         SDL_modelist = (SDL_Rect **)SDL_malloc((1+1)*sizeof(SDL_Rect *));
       
   808         if ( !SDL_modelist ) {
       
   809             SDL_OutOfMemory();
       
   810             return -1;
       
   811         }
       
   812         n = 0;
       
   813         SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
       
   814         if ( SDL_modelist[n] ) {
       
   815             SDL_modelist[n]->x = 0;
       
   816             SDL_modelist[n]->y = 0;
       
   817             SDL_modelist[n]->w = screen_w;
       
   818             SDL_modelist[n]->h = screen_h;
       
   819             ++n;
       
   820         }
       
   821         SDL_modelist[n] = NULL;
       
   822     }
       
   823 
       
   824 #ifdef X11MODES_DEBUG
       
   825     if ( use_xinerama ) {
       
   826         printf("Xinerama is enabled\n");
       
   827     }
       
   828 
       
   829     if ( use_xrandr ) {
       
   830         printf("XRandR is enabled\n");
       
   831     }
       
   832 
       
   833     if ( use_vidmode ) {
       
   834         printf("VidMode is enabled\n");
       
   835     }
       
   836 
       
   837     if ( use_xme ) {
       
   838         printf("Xi Graphics XME fullscreen is enabled\n");
       
   839     }
       
   840 
       
   841     if ( SDL_modelist ) {
       
   842         printf("X11 video mode list:\n");
       
   843         for ( i=0; SDL_modelist[i]; ++i ) {
       
   844             printf("\t%dx%d\n", SDL_modelist[i]->w, SDL_modelist[i]->h);
       
   845         }
       
   846     }
       
   847 #endif /* X11MODES_DEBUG */
       
   848 
       
   849     return 0;
       
   850 }
       
   851 
       
   852 int X11_SupportedVisual(_THIS, SDL_PixelFormat *format)
       
   853 {
       
   854     int i;
       
   855     for(i = 0; i < this->hidden->nvisuals; i++)
       
   856         if(this->hidden->visuals[i].bpp == format->BitsPerPixel)
       
   857             return 1;
       
   858     return 0;
       
   859 }
       
   860 
       
   861 SDL_Rect **X11_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
       
   862 {
       
   863     if ( X11_SupportedVisual(this, format) ) {
       
   864         if ( flags & SDL_FULLSCREEN ) {
       
   865             return(SDL_modelist);
       
   866         } else {
       
   867             return((SDL_Rect **)-1);
       
   868         }
       
   869     } else {
       
   870         return((SDL_Rect **)0);
       
   871     }
       
   872 }
       
   873 
       
   874 void X11_FreeVideoModes(_THIS)
       
   875 {
       
   876     int i;
       
   877 
       
   878     if ( SDL_modelist ) {
       
   879         for ( i=0; SDL_modelist[i]; ++i ) {
       
   880             SDL_free(SDL_modelist[i]);
       
   881         }
       
   882         SDL_free(SDL_modelist);
       
   883         SDL_modelist = NULL;
       
   884     }
       
   885 
       
   886 #if SDL_VIDEO_DRIVER_X11_XRANDR
       
   887     /* Free the Xrandr screen configuration */
       
   888     if ( screen_config ) {
       
   889         XRRFreeScreenConfigInfo(screen_config);
       
   890         screen_config = NULL;
       
   891     }
       
   892 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
       
   893 }
       
   894 
       
   895 int X11_ResizeFullScreen(_THIS)
       
   896 {
       
   897     int x = 0, y = 0;
       
   898     int real_w, real_h;
       
   899     int screen_w;
       
   900     int screen_h;
       
   901 
       
   902     screen_w = DisplayWidth(SDL_Display, SDL_Screen);
       
   903     screen_h = DisplayHeight(SDL_Display, SDL_Screen);
       
   904 
       
   905 #if SDL_VIDEO_DRIVER_X11_XINERAMA
       
   906     if ( use_xinerama &&
       
   907          window_w <= xinerama_info.width &&
       
   908          window_h <= xinerama_info.height ) {
       
   909         x = xinerama_info.x_org;
       
   910         y = xinerama_info.y_org;
       
   911     }
       
   912 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
       
   913 
       
   914     if ( currently_fullscreen ) {
       
   915         /* Switch resolution and cover it with the FSwindow */
       
   916         move_cursor_to(this, x, y);
       
   917         set_best_resolution(this, window_w, window_h);
       
   918         move_cursor_to(this, x, y);
       
   919         get_real_resolution(this, &real_w, &real_h);
       
   920         if ( window_w > real_w ) {
       
   921             real_w = MAX(real_w, screen_w);
       
   922         }
       
   923         if ( window_h > real_h ) {
       
   924             real_h = MAX(real_h, screen_h);
       
   925         }
       
   926         XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h);
       
   927         move_cursor_to(this, real_w/2, real_h/2);
       
   928 
       
   929         /* Center and reparent the drawing window */
       
   930         x = (real_w - window_w)/2;
       
   931         y = (real_h - window_h)/2;
       
   932         XReparentWindow(SDL_Display, SDL_Window, FSwindow, x, y);
       
   933         /* FIXME: move the mouse to the old relative location */
       
   934         XSync(SDL_Display, True);   /* Flush spurious mode change events */
       
   935     }
       
   936     return(1);
       
   937 }
       
   938 
       
   939 void X11_QueueEnterFullScreen(_THIS)
       
   940 {
       
   941     switch_waiting = 0x01 | SDL_FULLSCREEN;
       
   942     switch_time = SDL_GetTicks() + 1500;
       
   943 #if 0 /* This causes a BadMatch error if the window is iconified (not needed) */
       
   944     XSetInputFocus(SDL_Display, WMwindow, RevertToNone, CurrentTime);
       
   945 #endif
       
   946 }
       
   947 
       
   948 int X11_EnterFullScreen(_THIS)
       
   949 {
       
   950     int okay;
       
   951 #if 0
       
   952     Window tmpwin, *windows;
       
   953     int i, nwindows;
       
   954 #endif
       
   955     int x = 0, y = 0;
       
   956     int real_w, real_h;
       
   957     int screen_w;
       
   958     int screen_h;
       
   959 
       
   960     okay = 1;
       
   961     if ( currently_fullscreen ) {
       
   962         return(okay);
       
   963     }
       
   964 
       
   965     /* Ungrab the input so that we can move the mouse around */
       
   966     X11_GrabInputNoLock(this, SDL_GRAB_OFF);
       
   967 
       
   968 #if SDL_VIDEO_DRIVER_X11_XINERAMA
       
   969     if ( use_xinerama &&
       
   970          window_w <= xinerama_info.width &&
       
   971          window_h <= xinerama_info.height ) {
       
   972         x = xinerama_info.x_org;
       
   973         y = xinerama_info.y_org;
       
   974     }
       
   975 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
       
   976 
       
   977     /* Map the fullscreen window to blank the screen */
       
   978     screen_w = DisplayWidth(SDL_Display, SDL_Screen);
       
   979     screen_h = DisplayHeight(SDL_Display, SDL_Screen);
       
   980     get_real_resolution(this, &real_w, &real_h);
       
   981     if ( window_w > real_w ) {
       
   982         real_w = MAX(real_w, screen_w);
       
   983     }
       
   984     if ( window_h > real_h ) {
       
   985         real_h = MAX(real_h, screen_h);
       
   986     }
       
   987     XMoveResizeWindow(SDL_Display, FSwindow,
       
   988                       x, y, real_w, real_h);
       
   989     XMapRaised(SDL_Display, FSwindow);
       
   990     X11_WaitMapped(this, FSwindow);
       
   991 
       
   992 #if 0 /* This seems to break WindowMaker in focus-follows-mouse mode */
       
   993     /* Make sure we got to the top of the window stack */
       
   994     if ( XQueryTree(SDL_Display, SDL_Root, &tmpwin, &tmpwin,
       
   995                             &windows, &nwindows) && windows ) {
       
   996         /* If not, try to put us there - if fail... oh well */
       
   997         if ( windows[nwindows-1] != FSwindow ) {
       
   998             tmpwin = windows[nwindows-1];
       
   999             for ( i=0; i<nwindows; ++i ) {
       
  1000                 if ( windows[i] == FSwindow ) {
       
  1001                     SDL_memcpy(&windows[i], &windows[i+1],
       
  1002                            (nwindows-i-1)*sizeof(windows[i]));
       
  1003                     break;
       
  1004                 }
       
  1005             }
       
  1006             windows[nwindows-1] = FSwindow;
       
  1007             XRestackWindows(SDL_Display, windows, nwindows);
       
  1008             XSync(SDL_Display, False);
       
  1009         }
       
  1010         XFree(windows);
       
  1011     }
       
  1012 #else
       
  1013     XRaiseWindow(SDL_Display, FSwindow);
       
  1014 #endif
       
  1015 
       
  1016 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
  1017     /* Save the current video mode */
       
  1018     if ( use_vidmode ) {
       
  1019         SDL_NAME(XF86VidModeLockModeSwitch)(SDL_Display, SDL_Screen, True);
       
  1020     }
       
  1021 #endif
       
  1022     currently_fullscreen = 1;
       
  1023 
       
  1024     /* Set the new resolution */
       
  1025     okay = X11_ResizeFullScreen(this);
       
  1026     if ( ! okay ) {
       
  1027         X11_LeaveFullScreen(this);
       
  1028     }
       
  1029     /* Set the colormap */
       
  1030     if ( SDL_XColorMap ) {
       
  1031         XInstallColormap(SDL_Display, SDL_XColorMap);
       
  1032     }
       
  1033     if ( okay ) {
       
  1034         X11_GrabInputNoLock(this, this->input_grab | SDL_GRAB_FULLSCREEN);
       
  1035     }
       
  1036 
       
  1037     /* We may need to refresh the screen at this point (no backing store)
       
  1038        We also don't get an event, which is why we explicitly refresh. */
       
  1039     if ( this->screen ) {
       
  1040         if ( this->screen->flags & SDL_OPENGL ) {
       
  1041             SDL_PrivateExpose();
       
  1042         } else {
       
  1043             X11_RefreshDisplay(this);
       
  1044         }
       
  1045     }
       
  1046 
       
  1047     return(okay);
       
  1048 }
       
  1049 
       
  1050 int X11_LeaveFullScreen(_THIS)
       
  1051 {
       
  1052     if ( currently_fullscreen ) {
       
  1053         XReparentWindow(SDL_Display, SDL_Window, WMwindow, 0, 0);
       
  1054 #if SDL_VIDEO_DRIVER_X11_VIDMODE
       
  1055         if ( use_vidmode ) {
       
  1056             restore_mode(this);
       
  1057             SDL_NAME(XF86VidModeLockModeSwitch)(SDL_Display, SDL_Screen, False);
       
  1058         }
       
  1059 #endif
       
  1060 
       
  1061 #if SDL_VIDEO_DRIVER_X11_XME
       
  1062         if ( use_xme ) {
       
  1063             int rw, rh;        
       
  1064             
       
  1065             /* check current mode so we can avoid uneccessary mode changes */
       
  1066             get_real_resolution(this, &rw, &rh);
       
  1067 
       
  1068             if (rw != saved_res.width || rh != saved_res.height) {
       
  1069                 XiGMiscChangeResolution(SDL_Display, 
       
  1070                                         SDL_Screen,
       
  1071                                         0, /* view */
       
  1072                                         saved_res.width, 
       
  1073                                         saved_res.height,
       
  1074                                         0);
       
  1075                 XSync(SDL_Display, False);
       
  1076             }
       
  1077         }
       
  1078 #endif
       
  1079 
       
  1080 #if SDL_VIDEO_DRIVER_X11_XRANDR
       
  1081         if ( use_xrandr ) {
       
  1082             XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
       
  1083                                saved_size_id, saved_rotation, CurrentTime);
       
  1084         }
       
  1085 #endif
       
  1086 
       
  1087         XUnmapWindow(SDL_Display, FSwindow);
       
  1088         X11_WaitUnmapped(this, FSwindow);
       
  1089         XSync(SDL_Display, True);   /* Flush spurious mode change events */
       
  1090         currently_fullscreen = 0;
       
  1091     }
       
  1092     /* If we get popped out of fullscreen mode for some reason, input_grab
       
  1093        will still have the SDL_GRAB_FULLSCREEN flag set, since this is only
       
  1094        temporary.  In this case, release the grab unless the input has been
       
  1095        explicitly grabbed.
       
  1096      */
       
  1097     X11_GrabInputNoLock(this, this->input_grab & ~SDL_GRAB_FULLSCREEN);
       
  1098 
       
  1099     /* We may need to refresh the screen at this point (no backing store)
       
  1100        We also don't get an event, which is why we explicitly refresh. */
       
  1101     if ( this->screen ) {
       
  1102         if ( this->screen->flags & SDL_OPENGL ) {
       
  1103             SDL_PrivateExpose();
       
  1104         } else {
       
  1105             X11_RefreshDisplay(this);
       
  1106         }
       
  1107     }
       
  1108 
       
  1109     return(0);
       
  1110 }