aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesalib/configure.ac14
-rw-r--r--mesalib/src/glsl/glsl_types.cpp2
-rw-r--r--mesalib/src/mesa/drivers/dri/common/utils.c3
-rw-r--r--mesalib/src/mesa/main/hash_table.c3
-rw-r--r--mesalib/src/mesa/main/macros.h3
-rw-r--r--mesalib/src/mesa/main/set.c3
-rw-r--r--xorg-server/Xext/xtest.c17
-rw-r--r--xorg-server/Xi/exevents.c2
-rw-r--r--xorg-server/dix/devices.c46
-rw-r--r--xorg-server/dix/events.c6
-rw-r--r--xorg-server/dix/getevents.c75
-rw-r--r--xorg-server/dix/ptrveloc.c38
-rw-r--r--xorg-server/hw/dmx/config/xdmxconfig.c3
-rw-r--r--xorg-server/hw/xfree86/common/xf86Module.h2
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/lnx_acpi.c9
-rw-r--r--xorg-server/include/input.h3
-rw-r--r--xorg-server/include/inputstr.h8
-rw-r--r--xorg-server/include/list.h2
-rw-r--r--xorg-server/include/misc.h1
-rw-r--r--xorg-server/include/protocol-versions.h2
-rw-r--r--xorg-server/os/log.c21
-rwxr-xr-xxorg-server/os/utils.c32
-rw-r--r--xorg-server/randr/randrstr.h2
-rw-r--r--xorg-server/test/signal-logging.c200
-rw-r--r--xorg-server/xkb/xkbActions.c147
25 files changed, 416 insertions, 228 deletions
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index 6735fdcf0..d08bc2779 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -499,10 +499,16 @@ AC_CHECK_FUNC([dlopen], [DEFINES="$DEFINES -DHAVE_DLOPEN"],
[DEFINES="$DEFINES -DHAVE_DLOPEN"; DLOPEN_LIBS="-ldl"])])
AC_SUBST([DLOPEN_LIBS])
-AC_CHECK_FUNCS([clock_gettime], [CLOCK_LIB=],
- [AC_CHECK_LIB([rt], [clock_gettime], [CLOCK_LIB=-lrt],
- [AC_MSG_ERROR([Couldn't find clock_gettime])])])
-AC_SUBST([CLOCK_LIB])
+case "$host_os" in
+darwin*)
+ ;;
+*)
+ AC_CHECK_FUNCS([clock_gettime], [CLOCK_LIB=],
+ [AC_CHECK_LIB([rt], [clock_gettime], [CLOCK_LIB=-lrt],
+ [AC_MSG_ERROR([Couldn't find clock_gettime])])])
+ AC_SUBST([CLOCK_LIB])
+ ;;
+esac
dnl See if posix_memalign is available
AC_CHECK_FUNC([posix_memalign], [DEFINES="$DEFINES -DHAVE_POSIX_MEMALIGN"])
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index 4a2c87907..3b066d099 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -81,6 +81,7 @@ glsl_type::glsl_type(GLenum gl_type,
glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
const char *name) :
+ gl_type(0),
base_type(GLSL_TYPE_STRUCT),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
sampler_type(0), interface_packing(0),
@@ -103,6 +104,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
enum glsl_interface_packing packing, const char *name) :
+ gl_type(0),
base_type(GLSL_TYPE_INTERFACE),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
sampler_type(0), interface_packing((unsigned) packing),
diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c
index 062712bf3..ac0773b0d 100644
--- a/mesalib/src/mesa/drivers/dri/common/utils.c
+++ b/mesalib/src/mesa/drivers/dri/common/utils.c
@@ -32,6 +32,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
+#include "main/macros.h"
#include "main/mtypes.h"
#include "main/cpuinfo.h"
#include "main/extensions.h"
@@ -391,8 +392,6 @@ static const struct { unsigned int attrib, offset; } attribMap[] = {
__ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level)
};
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
-
/**
* Return the value of a configuration attribute. The attribute is
diff --git a/mesalib/src/mesa/main/hash_table.c b/mesalib/src/mesa/main/hash_table.c
index 2bd1929aa..af0510da1 100644
--- a/mesalib/src/mesa/main/hash_table.c
+++ b/mesalib/src/mesa/main/hash_table.c
@@ -44,10 +44,9 @@
#include <string.h>
#include "main/hash_table.h"
+#include "main/macros.h"
#include "ralloc.h"
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
-
static const uint32_t deleted_key_value;
/**
diff --git a/mesalib/src/mesa/main/macros.h b/mesalib/src/mesa/main/macros.h
index d1e81fe08..f6d38fb64 100644
--- a/mesalib/src/mesa/main/macros.h
+++ b/mesalib/src/mesa/main/macros.h
@@ -766,5 +766,8 @@ DIFFERENT_SIGNS(GLfloat x, GLfloat y)
#define ENUM_TO_DOUBLE(E) ((GLdouble)(GLint)(E))
#define ENUM_TO_BOOLEAN(E) ((E) ? GL_TRUE : GL_FALSE)
+/* Compute the size of an array */
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
#endif
diff --git a/mesalib/src/mesa/main/set.c b/mesalib/src/mesa/main/set.c
index 736841fc9..2519b9694 100644
--- a/mesalib/src/mesa/main/set.c
+++ b/mesalib/src/mesa/main/set.c
@@ -34,11 +34,10 @@
#include <stdlib.h>
+#include "macros.h"
#include "set.h"
#include "ralloc.h"
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
-
/*
* From Knuth -- a good choice for hash/rehash values is p, p-2 where
* p and p-2 are both prime. These tables are sized to have an extra 10%
diff --git a/xorg-server/Xext/xtest.c b/xorg-server/Xext/xtest.c
index e7f94d3d9..b0b974c78 100644
--- a/xorg-server/Xext/xtest.c
+++ b/xorg-server/Xext/xtest.c
@@ -153,7 +153,6 @@ ProcXTestFakeInput(ClientPtr client)
DeviceIntPtr dev = NULL;
WindowPtr root;
Bool extension = FALSE;
- deviceValuator *dv = NULL;
ValuatorMask mask;
int valuators[MAX_VALUATORS] = { 0 };
int numValuators = 0;
@@ -238,14 +237,14 @@ ProcXTestFakeInput(ClientPtr client)
}
if (nev > 1 && !dev->valuator) {
- client->errorValue = dv->first_valuator;
+ client->errorValue = firstValuator;
return BadValue;
}
/* check validity of valuator events */
base = firstValuator;
for (n = 1; n < nev; n++) {
- dv = (deviceValuator *) (ev + n);
+ deviceValuator *dv = (deviceValuator *) (ev + n);
if (dv->type != DeviceValuator) {
client->errorValue = dv->type;
return BadValue;
@@ -303,7 +302,7 @@ ProcXTestFakeInput(ClientPtr client)
numValuators = 2;
firstValuator = 0;
if (ev->u.u.detail == xFalse)
- flags = POINTER_ABSOLUTE | POINTER_SCREEN;
+ flags = POINTER_ABSOLUTE | POINTER_DESKTOP;
break;
default:
client->errorValue = ev->u.u.type;
@@ -374,6 +373,14 @@ ProcXTestFakeInput(ClientPtr client)
client->errorValue = ev->u.keyButtonPointer.root;
return BadValue;
}
+
+ /* Add the root window's offset to the valuators */
+ if ((flags & POINTER_ABSOLUTE) && firstValuator <= 1 && numValuators > 0) {
+ if (firstValuator == 0)
+ valuators[0] += root->drawable.pScreen->x;
+ if (firstValuator < 2 && firstValuator + numValuators > 1)
+ valuators[1 - firstValuator] += root->drawable.pScreen->y;
+ }
}
if (ev->u.u.detail != xTrue && ev->u.u.detail != xFalse) {
client->errorValue = ev->u.u.detail;
@@ -416,7 +423,7 @@ ProcXTestFakeInput(ClientPtr client)
}
for (i = 0; i < nevents; i++)
- mieqProcessDeviceEvent(dev, &xtest_evlist[i], NULL);
+ mieqProcessDeviceEvent(dev, &xtest_evlist[i], miPointerGetScreen(inputInfo.pointer));
if (need_ptr_update)
miPointerUpdateSprite(dev);
diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c
index 2ff2471c5..079de15bf 100644
--- a/xorg-server/Xi/exevents.c
+++ b/xorg-server/Xi/exevents.c
@@ -1265,7 +1265,7 @@ TouchCopyValuatorData(DeviceEvent *ev, TouchPointInfoPtr ti)
{
int i;
- for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+ for (i = 0; i < ARRAY_SIZE(ev->valuators.data); i++)
if (BitIsOn(ev->valuators.mask, i))
valuator_mask_set_double(ti->valuators, i, ev->valuators.data[i]);
}
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c
index f82b81ec0..0df1d3834 100644
--- a/xorg-server/dix/devices.c
+++ b/xorg-server/dix/devices.c
@@ -97,9 +97,10 @@ SOFTWARE.
static void RecalculateMasterButtons(DeviceIntPtr slave);
static void
-DeviceSetTransform(DeviceIntPtr dev, float *transform)
+DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
{
struct pixman_f_transform scale;
+ struct pixman_f_transform transform;
double sx, sy;
int x, y;
@@ -126,16 +127,21 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform)
/* transform */
for (y = 0; y < 3; y++)
for (x = 0; x < 3; x++)
- dev->transform.m[y][x] = *transform++;
+ transform.m[y][x] = *transform_data++;
- pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
+ pixman_f_transform_multiply(&dev->scale_and_transform, &scale, &transform);
/* scale */
pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
- pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
+ pixman_f_transform_multiply(&dev->scale_and_transform, &dev->scale_and_transform, &scale);
+
+ /* remove translation component for relative movements */
+ dev->relative_transform = transform;
+ dev->relative_transform.m[0][2] = 0;
+ dev->relative_transform.m[1][2] = 0;
}
/**
@@ -312,9 +318,10 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
/* unity matrix */
memset(transform, 0, sizeof(transform));
transform[0] = transform[4] = transform[8] = 1.0f;
- dev->transform.m[0][0] = 1.0;
- dev->transform.m[1][1] = 1.0;
- dev->transform.m[2][2] = 1.0;
+ dev->relative_transform.m[0][0] = 1.0;
+ dev->relative_transform.m[1][1] = 1.0;
+ dev->relative_transform.m[2][2] = 1.0;
+ dev->scale_and_transform = dev->relative_transform;
XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
XIGetKnownProperty(XATOM_FLOAT), 32,
@@ -521,6 +528,12 @@ DisableAllDevices(void)
{
DeviceIntPtr dev, tmp;
+ /* Disable slave devices first, excluding XTest devices */
+ nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
+ if (!IsXTestDevice(dev, NULL) && !IsMaster(dev))
+ DisableDevice(dev, FALSE);
+ }
+ /* Disable XTest devices */
nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
if (!IsMaster(dev))
DisableDevice(dev, FALSE);
@@ -1052,6 +1065,25 @@ CloseDownDevices(void)
}
/**
+ * Signal all devices that we're in the process of aborting.
+ * This function is called from a signal handler.
+ */
+void
+AbortDevices(void)
+{
+ DeviceIntPtr dev;
+ nt_list_for_each_entry(dev, inputInfo.devices, next) {
+ if (!IsMaster(dev))
+ (*dev->deviceProc) (dev, DEVICE_ABORT);
+ }
+
+ nt_list_for_each_entry(dev, inputInfo.off_devices, next) {
+ if (!IsMaster(dev))
+ (*dev->deviceProc) (dev, DEVICE_ABORT);
+ }
+}
+
+/**
* Remove the cursor sprite for all devices. This needs to be done before any
* resources are freed or any device is deleted.
*/
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c
index cb9440b7c..f895365d6 100644
--- a/xorg-server/dix/events.c
+++ b/xorg-server/dix/events.c
@@ -4575,6 +4575,7 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
{
GrabPtr grab = mouse->deviceGrab.grab;
xXIEnterEvent *event;
+ WindowPtr focus;
int filter;
int btlen, len, i;
DeviceIntPtr kbd;
@@ -4616,6 +4617,11 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
event->group.locked_group = kbd->key->xkbInfo->state.locked_group;
}
+ focus = (kbd) ? kbd->focus->win : None;
+ if ((focus != NoneWin) &&
+ ((pWin == focus) || (focus == PointerRootWin) || IsParent(focus, pWin)))
+ event->focus = TRUE;
+
FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent *) event, pWin,
None, FALSE);
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c
index ad45149d2..8d9f9a54e 100644
--- a/xorg-server/dix/getevents.c
+++ b/xorg-server/dix/getevents.c
@@ -791,11 +791,33 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
* @param[in,out] mask Valuator data for this event, modified in-place.
*/
static void
-moveRelative(DeviceIntPtr dev, ValuatorMask *mask)
+moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
{
int i;
Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
+ /* for abs devices in relative mode, we've just scaled wrong, since we
+ mapped the device's shape into the screen shape. Undo this. */
+ if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator &&
+ dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) {
+
+ double ratio = 1.0 * screenInfo.width/screenInfo.height;
+
+ if (ratio > 1.0) {
+ double y;
+ if (valuator_mask_fetch_double(mask, 1, &y)) {
+ y *= ratio;
+ valuator_mask_set_double(mask, 1, y);
+ }
+ } else {
+ double x;
+ if (valuator_mask_fetch_double(mask, 0, &x)) {
+ x *= ratio;
+ valuator_mask_set_double(mask, 0, x);
+ }
+ }
+ }
+
/* calc other axes, clip, drop back into valuators */
for (i = 0; i < valuator_mask_size(mask); i++) {
double val = dev->last.valuators[i];
@@ -835,27 +857,33 @@ accelPointer(DeviceIntPtr dev, ValuatorMask *valuators, CARD32 ms)
* device's coordinate range.
*
* @param dev The device to scale for.
- * @param[in, out] mask The mask in desktop coordinates, modified in place
+ * @param[in, out] mask The mask in desktop/screen coordinates, modified in place
* to contain device coordinate range.
+ * @param flags If POINTER_SCREEN is set, mask is in per-screen coordinates.
+ * Otherwise, mask is in desktop coords.
*/
static void
-scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask)
+scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask, int flags)
{
double scaled;
ScreenPtr scr = miPointerGetScreen(dev);
if (valuator_mask_isset(mask, 0)) {
- scaled = valuator_mask_get_double(mask, 0) + scr->x;
+ scaled = valuator_mask_get_double(mask, 0);
+ if (flags & POINTER_SCREEN)
+ scaled += scr->x;
scaled = rescaleValuatorAxis(scaled,
NULL, dev->valuator->axes + 0,
- 0, scr->width);
+ screenInfo.x, screenInfo.width);
valuator_mask_set_double(mask, 0, scaled);
}
if (valuator_mask_isset(mask, 1)) {
- scaled = valuator_mask_get_double(mask, 1) + scr->y;
+ scaled = valuator_mask_get_double(mask, 1);
+ if (flags & POINTER_SCREEN)
+ scaled += scr->y;
scaled = rescaleValuatorAxis(scaled,
NULL, dev->valuator->axes + 1,
- 0, scr->height);
+ screenInfo.y, screenInfo.height);
valuator_mask_set_double(mask, 1, scaled);
}
}
@@ -1194,6 +1222,27 @@ transform(struct pixman_f_transform *m, double *x, double *y)
*y = p.v[1];
}
+static void
+transformRelative(DeviceIntPtr dev, ValuatorMask *mask)
+{
+ double x = 0, y = 0;
+
+ valuator_mask_fetch_double(mask, 0, &x);
+ valuator_mask_fetch_double(mask, 1, &y);
+
+ transform(&dev->relative_transform, &x, &y);
+
+ if (x)
+ valuator_mask_set_double(mask, 0, x);
+ else
+ valuator_mask_unset(mask, 0);
+
+ if (y)
+ valuator_mask_set_double(mask, 1, y);
+ else
+ valuator_mask_unset(mask, 1);
+}
+
/**
* Apply the device's transformation matrix to the valuator mask and replace
* the scaled values in mask. This transformation only applies to valuators
@@ -1221,7 +1270,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
ox = dev->last.valuators[0];
oy = dev->last.valuators[1];
- pixman_f_transform_invert(&invert, &dev->transform);
+ pixman_f_transform_invert(&invert, &dev->scale_and_transform);
transform(&invert, &ox, &oy);
x = ox;
@@ -1234,7 +1283,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
if (valuator_mask_isset(mask, 1))
oy = y = valuator_mask_get_double(mask, 1);
- transform(&dev->transform, &x, &y);
+ transform(&dev->scale_and_transform, &x, &y);
if (valuator_mask_isset(mask, 0) || ox != x)
valuator_mask_set_double(mask, 0, x);
@@ -1383,10 +1432,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
/* valuators are in driver-native format (rel or abs) */
if (flags & POINTER_ABSOLUTE) {
- if (flags & POINTER_SCREEN) { /* valuators are in screen coords */
+ if (flags & (POINTER_SCREEN | POINTER_DESKTOP)) { /* valuators are in screen/desktop coords */
sx = valuator_mask_get(&mask, 0);
sy = valuator_mask_get(&mask, 1);
- scale_from_screen(pDev, &mask);
+ scale_from_screen(pDev, &mask, flags);
}
transformAbsolute(pDev, &mask);
@@ -1395,12 +1444,14 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
set_raw_valuators(raw, &mask, raw->valuators.data);
}
else {
+ transformRelative(pDev, &mask);
+
if (flags & POINTER_ACCELERATE)
accelPointer(pDev, &mask, ms);
if ((flags & POINTER_NORAW) == 0)
set_raw_valuators(raw, &mask, raw->valuators.data);
- moveRelative(pDev, &mask);
+ moveRelative(pDev, flags, &mask);
}
/* valuators are in device coordinate system in absolute coordinates */
diff --git a/xorg-server/dix/ptrveloc.c b/xorg-server/dix/ptrveloc.c
index 7d3d9f938..844e18538 100644
--- a/xorg-server/dix/ptrveloc.c
+++ b/xorg-server/dix/ptrveloc.c
@@ -86,7 +86,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr,
/*#define PTRACCEL_DEBUGGING*/
#ifdef PTRACCEL_DEBUGGING
-#define DebugAccelF ErrorF
+#define DebugAccelF(...) ErrorFSigSafe("dix/ptraccel: " __VA_ARGS__)
#else
#define DebugAccelF(...) /* */
#endif
@@ -430,7 +430,7 @@ void
InitTrackers(DeviceVelocityPtr vel, int ntracker)
{
if (ntracker < 1) {
- ErrorF("(dix ptracc) invalid number of trackers\n");
+ ErrorF("invalid number of trackers\n");
return;
}
free(vel->tracker);
@@ -575,7 +575,7 @@ FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t)
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",
+ DebugAccelF("motion [dx: %f dy: %f dir:%d diff: %d]\n",
dx, dy, vel->tracker[n].dir,
cur_t - vel->tracker[vel->cur_tracker].time);
vel->cur_tracker = n;
@@ -623,7 +623,8 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
/* bail out if data is too old and protect from overrun */
if (age_ms >= vel->reset_time || age_ms < 0) {
- DebugAccelF("(dix prtacc) query: tracker too old\n");
+ DebugAccelF("query: tracker too old (reset after %d, age is %d)\n",
+ vel->reset_time, age_ms);
break;
}
@@ -635,7 +636,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
*/
dir &= tracker->dir;
if (dir == 0) { /* we've changed octant of movement (e.g. NE → NW) */
- DebugAccelF("(dix prtacc) query: no longer linear\n");
+ DebugAccelF("query: no longer linear\n");
/* instead of breaking it we might also inspect the partition after,
* but actual improvement with this is probably rare. */
break;
@@ -656,7 +657,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
velocity_diff / (initial_velocity + tracker_velocity) >=
vel->max_rel_diff) {
/* we're not in range, quit - it won't get better. */
- DebugAccelF("(dix prtacc) query: tracker too different:"
+ DebugAccelF("query: tracker too different:"
" old %2.2f initial %2.2f diff: %2.2f\n",
tracker_velocity, initial_velocity, velocity_diff);
break;
@@ -669,14 +670,14 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
}
}
if (offset == vel->num_tracker) {
- DebugAccelF("(dix prtacc) query: last tracker in effect\n");
+ DebugAccelF("query: last tracker in effect\n");
used_offset = vel->num_tracker - 1;
}
if (used_offset >= 0) {
#ifdef PTRACCEL_DEBUGGING
MotionTracker *tracker = TRACKER(vel, used_offset);
- DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
+ DebugAccelF("result: offset %i [dx: %f dy: %f diff: %i]\n",
used_offset, tracker->dx, tracker->dy,
cur_t - tracker->time);
#endif
@@ -702,6 +703,8 @@ ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time)
velocity = QueryTrackers(vel, time);
+ DebugAccelF("velocity is %f\n", velocity);
+
vel->velocity = velocity;
return velocity == 0;
}
@@ -777,7 +780,7 @@ ComputeAcceleration(DeviceIntPtr dev,
double result;
if (vel->velocity <= 0) {
- DebugAccelF("(dix ptracc) profile skipped\n");
+ DebugAccelF("profile skipped\n");
/*
* If we have no idea about device velocity, don't pretend it.
*/
@@ -801,14 +804,14 @@ ComputeAcceleration(DeviceIntPtr dev,
threshold,
acc);
result /= 6.0f;
- DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
+ DebugAccelF("profile average [%.2f ... %.2f] is %.3f\n",
vel->velocity, vel->last_velocity, result);
}
else {
result = BasicComputeAcceleration(dev, vel,
vel->velocity, threshold, acc);
- DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
- vel->velocity, res);
+ DebugAccelF("profile sample [%.2f] is %.3f\n",
+ vel->velocity, result);
}
return result;
@@ -1059,11 +1062,8 @@ SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel,
DeviceVelocityPtr
GetDevicePredictableAccelData(DeviceIntPtr dev)
{
- /*sanity check */
- if (!dev) {
- ErrorF("[dix] accel: DeviceIntPtr was NULL");
- return NULL;
- }
+ BUG_RETURN_VAL(!dev, NULL);
+
if (dev->valuator &&
dev->valuator->accelScheme.AccelSchemeProc ==
acceleratePointerPredictable &&
@@ -1122,6 +1122,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
(double) dev->ptrfeed->ctrl.num /
(double) dev->ptrfeed->ctrl.den);
+ DebugAccelF("mult is %f\n", mult);
if (mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
if (mult > 1.0f && soften)
ApplySoftening(velocitydata, &dx, &dy);
@@ -1131,8 +1132,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
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);
+ DebugAccelF("delta x:%.3f y:%.3f\n", mult * dx, mult * dy);
}
}
}
diff --git a/xorg-server/hw/dmx/config/xdmxconfig.c b/xorg-server/hw/dmx/config/xdmxconfig.c
index f30841244..2121dd781 100644
--- a/xorg-server/hw/dmx/config/xdmxconfig.c
+++ b/xorg-server/hw/dmx/config/xdmxconfig.c
@@ -31,9 +31,6 @@
*
*/
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
#include <stdio.h>
#include <stdlib.h>
diff --git a/xorg-server/hw/xfree86/common/xf86Module.h b/xorg-server/hw/xfree86/common/xf86Module.h
index e545c1498..1393427f8 100644
--- a/xorg-server/hw/xfree86/common/xf86Module.h
+++ b/xorg-server/hw/xfree86/common/xf86Module.h
@@ -81,7 +81,7 @@ typedef enum {
*/
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(14, 1)
-#define ABI_XINPUT_VERSION SET_ABI_VERSION(19, 0)
+#define ABI_XINPUT_VERSION SET_ABI_VERSION(19, 1)
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(7, 0)
#define ABI_FONT_VERSION SET_ABI_VERSION(0, 6)
diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_acpi.c b/xorg-server/hw/xfree86/os-support/linux/lnx_acpi.c
index d98efa247..dcaa19ee1 100644
--- a/xorg-server/hw/xfree86/os-support/linux/lnx_acpi.c
+++ b/xorg-server/hw/xfree86/os-support/linux/lnx_acpi.c
@@ -82,18 +82,21 @@ lnxACPIGetEventFromOs(int fd, pmEvent * events, int num)
video = strtok(ev, " ");
- GFX = strtok(NULL, " ");
+ if (!(GFX = strtok(NULL, " ")))
+ return 0;
#if 0
ErrorF("GFX: %s\n", GFX);
#endif
- notify = strtok(NULL, " ");
+ if (!(notify = strtok(NULL, " ")))
+ return 0;
notify_l = strtoul(notify, NULL, 16);
#if 0
ErrorF("notify: 0x%lx\n", notify_l);
#endif
- data = strtok(NULL, " ");
+ if (!(data = strtok(NULL, " ")))
+ return 0;
data_l = strtoul(data, NULL, 16);
#if 0
ErrorF("data: 0x%lx\n", data_l);
diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h
index f53ed9905..5c65597e4 100644
--- a/xorg-server/include/input.h
+++ b/xorg-server/include/input.h
@@ -62,6 +62,7 @@ SOFTWARE.
#define DEVICE_ON 1
#define DEVICE_OFF 2
#define DEVICE_CLOSE 3
+#define DEVICE_ABORT 4
#define POINTER_RELATIVE (1 << 1)
#define POINTER_ABSOLUTE (1 << 2)
@@ -69,6 +70,7 @@ SOFTWARE.
#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 */
+#define POINTER_DESKTOP (1 << 7) /* Data in desktop coordinates */
/* GetTouchEvent flags */
#define TOUCH_ACCEPT (1 << 0)
@@ -268,6 +270,7 @@ extern void DisableAllDevices(void);
extern int InitAndStartDevices(void);
extern void CloseDownDevices(void);
+extern void AbortDevices(void);
extern void UndisplayDevices(void);
diff --git a/xorg-server/include/inputstr.h b/xorg-server/include/inputstr.h
index 48a29bede..de96faeda 100644
--- a/xorg-server/include/inputstr.h
+++ b/xorg-server/include/inputstr.h
@@ -588,8 +588,12 @@ typedef struct _DeviceIntRec {
XIPropertyHandlerPtr handlers; /* NULL-terminated */
} properties;
- /* coordinate transformation matrix for absolute input devices */
- struct pixman_f_transform transform;
+ /* coordinate transformation matrix for relative movement. Matrix with
+ * the translation component dropped */
+ struct pixman_f_transform relative_transform;
+ /* scale matrix for absolute devices, this is the combined matrix of
+ [1/scale] . [transform] . [scale]. See DeviceSetTransform */
+ struct pixman_f_transform scale_and_transform;
/* XTest related master device id */
int xtest_master_id;
diff --git a/xorg-server/include/list.h b/xorg-server/include/list.h
index 61b10bd2a..cb5caf881 100644
--- a/xorg-server/include/list.h
+++ b/xorg-server/include/list.h
@@ -358,7 +358,7 @@ xorg_list_is_empty(struct xorg_list *head)
* struct foo *element = list;
* while ((element = nt_list_next(element, next)) { }
*
- * This macro is not safe for node deletion. Use xorg_list_for_each_entry_safe
+ * This macro is not safe for node deletion. Use nt_list_for_each_entry_safe
* instead.
*
* @param list The list or current element.
diff --git a/xorg-server/include/misc.h b/xorg-server/include/misc.h
index 9ed54b1a8..664e02cae 100644
--- a/xorg-server/include/misc.h
+++ b/xorg-server/include/misc.h
@@ -260,6 +260,7 @@ extern char **xstrtokenize(const char *str, const char *separators);
extern void FormatInt64(int64_t num, char *string);
extern void FormatUInt64(uint64_t num, char *string);
extern void FormatUInt64Hex(uint64_t num, char *string);
+extern void FormatDouble(double dbl, char *string);
/**
* Compare the two version numbers comprising of major.minor.
diff --git a/xorg-server/include/protocol-versions.h b/xorg-server/include/protocol-versions.h
index 10f5117f2..5ceaeb012 100644
--- a/xorg-server/include/protocol-versions.h
+++ b/xorg-server/include/protocol-versions.h
@@ -65,7 +65,7 @@
/* RandR */
#define SERVER_RANDR_MAJOR_VERSION 1
-#define SERVER_RANDR_MINOR_VERSION 3
+#define SERVER_RANDR_MINOR_VERSION 4
/* Record */
#define SERVER_RECORD_MAJOR_VERSION 1
diff --git a/xorg-server/os/log.c b/xorg-server/os/log.c
index 23f181d8d..a65b03c66 100644
--- a/xorg-server/os/log.c
+++ b/xorg-server/os/log.c
@@ -304,7 +304,13 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
continue;
}
- switch (f[++f_idx]) {
+ f_idx++;
+
+ /* silently swallow length modifiers */
+ while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.'))
+ f_idx++;
+
+ switch (f[f_idx]) {
case 's':
string_arg = va_arg(args, char*);
p_len = strlen_sigsafe(string_arg);
@@ -351,7 +357,16 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
for (i = 0; i < p_len && s_idx < size - 1; i++)
string[s_idx++] = number[i];
break;
-
+ case 'f':
+ {
+ double d = va_arg(args, double);
+ FormatDouble(d, number);
+ p_len = strlen_sigsafe(number);
+
+ for (i = 0; i < p_len && s_idx < size - 1; i++)
+ string[s_idx++] = number[i];
+ }
+ break;
default:
va_arg(args, char*);
string[s_idx++] = '%';
@@ -654,7 +669,7 @@ AbortServer(void)
#endif
CloseWellKnownConnections();
OsCleanup(TRUE);
- CloseDownDevices();
+ AbortDevices();
AbortDDX(EXIT_ERR_ABORT);
fflush(stderr);
if (CoreDump)
diff --git a/xorg-server/os/utils.c b/xorg-server/os/utils.c
index 518400cfd..750bd8dfb 100755
--- a/xorg-server/os/utils.c
+++ b/xorg-server/os/utils.c
@@ -2048,6 +2048,38 @@ FormatUInt64(uint64_t num, char *string)
string[len] = '\0';
}
+/**
+ * Format a double number as %.2f.
+ */
+void
+FormatDouble(double dbl, char *string)
+{
+ int slen = 0;
+ uint64_t frac;
+
+ frac = (dbl > 0 ? dbl : -dbl) * 100.0 + 0.5;
+ frac %= 100;
+
+ /* write decimal part to string */
+ if (dbl < 0 && dbl > -1)
+ string[slen++] = '-';
+ FormatInt64((int64_t)dbl, &string[slen]);
+
+ while(string[slen] != '\0')
+ slen++;
+
+ /* append fractional part, but only if we have enough characters. We
+ * expect string to be 21 chars (incl trailing \0) */
+ if (slen <= 17) {
+ string[slen++] = '.';
+ if (frac < 10)
+ string[slen++] = '0';
+
+ FormatUInt64(frac, &string[slen]);
+ }
+}
+
+
/* Format a number into a hexadecimal string in a signal safe manner. The string
* should be at least 17 characters in order to handle all uint64_t values. */
void
diff --git a/xorg-server/randr/randrstr.h b/xorg-server/randr/randrstr.h
index a16302f4d..f52d0f284 100644
--- a/xorg-server/randr/randrstr.h
+++ b/xorg-server/randr/randrstr.h
@@ -57,7 +57,7 @@
#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */
#define RANDR_GET_CRTC_INTERFACE 1
-#define RANDR_INTERFACE_VERSION 0x0103
+#define RANDR_INTERFACE_VERSION 0x0104
typedef XID RRMode;
typedef XID RROutput;
diff --git a/xorg-server/test/signal-logging.c b/xorg-server/test/signal-logging.c
index 810bd20ed..1ef17af2c 100644
--- a/xorg-server/test/signal-logging.c
+++ b/xorg-server/test/signal-logging.c
@@ -41,15 +41,41 @@ struct signed_number_format_test {
char string[21];
};
+struct float_number_format_test {
+ double number;
+ char string[21];
+};
+
+static Bool
+check_signed_number_format_test(long int number)
+{
+ char string[21];
+ char expected[21];
+
+ sprintf(expected, "%ld", number);
+ FormatInt64(number, string);
+ if(strncmp(string, expected, 21) != 0) {
+ fprintf(stderr, "Failed to convert %jd to decimal string (expected %s but got %s)\n",
+ number, expected, string);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static Bool
-check_signed_number_format_test(const struct signed_number_format_test *test)
+check_float_format_test(double number)
{
char string[21];
+ char expected[21];
+
+ /* we currently always print float as .2f */
+ sprintf(expected, "%.2f", number);
- FormatInt64(test->number, string);
- if(strncmp(string, test->string, 21) != 0) {
- fprintf(stderr, "Failed to convert %jd to decimal string (%s vs %s)\n",
- test->number, test->string, string);
+ FormatDouble(number, string);
+ if(strncmp(string, expected, 21) != 0) {
+ fprintf(stderr, "Failed to convert %f to string (%s vs %s)\n",
+ number, expected, string);
return FALSE;
}
@@ -57,125 +83,71 @@ check_signed_number_format_test(const struct signed_number_format_test *test)
}
static Bool
-check_number_format_test(const struct number_format_test *test)
+check_number_format_test(long unsigned int number)
{
char string[21];
+ char expected[21];
- FormatUInt64(test->number, string);
- if(strncmp(string, test->string, 21) != 0) {
+ sprintf(expected, "%lu", number);
+
+ FormatUInt64(number, string);
+ if(strncmp(string, expected, 21) != 0) {
fprintf(stderr, "Failed to convert %ju to decimal string (%s vs %s)\n",
- test->number, test->string, string);
+ number, expected, string);
return FALSE;
}
- FormatUInt64Hex(test->number, string);
- if(strncmp(string, test->hex_string, 17) != 0) {
- fprintf(stderr,
- "Failed to convert %ju to hexadecimal string (%s vs %s)\n",
- test->number, test->hex_string, string);
+
+ sprintf(expected, "%lx", number);
+ FormatUInt64Hex(number, string);
+ if(strncmp(string, expected, 17) != 0) {
+ fprintf(stderr, "Failed to convert %ju to hexadecimal string (%s vs %s)\n",
+ number, expected, string);
return FALSE;
}
return TRUE;
}
+/* FIXME: max range stuff */
+double float_tests[] = { 0, 5, 0.1, 0.01, 5.2342, 10.2301,
+ -1, -2.00, -0.6023, -1203.30
+ };
+
static void
number_formatting(void)
{
int i;
- struct number_format_test unsigned_tests[] = {
- { /* Zero */
- 0,
- "0",
- "0",
- },
- { /* Single digit number */
- 5,
- "5",
- "5",
- },
- { /* Two digit decimal number */
- 12,
- "12",
- "c",
- },
- { /* Two digit hex number */
- 37,
- "37",
- "25",
- },
- { /* Large < 32 bit number */
- 0xC90B2,
- "823474",
- "c90b2",
- },
- { /* Large > 32 bit number */
- 0x15D027BF211B37A,
- "98237498237498234",
- "15d027bf211b37a",
- },
- { /* Maximum 64-bit number */
- 0xFFFFFFFFFFFFFFFF,
- "18446744073709551615",
- "ffffffffffffffff",
- },
+ long unsigned int unsigned_tests[] = { 0,/* Zero */
+ 5, /* Single digit number */
+ 12, /* Two digit decimal number */
+ 37, /* Two digit hex number */
+ 0xC90B2, /* Large < 32 bit number */
+ 0x15D027BF211B37A, /* Large > 32 bit number */
+ 0xFFFFFFFFFFFFFFFF, /* Maximum 64-bit number */
};
- struct signed_number_format_test signed_tests[] = {
- { /* Zero */
- 0,
- "0",
- },
- { /* Single digit number */
- 5,
- "5",
- },
- { /* Two digit decimal number */
- 12,
- "12",
- },
- { /* Two digit hex number */
- 37,
- "37",
- },
- { /* Large < 32 bit number */
- 0xC90B2,
- "823474",
- },
- { /* Large > 32 bit number */
- 0x15D027BF211B37A,
- "98237498237498234",
- },
- { /* Maximum 64-bit signed number */
- 0x7FFFFFFFFFFFFFFF,
- "9223372036854775807",
- },
- { /* Single digit number */
- -1,
- "-1",
- },
- { /* Two digit decimal number */
- -12,
- "-12",
- },
- { /* Large < 32 bit number */
- -0xC90B2,
- "-823474",
- },
- { /* Large > 32 bit number */
- -0x15D027BF211B37A,
- "-98237498237498234",
- },
- { /* Maximum 64-bit number */
- -0x7FFFFFFFFFFFFFFF,
- "-9223372036854775807",
- },
- };
+ long int signed_tests[] = { 0,/* Zero */
+ 5, /* Single digit number */
+ 12, /* Two digit decimal number */
+ 37, /* Two digit hex number */
+ 0xC90B2, /* Large < 32 bit number */
+ 0x15D027BF211B37A, /* Large > 32 bit number */
+ 0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */
+ -1, /* Single digit number */
+ -12, /* Two digit decimal number */
+ -0xC90B2, /* Large < 32 bit number */
+ -0x15D027BF211B37A, /* Large > 32 bit number */
+ -0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */
+ } ;
for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); i++)
- assert(check_number_format_test(unsigned_tests + i));
+ assert(check_number_format_test(unsigned_tests[i]));
for (i = 0; i < sizeof(unsigned_tests) / sizeof(signed_tests[0]); i++)
- assert(check_signed_number_format_test(signed_tests + i));
+ assert(check_signed_number_format_test(signed_tests[i]));
+
+ for (i = 0; i < sizeof(float_tests) / sizeof(float_tests[0]); i++)
+ assert(check_float_format_test(float_tests[i]));
}
#pragma GCC diagnostic ignored "-Wformat-security"
@@ -292,6 +264,30 @@ static void logging_format(void)
ptr <<= 1;
} while(ptr);
+
+ for (i = 0; i < sizeof(float_tests)/sizeof(float_tests[0]); i++) {
+ double d = float_tests[i];
+ char expected[30];
+ sprintf(expected, "(EE) %.2f\n", d);
+ LogMessageVerbSigSafe(X_ERROR, -1, "%f\n", d);
+ read_log_msg(logmsg);
+ assert(strcmp(logmsg, expected) == 0);
+
+ /* test for length modifiers, we just ignore them atm */
+ LogMessageVerbSigSafe(X_ERROR, -1, "%.3f\n", d);
+ read_log_msg(logmsg);
+ assert(strcmp(logmsg, expected) == 0);
+
+ LogMessageVerbSigSafe(X_ERROR, -1, "%3f\n", d);
+ read_log_msg(logmsg);
+ assert(strcmp(logmsg, expected) == 0);
+
+ LogMessageVerbSigSafe(X_ERROR, -1, "%.0f\n", d);
+ read_log_msg(logmsg);
+ assert(strcmp(logmsg, expected) == 0);
+ }
+
+
LogClose(EXIT_NO_ERROR);
unlink(log_file_path);
diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c
index c1edeea55..f089bf0fa 100644
--- a/xorg-server/xkb/xkbActions.c
+++ b/xorg-server/xkb/xkbActions.c
@@ -747,6 +747,15 @@ _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
XkbMessageAction *pMsg;
DeviceIntPtr kbd;
+ if ((filter->keycode != 0) && (filter->keycode != keycode))
+ return 1;
+
+ /* This can happen if the key repeats, and the state (modifiers or group)
+ changes meanwhile. */
+ if ((filter->keycode == keycode) && pAction &&
+ (pAction->type != XkbSA_ActionMessage))
+ return 1;
+
kbd = xkbi->device;
if (filter->keycode == 0) { /* initial press */
pMsg = &pAction->msg;
@@ -774,20 +783,27 @@ _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
}
else if (filter->keycode == keycode) {
pMsg = &filter->upAction.msg;
- if (pMsg->flags & XkbSA_MessageOnRelease) {
- xkbActionMessage msg;
-
- msg.keycode = keycode;
- msg.press = 0;
- msg.keyEventFollows =
- ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
- memcpy((char *) msg.message, (char *) pMsg->message,
- XkbActionMessageLength);
- XkbSendActionMessage(kbd, &msg);
+ if (pAction == NULL) {
+ if (pMsg->flags & XkbSA_MessageOnRelease) {
+ xkbActionMessage msg;
+
+ msg.keycode = keycode;
+ msg.press = 0;
+ msg.keyEventFollows =
+ ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
+ memcpy((char *) msg.message, (char *) pMsg->message,
+ XkbActionMessageLength);
+ XkbSendActionMessage(kbd, &msg);
+ }
+ filter->keycode = 0;
+ filter->active = 0;
+ return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
+ } else if (memcmp(pMsg, pAction, 8) == 0) {
+ /* Repeat: If we send the same message, avoid multiple messages
+ on release from piling up. */
+ filter->keycode = 0;
+ filter->active = 0;
}
- filter->keycode = 0;
- filter->active = 0;
- return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
}
return 1;
}
@@ -803,15 +819,21 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
ProcessInputProc backupproc;
+ if ((filter->keycode != 0) && (filter->keycode != keycode))
+ return 1;
+
+ /* This can happen if the key repeats, and the state (modifiers or group)
+ changes meanwhile. */
+ if ((filter->keycode == keycode) && pAction &&
+ (pAction->type != XkbSA_RedirectKey))
+ return 1;
+
/* never actually used uninitialised, but gcc isn't smart enough
* to work that out. */
memset(&old, 0, sizeof(old));
memset(&old_prev, 0, sizeof(old_prev));
memset(&ev, 0, sizeof(ev));
- if ((filter->keycode != 0) && (filter->keycode != keycode))
- return 1;
-
GetSpritePosition(xkbi->device, &x, &y);
ev.header = ET_Internal;
ev.length = sizeof(DeviceEvent);
@@ -870,49 +892,60 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
xkbi->state = old;
xkbi->prev_state = old_prev;
}
+ return 0;
}
- else if (filter->keycode == keycode) {
-
- ev.type = ET_KeyRelease;
- ev.detail.key = filter->upAction.redirect.new_key;
-
- mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
- mods = XkbSARedirectVMods(&filter->upAction.redirect);
- if (mask)
- XkbVirtualModsToReal(xkbi->desc, mask, &mask);
- if (mods)
- XkbVirtualModsToReal(xkbi->desc, mods, &mods);
- mask |= filter->upAction.redirect.mods_mask;
- mods |= filter->upAction.redirect.mods;
-
- if (mask || mods) {
- old = xkbi->state;
- old_prev = xkbi->prev_state;
- xkbi->state.base_mods &= ~mask;
- xkbi->state.base_mods |= (mods & mask);
- xkbi->state.latched_mods &= ~mask;
- xkbi->state.latched_mods |= (mods & mask);
- xkbi->state.locked_mods &= ~mask;
- xkbi->state.locked_mods |= (mods & mask);
- XkbComputeDerivedState(xkbi);
- xkbi->prev_state = xkbi->state;
- }
-
- UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
- xkbi->device->public.processInputProc((InternalEvent *) &ev,
- xkbi->device);
- COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
- xkbUnwrapProc);
-
- if (mask || mods) {
- xkbi->state = old;
- xkbi->prev_state = old_prev;
- }
-
- filter->keycode = 0;
- filter->active = 0;
+ else {
+ /* If it is a key release, or we redirect to another key, release the
+ previous new_key. Otherwise, repeat. */
+ ev.detail.key = filter->upAction.redirect.new_key;
+ if (pAction == NULL || ev.detail.key != pAction->redirect.new_key) {
+ ev.type = ET_KeyRelease;
+ filter->active = 0;
+ }
+ else {
+ ev.type = ET_KeyPress;
+ ev.key_repeat = TRUE;
+ }
+
+ mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
+ mods = XkbSARedirectVMods(&filter->upAction.redirect);
+ if (mask)
+ XkbVirtualModsToReal(xkbi->desc, mask, &mask);
+ if (mods)
+ XkbVirtualModsToReal(xkbi->desc, mods, &mods);
+ mask |= filter->upAction.redirect.mods_mask;
+ mods |= filter->upAction.redirect.mods;
+
+ if (mask || mods) {
+ old = xkbi->state;
+ old_prev = xkbi->prev_state;
+ xkbi->state.base_mods &= ~mask;
+ xkbi->state.base_mods |= (mods & mask);
+ xkbi->state.latched_mods &= ~mask;
+ xkbi->state.latched_mods |= (mods & mask);
+ xkbi->state.locked_mods &= ~mask;
+ xkbi->state.locked_mods |= (mods & mask);
+ XkbComputeDerivedState(xkbi);
+ xkbi->prev_state = xkbi->state;
+ }
+
+ UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
+ xkbi->device->public.processInputProc((InternalEvent *) &ev,
+ xkbi->device);
+ COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
+ xkbUnwrapProc);
+
+ if (mask || mods) {
+ xkbi->state = old;
+ xkbi->prev_state = old_prev;
+ }
+
+ /* We return 1 in case we have sent a release event because the new_key
+ has changed. Then, subsequently, we will call this function again
+ with the same pAction, which will create the press for the new
+ new_key. */
+ return (pAction && ev.detail.key != pAction->redirect.new_key);
}
- return 0;
}
static int