2006-10-14 21:14:07 +02:00
|
|
|
/*
|
|
|
|
* Copyright © 2006 Nokia Corporation
|
2007-08-01 00:52:20 +02:00
|
|
|
* Copyright © 2006-2007 Daniel Stone
|
2006-10-19 23:44:46 +02:00
|
|
|
*
|
2007-08-01 00:52:20 +02:00
|
|
|
* 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:
|
2006-10-14 21:14:07 +02:00
|
|
|
*
|
2007-08-01 00:52:20 +02:00
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
* Software.
|
2006-10-14 21:14:07 +02:00
|
|
|
*
|
2007-08-01 00:52:20 +02:00
|
|
|
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
|
2006-10-14 21:14:07 +02:00
|
|
|
*
|
|
|
|
* Author: Daniel Stone <daniel@fooishbar.org>
|
|
|
|
*/
|
2006-11-16 03:21:08 +01:00
|
|
|
/*
|
|
|
|
* MPX additions:
|
|
|
|
* Copyright © 2006 Peter Hutterer
|
|
|
|
* Author: Peter Hutterer <peter@cs.unisa.edu.au>
|
|
|
|
*
|
|
|
|
*/
|
2006-10-14 21:14:07 +02:00
|
|
|
|
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
|
|
#include <dix-config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <X11/X.h>
|
|
|
|
#include <X11/keysym.h>
|
|
|
|
#define NEED_EVENTS
|
|
|
|
#define NEED_REPLIES
|
|
|
|
#include <X11/Xproto.h>
|
2006-11-08 14:24:58 +01:00
|
|
|
|
|
|
|
#include "misc.h"
|
|
|
|
#include "resource.h"
|
2006-10-14 21:14:07 +02:00
|
|
|
#include "inputstr.h"
|
|
|
|
#include "scrnintstr.h"
|
|
|
|
#include "cursorstr.h"
|
|
|
|
#include "dixstruct.h"
|
|
|
|
#include "globals.h"
|
2006-11-07 10:29:51 +01:00
|
|
|
#include "dixevents.h"
|
2006-10-14 21:14:07 +02:00
|
|
|
#include "mipointer.h"
|
|
|
|
|
|
|
|
#ifdef XKB
|
|
|
|
#include <X11/extensions/XKBproto.h>
|
2007-03-18 21:31:19 +01:00
|
|
|
#include <xkbsrv.h>
|
2006-10-14 21:14:07 +02:00
|
|
|
extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies);
|
|
|
|
#endif
|
|
|
|
|
2006-10-23 01:48:30 +02:00
|
|
|
#ifdef PANORAMIX
|
|
|
|
#include "panoramiX.h"
|
|
|
|
#include "panoramiXsrv.h"
|
|
|
|
#endif
|
|
|
|
|
2006-10-23 05:55:21 +02:00
|
|
|
#include <X11/extensions/XI.h>
|
2006-10-14 21:14:07 +02:00
|
|
|
#include <X11/extensions/XIproto.h>
|
|
|
|
#include "exglobals.h"
|
|
|
|
#include "exevents.h"
|
|
|
|
#include "exglobals.h"
|
|
|
|
#include "extnsionst.h"
|
2007-11-09 13:40:24 +01:00
|
|
|
#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
/* Maximum number of valuators, divided by six, rounded up, to get number
|
|
|
|
* of events. */
|
2006-10-14 21:14:07 +02:00
|
|
|
#define MAX_VALUATOR_EVENTS 6
|
|
|
|
|
2006-10-25 00:08:29 +02:00
|
|
|
/* Number of motion history events to store. */
|
|
|
|
#define MOTION_HISTORY_SIZE 256
|
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
|
2006-10-14 21:14:07 +02:00
|
|
|
/**
|
2006-11-08 14:24:58 +01:00
|
|
|
* Pick some arbitrary size for Xi motion history.
|
2006-10-14 21:14:07 +02:00
|
|
|
*/
|
|
|
|
_X_EXPORT int
|
2007-04-09 23:33:15 +02:00
|
|
|
GetMotionHistorySize(void)
|
2006-11-08 14:24:58 +01:00
|
|
|
{
|
|
|
|
return MOTION_HISTORY_SIZE;
|
2006-10-14 21:14:07 +02:00
|
|
|
}
|
|
|
|
|
2007-09-06 02:46:23 +02:00
|
|
|
static void
|
|
|
|
set_key_down(DeviceIntPtr pDev, int key_code)
|
|
|
|
{
|
|
|
|
pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
set_key_up(DeviceIntPtr pDev, int key_code)
|
|
|
|
{
|
|
|
|
pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
key_is_down(DeviceIntPtr pDev, int key_code)
|
|
|
|
{
|
2007-10-25 17:45:50 +02:00
|
|
|
return !!(pDev->key->postdown[key_code >> 3] & (1 << (key_code & 7)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
key_autorepeats(DeviceIntPtr pDev, int key_code)
|
|
|
|
{
|
|
|
|
return !!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] &
|
|
|
|
(1 << (key_code & 7)));
|
2007-09-06 02:46:23 +02:00
|
|
|
}
|
2006-11-08 14:24:58 +01:00
|
|
|
|
2007-11-12 02:05:18 +01:00
|
|
|
void
|
2007-11-09 13:40:24 +01:00
|
|
|
CreateClassesChangedEvent(EventList* event,
|
|
|
|
DeviceIntPtr master,
|
|
|
|
DeviceIntPtr slave)
|
|
|
|
{
|
|
|
|
deviceClassesChangedEvent *dcce;
|
|
|
|
int len = sizeof(xEvent);
|
|
|
|
CARD32 ms = GetTimeInMillis();
|
|
|
|
|
|
|
|
/* XXX: ok, this is a bit weird. We need to alloc enough size for the
|
|
|
|
* event so it can be filled in in POE lateron. Reason being that if
|
|
|
|
* we realloc the event in POE we can get SIGABRT when we try to free
|
|
|
|
* or realloc the original pointer.
|
|
|
|
* We can only do it here as we don't have the EventList in the event
|
|
|
|
* processing any more.
|
|
|
|
*
|
|
|
|
* Code is basically same as in Xi/listdev.c
|
|
|
|
*/
|
|
|
|
if (slave->key)
|
|
|
|
len += sizeof(xKeyInfo);
|
|
|
|
if (slave->button)
|
|
|
|
len += sizeof(xButtonInfo);
|
|
|
|
if (slave->valuator)
|
|
|
|
{
|
|
|
|
int chunks = ((int)slave->valuator->numAxes + 19) / VPC;
|
|
|
|
len += (chunks * sizeof(xValuatorInfo) +
|
|
|
|
slave->valuator->numAxes * sizeof(xAxisInfo));
|
|
|
|
}
|
|
|
|
if (event->evlen < len)
|
|
|
|
{
|
|
|
|
event->event = realloc(event->event, len);
|
|
|
|
if (!event->event)
|
|
|
|
FatalError("[dix] Cannot allocate memory for "
|
|
|
|
"DeviceClassesChangedEvent.\n");
|
|
|
|
event->evlen = len;
|
|
|
|
}
|
|
|
|
|
|
|
|
dcce = (deviceClassesChangedEvent*)event->event;
|
|
|
|
dcce->type = GenericEvent;
|
|
|
|
dcce->extension = IReqCode;
|
|
|
|
dcce->evtype = XI_DeviceClassesChangedNotify;
|
|
|
|
dcce->time = ms;
|
|
|
|
dcce->new_slave = slave->id;
|
|
|
|
dcce->length = (len - sizeof(xEvent))/4;
|
|
|
|
}
|
|
|
|
|
2006-10-14 21:14:07 +02:00
|
|
|
/**
|
2006-11-08 14:24:58 +01:00
|
|
|
* Allocate the motion history buffer.
|
2006-10-14 21:14:07 +02:00
|
|
|
*/
|
2006-11-08 14:24:58 +01:00
|
|
|
_X_EXPORT void
|
|
|
|
AllocateMotionHistory(DeviceIntPtr pDev)
|
|
|
|
{
|
|
|
|
if (pDev->valuator->motion)
|
|
|
|
xfree(pDev->valuator->motion);
|
|
|
|
|
|
|
|
if (pDev->valuator->numMotionEvents < 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pDev->valuator->motion = xalloc(((sizeof(INT32) * pDev->valuator->numAxes) +
|
|
|
|
sizeof(Time)) *
|
|
|
|
pDev->valuator->numMotionEvents);
|
|
|
|
pDev->valuator->first_motion = 0;
|
|
|
|
pDev->valuator->last_motion = 0;
|
2006-10-14 21:14:07 +02:00
|
|
|
}
|
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
|
2006-10-14 21:14:07 +02:00
|
|
|
/**
|
2006-11-08 14:24:58 +01:00
|
|
|
* Dump the motion history between start and stop into the supplied buffer.
|
|
|
|
* Only records the event for a given screen in theory, but in practice, we
|
|
|
|
* sort of ignore this.
|
2006-10-14 21:14:07 +02:00
|
|
|
*/
|
|
|
|
_X_EXPORT int
|
2006-11-08 14:24:58 +01:00
|
|
|
GetMotionHistory(DeviceIntPtr pDev, xTimecoord *buff, unsigned long start,
|
|
|
|
unsigned long stop, ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
char *ibuff = NULL, *obuff = (char *) buff;
|
|
|
|
int i = 0, ret = 0;
|
|
|
|
Time current;
|
|
|
|
/* The size of a single motion event. */
|
|
|
|
int size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
if (!pDev->valuator || !pDev->valuator->numMotionEvents)
|
2006-10-14 21:14:07 +02:00
|
|
|
return 0;
|
2006-10-19 23:44:46 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
for (i = pDev->valuator->first_motion;
|
|
|
|
i != pDev->valuator->last_motion;
|
|
|
|
i = (i + 1) % pDev->valuator->numMotionEvents) {
|
|
|
|
/* We index the input buffer by which element we're accessing, which
|
|
|
|
* is not monotonic, and the output buffer by how many events we've
|
|
|
|
* written so far. */
|
|
|
|
ibuff = (char *) pDev->valuator->motion + (i * size);
|
|
|
|
memcpy(¤t, ibuff, sizeof(Time));
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
if (current > stop) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
else if (current >= start) {
|
|
|
|
memcpy(obuff, ibuff, size);
|
|
|
|
obuff += size;
|
|
|
|
ret++;
|
|
|
|
}
|
|
|
|
}
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
return ret;
|
|
|
|
}
|
2006-10-14 21:14:07 +02:00
|
|
|
|
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
/**
|
|
|
|
* Update the motion history for a specific device, with the list of
|
|
|
|
* valuators.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
|
|
|
|
int num_valuators, int *valuators)
|
|
|
|
{
|
|
|
|
char *buff = (char *) pDev->valuator->motion;
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
if (!pDev->valuator->numMotionEvents)
|
|
|
|
return;
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) *
|
|
|
|
pDev->valuator->last_motion;
|
|
|
|
memcpy(buff, &ms, sizeof(Time));
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
buff += sizeof(Time);
|
|
|
|
bzero(buff, sizeof(INT32) * pDev->valuator->numAxes);
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
buff += sizeof(INT32) * first_valuator;
|
|
|
|
memcpy(buff, valuators, sizeof(INT32) * num_valuators);
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) %
|
|
|
|
pDev->valuator->numMotionEvents;
|
2006-11-08 14:36:47 +01:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
/* If we're wrapping around, just keep the circular buffer going. */
|
|
|
|
if (pDev->valuator->first_motion == pDev->valuator->last_motion)
|
|
|
|
pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) %
|
|
|
|
pDev->valuator->numMotionEvents;
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
return;
|
|
|
|
}
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the maximum number of events GetKeyboardEvents,
|
|
|
|
* GetKeyboardValuatorEvents, and GetPointerEvents will ever return.
|
|
|
|
*
|
|
|
|
* Should be used in DIX as:
|
|
|
|
* xEvent *events = xcalloc(sizeof(xEvent), GetMaximumEventsNum());
|
|
|
|
*/
|
|
|
|
_X_EXPORT int
|
2007-04-09 23:33:15 +02:00
|
|
|
GetMaximumEventsNum(void) {
|
2007-09-28 11:16:41 +02:00
|
|
|
/* Three base events -- raw event and device, plus valuator events.
|
2007-09-27 04:15:03 +02:00
|
|
|
* Multiply by two if we're doing key repeats.
|
|
|
|
*/
|
2007-09-28 11:16:41 +02:00
|
|
|
int ret = 2 + MAX_VALUATOR_EVENTS;
|
2006-11-08 14:24:58 +01:00
|
|
|
|
|
|
|
#ifdef XKB
|
|
|
|
if (noXkbExtension)
|
|
|
|
#endif
|
|
|
|
ret *= 2;
|
|
|
|
|
|
|
|
return ret;
|
2006-10-14 21:14:07 +02:00
|
|
|
}
|
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
|
2006-10-22 23:08:32 +02:00
|
|
|
/* Originally a part of xf86PostMotionEvent; modifies valuators
|
|
|
|
* in-place. */
|
2006-10-14 21:14:07 +02:00
|
|
|
static void
|
|
|
|
acceleratePointer(DeviceIntPtr pDev, int first_valuator, int num_valuators,
|
|
|
|
int *valuators)
|
|
|
|
{
|
|
|
|
float mult = 0.0;
|
|
|
|
int dx = 0, dy = 0;
|
|
|
|
int *px = NULL, *py = NULL;
|
|
|
|
|
|
|
|
if (!num_valuators || !valuators)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (first_valuator == 0) {
|
|
|
|
dx = valuators[0];
|
|
|
|
px = &valuators[0];
|
|
|
|
}
|
|
|
|
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
|
|
|
|
dy = valuators[1 - first_valuator];
|
|
|
|
py = &valuators[1 - first_valuator];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dx && !dy)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) {
|
|
|
|
/* modeled from xf86Events.c */
|
|
|
|
if (pDev->ptrfeed->ctrl.threshold) {
|
|
|
|
if ((abs(dx) + abs(dy)) >= pDev->ptrfeed->ctrl.threshold) {
|
|
|
|
pDev->valuator->dxremaind = ((float)dx *
|
|
|
|
(float)(pDev->ptrfeed->ctrl.num)) /
|
|
|
|
(float)(pDev->ptrfeed->ctrl.den) +
|
|
|
|
pDev->valuator->dxremaind;
|
|
|
|
if (px) {
|
|
|
|
*px = (int)pDev->valuator->dxremaind;
|
|
|
|
pDev->valuator->dxremaind = pDev->valuator->dxremaind -
|
|
|
|
(float)(*px);
|
|
|
|
}
|
|
|
|
|
|
|
|
pDev->valuator->dyremaind = ((float)dy *
|
|
|
|
(float)(pDev->ptrfeed->ctrl.num)) /
|
|
|
|
(float)(pDev->ptrfeed->ctrl.den) +
|
|
|
|
pDev->valuator->dyremaind;
|
|
|
|
if (py) {
|
|
|
|
*py = (int)pDev->valuator->dyremaind;
|
|
|
|
pDev->valuator->dyremaind = pDev->valuator->dyremaind -
|
|
|
|
(float)(*py);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2007-08-23 22:48:19 +02:00
|
|
|
mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
|
2006-10-14 21:14:07 +02:00
|
|
|
((float)(pDev->ptrfeed->ctrl.num) /
|
|
|
|
(float)(pDev->ptrfeed->ctrl.den) - 1.0) /
|
|
|
|
2.0) / 2.0;
|
|
|
|
if (dx) {
|
|
|
|
pDev->valuator->dxremaind = mult * (float)dx +
|
|
|
|
pDev->valuator->dxremaind;
|
|
|
|
*px = (int)pDev->valuator->dxremaind;
|
|
|
|
pDev->valuator->dxremaind = pDev->valuator->dxremaind -
|
|
|
|
(float)(*px);
|
|
|
|
}
|
|
|
|
if (dy) {
|
|
|
|
pDev->valuator->dyremaind = mult * (float)dy +
|
|
|
|
pDev->valuator->dyremaind;
|
|
|
|
*py = (int)pDev->valuator->dyremaind;
|
|
|
|
pDev->valuator->dyremaind = pDev->valuator->dyremaind -
|
|
|
|
(float)(*py);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
|
2006-10-23 05:23:45 +02:00
|
|
|
/**
|
2006-11-08 14:24:58 +01:00
|
|
|
* Clip an axis to its bounds, which are declared in the call to
|
|
|
|
* InitValuatorAxisClassStruct.
|
2006-10-23 05:23:45 +02:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
|
|
|
|
{
|
|
|
|
AxisInfoPtr axes = pDev->valuator->axes + axisNum;
|
|
|
|
|
|
|
|
if (*val < axes->min_value)
|
|
|
|
*val = axes->min_value;
|
|
|
|
if (axes->max_value >= 0 && *val > axes->max_value)
|
|
|
|
*val = axes->max_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2006-11-08 14:24:58 +01:00
|
|
|
* Clip every axis in the list of valuators to its bounds.
|
2006-10-23 05:23:45 +02:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
|
|
|
|
int *valuators)
|
|
|
|
{
|
|
|
|
AxisInfoPtr axes = pDev->valuator->axes + first_valuator;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < num_valuators; i++, axes++)
|
|
|
|
clipAxis(pDev, i + first_valuator, &(valuators[i]));
|
|
|
|
}
|
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
|
2006-10-23 05:23:45 +02:00
|
|
|
/**
|
|
|
|
* Fills events with valuator events for pDev, as given by the other
|
|
|
|
* parameters.
|
2006-11-08 14:24:58 +01:00
|
|
|
*
|
|
|
|
* FIXME: Need to fix ValuatorClassRec to store all the valuators as
|
|
|
|
* last posted, not just x and y; otherwise relative non-x/y
|
|
|
|
* valuators, though a very narrow use case, will be broken.
|
2006-10-23 05:23:45 +02:00
|
|
|
*/
|
2007-05-02 06:20:09 +02:00
|
|
|
static EventList *
|
|
|
|
getValuatorEvents(EventList *events, DeviceIntPtr pDev, int first_valuator,
|
2006-10-23 05:23:45 +02:00
|
|
|
int num_valuators, int *valuators) {
|
2007-05-02 06:20:09 +02:00
|
|
|
deviceValuator *xv;
|
2006-10-23 05:23:45 +02:00
|
|
|
int i = 0, final_valuator = first_valuator + num_valuators;
|
|
|
|
|
2007-05-02 06:20:09 +02:00
|
|
|
for (i = first_valuator; i < final_valuator; i += 6, events++) {
|
|
|
|
xv = (deviceValuator*)events->event;
|
2006-10-23 05:23:45 +02:00
|
|
|
xv->type = DeviceValuator;
|
|
|
|
xv->first_valuator = i;
|
|
|
|
xv->num_valuators = num_valuators;
|
|
|
|
xv->deviceid = pDev->id;
|
|
|
|
switch (final_valuator - i) {
|
|
|
|
case 6:
|
|
|
|
xv->valuator5 = valuators[i + 5];
|
|
|
|
case 5:
|
|
|
|
xv->valuator4 = valuators[i + 4];
|
|
|
|
case 4:
|
|
|
|
xv->valuator3 = valuators[i + 3];
|
|
|
|
case 3:
|
|
|
|
xv->valuator2 = valuators[i + 2];
|
|
|
|
case 2:
|
|
|
|
xv->valuator1 = valuators[i + 1];
|
|
|
|
case 1:
|
|
|
|
xv->valuator0 = valuators[i];
|
|
|
|
}
|
2006-10-27 00:23:58 +02:00
|
|
|
|
|
|
|
if (i + 6 < final_valuator)
|
|
|
|
xv->deviceid |= MORE_EVENTS;
|
2006-10-23 05:23:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return events;
|
|
|
|
}
|
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
|
2006-10-25 00:08:29 +02:00
|
|
|
/**
|
2006-11-08 14:24:58 +01:00
|
|
|
* Convenience wrapper around GetKeyboardValuatorEvents, that takes no
|
|
|
|
* valuators.
|
2006-10-25 00:08:29 +02:00
|
|
|
*/
|
|
|
|
_X_EXPORT int
|
2007-05-02 06:20:09 +02:00
|
|
|
GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) {
|
2006-11-08 14:24:58 +01:00
|
|
|
return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL);
|
2006-10-25 00:08:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2006-11-08 14:24:58 +01:00
|
|
|
* Returns a set of keyboard events for KeyPress/KeyRelease, optionally
|
|
|
|
* also with valuator events. Handles Xi and XKB.
|
|
|
|
*
|
2007-09-28 11:16:41 +02:00
|
|
|
* DOES NOT GENERATE CORE EVENTS! Core events are created when processing the
|
|
|
|
* event (ProcessOtherEvent).
|
|
|
|
*
|
2006-11-08 14:24:58 +01:00
|
|
|
* events is not NULL-terminated; the return value is the number of events.
|
|
|
|
* The DDX is responsible for allocating the event structure in the first
|
|
|
|
* place via GetMaximumEventsNum(), and for freeing it.
|
|
|
|
*
|
|
|
|
* This function does not change the core keymap to that of the device;
|
|
|
|
* that is done by SwitchCoreKeyboard, which is called from
|
|
|
|
* mieqProcessInputEvents. If replacing that function, take care to call
|
|
|
|
* SetCoreKeyboard before processInputProc, so keymaps are altered to suit.
|
|
|
|
*
|
|
|
|
* Note that this function recurses! If called for non-XKB, a repeating
|
|
|
|
* key press will trigger a matching KeyRelease, as well as the
|
|
|
|
* KeyPresses.
|
2006-10-25 00:08:29 +02:00
|
|
|
*/
|
|
|
|
_X_EXPORT int
|
2007-05-02 06:20:09 +02:00
|
|
|
GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
|
2006-11-08 14:24:58 +01:00
|
|
|
int key_code, int first_valuator,
|
|
|
|
int num_valuators, int *valuators) {
|
|
|
|
int numEvents = 0;
|
|
|
|
CARD32 ms = 0;
|
|
|
|
KeySym *map = pDev->key->curKeySyms.map;
|
|
|
|
KeySym sym = map[key_code * pDev->key->curKeySyms.mapWidth];
|
|
|
|
deviceKeyButtonPointer *kbp = NULL;
|
2007-11-09 13:40:24 +01:00
|
|
|
DeviceIntPtr master;
|
2006-10-25 00:08:29 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
if (!events)
|
2006-10-25 00:08:29 +02:00
|
|
|
return 0;
|
|
|
|
|
2007-09-23 11:43:31 +02:00
|
|
|
/* DO NOT WANT */
|
2006-11-08 14:24:58 +01:00
|
|
|
if (type != KeyPress && type != KeyRelease)
|
|
|
|
return 0;
|
2006-10-25 00:08:29 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
if (!pDev->key || !pDev->focus || !pDev->kbdfeed ||
|
|
|
|
(pDev->coreEvents && !inputInfo.keyboard->key))
|
|
|
|
return 0;
|
|
|
|
|
2007-09-28 11:16:41 +02:00
|
|
|
numEvents = 1;
|
2006-11-08 14:24:58 +01:00
|
|
|
|
2007-09-23 11:43:31 +02:00
|
|
|
if (key_code < 8 || key_code > 255)
|
|
|
|
return 0;
|
|
|
|
|
2007-11-09 13:40:24 +01:00
|
|
|
master = pDev->u.master;
|
|
|
|
if (master && master->u.lastSlave != pDev)
|
|
|
|
{
|
|
|
|
CreateClassesChangedEvent(events, master, pDev);
|
|
|
|
|
2007-11-12 03:40:39 +01:00
|
|
|
if (master->valuator && pDev->valuator)
|
|
|
|
{
|
|
|
|
pDev->valuator->lastx = master->valuator->lastx;
|
|
|
|
pDev->valuator->lasty = master->valuator->lasty;
|
|
|
|
}
|
2007-11-09 13:40:24 +01:00
|
|
|
master->u.lastSlave = pDev;
|
|
|
|
numEvents++;
|
|
|
|
events++;
|
|
|
|
}
|
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
if (num_valuators) {
|
|
|
|
if ((num_valuators / 6) + 1 > MAX_VALUATOR_EVENTS)
|
|
|
|
num_valuators = MAX_VALUATOR_EVENTS;
|
|
|
|
numEvents += (num_valuators / 6) + 1;
|
2006-10-25 00:08:29 +02:00
|
|
|
}
|
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
#ifdef XKB
|
|
|
|
if (noXkbExtension)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
switch (sym) {
|
|
|
|
case XK_Num_Lock:
|
|
|
|
case XK_Caps_Lock:
|
|
|
|
case XK_Scroll_Lock:
|
|
|
|
case XK_Shift_Lock:
|
|
|
|
if (type == KeyRelease)
|
|
|
|
return 0;
|
2007-09-06 02:46:23 +02:00
|
|
|
else if (type == KeyPress && key_is_down(pDev, key_code))
|
|
|
|
type = KeyRelease;
|
2006-11-08 14:24:58 +01:00
|
|
|
}
|
|
|
|
}
|
2006-10-25 00:08:29 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
/* Handle core repeating, via press/release/press/release.
|
|
|
|
* FIXME: In theory, if you're repeating with two keyboards in non-XKB,
|
|
|
|
* you could get unbalanced events here. */
|
2007-09-06 02:46:23 +02:00
|
|
|
if (type == KeyPress && key_is_down(pDev, key_code)) {
|
2007-10-25 17:45:50 +02:00
|
|
|
/* If autorepeating is disabled either globally or just for that key,
|
|
|
|
* or we have a modifier, don't generate a repeat event. */
|
2006-11-08 14:24:58 +01:00
|
|
|
if (!pDev->kbdfeed->ctrl.autoRepeat ||
|
2007-10-25 17:45:50 +02:00
|
|
|
!key_autorepeats(pDev, key_code) ||
|
|
|
|
pDev->key->modifierMap[key_code])
|
2006-11-08 14:24:58 +01:00
|
|
|
return 0;
|
2006-10-25 00:08:29 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
#ifdef XKB
|
|
|
|
if (noXkbExtension)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
numEvents += GetKeyboardValuatorEvents(events, pDev,
|
|
|
|
KeyRelease, key_code,
|
|
|
|
first_valuator, num_valuators,
|
|
|
|
valuators);
|
|
|
|
events += numEvents;
|
|
|
|
}
|
|
|
|
}
|
2006-10-25 00:08:29 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
ms = GetTimeInMillis();
|
2006-10-25 00:08:29 +02:00
|
|
|
|
2007-05-02 06:20:09 +02:00
|
|
|
kbp = (deviceKeyButtonPointer *) events->event;
|
2006-11-08 14:24:58 +01:00
|
|
|
kbp->time = ms;
|
|
|
|
kbp->deviceid = pDev->id;
|
2007-06-21 08:17:48 +02:00
|
|
|
kbp->detail = key_code;
|
2007-09-06 02:46:23 +02:00
|
|
|
if (type == KeyPress) {
|
2006-11-08 14:24:58 +01:00
|
|
|
kbp->type = DeviceKeyPress;
|
2007-09-06 02:46:23 +02:00
|
|
|
set_key_down(pDev, key_code);
|
|
|
|
}
|
|
|
|
else if (type == KeyRelease) {
|
2006-11-08 14:24:58 +01:00
|
|
|
kbp->type = DeviceKeyRelease;
|
2007-09-06 02:46:23 +02:00
|
|
|
set_key_up(pDev, key_code);
|
|
|
|
}
|
2006-10-25 00:08:29 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
events++;
|
|
|
|
if (num_valuators) {
|
|
|
|
kbp->deviceid |= MORE_EVENTS;
|
|
|
|
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
|
|
|
events = getValuatorEvents(events, pDev, first_valuator,
|
|
|
|
num_valuators, valuators);
|
|
|
|
}
|
2006-10-25 00:08:29 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
return numEvents;
|
2006-10-25 00:08:29 +02:00
|
|
|
}
|
|
|
|
|
2007-05-02 06:20:09 +02:00
|
|
|
/**
|
|
|
|
* Initialize an event list and fill with 32 byte sized events.
|
|
|
|
* This event list is to be passed into GetPointerEvents() and
|
|
|
|
* GetKeyboardEvents().
|
|
|
|
*
|
|
|
|
* @param num_events Number of elements in list.
|
|
|
|
*/
|
|
|
|
_X_EXPORT EventListPtr
|
|
|
|
InitEventList(int num_events)
|
|
|
|
{
|
|
|
|
EventListPtr events;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
events = (EventListPtr)xcalloc(num_events, sizeof(EventList));
|
|
|
|
if (!events)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (i = 0; i < num_events; i++)
|
|
|
|
{
|
|
|
|
events[i].evlen = sizeof(xEvent);
|
|
|
|
events[i].event = xcalloc(1, sizeof(xEvent));
|
|
|
|
if (!events[i].event)
|
|
|
|
{
|
|
|
|
/* rollback */
|
|
|
|
while(i--)
|
|
|
|
xfree(events[i].event);
|
|
|
|
xfree(events);
|
|
|
|
events = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return events;
|
|
|
|
}
|
2006-11-08 14:24:58 +01:00
|
|
|
|
2006-10-14 21:14:07 +02:00
|
|
|
/**
|
2007-05-02 06:20:09 +02:00
|
|
|
* Free an event list.
|
|
|
|
*
|
|
|
|
* @param list The list to be freed.
|
|
|
|
* @param num_events Number of elements in list.
|
|
|
|
*/
|
|
|
|
_X_EXPORT void
|
|
|
|
FreeEventList(EventListPtr list, int num_events)
|
|
|
|
{
|
|
|
|
if (!list)
|
|
|
|
return;
|
|
|
|
while(num_events--)
|
|
|
|
xfree(list[num_events].event);
|
|
|
|
xfree(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate a series of xEvents (filled into the EventList) representing
|
|
|
|
* pointer motion, or button presses. Xi and XKB-aware.
|
2006-10-14 21:14:07 +02:00
|
|
|
*
|
2007-09-28 11:16:41 +02:00
|
|
|
* DOES NOT GENERATE CORE EVENTS! Core events are created when processing the
|
|
|
|
* event (ProcessOtherEvent).
|
|
|
|
*
|
2006-10-14 21:14:07 +02:00
|
|
|
* events is not NULL-terminated; the return value is the number of events.
|
|
|
|
* The DDX is responsible for allocating the event structure in the first
|
2007-05-02 06:20:09 +02:00
|
|
|
* place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
|
2007-02-05 05:18:48 +01:00
|
|
|
*
|
2006-10-14 21:14:07 +02:00
|
|
|
*/
|
|
|
|
_X_EXPORT int
|
2007-05-02 06:20:09 +02:00
|
|
|
GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
|
2006-10-14 21:14:07 +02:00
|
|
|
int flags, int first_valuator, int num_valuators,
|
|
|
|
int *valuators) {
|
2007-05-02 06:20:09 +02:00
|
|
|
int num_events = 0, final_valuator = 0, i;
|
2006-10-25 00:07:36 +02:00
|
|
|
CARD32 ms = 0;
|
2007-05-02 06:20:09 +02:00
|
|
|
CARD32* valptr;
|
2006-10-14 21:14:07 +02:00
|
|
|
deviceKeyButtonPointer *kbp = NULL;
|
2007-05-02 06:20:09 +02:00
|
|
|
rawDeviceEvent* ev;
|
2007-10-16 10:07:33 +02:00
|
|
|
DeviceIntPtr master;
|
2007-05-02 06:20:09 +02:00
|
|
|
|
2006-12-06 22:18:52 +01:00
|
|
|
/* Thanks to a broken lib, we _always_ have to chase DeviceMotionNotifies
|
|
|
|
* with DeviceValuators. */
|
2006-10-14 21:14:07 +02:00
|
|
|
Bool sendValuators = (type == MotionNotify || flags & POINTER_ABSOLUTE);
|
|
|
|
int x = 0, y = 0;
|
2007-02-14 01:48:43 +01:00
|
|
|
/* The core pointer must not send Xi events. */
|
|
|
|
Bool coreOnly = (pDev == inputInfo.pointer);
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-10-23 05:23:45 +02:00
|
|
|
/* Sanity checks. */
|
2006-10-14 21:14:07 +02:00
|
|
|
if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
|
|
|
|
return 0;
|
|
|
|
|
2006-10-23 05:23:45 +02:00
|
|
|
if ((type == ButtonPress || type == ButtonRelease) && !pDev->button)
|
2006-10-14 21:14:07 +02:00
|
|
|
return 0;
|
2007-10-16 10:07:33 +02:00
|
|
|
|
2007-08-01 00:08:26 +02:00
|
|
|
/* FIXME: I guess it should, in theory, be possible to post button events
|
|
|
|
* from devices without valuators. */
|
|
|
|
if (!pDev->valuator)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (type == MotionNotify && num_valuators <= 0)
|
2006-12-06 22:18:52 +01:00
|
|
|
return 0;
|
|
|
|
|
2007-10-16 10:07:33 +02:00
|
|
|
ms = GetTimeInMillis();
|
|
|
|
|
|
|
|
num_events = 2;
|
|
|
|
|
|
|
|
master = pDev->u.master;
|
|
|
|
if (master && master->u.lastSlave != pDev)
|
|
|
|
{
|
2007-11-09 13:40:24 +01:00
|
|
|
CreateClassesChangedEvent(events, master, pDev);
|
2007-10-16 10:07:33 +02:00
|
|
|
|
|
|
|
pDev->valuator->lastx = master->valuator->lastx;
|
|
|
|
pDev->valuator->lasty = master->valuator->lasty;
|
|
|
|
master->u.lastSlave = pDev;
|
2007-11-09 13:40:24 +01:00
|
|
|
|
|
|
|
num_events++;
|
|
|
|
events++;
|
2007-10-16 10:07:33 +02:00
|
|
|
}
|
|
|
|
|
2006-10-14 21:14:07 +02:00
|
|
|
/* Do we need to send a DeviceValuator event? */
|
2007-02-14 01:56:53 +01:00
|
|
|
if (!coreOnly && sendValuators) {
|
2006-10-23 05:23:45 +02:00
|
|
|
if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS)
|
|
|
|
num_valuators = MAX_VALUATOR_EVENTS * 6;
|
|
|
|
num_events += ((num_valuators - 1) / 6) + 1;
|
2006-10-14 21:14:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
final_valuator = num_valuators + first_valuator;
|
|
|
|
|
2006-10-23 05:23:45 +02:00
|
|
|
/* You fail. */
|
|
|
|
if (first_valuator < 0 || final_valuator > pDev->valuator->numAxes)
|
|
|
|
return 0;
|
|
|
|
|
2007-05-02 06:20:09 +02:00
|
|
|
/* fill up the raw event, after checking that it is large enough to
|
|
|
|
* accommodate all valuators.
|
|
|
|
*/
|
|
|
|
if (events->evlen <
|
|
|
|
(sizeof(xEvent) + ((num_valuators - 4) * sizeof(CARD32))))
|
|
|
|
{
|
|
|
|
events->evlen = sizeof(xEvent) +
|
|
|
|
((num_valuators - 4) * sizeof(CARD32));
|
|
|
|
events->event = realloc(events->event, events->evlen);
|
|
|
|
if (!events->event)
|
|
|
|
FatalError("Could not allocate event storage.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
ev = (rawDeviceEvent*)events->event;
|
|
|
|
ev->type = GenericEvent;
|
|
|
|
ev->evtype = XI_RawDeviceEvent;
|
|
|
|
ev->extension = IReqCode;
|
|
|
|
ev->length = (num_valuators > 4) ? (num_valuators - 4) : 0;
|
2007-05-17 10:29:02 +02:00
|
|
|
ev->event_type = type;
|
2007-05-02 06:20:09 +02:00
|
|
|
ev->buttons = buttons;
|
|
|
|
ev->num_valuators = num_valuators;
|
|
|
|
ev->first_valuator = first_valuator;
|
|
|
|
ev->deviceid = pDev->id;
|
|
|
|
valptr = &(ev->valuator0);
|
|
|
|
for (i = 0; i < num_valuators; i++, valptr++)
|
|
|
|
*valptr = valuators[i];
|
|
|
|
|
|
|
|
events++;
|
2006-11-16 01:25:15 +01:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
/* Set x and y based on whether this is absolute or relative, and
|
|
|
|
* accelerate if we need to. */
|
2006-10-14 21:14:07 +02:00
|
|
|
if (flags & POINTER_ABSOLUTE) {
|
|
|
|
if (num_valuators >= 1 && first_valuator == 0) {
|
|
|
|
x = valuators[0];
|
|
|
|
}
|
|
|
|
else {
|
2007-09-13 16:03:07 +02:00
|
|
|
x = pDev->valuator->lastx;
|
2006-10-14 21:14:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
|
|
|
|
y = valuators[1 - first_valuator];
|
|
|
|
}
|
|
|
|
else {
|
2007-09-13 16:03:07 +02:00
|
|
|
y = pDev->valuator->lasty;
|
2006-10-14 21:14:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (flags & POINTER_ACCELERATE)
|
|
|
|
acceleratePointer(pDev, first_valuator, num_valuators,
|
|
|
|
valuators);
|
|
|
|
|
2006-11-16 01:25:15 +01:00
|
|
|
if (first_valuator == 0 && num_valuators >= 1)
|
2007-09-13 16:03:07 +02:00
|
|
|
x = pDev->valuator->lastx + valuators[0];
|
2006-11-16 01:25:15 +01:00
|
|
|
else
|
2007-09-13 16:03:07 +02:00
|
|
|
x = pDev->valuator->lastx;
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2006-11-16 01:25:15 +01:00
|
|
|
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
|
2007-09-13 16:03:07 +02:00
|
|
|
y = pDev->valuator->lasty + valuators[1 - first_valuator];
|
2006-11-16 01:25:15 +01:00
|
|
|
else
|
2007-09-13 16:03:07 +02:00
|
|
|
y = pDev->valuator->lasty;
|
2006-10-14 21:14:07 +02:00
|
|
|
}
|
|
|
|
|
2006-10-23 05:23:45 +02:00
|
|
|
/* Clip both x and y to the defined limits (usually co-ord space limit). */
|
|
|
|
clipAxis(pDev, 0, &x);
|
|
|
|
clipAxis(pDev, 1, &y);
|
2006-10-14 21:14:07 +02:00
|
|
|
|
|
|
|
/* This takes care of crossing screens for us, as well as clipping
|
|
|
|
* to the current screen. Right now, we only have one history buffer,
|
|
|
|
* so we don't set this for both the device and core.*/
|
|
|
|
miPointerSetPosition(pDev, &x, &y, ms);
|
|
|
|
|
2006-10-23 05:23:45 +02:00
|
|
|
/* Drop x and y back into the valuators list, if they were originally
|
|
|
|
* present. */
|
|
|
|
if (first_valuator == 0 && num_valuators >= 1)
|
|
|
|
valuators[0] = x;
|
|
|
|
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
|
|
|
|
valuators[1 - first_valuator] = y;
|
|
|
|
|
2006-10-25 00:09:19 +02:00
|
|
|
updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
|
|
|
|
|
2006-10-14 21:14:07 +02:00
|
|
|
pDev->valuator->lastx = x;
|
|
|
|
pDev->valuator->lasty = y;
|
2007-11-08 06:14:18 +01:00
|
|
|
if (master)
|
|
|
|
{
|
|
|
|
master->valuator->lastx = x;
|
|
|
|
master->valuator->lasty = y;
|
|
|
|
}
|
2006-10-14 21:14:07 +02:00
|
|
|
|
2007-09-05 08:49:45 +02:00
|
|
|
if (!coreOnly)
|
|
|
|
{
|
2007-05-02 06:20:09 +02:00
|
|
|
kbp = (deviceKeyButtonPointer *) events->event;
|
2007-02-14 01:48:43 +01:00
|
|
|
kbp->time = ms;
|
|
|
|
kbp->deviceid = pDev->id;
|
|
|
|
|
|
|
|
if (type == MotionNotify) {
|
|
|
|
kbp->type = DeviceMotionNotify;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (type == ButtonPress)
|
|
|
|
kbp->type = DeviceButtonPress;
|
|
|
|
else if (type == ButtonRelease)
|
|
|
|
kbp->type = DeviceButtonRelease;
|
|
|
|
kbp->detail = pDev->button->map[buttons];
|
|
|
|
}
|
|
|
|
|
|
|
|
kbp->root_x = x;
|
|
|
|
kbp->root_y = y;
|
|
|
|
|
2007-02-05 05:18:48 +01:00
|
|
|
events++;
|
|
|
|
if (sendValuators) {
|
|
|
|
kbp->deviceid |= MORE_EVENTS;
|
|
|
|
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
|
|
|
events = getValuatorEvents(events, pDev, first_valuator,
|
2007-02-14 07:39:33 +01:00
|
|
|
num_valuators, valuators);
|
2007-02-05 05:18:48 +01:00
|
|
|
}
|
2006-10-14 21:14:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return num_events;
|
|
|
|
}
|
2006-10-19 23:30:28 +02:00
|
|
|
|
2006-11-08 14:24:58 +01:00
|
|
|
|
2006-10-23 05:55:21 +02:00
|
|
|
/**
|
|
|
|
* Post ProximityIn/ProximityOut events, accompanied by valuators.
|
|
|
|
*
|
|
|
|
* events is not NULL-terminated; the return value is the number of events.
|
|
|
|
* The DDX is responsible for allocating the event structure in the first
|
|
|
|
* place via GetMaximumEventsNum(), and for freeing it.
|
|
|
|
*/
|
|
|
|
_X_EXPORT int
|
2007-05-02 06:20:09 +02:00
|
|
|
GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
|
2006-10-23 05:55:21 +02:00
|
|
|
int first_valuator, int num_valuators, int *valuators)
|
|
|
|
{
|
|
|
|
int num_events = 0;
|
2007-05-02 06:20:09 +02:00
|
|
|
deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer *) events->event;
|
2006-10-23 05:55:21 +02:00
|
|
|
|
|
|
|
/* Sanity checks. */
|
|
|
|
if (type != ProximityIn && type != ProximityOut)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!pDev->valuator)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Do we need to send a DeviceValuator event? */
|
|
|
|
if ((pDev->valuator->mode & 1) == Relative)
|
|
|
|
num_valuators = 0;
|
|
|
|
|
|
|
|
if (num_valuators) {
|
|
|
|
if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS)
|
|
|
|
num_valuators = MAX_VALUATOR_EVENTS * 6;
|
|
|
|
num_events += ((num_valuators - 1) / 6) + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* You fail. */
|
|
|
|
if (first_valuator < 0 ||
|
|
|
|
(num_valuators + first_valuator) > pDev->valuator->numAxes)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
kbp->type = type;
|
|
|
|
kbp->deviceid = pDev->id;
|
|
|
|
kbp->detail = 0;
|
|
|
|
kbp->time = GetTimeInMillis();
|
|
|
|
|
|
|
|
if (num_valuators) {
|
|
|
|
kbp->deviceid |= MORE_EVENTS;
|
|
|
|
events++;
|
2006-11-08 14:24:58 +01:00
|
|
|
clipValuators(pDev, first_valuator, num_valuators, valuators);
|
2006-10-23 05:55:21 +02:00
|
|
|
events = getValuatorEvents(events, pDev, first_valuator,
|
|
|
|
num_valuators, valuators);
|
|
|
|
}
|
|
|
|
|
|
|
|
return num_events;
|
|
|
|
}
|
|
|
|
|
2006-10-22 23:08:32 +02:00
|
|
|
/**
|
|
|
|
* Note that pDev was the last function to send a core pointer event.
|
|
|
|
* Currently a no-op.
|
|
|
|
*
|
|
|
|
* Call this just before processInputProc.
|
2006-11-08 14:36:47 +01:00
|
|
|
*/
|
2006-10-22 23:08:32 +02:00
|
|
|
_X_EXPORT void
|
|
|
|
SwitchCorePointer(DeviceIntPtr pDev)
|
2006-10-19 23:30:28 +02:00
|
|
|
{
|
|
|
|
if (inputInfo.pointer->devPrivates[CoreDevicePrivatesIndex].ptr != pDev)
|
|
|
|
inputInfo.pointer->devPrivates[CoreDevicePrivatesIndex].ptr = pDev;
|
|
|
|
}
|
2006-10-23 01:48:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Synthesize a single motion event for the core pointer.
|
|
|
|
*
|
|
|
|
* Used in cursor functions, e.g. when cursor confinement changes, and we need
|
|
|
|
* to shift the pointer to get it inside the new bounds.
|
|
|
|
*/
|
|
|
|
void
|
2006-12-11 08:39:59 +01:00
|
|
|
PostSyntheticMotion(DeviceIntPtr pDev,
|
|
|
|
int x,
|
|
|
|
int y,
|
2006-12-19 01:01:40 +01:00
|
|
|
int screen,
|
2006-12-11 08:39:59 +01:00
|
|
|
unsigned long time)
|
2006-10-23 01:48:30 +02:00
|
|
|
{
|
2006-10-23 05:23:45 +02:00
|
|
|
xEvent xE;
|
2006-10-23 01:48:30 +02:00
|
|
|
|
|
|
|
#ifdef PANORAMIX
|
|
|
|
/* Translate back to the sprite screen since processInputProc
|
|
|
|
will translate from sprite screen to screen 0 upon reentry
|
|
|
|
to the DIX layer. */
|
|
|
|
if (!noPanoramiXExtension) {
|
2006-12-19 01:01:40 +01:00
|
|
|
x += panoramiXdataPtr[0].x - panoramiXdataPtr[screen].x;
|
|
|
|
y += panoramiXdataPtr[0].y - panoramiXdataPtr[screen].y;
|
2006-10-23 01:48:30 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-10-23 05:23:45 +02:00
|
|
|
memset(&xE, 0, sizeof(xEvent));
|
2006-10-23 01:48:30 +02:00
|
|
|
xE.u.u.type = MotionNotify;
|
|
|
|
xE.u.keyButtonPointer.rootX = x;
|
|
|
|
xE.u.keyButtonPointer.rootY = y;
|
2006-11-07 10:29:51 +01:00
|
|
|
xE.u.keyButtonPointer.time = time;
|
2006-10-23 01:48:30 +02:00
|
|
|
|
2006-12-11 08:39:59 +01:00
|
|
|
(*pDev->public.processInputProc)(&xE, pDev, 1);
|
2006-10-23 01:48:30 +02:00
|
|
|
}
|