xserver: Branch 'master' - 5 commits

Peter Hutterer whot at kemper.freedesktop.org
Thu Feb 12 20:51:14 PST 2009


 dix/enterleave.c    |  103 ++++++++++++++++++++-----------------
 dix/events.c        |   70 +++++++++++++------------
 dix/main.c          |    1 
 dix/ptrveloc.c      |  144 +++++++++++++++++++++++++++++++++-------------------
 include/dix.h       |    3 -
 include/inputstr.h  |   58 ++++++++++++++++++--
 include/ptrveloc.h  |    2 
 include/windowstr.h |    4 -
 8 files changed, 239 insertions(+), 146 deletions(-)

New commits:
commit 340f1576afcdaf883d185da356e5d6282aa65e19
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 12 10:44:27 2009 +1000

    dix: remove DefineInitialRootWindow()
    
    Obsolete.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 14a0e5e..598dc75 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2662,17 +2662,6 @@ void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
 #endif
 
 /**
- * Called from main() with the root window on the first screen. Used to do a
- * lot more when MPX wasn't around yet. Things change.
- *
- * Should delete this now? -ds
- */
-void
-DefineInitialRootWindow(WindowPtr win)
-{
-}
-
-/**
  * Initialize a sprite for the given device and set it to some sane values. If
  * the device already has a sprite alloc'd, don't realloc but just reset to
  * default values.
diff --git a/dix/main.c b/dix/main.c
index 3c25e2e..1c66c86 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -362,7 +362,6 @@ int main(int argc, char *argv[], char *envp[])
 
 	for (i = 0; i < screenInfo.numScreens; i++)
 	    InitRootWindow(WindowTable[i]);
-	DefineInitialRootWindow(WindowTable[0]);
 
         InitCoreDevices();
 	InitInput(argc, argv);
diff --git a/include/dix.h b/include/dix.h
index 658dd29..8d6b9ff 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -376,9 +376,6 @@ extern _X_EXPORT int DeliverDeviceEvents(
     DeviceIntPtr /* dev */,
     int /* count */);
 
-extern _X_EXPORT void DefineInitialRootWindow(
-    WindowPtr /* win */);
-
 extern _X_EXPORT void InitializeSprite(
     DeviceIntPtr /* pDev */,
     WindowPtr    /* pWin */);
commit c178c3f814f7666f43cbf47d24c7543b289f9b1a
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 12 15:29:38 2009 +1000

    dix: doxygen-ify enterleave.c
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/enterleave.c b/dix/enterleave.c
index b8de9f0..2f2cff4 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -34,8 +34,11 @@
 #include "exglobals.h"
 #include "enterleave.h"
 
-/* @file This file describes the model for sending core enter/leave events and
- * focus in/out in the case of multiple pointers/keyboard foci
+/**
+ * @file
+ * This file describes the model for sending core enter/leave events and
+ * focus in/out in the case of multiple pointers/keyboard foci.
+ *
  * Since we can't send more than one Enter or Leave/Focus in or out event per
  * window to a core client without confusing it, this is a rather complicated
  * approach.
@@ -49,7 +52,7 @@
  * http://lists.freedesktop.org/archives/xorg/2008-December/041740.html
  *
  * Additional notes:
- * -) The core protocol spec says that "In a LeaveNotify event, if a child of the
+ * - The core protocol spec says that "In a LeaveNotify event, if a child of the
  * event window contains the initial position of the pointer, then the child
  * component is set to that child. Otherwise, it is None.  For an EnterNotify
  * event, if a child of the event window contains the final pointer position,
@@ -58,7 +61,7 @@
  * By inference, this means that only NotifyVirtual or NotifyNonlinearVirtual
  * events may have a subwindow set to other than None.
  *
- * -) NotifyPointer events may be sent if the focus changes from window A to
+ * - NotifyPointer events may be sent if the focus changes from window A to
  * B. The assumption used in this model is that NotifyPointer events are only
  * sent for the pointer paired with the keyboard that is involved in the focus
  * events. For example, if F(W) changes because of keyboard 2, then
@@ -69,7 +72,7 @@ static WindowPtr PointerWindows[MAXDEVICES];
 static WindowPtr FocusWindows[MAXDEVICES];
 
 /**
- * Return TRUE if @win has a pointer within its boundaries, excluding child
+ * Return TRUE if 'win' has a pointer within its boundaries, excluding child
  * window.
  */
 static BOOL
