Re: [AD] Real weird unix bug, help wanted

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]




Elias Pschernig wrote:
On Thu, 2006-03-02 at 12:21 +0100, Elias Pschernig wrote:

I'll restart now X11 and see if it then disappears again..


Ok. I restarted now X11, then your program, and switched 10 times (I
wonder what people around me thought :P) - and it always worked.

Then I clicked the firefox icon, typed in the allegro home page address
and let it load. Then started your program again, first switch worked,
and 2nd and 3rd switch failed with the problem.

Well, anyway, I must think what this could mean..


Good to hear you're looking into this. I've been looking onto this too and I believe its a windowmanager <-> allegro app interaction race, after doing:
      setattr.override_redirect = True;
      XChangeWindowAttributes(_xwin.display, _xwin.window,
                              CWOverrideRedirect, &setattr);

The WM should leave the window alone, but it might take some time for the WM to get around to releasing the window, quoting from man XMoveWindow:
       If the override-redirect flag of the window is False and some
       other
       client has selected SubstructureRedirectMask on the parent, the X
       server generates a ConfigureRequest event, and no further
       processing is performed.  Otherwise, the window is moved.

I've also been reading the ICCMM (enough C and M's ?) docs but nothing there.

I've had simular issues with xmame, it is possible though, SDL does it.

But for now I've written a patch (attached) which destroys the window when switching to fullscreen and then recreates it, since a new unmapped window is not touched by the WM untill mapped, this way we are sure the window will never get touched as we set OverrideRedirect before mapping the window, the WM will see this immediately and never touch the window.

This all assumes that some client <-> WM interaction (race) is at fault.

Regards,

Hans
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~


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/