Merge remote-tracking branch 'whot/next'
This commit is contained in:
commit
f5d50b46dd
|
@ -774,12 +774,9 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
|
|||
|
||||
for (i = 0; i <= last_valuator && i < v->numAxes; i++)
|
||||
{
|
||||
/* XXX: Relative/Absolute mode */
|
||||
if (BitIsOn(&event->valuators.mask, i))
|
||||
{
|
||||
/* XXX: Relative/Absolute mode */
|
||||
v->axisVal[i] = event->valuators.data[i];
|
||||
v->axisVal[i] += (event->valuators.data_frac[i] * 1.0f / (1 << 16) / (1 << 16));
|
||||
}
|
||||
}
|
||||
|
||||
if (event->type == ET_KeyPress) {
|
||||
|
@ -1070,16 +1067,16 @@ InitProximityClassDeviceStruct(DeviceIntPtr dev)
|
|||
*
|
||||
* @see InitValuatorClassDeviceStruct
|
||||
*/
|
||||
void
|
||||
Bool
|
||||
InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
|
||||
int resolution, int min_res, int max_res, int mode)
|
||||
{
|
||||
AxisInfoPtr ax;
|
||||
|
||||
if (!dev || !dev->valuator || minval > maxval)
|
||||
return;
|
||||
if (!dev || !dev->valuator || (minval > maxval && mode == Absolute))
|
||||
return FALSE;
|
||||
if (axnum >= dev->valuator->numAxes)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
ax = dev->valuator->axes + axnum;
|
||||
|
||||
|
@ -1093,6 +1090,57 @@ InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int
|
|||
|
||||
if (mode & OutOfProximity)
|
||||
dev->proximity->in_proximity = FALSE;
|
||||
|
||||
return SetScrollValuator(dev, axnum, SCROLL_TYPE_NONE, 0, SCROLL_FLAG_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given axis number as a scrolling valuator.
|
||||
*/
|
||||
Bool
|
||||
SetScrollValuator(DeviceIntPtr dev, int axnum, enum ScrollType type, double increment, int flags)
|
||||
{
|
||||
AxisInfoPtr ax;
|
||||
int *current_ax;
|
||||
|
||||
if (!dev || !dev->valuator || axnum >= dev->valuator->numAxes)
|
||||
return FALSE;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SCROLL_TYPE_VERTICAL:
|
||||
current_ax = &dev->valuator->v_scroll_axis;
|
||||
break;
|
||||
case SCROLL_TYPE_HORIZONTAL:
|
||||
current_ax = &dev->valuator->h_scroll_axis;
|
||||
break;
|
||||
case SCROLL_TYPE_NONE:
|
||||
ax = &dev->valuator->axes[axnum];
|
||||
ax->scroll.type = type;
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (increment == 0.0)
|
||||
return FALSE;
|
||||
|
||||
if (*current_ax != -1 && axnum != *current_ax)
|
||||
{
|
||||
ax = &dev->valuator->axes[*current_ax];
|
||||
if (ax->scroll.type == type &&
|
||||
(flags & SCROLL_FLAG_PREFERRED) && (ax->scroll.flags & SCROLL_FLAG_PREFERRED))
|
||||
return FALSE;
|
||||
}
|
||||
*current_ax = axnum;
|
||||
|
||||
ax = &dev->valuator->axes[axnum];
|
||||
ax->scroll.type = type;
|
||||
ax->scroll.increment = increment;
|
||||
ax->scroll.flags = flags;
|
||||
/* FIXME: generate DeviceChanged Events */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -52,11 +52,14 @@ static struct dev_properties
|
|||
} dev_properties[] = {
|
||||
{0, XI_PROP_ENABLED},
|
||||
{0, XI_PROP_XTEST_DEVICE},
|
||||
|
||||
{0, XATOM_FLOAT},
|
||||
|
||||
{0, ACCEL_PROP_PROFILE_NUMBER},
|
||||
{0, ACCEL_PROP_CONSTANT_DECELERATION},
|
||||
{0, ACCEL_PROP_ADAPTIVE_DECELERATION},
|
||||
{0, ACCEL_PROP_VELOCITY_SCALING},
|
||||
|
||||
{0, AXIS_LABEL_PROP},
|
||||
{0, AXIS_LABEL_PROP_REL_X},
|
||||
{0, AXIS_LABEL_PROP_REL_Y},
|
||||
|
@ -68,6 +71,8 @@ static struct dev_properties
|
|||
{0, AXIS_LABEL_PROP_REL_DIAL},
|
||||
{0, AXIS_LABEL_PROP_REL_WHEEL},
|
||||
{0, AXIS_LABEL_PROP_REL_MISC},
|
||||
{0, AXIS_LABEL_PROP_REL_VSCROLL},
|
||||
{0, AXIS_LABEL_PROP_REL_HSCROLL},
|
||||
{0, AXIS_LABEL_PROP_ABS_X},
|
||||
{0, AXIS_LABEL_PROP_ABS_Y},
|
||||
{0, AXIS_LABEL_PROP_ABS_Z},
|
||||
|
|
|
@ -229,7 +229,16 @@ SizeDeviceClasses(DeviceIntPtr dev)
|
|||
}
|
||||
|
||||
if (dev->valuator)
|
||||
len += sizeof(xXIValuatorInfo) * dev->valuator->numAxes;
|
||||
{
|
||||
int i;
|
||||
len += (sizeof(xXIValuatorInfo)) * dev->valuator->numAxes;
|
||||
|
||||
for (i = 0; i < dev->valuator->numAxes; i++) {
|
||||
if (dev->valuator->axes[i].scroll.type != SCROLL_TYPE_NONE)
|
||||
len += sizeof(xXIScrollInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return len;
|
||||
}
|
||||
|
@ -369,6 +378,56 @@ SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info)
|
|||
swaps(&info->sourceid);
|
||||
}
|
||||
|
||||
int
|
||||
ListScrollInfo(DeviceIntPtr dev, xXIScrollInfo *info, int axisnumber)
|
||||
{
|
||||
ValuatorClassPtr v = dev->valuator;
|
||||
AxisInfoPtr axis = &v->axes[axisnumber];
|
||||
|
||||
if (axis->scroll.type == SCROLL_TYPE_NONE)
|
||||
return 0;
|
||||
|
||||
info->type = XIScrollClass;
|
||||
info->length = sizeof(xXIScrollInfo)/4;
|
||||
info->number = axisnumber;
|
||||
switch(axis->scroll.type)
|
||||
{
|
||||
case SCROLL_TYPE_VERTICAL:
|
||||
info->scroll_type = XIScrollTypeVertical;
|
||||
break;
|
||||
case SCROLL_TYPE_HORIZONTAL:
|
||||
info->scroll_type = XIScrollTypeHorizontal;
|
||||
break;
|
||||
default:
|
||||
ErrorF("[Xi] Unknown scroll type %d. This is a bug.\n", axis->scroll.type);
|
||||
break;
|
||||
}
|
||||
info->increment.integral = (int)axis->scroll.increment;
|
||||
info->increment.frac = (unsigned int)(axis->scroll.increment * (1UL << 16) * (1UL << 16));
|
||||
info->sourceid = v->sourceid;
|
||||
|
||||
info->flags = 0;
|
||||
|
||||
if (axis->scroll.flags & SCROLL_FLAG_DONT_EMULATE)
|
||||
info->flags |= XIScrollFlagNoEmulation;
|
||||
if (axis->scroll.flags & SCROLL_FLAG_PREFERRED)
|
||||
info->flags |= XIScrollFlagPreferred;
|
||||
|
||||
return info->length * 4;
|
||||
}
|
||||
|
||||
static void
|
||||
SwapScrollInfo(DeviceIntPtr dev, xXIScrollInfo* info)
|
||||
{
|
||||
swaps(&info->type);
|
||||
swaps(&info->length);
|
||||
swaps(&info->number);
|
||||
swaps(&info->sourceid);
|
||||
swaps(&info->scroll_type);
|
||||
swapl(&info->increment.integral);
|
||||
swapl(&info->increment.frac);
|
||||
}
|
||||
|
||||
int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment)
|
||||
{
|
||||
DeviceIntPtr master = GetMaster(dev, MASTER_ATTACHED);
|
||||
|
@ -458,6 +517,15 @@ ListDeviceClasses(ClientPtr client, DeviceIntPtr dev,
|
|||
total_len += len;
|
||||
}
|
||||
|
||||
for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++)
|
||||
{
|
||||
len = ListScrollInfo(dev, (xXIScrollInfo*)any, i);
|
||||
if (len)
|
||||
(*nclasses)++;
|
||||
any += len;
|
||||
total_len += len;
|
||||
}
|
||||
|
||||
return total_len;
|
||||
}
|
||||
|
||||
|
@ -484,6 +552,9 @@ SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
|
|||
case XIValuatorClass:
|
||||
SwapValuatorInfo(dev, (xXIValuatorInfo*)any);
|
||||
break;
|
||||
case XIScrollClass:
|
||||
SwapScrollInfo(dev, (xXIScrollInfo*)any);
|
||||
break;
|
||||
}
|
||||
|
||||
any += len * 4;
|
||||
|
|
|
@ -44,4 +44,5 @@ int ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info, Bool reportState);
|
|||
int ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info);
|
||||
int ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info,
|
||||
int axisnumber, Bool reportState);
|
||||
int ListScrollInfo(DeviceIntPtr dev, xXIScrollInfo* info, int axisnumber);
|
||||
#endif /* QUERYDEV_H */
|
||||
|
|
|
@ -190,8 +190,6 @@ ProcXIWarpPointer(ClientPtr client)
|
|||
/* if we don't update the device, we get a jump next time it moves */
|
||||
pDev->last.valuators[0] = x;
|
||||
pDev->last.valuators[1] = y;
|
||||
pDev->last.remainder[0] = 0;
|
||||
pDev->last.remainder[1] = 0;
|
||||
miPointerUpdateSprite(pDev);
|
||||
|
||||
/* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it
|
||||
|
|
|
@ -778,7 +778,7 @@ WINDOWSWMPROTO="windowswmproto"
|
|||
APPLEWMPROTO="applewmproto >= 1.4"
|
||||
|
||||
dnl Core modules for most extensions, et al.
|
||||
SDK_REQUIRED_MODULES="[xproto >= 7.0.22] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto"
|
||||
SDK_REQUIRED_MODULES="[xproto >= 7.0.22] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 2.0.99.1] [kbproto >= 1.0.3] fontsproto"
|
||||
# Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc
|
||||
AC_SUBST(SDK_REQUIRED_MODULES)
|
||||
|
||||
|
|
|
@ -260,6 +260,8 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
|
|||
offsetof(DeviceIntRec, devPrivates), PRIVATE_DEVICE);
|
||||
if (!dev)
|
||||
return (DeviceIntPtr)NULL;
|
||||
|
||||
dev->last.scroll = NULL;
|
||||
dev->id = devid;
|
||||
dev->public.processInputProc = ProcessOtherEvent;
|
||||
dev->public.realInputProc = ProcessOtherEvent;
|
||||
|
@ -939,6 +941,7 @@ CloseDevice(DeviceIntPtr dev)
|
|||
|
||||
free(dev->deviceGrab.sync.event);
|
||||
free(dev->config_info); /* Allocated in xf86ActivateDevice. */
|
||||
free(dev->last.scroll);
|
||||
dev->config_info = NULL;
|
||||
dixFreeObjectWithPrivates(dev, PRIVATE_DEVICE);
|
||||
}
|
||||
|
@ -1277,10 +1280,19 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
|
|||
if (!valc)
|
||||
return FALSE;
|
||||
|
||||
dev->last.scroll = valuator_mask_new(numAxes);
|
||||
if (!dev->last.scroll)
|
||||
{
|
||||
free(valc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
valc->sourceid = dev->id;
|
||||
valc->motion = NULL;
|
||||
valc->first_motion = 0;
|
||||
valc->last_motion = 0;
|
||||
valc->h_scroll_axis = -1;
|
||||
valc->v_scroll_axis = -1;
|
||||
|
||||
valc->numMotionEvents = numMotionEvents;
|
||||
valc->motionHintWindow = NullWindow;
|
||||
|
|
|
@ -605,6 +605,7 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
|
|||
xde->root_x = FP1616(ev->root_x, ev->root_x_frac);
|
||||
xde->root_y = FP1616(ev->root_y, ev->root_y_frac);
|
||||
|
||||
xde->flags = ev->flags;
|
||||
if (ev->key_repeat)
|
||||
xde->flags |= XIKeyRepeat;
|
||||
|
||||
|
@ -632,8 +633,9 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
|
|||
if (BitIsOn(ev->valuators.mask, i))
|
||||
{
|
||||
SetBit(ptr, i);
|
||||
axisval->integral = ev->valuators.data[i];
|
||||
axisval->frac = ev->valuators.data_frac[i];
|
||||
axisval->integral = trunc(ev->valuators.data[i]);
|
||||
axisval->frac = (ev->valuators.data[i] - axisval->integral) *
|
||||
(1 << 16) * (1 << 16);
|
||||
axisval++;
|
||||
}
|
||||
}
|
||||
|
@ -648,7 +650,7 @@ eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
|
|||
int vallen, nvals;
|
||||
int i, len = sizeof(xXIRawEvent);
|
||||
char *ptr;
|
||||
FP3232 *axisval;
|
||||
FP3232 *axisval, *axisval_raw;
|
||||
|
||||
nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
|
||||
len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once
|
||||
|
@ -666,19 +668,25 @@ eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
|
|||
raw->detail = ev->detail.button;
|
||||
raw->deviceid = ev->deviceid;
|
||||
raw->valuators_len = vallen;
|
||||
raw->flags = ev->flags;
|
||||
|
||||
ptr = (char*)&raw[1];
|
||||
axisval = (FP3232*)(ptr + raw->valuators_len * 4);
|
||||
axisval_raw = axisval + nvals;
|
||||
for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
|
||||
{
|
||||
if (BitIsOn(ev->valuators.mask, i))
|
||||
{
|
||||
SetBit(ptr, i);
|
||||
axisval->integral = ev->valuators.data[i];
|
||||
axisval->frac = ev->valuators.data_frac[i];
|
||||
(axisval + nvals)->integral = ev->valuators.data_raw[i];
|
||||
(axisval + nvals)->frac = ev->valuators.data_raw_frac[i];
|
||||
axisval->integral = trunc(ev->valuators.data[i]);
|
||||
axisval->frac = (ev->valuators.data[i] - axisval->integral) *
|
||||
(1 << 16) * (1 << 16);
|
||||
axisval_raw->integral = trunc(ev->valuators.data_raw[i]);
|
||||
axisval_raw->frac =
|
||||
(ev->valuators.data_raw[i] - axisval_raw->integral) *
|
||||
(1 << 16) * (1 << 16);
|
||||
axisval++;
|
||||
axisval_raw++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
92
dix/events.c
92
dix/events.c
|
@ -2268,33 +2268,93 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
|
|||
return nondeliveries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out raw events for XI 2.0 and XI 2.1 clients.
|
||||
*
|
||||
* If there is a grab on the device, 2.0 clients only get raw events if they
|
||||
* have the grab. 2.1+ clients get raw events in all cases.
|
||||
*
|
||||
* @return TRUE if the event should be discarded, FALSE otherwise.
|
||||
*/
|
||||
static BOOL
|
||||
FilterRawEvents(const ClientPtr client, const GrabPtr grab)
|
||||
{
|
||||
XIClientPtr client_xi_version;
|
||||
int cmp;
|
||||
|
||||
/* device not grabbed -> don't filter */
|
||||
if (!grab)
|
||||
return FALSE;
|
||||
|
||||
client_xi_version = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
|
||||
|
||||
cmp = version_compare(client_xi_version->major_version,
|
||||
client_xi_version->minor_version, 2, 0);
|
||||
/* XI 2.0: if device is grabbed, skip
|
||||
XI 2.1: if device is grabbed by us, skip, we've already delivered */
|
||||
return (cmp == 0) ? TRUE : SameClient(grab, client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deliver a raw event to the grab owner (if any) and to all root windows.
|
||||
*
|
||||
* Raw event delivery differs between XI 2.0 and XI 2.1.
|
||||
* XI 2.0: events delivered to the grabbing client (if any) OR to all root
|
||||
* windows
|
||||
* XI 2.1: events delivered to all root windows, regardless of grabbing
|
||||
* state.
|
||||
*/
|
||||
void
|
||||
DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
|
||||
{
|
||||
GrabPtr grab = device->deviceGrab.grab;
|
||||
xEvent *xi;
|
||||
int i, rc;
|
||||
int filter;
|
||||
|
||||
rc = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
|
||||
if (rc != Success)
|
||||
{
|
||||
ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n",
|
||||
__func__, device->name, rc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (grab)
|
||||
DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE);
|
||||
else { /* deliver to all root windows */
|
||||
xEvent *xi;
|
||||
int i;
|
||||
int filter;
|
||||
|
||||
i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
|
||||
if (i != Success)
|
||||
filter = GetEventFilter(device, xi);
|
||||
|
||||
for (i = 0; i < screenInfo.numScreens; i++)
|
||||
{
|
||||
WindowPtr root;
|
||||
InputClients *inputclients;
|
||||
|
||||
root = screenInfo.screens[i]->root;
|
||||
if (!GetClientsForDelivery(device, root, xi, filter, &inputclients))
|
||||
continue;
|
||||
|
||||
for (; inputclients; inputclients = inputclients->next)
|
||||
{
|
||||
ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n",
|
||||
__func__, device->name, i);
|
||||
return;
|
||||
ClientPtr c; /* unused */
|
||||
Mask m; /* unused */
|
||||
InputClients ic = *inputclients;
|
||||
|
||||
/* Because we run through the list manually, copy the actual
|
||||
* list, shorten the copy to only have one client and then pass
|
||||
* that down to DeliverEventToInputClients. This way we avoid
|
||||
* double events on XI 2.1 clients that have a grab on the
|
||||
* device.
|
||||
*/
|
||||
ic.next = NULL;
|
||||
|
||||
if (!FilterRawEvents(rClient(&ic), grab))
|
||||
DeliverEventToInputClients(device, &ic, root, xi, 1,
|
||||
filter, NULL, &c, &m);
|
||||
}
|
||||
|
||||
filter = GetEventFilter(device, xi);
|
||||
|
||||
for (i = 0; i < screenInfo.numScreens; i++)
|
||||
DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1,
|
||||
filter, NullGrab);
|
||||
free(xi);
|
||||
}
|
||||
|
||||
free(xi);
|
||||
}
|
||||
|
||||
/* If the event goes to dontClient, don't send it and return 0. if
|
||||
|
|
618
dix/getevents.c
618
dix/getevents.c
|
@ -2,6 +2,7 @@
|
|||
* Copyright © 2006 Nokia Corporation
|
||||
* Copyright © 2006-2007 Daniel Stone
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
* Copyright © 2011 The Chromium Authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -58,6 +59,7 @@
|
|||
#endif
|
||||
|
||||
#include <X11/extensions/XI.h>
|
||||
#include <X11/extensions/XI2.h>
|
||||
#include <X11/extensions/XIproto.h>
|
||||
#include <pixman.h>
|
||||
#include "exglobals.h"
|
||||
|
@ -167,7 +169,7 @@ init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail)
|
|||
}
|
||||
|
||||
static void
|
||||
set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, int32_t* data)
|
||||
set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, double* data)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -176,7 +178,7 @@ set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, int32_t* data)
|
|||
if (valuator_mask_isset(mask, i))
|
||||
{
|
||||
SetBit(event->valuators.mask, i);
|
||||
data[i] = valuator_mask_get(mask, i);
|
||||
data[i] = valuator_mask_get_double(mask, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -196,9 +198,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask)
|
|||
SetBit(event->valuators.mask, i);
|
||||
if (valuator_get_mode(dev, i) == Absolute)
|
||||
SetBit(event->valuators.mode, i);
|
||||
event->valuators.data[i] = valuator_mask_get(mask, i);
|
||||
event->valuators.data_frac[i] =
|
||||
dev->last.remainder[i] * (1 << 16) * (1 << 16);
|
||||
event->valuators.data[i] = valuator_mask_get_double(mask, i);
|
||||
}
|
||||
else if (valuator_get_mode(dev, i) == Absolute)
|
||||
event->valuators.data[i] = dev->valuator->axisVal[i];
|
||||
|
@ -255,39 +255,29 @@ CreateClassesChangedEvent(InternalEvent* event,
|
|||
/**
|
||||
* Rescale the coord between the two axis ranges.
|
||||
*/
|
||||
static int
|
||||
rescaleValuatorAxis(int coord, float remainder, float *remainder_return, AxisInfoPtr from, AxisInfoPtr to,
|
||||
int defmax)
|
||||
static double
|
||||
rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to,
|
||||
double defmax)
|
||||
{
|
||||
int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax, coord_return;
|
||||
float value;
|
||||
double fmin = 0.0, fmax = defmax;
|
||||
double tmin = 0.0, tmax = defmax;
|
||||
|
||||
if(from && from->min_value < from->max_value) {
|
||||
if (from && from->min_value < from->max_value) {
|
||||
fmin = from->min_value;
|
||||
fmax = from->max_value;
|
||||
}
|
||||
if(to && to->min_value < to->max_value) {
|
||||
if (to && to->min_value < to->max_value) {
|
||||
tmin = to->min_value;
|
||||
tmax = to->max_value;
|
||||
}
|
||||
|
||||
if(fmin == tmin && fmax == tmax) {
|
||||
if (remainder_return)
|
||||
*remainder_return = remainder;
|
||||
if (fmin == tmin && fmax == tmax)
|
||||
return coord;
|
||||
}
|
||||
|
||||
if(fmax == fmin) { /* avoid division by 0 */
|
||||
if (remainder_return)
|
||||
*remainder_return = 0.0;
|
||||
return 0;
|
||||
}
|
||||
if (fmax == fmin) /* avoid division by 0 */
|
||||
return 0.0;
|
||||
|
||||
value = (coord + remainder - fmin) * (tmax - tmin) / (fmax - fmin) + tmin;
|
||||
coord_return = lroundf(value);
|
||||
if (remainder_return)
|
||||
*remainder_return = value - coord_return;
|
||||
return coord_return;
|
||||
return (coord - fmin) * (tmax - tmin) / (fmax - fmin) + tmin;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -309,19 +299,25 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
|
|||
* position of the pointer */
|
||||
pDev->last.valuators[0] = master->last.valuators[0];
|
||||
pDev->last.valuators[1] = master->last.valuators[1];
|
||||
pDev->last.remainder[0] = master->last.remainder[0];
|
||||
pDev->last.remainder[1] = master->last.remainder[1];
|
||||
|
||||
if (!pDev->valuator)
|
||||
return;
|
||||
|
||||
/* scale back to device coordinates */
|
||||
if(pDev->valuator->numAxes > 0)
|
||||
pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], pDev->last.remainder[0],
|
||||
&pDev->last.remainder[0], NULL, pDev->valuator->axes + 0, scr->width);
|
||||
{
|
||||
pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0],
|
||||
NULL,
|
||||
pDev->valuator->axes + 0,
|
||||
scr->width);
|
||||
}
|
||||
if(pDev->valuator->numAxes > 1)
|
||||
pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], pDev->last.remainder[1],
|
||||
&pDev->last.remainder[1], NULL, pDev->valuator->axes + 1, scr->height);
|
||||
{
|
||||
pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1],
|
||||
NULL,
|
||||
pDev->valuator->axes + 1,
|
||||
scr->height);
|
||||
}
|
||||
|
||||
/* calculate the other axis as well based on info from the old
|
||||
* slave-device. If the old slave had less axes than this one,
|
||||
|
@ -332,16 +328,13 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
|
|||
if (i >= lastSlave->valuator->numAxes)
|
||||
{
|
||||
pDev->last.valuators[i] = 0;
|
||||
pDev->last.remainder[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDev->last.valuators[i] =
|
||||
rescaleValuatorAxis(pDev->last.valuators[i],
|
||||
pDev->last.remainder[i],
|
||||
&pDev->last.remainder[i],
|
||||
lastSlave->valuator->axes + i,
|
||||
pDev->valuator->axes + i, 0);
|
||||
double val = pDev->last.valuators[i];
|
||||
val = rescaleValuatorAxis(val, lastSlave->valuator->axes + i,
|
||||
pDev->valuator->axes + i, 0);
|
||||
pDev->last.valuators[i] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -452,7 +445,7 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
|
|||
/* scale to screen coords */
|
||||
to = &core_axis;
|
||||
to->max_value = pScreen->width;
|
||||
coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->width);
|
||||
coord = rescaleValuatorAxis(coord, &from, to, pScreen->width);
|
||||
|
||||
memcpy(corebuf, &coord, sizeof(INT16));
|
||||
corebuf++;
|
||||
|
@ -463,7 +456,7 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
|
|||
memcpy(&coord, icbuf++, sizeof(INT32));
|
||||
|
||||
to->max_value = pScreen->height;
|
||||
coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->height);
|
||||
coord = rescaleValuatorAxis(coord, &from, to, pScreen->height);
|
||||
memcpy(corebuf, &coord, sizeof(INT16));
|
||||
|
||||
} else if (IsMaster(pDev))
|
||||
|
@ -491,7 +484,7 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
|
|||
from.max_value = pScreen->height;
|
||||
|
||||
/* scale from stored range into current range */
|
||||
coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, 0);
|
||||
coord = rescaleValuatorAxis(coord, &from, to, 0);
|
||||
memcpy(ocbuf, &coord, sizeof(INT32));
|
||||
ocbuf++;
|
||||
}
|
||||
|
@ -525,7 +518,7 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
|
|||
*/
|
||||
static void
|
||||
updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
|
||||
int *valuators)
|
||||
double *valuators)
|
||||
{
|
||||
char *buff = (char *) pDev->valuator->motion;
|
||||
ValuatorClassPtr v;
|
||||
|
@ -547,6 +540,7 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
|
|||
|
||||
for (i = 0; i < v->numAxes; i++)
|
||||
{
|
||||
int val;
|
||||
/* XI1 doesn't support mixed mode devices */
|
||||
if (valuator_get_mode(pDev, i) != valuator_get_mode(pDev, 0))
|
||||
break;
|
||||
|
@ -559,7 +553,8 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
|
|||
buff += sizeof(INT32);
|
||||
memcpy(buff, &v->axes[i].max_value, sizeof(INT32));
|
||||
buff += sizeof(INT32);
|
||||
memcpy(buff, &valuators[i], sizeof(INT32));
|
||||
val = valuators[i];
|
||||
memcpy(buff, &val, sizeof(INT32));
|
||||
buff += sizeof(INT32);
|
||||
}
|
||||
} else
|
||||
|
@ -575,12 +570,14 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
|
|||
|
||||
for (i = 0; i < MAX_VALUATORS; i++)
|
||||
{
|
||||
int val;
|
||||
if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i))
|
||||
{
|
||||
buff += sizeof(INT32);
|
||||
continue;
|
||||
}
|
||||
memcpy(buff, &valuators[i], sizeof(INT32));
|
||||
val = valuators[i];
|
||||
memcpy(buff, &val, sizeof(INT32));
|
||||
buff += sizeof(INT32);
|
||||
}
|
||||
}
|
||||
|
@ -607,8 +604,10 @@ GetMaximumEventsNum(void) {
|
|||
/* One raw event
|
||||
* One device event
|
||||
* One possible device changed event
|
||||
* Lots of possible separate button scroll events (horiz + vert)
|
||||
* Lots of possible separate raw button scroll events (horiz + vert)
|
||||
*/
|
||||
return 3;
|
||||
return 100;
|
||||
}
|
||||
|
||||
|
||||
|
@ -617,7 +616,7 @@ GetMaximumEventsNum(void) {
|
|||
* InitValuatorAxisClassStruct.
|
||||
*/
|
||||
static void
|
||||
clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
|
||||
clipAxis(DeviceIntPtr pDev, int axisNum, double *val)
|
||||
{
|
||||
AxisInfoPtr axis;
|
||||
|
||||
|
@ -647,9 +646,9 @@ clipValuators(DeviceIntPtr pDev, ValuatorMask *mask)
|
|||
for (i = 0; i < valuator_mask_size(mask); i++)
|
||||
if (valuator_mask_isset(mask, i))
|
||||
{
|
||||
int val = valuator_mask_get(mask, i);
|
||||
double val = valuator_mask_get_double(mask, i);
|
||||
clipAxis(pDev, i, &val);
|
||||
valuator_mask_set(mask, i, val);
|
||||
valuator_mask_set_double(mask, i, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -690,85 +689,52 @@ UpdateFromMaster(InternalEvent* events, DeviceIntPtr dev, int type, int *num_eve
|
|||
/**
|
||||
* Move the device's pointer to the position given in the valuators.
|
||||
*
|
||||
* @param dev The device which's pointer is to be moved.
|
||||
* @param x Returns the x position of the pointer after the move.
|
||||
* @param y Returns the y position of the pointer after the move.
|
||||
* @param mask Bit mask of valid valuators.
|
||||
* @param valuators Valuator data for each axis between @first and
|
||||
* @first+@num.
|
||||
* @param dev The device whose pointer is to be moved.
|
||||
* @param mask Valuator data for this event.
|
||||
*/
|
||||
static void
|
||||
moveAbsolute(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
|
||||
moveAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (valuator_mask_isset(mask, 0))
|
||||
*x = valuator_mask_get(mask, 0);
|
||||
else
|
||||
*x = dev->last.valuators[0];
|
||||
|
||||
if (valuator_mask_isset(mask, 1))
|
||||
*y = valuator_mask_get(mask, 1);
|
||||
else
|
||||
*y = dev->last.valuators[1];
|
||||
|
||||
clipAxis(dev, 0, x);
|
||||
clipAxis(dev, 1, y);
|
||||
|
||||
for (i = 2; i < valuator_mask_size(mask); i++)
|
||||
for (i = 0; i < valuator_mask_size(mask); i++)
|
||||
{
|
||||
if (valuator_mask_isset(mask, i))
|
||||
{
|
||||
dev->last.valuators[i] = valuator_mask_get(mask, i);
|
||||
clipAxis(dev, i, &dev->last.valuators[i]);
|
||||
}
|
||||
double val;
|
||||
|
||||
if (!valuator_mask_isset(mask, i))
|
||||
continue;
|
||||
val = valuator_mask_get_double(mask, i);
|
||||
clipAxis(dev, i, &val);
|
||||
valuator_mask_set_double(mask, i, val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the device's pointer by the values given in @valuators.
|
||||
*
|
||||
* @param dev The device which's pointer is to be moved.
|
||||
* @param x Returns the x position of the pointer after the move.
|
||||
* @param y Returns the y position of the pointer after the move.
|
||||
* @param mask Bit mask of valid valuators.
|
||||
* @param valuators Valuator data for each axis between @first and
|
||||
* @first+@num.
|
||||
* @param dev The device whose pointer is to be moved.
|
||||
* @param mask Valuator data for this event.
|
||||
*/
|
||||
static void
|
||||
moveRelative(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
|
||||
moveRelative(DeviceIntPtr dev, ValuatorMask *mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
*x = dev->last.valuators[0];
|
||||
*y = dev->last.valuators[1];
|
||||
|
||||
if (valuator_mask_isset(mask, 0))
|
||||
*x += valuator_mask_get(mask, 0);
|
||||
|
||||
if (valuator_mask_isset(mask, 1))
|
||||
*y += valuator_mask_get(mask, 1);
|
||||
|
||||
/* if attached, clip both x and y to the defined limits (usually
|
||||
* co-ord space limit). If it is attached, we need x/y to go over the
|
||||
* limits to be able to change screens. */
|
||||
if (dev->valuator && (IsMaster(dev) || !IsFloating(dev))) {
|
||||
if (valuator_get_mode(dev, 0) == Absolute)
|
||||
clipAxis(dev, 0, x);
|
||||
if (valuator_get_mode(dev, 1) == Absolute)
|
||||
clipAxis(dev, 1, y);
|
||||
}
|
||||
Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
|
||||
|
||||
/* calc other axes, clip, drop back into valuators */
|
||||
for (i = 2; i < valuator_mask_size(mask); i++)
|
||||
for (i = 0; i < valuator_mask_size(mask); i++)
|
||||
{
|
||||
if (valuator_mask_isset(mask, i))
|
||||
{
|
||||
dev->last.valuators[i] += valuator_mask_get(mask, i);
|
||||
if (valuator_get_mode(dev, i) == Absolute)
|
||||
clipAxis(dev, i, &dev->last.valuators[i]);
|
||||
valuator_mask_set(mask, i, dev->last.valuators[i]);
|
||||
}
|
||||
double val = dev->last.valuators[i];
|
||||
|
||||
if (!valuator_mask_isset(mask, i))
|
||||
continue;
|
||||
val += valuator_mask_get_double(mask, i);
|
||||
/* x & y need to go over the limits to cross screens if the SD
|
||||
* isn't currently attached; otherwise, clip to screen bounds. */
|
||||
if (valuator_get_mode(dev, i) == Absolute &&
|
||||
((i != 0 && i != 1) || clip_xy))
|
||||
clipAxis(dev, i, &val);
|
||||
valuator_mask_set_double(mask, i, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -799,89 +765,68 @@ accelPointer(DeviceIntPtr dev, ValuatorMask* valuators, CARD32 ms)
|
|||
*
|
||||
* @param dev The device to be moved.
|
||||
* @param mode Movement mode (Absolute or Relative)
|
||||
* @param x Pointer to current x-axis value, may be modified.
|
||||
* @param y Pointer to current y-axis value, may be modified.
|
||||
* @param x_frac Fractional part of current x-axis value, may be modified.
|
||||
* @param y_frac Fractional part of current y-axis value, may be modified.
|
||||
* @param scr Screen the device's sprite is currently on.
|
||||
* @param mask Mask of axis values for this event
|
||||
* @param screenx Screen x coordinate the sprite is on after the update.
|
||||
* @param screeny Screen y coordinate the sprite is on after the update.
|
||||
* @param screenx_frac Fractional part of screen x coordinate, as above.
|
||||
* @param screeny_frac Fractional part of screen y coordinate, as above.
|
||||
*/
|
||||
static void
|
||||
positionSprite(DeviceIntPtr dev, int mode,
|
||||
int *x, int *y, float x_frac, float y_frac,
|
||||
ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac)
|
||||
positionSprite(DeviceIntPtr dev, int mode, ScreenPtr scr, ValuatorMask *mask,
|
||||
double *screenx, double *screeny)
|
||||
{
|
||||
int old_screenx, old_screeny;
|
||||
int isx, isy; /* screen {x, y}, in int */
|
||||
double x, y;
|
||||
|
||||
if (!dev->valuator || dev->valuator->numAxes < 2)
|
||||
return;
|
||||
|
||||
if (valuator_mask_isset(mask, 0))
|
||||
x = valuator_mask_get_double(mask, 0);
|
||||
else
|
||||
x = dev->last.valuators[0];
|
||||
if (valuator_mask_isset(mask, 1))
|
||||
y = valuator_mask_get_double(mask, 1);
|
||||
else
|
||||
y = dev->last.valuators[1];
|
||||
|
||||
/* scale x&y to screen */
|
||||
if (dev->valuator && dev->valuator->numAxes > 0) {
|
||||
*screenx = rescaleValuatorAxis(*x, x_frac, screenx_frac,
|
||||
dev->valuator->axes + 0, NULL, scr->width);
|
||||
} else {
|
||||
*screenx = dev->last.valuators[0];
|
||||
*screenx_frac = dev->last.remainder[0];
|
||||
}
|
||||
*screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL,
|
||||
scr->width);
|
||||
*screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL,
|
||||
scr->height);
|
||||
|
||||
if (dev->valuator && dev->valuator->numAxes > 1) {
|
||||
*screeny = rescaleValuatorAxis(*y, y_frac, screeny_frac,
|
||||
dev->valuator->axes + 1, NULL, scr->height);
|
||||
} else {
|
||||
*screeny = dev->last.valuators[1];
|
||||
*screeny_frac = dev->last.remainder[1];
|
||||
}
|
||||
|
||||
/* Hit the left screen edge? */
|
||||
if (*screenx <= 0 && *screenx_frac < 0.0f)
|
||||
/* miPointerSetPosition takes care of crossing screens for us, as well as
|
||||
* clipping to the current screen. In the event we actually change screen,
|
||||
* we just drop the float component on the floor, then convert from
|
||||
* screenx back into device co-ordinates. */
|
||||
isx = trunc(*screenx);
|
||||
isy = trunc(*screeny);
|
||||
miPointerSetPosition(dev, mode, &isx, &isy);
|
||||
scr = miPointerGetScreen(dev);
|
||||
if (isx != trunc(*screenx))
|
||||
{
|
||||
*screenx_frac = 0.0f;
|
||||
x_frac = 0.0f;
|
||||
*screenx -= trunc(*screenx) - isx;
|
||||
x = rescaleValuatorAxis(*screenx, NULL, dev->valuator->axes + 0,
|
||||
scr->width);
|
||||
}
|
||||
if (*screeny <= 0 && *screeny_frac < 0.0f)
|
||||
if (isy != trunc(*screeny))
|
||||
{
|
||||
*screeny_frac = 0.0f;
|
||||
y_frac = 0.0f;
|
||||
*screeny -= trunc(*screeny) - isy;
|
||||
y = rescaleValuatorAxis(*screeny, NULL, dev->valuator->axes + 1,
|
||||
scr->height);
|
||||
}
|
||||
|
||||
|
||||
old_screenx = *screenx;
|
||||
old_screeny = *screeny;
|
||||
/* This takes care of crossing screens for us, as well as clipping
|
||||
* to the current screen. */
|
||||
miPointerSetPosition(dev, mode, screenx, screeny);
|
||||
|
||||
if(!IsMaster(dev) && !IsFloating(dev)) {
|
||||
/* Update the MD's co-ordinates, which are always in screen space. */
|
||||
if (!IsMaster(dev) || !IsFloating(dev)) {
|
||||
DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
|
||||
master->last.valuators[0] = *screenx;
|
||||
master->last.valuators[1] = *screeny;
|
||||
master->last.remainder[0] = *screenx_frac;
|
||||
master->last.remainder[1] = *screeny_frac;
|
||||
}
|
||||
|
||||
if (dev->valuator)
|
||||
{
|
||||
/* Crossed screen? Scale back to device coordiantes */
|
||||
if(*screenx != old_screenx)
|
||||
{
|
||||
scr = miPointerGetScreen(dev);
|
||||
*x = rescaleValuatorAxis(*screenx, *screenx_frac, &x_frac, NULL,
|
||||
dev->valuator->axes + 0, scr->width);
|
||||
}
|
||||
if(*screeny != old_screeny)
|
||||
{
|
||||
scr = miPointerGetScreen(dev);
|
||||
*y = rescaleValuatorAxis(*screeny, *screeny_frac, &y_frac, NULL,
|
||||
dev->valuator->axes + 1, scr->height);
|
||||
}
|
||||
}
|
||||
|
||||
/* dropy x/y (device coordinates) back into valuators for next event */
|
||||
dev->last.valuators[0] = *x;
|
||||
dev->last.valuators[1] = *y;
|
||||
dev->last.remainder[0] = x_frac;
|
||||
dev->last.remainder[1] = y_frac;
|
||||
if (valuator_mask_isset(mask, 0))
|
||||
valuator_mask_set_double(mask, 0, x);
|
||||
if (valuator_mask_isset(mask, 1))
|
||||
valuator_mask_set_double(mask, 1, y);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1045,32 +990,37 @@ FreeEventList(InternalEvent *list, int num_events)
|
|||
* back into x/y.
|
||||
*/
|
||||
static void
|
||||
transform(struct pixman_f_transform *m, int *x, int *y)
|
||||
transform(struct pixman_f_transform *m, double *x, double *y)
|
||||
{
|
||||
struct pixman_f_vector p = {.v = {*x, *y, 1}};
|
||||
pixman_f_transform_point(m, &p);
|
||||
|
||||
*x = lround(p.v[0]);
|
||||
*y = lround(p.v[1]);
|
||||
*x = p.v[0];
|
||||
*y = p.v[1];
|
||||
}
|
||||
|
||||
static void
|
||||
transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
|
||||
{
|
||||
int x, y, ox, oy;
|
||||
double x, y, ox, oy;
|
||||
|
||||
ox = x = valuator_mask_isset(mask, 0) ? valuator_mask_get(mask, 0) :
|
||||
dev->last.valuators[0];
|
||||
oy = y = valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) :
|
||||
dev->last.valuators[1];
|
||||
if (valuator_mask_isset(mask, 0))
|
||||
ox = x = valuator_mask_get_double(mask, 0);
|
||||
else
|
||||
ox = x = dev->last.valuators[0];
|
||||
|
||||
if (valuator_mask_isset(mask, 1))
|
||||
oy = y = valuator_mask_get_double(mask, 1);
|
||||
else
|
||||
oy = y = dev->last.valuators[1];
|
||||
|
||||
transform(&dev->transform, &x, &y);
|
||||
|
||||
if (valuator_mask_isset(mask, 0) || ox != x)
|
||||
valuator_mask_set(mask, 0, x);
|
||||
valuator_mask_set_double(mask, 0, x);
|
||||
|
||||
if (valuator_mask_isset(mask, 1) || oy != y)
|
||||
valuator_mask_set(mask, 1, y);
|
||||
valuator_mask_set_double(mask, 1, y);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1097,42 +1047,25 @@ QueuePointerEvents(DeviceIntPtr device, int type,
|
|||
}
|
||||
|
||||
/**
|
||||
* Generate a series of InternalEvents representing pointer motion, or
|
||||
* button presses.
|
||||
* Helper function for GetPointerEvents, which only generates motion and
|
||||
* raw motion events for the slave device: does not update the master device.
|
||||
*
|
||||
* The DDX is responsible for allocating the events in the first
|
||||
* place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
|
||||
*
|
||||
* In the generated events rootX/Y will be in absolute screen coords and
|
||||
* the valuator information in the absolute or relative device coords.
|
||||
*
|
||||
* last.valuators[x] of the device is always in absolute device coords.
|
||||
* last.valuators[x] of the master device is in absolute screen coords.
|
||||
*
|
||||
* master->last.valuators[x] for x > 2 is undefined.
|
||||
* Should not be called by anyone other than GetPointerEvents.
|
||||
*
|
||||
* @return the number of events written into events.
|
||||
*/
|
||||
int
|
||||
GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons,
|
||||
int flags, const ValuatorMask *mask_in) {
|
||||
int num_events = 1;
|
||||
CARD32 ms;
|
||||
static int
|
||||
fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
|
||||
int buttons, CARD32 ms, int flags,
|
||||
const ValuatorMask *mask_in)
|
||||
{
|
||||
int num_events = 1, i;
|
||||
DeviceEvent *event;
|
||||
RawDeviceEvent *raw;
|
||||
int x = 0, y = 0, /* device coords */
|
||||
cx, cy; /* only screen coordinates */
|
||||
float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac;
|
||||
RawDeviceEvent *raw;
|
||||
double screenx = 0.0, screeny = 0.0;
|
||||
ScreenPtr scr = miPointerGetScreen(pDev);
|
||||
ValuatorMask mask;
|
||||
|
||||
/* refuse events from disabled devices */
|
||||
if (!pDev->enabled)
|
||||
return 0;
|
||||
|
||||
if (!scr)
|
||||
return 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MotionNotify:
|
||||
|
@ -1148,10 +1081,6 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons
|
|||
return 0;
|
||||
}
|
||||
|
||||
ms = GetTimeInMillis(); /* before pointer update to help precision */
|
||||
|
||||
events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
|
||||
|
||||
valuator_mask_copy(&mask, mask_in);
|
||||
|
||||
if ((flags & POINTER_NORAW) == 0)
|
||||
|
@ -1161,61 +1090,54 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons
|
|||
num_events++;
|
||||
|
||||
init_raw(pDev, raw, ms, type, buttons);
|
||||
set_raw_valuators(raw, &mask, raw->valuators.data_raw);
|
||||
set_raw_valuators(raw, &mask, raw->valuators.data_raw);
|
||||
}
|
||||
|
||||
if (flags & POINTER_ABSOLUTE)
|
||||
{
|
||||
if (flags & POINTER_SCREEN) /* valuators are in screen coords */
|
||||
{
|
||||
int scaled;
|
||||
double scaled;
|
||||
|
||||
if (valuator_mask_isset(&mask, 0))
|
||||
{
|
||||
scaled = rescaleValuatorAxis(valuator_mask_get(&mask, 0),
|
||||
0.0, &x_frac, NULL,
|
||||
pDev->valuator->axes + 0,
|
||||
scaled = rescaleValuatorAxis(valuator_mask_get_double(&mask, 0),
|
||||
NULL, pDev->valuator->axes + 0,
|
||||
scr->width);
|
||||
valuator_mask_set(&mask, 0, scaled);
|
||||
valuator_mask_set_double(&mask, 0, scaled);
|
||||
}
|
||||
if (valuator_mask_isset(&mask, 1))
|
||||
{
|
||||
scaled = rescaleValuatorAxis(valuator_mask_get(&mask, 1),
|
||||
0.0, &y_frac, NULL,
|
||||
pDev->valuator->axes + 1,
|
||||
scaled = rescaleValuatorAxis(valuator_mask_get_double(&mask, 1),
|
||||
NULL, pDev->valuator->axes + 1,
|
||||
scr->height);
|
||||
valuator_mask_set(&mask, 1, scaled);
|
||||
valuator_mask_set_double(&mask, 1, scaled);
|
||||
}
|
||||
}
|
||||
|
||||
transformAbsolute(pDev, &mask);
|
||||
moveAbsolute(pDev, &x, &y, &mask);
|
||||
moveAbsolute(pDev, &mask);
|
||||
} else {
|
||||
if (flags & POINTER_ACCELERATE) {
|
||||
if (flags & POINTER_ACCELERATE)
|
||||
accelPointer(pDev, &mask, ms);
|
||||
/* The pointer acceleration code modifies the fractional part
|
||||
* in-place, so we need to extract this information first */
|
||||
x_frac = pDev->last.remainder[0];
|
||||
y_frac = pDev->last.remainder[1];
|
||||
}
|
||||
moveRelative(pDev, &x, &y, &mask);
|
||||
moveRelative(pDev, &mask);
|
||||
}
|
||||
|
||||
if ((flags & POINTER_NORAW) == 0)
|
||||
set_raw_valuators(raw, &mask, raw->valuators.data);
|
||||
set_raw_valuators(raw, &mask, raw->valuators.data);
|
||||
|
||||
positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
|
||||
&x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
|
||||
positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative, scr,
|
||||
&mask, &screenx, &screeny);
|
||||
updateHistory(pDev, &mask, ms);
|
||||
|
||||
/* Update the valuators with the true value sent to the client*/
|
||||
if (valuator_mask_isset(&mask, 0))
|
||||
valuator_mask_set(&mask, 0, x);
|
||||
if (valuator_mask_isset(&mask, 1))
|
||||
valuator_mask_set(&mask, 1, y);
|
||||
|
||||
clipValuators(pDev, &mask);
|
||||
|
||||
for (i = 0; i < valuator_mask_size(&mask); i++)
|
||||
{
|
||||
if (valuator_mask_isset(&mask, i))
|
||||
pDev->last.valuators[i] = valuator_mask_get_double(&mask, i);
|
||||
}
|
||||
|
||||
event = &events->device_event;
|
||||
init_device_event(event, pDev, ms);
|
||||
|
||||
|
@ -1235,16 +1157,220 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons
|
|||
event->detail.button = buttons;
|
||||
}
|
||||
|
||||
event->root_x = cx; /* root_x/y always in screen coords */
|
||||
event->root_y = cy;
|
||||
event->root_x_frac = cx_frac;
|
||||
event->root_y_frac = cy_frac;
|
||||
/* root_x and root_y must be in screen co-ordinates */
|
||||
event->root_x = trunc(screenx);
|
||||
event->root_y = trunc(screeny);
|
||||
event->root_x_frac = screenx - trunc(screenx);
|
||||
event->root_y_frac = screeny - trunc(screeny);
|
||||
|
||||
if (flags & POINTER_EMULATED) {
|
||||
raw->flags = XIPointerEmulated;
|
||||
event->flags = XIPointerEmulated;
|
||||
}
|
||||
|
||||
set_valuators(pDev, event, &mask);
|
||||
|
||||
return num_events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate events for each scroll axis that changed between before/after
|
||||
* for the device.
|
||||
*
|
||||
* @param events The pointer to the event list to fill the events
|
||||
* @param dev The device to generate the events for
|
||||
* @param axis The axis number to generate events for
|
||||
* @param mask State before this event in absolute coords
|
||||
* @param[in,out] last Last scroll state posted in absolute coords (modified
|
||||
* in-place)
|
||||
* @param ms Current time in ms
|
||||
* @param max_events Max number of events to be generated
|
||||
* @return The number of events generated
|
||||
*/
|
||||
static int
|
||||
emulate_scroll_button_events(InternalEvent *events,
|
||||
DeviceIntPtr dev,
|
||||
int axis,
|
||||
const ValuatorMask *mask,
|
||||
ValuatorMask *last,
|
||||
CARD32 ms,
|
||||
int max_events)
|
||||
{
|
||||
AxisInfoPtr ax;
|
||||
double delta;
|
||||
double incr;
|
||||
int num_events = 0;
|
||||
double total;
|
||||
int b;
|
||||
|
||||
if (dev->valuator->axes[axis].scroll.type == SCROLL_TYPE_NONE)
|
||||
return 0;
|
||||
|
||||
if (!valuator_mask_isset(mask, axis))
|
||||
return 0;
|
||||
|
||||
ax = &dev->valuator->axes[axis];
|
||||
incr = ax->scroll.increment;
|
||||
|
||||
if (!valuator_mask_isset(last, axis))
|
||||
valuator_mask_set_double(last, axis, 0);
|
||||
|
||||
delta = valuator_mask_get_double(mask, axis) - valuator_mask_get_double(last, axis);
|
||||
total = delta;
|
||||
b = (ax->scroll.type == SCROLL_TYPE_VERTICAL) ? 5 : 7;
|
||||
|
||||
if ((incr > 0 && delta < 0) ||
|
||||
(incr < 0 && delta > 0))
|
||||
b--; /* we're scrolling up or left → button 4 or 6 */
|
||||
|
||||
while (fabs(delta) >= fabs(incr))
|
||||
{
|
||||
int nev_tmp;
|
||||
|
||||
if (delta > 0)
|
||||
delta -= fabs(incr);
|
||||
else if (delta < 0)
|
||||
delta += fabs(incr);
|
||||
|
||||
/* fill_pointer_events() generates four events: one normal and one raw
|
||||
* event for button press and button release.
|
||||
* We may get a bigger scroll delta than we can generate events
|
||||
* for. In that case, we keep decreasing delta, but skip events.
|
||||
*/
|
||||
if (num_events + 4 < max_events)
|
||||
{
|
||||
nev_tmp = fill_pointer_events(events, dev, ButtonPress, b, ms,
|
||||
POINTER_EMULATED, NULL);
|
||||
events += nev_tmp;
|
||||
num_events += nev_tmp;
|
||||
nev_tmp = fill_pointer_events(events, dev, ButtonRelease, b, ms,
|
||||
POINTER_EMULATED, NULL);
|
||||
events += nev_tmp;
|
||||
num_events += nev_tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* We emulated, update last.scroll */
|
||||
if (total != delta)
|
||||
{
|
||||
total -= delta;
|
||||
valuator_mask_set_double(last, axis,
|
||||
valuator_mask_get_double(last, axis) + total);
|
||||
}
|
||||
|
||||
return num_events;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a complete series of InternalEvents (filled into the EventList)
|
||||
* representing pointer motion, or button presses. If the device is a slave
|
||||
* device, also potentially generate a DeviceClassesChangedEvent to update
|
||||
* the master device.
|
||||
*
|
||||
* 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 InitEventList() and GetMaximumEventsNum(), and for freeing it.
|
||||
*
|
||||
* In the generated events rootX/Y will be in absolute screen coords and
|
||||
* the valuator information in the absolute or relative device coords.
|
||||
*
|
||||
* last.valuators[x] of the device is always in absolute device coords.
|
||||
* last.valuators[x] of the master device is in absolute screen coords.
|
||||
*
|
||||
* master->last.valuators[x] for x > 2 is undefined.
|
||||
*/
|
||||
int
|
||||
GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
|
||||
int buttons, int flags, const ValuatorMask *mask_in)
|
||||
{
|
||||
CARD32 ms = GetTimeInMillis();
|
||||
int num_events = 0, nev_tmp;
|
||||
int h_scroll_axis = pDev->valuator->h_scroll_axis;
|
||||
int v_scroll_axis = pDev->valuator->v_scroll_axis;
|
||||
ValuatorMask mask;
|
||||
ValuatorMask scroll;
|
||||
int i;
|
||||
|
||||
/* refuse events from disabled devices */
|
||||
if (!pDev->enabled)
|
||||
return 0;
|
||||
|
||||
if (!miPointerGetScreen(pDev))
|
||||
return 0;
|
||||
|
||||
events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT,
|
||||
&num_events);
|
||||
|
||||
valuator_mask_copy(&mask, mask_in);
|
||||
|
||||
/* Turn a scroll button press into a smooth-scrolling event if
|
||||
* necessary. This only needs to cater for the XIScrollFlagPreferred
|
||||
* axis (if more than one scrolling axis is present) */
|
||||
if (type == ButtonPress)
|
||||
{
|
||||
double val, adj;
|
||||
int axis;
|
||||
|
||||
switch (buttons) {
|
||||
case 4:
|
||||
adj = 1.0;
|
||||
axis = v_scroll_axis;
|
||||
break;
|
||||
case 5:
|
||||
adj = -1.0;
|
||||
axis = v_scroll_axis;
|
||||
break;
|
||||
case 6:
|
||||
adj = 1.0;
|
||||
axis = h_scroll_axis;
|
||||
break;
|
||||
case 7:
|
||||
adj = -1.0;
|
||||
axis = h_scroll_axis;
|
||||
break;
|
||||
default:
|
||||
adj = 0.0;
|
||||
axis = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (adj != 0.0 && axis != -1)
|
||||
{
|
||||
adj *= pDev->valuator->axes[axis].scroll.increment;
|
||||
val = valuator_mask_get_double(&mask, axis) + adj;
|
||||
valuator_mask_set_double(&mask, axis, val);
|
||||
type = MotionNotify;
|
||||
buttons = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* First fill out the original event set, with smooth-scrolling axes. */
|
||||
nev_tmp = fill_pointer_events(events, pDev, type, buttons, ms, flags,
|
||||
&mask);
|
||||
events += nev_tmp;
|
||||
num_events += nev_tmp;
|
||||
|
||||
valuator_mask_zero(&scroll);
|
||||
|
||||
/* Now turn the smooth-scrolling axes back into emulated button presses
|
||||
* for legacy clients, based on the integer delta between before and now */
|
||||
for (i = 0; i < valuator_mask_size(&mask); i++) {
|
||||
if (!valuator_mask_isset(&mask, i))
|
||||
continue;
|
||||
|
||||
valuator_mask_set_double(&scroll, i, pDev->last.valuators[i]);
|
||||
|
||||
nev_tmp = emulate_scroll_button_events(events, pDev, i, &scroll,
|
||||
pDev->last.scroll, ms,
|
||||
GetMaximumEventsNum() - num_events);
|
||||
events += nev_tmp;
|
||||
num_events += nev_tmp;
|
||||
}
|
||||
|
||||
return num_events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate internal events representing this proximity event and enqueue
|
||||
* them on the event queue.
|
||||
|
|
|
@ -497,10 +497,10 @@ valuator_mask_isset(const ValuatorMask *mask, int valuator)
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the valuator to the given data.
|
||||
* Set the valuator to the given floating-point data.
|
||||
*/
|
||||
void
|
||||
valuator_mask_set(ValuatorMask *mask, int valuator, int data)
|
||||
valuator_mask_set_double(ValuatorMask *mask, int valuator, double data)
|
||||
{
|
||||
mask->last_bit = max(valuator, mask->last_bit);
|
||||
SetBit(mask->mask, valuator);
|
||||
|
@ -508,13 +508,33 @@ valuator_mask_set(ValuatorMask *mask, int valuator, int data)
|
|||
}
|
||||
|
||||
/**
|
||||
* Return the requested valuator value. If the mask bit is not set for the
|
||||
* given valuator, the returned value is undefined.
|
||||
* Set the valuator to the given integer data.
|
||||
*/
|
||||
void
|
||||
valuator_mask_set(ValuatorMask *mask, int valuator, int data)
|
||||
{
|
||||
valuator_mask_set_double(mask, valuator, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the requested valuator value as a double. If the mask bit is not
|
||||
* set for the given valuator, the returned value is undefined.
|
||||
*/
|
||||
double
|
||||
valuator_mask_get_double(const ValuatorMask *mask, int valuator)
|
||||
{
|
||||
return mask->valuators[valuator];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the requested valuator value as an integer, rounding towards zero.
|
||||
* If the mask bit is not set for the given valuator, the returned value is
|
||||
* undefined.
|
||||
*/
|
||||
int
|
||||
valuator_mask_get(const ValuatorMask *mask, int valuator)
|
||||
{
|
||||
return mask->valuators[valuator];
|
||||
return trunc(valuator_mask_get_double(mask, valuator));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -527,7 +547,7 @@ valuator_mask_unset(ValuatorMask *mask, int valuator)
|
|||
int i, lastbit = -1;
|
||||
|
||||
ClearBit(mask->mask, valuator);
|
||||
mask->valuators[valuator] = 0;
|
||||
mask->valuators[valuator] = 0.0;
|
||||
|
||||
for (i = 0; i <= mask->last_bit; i++)
|
||||
if (valuator_mask_isset(mask, i))
|
||||
|
|
257
dix/ptrveloc.c
257
dix/ptrveloc.c
|
@ -63,9 +63,9 @@
|
|||
/* fwds */
|
||||
int
|
||||
SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
|
||||
static float
|
||||
SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, float velocity,
|
||||
float threshold, float acc);
|
||||
static double
|
||||
SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity,
|
||||
double threshold, double acc);
|
||||
static PointerAccelerationProfileFunc
|
||||
GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
|
||||
static BOOL
|
||||
|
@ -478,14 +478,10 @@ DoGetDirection(int dx, int dy){
|
|||
else
|
||||
dir = UNDEFINED; /* shouldn't happen */
|
||||
} else { /* compute angle and set appropriate flags */
|
||||
float r;
|
||||
double r;
|
||||
int i1, i2;
|
||||
|
||||
#ifdef _ISOC99_SOURCE
|
||||
r = atan2f(dy, dx);
|
||||
#else
|
||||
r = atan2(dy, dx);
|
||||
#endif
|
||||
/* find direction.
|
||||
*
|
||||
* Add 360° to avoid r become negative since C has no well-defined
|
||||
|
@ -524,8 +520,7 @@ static int
|
|||
GetDirection(int dx, int dy){
|
||||
static int cache[DIRECTION_CACHE_SIZE][DIRECTION_CACHE_SIZE];
|
||||
int dir;
|
||||
if (abs(dx) <= DIRECTION_CACHE_RANGE &&
|
||||
abs(dy) <= DIRECTION_CACHE_RANGE) {
|
||||
if (abs(dx) <= DIRECTION_CACHE_RANGE && abs(dy) <= DIRECTION_CACHE_RANGE) {
|
||||
/* cacheable */
|
||||
dir = cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy];
|
||||
if(dir == 0) {
|
||||
|
@ -553,7 +548,7 @@ GetDirection(int dx, int dy){
|
|||
* 0/0 and set it as the current one.
|
||||
*/
|
||||
static inline void
|
||||
FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t)
|
||||
FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t)
|
||||
{
|
||||
int n;
|
||||
for(n = 0; n < vel->num_tracker; n++){
|
||||
|
@ -561,8 +556,8 @@ FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t)
|
|||
vel->tracker[n].dy += dy;
|
||||
}
|
||||
n = (vel->cur_tracker + 1) % vel->num_tracker;
|
||||
vel->tracker[n].dx = 0;
|
||||
vel->tracker[n].dy = 0;
|
||||
vel->tracker[n].dx = 0.0;
|
||||
vel->tracker[n].dy = 0.0;
|
||||
vel->tracker[n].time = cur_t;
|
||||
vel->tracker[n].dir = GetDirection(dx, dy);
|
||||
DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
|
||||
|
@ -576,9 +571,9 @@ FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t)
|
|||
* velocity scaling.
|
||||
* This assumes linear motion.
|
||||
*/
|
||||
static float
|
||||
static double
|
||||
CalcTracker(const MotionTracker *tracker, int cur_t){
|
||||
float dist = sqrt(tracker->dx * tracker->dx + tracker->dy * tracker->dy);
|
||||
double dist = sqrt(tracker->dx * tracker->dx + tracker->dy * tracker->dy);
|
||||
int dtime = cur_t - tracker->time;
|
||||
if(dtime > 0)
|
||||
return dist / dtime;
|
||||
|
@ -593,16 +588,16 @@ CalcTracker(const MotionTracker *tracker, int cur_t){
|
|||
*
|
||||
* @return The tracker's velocity or 0 if the above conditions are unmet
|
||||
*/
|
||||
static float
|
||||
static double
|
||||
QueryTrackers(DeviceVelocityPtr vel, int cur_t){
|
||||
int offset, dir = UNDEFINED, used_offset = -1, age_ms;
|
||||
/* initial velocity: a low-offset, valid velocity */
|
||||
float initial_velocity = 0, result = 0, velocity_diff;
|
||||
float velocity_factor = vel->corr_mul * vel->const_acceleration; /* premultiply */
|
||||
double initial_velocity = 0, result = 0, velocity_diff;
|
||||
double velocity_factor = vel->corr_mul * vel->const_acceleration; /* premultiply */
|
||||
/* loop from current to older data */
|
||||
for(offset = 1; offset < vel->num_tracker; offset++){
|
||||
MotionTracker *tracker = TRACKER(vel, offset);
|
||||
float tracker_velocity;
|
||||
double tracker_velocity;
|
||||
|
||||
age_ms = cur_t - tracker->time;
|
||||
|
||||
|
@ -674,11 +669,11 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t){
|
|||
BOOL
|
||||
ProcessVelocityData2D(
|
||||
DeviceVelocityPtr vel,
|
||||
int dx,
|
||||
int dy,
|
||||
double dx,
|
||||
double dy,
|
||||
int time)
|
||||
{
|
||||
float velocity;
|
||||
double velocity;
|
||||
|
||||
vel->last_velocity = vel->velocity;
|
||||
|
||||
|
@ -694,12 +689,12 @@ ProcessVelocityData2D(
|
|||
* this flattens significant ( > 1) mickeys a little bit for more steady
|
||||
* constant-velocity response
|
||||
*/
|
||||
static inline float
|
||||
ApplySimpleSoftening(int prev_delta, int delta)
|
||||
static inline double
|
||||
ApplySimpleSoftening(double prev_delta, double delta)
|
||||
{
|
||||
float result = delta;
|
||||
double result = delta;
|
||||
|
||||
if (delta < -1 || delta > 1) {
|
||||
if (delta < -1.0 || delta > 1.0) {
|
||||
if (delta > prev_delta)
|
||||
result -= 0.5;
|
||||
else if (delta < prev_delta)
|
||||
|
@ -718,8 +713,8 @@ ApplySimpleSoftening(int prev_delta, int delta)
|
|||
static void
|
||||
ApplySoftening(
|
||||
DeviceVelocityPtr vel,
|
||||
float* fdx,
|
||||
float* fdy)
|
||||
double* fdx,
|
||||
double* fdy)
|
||||
{
|
||||
if (vel->use_softening) {
|
||||
*fdx = ApplySimpleSoftening(vel->last_dx, *fdx);
|
||||
|
@ -728,7 +723,7 @@ ApplySoftening(
|
|||
}
|
||||
|
||||
static void
|
||||
ApplyConstantDeceleration(DeviceVelocityPtr vel, float *fdx, float *fdy)
|
||||
ApplyConstantDeceleration(DeviceVelocityPtr vel, double *fdx, double *fdy)
|
||||
{
|
||||
*fdx *= vel->const_acceleration;
|
||||
*fdy *= vel->const_acceleration;
|
||||
|
@ -737,15 +732,15 @@ ApplyConstantDeceleration(DeviceVelocityPtr vel, float *fdx, float *fdy)
|
|||
/*
|
||||
* compute the acceleration for given velocity and enforce min_acceleartion
|
||||
*/
|
||||
float
|
||||
double
|
||||
BasicComputeAcceleration(
|
||||
DeviceIntPtr dev,
|
||||
DeviceVelocityPtr vel,
|
||||
float velocity,
|
||||
float threshold,
|
||||
float acc){
|
||||
double velocity,
|
||||
double threshold,
|
||||
double acc){
|
||||
|
||||
float result;
|
||||
double result;
|
||||
result = vel->Profile(dev, vel, velocity, threshold, acc);
|
||||
|
||||
/* enforce min_acceleration */
|
||||
|
@ -759,13 +754,13 @@ BasicComputeAcceleration(
|
|||
* If the velocity has changed, an average is taken of 6 velocity factors:
|
||||
* current velocity, last velocity and 4 times the average between the two.
|
||||
*/
|
||||
static float
|
||||
static double
|
||||
ComputeAcceleration(
|
||||
DeviceIntPtr dev,
|
||||
DeviceVelocityPtr vel,
|
||||
float threshold,
|
||||
float acc){
|
||||
float result;
|
||||
double threshold,
|
||||
double acc){
|
||||
double result;
|
||||
|
||||
if(vel->velocity <= 0){
|
||||
DebugAccelF("(dix ptracc) profile skipped\n");
|
||||
|
@ -808,13 +803,13 @@ ComputeAcceleration(
|
|||
/**
|
||||
* Polynomial function similar previous one, but with f(1) = 1
|
||||
*/
|
||||
static float
|
||||
static double
|
||||
PolynomialAccelerationProfile(
|
||||
DeviceIntPtr dev,
|
||||
DeviceVelocityPtr vel,
|
||||
float velocity,
|
||||
float ignored,
|
||||
float acc)
|
||||
double velocity,
|
||||
double ignored,
|
||||
double acc)
|
||||
{
|
||||
return pow(velocity, (acc - 1.0) * 0.5);
|
||||
}
|
||||
|
@ -824,13 +819,13 @@ PolynomialAccelerationProfile(
|
|||
* returns acceleration for velocity.
|
||||
* This profile selects the two functions like the old scheme did
|
||||
*/
|
||||
static float
|
||||
static double
|
||||
ClassicProfile(
|
||||
DeviceIntPtr dev,
|
||||
DeviceVelocityPtr vel,
|
||||
float velocity,
|
||||
float threshold,
|
||||
float acc)
|
||||
double velocity,
|
||||
double threshold,
|
||||
double acc)
|
||||
{
|
||||
if (threshold > 0) {
|
||||
return SimpleSmoothProfile (dev,
|
||||
|
@ -856,15 +851,15 @@ ClassicProfile(
|
|||
* This has the expense of overall response dependency on min-acceleration.
|
||||
* In effect, min_acceleration mimics const_acceleration in this profile.
|
||||
*/
|
||||
static float
|
||||
static double
|
||||
PowerProfile(
|
||||
DeviceIntPtr dev,
|
||||
DeviceVelocityPtr vel,
|
||||
float velocity,
|
||||
float threshold,
|
||||
float acc)
|
||||
double velocity,
|
||||
double threshold,
|
||||
double acc)
|
||||
{
|
||||
float vel_dist;
|
||||
double vel_dist;
|
||||
|
||||
acc = (acc-1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */
|
||||
|
||||
|
@ -882,11 +877,11 @@ PowerProfile(
|
|||
* - starts faster than a sinoid
|
||||
* - smoothness C1 (Cinf if you dare to ignore endpoints)
|
||||
*/
|
||||
static inline float
|
||||
CalcPenumbralGradient(float x){
|
||||
static inline double
|
||||
CalcPenumbralGradient(double x){
|
||||
x *= 2.0f;
|
||||
x -= 1.0f;
|
||||
return 0.5f + (x * sqrt(1.0f - x*x) + asin(x))/M_PI;
|
||||
return 0.5f + (x * sqrt(1.0 - x*x) + asin(x))/M_PI;
|
||||
}
|
||||
|
||||
|
||||
|
@ -894,13 +889,13 @@ CalcPenumbralGradient(float x){
|
|||
* acceleration function similar to classic accelerated/unaccelerated,
|
||||
* but with smooth transition in between (and towards zero for adaptive dec.).
|
||||
*/
|
||||
static float
|
||||
static double
|
||||
SimpleSmoothProfile(
|
||||
DeviceIntPtr dev,
|
||||
DeviceVelocityPtr vel,
|
||||
float velocity,
|
||||
float threshold,
|
||||
float acc)
|
||||
double velocity,
|
||||
double threshold,
|
||||
double acc)
|
||||
{
|
||||
if(velocity < 1.0f)
|
||||
return CalcPenumbralGradient(0.5 + velocity*0.5) * 2.0f - 1.0f;
|
||||
|
@ -920,15 +915,15 @@ SimpleSmoothProfile(
|
|||
* This profile uses the first half of the penumbral gradient as a start
|
||||
* and then scales linearly.
|
||||
*/
|
||||
static float
|
||||
static double
|
||||
SmoothLinearProfile(
|
||||
DeviceIntPtr dev,
|
||||
DeviceVelocityPtr vel,
|
||||
float velocity,
|
||||
float threshold,
|
||||
float acc)
|
||||
double velocity,
|
||||
double threshold,
|
||||
double acc)
|
||||
{
|
||||
float res, nv;
|
||||
double res, nv;
|
||||
|
||||
if(acc > 1.0f)
|
||||
acc -= 1.0f; /*this is so acc = 1 is no acceleration */
|
||||
|
@ -955,15 +950,15 @@ SmoothLinearProfile(
|
|||
* From 0 to threshold, the response graduates smoothly from min_accel to
|
||||
* acceleration. Beyond threshold it is exactly the specified acceleration.
|
||||
*/
|
||||
static float
|
||||
static double
|
||||
SmoothLimitedProfile(
|
||||
DeviceIntPtr dev,
|
||||
DeviceVelocityPtr vel,
|
||||
float velocity,
|
||||
float threshold,
|
||||
float acc)
|
||||
double velocity,
|
||||
double threshold,
|
||||
double acc)
|
||||
{
|
||||
float res;
|
||||
double res;
|
||||
|
||||
if(velocity >= threshold || threshold == 0.0f)
|
||||
return acc;
|
||||
|
@ -976,24 +971,24 @@ SmoothLimitedProfile(
|
|||
}
|
||||
|
||||
|
||||
static float
|
||||
static double
|
||||
LinearProfile(
|
||||
DeviceIntPtr dev,
|
||||
DeviceVelocityPtr vel,
|
||||
float velocity,
|
||||
float threshold,
|
||||
float acc)
|
||||
double velocity,
|
||||
double threshold,
|
||||
double acc)
|
||||
{
|
||||
return acc * velocity;
|
||||
}
|
||||
|
||||
static float
|
||||
static double
|
||||
NoProfile(
|
||||
DeviceIntPtr dev,
|
||||
DeviceVelocityPtr vel,
|
||||
float velocity,
|
||||
float threshold,
|
||||
float acc)
|
||||
double velocity,
|
||||
double threshold,
|
||||
double acc)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
@ -1119,11 +1114,11 @@ acceleratePointerPredictable(
|
|||
ValuatorMask* val,
|
||||
CARD32 evtime)
|
||||
{
|
||||
int dx = 0, dy = 0, tmpi;
|
||||
double dx = 0, dy = 0;
|
||||
DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev);
|
||||
Bool soften = TRUE;
|
||||
|
||||
if (!velocitydata)
|
||||
if (valuator_mask_num_valuators(val) == 0 || !velocitydata)
|
||||
return;
|
||||
|
||||
if (velocitydata->statistics.profile_number == AccelProfileNone &&
|
||||
|
@ -1132,59 +1127,39 @@ acceleratePointerPredictable(
|
|||
}
|
||||
|
||||
if (valuator_mask_isset(val, 0)) {
|
||||
dx = valuator_mask_get(val, 0);
|
||||
dx = valuator_mask_get_double(val, 0);
|
||||
}
|
||||
|
||||
if (valuator_mask_isset(val, 1)) {
|
||||
dy = valuator_mask_get(val, 1);
|
||||
dy = valuator_mask_get_double(val, 1);
|
||||
}
|
||||
|
||||
if (dx || dy){
|
||||
if (dx != 0.0 || dy != 0.0) {
|
||||
/* reset non-visible state? */
|
||||
if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) {
|
||||
soften = FALSE;
|
||||
}
|
||||
|
||||
if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
|
||||
float mult;
|
||||
double mult;
|
||||
|
||||
/* invoke acceleration profile to determine acceleration */
|
||||
mult = ComputeAcceleration (dev, velocitydata,
|
||||
dev->ptrfeed->ctrl.threshold,
|
||||
(float)dev->ptrfeed->ctrl.num /
|
||||
(float)dev->ptrfeed->ctrl.den);
|
||||
dev->ptrfeed->ctrl.threshold,
|
||||
(double)dev->ptrfeed->ctrl.num /
|
||||
(double)dev->ptrfeed->ctrl.den);
|
||||
|
||||
if(mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
|
||||
float fdx = dx,
|
||||
fdy = dy;
|
||||
|
||||
if (mult > 1.0f && soften)
|
||||
ApplySoftening(velocitydata, &fdx, &fdy);
|
||||
ApplyConstantDeceleration(velocitydata, &fdx, &fdy);
|
||||
ApplySoftening(velocitydata, &dx, &dy);
|
||||
ApplyConstantDeceleration(velocitydata, &dx, &dy);
|
||||
|
||||
/* Calculate the new delta (with accel) and drop it back
|
||||
* into the valuator masks */
|
||||
if (dx) {
|
||||
float tmp;
|
||||
tmp = mult * fdx + dev->last.remainder[0];
|
||||
/* Since it may not be apparent: lrintf() does not offer
|
||||
* strong statements about rounding; however because we
|
||||
* process each axis conditionally, there's no danger
|
||||
* of a toggling remainder. Its lack of guarantees likely
|
||||
* makes it faster on the average target. */
|
||||
tmpi = lrintf(tmp);
|
||||
valuator_mask_set(val, 0, tmpi);
|
||||
dev->last.remainder[0] = tmp - (float)tmpi;
|
||||
}
|
||||
if (dy) {
|
||||
float tmp;
|
||||
tmp = mult * fdy + dev->last.remainder[1];
|
||||
tmpi = lrintf(tmp);
|
||||
valuator_mask_set(val, 1, tmpi);
|
||||
dev->last.remainder[1] = tmp - (float)tmpi;
|
||||
}
|
||||
DebugAccelF("pos (%i | %i) remainders x: %.3f y: %.3f delta x:%.3f y:%.3f\n",
|
||||
*px, *py, dev->last.remainder[0], dev->last.remainder[1], fdx, fdy);
|
||||
if (dx != 0.0)
|
||||
valuator_mask_set_double(val, 0, mult * dx);
|
||||
if (dy != 0.0)
|
||||
valuator_mask_set_double(val, 1, mult * dy);
|
||||
DebugAccelF("pos (%i | %i) delta x:%.3f y:%.3f\n", mult * dx,
|
||||
mult * dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1205,8 +1180,8 @@ acceleratePointerLightweight(
|
|||
ValuatorMask* val,
|
||||
CARD32 ignored)
|
||||
{
|
||||
float mult = 0.0, tmpf;
|
||||
int dx = 0, dy = 0, tmpi;
|
||||
double mult = 0.0, tmpf;
|
||||
double dx = 0.0, dy = 0.0;
|
||||
|
||||
if (valuator_mask_isset(val, 0)) {
|
||||
dx = valuator_mask_get(val, 0);
|
||||
|
@ -1216,53 +1191,35 @@ acceleratePointerLightweight(
|
|||
dy = valuator_mask_get(val, 1);
|
||||
}
|
||||
|
||||
if (!dx && !dy)
|
||||
if (valuator_mask_num_valuators(val) == 0)
|
||||
return;
|
||||
|
||||
if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
|
||||
/* modeled from xf86Events.c */
|
||||
if (dev->ptrfeed->ctrl.threshold) {
|
||||
if ((abs(dx) + abs(dy)) >= dev->ptrfeed->ctrl.threshold) {
|
||||
tmpf = ((float)dx *
|
||||
(float)(dev->ptrfeed->ctrl.num)) /
|
||||
(float)(dev->ptrfeed->ctrl.den) +
|
||||
dev->last.remainder[0];
|
||||
if (dx) {
|
||||
tmpi = (int) tmpf;
|
||||
valuator_mask_set(val, 0, tmpi);
|
||||
dev->last.remainder[0] = tmpf - (float)tmpi;
|
||||
if ((fabs(dx) + fabs(dy)) >= dev->ptrfeed->ctrl.threshold) {
|
||||
if (dx != 0.0) {
|
||||
tmpf = (dx * (double)(dev->ptrfeed->ctrl.num)) /
|
||||
(double)(dev->ptrfeed->ctrl.den);
|
||||
valuator_mask_set_double(val, 0, tmpf);
|
||||
}
|
||||
|
||||
tmpf = ((float)dy *
|
||||
(float)(dev->ptrfeed->ctrl.num)) /
|
||||
(float)(dev->ptrfeed->ctrl.den) +
|
||||
dev->last.remainder[1];
|
||||
if (dy) {
|
||||
tmpi = (int) tmpf;
|
||||
valuator_mask_set(val, 1, tmpi);
|
||||
dev->last.remainder[1] = tmpf - (float)tmpi;
|
||||
if (dy != 0.0) {
|
||||
tmpf = (dy * (double)(dev->ptrfeed->ctrl.num)) /
|
||||
(double)(dev->ptrfeed->ctrl.den);
|
||||
valuator_mask_set_double(val, 1, tmpf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
|
||||
((float)(dev->ptrfeed->ctrl.num) /
|
||||
(float)(dev->ptrfeed->ctrl.den) - 1.0) /
|
||||
mult = pow(dx * dx + dy * dy,
|
||||
((double)(dev->ptrfeed->ctrl.num) /
|
||||
(double)(dev->ptrfeed->ctrl.den) - 1.0) /
|
||||
2.0) / 2.0;
|
||||
if (dx) {
|
||||
tmpf = mult * (float)dx +
|
||||
dev->last.remainder[0];
|
||||
tmpi = (int) tmpf;
|
||||
valuator_mask_set(val, 0, tmpi);
|
||||
dev->last.remainder[0] = tmpf - (float)tmpi;
|
||||
}
|
||||
if (dy) {
|
||||
tmpf = mult * (float)dy +
|
||||
dev->last.remainder[1];
|
||||
tmpi = (int)tmpf;
|
||||
valuator_mask_set(val, 1, tmpi);
|
||||
dev->last.remainder[1] = tmpf - (float)tmpi;
|
||||
}
|
||||
if (dx != 0.0)
|
||||
valuator_mask_set_double(val, 0, mult * dx);
|
||||
if (dy != 0.0)
|
||||
valuator_mask_set_double(val, 1, mult * dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ typedef enum {
|
|||
*/
|
||||
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
|
||||
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(11, 0)
|
||||
#define ABI_XINPUT_VERSION SET_ABI_VERSION(13, 0)
|
||||
#define ABI_XINPUT_VERSION SET_ABI_VERSION(14, 0)
|
||||
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(6, 0)
|
||||
#define ABI_FONT_VERSION SET_ABI_VERSION(0, 6)
|
||||
|
||||
|
|
|
@ -1363,15 +1363,15 @@ xf86XInputSetScreen(InputInfoPtr pInfo,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
Bool
|
||||
xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
|
||||
int resolution, int min_res, int max_res, int mode)
|
||||
{
|
||||
if (!dev || !dev->valuator)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res,
|
||||
max_res, mode);
|
||||
return InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res,
|
||||
max_res, mode);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -145,7 +145,7 @@ extern _X_EXPORT InputInfoPtr xf86FirstLocalDevice(void);
|
|||
extern _X_EXPORT int xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min);
|
||||
extern _X_EXPORT void xf86XInputSetScreen(InputInfoPtr pInfo, int screen_number, int x, int y);
|
||||
extern _X_EXPORT void xf86ProcessCommonOptions(InputInfoPtr pInfo, XF86OptionPtr options);
|
||||
extern _X_EXPORT void xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval,
|
||||
extern _X_EXPORT Bool xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval,
|
||||
int maxval, int resolution, int min_res,
|
||||
int max_res, int mode);
|
||||
extern _X_EXPORT void xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum);
|
||||
|
|
|
@ -95,8 +95,7 @@ struct _DeviceEvent
|
|||
struct {
|
||||
uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
|
||||
uint8_t mode[(MAX_VALUATORS + 7)/8]; /**< Valuator mode (Abs or Rel)*/
|
||||
int32_t data[MAX_VALUATORS]; /**< Valuator data */
|
||||
int32_t data_frac[MAX_VALUATORS]; /**< Fractional part for data */
|
||||
double data[MAX_VALUATORS]; /**< Valuator data */
|
||||
} valuators;
|
||||
struct {
|
||||
uint32_t base; /**< XKB base modifiers */
|
||||
|
@ -113,6 +112,7 @@ struct _DeviceEvent
|
|||
Window root; /**< Root window of the event */
|
||||
int corestate; /**< Core key/button state BEFORE the event */
|
||||
int key_repeat; /**< Internally-generated key repeat event */
|
||||
uint32_t flags; /**< Flags to be copied into the generated event */
|
||||
};
|
||||
|
||||
|
||||
|
@ -198,11 +198,10 @@ struct _RawDeviceEvent
|
|||
} detail;
|
||||
struct {
|
||||
uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
|
||||
int32_t data[MAX_VALUATORS]; /**< Valuator data */
|
||||
int32_t data_frac[MAX_VALUATORS]; /**< Fractional part for data */
|
||||
int32_t data_raw[MAX_VALUATORS]; /**< Valuator data as posted */
|
||||
int32_t data_raw_frac[MAX_VALUATORS];/**< Fractional part for data_raw */
|
||||
double data[MAX_VALUATORS]; /**< Valuator data */
|
||||
double data_raw[MAX_VALUATORS]; /**< Valuator data as posted */
|
||||
} valuators;
|
||||
uint32_t flags; /**< Flags to be copied into the generated event */
|
||||
};
|
||||
|
||||
#ifdef XQUARTZ
|
||||
|
|
|
@ -37,10 +37,26 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
* Interface available to drivers *
|
||||
***************************************************************/
|
||||
|
||||
/**
|
||||
* Scroll flags for ::SetScrollValuator.
|
||||
*/
|
||||
enum ScrollFlags {
|
||||
SCROLL_FLAG_NONE = 0,
|
||||
/**
|
||||
* Do not emulate legacy button events for valuator events on this axis.
|
||||
*/
|
||||
SCROLL_FLAG_DONT_EMULATE = (1 << 1),
|
||||
/**
|
||||
* This axis is the preferred axis for valuator emulation for this axis'
|
||||
* scroll type.
|
||||
*/
|
||||
SCROLL_FLAG_PREFERRED = (1 << 2)
|
||||
};
|
||||
|
||||
extern _X_EXPORT int InitProximityClassDeviceStruct(
|
||||
DeviceIntPtr /* dev */);
|
||||
|
||||
extern _X_EXPORT void InitValuatorAxisStruct(
|
||||
extern _X_EXPORT Bool InitValuatorAxisStruct(
|
||||
DeviceIntPtr /* dev */,
|
||||
int /* axnum */,
|
||||
Atom /* label */,
|
||||
|
@ -51,6 +67,13 @@ extern _X_EXPORT void InitValuatorAxisStruct(
|
|||
int /* max_res */,
|
||||
int /* mode */);
|
||||
|
||||
extern _X_EXPORT Bool SetScrollValuator(
|
||||
DeviceIntPtr /* dev */,
|
||||
int /* axnum */,
|
||||
enum ScrollType /* type */,
|
||||
double /* increment */,
|
||||
int /* flags */);
|
||||
|
||||
/* Input device properties */
|
||||
extern _X_EXPORT void XIDeleteAllDeviceProperties(
|
||||
DeviceIntPtr /* device */
|
||||
|
|
|
@ -68,6 +68,7 @@ SOFTWARE.
|
|||
#define POINTER_ACCELERATE (1 << 3)
|
||||
#define POINTER_SCREEN (1 << 4) /* Data in screen coordinates */
|
||||
#define POINTER_NORAW (1 << 5) /* Don't generate RawEvents */
|
||||
#define POINTER_EMULATED (1 << 6) /* Event was emulated from another event */
|
||||
|
||||
/*int constants for pointer acceleration schemes*/
|
||||
#define PtrAccelNoOp 0
|
||||
|
@ -583,6 +584,9 @@ extern _X_EXPORT void valuator_mask_set_range(ValuatorMask *mask,
|
|||
extern _X_EXPORT void valuator_mask_set(ValuatorMask *mask,
|
||||
int valuator,
|
||||
int data);
|
||||
extern _X_EXPORT void valuator_mask_set_double(ValuatorMask *mask,
|
||||
int valuator,
|
||||
double data);
|
||||
extern _X_EXPORT void valuator_mask_zero(ValuatorMask *mask);
|
||||
extern _X_EXPORT int valuator_mask_size(const ValuatorMask *mask);
|
||||
extern _X_EXPORT int valuator_mask_isset(const ValuatorMask *mask, int bit);
|
||||
|
@ -591,6 +595,8 @@ extern _X_EXPORT int valuator_mask_num_valuators(const ValuatorMask *mask);
|
|||
extern _X_EXPORT void valuator_mask_copy(ValuatorMask *dest,
|
||||
const ValuatorMask *src);
|
||||
extern _X_EXPORT int valuator_mask_get(const ValuatorMask *mask, int valnum);
|
||||
extern _X_EXPORT double valuator_mask_get_double(const ValuatorMask *mask,
|
||||
int valnum);
|
||||
|
||||
/* InputOption handling interface */
|
||||
extern _X_EXPORT InputOption* input_option_new(InputOption *list, const char *key, const char *value);
|
||||
|
|
|
@ -74,6 +74,16 @@ extern _X_EXPORT int CountBits(const uint8_t *mask, int len);
|
|||
#define XI2LASTEVENT 17 /* XI_RawMotion */
|
||||
#define XI2MASKSIZE ((XI2LASTEVENT + 7)/8) /* no of bits for masks */
|
||||
|
||||
/**
|
||||
* Scroll types for ::SetScrollValuator and the scroll type in the
|
||||
* ::ScrollInfoPtr.
|
||||
*/
|
||||
enum ScrollType {
|
||||
SCROLL_TYPE_NONE = 0, /**< Not a scrolling valuator */
|
||||
SCROLL_TYPE_VERTICAL = 8,
|
||||
SCROLL_TYPE_HORIZONTAL = 9,
|
||||
};
|
||||
|
||||
/**
|
||||
* This struct stores the core event mask for each client except the client
|
||||
* that created the window.
|
||||
|
@ -252,6 +262,12 @@ typedef struct _KeyClassRec {
|
|||
struct _XkbSrvInfo *xkbInfo;
|
||||
} KeyClassRec, *KeyClassPtr;
|
||||
|
||||
typedef struct _ScrollInfo {
|
||||
enum ScrollType type;
|
||||
double increment;
|
||||
int flags;
|
||||
} ScrollInfo, *ScrollInfoPtr;
|
||||
|
||||
typedef struct _AxisInfo {
|
||||
int resolution;
|
||||
int min_resolution;
|
||||
|
@ -260,6 +276,7 @@ typedef struct _AxisInfo {
|
|||
int max_value;
|
||||
Atom label;
|
||||
CARD8 mode;
|
||||
ScrollInfo scroll;
|
||||
} AxisInfo, *AxisInfoPtr;
|
||||
|
||||
typedef struct _ValuatorAccelerationRec {
|
||||
|
@ -283,6 +300,8 @@ typedef struct _ValuatorClassRec {
|
|||
unsigned short numAxes;
|
||||
double *axisVal; /* always absolute, but device-coord system */
|
||||
ValuatorAccelerationRec accelScheme;
|
||||
int h_scroll_axis; /* horiz smooth-scrolling axis */
|
||||
int v_scroll_axis; /* vert smooth-scrolling axis */
|
||||
} ValuatorClassRec;
|
||||
|
||||
typedef struct _ButtonClassRec {
|
||||
|
@ -521,10 +540,10 @@ typedef struct _DeviceIntRec {
|
|||
* remainder supports acceleration
|
||||
*/
|
||||
struct {
|
||||
int valuators[MAX_VALUATORS];
|
||||
float remainder[MAX_VALUATORS];
|
||||
double valuators[MAX_VALUATORS];
|
||||
int numValuators;
|
||||
DeviceIntPtr slave;
|
||||
ValuatorMask *scroll;
|
||||
} last;
|
||||
|
||||
/* Input device property handling. */
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
struct _ValuatorMask {
|
||||
int8_t last_bit; /* highest bit set in mask */
|
||||
uint8_t mask[(MAX_VALUATORS + 7)/8];
|
||||
int valuators[MAX_VALUATORS]; /* valuator data */
|
||||
double valuators[MAX_VALUATORS]; /* valuator data */
|
||||
};
|
||||
|
||||
extern void verify_internal_event(const InternalEvent *ev);
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
|
||||
/* X Input */
|
||||
#define SERVER_XI_MAJOR_VERSION 2
|
||||
#define SERVER_XI_MINOR_VERSION 0
|
||||
#define SERVER_XI_MINOR_VERSION 1
|
||||
|
||||
/* XKB */
|
||||
#define SERVER_XKB_MAJOR_VERSION 1
|
||||
|
|
|
@ -47,9 +47,9 @@ struct _DeviceVelocityRec;
|
|||
* profile
|
||||
* returns actual acceleration depending on velocity, acceleration control,...
|
||||
*/
|
||||
typedef float (*PointerAccelerationProfileFunc)
|
||||
typedef double (*PointerAccelerationProfileFunc)
|
||||
(DeviceIntPtr dev, struct _DeviceVelocityRec* vel,
|
||||
float velocity, float threshold, float accelCoeff);
|
||||
double velocity, double threshold, double accelCoeff);
|
||||
|
||||
/**
|
||||
* a motion history, with just enough information to
|
||||
|
@ -57,8 +57,8 @@ typedef float (*PointerAccelerationProfileFunc)
|
|||
* a more or less straight line
|
||||
*/
|
||||
typedef struct _MotionTracker {
|
||||
int dx, dy; /* accumulated delta for each axis */
|
||||
int time; /* time of creation */
|
||||
double dx, dy; /* accumulated delta for each axis */
|
||||
int time; /* time of creation */
|
||||
int dir; /* initial direction bitfield */
|
||||
} MotionTracker, *MotionTrackerPtr;
|
||||
|
||||
|
@ -69,17 +69,17 @@ typedef struct _DeviceVelocityRec {
|
|||
MotionTrackerPtr tracker;
|
||||
int num_tracker;
|
||||
int cur_tracker; /* current index */
|
||||
float velocity; /* velocity as guessed by algorithm */
|
||||
float last_velocity; /* previous velocity estimate */
|
||||
int last_dx; /* last time-difference */
|
||||
int last_dy ; /* phase of last/current estimate */
|
||||
float corr_mul; /* config: multiply this into velocity */
|
||||
float const_acceleration; /* config: (recipr.) const deceleration */
|
||||
float min_acceleration; /* config: minimum acceleration */
|
||||
double velocity; /* velocity as guessed by algorithm */
|
||||
double last_velocity; /* previous velocity estimate */
|
||||
double last_dx; /* last time-difference */
|
||||
double last_dy; /* phase of last/current estimate */
|
||||
double corr_mul; /* config: multiply this into velocity */
|
||||
double const_acceleration; /* config: (recipr.) const deceleration */
|
||||
double min_acceleration; /* config: minimum acceleration */
|
||||
short reset_time; /* config: reset non-visible state after # ms */
|
||||
short use_softening; /* config: use softening of mouse values */
|
||||
float max_rel_diff; /* config: max. relative difference */
|
||||
float max_diff; /* config: max. difference */
|
||||
double max_rel_diff; /* config: max. relative difference */
|
||||
double max_diff; /* config: max. difference */
|
||||
int initial_range; /* config: max. offset used as initial velocity */
|
||||
Bool average_accel; /* config: average acceleration over velocity */
|
||||
PointerAccelerationProfileFunc Profile;
|
||||
|
@ -107,11 +107,11 @@ extern _X_EXPORT void
|
|||
InitTrackers(DeviceVelocityPtr vel, int ntracker);
|
||||
|
||||
extern _X_EXPORT BOOL
|
||||
ProcessVelocityData2D(DeviceVelocityPtr vel, int dx, int dy, int time);
|
||||
ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time);
|
||||
|
||||
extern _X_EXPORT float
|
||||
extern _X_EXPORT double
|
||||
BasicComputeAcceleration(DeviceIntPtr dev, DeviceVelocityPtr vel,
|
||||
float velocity, float threshold, float acc);
|
||||
double velocity, double threshold, double acc);
|
||||
|
||||
extern _X_EXPORT void
|
||||
FreeVelocityData(DeviceVelocityPtr vel);
|
||||
|
|
|
@ -77,6 +77,8 @@
|
|||
#define AXIS_LABEL_PROP_REL_DIAL "Rel Dial"
|
||||
#define AXIS_LABEL_PROP_REL_WHEEL "Rel Vert Wheel"
|
||||
#define AXIS_LABEL_PROP_REL_MISC "Rel Misc"
|
||||
#define AXIS_LABEL_PROP_REL_VSCROLL "Rel Vert Scroll"
|
||||
#define AXIS_LABEL_PROP_REL_HSCROLL "Rel Horiz Scroll"
|
||||
|
||||
/*
|
||||
* Absolute axes
|
||||
|
|
78
test/input.c
78
test/input.c
|
@ -52,6 +52,7 @@ static void dix_init_valuators(void)
|
|||
{
|
||||
DeviceIntRec dev;
|
||||
ValuatorClassPtr val;
|
||||
AxisInfoPtr axis;
|
||||
const int num_axes = 2;
|
||||
int i;
|
||||
Atom atoms[MAX_VALUATORS] = { 0 };
|
||||
|
@ -78,6 +79,62 @@ static void dix_init_valuators(void)
|
|||
}
|
||||
|
||||
assert(dev.last.numValuators == num_axes);
|
||||
|
||||
/* invalid increment */
|
||||
assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_VERTICAL, 0.0, SCROLL_FLAG_NONE) == FALSE);
|
||||
/* invalid type */
|
||||
assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_VERTICAL - 1, 1.0, SCROLL_FLAG_NONE) == FALSE);
|
||||
assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_HORIZONTAL + 1, 1.0, SCROLL_FLAG_NONE) == FALSE);
|
||||
/* invalid axisnum */
|
||||
assert(SetScrollValuator(&dev, 2, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE) == FALSE);
|
||||
|
||||
/* valid */
|
||||
assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_VERTICAL, 3.0, SCROLL_FLAG_NONE) == TRUE);
|
||||
axis = &dev.valuator->axes[0];
|
||||
assert(axis->scroll.increment == 3.0);
|
||||
assert(axis->scroll.type == SCROLL_TYPE_VERTICAL);
|
||||
assert(axis->scroll.flags == 0);
|
||||
|
||||
/* valid */
|
||||
assert(SetScrollValuator(&dev, 1, SCROLL_TYPE_HORIZONTAL, 2.0, SCROLL_FLAG_NONE) == TRUE);
|
||||
axis = &dev.valuator->axes[1];
|
||||
assert(axis->scroll.increment == 2.0);
|
||||
assert(axis->scroll.type == SCROLL_TYPE_HORIZONTAL);
|
||||
assert(axis->scroll.flags == 0);
|
||||
|
||||
/* can add another non-preffered axis */
|
||||
assert(SetScrollValuator(&dev, 1, SCROLL_TYPE_VERTICAL, 5.0, SCROLL_FLAG_NONE) == TRUE);
|
||||
assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_HORIZONTAL, 5.0, SCROLL_FLAG_NONE) == TRUE);
|
||||
|
||||
/* can overwrite with Preferred */
|
||||
assert(SetScrollValuator(&dev, 1, SCROLL_TYPE_VERTICAL, 5.5, SCROLL_FLAG_PREFERRED) == TRUE);
|
||||
axis = &dev.valuator->axes[1];
|
||||
assert(axis->scroll.increment == 5.5);
|
||||
assert(axis->scroll.type == SCROLL_TYPE_VERTICAL);
|
||||
assert(axis->scroll.flags == SCROLL_FLAG_PREFERRED);
|
||||
|
||||
assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_HORIZONTAL, 8.8, SCROLL_FLAG_PREFERRED) == TRUE);
|
||||
axis = &dev.valuator->axes[0];
|
||||
assert(axis->scroll.increment == 8.8);
|
||||
assert(axis->scroll.type == SCROLL_TYPE_HORIZONTAL);
|
||||
assert(axis->scroll.flags == SCROLL_FLAG_PREFERRED);
|
||||
|
||||
/* can overwrite as none */
|
||||
assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_NONE, 5.0,
|
||||
SCROLL_FLAG_NONE) == TRUE);
|
||||
axis = &dev.valuator->axes[0];
|
||||
assert(axis->scroll.type == SCROLL_TYPE_NONE);
|
||||
|
||||
/* can overwrite axis with new settings */
|
||||
assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_VERTICAL, 5.0, SCROLL_FLAG_NONE) == TRUE);
|
||||
axis = &dev.valuator->axes[0];
|
||||
assert(axis->scroll.type == SCROLL_TYPE_VERTICAL);
|
||||
assert(axis->scroll.increment == 5.0);
|
||||
assert(axis->scroll.flags == SCROLL_FLAG_NONE);
|
||||
assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_VERTICAL, 3.0, SCROLL_FLAG_NONE) == TRUE);
|
||||
assert(axis->scroll.type == SCROLL_TYPE_VERTICAL);
|
||||
assert(axis->scroll.increment == 3.0);
|
||||
assert(axis->scroll.flags == SCROLL_FLAG_NONE);
|
||||
}
|
||||
|
||||
/* just check the known success cases, and that error cases set the client's
|
||||
|
@ -1089,12 +1146,16 @@ static void dix_input_valuator_masks(void)
|
|||
{
|
||||
ValuatorMask *mask = NULL, *copy;
|
||||
int nvaluators = MAX_VALUATORS;
|
||||
int valuators[nvaluators];
|
||||
double valuators[nvaluators];
|
||||
int val_ranged[nvaluators];
|
||||
int i;
|
||||
int first_val, num_vals;
|
||||
|
||||
for (i = 0; i < nvaluators; i++)
|
||||
valuators[i] = i;
|
||||
{
|
||||
valuators[i] = i + 0.5;
|
||||
val_ranged[i] = i;
|
||||
}
|
||||
|
||||
mask = valuator_mask_new(nvaluators);
|
||||
assert(mask != NULL);
|
||||
|
@ -1104,9 +1165,10 @@ static void dix_input_valuator_masks(void)
|
|||
for (i = 0; i < nvaluators; i++)
|
||||
{
|
||||
assert(!valuator_mask_isset(mask, i));
|
||||
valuator_mask_set(mask, i, valuators[i]);
|
||||
valuator_mask_set_double(mask, i, valuators[i]);
|
||||
assert(valuator_mask_isset(mask, i));
|
||||
assert(valuator_mask_get(mask, i) == valuators[i]);
|
||||
assert(valuator_mask_get(mask, i) == trunc(valuators[i]));
|
||||
assert(valuator_mask_get_double(mask, i) == valuators[i]);
|
||||
assert(valuator_mask_size(mask) == i + 1);
|
||||
assert(valuator_mask_num_valuators(mask) == i + 1);
|
||||
}
|
||||
|
@ -1132,7 +1194,7 @@ static void dix_input_valuator_masks(void)
|
|||
first_val = 5;
|
||||
num_vals = 6;
|
||||
|
||||
valuator_mask_set_range(mask, first_val, num_vals, valuators);
|
||||
valuator_mask_set_range(mask, first_val, num_vals, val_ranged);
|
||||
assert(valuator_mask_size(mask) == first_val + num_vals);
|
||||
assert(valuator_mask_num_valuators(mask) == num_vals);
|
||||
for (i = 0; i < nvaluators; i++)
|
||||
|
@ -1142,7 +1204,9 @@ static void dix_input_valuator_masks(void)
|
|||
else
|
||||
{
|
||||
assert(valuator_mask_isset(mask, i));
|
||||
assert(valuator_mask_get(mask, i) == valuators[i - first_val]);
|
||||
assert(valuator_mask_get(mask, i) == val_ranged[i - first_val]);
|
||||
assert(valuator_mask_get_double(mask, i) ==
|
||||
val_ranged[i - first_val]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1156,6 +1220,8 @@ static void dix_input_valuator_masks(void)
|
|||
{
|
||||
assert(valuator_mask_isset(mask, i) == valuator_mask_isset(copy, i));
|
||||
assert(valuator_mask_get(mask, i) == valuator_mask_get(copy, i));
|
||||
assert(valuator_mask_get_double(mask, i) ==
|
||||
valuator_mask_get_double(copy, i));
|
||||
}
|
||||
|
||||
valuator_mask_free(&mask);
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "extinit.h" /* for XInputExtensionInit */
|
||||
#include "exglobals.h"
|
||||
#include "xkbsrv.h" /* for XkbInitPrivates */
|
||||
#include "xserver-properties.h"
|
||||
#include <X11/extensions/XI2.h>
|
||||
|
||||
#include "protocol-common.h"
|
||||
|
||||
|
@ -63,6 +65,65 @@ static void fake_init_sprite(DeviceIntPtr dev)
|
|||
sprite->physLimits.y2 = screen.height;
|
||||
}
|
||||
|
||||
/* This is essentially CorePointerProc with ScrollAxes added */
|
||||
static int
|
||||
TestPointerProc(DeviceIntPtr pDev, int what)
|
||||
{
|
||||
#define NBUTTONS 10
|
||||
#define NAXES 4
|
||||
BYTE map[NBUTTONS + 1];
|
||||
int i = 0;
|
||||
Atom btn_labels[NBUTTONS] = {0};
|
||||
Atom axes_labels[NAXES] = {0};
|
||||
|
||||
switch (what) {
|
||||
case DEVICE_INIT:
|
||||
for (i = 1; i <= NBUTTONS; i++)
|
||||
map[i] = i;
|
||||
|
||||
btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
|
||||
btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
|
||||
btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
|
||||
btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
|
||||
btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
|
||||
btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
|
||||
btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
|
||||
/* don't know about the rest */
|
||||
|
||||
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
|
||||
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
|
||||
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL);
|
||||
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL);
|
||||
|
||||
if (!InitPointerDeviceStruct((DevicePtr)pDev, map, NBUTTONS, btn_labels,
|
||||
(PtrCtrlProcPtr)NoopDDA,
|
||||
GetMotionHistorySize(), NAXES, axes_labels))
|
||||
{
|
||||
ErrorF("Could not initialize device '%s'. Out of memory.\n",
|
||||
pDev->name);
|
||||
return BadAlloc;
|
||||
}
|
||||
pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
|
||||
pDev->last.valuators[0] = pDev->valuator->axisVal[0];
|
||||
pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
|
||||
pDev->last.valuators[1] = pDev->valuator->axisVal[1];
|
||||
|
||||
SetScrollValuator(pDev, 2, SCROLL_TYPE_VERTICAL, 2.4, SCROLL_FLAG_NONE);
|
||||
SetScrollValuator(pDev, 3, SCROLL_TYPE_HORIZONTAL, 3.5, SCROLL_FLAG_PREFERRED);
|
||||
break;
|
||||
|
||||
case DEVICE_CLOSE:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Success;
|
||||
|
||||
#undef NBUTTONS
|
||||
#undef NAXES
|
||||
}
|
||||
/**
|
||||
* Create and init 2 master devices (VCP + VCK) and two slave devices, one
|
||||
* default mouse, one default keyboard.
|
||||
|
@ -84,7 +145,7 @@ struct devices init_devices(void)
|
|||
EnableDevice(devices.vck, FALSE);
|
||||
|
||||
AllocDevicePair(&client, "", &devices.mouse, &devices.kbd,
|
||||
CorePointerProc, CoreKeyboardProc, FALSE);
|
||||
TestPointerProc, CoreKeyboardProc, FALSE);
|
||||
ActivateDevice(devices.mouse, FALSE);
|
||||
ActivateDevice(devices.kbd, FALSE);
|
||||
EnableDevice(devices.mouse, FALSE);
|
||||
|
|
|
@ -41,6 +41,7 @@ static void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
|
|||
int nvals = 0;
|
||||
int bits_set;
|
||||
int len;
|
||||
uint32_t flagmask = 0;
|
||||
|
||||
if (swap)
|
||||
{
|
||||
|
@ -51,6 +52,7 @@ static void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
|
|||
swapl(&out->time);
|
||||
swapl(&out->detail);
|
||||
swaps(&out->valuators_len);
|
||||
swapl(&out->flags);
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,7 +63,17 @@ static void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
|
|||
assert(out->detail == in->detail.button);
|
||||
assert(out->deviceid == in->deviceid);
|
||||
assert(out->valuators_len >= bytes_to_int32(bits_to_bytes(sizeof(in->valuators.mask))));
|
||||
assert(out->flags == 0); /* FIXME: we don't set the flags yet */
|
||||
|
||||
switch (in->type) {
|
||||
case ET_RawMotion:
|
||||
case ET_RawButtonPress:
|
||||
case ET_RawButtonRelease:
|
||||
flagmask = XIPointerEmulated;
|
||||
break;
|
||||
default:
|
||||
flagmask = 0;
|
||||
}
|
||||
assert((out->flags & ~flagmask) == 0);
|
||||
|
||||
ptr = (unsigned char*)&out[1];
|
||||
bits_set = 0;
|
||||
|
@ -92,8 +104,8 @@ static void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
|
|||
value = (FP3232*)(((unsigned char*)&out[1]) + out->valuators_len * 4);
|
||||
value += nvals;
|
||||
|
||||
vi.integral = in->valuators.data[i];
|
||||
vi.frac = in->valuators.data_frac[i];
|
||||
vi.integral = trunc(in->valuators.data[i]);
|
||||
vi.frac = in->valuators.data[i] - vi.integral;
|
||||
|
||||
vo.integral = value->integral;
|
||||
vo.frac = value->frac;
|
||||
|
@ -108,8 +120,8 @@ static void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
|
|||
|
||||
raw_value = value + bits_set;
|
||||
|
||||
vi.integral = in->valuators.data_raw[i];
|
||||
vi.frac = in->valuators.data_raw_frac[i];
|
||||
vi.integral = trunc(in->valuators.data_raw[i]);
|
||||
vi.frac = in->valuators.data_raw[i] - vi.integral;
|
||||
|
||||
vo.integral = raw_value->integral;
|
||||
vo.frac = raw_value->frac;
|
||||
|
@ -247,10 +259,8 @@ static void test_convert_XIRawEvent(void)
|
|||
{
|
||||
XISetMask(in.valuators.mask, i);
|
||||
|
||||
in.valuators.data[i] = i;
|
||||
in.valuators.data_raw[i] = i + 10;
|
||||
in.valuators.data_frac[i] = i + 20;
|
||||
in.valuators.data_raw_frac[i] = i + 30;
|
||||
in.valuators.data[i] = i + (i * 0.0010);
|
||||
in.valuators.data_raw[i] = (i + 10) + (i * 0.0030);
|
||||
test_XIRawEvent(&in);
|
||||
XIClearMask(in.valuators.mask, i);
|
||||
}
|
||||
|
@ -305,6 +315,11 @@ static void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out,
|
|||
assert(out->sourceid == in->sourceid);
|
||||
|
||||
switch (in->type) {
|
||||
case ET_ButtonPress:
|
||||
case ET_Motion:
|
||||
case ET_ButtonRelease:
|
||||
flagmask = XIPointerEmulated;
|
||||
break;
|
||||
case ET_KeyPress:
|
||||
flagmask = XIKeyRepeat;
|
||||
break;
|
||||
|
@ -375,8 +390,8 @@ static void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out,
|
|||
{
|
||||
FP3232 vi, vo;
|
||||
|
||||
vi.integral = in->valuators.data[i];
|
||||
vi.frac = in->valuators.data_frac[i];
|
||||
vi.integral = trunc(in->valuators.data[i]);
|
||||
vi.frac = (in->valuators.data[i] - vi.integral) * (1UL << 32);
|
||||
|
||||
vo = *values;
|
||||
|
||||
|
@ -618,8 +633,7 @@ static void test_convert_XIDeviceEvent(void)
|
|||
{
|
||||
XISetMask(in.valuators.mask, i);
|
||||
|
||||
in.valuators.data[i] = i;
|
||||
in.valuators.data_frac[i] = i + 20;
|
||||
in.valuators.data[i] = i + (i * 0.0020);
|
||||
test_XIDeviceEvent(&in);
|
||||
XIClearMask(in.valuators.mask, i);
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ static void reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void
|
|||
dev = devices.mouse;
|
||||
assert(info->use == XISlavePointer);
|
||||
assert(info->attachment == devices.vcp->id);
|
||||
assert(info->num_classes == 3); /* 2 axes + button */
|
||||
assert(info->num_classes == 7); /* 4 axes + button + 2 scroll*/
|
||||
break;
|
||||
case 5: /* keyboard */
|
||||
dev = devices.kbd;
|
||||
|
@ -183,11 +183,48 @@ static void reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 2: /* VCP and mouse have the same properties */
|
||||
case 4:
|
||||
{
|
||||
assert(any->type == XIButtonClass ||
|
||||
any->type == XIValuatorClass);
|
||||
any->type == XIValuatorClass ||
|
||||
any->type == XIScrollClass);
|
||||
|
||||
if (any->type == XIScrollClass)
|
||||
{
|
||||
xXIScrollInfo *si = (xXIScrollInfo*)any;
|
||||
|
||||
if (client->swapped)
|
||||
{
|
||||
swaps(&si->number);
|
||||
swaps(&si->scroll_type);
|
||||
swapl(&si->increment.integral);
|
||||
swapl(&si->increment.frac);
|
||||
}
|
||||
assert(si->length == 6);
|
||||
assert(si->number == 2 || si->number == 3);
|
||||
if (si->number == 2) {
|
||||
assert(si->scroll_type == XIScrollTypeVertical);
|
||||
assert(!si->flags);
|
||||
}
|
||||
if (si->number == 3) {
|
||||
assert(si->scroll_type == XIScrollTypeHorizontal);
|
||||
assert(si->flags & XIScrollFlagPreferred);
|
||||
assert(!(si->flags & ~XIScrollFlagPreferred));
|
||||
}
|
||||
|
||||
assert(si->increment.integral == si->number);
|
||||
/* FIXME: frac testing with float/FP issues? */
|
||||
assert(si->increment.frac > 0.3 * (1UL << 32));
|
||||
assert(si->increment.frac < 0.6 * (1UL << 32));
|
||||
}
|
||||
|
||||
}
|
||||
/* fall through */
|
||||
case 2: /* VCP and mouse have the same properties except for scroll */
|
||||
{
|
||||
if (info->deviceid == 2 ) /* VCP */
|
||||
assert(any->type == XIButtonClass ||
|
||||
any->type == XIValuatorClass);
|
||||
|
||||
if (any->type == XIButtonClass)
|
||||
{
|
||||
|
@ -217,8 +254,10 @@ static void reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void
|
|||
}
|
||||
|
||||
assert(vi->length == 11);
|
||||
assert(vi->number == 0 ||
|
||||
vi->number == 1);
|
||||
assert(vi->number >= 0 && vi->number < 4);
|
||||
if (info->deviceid == 2) /* VCP */
|
||||
assert(vi->number < 2);
|
||||
|
||||
assert(vi->mode == XIModeRelative);
|
||||
/* device was set up as relative, so standard
|
||||
* values here. */
|
||||
|
|
|
@ -37,6 +37,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <X11/extensions/XIproto.h>
|
||||
#include "inputstr.h"
|
||||
#include "eventstr.h"
|
||||
#include "inpututils.h"
|
||||
#include <xkbsrv.h>
|
||||
#if !defined(WIN32)
|
||||
#include <sys/time.h>
|
||||
|
|
Loading…
Reference in New Issue
Block a user