--- allegro-4.2.0/include/xalleg.h.fullscreen 2004-12-02 02:02:31.000000000 +0100
+++ allegro-4.2.0/include/xalleg.h 2006-03-03 23:10:18.000000000 +0100
@@ -124,8 +124,8 @@
#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
XF86VidModeModeInfo **modesinfo;
int num_modes;
- int mode_switched;
- int override_redirected;
+ int mode_switched; /* only kept around and set for ABI compat */
+ int override_redirected; /* no longer used, kept for ABI compat */
#endif
char window_title[1024];
@@ -139,6 +139,18 @@
#endif
void (*close_button_callback)(void);
+
+ /* These are at the end of the struct to maintain abi compat with
+ allegro-4.2.0 (if and only if compiled with the same configuration).
+ Notice that IMHO apps really shouldnot be using _xwin, but we export it,
+ so its fair game. */
+#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
+ XF86VidModeModeInfo *orig_modeinfo;
+#endif
+ /* Seperate fullscreen and managed window id's, see
+ _xwin_private_create_window in src/x/xwin.c for more details. */
+ Window fs_window;
+ Window wm_window;
} _xwin;
--- allegro-4.2.0/src/x/xwin.c.fullscreen 2005-10-27 23:23:40.000000000 +0200
+++ allegro-4.2.0/src/x/xwin.c 2006-03-03 23:52:22.000000000 +0100
@@ -142,7 +142,12 @@
NULL, /* mutex */
#endif
- NULL /* window close hook */
+ NULL, /* window close hook */
+#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
+ 0, /* orig_modeinfo */
+#endif
+ None, /* fs_window */
+ None /* wm_window */
};
void *allegro_icon = alex_xpm;
@@ -199,7 +204,6 @@
static void _xwin_private_set_palette_range(AL_CONST PALETTE p, int from, int to);
static void _xwin_private_set_window_defaults(void);
static void _xwin_private_flush_buffers(void);
-static void _xwin_private_resize_window(int w, int h);
static void _xwin_private_process_event(XEvent *event);
static void _xwin_private_set_warped_mouse_mode(int permanent);
static void _xwin_private_redraw_window(int x, int y, int w, int h);
@@ -261,7 +265,8 @@
static void _xwin_private_slow_palette_32(int sx, int sy, int sw, int sh);
#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
-static int _xvidmode_private_set_fullscreen(int w, int h);
+static void _xvidmode_private_set_fullscreen(int w, int h, int *vidmode_width,
+ int *vidmode_height);
static void _xvidmode_private_unset_fullscreen(void);
#endif
@@ -372,10 +377,31 @@
}
}
-
+/* _xwin_wait_mapped:
+ * wait for a window to become mapped. (shamelessly borrowed from SDL)
+ */
+static void _xwin_wait_mapped(Window win)
+{
+ XEvent event;
+ do {
+ XMaskEvent(_xwin.display, StructureNotifyMask, &event);
+ } while ( (event.type != MapNotify) || (event.xmap.event != win) );
+}
/* _xwin_create_window:
- * Wrapper for XCreateWindow.
+ * We use 3 windows:
+ * -fs_window (for fullscreen)
+ * -wm_window (window managed)
+ * -window (the real window)
+ * 2 of which will be created here: wm_window and window. The fullscreen
+ * window gets (re)created when needed, because reusing it causes trouble see:
+ * http://sourceforge.net/tracker/index.php?func=detail&aid=1441740&group_id=5665&atid=105665
+ * The real window uses wm_window as parent initially and will be reparened to
+ * the (freshly created) fullscreen window when requested and reparented
+ * back again in screen_destroy.
+ *
+ * Idea / concept of 3 windows borrowed from SDL. But somehow SDL manages
+ * to reuse the fullscreen window too.
*/
static int _xwin_private_create_window(void)
{
@@ -389,21 +415,23 @@
_mouse_on = FALSE;
- /* Create window. */
+ /* Create the managed window. */
+ setattr.background_pixel = XBlackPixel(_xwin.display, _xwin.screen);
setattr.border_pixel = XBlackPixel(_xwin.display, _xwin.screen);
- setattr.event_mask = (KeyPressMask | KeyReleaseMask
+ setattr.event_mask = (KeyPressMask | KeyReleaseMask | StructureNotifyMask
| EnterWindowMask | LeaveWindowMask
| FocusChangeMask | ExposureMask | PropertyChangeMask
| ButtonPressMask | ButtonReleaseMask | PointerMotionMask
/*| MappingNotifyMask (SubstructureRedirectMask?)*/);
- _xwin.window = XCreateWindow(_xwin.display, XDefaultRootWindow(_xwin.display),
+ _xwin.wm_window = XCreateWindow(_xwin.display,
+ XDefaultRootWindow(_xwin.display),
0, 0, 320, 200, 0,
CopyFromParent, InputOutput, CopyFromParent,
- CWBorderPixel | CWEventMask, &setattr);
-
+ CWBackPixel | CWBorderPixel | CWEventMask,
+ &setattr);
/* Get associated visual and window depth (bits per pixel). */
- XGetWindowAttributes(_xwin.display, _xwin.window, &getattr);
+ XGetWindowAttributes(_xwin.display, _xwin.wm_window, &getattr);
_xwin.visual = getattr.visual;
_xwin.window_depth = getattr.depth;
@@ -411,15 +439,27 @@
if ((_xwin.visual->class == PseudoColor)
|| (_xwin.visual->class == GrayScale)
|| (_xwin.visual->class == DirectColor))
- _xwin.colormap = XCreateColormap(_xwin.display, _xwin.window, _xwin.visual, AllocAll);
+ _xwin.colormap = XCreateColormap(_xwin.display, _xwin.wm_window, _xwin.visual, AllocAll);
else
- _xwin.colormap = XCreateColormap(_xwin.display, _xwin.window, _xwin.visual, AllocNone);
- XSetWindowColormap(_xwin.display, _xwin.window, _xwin.colormap);
+ _xwin.colormap = XCreateColormap(_xwin.display, _xwin.wm_window, _xwin.visual, AllocNone);
+ XSetWindowColormap(_xwin.display, _xwin.wm_window, _xwin.colormap);
XInstallColormap(_xwin.display, _xwin.colormap);
+
+ /* Create the real / drawing window (reuses setattr). */
+ setattr.colormap = _xwin.colormap;
+ _xwin.window = XCreateWindow(_xwin.display,
+ _xwin.wm_window,
+ 0, 0, 320, 200, 0,
+ CopyFromParent, InputOutput, CopyFromParent,
+ CWBackPixel | CWBorderPixel | CWEventMask |
+ CWColormap, &setattr);
+ /* Map the real / drawing window it won't appear untill the parent does */
+ XMapWindow(_xwin.display, _xwin.window);
+
/* Set WM_DELETE_WINDOW atom in WM_PROTOCOLS property (to get window_delete requests). */
wm_delete_window = XInternAtom (_xwin.display, "WM_DELETE_WINDOW", False);
- XSetWMProtocols (_xwin.display, _xwin.window, &wm_delete_window, 1);
+ XSetWMProtocols (_xwin.display, _xwin.wm_window, &wm_delete_window, 1);
/* Set default window parameters. */
(*_xwin_window_defaultor)();
@@ -494,6 +534,11 @@
XDestroyWindow(_xwin.display, _xwin.window);
_xwin.window = None;
}
+
+ if (_xwin.wm_window != None) {
+ XDestroyWindow(_xwin.display, _xwin.wm_window);
+ _xwin.wm_window = None;
+ }
}
void _xwin_destroy_window(void)
@@ -673,10 +718,6 @@
static BITMAP *_xwin_private_create_screen(GFX_DRIVER *drv, int w, int h,
int vw, int vh, int depth, int fullscreen)
{
-#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
- XSetWindowAttributes setattr;
-#endif
-
if (_xwin.window == None) {
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("No window"));
return 0;
@@ -711,55 +752,48 @@
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported color depth"));
return 0;
}
-
-#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
- /* If we are going fullscreen, disable window decorations. */
- if (fullscreen) {
- setattr.override_redirect = True;
- XChangeWindowAttributes(_xwin.display, _xwin.window,
- CWOverrideRedirect, &setattr);
- _xwin.override_redirected = 1;
- }
-#endif
-
- /* Set window size and save dimensions. */
- _xwin_private_resize_window(w, h);
+
+ /* Save dimensions. */
+ _xwin.window_width = w;
+ _xwin.window_height = h;
_xwin.screen_width = w;
_xwin.screen_height = h;
_xwin.screen_depth = depth;
_xwin.virtual_width = vw;
_xwin.virtual_height = vh;
-#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
- if (fullscreen) {
- AL_CONST char *fc;
- char tmp1[64], tmp2[128];
- int i;
-
- /* Switch video mode. */
- if (!_xvidmode_private_set_fullscreen(w, h)) {
- ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not set video mode"));
- return 0;
- }
+ /* Resize the (real) window */
+ XResizeWindow(_xwin.display, _xwin.window, w, h);
- /* Hack: make the window fully visible and center cursor. */
- XMoveWindow(_xwin.display, _xwin.window, 0, 0);
- XF86VidModeSetViewPort(_xwin.display, _xwin.screen, 0, 0);
-
- /* This chunk is disabled by default because of problems on KDE desktops. */
- fc = get_config_string(uconvert_ascii("graphics", tmp1),
- uconvert_ascii("force_centering", tmp2),
- NULL);
-
- if ((fc) && ((i = ugetc(fc)) != 0) && ((i == 'y') || (i == 'Y') || (i == '1'))) {
- XWarpPointer(_xwin.display, None, _xwin.window, 0, 0, 0, 0, 0, 0);
- XWarpPointer(_xwin.display, None, _xwin.window, 0, 0, 0, 0, w - 1, 0);
- XWarpPointer(_xwin.display, None, _xwin.window, 0, 0, 0, 0, 0, h - 1);
- XWarpPointer(_xwin.display, None, _xwin.window, 0, 0, 0, 0, w - 1, h - 1);
- }
+ if (fullscreen) {
+ XSetWindowAttributes setattr;
+ /* local width and height vars used for fullscreen window size and for
+ storing the video_mode size which is then used to center the window */
+ int fs_width = DisplayWidth(_xwin.display, _xwin.screen);
+ int fs_height = DisplayHeight(_xwin.display, _xwin.screen);
- XWarpPointer(_xwin.display, None, _xwin.window, 0, 0, 0, 0, w / 2, h / 2);
- XSync(_xwin.display, False);
+ /* Create the fullscreen window */
+ setattr.override_redirect = True;
+ setattr.background_pixel = XBlackPixel(_xwin.display, _xwin.screen);
+ setattr.border_pixel = XBlackPixel(_xwin.display, _xwin.screen);
+ setattr.event_mask = StructureNotifyMask;
+ setattr.colormap = _xwin.colormap;
+ _xwin.fs_window = XCreateWindow(_xwin.display,
+ XDefaultRootWindow(_xwin.display),
+ 0, 0, fs_width, fs_height, 0,
+ CopyFromParent, InputOutput,
+ CopyFromParent, CWOverrideRedirect |
+ CWBackPixel | CWColormap | CWBorderPixel |
+ CWEventMask, &setattr);
+
+ /* Map the fullscreen window */
+ XMapRaised(_xwin.display, _xwin.fs_window);
+ _xwin_wait_mapped(_xwin.fs_window);
+ /* Make sure we got to the top of the window stack */
+ XRaiseWindow(_xwin.display, _xwin.fs_window);
+
+ /* Reparent the real window */
+ XReparentWindow(_xwin.display, _xwin.window, _xwin.fs_window, 0, 0);
/* Grab the keyboard and mouse. */
if (XGrabKeyboard(_xwin.display, XDefaultRootWindow(_xwin.display), False,
@@ -775,8 +809,45 @@
return 0;
}
_xwin.mouse_grabbed = 1;
- }
+
+#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
+ /* Try to switch video mode. This must be done after the pointer is
+ grabbed, because otherwise it can be outside the window negating the
+ XF86VidModeSetViewPort done in set_fullscreen. This makes the old
+ center the window hack unnescesarry. Notice that since the XF86VM
+ extension requests do not go through the regular X output buffer? We
+ need to make sure that all above requests are processed first. */
+ XSync(_xwin.display, False);
+ _xvidmode_private_set_fullscreen(w, h, &fs_width, &fs_height);
#endif
+
+ /* Center the window (if nescesarry) */
+ if ((fs_width != w) || (fs_height != h))
+ XMoveWindow(_xwin.display, _xwin.window, (fs_width - w) / 2,
+ (fs_height - h) / 2);
+
+ /* Last: center the cursor */
+ XWarpPointer(_xwin.display, None, _xwin.window, 0, 0, 0, 0, w / 2, h / 2);
+ } else {
+ XSizeHints *hints = XAllocSizeHints();;
+
+ /* Resize managed window. */
+ XResizeWindow(_xwin.display, _xwin.wm_window, w, h);
+
+ /* Set size and position hints for Window Manager. */
+ if (hints) {
+ hints->flags = PMinSize | PMaxSize | PBaseSize;
+ hints->min_width = hints->max_width = hints->base_width = w;
+ hints->min_height = hints->max_height = hints->base_height = h;
+ XSetWMNormalHints(_xwin.display, _xwin.wm_window, hints);
+
+ XFree(hints);
+ }
+
+ /* Map the window managed window */
+ XMapWindow(_xwin.display, _xwin.wm_window);
+ _xwin_wait_mapped(_xwin.wm_window);
+ }
/* Create XImage with the size of virtual screen. */
if (_xwin_private_create_ximage(vw, vh) != 0) {
@@ -804,12 +875,6 @@
bmp = _xwin_private_create_screen(drv, w, h, vw, vh, depth, fullscreen);
if (bmp == 0) {
_xwin_private_destroy_screen();
- /* Work around a weird bug with some window managers (KWin, Window Maker). */
- if (fullscreen) {
- bmp = _xwin_private_create_screen(drv, w, h, vw, vh, depth, fullscreen);
- if (bmp == 0)
- _xwin_private_destroy_screen();
- }
}
XUNLOCK();
return bmp;
@@ -843,7 +908,6 @@
_xwin_private_destroy_ximage();
-#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
if (_xwin.mouse_grabbed) {
XUngrabPointer(_xwin.display, CurrentTime);
_xwin.mouse_grabbed = 0;
@@ -854,14 +918,8 @@
_xwin.keyboard_grabbed = 0;
}
+#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
_xvidmode_private_unset_fullscreen();
-
- if (_xwin.override_redirected) {
- setattr.override_redirect = False;
- XChangeWindowAttributes(_xwin.display, _xwin.window,
- CWOverrideRedirect, &setattr);
- _xwin.override_redirected = 0;
- }
#endif
/* whack color-conversion blitter */
@@ -869,8 +927,16 @@
_release_colorconv_blitter(blitter_func);
blitter_func = NULL;
}
-
- XUnmapWindow (_xwin.display, _xwin.window);
+
+ if (_xwin.fs_window != None) {
+ /* Reparent the real window! */
+ XReparentWindow(_xwin.display, _xwin.window, _xwin.wm_window, 0, 0);
+ XUnmapWindow(_xwin.display, _xwin.fs_window);
+ XDestroyWindow(_xwin.display, _xwin.fs_window);
+ _xwin.fs_window = None;
+ }
+ else
+ XUnmapWindow (_xwin.display, _xwin.wm_window);
(*_xwin_window_defaultor)();
}
@@ -2139,31 +2205,31 @@
XpmAttributes attributes;
#endif
- if (_xwin.window == None)
+ if (_xwin.wm_window == None)
return;
/* Set window title. */
- XStoreName(_xwin.display, _xwin.window, _xwin.window_title);
+ XStoreName(_xwin.display, _xwin.wm_window, _xwin.window_title);
/* Set hints. */
hint.res_name = _xwin.application_name;
hint.res_class = _xwin.application_class;
- XSetClassHint(_xwin.display, _xwin.window, &hint);
+ XSetClassHint(_xwin.display, _xwin.wm_window, &hint);
wm_hints.flags = InputHint | StateHint | WindowGroupHint;
wm_hints.input = True;
wm_hints.initial_state = NormalState;
- wm_hints.window_group = _xwin.window;
+ wm_hints.window_group = _xwin.wm_window;
#ifdef ALLEGRO_XWINDOWS_WITH_XPM
if (allegro_icon) {
wm_hints.flags |= IconPixmapHint | IconMaskHint;
attributes.valuemask = XpmReturnAllocPixels | XpmReturnExtensions;
- XpmCreatePixmapFromData(_xwin.display,_xwin.window,allegro_icon,&wm_hints.icon_pixmap,&wm_hints.icon_mask, &attributes);
+ XpmCreatePixmapFromData(_xwin.display,_xwin.wm_window,allegro_icon,&wm_hints.icon_pixmap,&wm_hints.icon_mask, &attributes);
}
#endif
- XSetWMHints(_xwin.display, _xwin.window, &wm_hints);
+ XSetWMHints(_xwin.display, _xwin.wm_window, &wm_hints);
}
@@ -2213,41 +2279,6 @@
}
-
-/* _xwin_resize_window:
- * Wrapper for XResizeWindow.
- */
-static void _xwin_private_resize_window(int w, int h)
-{
- XSizeHints *hints;
-
- if (_xwin.window == None)
- return;
-
- /* New window size. */
- _xwin.window_width = w;
- _xwin.window_height = h;
-
- /* Resize window. */
- XUnmapWindow(_xwin.display, _xwin.window);
- XResizeWindow(_xwin.display, _xwin.window, w, h);
- XMapWindow(_xwin.display, _xwin.window);
-
- hints = XAllocSizeHints();
- if (hints == 0)
- return;
-
- /* Set size and position hints for Window Manager. */
- hints->flags = PMinSize | PMaxSize | PBaseSize;
- hints->min_width = hints->max_width = hints->base_width = w;
- hints->min_height = hints->max_height = hints->base_height = h;
- XSetWMNormalHints(_xwin.display, _xwin.window, hints);
-
- XFree(hints);
-}
-
-
-
/* _xwin_process_event:
* Process one event.
*/
@@ -2723,51 +2754,93 @@
* Support for XF86VidMode extension.
*/
#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
+/* qsort comparison function for sorting the modes */
+static int cmpmodes(const void *va, const void *vb)
+{
+ const XF86VidModeModeInfo *a = *(const XF86VidModeModeInfo **)va;
+ const XF86VidModeModeInfo *b = *(const XF86VidModeModeInfo **)vb;
+ if ( a->hdisplay == b->hdisplay )
+ return b->vdisplay - a->vdisplay;
+ else
+ return b->hdisplay - a->hdisplay;
+}
+
/* _xvidmode_private_set_fullscreen:
- * Attempt to switch video mode and make window fullscreen.
+ * Attempt to switch to a better matching video mode.
+ * Matching code for non exact match (smallest bigger res) rather shamelessly
+ * taken from SDL.
*/
-static int _xvidmode_private_set_fullscreen(int w, int h)
+static void _xvidmode_private_set_fullscreen(int w, int h, int *vidmode_width,
+ int *vidmode_height)
{
int vid_event_base, vid_error_base;
int vid_major_version, vid_minor_version;
- XF86VidModeModeInfo *mode;
int i;
-
+
/* Test that display is local. */
- if (!_xwin_private_display_is_local()) {
- ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("VidMode extension requires local display"));
- return 0;
- }
+ if (!_xwin_private_display_is_local())
+ return;
/* Test for presence of VidMode extension. */
if (!XF86VidModeQueryExtension(_xwin.display, &vid_event_base, &vid_error_base)
- || !XF86VidModeQueryVersion(_xwin.display, &vid_major_version, &vid_minor_version)) {
- ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("VidMode extension is not supported"));
- return 0;
- }
+ || !XF86VidModeQueryVersion(_xwin.display, &vid_major_version, &vid_minor_version))
+ return;
/* Get list of modelines. */
if (!XF86VidModeGetAllModeLines(_xwin.display, _xwin.screen,
&_xwin.num_modes, &_xwin.modesinfo))
- return 0;
-
- /* Search for a matching video mode. */
- for (i = 0; i < _xwin.num_modes; i++) {
- mode = _xwin.modesinfo[i];
- if ((mode->hdisplay == w) && (mode->vdisplay == h)) {
- /* Switch video mode. */
- if (!XF86VidModeSwitchToMode(_xwin.display, _xwin.screen, mode))
- return 0;
+ return;
- /* Lock mode switching. */
- XF86VidModeLockModeSwitch(_xwin.display, _xwin.screen, True);
+ /* Remember the mode to restore */
+ _xwin.orig_modeinfo = _xwin.modesinfo[0];
- _xwin.mode_switched = 1;
- return 1;
- }
+ /* Search for an exact matching video mode. */
+ for (i = 0; i < _xwin.num_modes; i++) {
+ if ((_xwin.modesinfo[i]->hdisplay == w) &&
+ (_xwin.modesinfo[i]->vdisplay == h))
+ break;
}
- return 0;
+ /* Search for a non exact match (smallest bigger res). */
+ if (i == _xwin.num_modes) {
+ int best_width = 0, best_height = 0;
+ qsort(_xwin.modesinfo, _xwin.num_modes, sizeof(void *), cmpmodes);
+ for (i = _xwin.num_modes-1; i > 0; i--) {
+ if ( ! best_width ) {
+ if ( (_xwin.modesinfo[i]->hdisplay >= w) &&
+ (_xwin.modesinfo[i]->vdisplay >= h) ) {
+ best_width = _xwin.modesinfo[i]->hdisplay;
+ best_height = _xwin.modesinfo[i]->vdisplay;
+ }
+ } else {
+ if ( (_xwin.modesinfo[i]->hdisplay != best_width) ||
+ (_xwin.modesinfo[i]->vdisplay != best_height) ) {
+ i++;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Switch video mode. */
+ if ((_xwin.modesinfo[i] == _xwin.orig_modeinfo) ||
+ !XF86VidModeSwitchToMode(_xwin.display, _xwin.screen,
+ _xwin.modesinfo[i])) {
+ *vidmode_width = _xwin.orig_modeinfo->hdisplay;
+ *vidmode_height = _xwin.orig_modeinfo->vdisplay;
+ _xwin.orig_modeinfo = NULL;
+ } else {
+ *vidmode_width = _xwin.modesinfo[i]->hdisplay;
+ *vidmode_height = _xwin.modesinfo[i]->vdisplay;
+ /* only kept / set for compatibility with apps which check this */
+ _xwin.mode_switched = 1;
+ }
+
+ /* Lock mode switching. */
+ XF86VidModeLockModeSwitch(_xwin.display, _xwin.screen, True);
+
+ /* Set viewport. */
+ XF86VidModeSetViewPort(_xwin.display, _xwin.screen, 0, 0);
}
@@ -2793,13 +2866,15 @@
static void _xvidmode_private_unset_fullscreen(void)
{
if (_xwin.num_modes > 0) {
- if (_xwin.mode_switched) {
- /* Unlock mode switching. */
- XF86VidModeLockModeSwitch(_xwin.display, _xwin.screen, False);
+ /* Unlock mode switching. */
+ XF86VidModeLockModeSwitch(_xwin.display, _xwin.screen, False);
+ if (_xwin.orig_modeinfo) {
/* Restore the original video mode. */
- XF86VidModeSwitchToMode(_xwin.display, _xwin.screen, _xwin.modesinfo[0]);
-
+ XF86VidModeSwitchToMode(_xwin.display, _xwin.screen,
+ _xwin.orig_modeinfo);
+ _xwin.orig_modeinfo = 0;
+ /* only kept / set for compatibility with apps which check this */
_xwin.mode_switched = 0;
}
@@ -2809,36 +2884,35 @@
_xwin.modesinfo = 0;
}
}
+#endif
-/* _xvidmode_private_fetch_mode_list:
+/* _xwin_private_fetch_mode_list:
* Generates a list of valid video modes.
*/
-static GFX_MODE_LIST *_xvidmode_private_fetch_mode_list(void)
+static GFX_MODE_LIST *_xwin_private_fetch_mode_list(void)
{
+ int num_modes = 1, num_bpp = 0;
+ GFX_MODE_LIST *mode_list;
+ int i, j;
+#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
+ int has_vidmode = 0;
int vid_event_base, vid_error_base;
int vid_major_version, vid_minor_version;
XF86VidModeModeInfo **modesinfo;
- int num_modes, num_bpp;
- GFX_MODE_LIST *mode_list;
- int i, j;
-
- /* Test that display is local. */
- if (!_xwin_private_display_is_local())
- return 0;
-
- /* Test for presence of VidMode extension. */
- if (!XF86VidModeQueryExtension(_xwin.display, &vid_event_base, &vid_error_base)
- || !XF86VidModeQueryVersion(_xwin.display, &vid_major_version, &vid_minor_version))
- return 0;
-
- /* Get list of modelines. */
- if (!XF86VidModeGetAllModeLines(_xwin.display, _xwin.screen, &num_modes, &modesinfo))
- return 0;
+
+ /* Test that display is local. */
+ if ( _xwin_private_display_is_local() &&
+ /* Test for presence of VidMode extension. */
+ XF86VidModeQueryExtension(_xwin.display, &vid_event_base, &vid_error_base) &&
+ XF86VidModeQueryVersion(_xwin.display, &vid_major_version, &vid_minor_version) &&
+ /* Get list of modelines. */
+ XF86VidModeGetAllModeLines(_xwin.display, _xwin.screen, &num_modes, &modesinfo))
+ has_vidmode = 1;
+#endif
/* Calculate the number of color depths we have to support. */
- num_bpp = 0;
#ifdef ALLEGRO_COLOR8
num_bpp++;
#endif
@@ -2857,25 +2931,48 @@
/* Allocate space for mode list. */
mode_list = malloc(sizeof(GFX_MODE_LIST));
if (!mode_list) {
- free_modelines(modesinfo, num_modes);
+#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
+ if (has_vidmode)
+ free_modelines(modesinfo, num_modes);
+#endif
return 0;
}
mode_list->mode = malloc(sizeof(GFX_MODE) * ((num_modes * num_bpp) + 1));
if (!mode_list->mode) {
free(mode_list);
- free_modelines(modesinfo, num_modes);
+#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
+ if (has_vidmode)
+ free_modelines(modesinfo, num_modes);
+#endif
return 0;
}
/* Fill in mode list. */
j = 0;
for (i = 0; i < num_modes; i++) {
-#define ADD_MODE(BPP) \
+
+#define ADD_SCREEN_MODE(BPP) \
+ mode_list->mode[j].width = DisplayWidth(_xwin.display, _xwin.screen); \
+ mode_list->mode[j].height = DisplayHeight(_xwin.display, _xwin.screen); \
+ mode_list->mode[j].bpp = BPP; \
+ j++
+#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
+#define ADD_VIDMODE_MODE(BPP) \
mode_list->mode[j].width = modesinfo[i]->hdisplay; \
mode_list->mode[j].height = modesinfo[i]->vdisplay; \
mode_list->mode[j].bpp = BPP; \
j++
+#define ADD_MODE(BPP) \
+ if (has_vidmode) { \
+ ADD_VIDMODE_MODE(BPP); \
+ } else { \
+ ADD_SCREEN_MODE(BPP); \
+ }
+#else
+#define ADD_MODE(BPP) ADD_SCREEN_MODE(BPP)
+#endif
+
#ifdef ALLEGRO_COLOR8
ADD_MODE(8);
#endif
@@ -2896,11 +2993,13 @@
mode_list->mode[j].bpp = 0;
mode_list->num_modes = j;
- free_modelines(modesinfo, num_modes);
+#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
+ if (has_vidmode)
+ free_modelines(modesinfo, num_modes);
+#endif
return mode_list;
}
-#endif
@@ -2909,15 +3008,11 @@
*/
GFX_MODE_LIST *_xwin_fetch_mode_list(void)
{
-#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
GFX_MODE_LIST *list;
XLOCK();
- list = _xvidmode_private_fetch_mode_list();
+ list = _xwin_private_fetch_mode_list();
XUNLOCK();
return list;
-#else
- return 0;
-#endif
}
--- allegro-4.2.0/src/x/xgfxdrv.c~ 2006-03-08 22:47:27.000000000 +0100
+++ allegro-4.2.0/src/x/xgfxdrv.c 2006-03-08 22:47:27.000000000 +0100
@@ -61,7 +61,6 @@
-#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
static BITMAP *_xwin_fullscreen_gfxdrv_init(int w, int h, int vw, int vh, int color_depth);
@@ -98,7 +97,6 @@
0,
FALSE
};
-#endif
@@ -109,9 +107,7 @@
{ GFX_XDGA2, &gfx_xdga2, FALSE },
{ GFX_XDGA2_SOFT, &gfx_xdga2_soft, FALSE },
#endif
-#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
{ GFX_XWINDOWS_FULLSCREEN, &gfx_xwin_fullscreen, TRUE },
-#endif
{ GFX_XWINDOWS, &gfx_xwin, TRUE },
{ 0, NULL, 0 }
};
@@ -138,7 +134,6 @@
-#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
/* _xwin_fullscreen_gfxdrv_init:
* Creates screen bitmap (with video mode extension).
*/
@@ -146,4 +141,3 @@
{
return _xwin_create_screen(&gfx_xwin_fullscreen, w, h, vw, vh, color_depth, TRUE);
}
-#endif