From: Allan R. <ar...@pa...> - 2012-03-30 20:13:19
|
Hello Folks, I have written a small portable GLUT package that works on Linux, Windows & Mac OS. For the Linux platforms, I am using the Freeglut implementation. I am now working on a capability based on the mouse movement and have found a difference in the behavior between Freeglut & GLUT and an trying to find a work around. Unfortunately, the callback I have for the glutMotionFunc has some time consuming work to do (at least with respect to the mouse movement) and gets behind as more movement events are queued. This results in very slow response, as well as continued processing after the movement has stopped. The same code run with the GLUT package does not exhibit this behavior. It appears that GLUT is throwing out all events received while processing the first one. While I do not get as smooth an effect, I do get much better response to the mouse position. Is there some way to to flush or ignore these extra events while I am responding to the first one? I have tried turning off the glutMontionFunc (setting the callback routine to NULL) while handling the callback, but this does not help. I can think of elaborate ways to do this, but I was hoping of something a bit simpler (preferably a couple of API calls). I am using a few different Linux distros, multiple verions of Red Hat enterprise versions as well as OpenSUSE. The Freeglut versions also run the gambit for an old 2.2 to the current 2.8. All seem to share this behavior. Thanks, Allan |
From: Jason W. <jas...@gm...> - 2012-03-31 01:24:11
|
You should not be doing so much work in an event handler. Keep track of the basic mouse movement and then do your work in a timer or idle callback. To the people who might respond that we should be like GLUT, if this is indeed the original GLUT's behavior, then I disagree. I really do not like the idea of throwing out mouse events. Like at all. On Fri, Mar 30, 2012 at 3:13 PM, Allan Runkle <ar...@pa...> wrote: > Hello Folks, > > I have written a small portable GLUT package that works on Linux, Windows & Mac OS. For the Linux platforms, > I am using the Freeglut implementation. I am now working on a capability based on the mouse movement and > have found a difference in the behavior between Freeglut & GLUT and an trying to find a work around. > > Unfortunately, the callback I have for the glutMotionFunc has some time consuming work to do (at least with respect > to the mouse movement) and gets behind as more movement events are queued. This results in very slow response, > as well as continued processing after the movement has stopped. The same code run with the GLUT package does > not exhibit this behavior. It appears that GLUT is throwing out all events received while processing the first one. > While I do not get as smooth an effect, I do get much better response to the mouse position. > > Is there some way to to flush or ignore these extra events while I am responding to the first one? I have tried turning > off the glutMontionFunc (setting the callback routine to NULL) while handling the callback, but this does not help. > I can think of elaborate ways to do this, but I was hoping of something a bit simpler (preferably a couple of API calls). > > I am using a few different Linux distros, multiple verions of Red Hat enterprise versions as well as OpenSUSE. The > Freeglut versions also run the gambit for an old 2.2 to the current 2.8. All seem to share this behavior. > > Thanks, > Allan > ------------------------------------------------------------------------------ > This SF email is sponsosred by: > Try Windows Azure free for 90 days Click Here > http://p.sf.net/sfu/sfd2d-msazure > _______________________________________________ > Freeglut-developer mailing list > Fre...@li... > https://lists.sourceforge.net/lists/listinfo/freeglut-developer |
From: Allan R. <ar...@pa...> - 2012-03-31 02:50:31
|
Jason, I do not necessarily disagree with you. I do not think that mimicking GLUT should be an absolute goal of Freeglut, but I only mentioned it as a point of comparison. With regard to my issue about capturing motion events, I think there is some room for discussion. While your suggestion would work, I have now decoupled a motion event from the action that results from it. If I have many other events coming in before my timer or idle callback get called, the action caused by the motion event may no longer be appropriate. I found a solution to my problem by modifying the event handler code in Freeglut (only will work on systems I am the SysAdmin for ... not too many these days) in the routine glutMainLoopEvent (freeglut_main.c): case MotionNotify: { /* New code starts here */ if ( XPending( fgDisplay.Display ) > 0) { XEvent nextEvent; XPeekEvent(fgDisplay.Display, &nextEvent); if (nextEvent.type == NotionNotify) break; } /* New code ends here */ GETWINDOW( xmotion ); GETMOUSE( xmotion ); if ( window->ActiveMenu ) Adding the option that John mentioned, "GLUT_DELETE_SUCCESSIVE_MOUSE_MOTION_EVENTS", should be trivial. Thanks for your speedy replies. Allan On Mar 30, 2012, at 18:24, Jason Wilkins wrote: > You should not be doing so much work in an event handler. Keep track > of the basic mouse movement and then do your work in a timer or idle > callback. > > To the people who might respond that we should be like GLUT, if this > is indeed the original GLUT's behavior, then I disagree. I really do > not like the idea of throwing out mouse events. Like at all. > > On Fri, Mar 30, 2012 at 3:13 PM, Allan Runkle <ar...@pa...> wrote: >> Hello Folks, >> >> I have written a small portable GLUT package that works on Linux, Windows & Mac OS. For the Linux platforms, >> I am using the Freeglut implementation. I am now working on a capability based on the mouse movement and >> have found a difference in the behavior between Freeglut & GLUT and an trying to find a work around. >> >> Unfortunately, the callback I have for the glutMotionFunc has some time consuming work to do (at least with respect >> to the mouse movement) and gets behind as more movement events are queued. This results in very slow response, >> as well as continued processing after the movement has stopped. The same code run with the GLUT package does >> not exhibit this behavior. It appears that GLUT is throwing out all events received while processing the first one. >> While I do not get as smooth an effect, I do get much better response to the mouse position. >> >> Is there some way to to flush or ignore these extra events while I am responding to the first one? I have tried turning >> off the glutMontionFunc (setting the callback routine to NULL) while handling the callback, but this does not help. >> I can think of elaborate ways to do this, but I was hoping of something a bit simpler (preferably a couple of API calls). >> >> I am using a few different Linux distros, multiple verions of Red Hat enterprise versions as well as OpenSUSE. The >> Freeglut versions also run the gambit for an old 2.2 to the current 2.8. All seem to share this behavior. >> |
From: John T. <nu...@me...> - 2012-03-31 09:47:18
|
On Fri, Mar 30, 2012 at 07:50:21PM -0700, Allan Runkle wrote: > I found a solution to my problem by modifying the event handler code in Freeglut (only will work on systems > I am the SysAdmin for ... not too many these days) in the routine glutMainLoopEvent (freeglut_main.c): > > case MotionNotify: > { > > /* New code starts here */ > if ( XPending( fgDisplay.Display ) > 0) > { XEvent nextEvent; > XPeekEvent(fgDisplay.Display, &nextEvent); > if (nextEvent.type == NotionNotify) break; > } > /* New code ends here */ There's an Xlib mechanism to do this sort of thing: XEvent xev; while(XCheckIfEvent(fgDisplay.Display, &xev, match_evmotion, 0)); static Bool match_evmotion(Display *dpy, XEvent *xev, XPointer arg) { return xev->type == MotionNotify; } > Adding the option that John mentioned, "GLUT_DELETE_SUCCESSIVE_MOUSE_MOTION_EVENTS", > should be trivial. If you are all in agreement I'll go ahead and do this change. But let's choose a shorter name please :) At the very least let's drop the MOUSE_ part from the name. -- John Tsiombikas http://nuclear.mutantstargoat.com/ |
From: John F. F. <joh...@cy...> - 2012-03-31 02:31:34
|
If there is a serious demand for both ways, it should be possible to add an option "GLUT_DELETE_SUCCESSIVE_MOUSE_MOTION_EVENTS". It would throw out all but the most recent mouse motion event when the event handler is called. - John F. On 3/30/2012 8:24 PM, Jason Wilkins wrote: > You should not be doing so much work in an event handler. Keep track > of the basic mouse movement and then do your work in a timer or idle > callback. > > To the people who might respond that we should be like GLUT, if this > is indeed the original GLUT's behavior, then I disagree. I really do > not like the idea of throwing out mouse events. Like at all. > > On Fri, Mar 30, 2012 at 3:13 PM, Allan Runkle<ar...@pa...> wrote: > >> Hello Folks, >> >> I have written a small portable GLUT package that works on Linux, Windows& Mac OS. For the Linux platforms, >> I am using the Freeglut implementation. I am now working on a capability based on the mouse movement and >> have found a difference in the behavior between Freeglut& GLUT and an trying to find a work around. >> >> Unfortunately, the callback I have for the glutMotionFunc has some time consuming work to do (at least with respect >> to the mouse movement) and gets behind as more movement events are queued. This results in very slow response, >> as well as continued processing after the movement has stopped. The same code run with the GLUT package does >> not exhibit this behavior. It appears that GLUT is throwing out all events received while processing the first one. >> While I do not get as smooth an effect, I do get much better response to the mouse position. >> >> Is there some way to to flush or ignore these extra events while I am responding to the first one? I have tried turning >> off the glutMontionFunc (setting the callback routine to NULL) while handling the callback, but this does not help. >> I can think of elaborate ways to do this, but I was hoping of something a bit simpler (preferably a couple of API calls). >> >> I am using a few different Linux distros, multiple verions of Red Hat enterprise versions as well as OpenSUSE. The >> Freeglut versions also run the gambit for an old 2.2 to the current 2.8. All seem to share this behavior. >> >> Thanks, >> Allan >> ------------------------------------------------------------------------------ >> This SF email is sponsosred by: >> Try Windows Azure free for 90 days Click Here >> http://p.sf.net/sfu/sfd2d-msazure >> _______________________________________________ >> Freeglut-developer mailing list >> Fre...@li... >> https://lists.sourceforge.net/lists/listinfo/freeglut-developer >> > ------------------------------------------------------------------------------ > This SF email is sponsosred by: > Try Windows Azure free for 90 days Click Here > http://p.sf.net/sfu/sfd2d-msazure > _______________________________________________ > Freeglut-developer mailing list > Fre...@li... > https://lists.sourceforge.net/lists/listinfo/freeglut-developer > > |
From: Diederick C. N. <dc...@gm...> - 2012-03-31 02:39:42
|
On Sat, Mar 31, 2012 at 10:31, John F. Fay <joh...@cy...> wrote: > If there is a serious demand for both ways, it should be possible to add > an option "GLUT_DELETE_SUCCESSIVE_MOUSE_MOTION_EVENTS". It would throw > out all but the most recent mouse motion event when the event handler is > called. > If thats easy to implement, it might give some users the flexibility they need. It should be off by default indeed, and in the documentation of the feature it should be noted, as Jason says, don't use it for performance reasons, use a architecture in which the idle or timer callbacks do the heavy processing. Best, Dee |
From: Allan R. <ar...@pa...> - 2012-03-31 10:26:48
|
On Mar 31, 2012, at 02:47, John Tsiombikas wrote: > On Fri, Mar 30, 2012 at 07:50:21PM -0700, Allan Runkle wrote: >> I found a solution to my problem by modifying the event handler code in Freeglut (only will work on systems >> I am the SysAdmin for ... not too many these days) in the routine glutMainLoopEvent (freeglut_main.c): >> >> case MotionNotify: >> { >> >> /* New code starts here */ >> if ( XPending( fgDisplay.Display ) > 0) >> { XEvent nextEvent; >> XPeekEvent(fgDisplay.Display, &nextEvent); >> if (nextEvent.type == NotionNotify) break; >> } >> /* New code ends here */ > > There's an Xlib mechanism to do this sort of thing: > > XEvent xev; > while(XCheckIfEvent(fgDisplay.Display, &xev, match_evmotion, 0)); > > static Bool match_evmotion(Display *dpy, XEvent *xev, XPointer arg) > { > return xev->type == MotionNotify; > } > Not familiar enough with that routine, but a quick read on the routine sounds like you could get and then process events out of order. A future motion event could be processed before an earlier mouse button press or release (as example). I admit, it is or should be a very small window of vulnerability. Also, after re-looking at where I placed my code segment, that is in the wrong place. There is code in the motion event handler that deals with menu actions (haven't used that capability yet, but looking forward to). The code to "skip" motion events should probably be as close to the INVOKE_WCB motion calls as possible. >> Adding the option that John mentioned, "GLUT_DELETE_SUCCESSIVE_MOUSE_MOTION_EVENTS", >> should be trivial. > > If you are all in agreement I'll go ahead and do this change. But let's > choose a shorter name please :) At the very least let's drop the MOUSE_ > part from the name. > How about "GLUT_SKIP_STALE_MOTION_EVENTS". Again, thanks for the quick look into this issue. Allan Runkle |
From: John F. F. <joh...@cy...> - 2012-03-31 12:42:45
|
Sounds very good. - John F. On 3/31/2012 5:26 AM, Allan Runkle wrote: > How about "GLUT_SKIP_STALE_MOTION_EVENTS". > > |
From: John T. <nu...@me...> - 2012-03-31 13:37:03
|
On Sat, Mar 31, 2012 at 03:26:40AM -0700, Allan Runkle wrote: > Also, after re-looking at where I placed my code segment, that is > in the wrong place. There is code in the motion event handler that > deals with menu actions (haven't used that capability yet, but looking > forward to). The code to "skip" motion events should probably be as > close to the INVOKE_WCB motion calls as possible. I don't think that's necessary. If the mouse handler takes too much time the menu handling will be jerky no matter if it handles the first or the last motion event in the queue. > How about "GLUT_SKIP_STALE_MOTION_EVENTS". Done. Please check it and let me know if there are any problems. -- John Tsiombikas http://nuclear.mutantstargoat.com/ |
From: Allan R. <ar...@pa...> - 2012-03-31 21:59:25
|
On Mar 31, 2012, at 06:36, John Tsiombikas wrote: > > Done. Please check it and let me know if there are any problems. > Built and did nominal testing on an OpenSUSE VM. It works well in this environment. It will take a few days to try it on other Linux versions and to see if there is a case that can make it fail. I'll let you folks know how it goes. Thanks Again, Allan Runkle |
From: Allan R. <ar...@pa...> - 2012-04-04 07:22:22
|
On Mar 31, 2012, at 06:36, John Tsiombikas wrote: > > Done. Please check it and let me know if there are any problems. > The "XCheckIfEvent" call works fine until a non-Motion event is placed in the event queue. True to form, all of the motion events are skipped and the last one queued is processed. After that, the non-motion event (which occured before that last motion event) is processed. In my test, while the motion callback was "busy", I released a mouse button while still moving the mouse. When the callback returned and the event queue was processed again, all but the last motion event was skipped (as expected), but the state of the mouse buttons was such that none were enabled. So instead of calling the Motion callback, the Passive one was called. The "XCheckIfEvent" method does not properly track events and changes in the motion state. Granted, I cheated like hell, to make my callback slow enough to generate these conditions, but this scenario is probable. While it could be possible to make this mechanism work, I think don't think it would be a necessarily clean implementation. My original suggestion is not as efficient, but will plod through the queue in order without missing state changes. It can be improved by processing all "stale" motion events within the motion handler instead of returning to the main event loop: if(fgState.SkipStaleMotion) { while ( XPending( fgDisplay.pDisplay.Display ) > 0) { XEvent nextEvent; XPeekEvent(fgDisplay.pDisplay.Display, &nextEvent); if (nextEvent.type == MotionNotify && event.xmotion.state == newEvent.xmotion.state) XNextEvent(fgDisplay.pDisplay.Display, &event); else break; } } I have a feeling the extra check comparing the motion state can be removed since a state change should be captured by a different event which would also cause the loop to terminate. Allan Runkle |