glut_input.c

来自「mesa-6.5-minigui源码」· C语言 代码 · 共 640 行 · 第 1/2 页

C
640
字号
/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. *//* This program is freely distributable without licensing fees   and is provided without guarantee or warrantee expressed or   implied. This program is -not- in the public domain. */#ifdef __VMS#include <GL/vms_x_fix.h>#endif#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#if !defined(_WIN32)#include <X11/Xlib.h>#if defined(__vms)#include <X11/XInput.h>#else#include <X11/extensions/XInput.h>#endif#include <X11/Xutil.h>#else#include <windows.h>#ifndef __CYGWIN32__#include <mmsystem.h>  /* Win32 Multimedia API header. */#endif#endif /* !_WIN32 */#include "glutint.h"int __glutNumDials = 0;int __glutNumSpaceballButtons = 0;int __glutNumButtonBoxButtons = 0;int __glutNumTabletButtons = 0;int __glutNumMouseButtons = 3;  /* Good guess. */XDevice *__glutTablet = NULL;XDevice *__glutDials = NULL;XDevice *__glutSpaceball = NULL;int __glutHasJoystick = 0;int __glutNumJoystickButtons = 0;int __glutNumJoystickAxes = 0;#if !defined(_WIN32)typedef struct _Range {  int min;  int range;} Range;#define NUM_SPACEBALL_AXIS	6#define NUM_TABLET_AXIS		2#define NUM_DIALS_AXIS		8Range __glutSpaceballRange[NUM_SPACEBALL_AXIS];Range __glutTabletRange[NUM_TABLET_AXIS];int *__glutDialsResolution;/* Safely assumes 0 is an illegal event type for X Input   extension events. */int __glutDeviceMotionNotify = 0;int __glutDeviceButtonPress = 0;int __glutDeviceButtonPressGrab = 0;int __glutDeviceButtonRelease = 0;int __glutDeviceStateNotify = 0;static intnormalizeTabletPos(int axis, int rawValue){  assert(rawValue >= __glutTabletRange[axis].min);  assert(rawValue <= __glutTabletRange[axis].min    + __glutTabletRange[axis].range);  /* Normalize rawValue to between 0 and 4000. */  return ((rawValue - __glutTabletRange[axis].min) * 4000) /    __glutTabletRange[axis].range;}static intnormalizeDialAngle(int axis, int rawValue){  /* XXX Assumption made that the resolution of the device is     number of clicks for one complete dial revolution.  This     is true for SGI's dial & button box. */  return (rawValue * 360.0) / __glutDialsResolution[axis];}static intnormalizeSpaceballAngle(int axis, int rawValue){  assert(rawValue >= __glutSpaceballRange[axis].min);  assert(rawValue <= __glutSpaceballRange[axis].min +    __glutSpaceballRange[axis].range);  /* Normalize rawValue to between -1800 and 1800. */  return ((rawValue - __glutSpaceballRange[axis].min) * 3600) /    __glutSpaceballRange[axis].range - 1800;}static intnormalizeSpaceballDelta(int axis, int rawValue){  assert(rawValue >= __glutSpaceballRange[axis].min);  assert(rawValue <= __glutSpaceballRange[axis].min +    __glutSpaceballRange[axis].range);  /* Normalize rawValue to between -1000 and 1000. */  return ((rawValue - __glutSpaceballRange[axis].min) * 2000) /    __glutSpaceballRange[axis].range - 1000;}static voidqueryTabletPos(GLUTwindow * window){  XDeviceState *state;  XInputClass *any;  XValuatorState *v;  int i;  state = XQueryDeviceState(__glutDisplay, __glutTablet);  any = state->data;  for (i = 0; i < state->num_classes; i++) {#if defined(__cplusplus) || defined(c_plusplus)    switch (any->c_class) {#else    switch (any->class) {#endif    case ValuatorClass:      v = (XValuatorState *) any;      if (v->num_valuators < 2)        goto end;      if (window->tabletPos[0] == -1)        window->tabletPos[0] = normalizeTabletPos(0, v->valuators[0]);      if (window->tabletPos[1] == -1)        window->tabletPos[1] = normalizeTabletPos(1, v->valuators[1]);    }    any = (XInputClass *) ((char *) any + any->length);  }end:  XFreeDeviceState(state);}static voidtabletPosChange(GLUTwindow * window, int first, int count, int *data){  int i, value, genEvent = 0;  for (i = first; i < first + count; i++) {    switch (i) {    case 0:            /* X axis */    case 1:            /* Y axis */      value = normalizeTabletPos(i, data[i - first]);      if (value != window->tabletPos[i]) {        window->tabletPos[i] = value;        genEvent = 1;      }      break;    }  }  if (window->tabletPos[0] == -1 || window->tabletPos[1] == -1)    queryTabletPos(window);  if (genEvent)    window->tabletMotion(window->tabletPos[0], window->tabletPos[1]);}#endif /* !_WIN32 */static int__glutProcessDeviceEvents(XEvent * event){#if !defined(_WIN32)  GLUTwindow *window;  /* XXX Ugly code fan out. */  /* Can't use switch/case since X Input event types are     dynamic. */  if (__glutDeviceMotionNotify && event->type == __glutDeviceMotionNotify) {    XDeviceMotionEvent *devmot = (XDeviceMotionEvent *) event;    window = __glutGetWindow(devmot->window);    if (window) {      if (__glutTablet        && devmot->deviceid == __glutTablet->device_id        && window->tabletMotion) {        tabletPosChange(window, devmot->first_axis, devmot->axes_count,          devmot->axis_data);      } else if (__glutDials          && devmot->deviceid == __glutDials->device_id        && window->dials) {        int i, first = devmot->first_axis, count = devmot->axes_count;        for (i = first; i < first + count; i++)          window->dials(i + 1,            normalizeDialAngle(i, devmot->axis_data[i - first]));      } else if (__glutSpaceball        && devmot->deviceid == __glutSpaceball->device_id) {        /* XXX Assume that space ball motion events come in as           all the first 6 axes.  Assume first 3 axes are XYZ           translations; second 3 axes are XYZ rotations. */        if (devmot->first_axis == 0 && devmot->axes_count == 6) {          if (window->spaceMotion)            window->spaceMotion(              normalizeSpaceballDelta(0, devmot->axis_data[0]),              normalizeSpaceballDelta(1, devmot->axis_data[1]),              normalizeSpaceballDelta(2, devmot->axis_data[2]));          if (window->spaceRotate)            window->spaceRotate(              normalizeSpaceballAngle(3, devmot->axis_data[3]),              normalizeSpaceballAngle(4, devmot->axis_data[4]),              normalizeSpaceballAngle(5, devmot->axis_data[5]));        }      }      return 1;    }  } else if (__glutDeviceButtonPress    && event->type == __glutDeviceButtonPress) {    XDeviceButtonEvent *devbtn = (XDeviceButtonEvent *) event;    window = __glutGetWindow(devbtn->window);    if (window) {      if (__glutTablet        && devbtn->deviceid == __glutTablet->device_id        && window->tabletButton        && devbtn->first_axis == 0        && devbtn->axes_count == 2) {        tabletPosChange(window, devbtn->first_axis, devbtn->axes_count,          devbtn->axis_data);        window->tabletButton(devbtn->button, GLUT_DOWN,          window->tabletPos[0], window->tabletPos[1]);      } else if (__glutDials          && devbtn->deviceid == __glutDials->device_id        && window->buttonBox) {        window->buttonBox(devbtn->button, GLUT_DOWN);      } else if (__glutSpaceball          && devbtn->deviceid == __glutSpaceball->device_id        && window->spaceButton) {        window->spaceButton(devbtn->button, GLUT_DOWN);      }      return 1;    }  } else if (__glutDeviceButtonRelease    && event->type == __glutDeviceButtonRelease) {    XDeviceButtonEvent *devbtn = (XDeviceButtonEvent *) event;    window = __glutGetWindow(devbtn->window);    if (window) {      if (__glutTablet        && devbtn->deviceid == __glutTablet->device_id        && window->tabletButton        && devbtn->first_axis == 0        && devbtn->axes_count == 2) {        tabletPosChange(window, devbtn->first_axis, devbtn->axes_count,          devbtn->axis_data);        window->tabletButton(devbtn->button, GLUT_UP,          window->tabletPos[0], window->tabletPos[1]);      } else if (__glutDials          && devbtn->deviceid == __glutDials->device_id        && window->buttonBox) {        window->buttonBox(devbtn->button, GLUT_UP);      } else if (__glutSpaceball          && devbtn->deviceid == __glutSpaceball->device_id        && window->spaceButton) {        window->spaceButton(devbtn->button, GLUT_UP);      }      return 1;    }  }#else  {    JOYINFOEX info;    JOYCAPS joyCaps;    memset(&info, 0, sizeof(JOYINFOEX));     info.dwSize = sizeof(JOYINFOEX);     info.dwFlags = JOY_RETURNALL;    if (joyGetPosEx(JOYSTICKID1,&info) != JOYERR_NOERROR) {      __glutHasJoystick = 1;      joyGetDevCaps(JOYSTICKID1, &joyCaps, sizeof(joyCaps));      __glutNumJoystickButtons = joyCaps.wNumButtons;      __glutNumJoystickAxes = joyCaps.wNumAxes;    } else {      __glutHasJoystick = 0;      __glutNumJoystickButtons = 0;      __glutNumJoystickAxes = 0;    }  }#endif /* !_WIN32 */  return 0;}static GLUTeventParser eventParser ={__glutProcessDeviceEvents, NULL};static voidaddDeviceEventParser(void){  static Bool been_here = False;  if (been_here)    return;  been_here = True;  __glutRegisterEventParser(&eventParser);}static intprobeDevices(void){  static Bool been_here = False;  static int support;#if !defined(_WIN32)  XExtensionVersion *version;  XDeviceInfoPtr device_info, device;  XAnyClassPtr any;  XButtonInfoPtr b;  XValuatorInfoPtr v;  XAxisInfoPtr a;  int num_dev = 0, btns = 0, dials = 0;  int i, j, k;#endif /* !_WIN32 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?