Fixed mousewheel callbacks under X11. (bug #247, github issue #66)

The code had the incorrect assumption that button numbers mapped to the wheel
follow after the last "real" button as returned by the GLUT_NUM_MOUSE_BUTTONS
query, which in turn resolves to a call to XGetPointerMapping. In reality the
X server always sends button presses for 4 and 5 when a wheel is turned down/up
respectively, and the rest of the mouse buttons (if any) follow afterwards.
Also XGetPointerMapping doesn't seem to reliably return the number of actual
buttons, and in any case the wheel "buttons" are certainly included in the
count as they can be remapped.
Since we can't know if buttons after 5 are further wheels or regular buttons
this modification only ever invokes the wheel callback for wheel 0.


git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1844 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
jtsiomb 2018-10-10 05:23:33 +00:00
parent 29313e5313
commit 4a4f400ca7

View File

@ -807,11 +807,8 @@ void fgPlatformProcessSingleEvent ( void )
case ButtonRelease: case ButtonRelease:
case ButtonPress: case ButtonPress:
{ {
GLboolean pressed = GL_TRUE; GLboolean pressed;
int button; int button, x, y;
if( event.type == ButtonRelease )
pressed = GL_FALSE ;
/* /*
* A mouse button has been pressed or released. Traditionally, * A mouse button has been pressed or released. Traditionally,
@ -829,59 +826,46 @@ void fgPlatformProcessSingleEvent ( void )
*/ */
button = event.xbutton.button - 1; button = event.xbutton.button - 1;
pressed = event.type == ButtonPress ? GL_TRUE : GL_FALSE;
x = event.xbutton.x;
y = event.xbutton.y;
/* /*
* Do not execute the application's mouse callback if a menu * Do not execute the application's mouse callback if a menu
* is hooked to this button. In that case an appropriate * is hooked to this button. In that case an appropriate
* private call should be generated. * private call should be generated.
*/ */
if( fgCheckActiveMenu( window, button, pressed, if(fgCheckActiveMenu( window, button, pressed, x, y))
event.xbutton.x, event.xbutton.y ) )
break; break;
/* /*
* Check if there is a mouse or mouse wheel callback hooked to the * Check if there is a mouse or mouse wheel callback hooked to the
* window * window
*/ */
if( ! FETCH_WCB( *window, Mouse ) && if(!FETCH_WCB(*window, Mouse) && !FETCH_WCB(*window, MouseWheel))
! FETCH_WCB( *window, MouseWheel ) )
break; break;
fgState.Modifiers = fgPlatformGetModifiers( event.xbutton.state ); fgState.Modifiers = fgPlatformGetModifiers(event.xbutton.state);
/* Finally execute the mouse or mouse wheel callback */ /* Finally execute the mouse or mouse wheel callback.
if( ( button < glutDeviceGet ( GLUT_NUM_MOUSE_BUTTONS ) ) || ( ! FETCH_WCB( *window, MouseWheel ) ) ) * The mouse wheel is reported as buttons 4 (down) and 5 (up) by
INVOKE_WCB( *window, Mouse, ( button, * the X server. "button" has been converted to 0-based above, so
pressed ? GLUT_DOWN : GLUT_UP, * that's 3 and 4 for us.
event.xbutton.x, * If a wheel callback hasn't been registered, we simply treat them
event.xbutton.y ) * as button presses and pass them to the mouse handler. This is
); * important for compatibility with the original GLUT.
else
{
/*
* Map 4 and 5 to wheel zero; EVEN to +1, ODD to -1
* " 6 and 7 " " one; ...
*
* XXX This *should* be behind some variables/macros,
* XXX since the order and numbering isn't certain
* XXX See XFree86 configuration docs (even back in the
* XXX 3.x days, and especially with 4.x).
*
* XXX Note that {button} has already been decremented
* XXX in mapping from X button numbering to GLUT.
*
* XXX Should add support for partial wheel turns as Windows does -- 5/27/11
*/ */
int wheel_number = (button - glutDeviceGet ( GLUT_NUM_MOUSE_BUTTONS )) / 2; if(button < 3 || button > 4 || !FETCH_WCB(*window, MouseWheel)) {
int direction = -1; INVOKE_WCB(*window, Mouse, (button, pressed ? GLUT_DOWN : GLUT_UP, x, y));
if( button % 2 ) } else {
direction = 1; if(pressed) {
int dir = button & 1 ? 1 : -1;
if( pressed ) /* there's no way to know if X buttons after 5 are more
INVOKE_WCB( *window, MouseWheel, ( wheel_number, * wheels/wheel axes, or regular buttons. So we'll only
direction, * ever invoke the wheel CB for wheel 0.
event.xbutton.x, */
event.xbutton.y ) INVOKE_WCB(*window, MouseWheel, (0, dir, x, y));
); }
} }
fgState.Modifiers = INVALID_MODIFIERS; fgState.Modifiers = INVALID_MODIFIERS;
} }