@@ -85,7 +88,7 @@ HasPointer(WindowPtr win)
 }
 
 /**
- * Return TRUE if at least one keyboard focus is set to @win (excluding
+ * Return TRUE if at least one keyboard focus is set to 'win' (excluding
  * descendants of win).
  */
 static BOOL
@@ -100,7 +103,7 @@ HasFocus(WindowPtr win)
 }
 
 /**
- * Return the window the device @dev is currently on.
+ * Return the window the device dev is currently on.
  */
 static WindowPtr
 PointerWin(DeviceIntPtr dev)
@@ -109,7 +112,7 @@ PointerWin(DeviceIntPtr dev)
 }
 
 /**
- * Search for the first window below @win that has a pointer directly within
+ * Search for the first window below 'win' that has a pointer directly within
  * it's boundaries (excluding boundaries of its own descendants).
  *
  * @return The child window that has the pointer within its boundaries or
@@ -129,7 +132,7 @@ FirstPointerChild(WindowPtr win)
 }
 
 /**
- * Search for the first window below @win that has a focus directly within
+ * Search for the first window below 'win' that has a focus directly within
  * it's boundaries (excluding boundaries of its own descendants).
  *
  * @return The child window that has the pointer within its boundaries or
@@ -150,7 +153,7 @@ FirstFocusChild(WindowPtr win)
 }
 
 /**
- * Set the presence flag for @dev to mark that it is now in @win.
+ * Set the presence flag for dev to mark that it is now in 'win'.
  */
 void
 EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode)
@@ -159,7 +162,7 @@ EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode)
 }
 
 /**
- * Unset the presence flag for @dev to mark that it is not in @win anymore.
+ * Unset the presence flag for dev to mark that it is not in 'win' anymore.
  */
 static void
 LeaveWindow(DeviceIntPtr dev, WindowPtr win, int mode)
@@ -168,7 +171,7 @@ LeaveWindow(DeviceIntPtr dev, WindowPtr win, int mode)
 }
 
 /**
- * Set the presence flag for @dev to mark that it is now in @win.
+ * Set the presence flag for dev to mark that it is now in 'win'.
  */
 void
 SetFocusIn(DeviceIntPtr dev, WindowPtr win)
@@ -177,7 +180,7 @@ SetFocusIn(DeviceIntPtr dev, WindowPtr win)
 }
 
 /**
- * Unset the presence flag for @dev to mark that it is not in @win anymore.
+ * Unset the presence flag for dev to mark that it is not in 'win' anymore.
  */
 void
 SetFocusOut(DeviceIntPtr dev, WindowPtr win)
