RE: Not receiving XI_RawMotion events while mouse button is pressed.

2011-05-11 Thread Roger Cruz
Hi Peter,

Thanks for answering.  I think your suspicion about the implicit pointer grab 
is probably correctly.  Here is what I found out.

The problem only occurred when my application was run on a system with two 
monitors.  Our code creates an X window/screen for each monitor (both screens 
are within the same frame buffer).  When I added the XI raw motion code, I only 
enabled raw motion events for the primary window and not for the secondary 
window.  I had to do this because I was receiving the same raw event twice (one 
for each window).  I used these pointer movements for an emulated mouse and 
having them delivered twice caused unnecessary acceleration.

The problem is that another application in our code warps the pointer to the 
secondary screen unbeknownst to me.  This didn't appear to have any side 
effects and I still got the raw motions events until the user performed a click 
and drag operation.  In this case we didn't get the raw motion movements from 
the secondary window anymore.

Based on what you described below, it appears (please correct me if wrong) that 
when the user clicks on the secondary screen, the pointer is implicitly grabbed 
and all the raw motion events are not delivered to the root window.  It is my 
understanding that raw motion events only work with the root window so if you 
look at my code below, when we register for the raw motion events, we do so at 
for the root window.  The root window should contain both the X screens 
mentioned above.

Now, I can't change the code that warps the pointer to the secondary screen so 
I have to be able to fix this problem entirely within my mouse code.  I have 
re-enabled the code so that both X windows call the code below to register for 
raw motion.  This fixes my click and drag problem but now I have the problem 
double events being delivered to my application.  Any suggestions on how to 
prevent that from occurring? 

Thanks

Roger R. Cruz


static void
enable_or_disable_xi_rawmotion_events(xstate_t *xs, xi_enable_disable state)
{
unsigned char mask[3] = { 0, 0, 0 };
XIEventMask *eventmask;

/*
 * This routine is commented out due a bug in X11's XI extension
 * which leaves the display lock taken.  It is fixed in version
 * 1.3.1 so when we upgrade to that version or newer, we can
 * re-enable the code.
 * eventmask = XIGetSelectedEvents(xs-dpy, xs-w, num);
 */

eventmask = NULL;
if (!eventmask) {
eventmask = (XIEventMask *)xmalloc(sizeof(*eventmask));
eventmask-mask_len = sizeof(mask);
eventmask-mask = mask;
}

eventmask-deviceid = XIAllMasterDevices;

if (state == XI_ENABLE_RAWMOTION)
  /* Register for pointer motion events in raw form */
XISetMask(eventmask-mask, XI_RawMotion);
else
/* Unregister for pointer motion events in raw form */
XIClearMask(eventmask-mask, XI_RawMotion);

XISelectEvents(xs-dpy, DefaultRootWindow(xs-dpy), eventmask, 1);
free(eventmask);
}


-Original Message-
From: Peter Hutterer [mailto:peter.hutte...@who-t.net]
Sent: Tue 5/10/2011 7:13 PM
To: Roger Cruz
Cc: xorg-devel@lists.x.org
Subject: Re: Not receiving XI_RawMotion events while mouse button is pressed.
 
On Tue, May 10, 2011 at 01:56:19PM -0500, Roger Cruz wrote:
 I have integrated libxi2's capability to provide raw motion pointer values
 into my application which was originally using (and still uses) xinput
 events.  The application currently registers for the old xinput events
 using XSelectInput.  
 
   XSelectInput(xs-dpy, xs-w, event_mask);
 
 where the event mask is
 
   event_mask = (OwnerGrabButtonMask  1) - 1;/* all events */
 
   event_mask = ~PointerMotionHintMask;
   event_mask = ~PropertyChangeMask;
   event_mask = ~ColormapChangeMask;
   event_mask = ~SubstructureNotifyMask;
 
 
 I added an additional xinput2 registration to only capture the raw motion 
 events which I needed.
 
   XISetMask(eventmask-mask, XI_RawMotion);
   XISelectEvents(xs-dpy, DefaultRootWindow(xs-dpy), eventmask, 1);
 
 This appears to be working fine.  I get raw motion and mouse button press
 and releases when done independently.  However, when I click to drag, I
 only get the button press event but not the raw motion events.  Is this
 expected behavior for the current implementation of libxi?  I need to be
 able to get raw motion events even when the button is pressed.  I don't
 believe anyone else is grabbing the pointer.

If the button press event is delivered somewhere, this activated an implicit
grab in the server and the device is now grabbed by that client that
received the button press event. I suspect this is the cause here too.

Furthermore, XI and XI2 grabs are handled separately, so if you get a XI1
grab, it does not carry the XI2 event mask. Your raw event is thus

RE: Not receiving XI_RawMotion events while mouse button is pressed.

2011-05-11 Thread Roger Cruz

I'm new to X so I haven't mastered all the terms yet.  I just know now that the 
moment a button press event is received (for a click and drag), the raw motion 
events stop coming.  The only way I fixed it is to have both windows/screens 
issue the call to setup the mask to monitor the raw motion events.  I honestly 
don't understand why that works.  Let me try setting up the raw button press 
and not use the old one to see if that avoids the problem.  Thanks for the 
suggestion.

Roger


-Original Message-
From: Peter Hutterer [mailto:peter.hutte...@who-t.net]
Sent: Wed 5/11/2011 7:55 PM
To: Roger Cruz
Cc: xorg-devel@lists.x.org
Subject: Re: Not receiving XI_RawMotion events while mouse button is pressed.
 
