1/* 2 * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina. 3 * 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation on the rights to use, copy, modify, merge, 10 * publish, distribute, sublicense, and/or sell copies of the Software, 11 * and to permit persons to whom the Software is furnished to do so, 12 * subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial 16 * portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS 22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 * SOFTWARE. 26 */ 27 28/* 29 * Authors: 30 * Rickard E. (Rik) Faith <faith@redhat.com> 31 * 32 */ 33 34/** \file 35 * This file provides functions similar to miPointerGetMotionEvents and 36 * miPointerPutMotionEvents, with the exception that devices with more 37 * than two axes are fully supported. These routines may be used only 38 * for motion buffers for extension devices, and are \a not compatible 39 * replacements for the mi routines. */ 40 41#ifdef HAVE_DMX_CONFIG_H 42#include <dmx-config.h> 43#endif 44 45#include "inputstr.h" 46#include "dmxinputinit.h" 47#include "dmxcommon.h" 48#include "dmxmotion.h" 49 50#define OFFSET(offset,element) ((offset) * (numAxes + 1) + (element)) 51 52/** Return size of motion buffer. \see DMX_MOTION_SIZE */ 53int dmxPointerGetMotionBufferSize(void) 54{ 55 return DMX_MOTION_SIZE; 56} 57 58/** This routine performs the same function as \a miPointerGetMotionEvents: 59 * the events in the motion history that are between the start and stop 60 * times (in mS) are placed in the coords vector, and the count of the 61 * number of items so placed is returned. This routine is called from 62 * dix/devices.c so that coords can hold valuator->numMotionEvents 63 * events. This routine is called from \a Xi/gtmotion.c with coords large 64 * enough to hold the same number of events in a variable-length 65 * extended \a xTimecoord structure. This provides sufficient data for the 66 * \a XGetDeviceMotionEvents library call, and would be identical to 67 * \a miPointerGetMotionEvents for devices with only 2 axes (i.e., core 68 * pointers) if \a xTimecoord used 32bit integers. 69 * 70 * Because DMX uses the mi* routines for all core devices, this routine 71 * only has to support extension devices using the polymorphic coords. 72 * Because compatibility with miPointerGetMotionEvents is not possible, 73 * it is not provided. */ 74int dmxPointerGetMotionEvents(DeviceIntPtr pDevice, 75 xTimecoord *coords, 76 unsigned long start, 77 unsigned long stop, 78 ScreenPtr pScreen) 79{ 80 GETDMXLOCALFROMPDEVICE; 81 int numAxes = pDevice->valuator->numAxes; 82 unsigned long *c = (unsigned long *)coords; 83 int count = 0; 84 int i, j; 85 86 if (!dmxLocal->history) return 0; 87 for (i = dmxLocal->head; i != dmxLocal->tail;) { 88 if (dmxLocal->history[OFFSET(i,0)] >= stop) break; 89 if (dmxLocal->history[OFFSET(i,0)] >= start) { 90 for (j = 0; j < numAxes + 1; j++) 91 c[OFFSET(count,j)] = dmxLocal->history[OFFSET(i,j)]; 92 ++count; 93 } 94 if (++i >= DMX_MOTION_SIZE) i = 0; 95 } 96 return count; 97} 98 99/** This routine adds an event to the motion history. A similar 100 * function is performed by miPointerMove for the mi versions of these 101 * routines. */ 102void dmxPointerPutMotionEvent(DeviceIntPtr pDevice, 103 int firstAxis, int axesCount, int *v, 104 unsigned long time) 105{ 106 GETDMXLOCALFROMPDEVICE; 107 int numAxes = pDevice->valuator->numAxes; 108 int i; 109 110 if (!dmxLocal->history) { 111 dmxLocal->history = malloc(sizeof(*dmxLocal->history) 112 * (numAxes + 1) 113 * DMX_MOTION_SIZE); 114 dmxLocal->head = 0; 115 dmxLocal->tail = 0; 116 dmxLocal->valuators = calloc(sizeof(*dmxLocal->valuators), numAxes); 117 } else { 118 if (++dmxLocal->tail >= DMX_MOTION_SIZE) dmxLocal->tail = 0; 119 if (dmxLocal->head == dmxLocal->tail) 120 if (++dmxLocal->head >= DMX_MOTION_SIZE) dmxLocal->head = 0; 121 } 122 123 dmxLocal->history[OFFSET(dmxLocal->tail,0)] = time; 124 125 /* Initialize the data from the known 126 * values (if Absolute) or to zero (if 127 * Relative) */ 128 for (i = 0; i < numAxes; i++) { 129 if (pDevice->valuator->axes[i].mode == Absolute) 130 dmxLocal->history[OFFSET(dmxLocal->tail,i+1)] 131 = dmxLocal->valuators[i]; 132 else 133 dmxLocal->history[OFFSET(dmxLocal->tail,i+1)] = 0; 134 } 135 136 for (i = firstAxis; i < axesCount; i++) { 137 dmxLocal->history[OFFSET(dmxLocal->tail,i+i)] 138 = (unsigned long)v[i-firstAxis]; 139 dmxLocal->valuators[i] = v[i-firstAxis]; 140 } 141} 142