Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

glut_input.c

Go to the documentation of this file.
00001 
00002 /* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */
00003 
00004 /* This program is freely distributable without licensing fees
00005    and is provided without guarantee or warrantee expressed or
00006    implied. This program is -not- in the public domain. */
00007 
00008 #include <assert.h>
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 
00013 #if !defined(_WIN32)
00014 #include <X11/Xlib.h>
00015 #if defined(__vms)
00016 #include <X11/XInput.h>
00017 #else
00018 #include <X11/extensions/XInput.h>
00019 #endif
00020 #include <X11/Xutil.h>
00021 #else
00022 #include <windows.h>
00023 #include <mmsystem.h>  /* Win32 Multimedia API header. */
00024 #endif /* !_WIN32 */
00025 
00026 #include "glutint.h"
00027 #include "wacom.h"
00028 
00029 int __glutNumDials = 0;
00030 int __glutNumSpaceballButtons = 0;
00031 int __glutNumButtonBoxButtons = 0;
00032 int __glutNumTabletButtons = 0;
00033 int __glutNumWacomTabletButtons = 0;
00034 int __glutNumWacomStylusButtons = 0;
00035 int __glutNumWacomEraserButtons = 0;
00036 int __glutNumWacomCursorButtons = 0;
00037 int __glutNumMouseButtons = 3;  /* Good guess. */
00038 XDevice *__glutTablet = NULL;
00039 XDevice *__glutWacomTablet = NULL;
00040 XDevice *__glutWacomStylus = NULL;
00041 XDevice *__glutWacomEraser = NULL;
00042 XDevice *__glutWacomCursor = NULL;
00043 XDevice *__glutDials = NULL;
00044 XDevice *__glutSpaceball = NULL;
00045 
00046 int __glutHasJoystick = 0;
00047 int __glutNumJoystickButtons = 0;
00048 int __glutNumJoystickAxes = 0;
00049 
00050 #if !defined(_WIN32)
00051 typedef struct _Range {
00052   int min;
00053   int range;
00054 } Range;
00055 
00056 typedef enum _WacomEventType {
00057   WACOM_MOTION_EVENT,
00058   WACOM_BUTTON_EVENT
00059 } WacomEventType;
00060 
00061 #define WACOM_NO_STATE_INFO   -1
00062 
00063 typedef enum _WacomProximityType {
00064   WACOM_NO_PROXIMITY_INFO = -1,
00065   WACOM_PROXIMITY_OUT,
00066   WACOM_PROXIMITY_IN
00067 } WacomProximityType;
00068 
00069 #define NUM_SPACEBALL_AXIS 6
00070 #define NUM_TABLET_AXIS    2
00071 #define NUM_WACOM_TABLET_AXIS WACOM_NUM_VALUATORS
00072 #define NUM_WACOM_STYLUS_AXIS WACOM_STYLUS_NUM_VALUATORS
00073 #define NUM_WACOM_ERASER_AXIS WACOM_ERASER_NUM_VALUATORS
00074 #define NUM_WACOM_CURSOR_AXIS WACOM_CURSOR_NUM_VALUATORS
00075 #define NUM_DIALS_AXIS     8
00076 
00077 Range __glutSpaceballRange[NUM_SPACEBALL_AXIS];
00078 Range __glutTabletRange[NUM_TABLET_AXIS];
00079 Range __glutWacomTabletRange[NUM_WACOM_TABLET_AXIS];
00080 Range __glutWacomStylusRange[NUM_WACOM_STYLUS_AXIS];
00081 Range __glutWacomEraserRange[NUM_WACOM_ERASER_AXIS];
00082 Range __glutWacomCursorRange[NUM_WACOM_CURSOR_AXIS];
00083 int *__glutDialsResolution;
00084 
00085 /* Safely assumes 0 is an illegal event type for X Input
00086    extension events. */
00087 int __glutDeviceMotionNotify = 0;
00088 int __glutDeviceButtonPress = 0;
00089 int __glutDeviceButtonPressGrab = 0;
00090 int __glutDeviceButtonRelease = 0;
00091 int __glutDeviceStateNotify = 0;
00092 int __glutProximityIn = 0;
00093 int __glutProximityOut = 0;
00094 
00095 static int
00096 normalizeTabletPos(int axis, int rawValue)
00097 {
00098   assert(rawValue >= __glutTabletRange[axis].min);
00099   assert(rawValue <= __glutTabletRange[axis].min
00100     + __glutTabletRange[axis].range);
00101   /* Normalize rawValue to between 0 and 4000. */
00102   return ((rawValue - __glutTabletRange[axis].min) * 4000) /
00103     __glutTabletRange[axis].range;
00104 }
00105 
00106 static int
00107 normalizeDialAngle(int axis, int rawValue)
00108 {
00109   /* XXX Assumption made that the resolution of the device is
00110      number of clicks for one complete dial revolution.  This
00111      is true for SGI's dial & button box. */
00112   return (rawValue * 360.0) / __glutDialsResolution[axis];
00113 }
00114 
00115 static int
00116 normalizeSpaceballAngle(int axis, int rawValue)
00117 {
00118   assert(rawValue >= __glutSpaceballRange[axis].min);
00119   assert(rawValue <= __glutSpaceballRange[axis].min +
00120     __glutSpaceballRange[axis].range);
00121   /* Normalize rawValue to between -1800 and 1800. */
00122   return ((rawValue - __glutSpaceballRange[axis].min) * 3600) /
00123     __glutSpaceballRange[axis].range - 1800;
00124 }
00125 
00126 static int
00127 normalizeSpaceballDelta(int axis, int rawValue)
00128 {
00129   assert(rawValue >= __glutSpaceballRange[axis].min);
00130   assert(rawValue <= __glutSpaceballRange[axis].min +
00131     __glutSpaceballRange[axis].range);
00132   /* Normalize rawValue to between -1000 and 1000. */
00133   return ((rawValue - __glutSpaceballRange[axis].min) * 2000) /
00134     __glutSpaceballRange[axis].range - 1000;
00135 }
00136 
00137 static void
00138 queryTabletPos(GLUTwindow * window)
00139 {
00140   XDeviceState *state;
00141   XInputClass *any;
00142   XValuatorState *v;
00143   int i;
00144 
00145   state = XQueryDeviceState(__glutDisplay, __glutTablet);
00146   any = state->data;
00147   for (i = 0; i < state->num_classes; i++) {
00148 #if defined(__cplusplus) || defined(c_plusplus)
00149     switch (any->c_class) {
00150 #else
00151     switch (any->class) {
00152 #endif
00153     case ValuatorClass:
00154       v = (XValuatorState *) any;
00155       if (v->num_valuators < 2)
00156         goto end;
00157       if (window->tabletPos[0] == -1)
00158         window->tabletPos[0] = normalizeTabletPos(0, v->valuators[0]);
00159       if (window->tabletPos[1] == -1)
00160         window->tabletPos[1] = normalizeTabletPos(1, v->valuators[1]);
00161     }
00162     any = (XInputClass *) ((char *) any + any->length);
00163   }
00164 end:
00165   XFreeDeviceState(state);
00166 }
00167 
00168 static void
00169 tabletPosChange(GLUTwindow * window, int first, int count, int *data)
00170 {
00171   int i, value, genEvent = 0;
00172 
00173   for (i = first; i < first + count; i++) {
00174     switch (i) {
00175     case 0:            /* X axis */
00176     case 1:            /* Y axis */
00177       value = normalizeTabletPos(i, data[i - first]);
00178       if (value != window->tabletPos[i]) {
00179         window->tabletPos[i] = value;
00180         genEvent = 1;
00181       }
00182       break;
00183     }
00184   }
00185   if (window->tabletPos[0] == -1 || window->tabletPos[1] == -1)
00186     queryTabletPos(window);
00187   if (genEvent)
00188     window->tabletMotion(window->tabletPos[0], window->tabletPos[1]);
00189 }
00190 
00191 static void
00192 wacomTabletChange(GLUTwindow * window, WacomEventType wacomEvent)
00193 {
00194   XDeviceState *state;
00195   XInputClass *any;
00196   XValuatorState *v;
00197   int i;
00198   int transducer, device, button, x, y, pressure, xtilt, ytilt, proximity;
00199   
00200   state = XQueryDeviceState(__glutDisplay, __glutWacomTablet);
00201   any = state->data;
00202   for (i = 0; i < state->num_classes; i++) {
00203 #if defined(__cplusplus) || defined(c_plusplus)
00204     if (any->c_class == ValuatorClass) {
00205 #else
00206     if (any->class == ValuatorClass) {
00207 #endif
00208       v = (XValuatorState *) any;
00209       transducer = v->valuators[WAC_TRANSDUCER_I];
00210       if (transducer & WAC_MENU_ID) {
00211    device = GLUT_WACOM_MENU;
00212    button = WAC_MENU_BUTTONS(v->valuators[WAC_BUTTON_I]);
00213    x = 0;
00214    y = 0;
00215    pressure = 0;
00216    xtilt = 0;
00217    ytilt = 0;
00218    proximity = 1;
00219    /* FIXME: Generate a Keyboard Pressed event! */
00220       } else {
00221    switch (transducer & WAC_TRANSDUCER_MSK) {
00222    case WAC_PUCK_ID:
00223      device = GLUT_WACOM_CURSOR;
00224      button = WAC_PUCK_BUTTONS(v->valuators[WAC_BUTTON_I]);
00225      /* FIXME: No puck button number generated! */
00226      x = v->valuators[WAC_XCOORD_I];
00227      y = v->valuators[WAC_YCOORD_I];
00228      pressure = 0;
00229      xtilt = v->valuators[WAC_ROTATION_I];
00230      xtilt = 5 * WAC_ROTATION_INTG(xtilt) + WAC_ROTATION_FRAC(xtilt);
00231      ytilt = 0;
00232      proximity = (short) v->valuators[WAC_ZCOORD_I];
00233      break;
00234    case WAC_STYLUS_ID:
00235      device = GLUT_WACOM_STYLUS;
00236      button = WAC_STYLUS_BUTTONS(v->valuators[WAC_BUTTON_I]);
00237      x = v->valuators[WAC_XCOORD_I];
00238      y = v->valuators[WAC_YCOORD_I];
00239      pressure = v->valuators[WAC_PRESSURE_I];
00240      xtilt = (short) v->valuators[WAC_XTILT_I];
00241      ytilt = (short) v->valuators[WAC_YTILT_I];
00242      proximity = ((transducer & WAC_TRANSDUCER_PROX_MSK) != 0x0);
00243      break;
00244    case WAC_ERASER_ID:
00245      device = GLUT_WACOM_ERASER;
00246      button = WAC_STYLUS_BUTTONS(v->valuators[WAC_BUTTON_I]);
00247      x = v->valuators[WAC_XCOORD_I];
00248      y = v->valuators[WAC_YCOORD_I];
00249      pressure = v->valuators[WAC_PRESSURE_I];
00250      xtilt = (short) v->valuators[WAC_XTILT_I];
00251      ytilt = (short) v->valuators[WAC_YTILT_I];
00252      proximity = ((transducer & WAC_TRANSDUCER_PROX_MSK) != 0x0);
00253      break;
00254    }
00255       }
00256       switch (wacomEvent) {
00257       case WACOM_MOTION_EVENT:
00258    if (device == GLUT_WACOM_CURSOR) {
00259      __glutWacomUpdate(x, y, 0, 0, 0);
00260      window->wacomMotion(device,
00261                WACOM_NO_STATE_INFO,
00262                __glutWacomX,
00263                __glutWacomY,
00264                pressure,
00265                WAC_CURSOR_ROTATION(xtilt),
00266                ytilt,
00267                proximity);
00268    } else {
00269      __glutWacomUpdate(x, y, pressure, xtilt, ytilt);
00270      window->wacomMotion(device,
00271                WAC_STYLUS_BUTTON_STATE(button),
00272                __glutWacomX,
00273                __glutWacomY,
00274                __glutWacomPressure,
00275                __glutWacomXTilt,
00276                __glutWacomYTilt,
00277                proximity);
00278    }
00279    break;
00280       case WACOM_BUTTON_EVENT:
00281    if (device == GLUT_WACOM_CURSOR) {
00282      __glutWacomSetButton(device, button);
00283      __glutWacomUpdate(x, y, 0, 0, 0);
00284      window->wacomButton(device,
00285                __glutWacomButton,
00286                __glutWacomState,
00287                WACOM_NO_STATE_INFO,
00288                __glutWacomX,
00289                __glutWacomY,
00290                pressure,
00291                WAC_CURSOR_ROTATION(xtilt),
00292                ytilt,
00293                proximity);
00294    } else {
00295      __glutWacomSetButton(device, WAC_STYLUS_BUTTON_ID(button));
00296      __glutWacomUpdate(x, y, pressure, xtilt, ytilt);
00297      window->wacomButton(device,
00298                __glutWacomButton,
00299                __glutWacomState,
00300                WAC_STYLUS_BUTTON_STATE(button),
00301                __glutWacomX,
00302                __glutWacomY,
00303                __glutWacomPressure,
00304                __glutWacomXTilt,
00305                __glutWacomYTilt,
00306                proximity);
00307    }
00308    break;
00309       }
00310       break;
00311     }
00312     any = (XInputClass *) ((char *) any + any->length);
00313   }
00314   XFreeDeviceState(state);
00315 }
00316 
00317 static void
00318 wacomStylusChange(GLUTwindow * window,
00319         WacomEventType wacomEvent, WacomProximityType wacomProximity)
00320 {
00321   XDeviceState *state;
00322   XInputClass *any;
00323   XValuatorState *v;
00324   XButtonState *b;
00325   int i;
00326   int button;
00327   
00328   state = XQueryDeviceState(__glutDisplay, __glutWacomStylus);
00329   any = state->data;
00330   for (i = 0; i < state->num_classes; i++) {
00331 #if defined(__cplusplus) || defined(c_plusplus)
00332     switch (any->c_class) {
00333 #else
00334     switch (any->class) {
00335 #endif
00336     case ButtonClass:
00337       b = (XButtonState *) any;
00338       break;
00339     case ValuatorClass:
00340       v = (XValuatorState *) any;
00341       break;
00342     }
00343     any = (XInputClass *) ((char *) any + any->length);
00344   }
00345   button = b->buttons[0];
00346   switch (wacomEvent) {
00347   case WACOM_MOTION_EVENT:
00348     __glutWacomUpdate(v->valuators[WACOM_XCOORD_I],
00349             v->valuators[WACOM_YCOORD_I],
00350             v->valuators[WACOM_PRESSURE_I],
00351             (short) v->valuators[WACOM_XTILT_I],
00352             (short) v->valuators[WACOM_YTILT_I]);
00353     window->wacomMotion(GLUT_WACOM_STYLUS,
00354          WACOM_STYLUS_BUTTON_STATE(button),
00355          __glutWacomX,
00356          __glutWacomY,
00357          __glutWacomPressure,
00358          __glutWacomXTilt,
00359          __glutWacomYTilt,
00360          WACOM_NO_PROXIMITY_INFO);
00361     break;
00362   case WACOM_BUTTON_EVENT:
00363     __glutWacomSetButton(GLUT_WACOM_STYLUS, WACOM_STYLUS_BUTTON_ID(button));
00364     __glutWacomUpdate(v->valuators[WACOM_XCOORD_I],
00365             v->valuators[WACOM_YCOORD_I],
00366             v->valuators[WACOM_PRESSURE_I],
00367             (short) v->valuators[WACOM_XTILT_I],
00368             (short) v->valuators[WACOM_YTILT_I]);
00369     window->wacomButton(GLUT_WACOM_STYLUS,
00370          __glutWacomButton,
00371          __glutWacomState,
00372          WACOM_STYLUS_BUTTON_STATE(button),
00373               __glutWacomX,
00374          __glutWacomY,
00375          __glutWacomPressure,
00376          __glutWacomXTilt,
00377          __glutWacomYTilt,
00378          wacomProximity);
00379     break;
00380   }
00381   XFreeDeviceState(state);
00382 }
00383 
00384 static void
00385 wacomEraserChange(GLUTwindow * window,
00386         WacomEventType wacomEvent, WacomProximityType wacomProximity)
00387 {
00388   XDeviceState *state;
00389   XInputClass *any;
00390   XValuatorState *v;
00391   XButtonState *b;
00392   int i;
00393   int button;
00394   
00395   state = XQueryDeviceState(__glutDisplay, __glutWacomEraser);
00396   any = state->data;
00397   for (i = 0; i < state->num_classes; i++) {
00398 #if defined(__cplusplus) || defined(c_plusplus)
00399     switch (any->c_class) {
00400 #else
00401     switch (any->class) {
00402 #endif
00403     case ButtonClass:
00404       b = (XButtonState *) any;
00405       break;
00406     case ValuatorClass:
00407       v = (XValuatorState *) any;
00408       break;
00409     }
00410     any = (XInputClass *) ((char *) any + any->length);
00411   }
00412   button = b->buttons[0];
00413   switch (wacomEvent) {
00414   case WACOM_MOTION_EVENT:
00415     __glutWacomUpdate(v->valuators[WACOM_XCOORD_I],
00416             v->valuators[WACOM_YCOORD_I],
00417             v->valuators[WACOM_PRESSURE_I],
00418             (short) v->valuators[WACOM_XTILT_I],
00419             (short) v->valuators[WACOM_YTILT_I]);
00420     window->wacomMotion(GLUT_WACOM_ERASER,
00421          WACOM_STYLUS_BUTTON_STATE(button),
00422          __glutWacomX,
00423          __glutWacomY,
00424          __glutWacomPressure,
00425          __glutWacomXTilt,
00426          __glutWacomYTilt,
00427          WACOM_NO_PROXIMITY_INFO);
00428     break;
00429   case WACOM_BUTTON_EVENT:
00430     __glutWacomSetButton(GLUT_WACOM_ERASER, WACOM_STYLUS_BUTTON_ID(button));
00431     __glutWacomUpdate(v->valuators[WACOM_XCOORD_I],
00432             v->valuators[WACOM_YCOORD_I],
00433             v->valuators[WACOM_PRESSURE_I],
00434             (short) v->valuators[WACOM_XTILT_I],
00435             (short) v->valuators[WACOM_YTILT_I]);
00436     window->wacomButton(GLUT_WACOM_ERASER,
00437          __glutWacomButton,
00438          __glutWacomState,
00439          WACOM_STYLUS_BUTTON_STATE(button),
00440               __glutWacomX,
00441          __glutWacomY,
00442          __glutWacomPressure,
00443          __glutWacomXTilt,
00444          __glutWacomYTilt,
00445          wacomProximity);
00446     break;
00447   }
00448   XFreeDeviceState(state);
00449 }
00450 
00451 static void
00452 wacomCursorChange(GLUTwindow * window, WacomEventType wacomEvent)
00453 {
00454   XDeviceState *state;
00455   XInputClass *any;
00456   XValuatorState *v;
00457   XButtonState *b;
00458   int i;
00459   
00460   state = XQueryDeviceState(__glutDisplay, __glutWacomCursor);
00461   any = state->data;
00462   for (i = 0; i < state->num_classes; i++) {
00463 #if defined(__cplusplus) || defined(c_plusplus)
00464     switch (any->c_class) {
00465 #else
00466     switch (any->class) {
00467 #endif
00468     case ButtonClass:
00469       b = (XButtonState *) any;
00470       break;
00471     case ValuatorClass:
00472       v = (XValuatorState *) any;
00473       break;
00474     }
00475     any = (XInputClass *) ((char *) any + any->length);
00476   }
00477   switch (wacomEvent) {
00478   case WACOM_MOTION_EVENT:
00479     __glutWacomUpdate(v->valuators[WACOM_XCOORD_I],
00480             v->valuators[WACOM_YCOORD_I],
00481             0, 0, 0);
00482     window->wacomMotion(GLUT_WACOM_CURSOR,
00483          WACOM_NO_STATE_INFO,
00484          __glutWacomX,
00485          __glutWacomY,
00486          /* No pressure info */
00487               0.0,
00488          /* 4D mouse rotation */
00489               WACOM_CURSOR_ROTATION((short)
00490                      v->valuators[WACOM_ROTATION_I]),
00491               /* No ytilt info */
00492          0.0,
00493                         /* 4D mouse wheel */
00494               (short) v->valuators[WACOM_WHEEL_I]);
00495     break;
00496   case WACOM_BUTTON_EVENT:
00497     __glutWacomSetButton(GLUT_WACOM_CURSOR, b->buttons[0]);
00498     __glutWacomUpdate(v->valuators[WACOM_XCOORD_I],
00499             v->valuators[WACOM_YCOORD_I],
00500             0, 0, 0);
00501     window->wacomButton(GLUT_WACOM_CURSOR,
00502          __glutWacomButton,
00503          __glutWacomState,
00504          WACOM_NO_STATE_INFO,
00505               __glutWacomX,
00506          __glutWacomY,
00507          /* No pressure info */
00508               0.0,
00509          /* 4D mouse rotation */
00510               WACOM_CURSOR_ROTATION((short)
00511                      v->valuators[WACOM_ROTATION_I]),
00512               /* No ytilt info */
00513          0.0,
00514          /* 4D mouse wheel */
00515               (short) v->valuators[WACOM_WHEEL_I]);
00516     break;
00517   }
00518   XFreeDeviceState(state);
00519 }
00520 #endif /* !_WIN32 */
00521 
00522 int
00523 __glutProcessDeviceEvents(XEvent * event)
00524 {
00525 #if !defined(_WIN32)
00526   GLUTwindow *window;
00527 
00528   /* XXX Ugly code fan out. */
00529 
00530   /* Can't use switch/case since X Input event types are
00531      dynamic. */
00532 
00533   if (__glutDeviceMotionNotify && event->type == __glutDeviceMotionNotify) {
00534     XDeviceMotionEvent *devmot = (XDeviceMotionEvent *) event;
00535 
00536     window = __glutGetWindow(devmot->window);
00537     if (window) {
00538       if (__glutTablet
00539         && devmot->deviceid == __glutTablet->device_id
00540         && window->tabletMotion) {
00541         tabletPosChange(window, devmot->first_axis, devmot->axes_count,
00542           devmot->axis_data);
00543       } else if (__glutWacomTablet
00544        && devmot->deviceid == __glutWacomTablet->device_id
00545        && window->wacomMotion) {
00546    wacomTabletChange(window, WACOM_MOTION_EVENT);
00547       } else if (__glutWacomStylus
00548        && devmot->deviceid == __glutWacomStylus->device_id
00549        && window->wacomMotion) {
00550    wacomStylusChange(window, WACOM_MOTION_EVENT, WACOM_NO_PROXIMITY_INFO);
00551       } else if (__glutWacomEraser
00552        && devmot->deviceid == __glutWacomEraser->device_id
00553        && window->wacomMotion) {
00554    wacomEraserChange(window, WACOM_MOTION_EVENT, WACOM_NO_PROXIMITY_INFO);
00555       } else if (__glutWacomCursor
00556        && devmot->deviceid == __glutWacomCursor->device_id
00557        && window->wacomMotion) {
00558    wacomCursorChange(window, WACOM_MOTION_EVENT);
00559       } else if (__glutDials
00560           && devmot->deviceid == __glutDials->device_id
00561         && window->dials) {
00562         int i, first = devmot->first_axis, count = devmot->axes_count;
00563 
00564         for (i = first; i < first + count; i++)
00565           window->dials(i + 1,
00566             normalizeDialAngle(i, devmot->axis_data[i - first]));
00567       } else if (__glutSpaceball
00568         && devmot->deviceid == __glutSpaceball->device_id) {
00569         /* XXX Assume that space ball motion events come in as
00570            all the first 6 axes.  Assume first 3 axes are XYZ
00571            translations; second 3 axes are XYZ rotations. */
00572         if (devmot->first_axis == 0 && devmot->axes_count == 6) {
00573           if (window->spaceMotion)
00574             window->spaceMotion(
00575               normalizeSpaceballDelta(0, devmot->axis_data[0]),
00576               normalizeSpaceballDelta(1, devmot->axis_data[1]),
00577               normalizeSpaceballDelta(2, devmot->axis_data[2]));
00578           if (window->spaceRotate)
00579             window->spaceRotate(
00580               normalizeSpaceballAngle(3, devmot->axis_data[3]),
00581               normalizeSpaceballAngle(4, devmot->axis_data[4]),
00582               normalizeSpaceballAngle(5, devmot->axis_data[5]));
00583         }
00584       }
00585       return 1;
00586     }
00587   } else if (__glutDeviceButtonPress
00588     && event->type == __glutDeviceButtonPress) {
00589     XDeviceButtonEvent *devbtn = (XDeviceButtonEvent *) event;
00590 
00591     window = __glutGetWindow(devbtn->window);
00592     if (window) {
00593       if (__glutTablet
00594         && devbtn->deviceid == __glutTablet->device_id
00595         && window->tabletButton
00596         && devbtn->first_axis == 0
00597         && devbtn->axes_count == 2) {
00598         tabletPosChange(window, devbtn->first_axis, devbtn->axes_count,
00599           devbtn->axis_data);
00600         window->tabletButton(devbtn->button, GLUT_DOWN,
00601           window->tabletPos[0], window->tabletPos[1]);
00602       } else if (__glutWacomTablet
00603        && devbtn->deviceid == __glutWacomTablet->device_id
00604        && window->wacomButton) {
00605    __glutSetWindow(window);
00606    __glutModifierMask = devbtn->state;
00607    wacomTabletChange(window, WACOM_BUTTON_EVENT);
00608    __glutModifierMask = ~0;
00609       } else if (__glutWacomStylus
00610        && devbtn->deviceid == __glutWacomStylus->device_id
00611        && window->wacomButton) {
00612    __glutSetWindow(window);
00613    __glutModifierMask = devbtn->state;
00614    wacomStylusChange(window, WACOM_BUTTON_EVENT, WACOM_NO_PROXIMITY_INFO);
00615    __glutModifierMask = ~0;
00616       } else if (__glutWacomEraser
00617        && devbtn->deviceid == __glutWacomEraser->device_id
00618        && window->wacomButton) {
00619    __glutSetWindow(window);
00620    __glutModifierMask = devbtn->state;
00621    wacomEraserChange(window, WACOM_BUTTON_EVENT, WACOM_NO_PROXIMITY_INFO);
00622    __glutModifierMask = ~0;
00623       } else if (__glutWacomCursor
00624        && devbtn->deviceid == __glutWacomCursor->device_id
00625        && window->wacomButton) {
00626    __glutSetWindow(window);
00627    __glutModifierMask = devbtn->state;
00628    wacomCursorChange(window, WACOM_BUTTON_EVENT);
00629    __glutModifierMask = ~0;
00630       } else if (__glutDials
00631           && devbtn->deviceid == __glutDials->device_id
00632         && window->buttonBox) {
00633         window->buttonBox(devbtn->button, GLUT_DOWN);
00634       } else if (__glutSpaceball
00635           && devbtn->deviceid == __glutSpaceball->device_id
00636         && window->spaceButton) {
00637         window->spaceButton(devbtn->button, GLUT_DOWN);
00638       }
00639       return 1;
00640     }
00641   } else if (__glutDeviceButtonRelease
00642     && event->type == __glutDeviceButtonRelease) {
00643     XDeviceButtonEvent *devbtn = (XDeviceButtonEvent *) event;
00644 
00645     window = __glutGetWindow(devbtn->window);
00646     if (window) {
00647       if (__glutTablet
00648         && devbtn->deviceid == __glutTablet->device_id
00649         && window->tabletButton
00650         && devbtn->first_axis == 0
00651         && devbtn->axes_count == 2) {
00652         tabletPosChange(window, devbtn->first_axis, devbtn->axes_count,
00653           devbtn->axis_data);
00654         window->tabletButton(devbtn->button, GLUT_UP,
00655           window->tabletPos[0], window->tabletPos[1]);
00656       } else if (__glutWacomTablet
00657        && devbtn->deviceid == __glutWacomTablet->device_id
00658        && window->wacomButton) {
00659    __glutSetWindow(window);
00660    __glutModifierMask = devbtn->state;
00661    wacomTabletChange(window, WACOM_BUTTON_EVENT);
00662    __glutModifierMask = ~0;
00663       } else if (__glutWacomStylus
00664        && devbtn->deviceid == __glutWacomStylus->device_id
00665        && window->wacomButton) {
00666    __glutSetWindow(window);
00667    __glutModifierMask = devbtn->state;
00668    wacomStylusChange(window, WACOM_BUTTON_EVENT, WACOM_NO_PROXIMITY_INFO);
00669    __glutModifierMask = ~0;
00670       } else if (__glutWacomEraser
00671        && devbtn->deviceid == __glutWacomEraser->device_id
00672        && window->wacomButton) {
00673    __glutSetWindow(window);
00674    __glutModifierMask = devbtn->state;
00675    wacomEraserChange(window, WACOM_BUTTON_EVENT, WACOM_NO_PROXIMITY_INFO);
00676    __glutModifierMask = ~0;
00677       } else if (__glutWacomCursor
00678        && devbtn->deviceid == __glutWacomCursor->device_id
00679        && window->wacomButton) {
00680    __glutSetWindow(window);
00681    __glutModifierMask = devbtn->state;
00682    wacomCursorChange(window, WACOM_BUTTON_EVENT);
00683    __glutModifierMask = ~0;
00684       } else if (__glutDials
00685           && devbtn->deviceid == __glutDials->device_id
00686         && window->buttonBox) {
00687         window->buttonBox(devbtn->button, GLUT_UP);
00688       } else if (__glutSpaceball
00689           && devbtn->deviceid == __glutSpaceball->device_id
00690         && window->spaceButton) {
00691         window->spaceButton(devbtn->button, GLUT_UP);
00692       }
00693       return 1;
00694     }
00695   } else if (__glutProximityIn && event->type == __glutProximityIn) {
00696     XProximityNotifyEvent *prxnot = (XProximityNotifyEvent *) event;
00697 
00698     window = __glutGetWindow(prxnot->window);
00699     if (window) {
00700       if (__glutWacomTablet
00701      && prxnot->deviceid == __glutWacomTablet->device_id
00702      && window->wacomButton) {
00703    __glutSetWindow(window);
00704    __glutModifierMask = prxnot->state;
00705    wacomTabletChange(window, WACOM_BUTTON_EVENT);
00706    __glutModifierMask = ~0;
00707       } else if (__glutWacomStylus
00708        && prxnot->deviceid == __glutWacomStylus->device_id
00709        && window->wacomButton) {
00710    __glutSetWindow(window);
00711    __glutModifierMask = prxnot->state;
00712    wacomStylusChange(window, WACOM_BUTTON_EVENT, WACOM_PROXIMITY_IN);
00713    __glutModifierMask = ~0;
00714       } else if (__glutWacomEraser
00715        && prxnot->deviceid == __glutWacomEraser->device_id
00716        && window->wacomButton) {
00717    __glutSetWindow(window);
00718    __glutModifierMask = prxnot->state;
00719    wacomEraserChange(window, WACOM_BUTTON_EVENT, WACOM_PROXIMITY_IN);
00720    __glutModifierMask = ~0;
00721       }
00722       return 1;
00723     }
00724   } else if (__glutProximityOut && event->type == __glutProximityOut) {
00725     XProximityNotifyEvent *prxnot = (XProximityNotifyEvent *) event;
00726 
00727     window = __glutGetWindow(prxnot->window);
00728     if (window) {
00729       if (__glutWacomTablet
00730      && prxnot->deviceid == __glutWacomTablet->device_id
00731      && window->wacomButton) {
00732    __glutSetWindow(window);
00733    __glutModifierMask = prxnot->state;
00734    wacomTabletChange(window, WACOM_BUTTON_EVENT);
00735    __glutModifierMask = ~0;
00736       } else if (__glutWacomStylus
00737        && prxnot->deviceid == __glutWacomStylus->device_id
00738        && window->wacomButton) {
00739    __glutSetWindow(window);
00740    __glutModifierMask = prxnot->state;
00741    wacomStylusChange(window, WACOM_BUTTON_EVENT, WACOM_PROXIMITY_OUT);
00742    __glutModifierMask = ~0;
00743       } else if (__glutWacomEraser
00744        && prxnot->deviceid == __glutWacomEraser->device_id
00745        && window->wacomButton) {
00746    __glutSetWindow(window);
00747    __glutModifierMask = prxnot->state;
00748    wacomEraserChange(window, WACOM_BUTTON_EVENT, WACOM_PROXIMITY_OUT);
00749    __glutModifierMask = ~0;
00750       }
00751       return 1;
00752     }
00753   }
00754 #else
00755   {
00756     JOYINFOEX info;
00757     int njoyId = 0;
00758     int nConnected = 0;
00759     MMRESULT result;
00760 
00761     /* Loop through all possible joystick IDs until we get the error
00762        JOYERR_PARMS. Count the number of times we get JOYERR_NOERROR
00763        indicating an installed joystick driver with a joystick currently
00764        attached to the port. */
00765     while ((result = joyGetPosEx(njoyId++,&info)) != JOYERR_PARMS) {
00766       if (result == JOYERR_NOERROR) {
00767         ++nConnected;  /* The count of connected joysticks. */
00768       }
00769     }
00770   }
00771 #endif /* !_WIN32 */
00772   return 0;
00773 }
00774 
00775 static GLUTeventParser eventParser =
00776 {__glutProcessDeviceEvents, NULL};
00777 
00778 static void
00779 addDeviceEventParser(void)
00780 {
00781   static Bool been_here = False;
00782 
00783   if (been_here)
00784     return;
00785   been_here = True;
00786   __glutRegisterEventParser(&eventParser);
00787 }
00788 
00789 static int
00790 probeDevices(void)
00791 {
00792   static Bool been_here = False;
00793   static int support;
00794 #if !defined(_WIN32)
00795   XExtensionVersion *version;
00796   XDeviceInfoPtr device_info, device;
00797   XAnyClassPtr any;
00798   XButtonInfoPtr b;
00799   XValuatorInfoPtr v;
00800   XAxisInfoPtr a;
00801   int num_dev, btns, dials;
00802   int i, j, k;
00803 #endif /* !_WIN32 */
00804 
00805   if (been_here) {
00806     return support;
00807   }
00808   been_here = True;
00809 
00810 #if !defined(_WIN32)
00811   version = XGetExtensionVersion(__glutDisplay, "XInputExtension");
00812   /* Ugh.  XInput extension API forces annoying cast of a pointer
00813      to a long so it can be compared with the NoSuchExtension
00814      value (#defined to 1). */
00815   if (version == NULL || ((long) version) == NoSuchExtension) {
00816     support = 0;
00817     return support;
00818   }
00819   XFree(version);
00820   device_info = XListInputDevices(__glutDisplay, &num_dev);
00821   if (device_info) {
00822     for (i = 0; i < num_dev; i++) {
00823       /* XXX These are SGI names for these devices;
00824          unfortunately, no good standard exists for standard
00825          types of X input extension devices. */
00826 
00827       device = &device_info[i];
00828       any = (XAnyClassPtr) device->inputclassinfo;
00829 
00830       if (!__glutSpaceball && !strcmp(device->name, "spaceball")) {
00831         v = NULL;
00832         b = NULL;
00833         for (j = 0; j < device->num_classes; j++) {
00834 #if defined(__cplusplus) || defined(c_plusplus)
00835           switch (any->c_class) {
00836 #else
00837           switch (any->class) {
00838 #endif
00839           case ButtonClass:
00840             b = (XButtonInfoPtr) any;
00841             btns = b->num_buttons;
00842             break;
00843           case ValuatorClass:
00844             v = (XValuatorInfoPtr) any;
00845             /* Sanity check: at least 6 valuators? */
00846             if (v->num_axes < NUM_SPACEBALL_AXIS)
00847               goto skip_device;
00848             a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo));
00849             for (k = 0; k < NUM_SPACEBALL_AXIS; k++, a++) {
00850               __glutSpaceballRange[k].min = a->min_value;
00851               __glutSpaceballRange[k].range = a->max_value - a->min_value;
00852             }
00853             break;
00854           }
00855           any = (XAnyClassPtr) ((char *) any + any->length);
00856         }
00857         if (v) {
00858           __glutSpaceball = XOpenDevice(__glutDisplay, device->id);
00859           if (__glutSpaceball) {
00860             __glutNumSpaceballButtons = btns;
00861             addDeviceEventParser();
00862           }
00863         }
00864       } else if (!__glutDials && !strcmp(device->name, "dial+buttons")) {
00865         v = NULL;
00866         b = NULL;
00867         for (j = 0; j < device->num_classes; j++) {
00868 #if defined(__cplusplus) || defined(c_plusplus)
00869           switch (any->c_class) {
00870 #else
00871           switch (any->class) {
00872 #endif
00873           case ButtonClass:
00874             b = (XButtonInfoPtr) any;
00875             btns = b->num_buttons;
00876             break;
00877           case ValuatorClass:
00878             v = (XValuatorInfoPtr) any;
00879             /* Sanity check: at least 8 valuators? */
00880             if (v->num_axes < NUM_DIALS_AXIS)
00881               goto skip_device;
00882             dials = v->num_axes;
00883             __glutDialsResolution = (int *) malloc(sizeof(int) * dials);
00884             a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo));
00885             for (k = 0; k < dials; k++, a++) {
00886               __glutDialsResolution[k] = a->resolution;
00887             }
00888             break;
00889           }
00890           any = (XAnyClassPtr) ((char *) any + any->length);
00891         }
00892         if (v) {
00893           __glutDials = XOpenDevice(__glutDisplay, device->id);
00894           if (__glutDials) {
00895             __glutNumButtonBoxButtons = btns;
00896             __glutNumDials = dials;
00897             addDeviceEventParser();
00898           }
00899         }
00900       } else if (!__glutTablet && !strcmp(device->name, "tablet")) {
00901         v = NULL;
00902         b = NULL;
00903         for (j = 0; j < device->num_classes; j++) {
00904 #if defined(__cplusplus) || defined(c_plusplus)
00905           switch (any->c_class) {
00906 #else
00907           switch (any->class) {
00908 #endif
00909           case ButtonClass:
00910             b = (XButtonInfoPtr) any;
00911             btns = b->num_buttons;
00912             break;
00913           case ValuatorClass:
00914             v = (XValuatorInfoPtr) any;
00915             /* Sanity check: exactly 2 valuators? */
00916             if (v->num_axes != NUM_TABLET_AXIS)
00917               goto skip_device;
00918             a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo));
00919             for (k = 0; k < NUM_TABLET_AXIS; k++, a++) {
00920               __glutTabletRange[k].min = a->min_value;
00921               __glutTabletRange[k].range = a->max_value - a->min_value;
00922             }
00923             break;
00924           }
00925           any = (XAnyClassPtr) ((char *) any + any->length);
00926         }
00927         if (v) {
00928           __glutTablet = XOpenDevice(__glutDisplay, device->id);
00929           if (__glutTablet) {
00930             __glutNumTabletButtons = btns;
00931             addDeviceEventParser();
00932           }
00933         }
00934       } else if (!__glutWacomTablet && !strcmp(device->name, WACOM_NAME)) {
00935         v = NULL;
00936         b = NULL;
00937         for (j = 0; j < device->num_classes; j++) {
00938 #if defined(__cplusplus) || defined(c_plusplus)
00939           switch (any->c_class) {
00940 #else
00941           switch (any->class) {
00942 #endif
00943           case ButtonClass:
00944             b = (XButtonInfoPtr) any;
00945             btns = b->num_buttons;
00946             break;
00947           case ValuatorClass:
00948             v = (XValuatorInfoPtr) any;
00949             /* Sanity check */
00950             if (v->num_axes != NUM_WACOM_TABLET_AXIS)
00951               goto skip_device;
00952             a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo));
00953             for (k = 0; k < NUM_WACOM_TABLET_AXIS; k++, a++) {
00954               __glutWacomTabletRange[k].min = a->min_value;
00955               __glutWacomTabletRange[k].range = a->max_value - a->min_value;
00956             }
00957             break;
00958           }
00959           any = (XAnyClassPtr) ((char *) any + any->length);
00960         }
00961         if (v) {
00962           __glutWacomTablet = XOpenDevice(__glutDisplay, device->id);
00963           if (__glutWacomTablet) {
00964             __glutNumWacomTabletButtons = btns;
00965             addDeviceEventParser();
00966           }
00967         }
00968       } else if (!__glutWacomStylus
00969        && !strcmp(device->name, WACOM_STYLUS_NAME)) {
00970         v = NULL;
00971         b = NULL;
00972         for (j = 0; j < device->num_classes; j++) {
00973 #if defined(__cplusplus) || defined(c_plusplus)
00974           switch (any->c_class) {
00975 #else
00976           switch (any->class) {
00977 #endif
00978           case ButtonClass:
00979             b = (XButtonInfoPtr) any;
00980             btns = b->num_buttons;
00981             break;
00982           case ValuatorClass:
00983             v = (XValuatorInfoPtr) any;
00984             /* Sanity check */
00985             if (v->num_axes != NUM_WACOM_STYLUS_AXIS)
00986               goto skip_device;
00987             a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo));
00988             for (k = 0; k < NUM_WACOM_STYLUS_AXIS; k++, a++) {
00989               __glutWacomStylusRange[k].min = a->min_value;
00990               __glutWacomStylusRange[k].range = a->max_value - a->min_value;
00991             }
00992             break;
00993           }
00994           any = (XAnyClassPtr) ((char *) any + any->length);
00995         }
00996         if (v) {
00997           __glutWacomStylus = XOpenDevice(__glutDisplay, device->id);
00998           if (__glutWacomStylus) {
00999             __glutNumWacomStylusButtons = btns;
01000             addDeviceEventParser();
01001           }
01002         }
01003       } else if (!__glutWacomEraser
01004        && !strcmp(device->name, WACOM_ERASER_NAME)) {
01005         v = NULL;
01006         b = NULL;
01007         for (j = 0; j < device->num_classes; j++) {
01008 #if defined(__cplusplus) || defined(c_plusplus)
01009           switch (any->c_class) {
01010 #else
01011           switch (any->class) {
01012 #endif
01013           case ButtonClass:
01014             b = (XButtonInfoPtr) any;
01015             btns = b->num_buttons;
01016             break;
01017           case ValuatorClass:
01018             v = (XValuatorInfoPtr) any;
01019             /* Sanity check */
01020             if (v->num_axes != NUM_WACOM_ERASER_AXIS)
01021               goto skip_device;
01022             a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo));
01023             for (k = 0; k < NUM_WACOM_ERASER_AXIS; k++, a++) {
01024               __glutWacomEraserRange[k].min = a->min_value;
01025               __glutWacomEraserRange[k].range = a->max_value - a->min_value;
01026             }
01027             break;
01028           }
01029           any = (XAnyClassPtr) ((char *) any + any->length);
01030         }
01031         if (v) {
01032           __glutWacomEraser = XOpenDevice(__glutDisplay, device->id);
01033           if (__glutWacomEraser) {
01034             __glutNumWacomEraserButtons = btns;
01035             addDeviceEventParser();
01036           }
01037         }
01038       } else if (!__glutWacomCursor
01039        && !strcmp(device->name, WACOM_CURSOR_NAME)) {
01040         v = NULL;
01041         b = NULL;
01042         for (j = 0; j < device->num_classes; j++) {
01043 #if defined(__cplusplus) || defined(c_plusplus)
01044           switch (any->c_class) {
01045 #else
01046           switch (any->class) {
01047 #endif
01048           case ButtonClass:
01049             b = (XButtonInfoPtr) any;
01050             btns = b->num_buttons;
01051             break;
01052           case ValuatorClass:
01053             v = (XValuatorInfoPtr) any;
01054             /* Sanity check */
01055             if (v->num_axes != NUM_WACOM_CURSOR_AXIS)
01056               goto skip_device;
01057             a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo));
01058             for (k = 0; k < NUM_WACOM_CURSOR_AXIS; k++, a++) {
01059               __glutWacomCursorRange[k].min = a->min_value;
01060               __glutWacomCursorRange[k].range = a->max_value - a->min_value;
01061             }
01062             break;
01063           }
01064           any = (XAnyClassPtr) ((char *) any + any->length);
01065         }
01066         if (v) {
01067           __glutWacomCursor = XOpenDevice(__glutDisplay, device->id);
01068           if (__glutWacomCursor) {
01069             __glutNumWacomCursorButtons = btns;
01070             addDeviceEventParser();
01071           }
01072         }
01073       } else if (!strcmp(device->name, "mouse")) {
01074         for (j = 0; j < device->num_classes; j++) {
01075 #if defined(__cplusplus) || defined(c_plusplus)
01076           if (any->c_class == ButtonClass) {
01077 #else
01078           if (any->class == ButtonClass) {
01079 #endif
01080             b = (XButtonInfoPtr) any;
01081             __glutNumMouseButtons = b->num_buttons;
01082           }
01083           any = (XAnyClassPtr) ((char *) any + any->length);
01084         }
01085       }
01086     skip_device:;
01087     }
01088     XFreeDeviceList(device_info);
01089   }
01090 #else /* _WIN32 */
01091   __glutNumMouseButtons = GetSystemMetrics(SM_CMOUSEBUTTONS);
01092 #endif /* !_WIN32 */
01093   /* X Input extension might be supported, but only if there is
01094      a tablet, wacom tablet, wacom stylus, wacom eraser, wacom cursor,
01095      dials, or spaceball do we claim devices are supported. */
01096   support = __glutTablet || __glutWacomTablet ||
01097             __glutWacomStylus || __glutWacomEraser || __glutWacomCursor ||
01098             __glutDials || __glutSpaceball;
01099   return support;
01100 }
01101 
01102 void
01103 __glutUpdateInputDeviceMask(GLUTwindow * window)
01104 {
01105 #if !defined(_WIN32)
01106   /* 5 (dial and buttons) +
01107      5 (tablet locator and buttons) +
01108      7 (wacom tablet) +
01109      7 (wacom stylus) +
01110      7 (wacom eraser) +
01111      5 (wacom cursor) +
01112      5 (Spaceball buttons and axis)
01113      = 41
01114   */
01115   XEventClass eventList[41];
01116   int rc, numEvents;
01117 
01118   rc = probeDevices();
01119   if (rc) {
01120     numEvents = 0;
01121     if (__glutTablet) {
01122       if (window->tabletMotion) {
01123         DeviceMotionNotify(__glutTablet, __glutDeviceMotionNotify,
01124           eventList[numEvents]);
01125         numEvents++;
01126       }
01127       if (window->tabletButton) {
01128         DeviceButtonPress(__glutTablet, __glutDeviceButtonPress,
01129           eventList[numEvents]);
01130         numEvents++;
01131         DeviceButtonPressGrab(__glutTablet, __glutDeviceButtonPressGrab,
01132           eventList[numEvents]);
01133         numEvents++;
01134         DeviceButtonRelease(__glutTablet, __glutDeviceButtonRelease,
01135           eventList[numEvents]);
01136         numEvents++;
01137       }
01138       if (window->tabletMotion || window->tabletButton) {
01139         DeviceStateNotify(__glutTablet, __glutDeviceStateNotify,
01140           eventList[numEvents]);
01141         numEvents++;
01142       }
01143     }
01144     if (__glutWacomTablet) {
01145       if (window->wacomMotion) {
01146         DeviceMotionNotify(__glutWacomTablet, __glutDeviceMotionNotify,
01147           eventList[numEvents]);
01148         numEvents++;
01149       }
01150       if (window->wacomButton) {
01151         DeviceButtonPress(__glutWacomTablet, __glutDeviceButtonPress,
01152           eventList[numEvents]);
01153         numEvents++;
01154         DeviceButtonPressGrab(__glutWacomTablet, __glutDeviceButtonPressGrab,
01155           eventList[numEvents]);
01156         numEvents++;
01157         DeviceButtonRelease(__glutWacomTablet, __glutDeviceButtonRelease,
01158           eventList[numEvents]);
01159         numEvents++;
01160    ProximityIn(__glutWacomTablet, __glutProximityIn,
01161      eventList[numEvents]);
01162    numEvents++;
01163    ProximityOut(__glutWacomTablet, __glutProximityOut,
01164      eventList[numEvents]);
01165    numEvents++;
01166       }
01167       if (window->wacomMotion || window->wacomButton) {
01168         DeviceStateNotify(__glutWacomTablet, __glutDeviceStateNotify,
01169           eventList[numEvents]);
01170         numEvents++;
01171       }
01172     }
01173     if (__glutWacomStylus) {
01174       if (window->wacomMotion) {
01175         DeviceMotionNotify(__glutWacomStylus, __glutDeviceMotionNotify,
01176           eventList[numEvents]);
01177         numEvents++;
01178       }
01179       if (window->wacomButton) {
01180         DeviceButtonPress(__glutWacomStylus, __glutDeviceButtonPress,
01181           eventList[numEvents]);
01182         numEvents++;
01183         DeviceButtonPressGrab(__glutWacomStylus, __glutDeviceButtonPressGrab,
01184           eventList[numEvents]);
01185         numEvents++;
01186         DeviceButtonRelease(__glutWacomStylus, __glutDeviceButtonRelease,
01187           eventList[numEvents]);
01188         numEvents++;
01189    ProximityIn(__glutWacomStylus, __glutProximityIn,
01190      eventList[numEvents]);
01191    numEvents++;
01192    ProximityOut(__glutWacomStylus, __glutProximityOut,
01193      eventList[numEvents]);
01194    numEvents++;
01195       }
01196       if (window->wacomMotion || window->wacomButton) {
01197         DeviceStateNotify(__glutWacomStylus, __glutDeviceStateNotify,
01198           eventList[numEvents]);
01199         numEvents++;
01200       }
01201     }
01202     if (__glutWacomEraser) {
01203       if (window->wacomMotion) {
01204         DeviceMotionNotify(__glutWacomEraser, __glutDeviceMotionNotify,
01205           eventList[numEvents]);
01206         numEvents++;
01207       }
01208       if (window->wacomButton) {
01209         DeviceButtonPress(__glutWacomEraser, __glutDeviceButtonPress,
01210           eventList[numEvents]);
01211         numEvents++;
01212         DeviceButtonPressGrab(__glutWacomEraser, __glutDeviceButtonPressGrab,
01213           eventList[numEvents]);
01214         numEvents++;
01215         DeviceButtonRelease(__glutWacomEraser, __glutDeviceButtonRelease,
01216           eventList[numEvents]);
01217         numEvents++;
01218    ProximityIn(__glutWacomEraser, __glutProximityIn,
01219      eventList[numEvents]);
01220    numEvents++;
01221    ProximityOut(__glutWacomEraser, __glutProximityOut,
01222      eventList[numEvents]);
01223    numEvents++;
01224       }
01225       if (window->wacomMotion || window->wacomButton) {
01226         DeviceStateNotify(__glutWacomEraser, __glutDeviceStateNotify,
01227           eventList[numEvents]);
01228         numEvents++;
01229       }
01230     }
01231     if (__glutWacomCursor) {
01232       if (window->wacomMotion) {
01233         DeviceMotionNotify(__glutWacomCursor, __glutDeviceMotionNotify,
01234           eventList[numEvents]);
01235         numEvents++;
01236       }
01237       if (window->wacomButton) {
01238         DeviceButtonPress(__glutWacomCursor, __glutDeviceButtonPress,
01239           eventList[numEvents]);
01240         numEvents++;
01241         DeviceButtonPressGrab(__glutWacomCursor, __glutDeviceButtonPressGrab,
01242           eventList[numEvents]);
01243         numEvents++;
01244         DeviceButtonRelease(__glutWacomCursor, __glutDeviceButtonRelease,
01245           eventList[numEvents]);
01246         numEvents++;
01247       }
01248       if (window->wacomMotion || window->wacomButton) {
01249         DeviceStateNotify(__glutWacomCursor, __glutDeviceStateNotify,
01250           eventList[numEvents]);
01251         numEvents++;
01252       }
01253     }
01254     if (__glutDials) {
01255       if (window->dials) {
01256         DeviceMotionNotify(__glutDials, __glutDeviceMotionNotify,
01257           eventList[numEvents]);
01258         numEvents++;
01259       }
01260       if (window->buttonBox) {
01261         DeviceButtonPress(__glutDials, __glutDeviceButtonPress,
01262           eventList[numEvents]);
01263         numEvents++;
01264         DeviceButtonPressGrab(__glutDials, __glutDeviceButtonPressGrab,
01265           eventList[numEvents]);
01266         numEvents++;
01267         DeviceButtonRelease(__glutDials, __glutDeviceButtonRelease,
01268           eventList[numEvents]);
01269         numEvents++;
01270       }
01271       if (window->dials || window->buttonBox) {
01272         DeviceStateNotify(__glutDials, __glutDeviceStateNotify,
01273           eventList[numEvents]);
01274         numEvents++;
01275       }
01276     }
01277     if (__glutSpaceball) {
01278       if (window->spaceMotion || window->spaceRotate) {
01279         DeviceMotionNotify(__glutSpaceball, __glutDeviceMotionNotify,
01280           eventList[numEvents]);
01281         numEvents++;
01282       }
01283       if (window->spaceButton) {
01284         DeviceButtonPress(__glutSpaceball, __glutDeviceButtonPress,
01285           eventList[numEvents]);
01286         numEvents++;
01287         DeviceButtonPressGrab(__glutSpaceball, __glutDeviceButtonPressGrab,
01288           eventList[numEvents]);
01289         numEvents++;
01290         DeviceButtonRelease(__glutSpaceball, __glutDeviceButtonRelease,
01291           eventList[numEvents]);
01292         numEvents++;
01293       }
01294       if (window->spaceMotion || window->spaceRotate || window->spaceButton) {
01295         DeviceStateNotify(__glutSpaceball, __glutDeviceStateNotify,
01296           eventList[numEvents]);
01297         numEvents++;
01298       }
01299     }
01300 #if 0
01301     if (window->children) {
01302       GLUTwindow *child = window->children;
01303 
01304       do {
01305         XChangeDeviceDontPropagateList(__glutDisplay, child->win,
01306           numEvents, eventList, AddToList);
01307         child = child->siblings;
01308       } while (child);
01309     }
01310 #endif
01311     XSelectExtensionEvent(__glutDisplay, window->win,
01312       eventList, numEvents);
01313     if (window->overlay) {
01314       XSelectExtensionEvent(__glutDisplay, window->overlay->win,
01315         eventList, numEvents);
01316     }
01317   } else {
01318     /* X Input extension not supported; no chance for exotic
01319        input devices. */
01320   }
01321 #endif /* !_WIN32 */
01322 }
01323 
01324 /* CENTRY */
01325 int APIENTRY
01326 glutDeviceGet(GLenum param)
01327 {
01328   probeDevices();
01329   switch (param) {
01330   case GLUT_HAS_KEYBOARD:
01331   case GLUT_HAS_MOUSE:
01332     /* Assume window system always has mouse and keyboard. */
01333     return 1;
01334   case GLUT_HAS_SPACEBALL:
01335     return __glutSpaceball != NULL;
01336   case GLUT_HAS_DIAL_AND_BUTTON_BOX:
01337     return __glutDials != NULL;
01338   case GLUT_HAS_TABLET:
01339     return __glutTablet != NULL;
01340   case GLUT_HAS_WACOM_TABLET:
01341 #if defined(__sgi)
01342     return __glutWacomTablet != NULL;
01343 #elif defined(__linux__)
01344     return __glutWacomStylus != NULL;
01345 #endif
01346   case GLUT_HAS_WACOM_STYLUS:
01347     return __glutWacomStylus != NULL;
01348   case GLUT_HAS_WACOM_ERASER:
01349     return __glutWacomEraser != NULL;
01350   case GLUT_HAS_WACOM_CURSOR:
01351     return __glutWacomCursor != NULL;
01352   case GLUT_NUM_MOUSE_BUTTONS:
01353     return __glutNumMouseButtons;
01354   case GLUT_NUM_SPACEBALL_BUTTONS:
01355     return __glutNumSpaceballButtons;
01356   case GLUT_NUM_BUTTON_BOX_BUTTONS:
01357     return __glutNumButtonBoxButtons;
01358   case GLUT_NUM_DIALS:
01359     return __glutNumDials;
01360   case GLUT_NUM_TABLET_BUTTONS:
01361     return __glutNumTabletButtons;
01362   case GLUT_NUM_WACOM_TABLET_BUTTONS:
01363     return __glutNumWacomTabletButtons;
01364   case GLUT_NUM_WACOM_STYLUS_BUTTONS:
01365     return __glutNumWacomStylusButtons;
01366   case GLUT_NUM_WACOM_ERASER_BUTTONS:
01367     return __glutNumWacomEraserButtons;
01368   case GLUT_NUM_WACOM_CURSOR_BUTTONS:
01369     return __glutNumWacomCursorButtons;
01370   case GLUT_WACOM_TABLET_XCOORD_MIN:
01371     return __glutWacomTabletRange[WAC_XCOORD_I].min;
01372   case GLUT_WACOM_TABLET_XCOORD_RANGE:
01373     return __glutWacomTabletRange[WAC_XCOORD_I].range;
01374   case GLUT_WACOM_TABLET_YCOORD_MIN:
01375     return __glutWacomTabletRange[WAC_YCOORD_I].min;
01376   case GLUT_WACOM_TABLET_YCOORD_RANGE:
01377     return __glutWacomTabletRange[WAC_YCOORD_I].range;
01378   case GLUT_WACOM_TABLET_PRESSURE_MIN:
01379     return __glutWacomTabletRange[WAC_PRESSURE_I].min;
01380   case GLUT_WACOM_TABLET_PRESSURE_RANGE:
01381     return __glutWacomTabletRange[WAC_PRESSURE_I].range;
01382   /* wacom sgi driver gives tilt value varying
01383      between -60 and +60 (not -64 and +63) degrees... */
01384   case GLUT_WACOM_TABLET_XTILT_MIN:
01385     return -60; /*__glutWacomTabletRange[WAC_XTILT_I].min;*/
01386   case GLUT_WACOM_TABLET_XTILT_RANGE:
01387     return 120; /*__glutWacomTabletRange[WAC_XTILT_I].range;*/
01388   case GLUT_WACOM_TABLET_YTILT_MIN:
01389     return -60; /*__glutWacomTabletRange[WAC_YTILT_I].min;*/
01390   case GLUT_WACOM_TABLET_YTILT_RANGE:
01391     return 120; /*__glutWacomTabletRange[WAC_YTILT_I].range;*/
01392   case GLUT_WACOM_STYLUS_XCOORD_MIN:
01393     return __glutWacomStylusRange[WACOM_XCOORD_I].min;
01394   case GLUT_WACOM_STYLUS_XCOORD_RANGE:
01395     return __glutWacomStylusRange[WACOM_XCOORD_I].range;
01396   case GLUT_WACOM_STYLUS_YCOORD_MIN:
01397     return __glutWacomStylusRange[WACOM_YCOORD_I].min;
01398   case GLUT_WACOM_STYLUS_YCOORD_RANGE:
01399     return __glutWacomStylusRange[WACOM_YCOORD_I].range;
01400   case GLUT_WACOM_STYLUS_PRESSURE_MIN:
01401     return __glutWacomStylusRange[WACOM_PRESSURE_I].min;
01402   case GLUT_WACOM_STYLUS_PRESSURE_RANGE:
01403     return __glutWacomStylusRange[WACOM_PRESSURE_I].range;
01404   case GLUT_WACOM_STYLUS_XTILT_MIN:
01405     return __glutWacomStylusRange[WACOM_XTILT_I].min;
01406   case GLUT_WACOM_STYLUS_XTILT_RANGE:
01407     return __glutWacomStylusRange[WACOM_XTILT_I].range;
01408   case GLUT_WACOM_STYLUS_YTILT_MIN:
01409     return __glutWacomStylusRange[WACOM_YTILT_I].min;
01410   case GLUT_WACOM_STYLUS_YTILT_RANGE:
01411     return __glutWacomStylusRange[WACOM_YTILT_I].range;
01412   case GLUT_WACOM_ERASER_XCOORD_MIN:
01413     return __glutWacomEraserRange[WACOM_XCOORD_I].min;
01414   case GLUT_WACOM_ERASER_XCOORD_RANGE:
01415     return __glutWacomEraserRange[WACOM_XCOORD_I].range;
01416   case GLUT_WACOM_ERASER_YCOORD_MIN:
01417     return __glutWacomEraserRange[WACOM_YCOORD_I].min;
01418   case GLUT_WACOM_ERASER_YCOORD_RANGE:
01419     return __glutWacomEraserRange[WACOM_YCOORD_I].range;
01420   case GLUT_WACOM_ERASER_PRESSURE_MIN:
01421     return __glutWacomEraserRange[WACOM_PRESSURE_I].min;
01422   case GLUT_WACOM_ERASER_PRESSURE_RANGE:
01423     return __glutWacomEraserRange[WACOM_PRESSURE_I].range;
01424   case GLUT_WACOM_ERASER_XTILT_MIN:
01425     return __glutWacomEraserRange[WACOM_XTILT_I].min;
01426   case GLUT_WACOM_ERASER_XTILT_RANGE:
01427     return __glutWacomEraserRange[WACOM_XTILT_I].range;
01428   case GLUT_WACOM_ERASER_YTILT_MIN:
01429     return __glutWacomEraserRange[WACOM_YTILT_I].min;
01430   case GLUT_WACOM_ERASER_YTILT_RANGE:
01431     return __glutWacomEraserRange[WACOM_YTILT_I].range;
01432   case GLUT_WACOM_CURSOR_XCOORD_MIN:
01433     return __glutWacomCursorRange[WACOM_XCOORD_I].min;
01434   case GLUT_WACOM_CURSOR_XCOORD_RANGE:
01435     return __glutWacomCursorRange[WACOM_XCOORD_I].range;
01436   case GLUT_WACOM_CURSOR_YCOORD_MIN:
01437     return __glutWacomCursorRange[WACOM_YCOORD_I].min;
01438   case GLUT_WACOM_CURSOR_YCOORD_RANGE:
01439     return __glutWacomCursorRange[WACOM_YCOORD_I].range;
01440   case GLUT_WACOM_CURSOR_PRESSURE_MIN:
01441     return __glutWacomCursorRange[WACOM_PRESSURE_I].min;
01442   case GLUT_WACOM_CURSOR_PRESSURE_RANGE:
01443     return __glutWacomCursorRange[WACOM_PRESSURE_I].range;
01444   case GLUT_WACOM_CURSOR_XTILT_MIN:
01445     return __glutWacomCursorRange[WACOM_XTILT_I].min;
01446   case GLUT_WACOM_CURSOR_XTILT_RANGE:
01447     return __glutWacomCursorRange[WACOM_XTILT_I].range;
01448   case GLUT_WACOM_CURSOR_YTILT_MIN:
01449     return __glutWacomCursorRange[WACOM_YTILT_I].min;
01450   case GLUT_WACOM_CURSOR_YTILT_RANGE:
01451     return __glutWacomCursorRange[WACOM_YTILT_I].range;
01452   case GLUT_DEVICE_IGNORE_KEY_REPEAT:
01453     return __glutCurrentWindow->ignoreKeyRepeat;
01454 #ifndef _WIN32
01455   case GLUT_DEVICE_KEY_REPEAT:
01456     {
01457       XKeyboardState state;
01458 
01459       XGetKeyboardControl(__glutDisplay, &state);
01460       return state.global_auto_repeat;
01461     }
01462   case GLUT_JOYSTICK_POLL_RATE:
01463     return 0;
01464 #else
01465   case GLUT_DEVICE_KEY_REPEAT:
01466     /* Win32 cannot globally disable key repeat. */
01467     return GLUT_KEY_REPEAT_ON;
01468   case GLUT_JOYSTICK_POLL_RATE:
01469     return __glutCurrentWindow->joyPollInterval;
01470 #endif
01471   case GLUT_HAS_JOYSTICK:
01472     return __glutHasJoystick;
01473   case GLUT_JOYSTICK_BUTTONS:
01474     return __glutNumJoystickButtons;
01475   case GLUT_JOYSTICK_AXES:
01476     return __glutNumJoystickAxes;
01477   default:
01478     __glutWarning("invalid glutDeviceGet parameter: %d", param);
01479     return -1;
01480   }
01481 }
01482 /* ENDCENTRY */

Generated on Mon Sep 18 11:39:31 2006 for jot by  doxygen 1.4.4