<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7654.12">
<TITLE>RE: Not receiving XI_RawMotion events while mouse button is pressed.</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->
<BR>

<P><FONT SIZE=2>I'm new to X so I haven't mastered all the terms yet.&nbsp; I just know now that the moment a button press event is received (for a click and drag), the raw motion events stop coming.&nbsp; The only way I &quot;fixed&quot; it is to have both windows/screens issue the call to setup the mask to monitor the raw motion events.&nbsp; I honestly don't understand why that works.&nbsp; Let me try setting up the raw button press and not use the old one to see if that avoids the problem.&nbsp; Thanks for the suggestion.<BR>
<BR>
Roger<BR>
<BR>
<BR>
-----Original Message-----<BR>
From: Peter Hutterer [<A HREF="mailto:peter.hutterer@who-t.net">mailto:peter.hutterer@who-t.net</A>]<BR>
Sent: Wed 5/11/2011 7:55 PM<BR>
To: Roger Cruz<BR>
Cc: xorg-devel@lists.x.org<BR>
Subject: Re: Not receiving XI_RawMotion events while mouse button is pressed.<BR>
<BR>
On Wed, May 11, 2011 at 01:08:45PM -0500, Roger Cruz wrote:<BR>
&gt; Thanks for answering.&nbsp; I think your suspicion about the implicit pointer<BR>
&gt; grab is probably correctly.&nbsp; Here is what I found out.<BR>
&gt;<BR>
&gt; The problem only occurred when my application was run on a system with two<BR>
&gt; monitors.&nbsp; Our code creates an X window/screen for each monitor (both<BR>
&gt; screens are within the same frame buffer).&nbsp; When I added the XI raw motion<BR>
&gt; code, I only enabled raw motion events for the primary window and not for<BR>
&gt; the secondary window.&nbsp; I had to do this because I was receiving the same<BR>
&gt; raw event twice (one for each window).&nbsp; I used these pointer movements for<BR>
&gt; an emulated mouse and having them delivered twice caused unnecessary<BR>
&gt; &quot;acceleration&quot;.<BR>
&gt;<BR>
&gt; The problem is that another application in our code warps the pointer to<BR>
&gt; the secondary screen unbeknownst to me.&nbsp; This didn't appear to have any<BR>
&gt; side effects and I still got the raw motions events until the user<BR>
&gt; performed a click and drag operation.&nbsp; In this case we didn't get the raw<BR>
&gt; motion movements from the secondary window anymore.<BR>
&gt;<BR>
&gt; Based on what you described below, it appears (please correct me if wrong)<BR>
&gt; that when the user clicks on the secondary screen, the pointer is<BR>
&gt; implicitly grabbed and all the raw motion events are not delivered to the<BR>
&gt; root window.&nbsp; It is my understanding that raw motion events only work with<BR>
&gt; the root window so if you look at my code below, when we register for the<BR>
&gt; raw motion events, we do so at for the root window.&nbsp; The root window<BR>
&gt; should contain both the X screens mentioned above.<BR>
&gt;<BR>
&gt; Now, I can't change the code that warps the pointer to the secondary<BR>
&gt; screen so I have to be able to fix this problem entirely within my mouse<BR>
&gt; code.&nbsp; I have re-enabled the code so that both X windows call the code<BR>
&gt; below to register for raw motion.&nbsp; This fixes my click and drag problem<BR>
&gt; but now I have the problem double events being delivered to my<BR>
&gt; application.&nbsp; Any suggestions on how to prevent that from occurring?<BR>
<BR>
Raw events are delivered to all root windows, regardless which window the<BR>
pointer is on. so you don't need to select on both root windows, the first<BR>
one is enough.<BR>
<BR>
I'm not sure how you'd fix the click-and-drag problem though. once you<BR>
deliver the ButtonPress event anywhere (unless it's an XI_ButtonPress<BR>
event), you lose the ability to receive raw events. at least that's how the<BR>
server is currently written, or so I thought.<BR>
<BR>
but tbh, you're mixing window and screen terminologies here so I'm not sure<BR>
what your setup is and why the above would work in your case.<BR>
<BR>
&gt; Thanks<BR>
&gt;<BR>
&gt; Roger R. Cruz<BR>
&gt;<BR>
&gt;<BR>
&gt; static void<BR>
&gt; enable_or_disable_xi_rawmotion_events(xstate_t *xs, xi_enable_disable state)<BR>
&gt; {<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char mask[3] = { 0, 0, 0 };<BR>
<BR>
I recommend using XIMaskLen(XI_RawMotion) here for the array length.<BR>
though admittedly that was buggy for a while...<BR>
<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XIEventMask *eventmask;<BR>
&gt;<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * This routine is commented out due a bug in X11's XI extension<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * which leaves the display lock taken.&nbsp; It is fixed in version<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 1.3.1 so when we upgrade to that version or newer, we can<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * re-enable the code.<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * eventmask = XIGetSelectedEvents(xs-&gt;dpy, xs-&gt;w, &amp;num);<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
&gt;<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eventmask = NULL;<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!eventmask) {<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eventmask = (XIEventMask *)xmalloc(sizeof(*eventmask));<BR>
<BR>
xmalloc? that's a server-internal function (that has now been removed). just<BR>
using normal calloc will do.<BR>
<BR>
Cheers,<BR>
&nbsp; Peter<BR>
&gt;<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eventmask-&gt;mask_len = sizeof(mask);<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eventmask-&gt;mask = mask;<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eventmask-&gt;deviceid = XIAllMasterDevices;<BR>
&gt;<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (state == XI_ENABLE_RAWMOTION)<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /* Register for pointer motion events in raw form */<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XISetMask(eventmask-&gt;mask, XI_RawMotion);<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Unregister for pointer motion events in raw form */<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XIClearMask(eventmask-&gt;mask, XI_RawMotion);<BR>
&gt;<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XISelectEvents(xs-&gt;dpy, DefaultRootWindow(xs-&gt;dpy), eventmask, 1);<BR>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(eventmask);<BR>
&gt; }<BR>
&gt;<BR>
&gt;<BR>
&gt; -----Original Message-----<BR>
&gt; From: Peter Hutterer [<A HREF="mailto:peter.hutterer@who-t.net">mailto:peter.hutterer@who-t.net</A>]<BR>
&gt; Sent: Tue 5/10/2011 7:13 PM<BR>
&gt; To: Roger Cruz<BR>
&gt; Cc: xorg-devel@lists.x.org<BR>
&gt; Subject: Re: Not receiving XI_RawMotion events while mouse button is pressed.<BR>
&gt;&nbsp;<BR>
&gt; On Tue, May 10, 2011 at 01:56:19PM -0500, Roger Cruz wrote:<BR>
&gt; &gt; I have integrated libxi2's capability to provide raw motion pointer values<BR>
&gt; &gt; into my application which was originally using (and still uses) xinput<BR>
&gt; &gt; events.&nbsp; The application currently registers for the old xinput events<BR>
&gt; &gt; using XSelectInput.&nbsp;<BR>
&gt; &gt;<BR>
&gt; &gt; &nbsp;&nbsp;&nbsp; XSelectInput(xs-&gt;dpy, xs-&gt;w, event_mask);<BR>
&gt; &gt;<BR>
&gt; &gt; where the event mask is<BR>
&gt; &gt;<BR>
&gt; &gt; &nbsp;&nbsp;&nbsp; event_mask = (OwnerGrabButtonMask &lt;&lt; 1) - 1;&nbsp;&nbsp;&nbsp; /* all events */<BR>
&gt; &gt;<BR>
&gt; &gt; &nbsp;&nbsp;&nbsp; event_mask &amp;= ~PointerMotionHintMask;<BR>
&gt; &gt; &nbsp;&nbsp;&nbsp; event_mask &amp;= ~PropertyChangeMask;<BR>
&gt; &gt; &nbsp;&nbsp;&nbsp; event_mask &amp;= ~ColormapChangeMask;<BR>
&gt; &gt; &nbsp;&nbsp;&nbsp; event_mask &amp;= ~SubstructureNotifyMask;<BR>
&gt; &gt;<BR>
&gt; &gt;<BR>
&gt; &gt; I added an additional xinput2 registration to only capture the raw motion events which I needed.<BR>
&gt; &gt;<BR>
&gt; &gt; &nbsp;&nbsp;&nbsp; XISetMask(eventmask-&gt;mask, XI_RawMotion);<BR>
&gt; &gt; &nbsp;&nbsp;&nbsp; XISelectEvents(xs-&gt;dpy, DefaultRootWindow(xs-&gt;dpy), eventmask, 1);<BR>
&gt; &gt;<BR>
&gt; &gt; This appears to be working fine.&nbsp; I get raw motion and mouse button press<BR>
&gt; &gt; and releases when done independently.&nbsp; However, when I click to drag, I<BR>
&gt; &gt; only get the button press event but not the raw motion events.&nbsp; Is this<BR>
&gt; &gt; expected behavior for the current implementation of libxi?&nbsp; I need to be<BR>
&gt; &gt; able to get raw motion events even when the button is pressed.&nbsp; I don't<BR>
&gt; &gt; believe anyone else is grabbing the pointer.<BR>
&gt;<BR>
&gt; If the button press event is delivered somewhere, this activated an implicit<BR>
&gt; grab in the server and the device is now grabbed by that client that<BR>
&gt; received the button press event. I suspect this is the cause here too.<BR>
&gt;<BR>
&gt; Furthermore, XI and XI2 grabs are handled separately, so if you get a XI1<BR>
&gt; grab, it does not carry the XI2 event mask. Your raw event is thus not<BR>
&gt; delivered once you have an XI grab.<BR>
&gt;<BR>
&gt; Cheers,<BR>
&gt;&nbsp;&nbsp; Peter<BR>
&gt;<BR>
&gt; No virus found in this incoming message.<BR>
&gt; Checked by AVG - www.avg.com<BR>
&gt; Version: 9.0.900 / Virus Database: 271.1.1/3617 - Release Date: 05/10/11 14:34:00<BR>
&gt;<BR>
<BR>
No virus found in this incoming message.<BR>
Checked by AVG - www.avg.com<BR>
Version: 9.0.900 / Virus Database: 271.1.1/3617 - Release Date: 05/11/11 15:12:00<BR>
<BR>
</FONT>
</P>

</BODY>
</HTML>