Commit f5d50b46 authored by Keith Packard's avatar Keith Packard

Merge remote-tracking branch 'whot/next'

parents 57cd32e9 524e5445
......@@ -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++;
}
}
......
......@@ -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)
{
ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n",
__func__, device->name, i);
return;
}
filter = GetEventFilter(device, xi);
for (i = 0; i < screenInfo.numScreens; i++)
{
WindowPtr root;
InputClients *inputclients;
filter = GetEventFilter(device, xi);
root = screenInfo.screens[i]->root;
if (!GetClientsForDelivery(device, root, xi, filter, &inputclients))
continue;
for (i = 0; i < screenInfo.numScreens; i++)
DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1,
filter, NullGrab);
free(xi);
for (; inputclients; inputclients = inputclients->next)
{
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);
}
}
free(xi);
}
/* If the event goes to dontClient, don't send it and return 0. if
......
This diff is collapsed.
......@@ -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))
......
......@@ -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) {