1517 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1517 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C
		
	
	
	
/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Xinput.c,v 3.70 2003/11/03 05:11:02 tsi Exp $ */
 | 
						|
/*
 | 
						|
 * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
 | 
						|
 *                                                                            
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
 * documentation for any purpose is  hereby granted without fee, provided that
 | 
						|
 * the  above copyright   notice appear  in   all  copies and  that both  that
 | 
						|
 * copyright  notice   and   this  permission   notice  appear  in  supporting
 | 
						|
 * documentation, and that   the  name of  Frederic   Lepied not  be  used  in
 | 
						|
 * advertising or publicity pertaining to distribution of the software without
 | 
						|
 * specific,  written      prior  permission.     Frederic  Lepied   makes  no
 | 
						|
 * representations about the suitability of this software for any purpose.  It
 | 
						|
 * is provided "as is" without express or implied warranty.                   
 | 
						|
 *                                                                            
 | 
						|
 * FREDERIC  LEPIED DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
 | 
						|
 * EVENT  SHALL FREDERIC  LEPIED BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
 | 
						|
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
						|
 * DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
 | 
						|
 * TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
 | 
						|
 * PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 *
 | 
						|
 */
 | 
						|
/*
 | 
						|
 * Copyright (c) 2000-2002 by The XFree86 Project, Inc.
 | 
						|
 *
 | 
						|
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
						|
 * copy of this software and associated documentation files (the "Software"),
 | 
						|
 * to deal in the Software without restriction, including without limitation
 | 
						|
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
						|
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
						|
 * Software is furnished to do so, subject to the following conditions:
 | 
						|
 *
 | 
						|
 * The above copyright notice and this permission notice shall be included in
 | 
						|
 * all copies or substantial portions of the Software.
 | 
						|
 *
 | 
						|
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
						|
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | 
						|
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | 
						|
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
						|
 * OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
 *
 | 
						|
 * Except as contained in this notice, the name of the copyright holder(s)
 | 
						|
 * and author(s) shall not be used in advertising or otherwise to promote
 | 
						|
 * the sale, use or other dealings in this Software without prior written
 | 
						|
 * authorization from the copyright holder(s) and author(s).
 | 
						|
 */
 | 
						|
/* $XConsortium: xf86Xinput.c /main/14 1996/10/27 11:05:25 kaleb $ */
 | 
						|
/* $XdotOrg: xserver/xorg/hw/xfree86/common/xf86Xinput.c,v 1.8 2006/03/24 20:50:13 fredrik Exp $ */
 | 
						|
 | 
						|
#ifdef HAVE_XORG_CONFIG_H
 | 
						|
#include <xorg-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <X11/Xfuncproto.h>
 | 
						|
#include <X11/Xmd.h>
 | 
						|
#ifdef XINPUT
 | 
						|
#include <X11/extensions/XI.h>
 | 
						|
#include <X11/extensions/XIproto.h>
 | 
						|
#endif
 | 
						|
#include "xf86.h"
 | 
						|
#include "xf86Priv.h"
 | 
						|
#include "xf86Xinput.h"
 | 
						|
#ifdef XINPUT
 | 
						|
#include "XIstubs.h"
 | 
						|
#endif
 | 
						|
#include "mipointer.h"
 | 
						|
#include "xf86InPriv.h"
 | 
						|
 | 
						|
#ifdef DPMSExtension
 | 
						|
#define DPMS_SERVER
 | 
						|
#include <X11/extensions/dpms.h>
 | 
						|
#include "dpmsproc.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef XFreeXDGA
 | 
						|
#include "dgaproc.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#include "exevents.h"	/* AddInputDevice */
 | 
						|
#include "exglobals.h"
 | 
						|
 | 
						|
#define EXTENSION_PROC_ARGS void *
 | 
						|
#include "extnsionst.h"
 | 
						|
#include "extinit.h"	/* LookupDeviceIntRec */
 | 
						|
 | 
						|
#include "windowstr.h"	/* screenIsSaved */
 | 
						|
 | 
						|
#include <stdarg.h>
 | 
						|
 | 
						|
#include "osdep.h"		/* EnabledDevices */
 | 
						|
#include <X11/Xpoll.h>
 | 
						|
#include "xf86_OSproc.h"	/* sigio stuff */
 | 
						|
 | 
						|
/******************************************************************************
 | 
						|
 * debugging macro
 | 
						|
 *****************************************************************************/
 | 
						|
#ifdef DBG
 | 
						|
#undef DBG
 | 
						|
#endif
 | 
						|
#ifdef DEBUG
 | 
						|
#undef DEBUG
 | 
						|
#endif
 | 
						|
 | 
						|
#define DEBUG 0
 | 
						|
 | 
						|
#if DEBUG
 | 
						|
static int      debug_level = 0;
 | 
						|
 | 
						|
#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
 | 
						|
#else
 | 
						|
#define DBG(lvl, f)
 | 
						|
#endif
 | 
						|
 | 
						|
/******************************************************************************
 | 
						|
 * macros
 | 
						|
 *****************************************************************************/
 | 
						|
#define ENQUEUE(e) xf86eqEnqueue((e))
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * xf86AlwaysCoreControl --
 | 
						|
 *	
 | 
						|
 *	Control proc for the integer feedback that controls the always
 | 
						|
 * core feature.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
static void
 | 
						|
xf86AlwaysCoreControl(DeviceIntPtr	device,
 | 
						|
		      IntegerCtrl	*control)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * Core devices functions --
 | 
						|
 *	
 | 
						|
 *	Test if device is the core device by checking the
 | 
						|
 * value of always core feedback and the inputInfo struct.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
_X_EXPORT int
 | 
						|