On Wed, May 11, 2011 at 01:08:45PM -0500, Roger Cruz wrote:
 Thanks for answering.  I think your suspicion about the implicit pointer
 grab is probably correctly.  Here is what I found out.
 
 The problem only occurred when my application was run on a system with two
 monitors.  Our code creates an X window/screen for each monitor (both
 screens are within the same frame buffer).  When I added the XI raw motion
 code, I only enabled raw motion events for the primary window and not for
 the secondary window.  I had to do this because I was receiving the same
 raw event twice (one for each window).  I used these pointer movements for
 an emulated mouse and having them delivered twice caused unnecessary
 acceleration.
 
 The problem is that another application in our code warps the pointer to
 the secondary screen unbeknownst to me.  This didn't appear to have any
 side effects and I still got the raw motions events until the user
 performed a click and drag operation.  In this case we didn't get the raw
 motion movements from the secondary window anymore.
 
 Based on what you described below, it appears (please correct me if wrong)
 that when the user clicks on the secondary screen, the pointer is
 implicitly grabbed and all the raw motion events are not delivered to the
 root window.  It is my understanding that raw motion events only work with
 the root window so if you look at my code below, when we register for the
 raw motion events, we do so at for the root window.  The root window
 should contain both the X screens mentioned above.
 
 Now, I can't change the code that warps the pointer to the secondary
 screen so I have to be able to fix this problem entirely within my mouse
 code.  I have re-enabled the code so that both X windows call the code
 below to register for raw motion.  This fixes my click and drag problem
 but now I have the problem double events being delivered to my
 application.  Any suggestions on how to prevent that from occurring? 

Raw events are delivered to all root windows, regardless which window the
pointer is on. so you don't need to select on both root windows, the first
one is enough.

I'm not sure how you'd fix the click-and-drag problem though. once you
deliver the ButtonPress event anywhere (unless it's an XI_ButtonPress
event), you lose the ability to receive raw events. at least that's how the
server is currently written, or so I thought.

but tbh, you're mixing window and screen terminologies here so I'm not sure
what your setup is and why the above would work in your case.

 Thanks
 
 Roger R. Cruz
 
 
 static void
 enable_or_disable_xi_rawmotion_events(xstate_t *xs, xi_enable_disable state)
 {
   unsigned char mask[3] = { 0, 0, 0 };

I recommend using XIMaskLen(XI_RawMotion) here for the array length.
though admittedly that was buggy for a while...

   XIEventMask *eventmask;
 
   /*
* This routine is commented out due a bug in X11's XI extension
* which leaves the display lock taken.  It is fixed in version
* 1.3.1 so when we upgrade to that version or newer, we can
* re-enable the code.
* eventmask = XIGetSelectedEvents(xs-dpy, xs-w, num);
*/
 
   eventmask = NULL;
   if (!eventmask) {
   eventmask = (XIEventMask *)xmalloc(sizeof(*eventmask));

xmalloc? that's a server-internal function (that has now been removed). just
using normal calloc will do.

Cheers,
  Peter
 
   eventmask-mask_len = sizeof(mask);
   eventmask-mask = mask;
   }
 
   eventmask-deviceid = XIAllMasterDevices;
 
   if (state == XI_ENABLE_RAWMOTION)
 /* Register for pointer motion events in raw form */
   XISetMask(eventmask-mask, XI_RawMotion);
   else
   /* Unregister for pointer motion events in raw form */
   XIClearMask(eventmask-mask, XI_RawMotion);
 
   XISelectEvents(xs-dpy, DefaultRootWindow(xs-dpy), eventmask, 1);
   free(eventmask);
 }
 
 
 -Original Message-
 From: Peter Hutterer [mailto:peter.hutte...@who-t.net]
 Sent: Tue 5/10/2011 7:13 PM
 To: Roger Cruz
 Cc: xorg-devel@lists.x.org
 Subject: Re: Not receiving XI_RawMotion events while mouse button is pressed.
  
 On Tue, May 10, 2011 at 01

RE: Not receiving XI_RawMotion events while mouse button is pressed.

2011-05-10 Thread Roger Cruz

I have integrated libxi2's capability to provide raw motion pointer values into 
my application which was originally using (and still uses) xinput events.  The 
application currently registers for the old xinput events using XSelectInput.  

XSelectInput(xs-dpy, xs-w, event_mask);

where the event mask is

event_mask = (OwnerGrabButtonMask  1) - 1;/* all events */

event_mask = ~PointerMotionHintMask;
event_mask = ~PropertyChangeMask;
event_mask = ~ColormapChangeMask;
event_mask = ~SubstructureNotifyMask;


I added an additional xinput2 registration to only capture the raw motion 
events which I needed.

XISetMask(eventmask-mask, XI_RawMotion);
XISelectEvents(xs-dpy, DefaultRootWindow(xs-dpy), eventmask, 1);

This appears to be working fine.  I get raw motion and mouse button press and 
releases when done independently.  However, when I click to drag, I only get 
the button press event but not the raw motion events.  Is this expected 
behavior for the current implementation of libxi?  I need to be able to get raw 
motion events even when the button is pressed.  I don't believe anyone else is 
grabbing the pointer.

Thanks
Roger R. Cruz

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel