[PATCH 3/5] dix: reduce FirstPointerChild complexity

Peter Hutterer peter.hutterer at who-t.net
Wed Jan 7 16:13:04 PST 2009


Instead of keeping a flag on each window for the devices that are in this
window, keep a local array that holds the current pointer window for each
device. Benefit: searching for the first descendant of a pointer is a simple
run through the array.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 dix/enterleave.c    |   64 ++++++++-------------------------------------------
 dix/window.c        |    1 -
 include/windowstr.h |    1 -
 3 files changed, 10 insertions(+), 56 deletions(-)

diff --git a/dix/enterleave.c b/dix/enterleave.c
index fbe7af4..0b15619 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -54,6 +54,8 @@
  * events may have a subwindow set to other than None.
  */
 
+static WindowPtr PointerWindows[MAXDEVICES];
+
 /**
  * Return TRUE if @win has a pointer within its boundaries, excluding child
  * window.
@@ -63,8 +65,8 @@ HasPointer(WindowPtr win)
 {
     int i;
 
-    for (i = 0; i < sizeof(win->enterleave); i++)
-        if (win->enterleave[i])
+    for (i = 0; i < MAXDEVICES; i++)
+        if (PointerWindows[i] == win)
             return TRUE;
 
     return FALSE;
@@ -80,57 +82,11 @@ HasPointer(WindowPtr win)
 static WindowPtr
 FirstPointerChild(WindowPtr win)
 {
-    static WindowPtr *queue = NULL;
-    static int queue_size  = 256; /* allocated size of queue */
-
-    WindowPtr child = NULL;
-    int queue_len   = 0;          /* no of elements in queue */
-    int queue_head  = 0;          /* pos of current element  */
-
-    if (!win || !win->firstChild)
-        return NULL;
-
-    if (!queue && !(queue = xcalloc(queue_size, sizeof(WindowPtr))))
-        FatalError("[dix] FirstPointerChild: OOM.\n");
-
-    queue[0] = win;
-    queue_head = 0;
-    queue_len  = 1;
-
-    while (queue_len--)
+    int i;
+    for (i = 0; i < MAXDEVICES; i++)
     {
-        if (queue[queue_head] != win && HasPointer(queue[queue_head]))
-            return queue[queue_head];
-
-        child = queue[queue_head]->firstChild;
-        /* pop children onto queue */
-        while(child)
-        {
-            queue_len++;
-            if (queue_len >= queue_size)
-            {
-                const int inc = 256;
-
-                queue = xrealloc(queue, (queue_size + inc) * sizeof(WindowPtr));
-                if (!queue)
-                    FatalError("[dix] FirstPointerChild: OOM.\n");
-
-                /* Are we wrapped around? */
-                if (queue_head + queue_len > queue_size)
-                {
-                    memmove(&queue[queue_head + inc], &queue[queue_head],
-                            (queue_size - queue_head) * sizeof(WindowPtr));
-                    queue_head += inc;
-                }
-
-                queue_size += inc;
-            }
-
-            queue[(queue_head + queue_len) % queue_size] = child;
-            child = child->nextSib;
-        }
-
-        queue_head = (queue_head + 1) % queue_size;
+        if (PointerWindows[i] && IsParent(win, PointerWindows[i]))
+            return PointerWindows[i];
     }
 
     return NULL;
@@ -143,7 +99,7 @@ FirstPointerChild(WindowPtr win)
 void
 EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode)
 {
-    win->enterleave[dev->id/8] |= (1 << (dev->id % 8));
+    PointerWindows[dev->id] = win;
 }
 
 /**
@@ -152,7 +108,7 @@ EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode)
 static void
 LeaveWindow(DeviceIntPtr dev, WindowPtr win, int mode)
 {
-    win->enterleave[dev->id/8] &= ~(1 << (dev->id % 8));
+    PointerWindows[dev->id] = NULL;
 }
 
 
diff --git a/dix/window.c b/dix/window.c
index 88ab5e9..ca07c96 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -300,7 +300,6 @@ SetWindowToDefaults(WindowPtr pWin)
     pWin->redirectDraw = RedirectDrawNone;
     pWin->forcedBG = FALSE;
 
-    memset(pWin->enterleave, 0, sizeof(pWin->enterleave));
     memset(pWin->focusinout, 0, sizeof(pWin->focusinout));
 
 #ifdef ROOTLESS
diff --git a/include/windowstr.h b/include/windowstr.h
index b39b351..9f86e2c 100644
--- a/include/windowstr.h
+++ b/include/windowstr.h
@@ -183,7 +183,6 @@ typedef struct _Window {
      * FocusIn/Out events for multiple pointers/keyboards. Each device ID
      * corresponds to one bit. If set, the device is in the window/has focus.
      */
-    char                enterleave[(MAXDEVICES + 7)/8];
     char                focusinout[(MAXDEVICES + 7)/8];
 } WindowRec;
 
-- 
1.6.0.6




More information about the xorg mailing list