xf86IsCorePointer(DeviceIntPtr	device)
 | 
						|
{
 | 
						|
    return(device == inputInfo.pointer);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
xf86ShareCorePointer(DeviceIntPtr	device)
 | 
						|
{
 | 
						|
    LocalDevicePtr	local = (LocalDevicePtr) device->public.devicePrivate;
 | 
						|
    
 | 
						|
    return((local->always_core_feedback &&
 | 
						|
	    local->always_core_feedback->ctrl.integer_displayed));
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
xf86SendDragEvents(DeviceIntPtr	device)
 | 
						|
{
 | 
						|
    LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate;
 | 
						|
    
 | 
						|
    if (inputInfo.pointer->button->buttonsDown > 0)
 | 
						|
	return (local->flags & XI86_SEND_DRAG_EVENTS);
 | 
						|
    else
 | 
						|
	return (TRUE);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
xf86IsCoreKeyboard(DeviceIntPtr	device)
 | 
						|
{
 | 
						|
    LocalDevicePtr	local = (LocalDevicePtr) device->public.devicePrivate;
 | 
						|
    
 | 
						|
    return((local->flags & XI86_ALWAYS_CORE) ||
 | 
						|
	   (device == inputInfo.keyboard));
 | 
						|
}
 | 
						|
 | 
						|
_X_EXPORT void
 | 
						|
xf86XInputSetSendCoreEvents(LocalDevicePtr local, Bool always)
 | 
						|
{
 | 
						|
    if (always) {
 | 
						|
	local->flags |= XI86_ALWAYS_CORE;
 | 
						|
    } else {
 | 
						|
	local->flags &= ~XI86_ALWAYS_CORE;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static int xf86CoreButtonState;
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * xf86CheckButton --
 | 
						|
 *	
 | 
						|
 *	Test if the core pointer button state is coherent with
 | 
						|
 * the button event to send.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
Bool
 | 
						|
xf86CheckButton(int	button,
 | 
						|
		int	down)
 | 
						|
{
 | 
						|
    int	check;
 | 
						|
    int bit = (1 << (button - 1));
 | 
						|
 | 
						|
    check = xf86CoreButtonState & bit;
 | 
						|
    
 | 
						|
    DBG(5, ErrorF("xf86CheckButton "
 | 
						|
		  "button=%d down=%d state=%d check=%d returns ",
 | 
						|
		   button, down, xf86CoreButtonState, check));
 | 
						|
    if ((check && down) || (!check && !down)) {
 | 
						|
	DBG(5, ErrorF("FALSE\n"));
 | 
						|
	return FALSE;
 | 
						|
    }
 | 
						|
    xf86CoreButtonState ^= bit;
 | 
						|
 | 
						|
    DBG(5, ErrorF("TRUE\n"));
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * xf86ProcessCommonOptions --
 | 
						|
 * 
 | 
						|
 *	Process global options.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
_X_EXPORT void
 | 
						|
xf86ProcessCommonOptions(LocalDevicePtr local,
 | 
						|
			 pointer	list)
 | 
						|
{
 | 
						|
    if (xf86SetBoolOption(list, "AlwaysCore", 0) ||
 | 
						|
	xf86SetBoolOption(list, "SendCoreEvents", 0)) {
 | 
						|
	local->flags |= XI86_ALWAYS_CORE;
 | 
						|
	xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name);
 | 
						|
    }
 | 
						|
 | 
						|
    if (xf86SetBoolOption(list, "CorePointer", 0)) {
 | 
						|
	local->flags |= XI86_CORE_POINTER;
 | 
						|
	xf86Msg(X_CONFIG, "%s: Core Pointer\n", local->name);
 | 
						|
    }
 | 
						|
 | 
						|
    if (xf86SetBoolOption(list, "CoreKeyboard", 0)) {
 | 
						|
	local->flags |= XI86_CORE_KEYBOARD;
 | 
						|
	xf86Msg(X_CONFIG, "%s: Core Keyboard\n", local->name);
 | 
						|
    }
 | 
						|
 | 
						|
    if (xf86SetBoolOption(list, "SendDragEvents", 1)) {
 | 
						|
	local->flags |= XI86_SEND_DRAG_EVENTS;
 | 
						|
    } else {
 | 
						|
	xf86Msg(X_CONFIG, "%s: doesn't report drag events\n", local->name);
 | 
						|
    }
 | 
						|
    
 | 
						|
    local->history_size = xf86SetIntOption(list, "HistorySize", 0);
 | 
						|
 | 
						|
    if (local->history_size > 0) {
 | 
						|
	xf86Msg(X_CONFIG, "%s: has a history of %d motions\n", local->name,
 | 
						|
		local->history_size);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * xf86XinputFinalizeInit --
 | 
						|
 * 
 | 
						|
 *	Create and initialize an integer feedback to control the always
 | 
						|
 * core feature.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
void
 | 
						|
xf86XinputFinalizeInit(DeviceIntPtr	dev)
 | 
						|
{
 | 
						|
    LocalDevicePtr        local = (LocalDevicePtr)dev->public.devicePrivate;
 | 
						|
 | 
						|
    local->dxremaind = 0.0;
 | 
						|
    local->dyremaind = 0.0;
 | 
						|
    
 | 
						|
    if (InitIntegerFeedbackClassDeviceStruct(dev, xf86AlwaysCoreControl) == FALSE) {
 | 
						|
	ErrorF("Unable to init integer feedback for always core feature\n");
 | 
						|
    } else {
 | 
						|
	local->always_core_feedback = dev->intfeed;
 | 
						|
	dev->intfeed->ctrl.integer_displayed = (local->flags & XI86_ALWAYS_CORE) ? 1 : 0;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * xf86ActivateDevice --
 | 
						|
 * 
 | 
						|
 *	Initialize an input device.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
_X_EXPORT void
 | 
						|
xf86ActivateDevice(LocalDevicePtr local)
 | 
						|
{
 | 
						|
    DeviceIntPtr	dev;
 | 
						|
 | 
						|
    if (local->flags & XI86_CONFIGURED) {
 | 
						|
	int	open_on_init;
 | 
						|
	
 | 
						|
	open_on_init = local->flags &
 | 
						|
		(XI86_OPEN_ON_INIT |
 | 
						|
		 XI86_ALWAYS_CORE | XI86_CORE_POINTER | XI86_CORE_KEYBOARD);
 | 
						|
	
 | 
						|
	dev = AddInputDevice(local->device_control,
 | 
						|
			     open_on_init);
 | 
						|
	if (dev == NULL)
 | 
						|
	    FatalError("Too many input devices");
 | 
						|
	
 | 
						|
	local->atom = MakeAtom(local->type_name,
 | 
						|
			       strlen(local->type_name),
 | 
						|
			       TRUE);
 | 
						|
	AssignTypeAndName (dev, local->atom, local->name);
 | 
						|
	dev->public.devicePrivate = (pointer) local;
 | 
						|
	local->dev = dev;      
 | 
						|
	
 | 
						|
	xf86XinputFinalizeInit(dev);
 | 
						|
 | 
						|
	/*
 | 
						|
	 * XXX Can a single device instance be both core keyboard and
 | 
						|
	 * core pointer?  If so, this should be changed.
 | 
						|
	 */
 | 
						|
	if (local->flags & XI86_CORE_POINTER)
 | 
						|
	    RegisterPointerDevice(dev);
 | 
						|
	else if (local->flags & XI86_CORE_KEYBOARD)
 | 
						|
	    RegisterKeyboardDevice(dev);
 | 
						|
#ifdef XINPUT
 | 
						|
	else
 | 
						|
	    RegisterOtherDevice(dev);
 | 
						|
#endif
 | 
						|
 | 
						|
	if (serverGeneration == 1) 
 | 
						|
	    xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
 | 
						|
		    local->name, local->type_name);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#ifdef XINPUT
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * Caller:	ProcXOpenDevice
 | 
						|
 *
 | 
						|
 * This is the implementation-dependent routine to open an input device.
 | 
						|
 * Some implementations open all input devices when the server is first
 | 
						|
 * initialized, and never close them.  Other implementations open only
 | 
						|
 * the X pointer and keyboard devices during server initialization,
 | 
						|
 * and only open other input devices when some client makes an
 | 
						|
 * XOpenDevice request.  This entry point is for the latter type of 
 | 
						|
 * implementation.
 | 
						|
 *
 | 
						|
 * If the physical device is not already open, do it here.  In this case,
 | 
						|
 * you need to keep track of the fact that one or more clients has the
 | 
						|
 * device open, and physically close it when the last client that has
 | 
						|
 * it open does an XCloseDevice.
 | 
						|
 *
 | 
						|
 * The default implementation is to do nothing (assume all input devices
 | 
						|
 * are opened during X server initialization and kept open).
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
 | 
						|
void
 | 
						|
OpenInputDevice(DeviceIntPtr	dev,
 | 
						|
		ClientPtr	client,
 | 
						|
		int		*status)
 | 
						|
{
 | 
						|
    if (!dev->inited) {
 | 
						|
	*status = BadDevice;
 | 
						|
    } else {
 | 
						|
	if (!dev->public.on) {
 | 
						|
	    if (!EnableDevice(dev)) {
 | 
						|
		*status = BadDevice;
 | 
						|
	    } else {
 | 
						|
		/* to prevent ProcXOpenDevice to call EnableDevice again */
 | 
						|
		dev->startup = FALSE;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * Caller:	ProcXChangeKeyboardDevice
 | 
						|
 *
 | 
						|
 * This procedure does the implementation-dependent portion of the work
 | 
						|
 * needed to change the keyboard device.
 | 
						|
 *
 | 
						|
 * The X keyboard device has a FocusRec.  If the device that has been 
 | 
						|
 * made into the new X keyboard did not have a FocusRec, 
 | 
						|
 * ProcXChangeKeyboardDevice will allocate one for it.
 | 
						|
 *
 | 
						|
 * If you do not want clients to be able to focus the old X keyboard
 | 
						|
 * device, call DeleteFocusClassDeviceStruct to free the FocusRec.
 | 
						|
 *
 | 
						|
 * If you support input devices with keys that you do not want to be 
 | 
						|
 * used as the X keyboard, you need to check for them here and return 
 | 
						|
 * a BadDevice error.
 | 
						|
 *
 | 
						|
 * The default implementation is to do nothing (assume you do want
 | 
						|
 * clients to be able to focus the old X keyboard).  The commented-out
 | 
						|
 * sample code shows what you might do if you don't want the default.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
 | 
						|
int
 | 
						|
ChangeKeyboardDevice (DeviceIntPtr old_dev, DeviceIntPtr new_dev)
 | 
						|
{
 | 
						|
  /**********************************************************************
 | 
						|
   * DeleteFocusClassDeviceStruct(old_dev);	 * defined in xchgptr.c *
 | 
						|
   **********************************************************************/
 | 
						|
  return !Success;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * Caller:	ProcXChangePointerDevice
 | 
						|
 *
 | 
						|
 * This procedure does the implementation-dependent portion of the work
 | 
						|
 * needed to change the pointer device.
 | 
						|
 *
 | 
						|
 * The X pointer device does not have a FocusRec.  If the device that
 | 
						|
 * has been made into the new X pointer had a FocusRec, 
 | 
						|
 * ProcXChangePointerDevice will free it.
 | 
						|
 *
 | 
						|
 * If you want clients to be able to focus the old pointer device that
 | 
						|
 * has now become accessible through the input extension, you need to 
 | 
						|
 * add a FocusRec to it here.
 | 
						|
 *
 | 
						|
 * The XChangePointerDevice protocol request also allows the client
 | 
						|
 * to choose which axes of the new pointer device are used to move 
 | 
						|
 * the X cursor in the X- and Y- directions.  If the axes are different
 | 
						|
 * than the default ones, you need to keep track of that here.
 | 
						|
 *
 | 
						|
 * If you support input devices with valuators that you do not want to be 
 | 
						|
 * used as the X pointer, you need to check for them here and return a 
 | 
						|
 * BadDevice error.
 | 
						|
 *
 | 
						|
 * The default implementation is to do nothing (assume you don't want
 | 
						|
 * clients to be able to focus the old X pointer).  The commented-out
 | 
						|
 * sample code shows what you might do if you don't want the default.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
 | 
						|
int
 | 
						|
ChangePointerDevice (
 | 
						|
     DeviceIntPtr	old_dev,
 | 
						|
     DeviceIntPtr	new_dev,
 | 
						|
     unsigned char	x,
 | 
						|
     unsigned char	y)
 | 
						|
{
 | 
						|
  /************************************************************************
 | 
						|
    InitFocusClassDeviceStruct(old_dev);	* allow focusing old ptr*
 | 
						|
    
 | 
						|
    x_axis = x;					* keep track of new x-axis*
 | 
						|
    y_axis = y;					* keep track of new y-axis*
 | 
						|
    if (x_axis != 0 || y_axis != 1)
 | 
						|
    axes_changed = TRUE;			* remember axes have changed*
 | 
						|
    else
 | 
						|
    axes_changed = FALSE;
 | 
						|
   *************************************************************************/
 | 
						|
 | 
						|
  /*
 | 
						|
   * We don't allow axis swap or other exotic features.
 | 
						|
   */
 | 
						|
  if (x == 0 && y == 1) {
 | 
						|
      LocalDevicePtr	old_local = (LocalDevicePtr)old_dev->public.devicePrivate;
 | 
						|
      LocalDevicePtr	new_local = (LocalDevicePtr)new_dev->public.devicePrivate;
 | 
						|
      
 | 
						|
      InitFocusClassDeviceStruct(old_dev);
 | 
						|
    
 | 
						|
      /* Restore Extended motion history information */
 | 
						|
      old_dev->valuator->GetMotionProc   = old_local->motion_history_proc;
 | 
						|
      old_dev->valuator->numMotionEvents = old_local->history_size;
 | 
						|
 | 
						|
      /* Save Extended motion history information */
 | 
						|
      new_local->motion_history_proc = new_dev->valuator->GetMotionProc;
 | 
						|
      new_local->history_size	     = new_dev->valuator->numMotionEvents;
 | 
						|
      
 | 
						|
      /* Set Core motion history information */
 | 
						|
      new_dev->valuator->GetMotionProc   = miPointerGetMotionEvents;
 | 
						|
      new_dev->valuator->numMotionEvents = miPointerGetMotionBufferSize();
 | 
						|
      
 | 
						|
    return Success;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    return !Success;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * Caller:	ProcXCloseDevice
 | 
						|
 *
 | 
						|
 * Take care of implementation-dependent details of closing a device.
 | 
						|
 * Some implementations may actually close the device, others may just
 | 
						|
 * remove this clients interest in that device.
 | 
						|
 *
 | 
						|
 * The default implementation is to do nothing (assume all input devices
 | 
						|
 * are initialized during X server initialization and kept open).
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
 | 
						|
void
 | 
						|
CloseInputDevice (DeviceIntPtr d, ClientPtr client)
 | 
						|
{
 | 
						|
  ErrorF("ProcXCloseDevice to close or not ?\n");
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * Caller:	ProcXListInputDevices
 | 
						|
 *
 | 
						|
 * This is the implementation-dependent routine to initialize an input 
 | 
						|
 * device to the point that information about it can be listed.
 | 
						|
 * Some implementations open all input devices when the server is first
 | 
						|
 * initialized, and never close them.  Other implementations open only
 | 
						|
 * the X pointer and keyboard devices during server initialization,
 | 
						|
 * and only open other input devices when some client makes an
 | 
						|
 * XOpenDevice request.  If some other process has the device open, the
 | 
						|
 * server may not be able to get information about the device to list it.
 | 
						|
 *
 | 
						|
 * This procedure should be used by implementations that do not initialize
 | 
						|
 * all input devices at server startup.  It should do device-dependent
 | 
						|
 * initialization for any devices not previously initialized, and call
 | 
						|
 * AddInputDevice for each of those devices so that a DeviceIntRec will be 
 | 
						|
 * created for them.
 | 
						|
 *
 | 
						|
 * The default implementation is to do nothing (assume all input devices
 | 
						|
 * are initialized during X server initialization and kept open).
 | 
						|
 * The commented-out sample code shows what you might do if you don't want 
 | 
						|
 * the default.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
 | 
						|
void
 | 
						|
AddOtherInputDevices ()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 *
 | 
						|
 * Caller:	ProcXSetDeviceMode
 | 
						|
 *
 | 
						|
 * Change the mode of an extension device.
 | 
						|
 * This function is used to change the mode of a device from reporting
 | 
						|
 * relative motion to reporting absolute positional information, and
 | 
						|
 * vice versa.
 | 
						|
 * The default implementation below is that no such devices are supported.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
 | 
						|
int
 | 
						|
SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
 | 
						|
{
 | 
						|
  LocalDevicePtr        local = (LocalDevicePtr)dev->public.devicePrivate;
 | 
						|
 | 
						|
  if (local->switch_mode) {
 | 
						|
    return (*local->switch_mode)(client, dev, mode);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    return BadMatch;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * Caller:	ProcXSetDeviceValuators
 | 
						|
 *
 | 
						|
 * Set the value of valuators on an extension input device.
 | 
						|
 * This function is used to set the initial value of valuators on
 | 
						|
 * those input devices that are capable of reporting either relative
 | 
						|
 * motion or an absolute position, and allow an initial position to be set.
 | 
						|
 * The default implementation below is that no such devices are supported.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
 | 
						|
int
 | 
						|
SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
 | 
						|
		    int first_valuator, int num_valuators)
 | 
						|
{
 | 
						|
  return BadMatch;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *
 | 
						|
 * Caller:	ProcXChangeDeviceControl
 | 
						|
 *
 | 
						|
 * Change the specified device controls on an extension input device.
 | 
						|
 *
 | 
						|
 ***********************************************************************
 | 
						|
 */
 | 
						|
 | 
						|
int
 | 
						|
ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
 | 
						|
{
 | 
						|
  LocalDevicePtr        local = (LocalDevicePtr)dev->public.devicePrivate;
 | 
						|
 | 
						|
  if (!local->control_proc) {
 | 
						|
      return (BadMatch);
 | 
						|
  }
 | 
						|
  else {
 | 
						|
      return (*local->control_proc)(local, control);
 | 
						|
  }
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
 * adapted from mieq.c to support extended events
 | 
						|
 *
 | 
						|
 */
 | 
						|
#define QUEUE_SIZE  256
 | 
						|
 | 
						|
typedef struct _Event {
 | 
						|
    xEvent	event;
 | 
						|
#ifdef XINPUT
 | 
						|
  deviceValuator val;
 | 
						|
#endif
 | 
						|
    ScreenPtr	pScreen;
 | 
						|
} EventRec, *EventPtr;
 | 
						|
 | 
						|
typedef struct _EventQueue {
 | 
						|
    HWEventQueueType head, tail;
 | 
						|
    CARD32	lastEventTime;	    /* to avoid time running backwards */
 | 
						|
    Bool	lastMotion;
 | 
						|
    EventRec	events[QUEUE_SIZE]; /* static allocation for signals */
 | 
						|
    DevicePtr	pKbd, pPtr;	    /* device pointer, to get funcs */
 | 
						|
    ScreenPtr	pEnqueueScreen;	    /* screen events are being delivered to */
 | 
						|
    ScreenPtr	pDequeueScreen;	    /* screen events are being dispatched to */
 | 
						|
} EventQueueRec, *EventQueuePtr;
 | 
						|
 | 
						|
static EventQueueRec xf86EventQueue;
 | 
						|
 | 
						|
Bool
 | 
						|
xf86eqInit (DevicePtr pKbd, DevicePtr pPtr)
 | 
						|
{
 | 
						|
    xf86EventQueue.head = xf86EventQueue.tail = 0;
 | 
						|
    xf86EventQueue.lastEventTime = GetTimeInMillis ();
 | 
						|
    xf86EventQueue.pKbd = pKbd;
 | 
						|
    xf86EventQueue.pPtr = pPtr;
 | 
						|
    xf86EventQueue.lastMotion = FALSE;
 | 
						|
    xf86EventQueue.pEnqueueScreen = screenInfo.screens[0];
 | 
						|
    xf86EventQueue.pDequeueScreen = xf86EventQueue.pEnqueueScreen;
 | 
						|
    SetInputCheck (&xf86EventQueue.head, &xf86EventQueue.tail);
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Must be reentrant with ProcessInputEvents.  Assumption: xf86eqEnqueue
 | 
						|
 * will never be interrupted.  If this is called from both signal
 | 
						|
 * handlers and regular code, make sure the signal is suspended when
 | 
						|
 * called from regular code.
 | 
						|
 */
 | 
						|
 | 
						|
_X_EXPORT void
 | 
						|
xf86eqEnqueue (xEvent *e)
 | 
						|
{
 | 
						|
    int		oldtail, newtail;
 | 
						|
    Bool	isMotion;
 | 
						|
#ifdef XINPUT
 | 
						|
    int		count;
 | 
						|
    
 | 
						|
    xf86AssertBlockedSIGIO ("xf86eqEnqueue");
 | 
						|
    switch (e->u.u.type) {
 | 
						|
    case KeyPress:
 | 
						|
    case KeyRelease:
 | 
						|
#ifdef XFreeXDGA
 | 
						|
	/* we do this here, because nobody seems to be calling
 | 
						|
	   xf86PostKeyEvent().  We can't steal MotionNotify events here
 | 
						|
	   because the motion-relative information has been lost already. */
 | 
						|
	if(DGAStealKeyEvent(xf86EventQueue.pEnqueueScreen->myNum, e))
 | 
						|
	    return;
 | 
						|
#endif
 | 
						|
	/* fall through */
 | 
						|
    case ButtonPress:
 | 
						|
    case ButtonRelease:
 | 
						|
    case MotionNotify:
 | 
						|
        count = 1;
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
#ifdef XFreeXDGA
 | 
						|
	if (DGAIsDgaEvent (e))
 | 
						|
	{
 | 
						|
	    count = 1;
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
	if (!((deviceKeyButtonPointer *) e)->deviceid & MORE_EVENTS) {
 | 
						|
            count = 1;
 | 
						|
	}
 | 
						|
        else {
 | 
						|
	    count = 2;
 | 
						|
	}
 | 
						|
        break;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    oldtail = xf86EventQueue.tail;
 | 
						|
    isMotion = e->u.u.type == MotionNotify;
 | 
						|
    if (isMotion && xf86EventQueue.lastMotion && oldtail != xf86EventQueue.head) {
 | 
						|
	if (oldtail == 0)
 | 
						|
	    oldtail = QUEUE_SIZE;
 | 
						|
	oldtail = oldtail - 1;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
    	newtail = oldtail + 1;
 | 
						|
    	if (newtail == QUEUE_SIZE)
 | 
						|
	    newtail = 0;
 | 
						|
    	/* Toss events which come in late */
 | 
						|
    	if (newtail == xf86EventQueue.head)
 | 
						|
	    return;
 | 
						|
	xf86EventQueue.tail = newtail;
 | 
						|
    }
 | 
						|
    
 | 
						|
    xf86EventQueue.lastMotion = isMotion;
 | 
						|
    xf86EventQueue.events[oldtail].event = *e;
 | 
						|
#ifdef XINPUT
 | 
						|
    if (count == 2) {
 | 
						|
	xf86EventQueue.events[oldtail].val = *((deviceValuator *) (((deviceKeyButtonPointer *) e)+1));
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    /*
 | 
						|
     * Make sure that event times don't go backwards - this
 | 
						|
     * is "unnecessary", but very useful
 | 
						|
     */
 | 
						|
    if (e->u.keyButtonPointer.time < xf86EventQueue.lastEventTime &&
 | 
						|
	xf86EventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000) {
 | 
						|
	
 | 
						|
	xf86EventQueue.events[oldtail].event.u.keyButtonPointer.time =
 | 
						|
	    xf86EventQueue.lastEventTime;
 | 
						|
    }
 | 
						|
    xf86EventQueue.events[oldtail].pScreen = xf86EventQueue.pEnqueueScreen;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Call this from ProcessInputEvents()
 | 
						|
 */
 | 
						|
void
 | 
						|
xf86eqProcessInputEvents ()
 | 
						|
{
 | 
						|
    EventRec	*e;
 | 
						|
    int		x, y;
 | 
						|
    struct {
 | 
						|
	xEvent	event;
 | 
						|
#ifdef XINPUT
 | 
						|
	deviceValuator	val;
 | 
						|
#endif
 | 
						|
    }		xe;
 | 
						|
#ifdef XINPUT
 | 
						|
    DeviceIntPtr                dev;
 | 
						|
    int                         id, count;
 | 
						|
    deviceKeyButtonPointer      *dev_xe;
 | 
						|
#endif
 | 
						|
 | 
						|
    while (xf86EventQueue.head != xf86EventQueue.tail) {
 | 
						|
	if (screenIsSaved == SCREEN_SAVER_ON)
 | 
						|
	    SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset);
 | 
						|
#ifdef DPMSExtension
 | 
						|
	else if (DPMSPowerLevel != DPMSModeOn)
 | 
						|
	    SetScreenSaverTimer();
 | 
						|
 | 
						|
        if (DPMSPowerLevel != DPMSModeOn)
 | 
						|
            DPMSSet(DPMSModeOn);
 | 
						|
#endif
 | 
						|
 | 
						|
	e = &xf86EventQueue.events[xf86EventQueue.head];
 | 
						|
	/*
 | 
						|
	 * Assumption - screen switching can only occur on motion events
 | 
						|
	 */
 | 
						|
	if (e->pScreen != xf86EventQueue.pDequeueScreen) {
 | 
						|
	    xf86EventQueue.pDequeueScreen = e->pScreen;
 | 
						|
	    x = e->event.u.keyButtonPointer.rootX;
 | 
						|
	    y = e->event.u.keyButtonPointer.rootY;
 | 
						|
	    if (xf86EventQueue.head == QUEUE_SIZE - 1)
 | 
						|
	    	xf86EventQueue.head = 0;
 | 
						|
	    else
 | 
						|
	    	++xf86EventQueue.head;
 | 
						|
	    NewCurrentScreen (xf86EventQueue.pDequeueScreen, x, y);
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    xe.event = e->event;
 | 
						|
	    xe.val = e->val;
 | 
						|
	    if (xf86EventQueue.head == QUEUE_SIZE - 1)
 | 
						|
	    	xf86EventQueue.head = 0;
 | 
						|
	    else
 | 
						|
	    	++xf86EventQueue.head;
 | 
						|
	    switch (xe.event.u.u.type) {
 | 
						|
	    case KeyPress:
 | 
						|
	    case KeyRelease:
 | 
						|
	    	(*xf86EventQueue.pKbd->processInputProc)
 | 
						|
		    (&xe.event, (DeviceIntPtr)xf86EventQueue.pKbd, 1);
 | 
						|
	    	break;
 | 
						|
#ifdef XINPUT
 | 
						|
            case ButtonPress:
 | 
						|
            case ButtonRelease:
 | 
						|
            case MotionNotify:
 | 
						|
	    	(*(inputInfo.pointer->public.processInputProc))
 | 
						|
		    (&xe.event, (DeviceIntPtr)inputInfo.pointer, 1);
 | 
						|
		break;
 | 
						|
 | 
						|
	    default:
 | 
						|
#ifdef XFreeXDGA
 | 
						|
		if (DGADeliverEvent (xf86EventQueue.pDequeueScreen, &xe.event))
 | 
						|
		    break;
 | 
						|
#endif
 | 
						|
		dev_xe = (deviceKeyButtonPointer *) &xe.event;
 | 
						|
		id = dev_xe->deviceid & DEVICE_BITS;
 | 
						|
		if (!(dev_xe->deviceid & MORE_EVENTS)) {
 | 
						|
		    count = 1;
 | 
						|
		}
 | 
						|
		else {
 | 
						|
		    count = 2;
 | 
						|
		}
 | 
						|
		dev = LookupDeviceIntRec(id);
 | 
						|
		if (dev == NULL) {
 | 
						|
		    ErrorF("LookupDeviceIntRec id=0x%x not found\n", id);
 | 
						|
/*                   FatalError("xf86eqProcessInputEvents : device not found.\n");
 | 
						|
 */
 | 
						|
		    break;
 | 
						|
		}
 | 
						|
		if (!dev->public.processInputProc) {
 | 
						|
		    FatalError("xf86eqProcessInputEvents : device has no input proc.\n");
 | 
						|
		    break;
 | 
						|
		}
 | 
						|
		(*dev->public.processInputProc)(&xe.event, dev, count);
 | 
						|
#else
 | 
						|
	    default:
 | 
						|
	    	(*xf86EventQueue.pPtr->processInputProc)
 | 
						|
		    (&xe.event, (DeviceIntPtr)xf86EventQueue.pPtr, 1);
 | 
						|
#endif
 | 
						|
	    	break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
xf86eqSwitchScreen(ScreenPtr	pScreen,
 | 
						|
		   Bool		fromDIX)
 | 
						|
{
 | 
						|
    xf86EventQueue.pEnqueueScreen = pScreen;
 | 
						|
  
 | 
						|
    if (fromDIX)
 | 
						|
	xf86EventQueue.pDequeueScreen = pScreen;
 | 
						|
}
 | 
						|
 | 
						|
/* 
 | 
						|
 * convenient functions to post events
 | 
						|
 */
 | 
						|
 | 
						|
_X_EXPORT void
 | 
						|
xf86PostMotionEvent(DeviceIntPtr	device,
 | 
						|
		    int			is_absolute,
 | 
						|
		    int			first_valuator,
 | 
						|
		    int			num_valuators,
 | 
						|
		    ...)
 | 
						|
{
 | 
						|
    va_list			var;
 | 
						|
    int				loop;
 | 
						|
    xEvent			xE[2];
 | 
						|
    deviceKeyButtonPointer	*xev  = (deviceKeyButtonPointer*) xE;
 | 
						|
    deviceValuator		*xv   = (deviceValuator*) xev+1;
 | 
						|
    LocalDevicePtr		local = (LocalDevicePtr) device->public.devicePrivate;
 | 
						|
    char			*buff = 0;
 | 
						|
    Time			current;
 | 
						|
    Bool			is_core = xf86IsCorePointer(device);
 | 
						|
    Bool			is_shared = xf86ShareCorePointer(device);
 | 
						|
    Bool			drag = xf86SendDragEvents(device);
 | 
						|
    ValuatorClassPtr		val = device->valuator;
 | 
						|
    int				valuator[6];
 | 
						|
    int				oldaxis[6];
 | 
						|
    int				*axisvals;
 | 
						|
    int				dx = 0, dy = 0;
 | 
						|
    float			mult;
 | 
						|
    int				x, y;
 | 
						|
    int				loop_start;
 | 
						|
    int				i;
 | 
						|
    int				num;
 | 
						|
    
 | 
						|
    DBG(5, ErrorF("xf86PostMotionEvent BEGIN 0x%x(%s) is_core=%s is_shared=%s is_absolute=%s\n",
 | 
						|
		  device, device->name,
 | 
						|
		  is_core ? "True" : "False",
 | 
						|
		  is_shared ? "True" : "False",
 | 
						|
		  is_absolute ? "True" : "False"));
 | 
						|
    
 | 
						|
    xf86Info.lastEventTime = xev->time = current = GetTimeInMillis();
 | 
						|
    
 | 
						|
    if (!is_core) {
 | 
						|
      if (HAS_MOTION_HISTORY(local)) {
 | 
						|
	buff = ((char *)local->motion_history +
 | 
						|
		(sizeof(INT32) * local->dev->valuator->numAxes + sizeof(Time)) * local->last);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (num_valuators && (!val || (first_valuator + num_valuators > val->numAxes))) {
 | 
						|
	ErrorF("Bad valuators reported for device \"%s\"\n", device->name);
 | 
						|
	return;
 | 
						|
    }
 | 
						|
 | 
						|
    axisvals = val->axisVal;
 | 
						|
    
 | 
						|
    va_start(var, num_valuators);
 | 
						|
 | 
						|
    loop_start = first_valuator;
 | 
						|
    for(loop=0; loop<num_valuators; loop++) {
 | 
						|
	
 | 
						|
	valuator[loop%6] = va_arg(var,int);
 | 
						|
	
 | 
						|
	if (loop % 6 == 5 || loop == num_valuators - 1)	{
 | 
						|
	    num = loop % 6 + 1;
 | 
						|
	    /*
 | 
						|
	     * Adjust first two relative valuators
 | 
						|
	     */
 | 
						|
	    if (!is_absolute && num_valuators >= 2 && loop_start == 0) {
 | 
						|
		
 | 
						|
		dx = valuator[0];
 | 
						|
		dy = valuator[1];
 | 
						|
 | 
						|
		/*
 | 
						|
		 * Accelerate
 | 
						|
		 */
 | 
						|
		if (device->ptrfeed && device->ptrfeed->ctrl.num) {
 | 
						|
		    /* modeled from xf86Events.c */
 | 
						|
		    if (device->ptrfeed->ctrl.threshold) {
 | 
						|
			if ((abs(dx) + abs(dy)) >= device->ptrfeed->ctrl.threshold) {
 | 
						|
			    local->dxremaind = ((float)dx * (float)(device->ptrfeed->ctrl.num)) /
 | 
						|
			        (float)(device->ptrfeed->ctrl.den) + local->dxremaind;
 | 
						|
			    valuator[0] = (int)local->dxremaind;
 | 
						|
			    local->dxremaind = local->dxremaind - (float)valuator[0];
 | 
						|
			    
 | 
						|
			    local->dyremaind = ((float)dy * (float)(device->ptrfeed->ctrl.num)) /
 | 
						|
			        (float)(device->ptrfeed->ctrl.den) + local->dyremaind;
 | 
						|
			    valuator[1] = (int)local->dyremaind;
 | 
						|
			    local->dyremaind = local->dyremaind - (float)valuator[1];
 | 
						|
			}
 | 
						|
		    }
 | 
						|
		    else if (dx || dy) {
 | 
						|
			mult = pow((float)(dx*dx+dy*dy),
 | 
						|
				   ((float)(device->ptrfeed->ctrl.num) /
 | 
						|
				    (float)(device->ptrfeed->ctrl.den) - 1.0) / 
 | 
						|
				   2.0) / 2.0;
 | 
						|
			if (dx) {
 | 
						|
			    local->dxremaind = mult * (float)dx + local->dxremaind;
 | 
						|
			    valuator[0] = (int)local->dxremaind;
 | 
						|
			    local->dxremaind = local->dxremaind - (float)valuator[0];
 | 
						|
			}
 | 
						|
			if (dy) {
 | 
						|
			    local->dyremaind = mult * (float)dy + local->dyremaind;
 | 
						|
			    valuator[1] = (int)local->dyremaind;
 | 
						|
			    local->dyremaind = local->dyremaind - (float)valuator[1];
 | 
						|
			}
 | 
						|
		    }
 | 
						|
		    DBG(6, ErrorF("xf86PostMotionEvent acceleration v0=%d v1=%d\n",
 | 
						|
				  valuator[0], valuator[1]));
 | 
						|
		}
 | 
						|
		
 | 
						|
		/*
 | 
						|
		 * Map current position back to device space in case
 | 
						|
		 * the cursor was warped
 | 
						|
		 */
 | 
						|
		if (is_core || is_shared)
 | 
						|
		{
 | 
						|
		    miPointerPosition (&x, &y);
 | 
						|
		    if (local->reverse_conversion_proc)
 | 
						|
			(*local->reverse_conversion_proc)(local, x, y, axisvals);
 | 
						|
		    else
 | 
						|
		    {
 | 
						|
			axisvals[0] = x;
 | 
						|
			axisvals[1] = y;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
	    }
 | 
						|
		
 | 
						|
	    /*
 | 
						|
	     * Update axes
 | 
						|
	     */
 | 
						|
	    for (i = 0; i < num; i++)
 | 
						|
	    {
 | 
						|
		oldaxis[i] = axisvals[loop_start + i];
 | 
						|
	        if (is_absolute)
 | 
						|
		    axisvals[loop_start + i] = valuator[i];
 | 
						|
		else
 | 
						|
		    axisvals[loop_start + i] += valuator[i];
 | 
						|
	    }
 | 
						|
		
 | 
						|
	    /*
 | 
						|
	     * Deliver extension event
 | 
						|
	     */
 | 
						|
	    if (!is_core) {
 | 
						|
		xev->type = DeviceMotionNotify;
 | 
						|
		xev->detail = 0;
 | 
						|
		xev->deviceid = device->id | MORE_EVENTS;
 | 
						|
            
 | 
						|
		xv->type = DeviceValuator;
 | 
						|
		xv->deviceid = device->id;
 | 
						|
	    
 | 
						|
		xv->device_state = 0;
 | 
						|
		xv->num_valuators = num;
 | 
						|
		xv->first_valuator = loop_start;
 | 
						|
		memcpy (&xv->valuator0, &axisvals[loop_start],
 | 
						|
			sizeof(INT32)*xv->num_valuators);
 | 
						|
		
 | 
						|
		if (HAS_MOTION_HISTORY(local)) {
 | 
						|
		    *(Time*)buff = current;
 | 
						|
		    memcpy(buff+sizeof(Time)+sizeof(INT32)*xv->first_valuator,
 | 
						|
			   &axisvals[loop_start],
 | 
						|
			   sizeof(INT32)*xv->num_valuators);
 | 
						|
		}
 | 
						|
		ENQUEUE(xE);
 | 
						|
	    }
 | 
						|
	    
 | 
						|
	    /*
 | 
						|
	     * Deliver core event
 | 
						|
	     */
 | 
						|
	    if (is_core ||
 | 
						|
		(is_shared && num_valuators >= 2 && loop_start == 0)) {
 | 
						|
#ifdef XFreeXDGA
 | 
						|
		/*
 | 
						|
		 * Let DGA peek at the event and steal it
 | 
						|
		 */
 | 
						|
		xev->type = MotionNotify;
 | 
						|
		xev->detail = 0;
 | 
						|
		if (is_absolute)
 | 
						|
		{
 | 
						|
		    dx = axisvals[0] - oldaxis[0];
 | 
						|
		    dy = axisvals[1] - oldaxis[1];
 | 
						|
		}
 | 
						|
		if (DGAStealMouseEvent(xf86EventQueue.pEnqueueScreen->myNum,
 | 
						|
				       xE, dx, dy))
 | 
						|
		    continue;
 | 
						|
#endif
 | 
						|
		if (!(*local->conversion_proc)(local, loop_start, num,
 | 
						|
					       axisvals[0], axisvals[1],
 | 
						|
					       axisvals[2], axisvals[3],
 | 
						|
					       axisvals[4], axisvals[5],
 | 
						|
					       &x, &y))
 | 
						|
		    continue;
 | 
						|
 | 
						|
		if (drag)
 | 
						|
		    miPointerAbsoluteCursor (x, y, current);
 | 
						|
		/*
 | 
						|
		 * Retrieve the position
 | 
						|
		 */
 | 
						|
		miPointerPosition (&x, &y);
 | 
						|
		if (local->reverse_conversion_proc)
 | 
						|
		    (*local->reverse_conversion_proc)(local, x, y, axisvals);
 | 
						|
		else
 | 
						|
		{
 | 
						|
		    axisvals[0] = x;
 | 
						|
		    axisvals[1] = y;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    loop_start += 6;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    va_end(var);
 | 
						|
    if (HAS_MOTION_HISTORY(local)) {
 | 
						|
	local->last = (local->last + 1) % device->valuator->numMotionEvents;
 | 
						|
	if (local->last == local->first)
 | 
						|
	    local->first = (local->first + 1) % device->valuator->numMotionEvents;
 | 
						|
    }
 | 
						|
    DBG(5, ErrorF("xf86PostMotionEvent END   0x%x(%s) is_core=%s is_shared=%s\n",
 | 
						|
		  device, device->name,
 | 
						|
		  is_core ? "True" : "False",
 | 
						|
		  is_shared ? "True" : "False"));
 | 
						|
}
 | 
						|
 | 
						|
_X_EXPORT void
 | 
						|
xf86PostProximityEvent(DeviceIntPtr	device,
 | 
						|
		       int		is_in,
 | 
						|
		       int		first_valuator,
 | 
						|
		       int		num_valuators,
 | 
						|
		       ...)
 | 
						|
{
 | 
						|
    va_list			var;
 | 
						|
    int				loop;
 | 
						|
    xEvent			xE[2];
 | 
						|
    deviceKeyButtonPointer	*xev = (deviceKeyButtonPointer*) xE;
 | 
						|
    deviceValuator		*xv = (deviceValuator*) xev+1;
 | 
						|
    ValuatorClassPtr		val = device->valuator;
 | 
						|
    Bool			is_core = xf86IsCorePointer(device);
 | 
						|
    Bool			is_absolute = val && ((val->mode & 1) == Relative);
 | 
						|
    
 | 
						|
    DBG(5, ErrorF("xf86PostProximityEvent BEGIN 0x%x(%s) prox=%s is_core=%s is_absolute=%s\n",
 | 
						|
		  device, device->name, is_in ? "true" : "false",
 | 
						|
		  is_core ? "True" : "False",
 | 
						|
		  is_absolute ? "True" : "False"));
 | 
						|
    
 | 
						|
    if (is_core) {
 | 
						|
	return;
 | 
						|
    }
 | 
						|
  
 | 
						|
    if (num_valuators && (!val || (first_valuator + num_valuators > val->numAxes))) {
 | 
						|
	ErrorF("Bad valuators reported for device \"%s\"\n", device->name);
 | 
						|
	return;
 | 
						|
    }
 | 
						|
 | 
						|
    xev->type = is_in ? ProximityIn : ProximityOut;
 | 
						|
    xev->detail = 0;
 | 
						|
    xev->deviceid = device->id | MORE_EVENTS;
 | 
						|
	
 | 
						|
    xv->type = DeviceValuator;
 | 
						|
    xv->deviceid = device->id;
 | 
						|
    xv->device_state = 0;
 | 
						|
 | 
						|
    if ((device->valuator->mode & 1) == Relative) {
 | 
						|
	num_valuators = 0;
 | 
						|
    }
 | 
						|
  
 | 
						|
    if (num_valuators != 0) {
 | 
						|
	int	*axisvals = val->axisVal;
 | 
						|
	    
 | 
						|
	va_start(var, num_valuators);
 | 
						|
 | 
						|
	for(loop=0; loop<num_valuators; loop++) {
 | 
						|
	    switch (loop % 6) {
 | 
						|
	    case 0:
 | 
						|
		xv->valuator0 = is_absolute ? va_arg(var, int) : axisvals[loop]; 
 | 
						|
		break;
 | 
						|
	    case 1:
 | 
						|
		xv->valuator1 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		break;
 | 
						|
	    case 2:
 | 
						|
		xv->valuator2 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		break;
 | 
						|
	    case 3:
 | 
						|
		xv->valuator3 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		break;
 | 
						|
	    case 4:
 | 
						|
		xv->valuator4 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		break;
 | 
						|
	    case 5:
 | 
						|
		xv->valuator5 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	    if ((loop % 6 == 5) || (loop == num_valuators - 1)) {
 | 
						|
		xf86Info.lastEventTime = xev->time = GetTimeInMillis();
 | 
						|
 | 
						|
		xv->num_valuators = (loop % 6) + 1;
 | 
						|
		xv->first_valuator = first_valuator + (loop / 6) * 6;
 | 
						|
		ENQUEUE(xE);
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	va_end(var);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	/* no valuator */
 | 
						|
	xf86Info.lastEventTime = xev->time = GetTimeInMillis();
 | 
						|
 | 
						|
	xv->num_valuators = 0;
 | 
						|
	xv->first_valuator = 0;
 | 
						|
	ENQUEUE(xE);
 | 
						|
    }
 | 
						|
    DBG(5, ErrorF("xf86PostProximityEvent END   0x%x(%s) prox=%s is_core=%s is_absolute=%s\n",
 | 
						|
		  device, device->name, is_in ? "true" : "false",
 | 
						|
		  is_core ? "True" : "False",
 | 
						|
		  is_absolute ? "True" : "False"));
 | 
						|
    
 | 
						|
}
 | 
						|
 | 
						|
_X_EXPORT void
 | 
						|
xf86PostButtonEvent(DeviceIntPtr	device,
 | 
						|
		    int			is_absolute,
 | 
						|
		    int			button,
 | 
						|
		    int			is_down,
 | 
						|
		    int			first_valuator,
 | 
						|
		    int			num_valuators,
 | 
						|
		    ...)
 | 
						|
{
 | 
						|
    va_list			var;
 | 
						|
    int				loop;
 | 
						|
    xEvent			xE[2];
 | 
						|
    deviceKeyButtonPointer	*xev	        = (deviceKeyButtonPointer*) xE;
 | 
						|
    deviceValuator		*xv	        = (deviceValuator*) xev+1;
 | 
						|
    ValuatorClassPtr		val		= device->valuator;
 | 
						|
    Bool			is_core		= xf86IsCorePointer(device);
 | 
						|
    Bool			is_shared       = xf86ShareCorePointer(device);
 | 
						|
    
 | 
						|
    DBG(5, ErrorF("xf86PostButtonEvent BEGIN 0x%x(%s) button=%d down=%s is_core=%s is_shared=%s is_absolute=%s\n",
 | 
						|
		  device, device->name, button,
 | 
						|
		  is_down ? "True" : "False",
 | 
						|
		  is_core ? "True" : "False",
 | 
						|
		  is_shared ? "True" : "False",
 | 
						|
		  is_absolute ? "True" : "False"));
 | 
						|
    
 | 
						|
    /* Check the core pointer button state not to send an inconsistent
 | 
						|
     * event. This can happen with the AlwaysCore feature.
 | 
						|
     */
 | 
						|
    if ((is_core || is_shared) && 
 | 
						|
	!xf86CheckButton(device->button->map[button], is_down)) 
 | 
						|
    {
 | 
						|
	return;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (num_valuators && (!val || (first_valuator + num_valuators > val->numAxes))) {
 | 
						|
	ErrorF("Bad valuators reported for device \"%s\"\n", device->name);
 | 
						|
	return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!is_core) {
 | 
						|
	xev->type = is_down ? DeviceButtonPress : DeviceButtonRelease;
 | 
						|
	xev->detail = button;
 | 
						|
	xev->deviceid = device->id | MORE_EVENTS;
 | 
						|
	    
 | 
						|
	xv->type = DeviceValuator;
 | 
						|
	xv->deviceid = device->id;
 | 
						|
	xv->device_state = 0;
 | 
						|
 | 
						|
	if (num_valuators != 0) {
 | 
						|
	    int			*axisvals = val->axisVal;
 | 
						|
	    
 | 
						|
	    va_start(var, num_valuators);
 | 
						|
      
 | 
						|
	    for(loop=0; loop<num_valuators; loop++) {
 | 
						|
		switch (loop % 6) {
 | 
						|
		case 0:
 | 
						|
		    xv->valuator0 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		    break;
 | 
						|
		case 1:
 | 
						|
		    xv->valuator1 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		    break;
 | 
						|
		case 2:
 | 
						|
		    xv->valuator2 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		    break;
 | 
						|
		case 3:
 | 
						|
		    xv->valuator3 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		    break;
 | 
						|
		case 4:
 | 
						|
		    xv->valuator4 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		    break;
 | 
						|
		case 5:
 | 
						|
		    xv->valuator5 = is_absolute ? va_arg(var, int) : axisvals[loop];
 | 
						|
		    break;
 | 
						|
		}
 | 
						|
		if ((loop % 6 == 5) || (loop == num_valuators - 1)) {
 | 
						|
		    xf86Info.lastEventTime = xev->time = GetTimeInMillis();
 | 
						|
		    xv->num_valuators = (loop % 6) + 1;
 | 
						|
		    xv->first_valuator = first_valuator + (loop / 6) * 6;
 | 
						|
		    ENQUEUE(xE);
 | 
						|
		    
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    va_end(var);
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    /* no valuator */
 | 
						|
	    xf86Info.lastEventTime = xev->time = GetTimeInMillis();
 | 
						|
	    xv->num_valuators = 0;
 | 
						|
	    xv->first_valuator = 0;
 | 
						|
	    ENQUEUE(xE);
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    /* removed rootX/rootY as DIX sets these fields */
 | 
						|
    if (is_core || is_shared) {
 | 
						|
	xE->u.u.type = is_down ? ButtonPress : ButtonRelease;
 | 
						|
	xE->u.u.detail =  device->button->map[button];
 | 
						|
	xf86Info.lastEventTime = xE->u.keyButtonPointer.time = GetTimeInMillis();
 | 
						|
	
 | 
						|
#ifdef XFreeXDGA
 | 
						|
	if (!DGAStealMouseEvent(xf86EventQueue.pEnqueueScreen->myNum, xE, 0, 0))
 | 
						|
#endif
 | 
						|
	    ENQUEUE(xE);
 | 
						|
    }
 | 
						|
    DBG(5, ErrorF("xf86PostButtonEvent END\n"));
 | 
						|
}
 | 
						|
 | 
						|
_X_EXPORT void
 | 
						|
xf86PostKeyEvent(DeviceIntPtr	device,
 | 
						|
		 unsigned int	key_code,
 | 
						|
		 int		is_down,
 | 
						|
		 int		is_absolute,
 | 
						|
		 int		first_valuator,
 | 
						|
		 int		num_valuators,
 | 
						|
		 ...)
 | 
						|
{
 | 
						|
    va_list			var;
 | 
						|
    int				loop;
 | 
						|
    xEvent			xE[2];
 | 
						|
    deviceKeyButtonPointer	*xev = (deviceKeyButtonPointer*) xE;
 | 
						|
    deviceValuator		*xv = (deviceValuator*) xev+1;
 | 
						|
    
 | 
						|
    va_start(var, num_valuators);
 | 
						|
 | 
						|
    for(loop=0; loop<num_valuators; loop++) {
 | 
						|
	switch (loop % 6) {
 | 
						|
	case 0:
 | 
						|
	    xv->valuator0 = va_arg(var, int);
 | 
						|
	    break;
 | 
						|
	case 1:
 | 
						|
	    xv->valuator1 = va_arg(var, int);
 | 
						|
	    break;
 | 
						|
	case 2:
 | 
						|
	    xv->valuator2 = va_arg(var, int);
 | 
						|
	    break;
 | 
						|
	case 3:
 | 
						|
	    xv->valuator3 = va_arg(var, int);
 | 
						|
	    break;
 | 
						|
	case 4:
 | 
						|
	    xv->valuator4 = va_arg(var, int);
 | 
						|
	    break;
 | 
						|
	case 5:
 | 
						|
	    xv->valuator5 = va_arg(var, int);
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
	if (((loop % 6 == 5) || (loop == num_valuators - 1))) {
 | 
						|
	    xev->type = is_down ? DeviceKeyPress : DeviceKeyRelease;
 | 
						|
	    xev->detail = key_code;
 | 
						|
	    
 | 
						|
	    xf86Info.lastEventTime = xev->time = GetTimeInMillis();
 | 
						|
	    xev->deviceid = device->id | MORE_EVENTS;
 | 
						|
	    
 | 
						|
	    xv->type = DeviceValuator;
 | 
						|
	    xv->deviceid = device->id;
 | 
						|
	    xv->device_state = 0;
 | 
						|
	    /* if the device is in the relative mode we don't have to send valuators */
 | 
						|
	    xv->num_valuators = is_absolute ? (loop % 6) + 1 : 0;
 | 
						|
	    xv->first_valuator = first_valuator + (loop / 6) * 6;
 | 
						|
	    
 | 
						|
	    ENQUEUE(xE);
 | 
						|
	    /* if the device is in the relative mode only one event is needed */
 | 
						|
	    if (!is_absolute) break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    va_end(var);
 | 
						|
}
 | 
						|
 | 
						|
_X_EXPORT void
 | 
						|
xf86PostKeyboardEvent(DeviceIntPtr      device,
 | 
						|
                      unsigned int      key_code,
 | 
						|
                      int               is_down)
 | 
						|
{
 | 
						|
    xEvent                      xE[2];
 | 
						|
    deviceKeyButtonPointer      *xev = (deviceKeyButtonPointer*) xE;
 | 
						|
 | 
						|
    if (xf86IsCoreKeyboard(device)) {
 | 
						|
        xev->type = is_down ? KeyPress : KeyRelease;
 | 
						|
    } else {
 | 
						|
        xev->type = is_down ? DeviceKeyPress : DeviceKeyRelease;
 | 
						|
    }
 | 
						|
    xev->detail = key_code;
 | 
						|
    xf86Info.lastEventTime = xev->time = GetTimeInMillis();
 | 
						|
 | 
						|
#ifdef XFreeXDGA
 | 
						|
    /* if(!DGAStealKeyEvent(xf86EventQueue.pEnqueueScreen->myNum, xE)) */
 | 
						|
#endif
 | 
						|
    ENQUEUE(xE);
 | 
						|
}
 | 
						|
 | 
						|
/* 
 | 
						|
 * Motion history management.
 | 
						|
 */
 | 
						|
 | 
						|
_X_EXPORT void
 | 
						|
xf86MotionHistoryAllocate(LocalDevicePtr	local)
 | 
						|
{
 | 
						|
    ValuatorClassPtr	valuator = local->dev->valuator;
 | 
						|
    
 | 
						|
    if (!HAS_MOTION_HISTORY(local))
 | 
						|
	return;
 | 
						|
    if (local->motion_history) xfree(local->motion_history);
 | 
						|
    local->motion_history = xalloc((sizeof(INT32) * valuator->numAxes + sizeof(Time))
 | 
						|
				   * valuator->numMotionEvents);
 | 
						|
    local->first = 0;
 | 
						|
    local->last	 = 0;
 | 
						|
}
 | 
						|
 | 
						|
_X_EXPORT int
 | 
						|
xf86GetMotionEvents(DeviceIntPtr	dev,
 | 
						|
		    xTimecoord		*buff,
 | 
						|
		    unsigned long	start,
 | 
						|
		    unsigned long	stop,
 | 
						|
		    ScreenPtr		pScreen)
 | 
						|
{
 | 
						|
    LocalDevicePtr	local	 = (LocalDevicePtr)dev->public.devicePrivate;
 | 
						|
    ValuatorClassPtr	valuator = dev->valuator;
 | 
						|
    int			num  	 = 0;
 | 
						|
    int			loop	 = local->first;
 | 
						|
    int			size;
 | 
						|
    Time		current;
 | 
						|
    
 | 
						|
    if (!HAS_MOTION_HISTORY(local))
 | 
						|
	return 0;
 | 
						|
 | 
						|
    size = (sizeof(INT32) * valuator->numAxes + sizeof(Time));
 | 
						|
 | 
						|
    while (loop != local->last) {
 | 
						|
	current = *(Time*)(((char *)local->motion_history)+loop*size);
 | 
						|
	if (current > stop)
 | 
						|
	    return num;
 | 
						|
	if (current >= start) {
 | 
						|
	    memcpy(((char *)buff)+size*num,
 | 
						|
		   ((char *)local->motion_history)+loop*size, size);
 | 
						|
	    num++;
 | 
						|
	}
 | 
						|
	loop = (loop + 1) % valuator->numMotionEvents;
 | 
						|
    }
 | 
						|
    return num;
 | 
						|
}
 | 
						|
 | 
						|
_X_EXPORT LocalDevicePtr
 | 
						|
xf86FirstLocalDevice()
 | 
						|
{
 | 
						|
    return xf86InputDevs;
 | 
						|
}
 | 
						|
 | 
						|
/* 
 | 
						|
 * Cx     - raw data from touch screen
 | 
						|
 * Sxhigh - scaled highest dimension
 | 
						|
 *          (remember, this is of rows - 1 because of 0 origin)
 | 
						|
 * Sxlow  - scaled lowest dimension
 | 
						|
 * Rxhigh - highest raw value from touch screen calibration
 | 
						|
 * Rxlow  - lowest raw value from touch screen calibration
 | 
						|
 *
 | 
						|
 * This function is the same for X or Y coordinates.
 | 
						|
 * You may have to reverse the high and low values to compensate for
 | 
						|
 * different orgins on the touch screen vs X.
 | 
						|
 */
 | 
						|
 | 
						|
_X_EXPORT int
 | 
						|
xf86ScaleAxis(int	Cx,
 | 
						|
	      int	Sxhigh,
 | 
						|
	      int	Sxlow,
 | 
						|
	      int	Rxhigh,
 | 
						|
	      int	Rxlow )
 | 
						|
{
 | 
						|
    int X;
 | 
						|
    int dSx = Sxhigh - Sxlow;
 | 
						|
    int dRx = Rxhigh - Rxlow;
 | 
						|
 | 
						|
    dSx = Sxhigh - Sxlow;
 | 
						|
    if (dRx) {
 | 
						|
	X = ((dSx * (Cx - Rxlow)) / dRx) + Sxlow;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	X = 0;
 | 
						|
	ErrorF ("Divide by Zero in xf86ScaleAxis");
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (X > Sxlow)
 | 
						|
	X = Sxlow;
 | 
						|
    if (X < Sxhigh)
 | 
						|
	X = Sxhigh;
 | 
						|
    
 | 
						|
    return (X);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * This function checks the given screen against the current screen and
 | 
						|
 * makes changes if appropriate. It should be called from an XInput driver's
 | 
						|
 * ReadInput function before any events are posted, if the device is screen
 | 
						|
 * specific like a touch screen.
 | 
						|
 */
 | 
						|
_X_EXPORT void
 | 
						|
xf86XInputSetScreen(LocalDevicePtr	local,
 | 
						|
		    int			screen_number,
 | 
						|
		    int			x,
 | 
						|
		    int			y)
 | 
						|
{
 | 
						|
    if ((xf86IsCorePointer(local->dev) || xf86ShareCorePointer(local->dev)) &&
 | 
						|
	(miPointerCurrentScreen() != screenInfo.screens[screen_number])) {
 | 
						|
	miPointerSetNewScreen (screen_number, x, y);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
_X_EXPORT void
 | 
						|
xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval,
 | 
						|
			   int resolution, int min_res, int max_res)
 | 
						|
{
 | 
						|
#ifdef XINPUT
 | 
						|
    if (maxval == -1) {
 | 
						|
	if (axnum == 0)
 | 
						|
	    maxval = screenInfo.screens[0]->width - 1;
 | 
						|
	else if (axnum == 1)
 | 
						|
	    maxval = screenInfo.screens[0]->height - 1;
 | 
						|
	/* else? */
 | 
						|
    }
 | 
						|
    InitValuatorAxisStruct(dev, axnum, minval, maxval, resolution, min_res,
 | 
						|
			   max_res);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Set the valuator values to be in synch with dix/event.c
 | 
						|
 * DefineInitialRootWindow().
 | 
						|
 */
 | 
						|
_X_EXPORT void
 | 
						|
xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
 | 
						|
{
 | 
						|
#ifdef XINPUT
 | 
						|
    if (axnum == 0)
 | 
						|
	dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
 | 
						|
    else if (axnum == 1)
 | 
						|
	dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/* end of xf86Xinput.c */
 |