--- xf86Wacom.c.ots Sun Aug 16 13:46:51 1998 +++ xf86Wacom.c Sun Aug 16 15:28:01 1998 @@ -239,13 +239,13 @@ #define HEADER_BIT 0x80 #define ZAXIS_SIGN_BIT 0x40 #define ZAXIS_BIT 0x04 -#define ZAXIS_BITS 0x7f +#define ZAXIS_BITS 0x3f #define POINTER_BIT 0x20 #define PROXIMITY_BIT 0x40 #define BUTTON_FLAG 0x08 #define BUTTONS_BITS 0x78 #define TILT_SIGN_BIT 0x40 -#define TILT_BITS 0x7f +#define TILT_BITS 0x3f /* defines to discriminate second side button and the eraser */ #define ERASER_PROX 4 @@ -717,6 +717,33 @@ } static void +xf86WcmSendButtons(LocalDevicePtr local, + int buttons, + int rx, + int ry, + int rz, + int rtx, + int rty) + +{ + int button; + WacomDevicePtr priv = (WacomDevicePtr) local->private; + + for (button=1; button<16; button++) { + int mask = 1 << (button-1); + + if ((mask & priv->oldButtons) != (mask & buttons)) { + DBG(4, ErrorF("xf86WcmReadInput button=%d state=%d\n", + button, (buttons & mask) != 0)); + xf86PostButtonEvent(local->dev, + (priv->flags & ABSOLUTE_FLAG), + button, (buttons & mask) != 0, + 0, 5, rx, ry, rz, rtx, rty); + } + } +} + +static void xf86WcmSendEvents(LocalDevicePtr local, int is_stylus, int is_button, @@ -731,6 +758,7 @@ int tx = 0, ty = 0; int rx, ry, rz, rtx, rty; int is_core_pointer, is_absolute; + int curDevice; DBG(7, ErrorF("[%s] prox=%s\tx=%d\ty=%d\tz=%d\tbutton=%s\tbuttons=%d\n", is_stylus ? "stylus" : "cursor", @@ -775,41 +803,55 @@ tx = (common->wcmData[7] & TILT_BITS); ty = (common->wcmData[8] & TILT_BITS); if (common->wcmData[7] & TILT_SIGN_BIT) - tx = - (~(tx-1) & 0x7f); + tx -= (TILT_BITS + 1); if (common->wcmData[8] & TILT_SIGN_BIT) - ty = - (~(ty-1) & 0x7f); + ty -= (TILT_BITS + 1); } - + /* * The eraser is reported as button 4 and 5 of the stylus. * if we haven't an independent device for the eraser * report the button as button 3 of the stylus. */ - if ((buttons > 3) && common->wcmHasEraser && - ((is_proximity && !priv->oldProximity && - (buttons == 4 || buttons == 5)) || - (priv->oldProximity == ERASER_PROX))) { - if (DEVICE_ID(priv->flags) != ERASER_ID) - return; - DBG(10, ErrorF("Eraser\n")); + if (is_proximity) { + if ((buttons & 4) && common->wcmHasEraser && + ((!priv->oldProximity || + (priv->oldProximity == ERASER_PROX)))) { + curDevice = ERASER_ID; + } else { + curDevice = STYLUS_ID; + } + } else { /* * When we are out of proximity with the eraser the * button 4 isn't reported so we must check the * previous proximity device. */ - if (common->wcmHasEraser && !is_proximity && - (priv->oldProximity == ERASER_PROX)) { - if (DEVICE_ID(priv->flags) != ERASER_ID) - return; - DBG(10, ErrorF("Eraser\n")); - } - else { - if (DEVICE_ID(priv->flags) != STYLUS_ID) - return; - DBG(10, ErrorF("Stylus\n")); + if (common->wcmHasEraser && (priv->oldProximity == ERASER_PROX)) { + curDevice = ERASER_ID; + } else { + curDevice = STYLUS_ID; } } + + /* We check here to see if we changed between eraser and stylus + * without leaving proximity. The most likely cause is that + * we were fooled by the second side switch into thinking the + * stylus was the eraser. If this happens, we send + * a proximity-out for the old device. + */ + if (curDevice != DEVICE_ID(priv->flags)) { + if (priv->oldProximity) { + buttons = 0; + is_proximity = 0; + } else + return; + } + + DBG(10, ErrorF((DEVICE_ID(priv->flags) == ERASER_ID) ? + "Eraser\n" : + "Stylus\n")); } else { if (DEVICE_ID(priv->flags) != CURSOR_ID) @@ -872,14 +914,19 @@ * we have the eraser else we have the second side * switch. */ - if (is_stylus && buttons > 3) { - if (buttons == 4) { - buttons = (priv->oldProximity == ERASER_PROX) ? 0 : 4; - } - else { - if (priv->oldProximity == ERASER_PROX && buttons == 5) - buttons = ((DEVICE_ID(priv->flags) == ERASER_ID) ? 1 : 3); + if (is_stylus) { + if (buttons & 4) { + if (priv->oldProximity == ERASER_PROX) { + buttons &= ~4; + } } + } else { + /* If the button flag is pressed, but the switch state + * is zero, this means that cursor button 16 was pressed */ + if (buttons = 0) + buttons = 16; + /* Turn button index reported for cursor into a bit mask. */ + buttons = 1 << (buttons - 1); } DBG(4, ErrorF("xf86WcmReadInput %s rx=%d ry=%d rz=%d priv->oldButtons=%d\n", @@ -899,17 +946,7 @@ } } if (priv->oldButtons != buttons) { - int delta; - int button; - - delta = buttons - priv->oldButtons; - button = (delta > 0) ? delta : -delta; - - DBG(4, ErrorF("xf86WcmReadInput button=%d delta=%d\n", button, - delta)); - - xf86PostButtonEvent(local->dev, is_absolute, button, (delta > 0), - 0, 5, rx, ry, rz, rtx, rty); + xf86WcmSendButtons (local, buttons, rx, ry, rz, rtx, rty); } priv->oldButtons = buttons; priv->oldX = x; @@ -921,9 +958,7 @@ else { /* !PROXIMITY */ /* reports button up when the device has been down and becomes out of proximity */ if (priv->oldButtons) { - xf86PostButtonEvent(local->dev, is_absolute, priv->oldButtons, 0, 0, 5, - rx, ry, rz, rtx, rty); - priv->oldButtons = 0; + xf86WcmSendButtons (local, 0, rx, ry, rz, rtx, rty); } if (!is_core_pointer) { /* macro button management */ @@ -1082,7 +1117,7 @@ z = ((common->wcmData[6] & ZAXIS_BITS) * 2) + ((common->wcmData[3] & ZAXIS_BIT) >> 2); if (common->wcmData[6] & ZAXIS_SIGN_BIT) - z = - (~(z-1) & 0x7f); + z -= 0x80; is_button = (common->wcmData[0] & BUTTON_FLAG); is_proximity = (common->wcmData[0] & PROXIMITY_BIT); @@ -1581,8 +1616,9 @@ nbaxes, xf86GetMotionEvents, local->history_size, - (priv->flags & ABSOLUTE_FLAG) - ? Absolute : Relative) + ((priv->flags & ABSOLUTE_FLAG) + ? Absolute : Relative) | + OutOfProximity) == FALSE) { ErrorF("unable to allocate Valuator class device\n"); return !Success;