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 + -
显示快捷键?