1706f2543Smrg/* 2706f2543Smrg * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina. 3706f2543Smrg * 4706f2543Smrg * All Rights Reserved. 5706f2543Smrg * 6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining 7706f2543Smrg * a copy of this software and associated documentation files (the 8706f2543Smrg * "Software"), to deal in the Software without restriction, including 9706f2543Smrg * without limitation on the rights to use, copy, modify, merge, 10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software, 11706f2543Smrg * and to permit persons to whom the Software is furnished to do so, 12706f2543Smrg * subject to the following conditions: 13706f2543Smrg * 14706f2543Smrg * The above copyright notice and this permission notice (including the 15706f2543Smrg * next paragraph) shall be included in all copies or substantial 16706f2543Smrg * portions of the Software. 17706f2543Smrg * 18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21706f2543Smrg * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS 22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25706f2543Smrg * SOFTWARE. 26706f2543Smrg */ 27706f2543Smrg 28706f2543Smrg/* 29706f2543Smrg * Authors: 30706f2543Smrg * Rickard E. (Rik) Faith <faith@redhat.com> 31706f2543Smrg * 32706f2543Smrg */ 33706f2543Smrg 34706f2543Smrg/** \file 35706f2543Smrg * This file provides functions similar to miPointerGetMotionEvents and 36706f2543Smrg * miPointerPutMotionEvents, with the exception that devices with more 37706f2543Smrg * than two axes are fully supported. These routines may be used only 38706f2543Smrg * for motion buffers for extension devices, and are \a not compatible 39706f2543Smrg * replacements for the mi routines. */ 40706f2543Smrg 41706f2543Smrg#ifdef HAVE_DMX_CONFIG_H 42706f2543Smrg#include <dmx-config.h> 43706f2543Smrg#endif 44706f2543Smrg 45706f2543Smrg#include "inputstr.h" 46706f2543Smrg#include "dmxinputinit.h" 47706f2543Smrg#include "dmxcommon.h" 48706f2543Smrg#include "dmxmotion.h" 49706f2543Smrg 50706f2543Smrg#define OFFSET(offset,element) ((offset) * (numAxes + 1) + (element)) 51706f2543Smrg 52706f2543Smrg/** Return size of motion buffer. \see DMX_MOTION_SIZE */ 53706f2543Smrgint dmxPointerGetMotionBufferSize(void) 54706f2543Smrg{ 55706f2543Smrg return DMX_MOTION_SIZE; 56706f2543Smrg} 57706f2543Smrg 58706f2543Smrg/** This routine performs the same function as \a miPointerGetMotionEvents: 59706f2543Smrg * the events in the motion history that are between the start and stop 60706f2543Smrg * times (in mS) are placed in the coords vector, and the count of the 61706f2543Smrg * number of items so placed is returned. This routine is called from 62706f2543Smrg * dix/devices.c so that coords can hold valuator->numMotionEvents 63706f2543Smrg * events. This routine is called from \a Xi/gtmotion.c with coords large 64706f2543Smrg * enough to hold the same number of events in a variable-length 65706f2543Smrg * extended \a xTimecoord structure. This provides sufficient data for the 66706f2543Smrg * \a XGetDeviceMotionEvents library call, and would be identical to 67706f2543Smrg * \a miPointerGetMotionEvents for devices with only 2 axes (i.e., core 68706f2543Smrg * pointers) if \a xTimecoord used 32bit integers. 69706f2543Smrg * 70706f2543Smrg * Because DMX uses the mi* routines for all core devices, this routine 71706f2543Smrg * only has to support extension devices using the polymorphic coords. 72706f2543Smrg * Because compatibility with miPointerGetMotionEvents is not possible, 73706f2543Smrg * it is not provided. */ 74706f2543Smrgint dmxPointerGetMotionEvents(DeviceIntPtr pDevice, 75706f2543Smrg xTimecoord *coords, 76706f2543Smrg unsigned long start, 77706f2543Smrg unsigned long stop, 78706f2543Smrg ScreenPtr pScreen) 79706f2543Smrg{ 80706f2543Smrg GETDMXLOCALFROMPDEVICE; 81706f2543Smrg int numAxes = pDevice->valuator->numAxes; 82706f2543Smrg unsigned long *c = (unsigned long *)coords; 83706f2543Smrg int count = 0; 84706f2543Smrg int i, j; 85706f2543Smrg 86706f2543Smrg if (!dmxLocal->history) return 0; 87706f2543Smrg for (i = dmxLocal->head; i != dmxLocal->tail;) { 88706f2543Smrg if (dmxLocal->history[OFFSET(i,0)] >= stop) break; 89706f2543Smrg if (dmxLocal->history[OFFSET(i,0)] >= start) { 90706f2543Smrg for (j = 0; j < numAxes + 1; j++) 91706f2543Smrg c[OFFSET(count,j)] = dmxLocal->history[OFFSET(i,j)]; 92706f2543Smrg ++count; 93706f2543Smrg } 94706f2543Smrg if (++i >= DMX_MOTION_SIZE) i = 0; 95706f2543Smrg } 96706f2543Smrg return count; 97706f2543Smrg} 98706f2543Smrg 99706f2543Smrg/** This routine adds an event to the motion history. A similar 100706f2543Smrg * function is performed by miPointerMove for the mi versions of these 101706f2543Smrg * routines. */ 102706f2543Smrgvoid dmxPointerPutMotionEvent(DeviceIntPtr pDevice, 103706f2543Smrg int firstAxis, int axesCount, int *v, 104706f2543Smrg unsigned long time) 105706f2543Smrg{ 106706f2543Smrg GETDMXLOCALFROMPDEVICE; 107706f2543Smrg int numAxes = pDevice->valuator->numAxes; 108706f2543Smrg int i; 109706f2543Smrg 110706f2543Smrg if (!dmxLocal->history) { 111706f2543Smrg dmxLocal->history = malloc(sizeof(*dmxLocal->history) 112706f2543Smrg * (numAxes + 1) 113706f2543Smrg * DMX_MOTION_SIZE); 114706f2543Smrg dmxLocal->head = 0; 115706f2543Smrg dmxLocal->tail = 0; 116706f2543Smrg dmxLocal->valuators = calloc(sizeof(*dmxLocal->valuators), numAxes); 117706f2543Smrg } else { 118706f2543Smrg if (++dmxLocal->tail >= DMX_MOTION_SIZE) dmxLocal->tail = 0; 119706f2543Smrg if (dmxLocal->head == dmxLocal->tail) 120706f2543Smrg if (++dmxLocal->head >= DMX_MOTION_SIZE) dmxLocal->head = 0; 121706f2543Smrg } 122706f2543Smrg 123706f2543Smrg dmxLocal->history[OFFSET(dmxLocal->tail,0)] = time; 124706f2543Smrg 125706f2543Smrg /* Initialize the data from the known 126706f2543Smrg * values (if Absolute) or to zero (if 127706f2543Smrg * Relative) */ 128706f2543Smrg for (i = 0; i < numAxes; i++) { 129706f2543Smrg if (pDevice->valuator->axes[i].mode == Absolute) 130706f2543Smrg dmxLocal->history[OFFSET(dmxLocal->tail,i+1)] 131706f2543Smrg = dmxLocal->valuators[i]; 132706f2543Smrg else 133706f2543Smrg dmxLocal->history[OFFSET(dmxLocal->tail,i+1)] = 0; 134706f2543Smrg } 135706f2543Smrg 136706f2543Smrg for (i = firstAxis; i < axesCount; i++) { 137706f2543Smrg dmxLocal->history[OFFSET(dmxLocal->tail,i+i)] 138706f2543Smrg = (unsigned long)v[i-firstAxis]; 139706f2543Smrg dmxLocal->valuators[i] = v[i-firstAxis]; 140706f2543Smrg } 141706f2543Smrg} 142