src/video/x11/SDL_x11modes.c
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
child 1690 43ba677b4f62
equal deleted inserted replaced
1667:1fddae038bc8 1668:4da1ee79c9af
    37 
    37 
    38 #define MAX(a, b)        (a > b ? a : b)
    38 #define MAX(a, b)        (a > b ? a : b)
    39 
    39 
    40 #if SDL_VIDEO_DRIVER_X11_VIDMODE
    40 #if SDL_VIDEO_DRIVER_X11_VIDMODE
    41 int
    41 int
    42 vidmode_refreshrate (SDL_NAME (XF86VidModeModeInfo) * mode)
    42 vidmode_refreshrate(SDL_NAME(XF86VidModeModeInfo) * mode)
    43 {
    43 {
    44     return (mode->htotal
    44     return (mode->htotal
    45             && mode->vtotal) ? (1000 * mode->dotclock / (mode->htotal *
    45             && mode->vtotal) ? (1000 * mode->dotclock / (mode->htotal *
    46                                                          mode->vtotal)) : 0;
    46                                                          mode->vtotal)) : 0;
    47 }
    47 }
    48 #endif
    48 #endif
    49 
    49 
    50 #if SDL_VIDEO_DRIVER_X11_VIDMODE
    50 #if SDL_VIDEO_DRIVER_X11_VIDMODE
    51 Bool SDL_NAME (XF86VidModeGetModeInfo) (Display * dpy, int scr,
    51 Bool SDL_NAME(XF86VidModeGetModeInfo) (Display * dpy, int scr,
    52                                         SDL_NAME (XF86VidModeModeInfo) * info)
    52                                        SDL_NAME(XF86VidModeModeInfo) * info)
    53 {
    53 {
    54     SDL_NAME (XF86VidModeModeLine) * l =
    54     SDL_NAME(XF86VidModeModeLine) * l =
    55         (SDL_NAME (XF86VidModeModeLine) *) ((char *) info +
    55         (SDL_NAME(XF86VidModeModeLine) *) ((char *) info +
    56                                             sizeof info->dotclock);
    56                                            sizeof info->dotclock);
    57     return SDL_NAME (XF86VidModeGetModeLine) (dpy, scr,
    57     return SDL_NAME(XF86VidModeGetModeLine) (dpy, scr,
    58                                               (int *) &info->dotclock, l);
    58                                              (int *) &info->dotclock, l);
    59 }
    59 }
    60 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
    60 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
    61 
    61 
    62 #if SDL_VIDEO_DRIVER_X11_VIDMODE
    62 #if SDL_VIDEO_DRIVER_X11_VIDMODE
    63 static void
    63 static void
    64 save_mode (_THIS)
    64 save_mode(_THIS)
    65 {
    65 {
    66     SDL_memset (&saved_mode, 0, sizeof (saved_mode));
    66     SDL_memset(&saved_mode, 0, sizeof(saved_mode));
    67     SDL_NAME (XF86VidModeGetModeInfo) (SDL_Display, SDL_Screen, &saved_mode);
    67     SDL_NAME(XF86VidModeGetModeInfo) (SDL_Display, SDL_Screen, &saved_mode);
    68     SDL_NAME (XF86VidModeGetViewPort) (SDL_Display, SDL_Screen, &saved_view.x,
    68     SDL_NAME(XF86VidModeGetViewPort) (SDL_Display, SDL_Screen, &saved_view.x,
    69                                        &saved_view.y);
    69                                       &saved_view.y);
    70 }
    70 }
    71 #endif
    71 #endif
    72 
    72 
    73 #if SDL_VIDEO_DRIVER_X11_VIDMODE
    73 #if SDL_VIDEO_DRIVER_X11_VIDMODE
    74 static void
    74 static void
    75 restore_mode (_THIS)
    75 restore_mode(_THIS)
    76 {
    76 {
    77     SDL_NAME (XF86VidModeModeLine) mode;
    77     SDL_NAME(XF86VidModeModeLine) mode;
    78     int unused;
    78     int unused;
    79 
    79 
    80     if (SDL_NAME (XF86VidModeGetModeLine)
    80     if (SDL_NAME(XF86VidModeGetModeLine)
    81         (SDL_Display, SDL_Screen, &unused, &mode)) {
    81         (SDL_Display, SDL_Screen, &unused, &mode)) {
    82         if ((saved_mode.hdisplay != mode.hdisplay) ||
    82         if ((saved_mode.hdisplay != mode.hdisplay) ||
    83             (saved_mode.vdisplay != mode.vdisplay)) {
    83             (saved_mode.vdisplay != mode.vdisplay)) {
    84             SDL_NAME (XF86VidModeSwitchToMode) (SDL_Display, SDL_Screen,
    84             SDL_NAME(XF86VidModeSwitchToMode) (SDL_Display, SDL_Screen,
    85                                                 &saved_mode);
    85                                                &saved_mode);
    86         }
    86         }
    87     }
    87     }
    88     if ((saved_view.x != 0) || (saved_view.y != 0)) {
    88     if ((saved_view.x != 0) || (saved_view.y != 0)) {
    89         SDL_NAME (XF86VidModeSetViewPort) (SDL_Display, SDL_Screen,
    89         SDL_NAME(XF86VidModeSetViewPort) (SDL_Display, SDL_Screen,
    90                                            saved_view.x, saved_view.y);
    90                                           saved_view.x, saved_view.y);
    91     }
    91     }
    92 }
    92 }
    93 #endif
    93 #endif
    94 
    94 
    95 static void get_real_resolution (_THIS, int *w, int *h);
    95 static void get_real_resolution(_THIS, int *w, int *h);
    96 
    96 
    97 static void
    97 static void
    98 set_best_resolution (_THIS, int width, int height)
    98 set_best_resolution(_THIS, int width, int height)
    99 {
    99 {
   100     SDL_DisplayMode mode;
   100     SDL_DisplayMode mode;
   101 
   101 
   102     mode.format = 0;
   102     mode.format = 0;
   103     mode.w = width;
   103     mode.w = width;
   104     mode.h = height;
   104     mode.h = height;
   105     mode.refresh_rate = 0;
   105     mode.refresh_rate = 0;
   106     SDL_GetClosestDisplayMode (&mode, &mode, SDL_FULLSCREEN);
   106     SDL_GetClosestDisplayMode(&mode, &mode, SDL_FULLSCREEN);
   107 
   107 
   108 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   108 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   109     if (use_vidmode) {
   109     if (use_vidmode) {
   110         SDL_NAME (XF86VidModeModeLine) vmode;
   110         SDL_NAME(XF86VidModeModeLine) vmode;
   111         SDL_NAME (XF86VidModeModeInfo) vinfo;
   111         SDL_NAME(XF86VidModeModeInfo) vinfo;
   112         SDL_NAME (XF86VidModeModeInfo) ** modes;
   112         SDL_NAME(XF86VidModeModeInfo) ** modes;
   113         int i, dotclock;
   113         int i, dotclock;
   114         int nmodes;
   114         int nmodes;
   115         int best = -1;
   115         int best = -1;
   116 
   116 
   117         if (SDL_NAME (XF86VidModeGetModeLine)
   117         if (SDL_NAME(XF86VidModeGetModeLine)
   118             (SDL_Display, SDL_Screen, &dotclock, &vmode)
   118             (SDL_Display, SDL_Screen, &dotclock, &vmode)
   119             && SDL_NAME (XF86VidModeGetAllModeLines) (SDL_Display,
   119             && SDL_NAME(XF86VidModeGetAllModeLines) (SDL_Display,
   120                                                       SDL_Screen, &nmodes,
   120                                                      SDL_Screen, &nmodes,
   121                                                       &modes)) {
   121                                                      &modes)) {
   122             vinfo.dotclock = dotclock;
   122             vinfo.dotclock = dotclock;
   123             SDL_memcpy (&vinfo.hdisplay, &vmode, sizeof (vmode));
   123             SDL_memcpy(&vinfo.hdisplay, &vmode, sizeof(vmode));
   124 
   124 
   125             for (i = 0; i < nmodes; i++) {
   125             for (i = 0; i < nmodes; i++) {
   126                 if ((modes[i]->hdisplay == mode.w) &&
   126                 if ((modes[i]->hdisplay == mode.w) &&
   127                     (modes[i]->vdisplay == mode.h) &&
   127                     (modes[i]->vdisplay == mode.h) &&
   128                     (vidmode_refreshrate (modes[i]) == mode.refresh_rate)) {
   128                     (vidmode_refreshrate(modes[i]) == mode.refresh_rate)) {
   129                     best = i;
   129                     best = i;
   130                     break;
   130                     break;
   131                 }
   131                 }
   132             }
   132             }
   133             if (best >= 0 &&
   133             if (best >= 0 &&
   134                 ((modes[best]->hdisplay != vmode.hdisplay) ||
   134                 ((modes[best]->hdisplay != vmode.hdisplay) ||
   135                  (modes[best]->vdisplay != vmode.vdisplay) ||
   135                  (modes[best]->vdisplay != vmode.vdisplay) ||
   136                  (vidmode_refreshrate (modes[best]) !=
   136                  (vidmode_refreshrate(modes[best]) !=
   137                   vidmode_refreshrate (&vinfo)))) {
   137                   vidmode_refreshrate(&vinfo)))) {
   138 #ifdef X11MODES_DEBUG
   138 #ifdef X11MODES_DEBUG
   139                 printf ("Best Mode %d: %d x %d @ %d\n", best,
   139                 printf("Best Mode %d: %d x %d @ %d\n", best,
   140                         modes[best]->hdisplay, modes[best]->vdisplay,
   140                        modes[best]->hdisplay, modes[best]->vdisplay,
   141                         vidmode_refreshrate (modes[best]));
   141                        vidmode_refreshrate(modes[best]));
   142 #endif
   142 #endif
   143                 SDL_NAME (XF86VidModeSwitchToMode) (SDL_Display,
   143                 SDL_NAME(XF86VidModeSwitchToMode) (SDL_Display,
   144                                                     SDL_Screen, modes[best]);
   144                                                    SDL_Screen, modes[best]);
   145             }
   145             }
   146             XFree (modes);
   146             XFree(modes);
   147         }
   147         }
   148     }
   148     }
   149 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
   149 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
   150 
   150 
   151     /* XiG */
   151     /* XiG */
   153     if (use_xme) {
   153     if (use_xme) {
   154         int i;
   154         int i;
   155         int w, h;
   155         int w, h;
   156 
   156 
   157         /* check current mode so we can avoid uneccessary mode changes */
   157         /* check current mode so we can avoid uneccessary mode changes */
   158         get_real_resolution (this, &w, &h);
   158         get_real_resolution(this, &w, &h);
   159 
   159 
   160         if ((mode.w != w) || (mode.h != h)) {
   160         if ((mode.w != w) || (mode.h != h)) {
   161 #ifdef X11MODES_DEBUG
   161 #ifdef X11MODES_DEBUG
   162             fprintf (stderr, "XME: set_best_resolution: "
   162             fprintf(stderr, "XME: set_best_resolution: "
   163                      "XiGMiscChangeResolution: %d %d\n", mode.w, mode.h);
   163                     "XiGMiscChangeResolution: %d %d\n", mode.w, mode.h);
   164 #endif
   164 #endif
   165             XiGMiscChangeResolution (SDL_Display, SDL_Screen, 0,        /* view */
   165             XiGMiscChangeResolution(SDL_Display, SDL_Screen, 0, /* view */
   166                                      mode.w, mode.h, 0);
   166                                     mode.w, mode.h, 0);
   167             XSync (SDL_Display, False);
   167             XSync(SDL_Display, False);
   168         }
   168         }
   169     }
   169     }
   170 #endif /* SDL_VIDEO_DRIVER_X11_XME */
   170 #endif /* SDL_VIDEO_DRIVER_X11_XME */
   171 
   171 
   172 #if SDL_VIDEO_DRIVER_X11_XRANDR
   172 #if SDL_VIDEO_DRIVER_X11_XRANDR
   173     if (use_xrandr) {
   173     if (use_xrandr) {
   174         int i, nsizes;
   174         int i, nsizes;
   175         XRRScreenSize *sizes;
   175         XRRScreenSize *sizes;
   176 
   176 
   177         /* find the smallest resolution that is at least as big as the user requested */
   177         /* find the smallest resolution that is at least as big as the user requested */
   178         sizes = XRRConfigSizes (screen_config, &nsizes);
   178         sizes = XRRConfigSizes(screen_config, &nsizes);
   179         for (i = (nsizes - 1); i >= 0; i--) {
   179         for (i = (nsizes - 1); i >= 0; i--) {
   180             if ((mode.w >= width) && (mode.h >= height)) {
   180             if ((mode.w >= width) && (mode.h >= height)) {
   181                 break;
   181                 break;
   182             }
   182             }
   183         }
   183         }
   184 
   184 
   185         if (i >= 0) {           /* found one, lets try it */
   185         if (i >= 0) {           /* found one, lets try it */
   186             int w, h;
   186             int w, h;
   187 
   187 
   188             /* check current mode so we can avoid uneccessary mode changes */
   188             /* check current mode so we can avoid uneccessary mode changes */
   189             get_real_resolution (this, &w, &h);
   189             get_real_resolution(this, &w, &h);
   190 
   190 
   191             if ((mode.w != w) || (mode.h != h)) {
   191             if ((mode.w != w) || (mode.h != h)) {
   192                 int size_id;
   192                 int size_id;
   193 
   193 
   194 #ifdef X11MODES_DEBUG
   194 #ifdef X11MODES_DEBUG
   195                 fprintf (stderr, "XRANDR: set_best_resolution: "
   195                 fprintf(stderr, "XRANDR: set_best_resolution: "
   196                          "XXRSetScreenConfig: %d %d\n", mode.w, mode.h);
   196                         "XXRSetScreenConfig: %d %d\n", mode.w, mode.h);
   197 #endif
   197 #endif
   198 
   198 
   199                 /* find the matching size entry index */
   199                 /* find the matching size entry index */
   200                 for (size_id = 0; size_id < nsizes; ++size_id) {
   200                 for (size_id = 0; size_id < nsizes; ++size_id) {
   201                     if ((sizes[size_id].width == mode.w) &&
   201                     if ((sizes[size_id].width == mode.w) &&
   202                         (sizes[size_id].height == mode.h))
   202                         (sizes[size_id].height == mode.h))
   203                         break;
   203                         break;
   204                 }
   204                 }
   205 
   205 
   206                 XRRSetScreenConfig (SDL_Display, screen_config,
   206                 XRRSetScreenConfig(SDL_Display, screen_config,
   207                                     SDL_Root, size_id, saved_rotation,
   207                                    SDL_Root, size_id, saved_rotation,
   208                                     CurrentTime);
   208                                    CurrentTime);
   209             }
   209             }
   210         }
   210         }
   211     }
   211     }
   212 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   212 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   213 }
   213 }
   214 
   214 
   215 static void
   215 static void
   216 get_real_resolution (_THIS, int *w, int *h)
   216 get_real_resolution(_THIS, int *w, int *h)
   217 {
   217 {
   218 #if SDL_VIDEO_DRIVER_X11_XME
   218 #if SDL_VIDEO_DRIVER_X11_XME
   219     if (use_xme) {
   219     if (use_xme) {
   220         int ractive;
   220         int ractive;
   221         XiGMiscResolutionInfo *modelist;
   221         XiGMiscResolutionInfo *modelist;
   222 
   222 
   223         XiGMiscQueryResolutions (SDL_Display, SDL_Screen, 0,    /* view */
   223         XiGMiscQueryResolutions(SDL_Display, SDL_Screen, 0,     /* view */
   224                                  &ractive, &modelist);
   224                                 &ractive, &modelist);
   225         *w = modelist[ractive].width;
   225         *w = modelist[ractive].width;
   226         *h = modelist[ractive].height;
   226         *h = modelist[ractive].height;
   227 #ifdef X11MODES_DEBUG
   227 #ifdef X11MODES_DEBUG
   228         fprintf (stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h);
   228         fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h);
   229 #endif
   229 #endif
   230         XFree (modelist);
   230         XFree(modelist);
   231         return;
   231         return;
   232     }
   232     }
   233 #endif /* SDL_VIDEO_DRIVER_X11_XME */
   233 #endif /* SDL_VIDEO_DRIVER_X11_XME */
   234 
   234 
   235 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   235 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   236     if (use_vidmode) {
   236     if (use_vidmode) {
   237         SDL_NAME (XF86VidModeModeLine) mode;
   237         SDL_NAME(XF86VidModeModeLine) mode;
   238         int unused;
   238         int unused;
   239 
   239 
   240         if (SDL_NAME (XF86VidModeGetModeLine)
   240         if (SDL_NAME(XF86VidModeGetModeLine)
   241             (SDL_Display, SDL_Screen, &unused, &mode)) {
   241             (SDL_Display, SDL_Screen, &unused, &mode)) {
   242             *w = mode.hdisplay;
   242             *w = mode.hdisplay;
   243             *h = mode.vdisplay;
   243             *h = mode.vdisplay;
   244             return;
   244             return;
   245         }
   245         }
   249 #if SDL_VIDEO_DRIVER_X11_XRANDR
   249 #if SDL_VIDEO_DRIVER_X11_XRANDR
   250     if (use_xrandr) {
   250     if (use_xrandr) {
   251         int nsizes;
   251         int nsizes;
   252         XRRScreenSize *sizes;
   252         XRRScreenSize *sizes;
   253 
   253 
   254         sizes = XRRConfigSizes (screen_config, &nsizes);
   254         sizes = XRRConfigSizes(screen_config, &nsizes);
   255         if (nsizes > 0) {
   255         if (nsizes > 0) {
   256             int cur_size;
   256             int cur_size;
   257             Rotation cur_rotation;
   257             Rotation cur_rotation;
   258 
   258 
   259             cur_size =
   259             cur_size =
   260                 XRRConfigCurrentConfiguration (screen_config, &cur_rotation);
   260                 XRRConfigCurrentConfiguration(screen_config, &cur_rotation);
   261             if (cur_size >= 0 && cur_size < nsizes) {
   261             if (cur_size >= 0 && cur_size < nsizes) {
   262                 *w = sizes[cur_size].width;
   262                 *w = sizes[cur_size].width;
   263                 *h = sizes[cur_size].height;
   263                 *h = sizes[cur_size].height;
   264             }
   264             }
   265 #ifdef X11MODES_DEBUG
   265 #ifdef X11MODES_DEBUG
   266             fprintf (stderr,
   266             fprintf(stderr,
   267                      "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h);
   267                     "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h);
   268 #endif
   268 #endif
   269             return;
   269             return;
   270         }
   270         }
   271     }
   271     }
   272 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   272 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   277         *h = xinerama[this->current_display].height;
   277         *h = xinerama[this->current_display].height;
   278         return;
   278         return;
   279     }
   279     }
   280 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
   280 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
   281 
   281 
   282     *w = DisplayWidth (SDL_Display, SDL_Screen);
   282     *w = DisplayWidth(SDL_Display, SDL_Screen);
   283     *h = DisplayHeight (SDL_Display, SDL_Screen);
   283     *h = DisplayHeight(SDL_Display, SDL_Screen);
   284 }
   284 }
   285 
   285 
   286 /* Called after mapping a window - waits until the window is mapped */
   286 /* Called after mapping a window - waits until the window is mapped */
   287 void
   287 void
   288 X11_WaitMapped (_THIS, Window win)
   288 X11_WaitMapped(_THIS, Window win)
   289 {
   289 {
   290     XEvent event;
   290     XEvent event;
   291     do {
   291     do {
   292         XMaskEvent (SDL_Display, StructureNotifyMask, &event);
   292         XMaskEvent(SDL_Display, StructureNotifyMask, &event);
   293     }
   293     }
   294     while ((event.type != MapNotify) || (event.xmap.event != win));
   294     while ((event.type != MapNotify) || (event.xmap.event != win));
   295 }
   295 }
   296 
   296 
   297 /* Called after unmapping a window - waits until the window is unmapped */
   297 /* Called after unmapping a window - waits until the window is unmapped */
   298 void
   298 void
   299 X11_WaitUnmapped (_THIS, Window win)
   299 X11_WaitUnmapped(_THIS, Window win)
   300 {
   300 {
   301     XEvent event;
   301     XEvent event;
   302     do {
   302     do {
   303         XMaskEvent (SDL_Display, StructureNotifyMask, &event);
   303         XMaskEvent(SDL_Display, StructureNotifyMask, &event);
   304     }
   304     }
   305     while ((event.type != UnmapNotify) || (event.xunmap.event != win));
   305     while ((event.type != UnmapNotify) || (event.xunmap.event != win));
   306 }
   306 }
   307 
   307 
   308 static void
   308 static void
   309 move_cursor_to (_THIS, int x, int y)
   309 move_cursor_to(_THIS, int x, int y)
   310 {
   310 {
   311     XWarpPointer (SDL_Display, None, SDL_Root, 0, 0, 0, 0, x, y);
   311     XWarpPointer(SDL_Display, None, SDL_Root, 0, 0, 0, 0, x, y);
   312 }
   312 }
   313 
   313 
   314 static int
   314 static int
   315 add_visual (_THIS, int depth, int class)
   315 add_visual(_THIS, int depth, int class)
   316 {
   316 {
   317     XVisualInfo vi;
   317     XVisualInfo vi;
   318     if (XMatchVisualInfo (SDL_Display, SDL_Screen, depth, class, &vi)) {
   318     if (XMatchVisualInfo(SDL_Display, SDL_Screen, depth, class, &vi)) {
   319         int n = this->hidden->nvisuals;
   319         int n = this->hidden->nvisuals;
   320         this->hidden->visuals[n].depth = vi.depth;
   320         this->hidden->visuals[n].depth = vi.depth;
   321         this->hidden->visuals[n].visual = vi.visual;
   321         this->hidden->visuals[n].visual = vi.visual;
   322         this->hidden->nvisuals++;
   322         this->hidden->nvisuals++;
   323     }
   323     }
   324     return (this->hidden->nvisuals);
   324     return (this->hidden->nvisuals);
   325 }
   325 }
   326 static int
   326 static int
   327 add_visual_byid (_THIS, const char *visual_id)
   327 add_visual_byid(_THIS, const char *visual_id)
   328 {
   328 {
   329     XVisualInfo *vi, template;
   329     XVisualInfo *vi, template;
   330     int nvis;
   330     int nvis;
   331 
   331 
   332     if (visual_id) {
   332     if (visual_id) {
   333         SDL_memset (&template, 0, (sizeof template));
   333         SDL_memset(&template, 0, (sizeof template));
   334         template.visualid = SDL_strtol (visual_id, NULL, 0);
   334         template.visualid = SDL_strtol(visual_id, NULL, 0);
   335         vi = XGetVisualInfo (SDL_Display, VisualIDMask, &template, &nvis);
   335         vi = XGetVisualInfo(SDL_Display, VisualIDMask, &template, &nvis);
   336         if (vi) {
   336         if (vi) {
   337             int n = this->hidden->nvisuals;
   337             int n = this->hidden->nvisuals;
   338             this->hidden->visuals[n].depth = vi->depth;
   338             this->hidden->visuals[n].depth = vi->depth;
   339             this->hidden->visuals[n].visual = vi->visual;
   339             this->hidden->visuals[n].visual = vi->visual;
   340             this->hidden->nvisuals++;
   340             this->hidden->nvisuals++;
   341             XFree (vi);
   341             XFree(vi);
   342         }
   342         }
   343     }
   343     }
   344     return (this->hidden->nvisuals);
   344     return (this->hidden->nvisuals);
   345 }
   345 }
   346 
   346 
   347 int
   347 int
   348 X11_GetVisuals (_THIS)
   348 X11_GetVisuals(_THIS)
   349 {
   349 {
   350     /* It's interesting to note that if we allow 32 bit depths,
   350     /* It's interesting to note that if we allow 32 bit depths,
   351        we get a visual with an alpha mask on composite servers.
   351        we get a visual with an alpha mask on composite servers.
   352        static int depth_list[] = { 32, 24, 16, 15, 8 };
   352        static int depth_list[] = { 32, 24, 16, 15, 8 };
   353      */
   353      */
   356     int use_directcolor = 1;
   356     int use_directcolor = 1;
   357     XPixmapFormatValues *pf;
   357     XPixmapFormatValues *pf;
   358 
   358 
   359     /* Search for the visuals in deepest-first order, so that the first
   359     /* Search for the visuals in deepest-first order, so that the first
   360        will be the richest one */
   360        will be the richest one */
   361     if (SDL_getenv ("SDL_VIDEO_X11_NODIRECTCOLOR")) {
   361     if (SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR")) {
   362         use_directcolor = 0;
   362         use_directcolor = 0;
   363     }
   363     }
   364     this->hidden->nvisuals = 0;
   364     this->hidden->nvisuals = 0;
   365     if (!add_visual_byid (this, SDL_getenv ("SDL_VIDEO_X11_VISUALID"))) {
   365     if (!add_visual_byid(this, SDL_getenv("SDL_VIDEO_X11_VISUALID"))) {
   366         for (i = 0; i < SDL_arraysize (depth_list); ++i) {
   366         for (i = 0; i < SDL_arraysize(depth_list); ++i) {
   367             if (depth_list[i] > 8) {
   367             if (depth_list[i] > 8) {
   368                 if (use_directcolor) {
   368                 if (use_directcolor) {
   369                     add_visual (this, depth_list[i], DirectColor);
   369                     add_visual(this, depth_list[i], DirectColor);
   370                 }
   370                 }
   371                 add_visual (this, depth_list[i], TrueColor);
   371                 add_visual(this, depth_list[i], TrueColor);
   372             } else {
   372             } else {
   373                 add_visual (this, depth_list[i], PseudoColor);
   373                 add_visual(this, depth_list[i], PseudoColor);
   374                 add_visual (this, depth_list[i], StaticColor);
   374                 add_visual(this, depth_list[i], StaticColor);
   375             }
   375             }
   376         }
   376         }
   377     }
   377     }
   378     if (this->hidden->nvisuals == 0) {
   378     if (this->hidden->nvisuals == 0) {
   379         SDL_SetError ("Found no sufficiently capable X11 visuals");
   379         SDL_SetError("Found no sufficiently capable X11 visuals");
   380         return -1;
   380         return -1;
   381     }
   381     }
   382 
   382 
   383     /* look up the pixel quantum for each depth */
   383     /* look up the pixel quantum for each depth */
   384     pf = XListPixmapFormats (SDL_Display, &np);
   384     pf = XListPixmapFormats(SDL_Display, &np);
   385     for (i = 0; i < this->hidden->nvisuals; i++) {
   385     for (i = 0; i < this->hidden->nvisuals; i++) {
   386         int d = this->hidden->visuals[i].depth;
   386         int d = this->hidden->visuals[i].depth;
   387         for (j = 0; j < np; j++)
   387         for (j = 0; j < np; j++)
   388             if (pf[j].depth == d)
   388             if (pf[j].depth == d)
   389                 break;
   389                 break;
   390         this->hidden->visuals[i].bpp = j < np ? pf[j].bits_per_pixel : d;
   390         this->hidden->visuals[i].bpp = j < np ? pf[j].bits_per_pixel : d;
   391     }
   391     }
   392 
   392 
   393     XFree (pf);
   393     XFree(pf);
   394     return 0;
   394     return 0;
   395 }
   395 }
   396 
   396 
   397 /* Global for the error handler */
   397 /* Global for the error handler */
   398 int vm_event, vm_error = -1;
   398 int vm_event, vm_error = -1;
   399 
   399 
   400 #if SDL_VIDEO_DRIVER_X11_XINERAMA
   400 #if SDL_VIDEO_DRIVER_X11_XINERAMA
   401 static int
   401 static int
   402 CheckXinerama (_THIS, int *major, int *minor)
   402 CheckXinerama(_THIS, int *major, int *minor)
   403 {
   403 {
   404     const char *env;
   404     const char *env;
   405 
   405 
   406     /* Default the extension not available */
   406     /* Default the extension not available */
   407     *major = *minor = 0;
   407     *major = *minor = 0;
   408 
   408 
   409     /* Allow environment override */
   409     /* Allow environment override */
   410     env = getenv ("SDL_VIDEO_X11_XINERAMA");
   410     env = getenv("SDL_VIDEO_X11_XINERAMA");
   411     if (env && !SDL_atoi (env)) {
   411     if (env && !SDL_atoi(env)) {
   412         return 0;
   412         return 0;
   413     }
   413     }
   414 
   414 
   415     /* Query the extension version */
   415     /* Query the extension version */
   416     if (!SDL_NAME (XineramaQueryExtension) (SDL_Display, major, minor) ||
   416     if (!SDL_NAME(XineramaQueryExtension) (SDL_Display, major, minor) ||
   417         !SDL_NAME (XineramaIsActive) (SDL_Display)) {
   417         !SDL_NAME(XineramaIsActive) (SDL_Display)) {
   418         return 0;
   418         return 0;
   419     }
   419     }
   420     return 1;
   420     return 1;
   421 }
   421 }
   422 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
   422 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
   423 
   423 
   424 #if SDL_VIDEO_DRIVER_X11_XRANDR
   424 #if SDL_VIDEO_DRIVER_X11_XRANDR
   425 static int
   425 static int
   426 CheckXRandR (_THIS, int *major, int *minor)
   426 CheckXRandR(_THIS, int *major, int *minor)
   427 {
   427 {
   428     const char *env;
   428     const char *env;
   429 
   429 
   430     /* Default the extension not available */
   430     /* Default the extension not available */
   431     *major = *minor = 0;
   431     *major = *minor = 0;
   432 
   432 
   433     /* Allow environment override */
   433     /* Allow environment override */
   434     env = getenv ("SDL_VIDEO_X11_XRANDR");
   434     env = getenv("SDL_VIDEO_X11_XRANDR");
   435     if (env && !SDL_atoi (env)) {
   435     if (env && !SDL_atoi(env)) {
   436         return 0;
   436         return 0;
   437     }
   437     }
   438 
   438 
   439     /* This defaults off now, due to KDE window maximize problems */
   439     /* This defaults off now, due to KDE window maximize problems */
   440     if (!env) {
   440     if (!env) {
   444     if (!SDL_X11_HAVE_XRANDR) {
   444     if (!SDL_X11_HAVE_XRANDR) {
   445         return 0;
   445         return 0;
   446     }
   446     }
   447 
   447 
   448     /* Query the extension version */
   448     /* Query the extension version */
   449     if (!XRRQueryVersion (SDL_Display, major, minor)) {
   449     if (!XRRQueryVersion(SDL_Display, major, minor)) {
   450         return 0;
   450         return 0;
   451     }
   451     }
   452     return 1;
   452     return 1;
   453 }
   453 }
   454 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   454 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   455 
   455 
   456 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   456 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   457 static int
   457 static int
   458 CheckVidMode (_THIS, int *major, int *minor)
   458 CheckVidMode(_THIS, int *major, int *minor)
   459 {
   459 {
   460     const char *env;
   460     const char *env;
   461 
   461 
   462     /* Default the extension not available */
   462     /* Default the extension not available */
   463     *major = *minor = 0;
   463     *major = *minor = 0;
   464 
   464 
   465     /* Allow environment override */
   465     /* Allow environment override */
   466     env = getenv ("SDL_VIDEO_X11_VIDMODE");
   466     env = getenv("SDL_VIDEO_X11_VIDMODE");
   467     if (env && !SDL_atoi (env)) {
   467     if (env && !SDL_atoi(env)) {
   468         return 0;
   468         return 0;
   469     }
   469     }
   470 
   470 
   471     /* Metro-X 4.3.0 and earlier has a broken implementation of
   471     /* Metro-X 4.3.0 and earlier has a broken implementation of
   472        XF86VidModeGetAllModeLines() - it hangs the client.
   472        XF86VidModeGetAllModeLines() - it hangs the client.
   473      */
   473      */
   474     if (SDL_strcmp (ServerVendor (SDL_Display), "Metro Link Incorporated") ==
   474     if (SDL_strcmp(ServerVendor(SDL_Display), "Metro Link Incorporated") == 0) {
   475         0) {
       
   476         FILE *metro_fp;
   475         FILE *metro_fp;
   477 
   476 
   478         metro_fp = fopen ("/usr/X11R6/lib/X11/Metro/.version", "r");
   477         metro_fp = fopen("/usr/X11R6/lib/X11/Metro/.version", "r");
   479         if (metro_fp != NULL) {
   478         if (metro_fp != NULL) {
   480             int major, minor, patch, version;
   479             int major, minor, patch, version;
   481             major = 0;
   480             major = 0;
   482             minor = 0;
   481             minor = 0;
   483             patch = 0;
   482             patch = 0;
   484             fscanf (metro_fp, "%d.%d.%d", &major, &minor, &patch);
   483             fscanf(metro_fp, "%d.%d.%d", &major, &minor, &patch);
   485             fclose (metro_fp);
   484             fclose(metro_fp);
   486             version = major * 100 + minor * 10 + patch;
   485             version = major * 100 + minor * 10 + patch;
   487             if (version < 431) {
   486             if (version < 431) {
   488                 return 0;
   487                 return 0;
   489             }
   488             }
   490         }
   489         }
   491     }
   490     }
   492 
   491 
   493     /* Query the extension version */
   492     /* Query the extension version */
   494     vm_error = -1;
   493     vm_error = -1;
   495     if (!SDL_NAME (XF86VidModeQueryExtension)
   494     if (!SDL_NAME(XF86VidModeQueryExtension)
   496         (SDL_Display, &vm_event, &vm_error)
   495         (SDL_Display, &vm_event, &vm_error)
   497         || !SDL_NAME (XF86VidModeQueryVersion) (SDL_Display, major, minor)) {
   496         || !SDL_NAME(XF86VidModeQueryVersion) (SDL_Display, major, minor)) {
   498         return 0;
   497         return 0;
   499     }
   498     }
   500     return 1;
   499     return 1;
   501 }
   500 }
   502 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
   501 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
   503 
   502 
   504 #if SDL_VIDEO_DRIVER_X11_XME
   503 #if SDL_VIDEO_DRIVER_X11_XME
   505 static int
   504 static int
   506 CheckXME (_THIS, int *major, int *minor)
   505 CheckXME(_THIS, int *major, int *minor)
   507 {
   506 {
   508     const char *env;
   507     const char *env;
   509 
   508 
   510     /* Default the extension not available */
   509     /* Default the extension not available */
   511     *major = *minor = 0;
   510     *major = *minor = 0;
   512 
   511 
   513     /* Allow environment override */
   512     /* Allow environment override */
   514     env = getenv ("SDL_VIDEO_X11_VIDMODE");
   513     env = getenv("SDL_VIDEO_X11_VIDMODE");
   515     if (env && !SDL_atoi (env)) {
   514     if (env && !SDL_atoi(env)) {
   516         return 0;
   515         return 0;
   517     }
   516     }
   518 
   517 
   519     /* Query the extension version */
   518     /* Query the extension version */
   520     if (!XiGMiscQueryVersion (SDL_Display, major, minor)) {
   519     if (!XiGMiscQueryVersion(SDL_Display, major, minor)) {
   521         return 0;
   520         return 0;
   522     }
   521     }
   523     return 1;
   522     return 1;
   524 }
   523 }
   525 #endif /* SDL_VIDEO_DRIVER_X11_XME */
   524 #endif /* SDL_VIDEO_DRIVER_X11_XME */
   526 
   525 
   527 int
   526 int
   528 X11_GetVideoModes (_THIS)
   527 X11_GetVideoModes(_THIS)
   529 {
   528 {
   530 #if SDL_VIDEO_DRIVER_X11_XINERAMA
   529 #if SDL_VIDEO_DRIVER_X11_XINERAMA
   531     int xinerama_major, xinerama_minor;
   530     int xinerama_major, xinerama_minor;
   532 #endif
   531 #endif
   533 #if SDL_VIDEO_DRIVER_X11_XRANDR
   532 #if SDL_VIDEO_DRIVER_X11_XRANDR
   538     short *rates;
   537     short *rates;
   539 #endif
   538 #endif
   540 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   539 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   541     int vm_major, vm_minor;
   540     int vm_major, vm_minor;
   542     int nmodes;
   541     int nmodes;
   543     SDL_NAME (XF86VidModeModeInfo) ** modes;
   542     SDL_NAME(XF86VidModeModeInfo) ** modes;
   544 #endif
   543 #endif
   545 #if SDL_VIDEO_DRIVER_X11_XME
   544 #if SDL_VIDEO_DRIVER_X11_XME
   546     int xme_major, xme_minor;
   545     int xme_major, xme_minor;
   547     int ractive, nummodes;
   546     int ractive, nummodes;
   548     XiGMiscResolutionInfo *modelist;
   547     XiGMiscResolutionInfo *modelist;
   554 
   553 
   555     use_xinerama = 0;
   554     use_xinerama = 0;
   556     use_xrandr = 0;
   555     use_xrandr = 0;
   557     use_vidmode = 0;
   556     use_vidmode = 0;
   558     use_xme = 0;
   557     use_xme = 0;
   559     screen_w = DisplayWidth (SDL_Display, SDL_Screen);
   558     screen_w = DisplayWidth(SDL_Display, SDL_Screen);
   560     screen_h = DisplayHeight (SDL_Display, SDL_Screen);
   559     screen_h = DisplayHeight(SDL_Display, SDL_Screen);
   561 
   560 
   562     mode.format = this->displays[this->current_display].desktop_mode.format;
   561     mode.format = this->displays[this->current_display].desktop_mode.format;
   563     mode.w = screen_w;
   562     mode.w = screen_w;
   564     mode.h = screen_h;
   563     mode.h = screen_h;
   565     mode.refresh_rate = 0;
   564     mode.refresh_rate = 0;
   566     SDL_AddDisplayMode (0, &mode);
   565     SDL_AddDisplayMode(0, &mode);
   567 
   566 
   568 #if SDL_VIDEO_DRIVER_X11_XINERAMA
   567 #if SDL_VIDEO_DRIVER_X11_XINERAMA
   569     /* Query Xinerama extention */
   568     /* Query Xinerama extention */
   570     if (CheckXinerama (this, &xinerama_major, &xinerama_minor)) {
   569     if (CheckXinerama(this, &xinerama_major, &xinerama_minor)) {
   571         int screens;
   570         int screens;
   572 
   571 
   573 #ifdef X11MODES_DEBUG
   572 #ifdef X11MODES_DEBUG
   574         printf ("X11 detected Xinerama:\n");
   573         printf("X11 detected Xinerama:\n");
   575 #endif
   574 #endif
   576         xinerama = SDL_NAME (XineramaQueryScreens) (SDL_Display, &screens);
   575         xinerama = SDL_NAME(XineramaQueryScreens) (SDL_Display, &screens);
   577         for (i = 0; i < screens; i++) {
   576         for (i = 0; i < screens; i++) {
   578 #ifdef X11MODES_DEBUG
   577 #ifdef X11MODES_DEBUG
   579             printf ("xinerama %d: %dx%d+%d+%d\n",
   578             printf("xinerama %d: %dx%d+%d+%d\n",
   580                     xinerama[i].screen_number,
   579                    xinerama[i].screen_number,
   581                     xinerama[i].width, xinerama[i].height,
   580                    xinerama[i].width, xinerama[i].height,
   582                     xinerama[i].x_org, xinerama[i].y_org);
   581                    xinerama[i].x_org, xinerama[i].y_org);
   583 #endif
   582 #endif
   584             if (xinerama[i].screen_number != 0) {
   583             if (xinerama[i].screen_number != 0) {
   585                 SDL_AddVideoDisplay (&mode);
   584                 SDL_AddVideoDisplay(&mode);
   586             }
   585             }
   587             mode.w = xinerama[i].width;
   586             mode.w = xinerama[i].width;
   588             mode.h = xinerama[i].height;
   587             mode.h = xinerama[i].height;
   589             SDL_AddDisplayMode (xinerama[i].screen_number, &mode);
   588             SDL_AddDisplayMode(xinerama[i].screen_number, &mode);
   590         }
   589         }
   591         use_xinerama = 1;
   590         use_xinerama = 1;
   592     }
   591     }
   593 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
   592 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
   594 
   593 
   595 #if SDL_VIDEO_DRIVER_X11_XRANDR
   594 #if SDL_VIDEO_DRIVER_X11_XRANDR
   596     /* XRandR */
   595     /* XRandR */
   597     /* require at least XRandR v1.0 (arbitrary) */
   596     /* require at least XRandR v1.0 (arbitrary) */
   598     if (CheckXRandR (this, &xrandr_major, &xrandr_minor)
   597     if (CheckXRandR(this, &xrandr_major, &xrandr_minor)
   599         && (xrandr_major >= 1)) {
   598         && (xrandr_major >= 1)) {
   600 #ifdef X11MODES_DEBUG
   599 #ifdef X11MODES_DEBUG
   601         fprintf (stderr, "XRANDR: XRRQueryVersion: V%d.%d\n",
   600         fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n",
   602                  xrandr_major, xrandr_minor);
   601                 xrandr_major, xrandr_minor);
   603 #endif
   602 #endif
   604 
   603 
   605         /* save the screen configuration since we must reference it
   604         /* save the screen configuration since we must reference it
   606            each time we toggle modes.
   605            each time we toggle modes.
   607          */
   606          */
   608         screen_config = XRRGetScreenInfo (SDL_Display, SDL_Root);
   607         screen_config = XRRGetScreenInfo(SDL_Display, SDL_Root);
   609 
   608 
   610         /* retrieve the list of resolution */
   609         /* retrieve the list of resolution */
   611         sizes = XRRConfigSizes (screen_config, &nsizes);
   610         sizes = XRRConfigSizes(screen_config, &nsizes);
   612         if (nsizes > 0) {
   611         if (nsizes > 0) {
   613             for (i = 0; i < nsizes; i++) {
   612             for (i = 0; i < nsizes; i++) {
   614                 mode.w = sizes[i].width;
   613                 mode.w = sizes[i].width;
   615                 mode.h = sizes[i].height;
   614                 mode.h = sizes[i].height;
   616 
   615 
   617                 rates = XRRConfigRates (screen_config, i, &nrates);
   616                 rates = XRRConfigRates(screen_config, i, &nrates);
   618                 if (nrates == 0) {
   617                 if (nrates == 0) {
   619                     mode.refresh_rate = 0;
   618                     mode.refresh_rate = 0;
   620                     SDL_AddDisplayMode (0, &mode);
   619                     SDL_AddDisplayMode(0, &mode);
   621                 } else {
   620                 } else {
   622                     int j;
   621                     int j;
   623                     for (j = 0; j < nrates; ++j) {
   622                     for (j = 0; j < nrates; ++j) {
   624                         mode.refresh_rate = rates[j];
   623                         mode.refresh_rate = rates[j];
   625                         SDL_AddDisplayMode (0, &mode);
   624                         SDL_AddDisplayMode(0, &mode);
   626                     }
   625                     }
   627                 }
   626                 }
   628             }
   627             }
   629 
   628 
   630             use_xrandr = xrandr_major * 100 + xrandr_minor;
   629             use_xrandr = xrandr_major * 100 + xrandr_minor;
   631             saved_size_id =
   630             saved_size_id =
   632                 XRRConfigCurrentConfiguration (screen_config,
   631                 XRRConfigCurrentConfiguration(screen_config, &saved_rotation);
   633                                                &saved_rotation);
       
   634         }
   632         }
   635     }
   633     }
   636 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   634 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   637 
   635 
   638 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   636 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   639     /* XVidMode */
   637     /* XVidMode */
   640     if (!use_xrandr &&
   638     if (!use_xrandr &&
   641         CheckVidMode (this, &vm_major, &vm_minor) &&
   639         CheckVidMode(this, &vm_major, &vm_minor) &&
   642         SDL_NAME (XF86VidModeGetAllModeLines) (SDL_Display, SDL_Screen,
   640         SDL_NAME(XF86VidModeGetAllModeLines) (SDL_Display, SDL_Screen,
   643                                                &nmodes, &modes)) {
   641                                               &nmodes, &modes)) {
   644 #ifdef X11MODES_DEBUG
   642 #ifdef X11MODES_DEBUG
   645         printf ("VidMode modes: (unsorted)\n");
   643         printf("VidMode modes: (unsorted)\n");
   646         for (i = 0; i < nmodes; ++i) {
   644         for (i = 0; i < nmodes; ++i) {
   647             printf ("Mode %d: %d x %d @ %d\n", i,
   645             printf("Mode %d: %d x %d @ %d\n", i,
   648                     modes[i]->hdisplay, modes[i]->vdisplay,
   646                    modes[i]->hdisplay, modes[i]->vdisplay,
   649                     vidmode_refreshrate (modes[i]));
   647                    vidmode_refreshrate(modes[i]));
   650         }
   648         }
   651 #endif
   649 #endif
   652         for (i = 0; i < nmodes; ++i) {
   650         for (i = 0; i < nmodes; ++i) {
   653             mode.w = modes[i]->hdisplay;
   651             mode.w = modes[i]->hdisplay;
   654             mode.h = modes[i]->vdisplay;
   652             mode.h = modes[i]->vdisplay;
   655             mode.refresh_rate = vidmode_refreshrate (modes[i]);
   653             mode.refresh_rate = vidmode_refreshrate(modes[i]);
   656             SDL_AddDisplayMode (0, &mode);
   654             SDL_AddDisplayMode(0, &mode);
   657         }
   655         }
   658         XFree (modes);
   656         XFree(modes);
   659 
   657 
   660         use_vidmode = vm_major * 100 + vm_minor;
   658         use_vidmode = vm_major * 100 + vm_minor;
   661         save_mode (this);
   659         save_mode(this);
   662     }
   660     }
   663 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
   661 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
   664 
   662 
   665 #if SDL_VIDEO_DRIVER_X11_XME
   663 #if SDL_VIDEO_DRIVER_X11_XME
   666     /* XiG */
   664     /* XiG */
   667     modelist = NULL;
   665     modelist = NULL;
   668     /* first lets make sure we have the extension, and it's at least v2.0 */
   666     /* first lets make sure we have the extension, and it's at least v2.0 */
   669     if (CheckXME (this, &xme_major, &xme_minor) && xme_major >= 2 && (nummodes = XiGMiscQueryResolutions (SDL_Display, SDL_Screen, 0,   /* view */
   667     if (CheckXME(this, &xme_major, &xme_minor) && xme_major >= 2 && (nummodes = XiGMiscQueryResolutions(SDL_Display, SDL_Screen, 0,     /* view */
   670                                                                                                           &ractive,
   668                                                                                                         &ractive,
   671                                                                                                           &modelist))
   669                                                                                                         &modelist))
   672         > 1) {                  /* then we actually have some */
   670         > 1) {                  /* then we actually have some */
   673         /* We get the list already sorted in descending order.
   671         /* We get the list already sorted in descending order.
   674            We'll copy it in reverse order so SDL is happy */
   672            We'll copy it in reverse order so SDL is happy */
   675 #ifdef X11MODES_DEBUG
   673 #ifdef X11MODES_DEBUG
   676         fprintf (stderr, "XME: nummodes = %d, active mode = %d\n",
   674         fprintf(stderr, "XME: nummodes = %d, active mode = %d\n",
   677                  nummodes, ractive);
   675                 nummodes, ractive);
   678 #endif
   676 #endif
   679         mode.refresh_rate = 0;
   677         mode.refresh_rate = 0;
   680         for (i = 0; i < nummodes; ++i) {
   678         for (i = 0; i < nummodes; ++i) {
   681 #ifdef X11MODES_DEBUG
   679 #ifdef X11MODES_DEBUG
   682             fprintf (stderr, "XME: mode = %4d, w = %4d, h = %4d\n",
   680             fprintf(stderr, "XME: mode = %4d, w = %4d, h = %4d\n",
   683                      i, modelist[i].width, modelist[i].height);
   681                     i, modelist[i].width, modelist[i].height);
   684 #endif
   682 #endif
   685             mode.w = modelist[i].width;
   683             mode.w = modelist[i].width;
   686             mode.h = modelist[i].height;
   684             mode.h = modelist[i].height;
   687             SDL_AddDisplayMode (0, &mode);
   685             SDL_AddDisplayMode(0, &mode);
   688         }
   686         }
   689 
   687 
   690         use_xme = xme_major * 100 + xme_minor;
   688         use_xme = xme_major * 100 + xme_minor;
   691         saved_res = modelist[ractive];  /* save the current resolution */
   689         saved_res = modelist[ractive];  /* save the current resolution */
   692     }
   690     }
   693     if (modelist) {
   691     if (modelist) {
   694         XFree (modelist);
   692         XFree(modelist);
   695     }
   693     }
   696 #endif /* SDL_VIDEO_DRIVER_X11_XME */
   694 #endif /* SDL_VIDEO_DRIVER_X11_XME */
   697 
   695 
   698 #ifdef X11MODES_DEBUG
   696 #ifdef X11MODES_DEBUG
   699     if (use_xinerama) {
   697     if (use_xinerama) {
   700         printf ("Xinerama is enabled\n");
   698         printf("Xinerama is enabled\n");
   701     }
   699     }
   702 
   700 
   703     if (use_xrandr) {
   701     if (use_xrandr) {
   704         printf ("XRandR is enabled\n");
   702         printf("XRandR is enabled\n");
   705     }
   703     }
   706 
   704 
   707     if (use_vidmode) {
   705     if (use_vidmode) {
   708         printf ("VidMode is enabled\n");
   706         printf("VidMode is enabled\n");
   709     }
   707     }
   710 
   708 
   711     if (use_xme) {
   709     if (use_xme) {
   712         printf ("Xi Graphics XME fullscreen is enabled\n");
   710         printf("Xi Graphics XME fullscreen is enabled\n");
   713     }
   711     }
   714 #endif /* X11MODES_DEBUG */
   712 #endif /* X11MODES_DEBUG */
   715 
   713 
   716     return 0;
   714     return 0;
   717 }
   715 }
   718 
   716 
   719 void
   717 void
   720 X11_FreeVideoModes (_THIS)
   718 X11_FreeVideoModes(_THIS)
   721 {
   719 {
   722 #if SDL_VIDEO_DRIVER_X11_XRANDR
   720 #if SDL_VIDEO_DRIVER_X11_XRANDR
   723     /* Free the Xrandr screen configuration */
   721     /* Free the Xrandr screen configuration */
   724     if (screen_config) {
   722     if (screen_config) {
   725         XRRFreeScreenConfigInfo (screen_config);
   723         XRRFreeScreenConfigInfo(screen_config);
   726         screen_config = NULL;
   724         screen_config = NULL;
   727     }
   725     }
   728 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   726 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   729 }
   727 }
   730 
   728 
   731 int
   729 int
   732 X11_ResizeFullScreen (_THIS)
   730 X11_ResizeFullScreen(_THIS)
   733 {
   731 {
   734     int x = 0, y = 0;
   732     int x = 0, y = 0;
   735     int real_w, real_h;
   733     int real_w, real_h;
   736     int screen_w;
   734     int screen_w;
   737     int screen_h;
   735     int screen_h;
   738 
   736 
   739     screen_w = DisplayWidth (SDL_Display, SDL_Screen);
   737     screen_w = DisplayWidth(SDL_Display, SDL_Screen);
   740     screen_h = DisplayHeight (SDL_Display, SDL_Screen);
   738     screen_h = DisplayHeight(SDL_Display, SDL_Screen);
   741 
   739 
   742 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   740 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   743     if (use_xinerama &&
   741     if (use_xinerama &&
   744         window_w <= xinerama[this->current_display].width &&
   742         window_w <= xinerama[this->current_display].width &&
   745         window_h <= xinerama[this->current_display].height) {
   743         window_h <= xinerama[this->current_display].height) {
   747         y = xinerama[this->current_display].y_org;
   745         y = xinerama[this->current_display].y_org;
   748     }
   746     }
   749 #endif
   747 #endif
   750     if (currently_fullscreen) {
   748     if (currently_fullscreen) {
   751         /* Switch resolution and cover it with the FSwindow */
   749         /* Switch resolution and cover it with the FSwindow */
   752         move_cursor_to (this, x, y);
   750         move_cursor_to(this, x, y);
   753         set_best_resolution (this, window_w, window_h);
   751         set_best_resolution(this, window_w, window_h);
   754         move_cursor_to (this, x, y);
   752         move_cursor_to(this, x, y);
   755         get_real_resolution (this, &real_w, &real_h);
   753         get_real_resolution(this, &real_w, &real_h);
   756         if (window_w > real_w) {
   754         if (window_w > real_w) {
   757             real_w = MAX (real_w, screen_w);
   755             real_w = MAX(real_w, screen_w);
   758         }
   756         }
   759         if (window_h > real_h) {
   757         if (window_h > real_h) {
   760             real_h = MAX (real_h, screen_h);
   758             real_h = MAX(real_h, screen_h);
   761         }
   759         }
   762         XMoveResizeWindow (SDL_Display, FSwindow, x, y, real_w, real_h);
   760         XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h);
   763         move_cursor_to (this, real_w / 2, real_h / 2);
   761         move_cursor_to(this, real_w / 2, real_h / 2);
   764 
   762 
   765         /* Center and reparent the drawing window */
   763         /* Center and reparent the drawing window */
   766         x = (real_w - window_w) / 2;
   764         x = (real_w - window_w) / 2;
   767         y = (real_h - window_h) / 2;
   765         y = (real_h - window_h) / 2;
   768         XReparentWindow (SDL_Display, SDL_Window, FSwindow, x, y);
   766         XReparentWindow(SDL_Display, SDL_Window, FSwindow, x, y);
   769         /* FIXME: move the mouse to the old relative location */
   767         /* FIXME: move the mouse to the old relative location */
   770         XSync (SDL_Display, True);      /* Flush spurious mode change events */
   768         XSync(SDL_Display, True);       /* Flush spurious mode change events */
   771     }
   769     }
   772     return (1);
   770     return (1);
   773 }
   771 }
   774 
   772 
   775 void
   773 void
   776 X11_QueueEnterFullScreen (_THIS)
   774 X11_QueueEnterFullScreen(_THIS)
   777 {
   775 {
   778     switch_waiting = 0x01 | SDL_FULLSCREEN;
   776     switch_waiting = 0x01 | SDL_FULLSCREEN;
   779     switch_time = SDL_GetTicks () + 1500;
   777     switch_time = SDL_GetTicks() + 1500;
   780 #if 0                           /* This causes a BadMatch error if the window is iconified (not needed) */
   778 #if 0                           /* This causes a BadMatch error if the window is iconified (not needed) */
   781     XSetInputFocus (SDL_Display, WMwindow, RevertToNone, CurrentTime);
   779     XSetInputFocus(SDL_Display, WMwindow, RevertToNone, CurrentTime);
   782 #endif
   780 #endif
   783 }
   781 }
   784 
   782 
   785 int
   783 int
   786 X11_EnterFullScreen (_THIS)
   784 X11_EnterFullScreen(_THIS)
   787 {
   785 {
   788     int okay;
   786     int okay;
   789 #if 0
   787 #if 0
   790     Window tmpwin, *windows;
   788     Window tmpwin, *windows;
   791     int i, nwindows;
   789     int i, nwindows;
   799     if (currently_fullscreen) {
   797     if (currently_fullscreen) {
   800         return (okay);
   798         return (okay);
   801     }
   799     }
   802 
   800 
   803     /* Ungrab the input so that we can move the mouse around */
   801     /* Ungrab the input so that we can move the mouse around */
   804     X11_GrabInputNoLock (this, SDL_GRAB_OFF);
   802     X11_GrabInputNoLock(this, SDL_GRAB_OFF);
   805 
   803 
   806 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   804 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   807     if (use_xinerama &&
   805     if (use_xinerama &&
   808         window_w <= xinerama[this->current_display].width &&
   806         window_w <= xinerama[this->current_display].width &&
   809         window_h <= xinerama[this->current_display].height) {
   807         window_h <= xinerama[this->current_display].height) {
   810         x = xinerama[this->current_display].x_org;
   808         x = xinerama[this->current_display].x_org;
   811         y = xinerama[this->current_display].y_org;
   809         y = xinerama[this->current_display].y_org;
   812     }
   810     }
   813 #endif
   811 #endif
   814     /* Map the fullscreen window to blank the screen */
   812     /* Map the fullscreen window to blank the screen */
   815     screen_w = DisplayWidth (SDL_Display, SDL_Screen);
   813     screen_w = DisplayWidth(SDL_Display, SDL_Screen);
   816     screen_h = DisplayHeight (SDL_Display, SDL_Screen);
   814     screen_h = DisplayHeight(SDL_Display, SDL_Screen);
   817     get_real_resolution (this, &real_w, &real_h);
   815     get_real_resolution(this, &real_w, &real_h);
   818     if (window_w > real_w) {
   816     if (window_w > real_w) {
   819         real_w = MAX (real_w, screen_w);
   817         real_w = MAX(real_w, screen_w);
   820     }
   818     }
   821     if (window_h > real_h) {
   819     if (window_h > real_h) {
   822         real_h = MAX (real_h, screen_h);
   820         real_h = MAX(real_h, screen_h);
   823     }
   821     }
   824     XMoveResizeWindow (SDL_Display, FSwindow, x, y, real_w, real_h);
   822     XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h);
   825     XMapRaised (SDL_Display, FSwindow);
   823     XMapRaised(SDL_Display, FSwindow);
   826     X11_WaitMapped (this, FSwindow);
   824     X11_WaitMapped(this, FSwindow);
   827 
   825 
   828 #if 0                           /* This seems to break WindowMaker in focus-follows-mouse mode */
   826 #if 0                           /* This seems to break WindowMaker in focus-follows-mouse mode */
   829     /* Make sure we got to the top of the window stack */
   827     /* Make sure we got to the top of the window stack */
   830     if (XQueryTree (SDL_Display, SDL_Root, &tmpwin, &tmpwin,
   828     if (XQueryTree(SDL_Display, SDL_Root, &tmpwin, &tmpwin,
   831                     &windows, &nwindows) && windows) {
   829                    &windows, &nwindows) && windows) {
   832         /* If not, try to put us there - if fail... oh well */
   830         /* If not, try to put us there - if fail... oh well */
   833         if (windows[nwindows - 1] != FSwindow) {
   831         if (windows[nwindows - 1] != FSwindow) {
   834             tmpwin = windows[nwindows - 1];
   832             tmpwin = windows[nwindows - 1];
   835             for (i = 0; i < nwindows; ++i) {
   833             for (i = 0; i < nwindows; ++i) {
   836                 if (windows[i] == FSwindow) {
   834                 if (windows[i] == FSwindow) {
   837                     SDL_memcpy (&windows[i], &windows[i + 1],
   835                     SDL_memcpy(&windows[i], &windows[i + 1],
   838                                 (nwindows - i - 1) * sizeof (windows[i]));
   836                                (nwindows - i - 1) * sizeof(windows[i]));
   839                     break;
   837                     break;
   840                 }
   838                 }
   841             }
   839             }
   842             windows[nwindows - 1] = FSwindow;
   840             windows[nwindows - 1] = FSwindow;
   843             XRestackWindows (SDL_Display, windows, nwindows);
   841             XRestackWindows(SDL_Display, windows, nwindows);
   844             XSync (SDL_Display, False);
   842             XSync(SDL_Display, False);
   845         }
   843         }
   846         XFree (windows);
   844         XFree(windows);
   847     }
   845     }
   848 #else
   846 #else
   849     XRaiseWindow (SDL_Display, FSwindow);
   847     XRaiseWindow(SDL_Display, FSwindow);
   850 #endif
   848 #endif
   851 
   849 
   852 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   850 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   853     /* Save the current video mode */
   851     /* Save the current video mode */
   854     if (use_vidmode) {
   852     if (use_vidmode) {
   855         SDL_NAME (XF86VidModeLockModeSwitch) (SDL_Display, SDL_Screen, True);
   853         SDL_NAME(XF86VidModeLockModeSwitch) (SDL_Display, SDL_Screen, True);
   856     }
   854     }
   857 #endif
   855 #endif
   858     currently_fullscreen = 1;
   856     currently_fullscreen = 1;
   859 
   857 
   860     /* Set the new resolution */
   858     /* Set the new resolution */
   861     okay = X11_ResizeFullScreen (this);
   859     okay = X11_ResizeFullScreen(this);
   862     if (!okay) {
   860     if (!okay) {
   863         X11_LeaveFullScreen (this);
   861         X11_LeaveFullScreen(this);
   864     }
   862     }
   865     /* Set the colormap */
   863     /* Set the colormap */
   866     if (SDL_XColorMap) {
   864     if (SDL_XColorMap) {
   867         XInstallColormap (SDL_Display, SDL_XColorMap);
   865         XInstallColormap(SDL_Display, SDL_XColorMap);
   868     }
   866     }
   869     if (okay) {
   867     if (okay) {
   870         X11_GrabInputNoLock (this,
   868         X11_GrabInputNoLock(this,
   871                              SDL_CurrentWindow.
   869                             SDL_CurrentWindow.
   872                              input_grab | SDL_GRAB_FULLSCREEN);
   870                             input_grab | SDL_GRAB_FULLSCREEN);
   873     }
   871     }
   874 
   872 
   875     /* We may need to refresh the screen at this point (no backing store)
   873     /* We may need to refresh the screen at this point (no backing store)
   876        We also don't get an event, which is why we explicitly refresh. */
   874        We also don't get an event, which is why we explicitly refresh. */
   877     if (SDL_VideoSurface) {
   875     if (SDL_VideoSurface) {
   878         if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) {
   876         if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) {
   879             SDL_PrivateExpose ();
   877             SDL_PrivateExpose();
   880         } else {
   878         } else {
   881             X11_RefreshDisplay (this);
   879             X11_RefreshDisplay(this);
   882         }
   880         }
   883     }
   881     }
   884 
   882 
   885     return (okay);
   883     return (okay);
   886 }
   884 }
   887 
   885 
   888 int
   886 int
   889 X11_LeaveFullScreen (_THIS)
   887 X11_LeaveFullScreen(_THIS)
   890 {
   888 {
   891     if (currently_fullscreen) {
   889     if (currently_fullscreen) {
   892         XReparentWindow (SDL_Display, SDL_Window, WMwindow, 0, 0);
   890         XReparentWindow(SDL_Display, SDL_Window, WMwindow, 0, 0);
   893 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   891 #if SDL_VIDEO_DRIVER_X11_VIDMODE
   894         if (use_vidmode) {
   892         if (use_vidmode) {
   895             restore_mode (this);
   893             restore_mode(this);
   896             SDL_NAME (XF86VidModeLockModeSwitch) (SDL_Display, SDL_Screen,
   894             SDL_NAME(XF86VidModeLockModeSwitch) (SDL_Display, SDL_Screen,
   897                                                   False);
   895                                                  False);
   898         }
   896         }
   899 #endif
   897 #endif
   900 
   898 
   901 #if SDL_VIDEO_DRIVER_X11_XME
   899 #if SDL_VIDEO_DRIVER_X11_XME
   902         if (use_xme) {
   900         if (use_xme) {
   903             int rw, rh;
   901             int rw, rh;
   904 
   902 
   905             /* check current mode so we can avoid uneccessary mode changes */
   903             /* check current mode so we can avoid uneccessary mode changes */
   906             get_real_resolution (this, &rw, &rh);
   904             get_real_resolution(this, &rw, &rh);
   907 
   905 
   908             if (rw != saved_res.width || rh != saved_res.height) {
   906             if (rw != saved_res.width || rh != saved_res.height) {
   909                 XiGMiscChangeResolution (SDL_Display, SDL_Screen, 0,    /* view */
   907                 XiGMiscChangeResolution(SDL_Display, SDL_Screen, 0,     /* view */
   910                                          saved_res.width,
   908                                         saved_res.width, saved_res.height, 0);
   911                                          saved_res.height, 0);
   909                 XSync(SDL_Display, False);
   912                 XSync (SDL_Display, False);
       
   913             }
   910             }
   914         }
   911         }
   915 #endif
   912 #endif
   916 
   913 
   917 #if SDL_VIDEO_DRIVER_X11_XRANDR
   914 #if SDL_VIDEO_DRIVER_X11_XRANDR
   918         if (use_xrandr) {
   915         if (use_xrandr) {
   919             XRRSetScreenConfig (SDL_Display, screen_config, SDL_Root,
   916             XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
   920                                 saved_size_id, saved_rotation, CurrentTime);
   917                                saved_size_id, saved_rotation, CurrentTime);
   921         }
   918         }
   922 #endif
   919 #endif
   923 
   920 
   924         XUnmapWindow (SDL_Display, FSwindow);
   921         XUnmapWindow(SDL_Display, FSwindow);
   925         X11_WaitUnmapped (this, FSwindow);
   922         X11_WaitUnmapped(this, FSwindow);
   926         XSync (SDL_Display, True);      /* Flush spurious mode change events */
   923         XSync(SDL_Display, True);       /* Flush spurious mode change events */
   927         currently_fullscreen = 0;
   924         currently_fullscreen = 0;
   928     }
   925     }
   929     /* If we get popped out of fullscreen mode for some reason, input_grab
   926     /* If we get popped out of fullscreen mode for some reason, input_grab
   930        will still have the SDL_GRAB_FULLSCREEN flag set, since this is only
   927        will still have the SDL_GRAB_FULLSCREEN flag set, since this is only
   931        temporary.  In this case, release the grab unless the input has been
   928        temporary.  In this case, release the grab unless the input has been
   932        explicitly grabbed.
   929        explicitly grabbed.
   933      */
   930      */
   934     X11_GrabInputNoLock (this,
   931     X11_GrabInputNoLock(this,
   935                          SDL_CurrentWindow.input_grab & ~SDL_GRAB_FULLSCREEN);
   932                         SDL_CurrentWindow.input_grab & ~SDL_GRAB_FULLSCREEN);
   936 
   933 
   937     /* We may need to refresh the screen at this point (no backing store)
   934     /* We may need to refresh the screen at this point (no backing store)
   938        We also don't get an event, which is why we explicitly refresh. */
   935        We also don't get an event, which is why we explicitly refresh. */
   939     if (SDL_VideoSurface) {
   936     if (SDL_VideoSurface) {
   940         if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) {
   937         if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) {
   941             SDL_PrivateExpose ();
   938             SDL_PrivateExpose();
   942         } else {
   939         } else {
   943             X11_RefreshDisplay (this);
   940             X11_RefreshDisplay(this);
   944         }
   941         }
   945     }
   942     }
   946 
   943 
   947     return (0);
   944     return (0);
   948 }
   945 }
   949 
   946 
   950 Uint32
   947 Uint32
   951 X11_VisualToFormat (const Visual * visual, int depth, int bpp)
   948 X11_VisualToFormat(const Visual * visual, int depth, int bpp)
   952 {
   949 {
   953     Uint32 Rmask = visual->red_mask;
   950     Uint32 Rmask = visual->red_mask;
   954     Uint32 Gmask = visual->green_mask;
   951     Uint32 Gmask = visual->green_mask;
   955     Uint32 Bmask = visual->blue_mask;
   952     Uint32 Bmask = visual->blue_mask;
   956     Uint32 Amask;
   953     Uint32 Amask;
   958     if (depth == 32) {
   955     if (depth == 32) {
   959         Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
   956         Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
   960     } else {
   957     } else {
   961         Amask = 0;
   958         Amask = 0;
   962     }
   959     }
   963     return (SDL_MasksToPixelFormatEnum (bpp, Rmask, Gmask, Bmask, Amask));
   960     return (SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask));
   964 }
   961 }
   965 
   962 
   966 /* vi: set ts=4 sw=4 expandtab: */
   963 /* vi: set ts=4 sw=4 expandtab: */