From 378732a90ebcb6341e6a843096d2e33024144595 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mar 08 2006 22:12:12 +0000 Subject: - fix fullscreen <-> window switching bug (bz 183645) - fix asm stretch code on i386 with NX processors, thanks to openBSD. --- diff --git a/allegro-4.2.0-fullscreen.patch b/allegro-4.2.0-fullscreen.patch new file mode 100644 index 0000000..9bb978d --- /dev/null +++ b/allegro-4.2.0-fullscreen.patch @@ -0,0 +1,266 @@ +diff -ur allegro-4.2.0.orig/include/allegro/platform/aintunix.h allegro-4.2.0/include/allegro/platform/aintunix.h +--- allegro-4.2.0.orig/include/allegro/platform/aintunix.h 2005-09-04 18:00:07.000000000 +0200 ++++ allegro-4.2.0/include/allegro/platform/aintunix.h 2006-03-02 14:50:17.000000000 +0100 +@@ -88,7 +88,11 @@ + + AL_FUNC(void, _xwin_handle_input, (void)); + AL_FUNC(void, _xwin_private_handle_input, (void)); +- ++ AL_FUNC(int , _xwin_keyboard_init, (void)); ++ AL_FUNC(void, _xwin_keyboard_exit, (void)); ++ ++ AL_VAR(int, _xwin_keyboard_installed); ++ + #ifndef ALLEGRO_MULTITHREADED + + AL_VAR(int, _xwin_missed_input); +Only in allegro-4.2.0/include/allegro/platform: aintunix.h~ +diff -ur allegro-4.2.0.orig/include/xalleg.h allegro-4.2.0/include/xalleg.h +--- allegro-4.2.0.orig/include/xalleg.h 2004-12-02 02:02:31.000000000 +0100 ++++ allegro-4.2.0/include/xalleg.h 2006-03-02 14:42:58.000000000 +0100 +@@ -126,6 +126,7 @@ + int num_modes; + int mode_switched; + int override_redirected; ++ int window_used; + #endif + + char window_title[1024]; +Only in allegro-4.2.0/include: xalleg.h~ +diff -ur allegro-4.2.0.orig/src/x/xkeyboard.c allegro-4.2.0/src/x/xkeyboard.c +--- allegro-4.2.0.orig/src/x/xkeyboard.c 2005-11-05 17:06:53.000000000 +0100 ++++ allegro-4.2.0/src/x/xkeyboard.c 2006-03-02 14:50:19.000000000 +0100 +@@ -34,12 +34,12 @@ + #define PREFIX_W "al-xkey WARNING: " + #define PREFIX_E "al-xkey ERROR: " + ++int _xwin_keyboard_installed = 0; + #ifdef ALLEGRO_USE_XIM + static XIM xim = NULL; + static XIC xic = NULL; + #endif + static XModifierKeymap *xmodmap = NULL; +-static int xkeyboard_installed = 0; + static int used[KEY_MAX]; + static int sym_per_key; + static int min_keycode, max_keycode; +@@ -365,7 +365,7 @@ + void _xwin_keyboard_handler(XKeyEvent *event, int dga2_hack) + { + int keycode; +- if (!xkeyboard_installed) ++ if (!_xwin_keyboard_installed) + return; + + if (_xwin_keyboard_callback) +@@ -646,7 +646,7 @@ + { + XKeyboardControl values; + +- if (!xkeyboard_installed) ++ if (!_xwin_keyboard_installed) + return; + + XLOCK(); +@@ -668,10 +668,10 @@ + + + +-/* x_keyboard_init ++/* _xwin_keyboard_init + * Initialise the X11 keyboard driver. + */ +-static int x_keyboard_init(void) ++int _xwin_keyboard_init(void) + { + #ifdef ALLEGRO_USE_XIM + XIMStyles *xim_styles; +@@ -680,7 +680,7 @@ + int i; + #endif + +- if (xkeyboard_installed) ++ if (_xwin_keyboard_installed) + return 0; + + main_pid = getpid(); +@@ -745,21 +745,21 @@ + + XUNLOCK (); + +- xkeyboard_installed = 1; ++ _xwin_keyboard_installed = 1; + + return 0; + } + + + +-/* x_keyboard_exit ++/* _xwin_keyboard_exit + * Shut down the X11 keyboard driver. + */ +-static void x_keyboard_exit(void) ++void _xwin_keyboard_exit(void) + { +- if (!xkeyboard_installed) ++ if (!_xwin_keyboard_installed) + return; +- xkeyboard_installed = 0; ++ _xwin_keyboard_installed = 0; + + XLOCK (); + +@@ -799,8 +799,8 @@ + "X11 keyboard", + "X11 keyboard", + FALSE, +- x_keyboard_init, +- x_keyboard_exit, ++ _xwin_keyboard_init, ++ _xwin_keyboard_exit, + NULL, // AL_METHOD(void, poll, (void)); + x_set_leds, + NULL, // AL_METHOD(void, set_rate, (int delay, int rate)); +Only in allegro-4.2.0/src/x: xkeyboard.c~ +diff -ur allegro-4.2.0.orig/src/x/xwin.c allegro-4.2.0/src/x/xwin.c +--- allegro-4.2.0.orig/src/x/xwin.c 2005-10-27 23:23:40.000000000 +0200 ++++ allegro-4.2.0/src/x/xwin.c 2006-03-02 14:48:00.000000000 +0100 +@@ -130,6 +130,7 @@ + 0, /* num_modes */ + 0, /* mode_switched */ + 0, /* override_redirected */ ++ 0, /* window_used */ + #endif + + XWIN_DEFAULT_WINDOW_TITLE, /* window_title */ +@@ -322,20 +323,13 @@ + } + } + +- +- +-/* _xwin_hide_x_mouse: +- * Create invisible X cursor ++/* _xwin_free_cursor: ++ * Helper for freeing the cursor which is done in a number of different places. + */ +-static void _xwin_hide_x_mouse(void) ++static void _xwin_free_cursor(void) + { +- unsigned long gcmask; +- XGCValues gcvalues; +- Pixmap pixmap; +- +- XUndefineCursor(_xwin.display, _xwin.window); +- + if (_xwin.cursor != None) { ++ XUndefineCursor(_xwin.display, _xwin.window); + XFreeCursor(_xwin.display, _xwin.cursor); + _xwin.cursor = None; + } +@@ -346,7 +340,19 @@ + _xwin.xcursor_image = None; + } + #endif ++} + ++/* _xwin_hide_x_mouse: ++ * Create invisible X cursor ++ */ ++static void _xwin_hide_x_mouse(void) ++{ ++ unsigned long gcmask; ++ XGCValues gcvalues; ++ Pixmap pixmap; ++ ++ _xwin_free_cursor(); ++ + pixmap = XCreatePixmap(_xwin.display, _xwin.window, 1, 1, 1); + if (pixmap != None) { + GC temp_gc; +@@ -462,20 +468,7 @@ + static void _xwin_private_destroy_window(void) + { + _xwin_private_destroy_screen(); +- +- if (_xwin.cursor != None) { +- XUndefineCursor(_xwin.display, _xwin.window); +- XFreeCursor(_xwin.display, _xwin.cursor); +- _xwin.cursor = None; +- } +- +-#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR +- if (_xwin.xcursor_image != None) { +- XcursorImageDestroy(_xwin.xcursor_image); +- _xwin.xcursor_image = None; +- } +-#endif +- ++ _xwin_free_cursor(); + _xwin.visual = 0; + + if (_xwin.gc != None) { +@@ -673,10 +666,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; +@@ -715,11 +704,50 @@ + #ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE + /* If we are going fullscreen, disable window decorations. */ + if (fullscreen) { ++ XSetWindowAttributes setattr; ++ ++ /* HACK HACK HACK ++ We need to destroy the window if it has already been used once, ++ since doing fullscreen with a window wich has been mapped already ++ has issues. see: http:// mail not archived yet */ ++ if (_xwin.window_used) { ++ /* remember if the keyboard was installed */ ++ int keyb_installed = _xwin_keyboard_installed; ++ ++ /* remember the cursor and set the cursor to None so that the ++ remembered cursor does not get freed. */ ++ Cursor cursor = _xwin.cursor; ++#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR ++ XcursorImage *xcursor_image = _xwin.xcursor_image; ++ _xwin.xcursor_image = None; ++#endif ++ _xwin.cursor = None; ++ ++ /* close keyboard & window, then recreate both */ ++ _xwin_keyboard_exit(); ++ _xwin_private_destroy_window(); ++ if ((*_xwin_window_creator)()) { ++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Could not create window")); ++ return 0; ++ } ++ if (keyb_installed) ++ /* has a return value but can't fail */ ++ _xwin_keyboard_init(); ++ ++ /* Free the new cursor and put the old one back */ ++ _xwin_free_cursor(); ++ _xwin.cursor = cursor; ++#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR ++ _xwin.xcursor_image = xcursor_image; ++#endif ++ XDefineCursor(_xwin.display, _xwin.window, _xwin.cursor); ++ } + setattr.override_redirect = True; + XChangeWindowAttributes(_xwin.display, _xwin.window, + CWOverrideRedirect, &setattr); + _xwin.override_redirected = 1; + } ++ _xwin.window_used = 1; + #endif + + /* Set window size and save dimensions. */ +Only in allegro-4.2.0/src/x: xwin.c~ diff --git a/allegro-4.2.0-fullscreen2.patch b/allegro-4.2.0-fullscreen2.patch new file mode 100644 index 0000000..6d5ec63 --- /dev/null +++ b/allegro-4.2.0-fullscreen2.patch @@ -0,0 +1,781 @@ +--- 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 diff --git a/allegro-4.2.0-mprotect.patch b/allegro-4.2.0-mprotect.patch new file mode 100644 index 0000000..da8fc5c --- /dev/null +++ b/allegro-4.2.0-mprotect.patch @@ -0,0 +1,100 @@ +--- allegro-4.2.0/tools/grabber.c.mprotect 2005-09-04 18:00:18.000000000 +0200 ++++ allegro-4.2.0/tools/grabber.c 2006-03-08 23:13:39.000000000 +0100 +@@ -3121,6 +3121,7 @@ + case OSTYPE_SUNOS: s = "SunOS/Solaris"; break; + case OSTYPE_FREEBSD: s = "FreeBSD"; break; + case OSTYPE_NETBSD: s = "NetBSD"; break; ++ case OSTYPE_OPENBSD: s = "OpenBSD"; break; + case OSTYPE_IRIX: s = "IRIX"; break; + case OSTYPE_DARWIN: s = "Darwin"; break; + case OSTYPE_QNX: s = "QNX"; break; +--- allegro-4.2.0/include/allegro/platform/alunixac.hin.mprotect 2005-10-30 21:23:33.000000000 +0100 ++++ allegro-4.2.0/include/allegro/platform/alunixac.hin 2006-03-08 23:13:39.000000000 +0100 +@@ -169,6 +169,9 @@ + /* Define to 1 if you have the `mmap' function. */ + #undef HAVE_MMAP + ++/* Define to 1 if you have the `mprotect' function. */ ++#undef HAVE_MPROTECT ++ + /* Define to 1 if you have the header file, and it defines `DIR'. */ + #undef HAVE_NDIR_H + +--- allegro-4.2.0/include/allegro/system.h.mprotect 2005-03-15 21:32:43.000000000 +0100 ++++ allegro-4.2.0/include/allegro/system.h 2006-03-08 23:13:39.000000000 +0100 +@@ -53,6 +53,7 @@ + #define OSTYPE_SUNOS AL_ID('S','U','N',' ') + #define OSTYPE_FREEBSD AL_ID('F','B','S','D') + #define OSTYPE_NETBSD AL_ID('N','B','S','D') ++#define OSTYPE_OPENBSD AL_ID('O','B','S','D') + #define OSTYPE_IRIX AL_ID('I','R','I','X') + #define OSTYPE_DARWIN AL_ID('D','A','R','W') + #define OSTYPE_QNX AL_ID('Q','N','X',' ') +--- allegro-4.2.0/configure.mprotect 2005-11-06 10:54:00.000000000 +0100 ++++ allegro-4.2.0/configure 2006-03-08 23:13:39.000000000 +0100 +@@ -11225,7 +11225,7 @@ + + + +-for ac_func in mmap memcmp mkstemp stricmp strlwr strupr vprintf ++for ac_func in mmap mprotect memcmp mkstemp stricmp strlwr strupr vprintf + do + as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` + echo "$as_me:$LINENO: checking for $ac_func" >&5 +--- allegro-4.2.0/configure.in.mprotect 2005-08-07 23:50:49.000000000 +0200 ++++ allegro-4.2.0/configure.in 2006-03-08 23:13:39.000000000 +0100 +@@ -713,7 +713,7 @@ + AC_STRUCT_TM + AC_TYPE_SIGNAL + +-AC_CHECK_FUNCS(mmap memcmp mkstemp stricmp strlwr strupr vprintf) ++AC_CHECK_FUNCS(mmap mprotect memcmp mkstemp stricmp strlwr strupr vprintf) + + dnl Tweak header files for library build + CFLAGS="$CFLAGS -DALLEGRO_LIB_BUILD" +--- allegro-4.2.0/src/unix/usystem.c.mprotect 2005-09-04 18:00:17.000000000 +0200 ++++ allegro-4.2.0/src/unix/usystem.c 2006-03-08 23:13:39.000000000 +0100 +@@ -196,6 +196,9 @@ + else if (!strcmp(utsn.sysname, "NetBSD")) { + os_type = OSTYPE_NETBSD; + } ++ else if (!strcmp(utsn.sysname, "OpenBSD")) { ++ os_type = OSTYPE_OPENBSD; ++ } + else if ((!strcmp(utsn.sysname, "IRIX")) + || (!strcmp(utsn.sysname, "IRIX64"))) { + os_type = OSTYPE_IRIX; +--- allegro-4.2.0/src/unix/uesd.c.mprotect 2005-03-12 08:54:27.000000000 +0100 ++++ allegro-4.2.0/src/unix/uesd.c 2006-03-08 23:13:39.000000000 +0100 +@@ -27,6 +27,7 @@ + + #include + #include ++#include /* FD_ZERO() needs this */ + #include + #include + +--- allegro-4.2.0/src/i386/istretch.c.mprotect 2005-03-15 19:02:22.000000000 +0100 ++++ allegro-4.2.0/src/i386/istretch.c 2006-03-08 23:14:52.000000000 +0100 +@@ -30,6 +30,10 @@ + #include "winalleg.h" /* For VirtualProtect */ + #endif /* ifdef ALLEGRO_WINDOWS */ + ++#ifdef HAVE_MPROTECT ++ #include ++ #include ++#endif + + + /* helper macro for generating stretchers in each color depth */ +@@ -435,7 +439,9 @@ + #ifdef ALLEGRO_WINDOWS + /* Play nice with Windows executable memory protection */ + VirtualProtect(_scratch_mem, _scratch_mem_size, PAGE_EXECUTE_READWRITE, &old_protect); +- #endif /* ifdef ALLEGRO_WINDOWS */ ++ #elif defined(HAVE_MPROTECT) ++ mprotect(_scratch_mem, _scratch_mem_size, PROT_EXEC|PROT_READ|PROT_WRITE); ++ #endif + + /* call the stretcher */ + _do_stretch(source, dest, _scratch_mem, sx>>16, sy, syd, diff --git a/allegro.spec b/allegro.spec index 1663258..afebc17 100644 --- a/allegro.spec +++ b/allegro.spec @@ -18,6 +18,8 @@ Patch3: allegro-4.2.0-nostrip.patch Patch4: allegro-4.2.0-digmid.patch Patch5: allegro-4.2.0-alsa-big-endian.patch Patch6: allegro-4.2.0-64bit.patch +Patch7: allegro-4.2.0-fullscreen2.patch +Patch8: allegro-4.2.0-mprotect.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: esound-devel, texinfo, perl, arts-devel BuildRequires: xorg-x11-proto-devel, libX11-devel, libXext-devel, libXt-devel @@ -128,6 +130,9 @@ které jsou užitečné pro vývoj Allegro programů. %patch4 -p1 -z .digmid %patch5 -p1 -z .alsa-big-endian %patch6 -p1 -z .64bit +%patch7 -p1 -z .fullscreen +%patch8 -p1 -z .mprotect + %build %configure \ @@ -214,6 +219,10 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Wed Mar 8 2006 Hans de Goede 4.2.0-9 +- fix fullscreen <-> window switching bug (bz 183645) +- fix asm stretch code on i386 with NX processors, thanks to openBSD. + * Mon Feb 27 2006 Hans de Goede 4.2.0-8 - fix sound not working on PPC (bz 183112) - fix allegro not finding and loading plugins/modules on x86_64 (bz 183113)