[AD] X11 key repeat fix

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


Hi,

here's something which has been bothering me for some time, but I always
just thought it's another symptom of the not-quite-optimal X11 driver of
Allegro: I noticed how in many games where you have to hold a key
pressed, for example to jump, they wouldn't work in X11, especially if
there was some load (not much, maybe 1% CPU, is usually enough).

Here's a testcase to demonstrate it:
http://allefant.sf.net/allegro/kbtest.c

With the XWIN driver, and if your system is affected by it (if not,
compiling allegro in the background might help), it's impossible to move
the circle to the top of the screen. If it would be a platform game
written with Allegro, but in Windows, and there was a high jump, you'd
be stuck.

The attached patch fixes is, but unfortunately I'm not quite sure how
hackish it is. Maybe there's a better way to distinguish repeated key
releases from real releases, or Allegro could switch off key repeat for
its X11 window somehow? And of course, getting the X11 driver to run
smoother in general, it would probably fix it as well. Someone should
look like SDL does it :)

-- 
Elias Pschernig <elias@xxxxxxxxxx>
Index: src/x/xwin.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/x/xwin.c,v
retrieving revision 1.55
diff -u -r1.55 xwin.c
--- src/x/xwin.c	29 Oct 2003 12:37:57 -0000	1.55
+++ src/x/xwin.c	5 Dec 2003 15:40:55 -0000
@@ -2207,8 +2207,8 @@
  */
 static void _xwin_private_handle_input(void)
 {
-   int i, events;
-   static XEvent event[5];
+   int i, events, events_queued;
+   static XEvent event[6];
 
    if (_xwin.display == 0)
       return;
@@ -2233,7 +2233,7 @@
    _xwin_private_flush_buffers();
 
    /* How much events are available in the queue.  */
-   events = XEventsQueued(_xwin.display, QueuedAlready);
+   events = events_queued = XEventsQueued(_xwin.display, QueuedAlready);
    if (events <= 0)
       return;
 
@@ -2245,9 +2245,31 @@
    for (i = 0; i < events; i++)
       XNextEvent(_xwin.display, &event[i]);
 
+   /* Can't have a KeyRelease as last event, since it might be only half
+    * of a key repeat pair. Also see comment below.
+    */
+   if (events_queued > events && event[i - 1].type == KeyRelease) {
+      XNextEvent(_xwin.display, &event[i]);
+      events++;
+   }
+
    /* Process all events.  */
-   for (i = 0; i < events; i++)
+   for (i = 0; i < events; i++) {
+
+      /* Hack to make Allegro's key[] array work despite of key repeat.
+       * If a KeyRelease is sent at the same time as a KeyPress following
+       * it with the same keycode, we ignore the release event.
+       */
+      if (event[i].type == KeyRelease && i + 1 < events) {				
+	 if (event[i + 1].type == KeyPress) {
+	    if (event[i].xkey.keycode == event[i + 1].xkey.keycode &&
+	       event[i].xkey.time == event[i + 1].xkey.time)
+	       continue;
+	 }
+      }
+
       _xwin_private_process_event(&event[i]);
+   }
 }
 
 void _xwin_handle_input(void)


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