@@ -189,7 +192,11 @@ SetFocusOut(DeviceIntPtr dev, WindowPtr win)
 
 
 /**
- * @return The window that is the first ancestor of both a and b.
+ * Return the common ancestor of 'a' and 'b' (if one exists).
+ * @param a A window with the same ancestor as b.
+ * @param b A window with the same ancestor as a.
+ * @return The window that is the first ancestor of both 'a' and 'b', or the
+ *         NullWindow if they do not have a common ancestor.
  */
 WindowPtr
 CommonAncestor(
@@ -203,10 +210,11 @@ CommonAncestor(
 
 
 /**
- * Send enter notifies to all windows between @ancestor and @child (excluding
+ * Send enter notifies to all windows between 'ancestor' and 'child' (excluding
  * both). Events are sent running up the window hierarchy. This function
  * recurses.
- * If @core is TRUE, core events are sent, otherwise XI events will be sent.
+ *
+ * @param core If TRUE, core events are sent, otherwise XI events will be sent.
  */
 static void
 DeviceEnterNotifies(DeviceIntPtr dev,
@@ -225,7 +233,7 @@ DeviceEnterNotifies(DeviceIntPtr dev,
 }
 
 /**
- * Send enter notifies to all windows between @ancestor and @child (excluding
+ * Send enter notifies to all windows between 'ancestor' and 'child' (excluding
  * both). Events are sent running down the window hierarchy. This function
  * recurses.
  */
@@ -310,7 +318,7 @@ CoreLeaveNotifies(DeviceIntPtr dev,
 }
 
 /**
- * Send leave notifies to all windows between @child and @ancestor.
+ * Send leave notifies to all windows between 'child' and 'ancestor'.
  * Events are sent running up the hierarchy.
  */
 static void
@@ -333,8 +341,8 @@ DeviceLeaveNotifies(DeviceIntPtr dev,
 }
 
 /**
- * Pointer @dev moves from @A to @B and @A neither a descendant of @B nor is
- * @B a descendant of @A.
+ * Pointer dev moves from A to B and A neither a descendant of B nor is
+ * B a descendant of A.
  */
 static void
 CoreEnterLeaveNonLinear(DeviceIntPtr dev,
@@ -418,7 +426,7 @@ CoreEnterLeaveNonLinear(DeviceIntPtr dev,
 }
 
 /**
- * Pointer @dev moves from @A to @B and @A is a descendant of @B.
+ * Pointer dev moves from A to B and A is a descendant of B.
  */
 static void
 CoreEnterLeaveToAncestor(DeviceIntPtr dev,
@@ -476,7 +484,7 @@ CoreEnterLeaveToAncestor(DeviceIntPtr dev,
 
 
 /**
- * Pointer @dev moves from @A to @B and @B is a descendant of @A.
+ * Pointer dev moves from A to B and B is a descendant of A.
  */
 static void
 CoreEnterLeaveToDescendant(DeviceIntPtr dev,
@@ -605,7 +613,7 @@ DoEnterLeaveEvents(DeviceIntPtr pDev,
 }
 
 /**
- * Send focus out events to all windows between @child and @ancestor.
+ * Send focus out events to all windows between 'child' and 'ancestor'.
  * Events are sent running up the hierarchy.
  */
 static void
@@ -625,7 +633,7 @@ DeviceFocusOutEvents(DeviceIntPtr dev,
 
 
 /**
- * Send enter notifies to all windows between @ancestor and @child (excluding
+ * Send enter notifies to all windows between 'ancestor' and 'child' (excluding
  * both). Events are sent running up the window hierarchy. This function
  * recurses.
  */
@@ -645,7 +653,7 @@ DeviceFocusInEvents(DeviceIntPtr dev,
 }
 
 /**
- * Send FocusIn events to all windows between @ancestor and @child (excluding
+ * Send FocusIn events to all windows between 'ancestor' and 'child' (excluding
  * both). Events are sent running down the window hierarchy. This function
  * recurses.
  */
@@ -727,13 +735,13 @@ CoreFocusOutEvents(DeviceIntPtr dev,
 
 /**
  * Send FocusOut(NotifyPointer) events from the current pointer window (which
- * is a descendant of @pwin_parent) up to (excluding) @pwin_parent.
+ * is a descendant of pwin_parent) up to (excluding) pwin_parent.
  *
- * NotifyPointer events are only sent for the device paired with @dev.
+ * NotifyPointer events are only sent for the device paired with dev.
  *
- * If the current pointer window is a descendat of @exclude or an ancestor of
- * @exclude, no events are sent. Note: If the current pointer IS @exclude,
- * events are sent!
+ * If the current pointer window is a descendant of 'exclude' or an ancestor of
+ * 'exclude', no events are sent. If the current pointer IS 'exclude', events
+ * are sent!
  */
 static void
 CoreFocusOutNotifyPointerEvents(DeviceIntPtr dev,
@@ -782,13 +790,13 @@ CoreFocusInRecurse(DeviceIntPtr dev,
 
 
 /**
- * Send FocusIn(NotifyPointer) events from @pwin_parent down to
- * including the current pointer window (which is a descendant of @pwin_parent).
- * If @inclusive is TRUE, @pwin_parent will receive the event too.
+ * Send FocusIn(NotifyPointer) events from pwin_parent down to
+ * including the current pointer window (which is a descendant of pwin_parent).
  *
- * @pwin is the pointer window.
- *
- * If the current pointer window is a child of @exclude, no events are sent.
+ * @param pwin The pointer window.
+ * @param exclude If the pointer window is a child of 'exclude', no events are
+ *                sent.
+ * @param inclusive If TRUE, pwin_parent will receive the event too.
  */
 static void
 CoreFocusInNotifyPointerEvents(DeviceIntPtr dev,
@@ -812,8 +820,8 @@ CoreFocusInNotifyPointerEvents(DeviceIntPtr dev,
 
 
 /**
- * Focus of @dev moves from @A to @B and @A neither a descendant of @B nor is
- * @B a descendant of @A.
+ * Focus of dev moves from A to B and A neither a descendant of B nor is
+ * B a descendant of A.
  */
 static void
 CoreFocusNonLinear(DeviceIntPtr dev,
@@ -910,7 +918,7 @@ CoreFocusNonLinear(DeviceIntPtr dev,
 
 
 /**
- * Focus of @dev moves from @A to @B and @A is a descendant of @B.
+ * Focus of dev moves from A to B and A is a descendant of B.
  */
 static void
 CoreFocusToAncestor(DeviceIntPtr dev,
@@ -971,7 +979,7 @@ CoreFocusToAncestor(DeviceIntPtr dev,
 }
 
 /**
- * Focus of @dev moves from @A to @B and @B is a descendant of @A.
+ * Focus of dev moves from A to B and B is a descendant of A.
  */
 static void
 CoreFocusToDescendant(DeviceIntPtr dev,
@@ -1068,7 +1076,7 @@ CoreFocusPointerRootNoneSwitch(DeviceIntPtr dev,
         if (!HasOtherPointer(root, GetPairedDevice(dev)) && !FirstFocusChild(root))
         {
             /* If pointer was on PointerRootWin and changes to NoneWin, and
-             * the pointer paired with @dev is below the current root window,
+             * the pointer paired with dev is below the current root window,
              * do a NotifyPointer run. */
             if (dev->focus && dev->focus->win == PointerRootWin &&
                 B != PointerRootWin)
@@ -1087,8 +1095,8 @@ CoreFocusPointerRootNoneSwitch(DeviceIntPtr dev,
 }
 
 /**
- * Focus moves from window @A to PointerRoot or to None.
- * Assumption: @A is a valid window and not PointerRoot or None.
+ * Focus moves from window A to PointerRoot or to None.
+ * Assumption: A is a valid window and not PointerRoot or None.
  */
 static void
 CoreFocusToPointerRootOrNone(DeviceIntPtr dev,
@@ -1136,8 +1144,8 @@ CoreFocusToPointerRootOrNone(DeviceIntPtr dev,
 }
 
 /**
- * Focus moves from PointerRoot or None to a window @to.
- * Assumption: @to is a valid window and not PointerRoot or None.
+ * Focus moves from PointerRoot or None to a window B.
+ * Assumption: B is a valid window and not PointerRoot or None.
  */
 static void
 CoreFocusFromPointerRootOrNone(DeviceIntPtr dev,
@@ -1160,7 +1168,7 @@ CoreFocusFromPointerRootOrNone(DeviceIntPtr dev,
         if (!HasFocus(root) && !FirstFocusChild(root))
         {
             /* If pointer was on PointerRootWin and changes to NoneWin, and
-             * the pointer paired with @dev is below the current root window,
+             * the pointer paired with dev is below the current root window,
              * do a NotifyPointer run. */
             if (dev->focus && dev->focus->win == PointerRootWin &&
                 B != PointerRootWin)
@@ -1229,6 +1237,9 @@ CoreFocusEvents(DeviceIntPtr dev,
     SetFocusIn(dev, to);
 }
 
+/**
+ * The root window the given device is currently on.
+ */
 #define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0]
 
 static void
commit cc696a2b7928ec497b6a0df3602fc70dec83a629
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 12 15:05:57 2009 +1000

    Doxygen-ify bits of events.c

diff --git a/dix/events.c b/dix/events.c
index d34d739..14a0e5e 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -107,7 +107,7 @@ of the copyright holder.
 
 ******************************************************************/
 
-/** @file
+/** @file events.c
  * This file handles event delivery and a big part of the server-side protocol
  * handling (the parts for input devices).
  */
@@ -163,9 +163,7 @@ typedef const char *string;
 
 #include "enterleave.h"
 
-/**
- * Extension events type numbering starts at EXTENSION_EVENT_BASE.
- */
+/* Extension events type numbering starts at EXTENSION_EVENT_BASE.  */
 #define NoSuchEvent 0x80000000	/* so doesn't match NoEventMask */
 #define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
 #define AllButtonsMask ( \
@@ -246,30 +244,35 @@ InputInfo inputInfo;
 
 /**
  * syncEvents is the global structure for queued events.
+ *
  * Devices can be frozen through GrabModeSync pointer grabs. If this is the
  * case, events from these devices are added to "pending" instead of being
  * processed normally. When the device is unfrozen, events in "pending" are
  * replayed and processed as if they would come from the device directly.
- *
- * pending ... list of queued events
- * pendtail ... last event in list
- * replayDev ... The device to replay events for. Only set in AllowEvents, in
- *               which case it is set to the device specified in the request.
- * replayWin ... the window the events are supposed to be replayed on. This
- *               window may be set to the grab's window (but only when
- *               Replay{Pointer|Keyboard} is given in the XAllowEvents
- *               request.
- * playingEvents ... flag to indicate whether we're in the process of
- *                   replaying events. Only set in ComputeFreezes().
  */
 static struct {
-    QdEventPtr		pending, *pendtail;
+    QdEventPtr		pending, /**<  list of queued events */
+                        *pendtail; /**< last event in list */
+    /** The device to replay events for. Only set in AllowEvents(), in which
+     * case it is set to the device specified in the request. */
     DeviceIntPtr	replayDev;	/* kludgy rock to put flag for */
+
+    /**
+     * The window the events are supposed to be replayed on.
+     * This window may be set to the grab's window (but only when
+     * Replay{Pointer|Keyboard} is given in the XAllowEvents()
+     * request. */
     WindowPtr		replayWin;	/*   ComputeFreezes            */
+    /**
+     * Flag to indicate whether we're in the process of
+     * replaying events. Only set in ComputeFreezes(). */
     Bool		playingEvents;
     TimeStamp		time;
 } syncEvents;
 
+/**
+ * The root window the given device is currently on.
+ */
 #define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0]
 
 static xEvent* swapEvent = NULL;
@@ -277,6 +280,7 @@ static int swapEventLen = 0;
 
 /**
  * Convert the given event type from an XI event to a core event.
+ * @param[in] The XI 1.x event type.
  * @return The matching core event type or 0 if there is none.
  */
 int
@@ -298,8 +302,8 @@ XItoCoreType(int xitype)
 }
 
 /**
- * True if device owns a cursor, false if device shares a cursor sprite with
- * another device.
+ * @return true if the device owns a cursor, false if device shares a cursor
+ * sprite with another device.
  */
 Bool
 DevHasCursor(DeviceIntPtr pDev)
@@ -308,7 +312,7 @@ DevHasCursor(DeviceIntPtr pDev)
 }
 
 /*
- * Return true if a device is a pointer, check is the same as used by XI to
+ * @return true if a device is a pointer, check is the same as used by XI to
  * fill the 'use' field.
  */
 Bool
@@ -318,7 +322,7 @@ IsPointerDevice(DeviceIntPtr dev)
 }
 
 /*
- * Return true if a device is a keyboard, check is the same as used by XI to
+ * @return true if a device is a keyboard, check is the same as used by XI to
  * fill the 'use' field.
  *
  * Some pointer devices have keys as well (e.g. multimedia keys). Try to not
commit 8364bf7374aa5f6d991700f0c02921dc6c638c9f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 11 16:06:36 2009 +1000

    Document the event masks.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 0db2d6a..d34d739 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -345,11 +345,20 @@ static Mask lastEventMask;
 
 extern int DeviceMotionNotify;
 
+#define CantBeFiltered NoEventMask
 /**
- * Event filters. One set of filters for each device, but only the first layer
+ * Event masks for each event type.
+ *
+ * One set of filters for each device, but only the first layer
  * is initialized. The rest is memcpy'd in InitEvents.
+ *
+ * Filters are used whether a given event may be delivered to a client,
+ * usually in the form of if (window-event-mask & filter); then deliver event.
+ *
+ * One notable filter is for PointerMotion/DevicePointerMotion events. Each
+ * time a button is pressed, the filter is modified to also contain the
+ * matching ButtonXMotion mask.
  */
-#define CantBeFiltered NoEventMask
 static Mask filters[MAXDEVICES][128] = {
 {
 	NoSuchEvent,		       /* 0 */
@@ -3621,7 +3630,7 @@ FixKeyState (xEvent *xE, DeviceIntPtr keybd)
  * The otherEventMasks on a WindowOptional is the combination of all event
  * masks set by all clients on the window.
  * deliverableEventMask is the combination of the eventMask and the
- * otherEventMask.
+ * otherEventMask plus the events that may be propagated to the parent.
  *
  * Traverses to siblings and parents of the window.
  */
diff --git a/include/inputstr.h b/include/inputstr.h
index 2b6de02..bed71be 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -65,24 +65,66 @@ SOFTWARE.
 
 #define EMASKSIZE	MAXDEVICES + 1
 
-/* Kludge: OtherClients and InputClients must be compatible, see code */
-
+/**
+ * This struct stores the core event mask for each client except the client
+ * that created the window.
+ *
+ * Each window that has events selected from other clients has at least one of
+ * these masks. If multiple clients selected for events on the same window,
+ * these masks are in a linked list.
+ *
+ * The event mask for the client that created the window is stored in
+ * win->eventMask instead.
+ *
+ * The resource id is simply a fake client ID to associate this mask with a
+ * client.
+ *
+ * Kludge: OtherClients and InputClients must be compatible, see code.
+ */
 typedef struct _OtherClients {
-    OtherClientsPtr	next;
-    XID			resource; /* id for putting into resource manager */
-    Mask		mask;
+    OtherClientsPtr	next; /**< Pointer to the next mask */
+    XID			resource; /**< id for putting into resource manager */
+    Mask		mask; /**< Core event mask */
 } OtherClients;
 
+/**
+ * This struct stores the XI event mask for each client.
+ *
+ * Each window that has events selected has at least one of these masks. If
+ * multiple client selected for events on the same window, these masks are in
+ * a linked list.
+ */
 typedef struct _InputClients {
-    InputClientsPtr	next;
-    XID			resource; /* id for putting into resource manager */
-    Mask		mask[EMASKSIZE];
+    InputClientsPtr	next; /**< Pointer to the next mask */
+    XID			resource; /**< id for putting into resource manager */
+    Mask		mask[EMASKSIZE]; /**< Actual XI event mask, deviceid is index */
 } InputClients;
 
+/**
+ * Combined XI event masks from all devices.
+ *
+ * This is the XI equivalent of the deliverableEvents, eventMask and
+ * dontPropagate mask of the WindowRec (or WindowOptRec).
+ *
+ * A window that has an XI client selecting for events has exactly one
+ * OtherInputMasks struct and exactly one InputClients struct hanging off
+ * inputClients. Each further client appends to the inputClients list.
+ * Each Mask field is per-device, with the device id as the index.
+ * Exception: for non-device events (Presence events), the MAX_DEVICES
+ * deviceid is used.
+ */
 typedef struct _OtherInputMasks {
+    /**
+     * Bitwise OR of all masks by all clients and the window's parent's masks.
+     */
     Mask		deliverableEvents[EMASKSIZE];
+    /**
+     * Bitwise OR of all masks by all clients on this window.
+     */
     Mask		inputEvents[EMASKSIZE];
+    /** The do-not-propagate masks for each device. */
     Mask		dontPropagateMask[EMASKSIZE];
+    /** The clients that selected for events */
     InputClientsPtr	inputClients;
 } OtherInputMasks;
 
diff --git a/include/windowstr.h b/include/windowstr.h
index 8ce3230..720803a 100644
--- a/include/windowstr.h
+++ b/include/windowstr.h
@@ -153,8 +153,8 @@ typedef struct _Window {
     RegionRec		borderSize;
     DDXPointRec		origin;		/* position relative to parent */
     unsigned short	borderWidth;
-    unsigned short	deliverableEvents;
-    Mask		eventMask;
+    unsigned short	deliverableEvents; /* all masks from all clients */
+    Mask		eventMask;      /* mask from the creating client */
     PixUnion		background;
     PixUnion		border;
     pointer		backStorage;	/* null when BS disabled */
commit ed9d58c3c25ee1b3dedbc4c116823c263ccf164d
Author: Simon Thum <simon.thum at gmx.de>
Date:   Sun Feb 8 17:21:09 2009 +0100

    dix: refactor pointer acceleration
    
    The algorithm is split in a 2D-specific and a general part.
    This potentially allows to accelerate more than just screen motion.
    A state machine is intoduced to make code more explicit and readable.
    It also improves handling of 'phase 1' mickeys when axial correction
    kicks in (corner case).
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index dcf91df..30e0207 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -81,7 +81,8 @@ SimpleSmoothProfile(DeviceVelocityPtr pVel, float velocity,
                     float threshold, float acc);
 static PointerAccelerationProfileFunc
 GetAccelerationProfile(DeviceVelocityPtr s, int profile_num);
-
+static short
+ProcessVelocityData(DeviceVelocityPtr s, float distance, int diff);
 
 /*#define PTRACCEL_DEBUGGING*/
 
@@ -519,38 +520,35 @@ GetAxis(int dx, int dy){
             return 1;
         if(dy == 1 || dy == -1)
             return 2;
-        return -1;
-    }else{
-        return -1;
     }
+    return -1;
 }
 
 
 /**
- * Perform velocity approximation
+ * Perform velocity approximation based on 2D 'mickeys' (mouse motion delta).
  * return true if non-visible state reset is suggested
  */
 static short
-ProcessVelocityData(
+ProcessVelocityData2D(
     DeviceVelocityPtr s,
     int dx,
     int dy,
     int time)
 {
-    float cvelocity;
+    float distance;
 
     int diff = time - s->lrm_time;
     int cur_ax, last_ax;
-    short reset = (diff >= s->reset_time);
+    BOOL reset;
 
-    /* remember last round's result */
-    s->last_velocity = s->velocity;
     cur_ax = GetAxis(dx, dy);
     last_ax = GetAxis(s->last_dx, s->last_dy);
 
-    if(cur_ax != last_ax && cur_ax != -1 && last_ax != -1 && !reset){
+    if(cur_ax != last_ax && cur_ax != -1 && last_ax != -1 &&
+	    diff < s->reset_time){
         /* correct for the error induced when diagonal movements are
-           reported as alternating axis mickeys */
+           reported as alternating axis-aligned mickeys */
         dx += s->last_dx;
         dy += s->last_dy;
         diff += s->last_diff;
@@ -560,6 +558,33 @@ ProcessVelocityData(
         s->last_diff = diff;
     }
 
+    distance = (float)sqrt(dx*dx + dy*dy);
+
+    s->lrm_time = time;
+
+    reset = ProcessVelocityData(s, distance, diff);
+
+    if(reset)
+	s->last_diff = 1;
+    return reset;
+}
+
+/**
+ * Perform velocity approximation given a one-dimensional delta.
+ * return true if non-visible state reset is suggested
+ */
+static short
+ProcessVelocityData(
+    DeviceVelocityPtr s,
+    float distance,
+    int diff)
+{
+    float cvelocity;
+    int phase;
+
+    /* remember previous result */
+    s->last_velocity = s->velocity;
+
     /*
      * cvelocity is not a real velocity yet, more a motion delta. constant
      * acceleration is multiplied here to make the velocity an on-screen
@@ -567,9 +592,7 @@ ProcessVelocityData(
      * make multiple devices with widely varying ConstantDecelerations respond
      * similar to acceleration controls.
      */
-    cvelocity = (float)sqrt(dx*dx + dy*dy) * s->const_acceleration;
-
-    s->lrm_time = time;
+    cvelocity = distance * s->const_acceleration;
 
     if (s->reset_time < 0 || diff < 0) { /* reset disabled or timer overrun? */
         /* simply set velocity from current movement, no reset. */
@@ -577,6 +600,24 @@ ProcessVelocityData(
         return FALSE;
     }
 
+    /* try to determine 'phase', i.e. whether we process the first(0),
+     * second(1) or any following motion event of a stroke(2) */
+    if(diff >= s->reset_time && cvelocity < 10){
+	phase = 0;
+    }else{
+	switch(s->last_phase){
+	case 0:
+	case 1:
+	    phase = s->last_phase + 1;
+	    break;
+	default:
+	    phase = 2;
+	    break;
+	}
+    }
+    s->last_phase = phase;
+    DebugAccelF("(dix ptracc) phase: %i\n", phase);
+
     if (diff == 0)
         diff = 1; /* prevent div-by-zero, though it shouldn't happen anyway*/
 
@@ -584,47 +625,47 @@ ProcessVelocityData(
        so we multiply by some per-device adjustable factor) */
     cvelocity = cvelocity * s->corr_mul / (float)diff;
 
-    /* short-circuit: when nv-reset the rest can be skipped */
-    if(reset == TRUE){
+    switch(phase){
+    case 0:
 	/*
-	 * we don't really have a velocity here, since diff includes inactive
-	 * time. This is dealt with in ComputeAcceleration.
+	 * First event of a stroke.
+	 * We don't really have a velocity here, since diff includes inactive
+	 * time. This is dealt with in ComputeAcceleration. Here we cancel out
+	 * remnants from previous strokes which the user is presumably
+	 * not aware of (non-visible state reset).
 	 */
 	StuffFilterChain(s, cvelocity);
 	s->velocity = s->last_velocity = cvelocity;
-	s->last_reset = TRUE;
 	DebugAccelF("(dix ptracc) non-visible state reset\n");
 	return TRUE;
-    }
-
-    if(s->last_reset == TRUE){
+    case 1:
 	/*
 	 * when here, we're probably processing the second mickey of a starting
 	 * stroke. This happens to be the first time we can reasonably pretend
 	 * that cvelocity is an actual velocity. Thus, to opt precision, we
 	 * stuff that into the filter chain.
 	 */
-	s->last_reset = FALSE;
 	DebugAccelF("(dix ptracc) after-reset vel:%.3f\n", cvelocity);
 	StuffFilterChain(s, cvelocity);
 	s->velocity = cvelocity;
 	return FALSE;
+    default:
+	/* normal operarion: feed into filter chain */
+	FeedFilterChain(s, cvelocity, diff);
+
+	/* perform coupling and decide final value */
+	s->velocity = QueryFilterChain(s, cvelocity);
+
+	DebugAccelF(
+	       "(dix ptracc) guess: vel=%.3f diff=%d   %i|%i|%i|%i|%i|%i|%i|%i|%i\n",
+	       s->velocity, diff,
+	       s->statistics.filter_usecount[0], s->statistics.filter_usecount[1],
+	       s->statistics.filter_usecount[2], s->statistics.filter_usecount[3],
+	       s->statistics.filter_usecount[4], s->statistics.filter_usecount[5],
+	       s->statistics.filter_usecount[6], s->statistics.filter_usecount[7],
+	       s->statistics.filter_usecount[8]);
+	return FALSE;
     }
-
-    /* feed into filter chain */
-    FeedFilterChain(s, cvelocity, diff);
-
-    /* perform coupling and decide final value */
-    s->velocity = QueryFilterChain(s, cvelocity);
-
-    DebugAccelF("(dix ptracc) guess: vel=%.3f diff=%d   %i|%i|%i|%i|%i|%i|%i|%i|%i\n",
-           s->velocity, diff,
-           s->statistics.filter_usecount[0], s->statistics.filter_usecount[1],
-           s->statistics.filter_usecount[2], s->statistics.filter_usecount[3],
-           s->statistics.filter_usecount[4], s->statistics.filter_usecount[5],
-           s->statistics.filter_usecount[6], s->statistics.filter_usecount[7],
-           s->statistics.filter_usecount[8]);
-    return FALSE;
 }
 
 
@@ -696,7 +737,7 @@ ComputeAcceleration(
     float acc){
     float res;
 
-    if(vel->last_reset){
+    if(vel->last_phase == 0){
 	DebugAccelF("(dix ptracc) profile skipped\n");
         /*
          * This is intended to override the first estimate of a stroke,
@@ -1009,6 +1050,7 @@ acceleratePointerPredictable(
     DeviceVelocityPtr velocitydata =
 	(DeviceVelocityPtr) pDev->valuator->accelScheme.accelData;
     float fdx, fdy; /* no need to init */
+    Bool soften = TRUE;
 
     if (!num_valuators || !valuators || !velocitydata)
         return;
@@ -1023,16 +1065,15 @@ acceleratePointerPredictable(
     }
 
     if (dx || dy){
-        /* reset nonvisible state? */
-        if (ProcessVelocityData(velocitydata, dx , dy, evtime)) {
-            /* set to center of pixel. makes sense as long as there are no
-             * means of passing on sub-pixel values.
+        /* reset non-visible state? */
+        if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) {
+            /* if nv-reset: set to center of pixel.
+             * makes sense as long as there are no means of passing on
+             * sub-pixel values to apps(XI2?). If you remove it, make
+             * sure suitable rounding is applied below.
              */
             pDev->last.remainder[0] = pDev->last.remainder[1] = 0.5f;
-            /* prevent softening (somewhat quirky solution,
-            as it depends on the algorithm) */
-            velocitydata->last_dx = dx;
-            velocitydata->last_dy = dy;
+            soften = FALSE;
         }
 
         if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) {
@@ -1044,9 +1085,10 @@ acceleratePointerPredictable(
 
             if(mult != 1.0 || velocitydata->const_acceleration != 1.0) {
                 ApplySofteningAndConstantDeceleration( velocitydata,
-                                                       dx, dy,
-                                                       &fdx, &fdy,
-                                                       mult > 1.0);
+						       dx, dy,
+						       &fdx, &fdy,
+						       (mult > 1.0) && soften);
+
                 if (dx) {
                     pDev->last.remainder[0] = mult * fdx + pDev->last.remainder[0];
                     *px = (int)pDev->last.remainder[0];
diff --git a/include/ptrveloc.h b/include/ptrveloc.h
index 096dea8..f9933c9 100644
--- a/include/ptrveloc.h
+++ b/include/ptrveloc.h
@@ -83,7 +83,7 @@ typedef struct _DeviceVelocityRec {
     int     lrm_time;       /* time the last motion event was processed  */
     int     last_dx, last_dy; /* last motion delta */
     int     last_diff;      /* last time-difference */
-    Bool    last_reset;     /* whether a nv-reset occurred just before */
+    int     last_phase;     /* phase of last/current estimate */
     float   corr_mul;       /* config: multiply this into velocity */
     float   const_acceleration;  /* config: (recipr.) const deceleration */
     float   min_acceleration;    /* config: minimum acceleration */


More information about the xorg-commit mailing list