summaryrefslogtreecommitdiff
path: root/Xi
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2009-08-03 16:46:11 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2009-08-13 10:58:39 +1000
commit55e1ea08d03d89ecc0f2db7652a4d15567204696 (patch)
tree81593bc7945aa2ce4fbc836a889dc772b0d5e7c3 /Xi
parent8ce4fde76fdf747fd3e00836c9c9c542e516ae9a (diff)
Xi: get device changed data from DeviceChangedEvents, not the device (#23100)
If a new device posts an event while the DCE is in the queue, getting the data from the device may result in invalid memory access. X.Org Bug 23100 <http://bugs.freedesktop.org/show_bug.cgi?id=23100>
Diffstat (limited to 'Xi')
-rw-r--r--Xi/exevents.c69
1 files changed, 66 insertions, 3 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 85d14b09b..49eacb4d1 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -674,6 +674,69 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dc
}
+static int
+AppendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info)
+{
+ uint32_t *kc;
+ int i;
+
+ info->type = KeyClass;
+ info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
+ info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes;
+ info->sourceid = dce->deviceid;
+
+ kc = (uint32_t*)&info[1];
+ for (i = 0; i < info->num_keycodes; i++)
+ *kc++ = i + dce->keys.min_keycode;
+
+ return info->length * 4;
+}
+
+static int
+AppendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info)
+{
+ unsigned char *bits;
+ int mask_len;
+
+ mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
+
+ info->type = ButtonClass;
+ info->num_buttons = dce->buttons.num_buttons;
+ info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
+ info->num_buttons + mask_len;
+ info->sourceid = dce->deviceid;
+
+ bits = (unsigned char*)&info[1];
+ memset(bits, 0, mask_len * 4);
+ /* FIXME: is_down? */
+
+ bits += mask_len * 4;
+ memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
+
+ return info->length * 4;
+}
+
+static int
+AppendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber)
+{
+ info->type = ValuatorClass;
+ info->length = sizeof(xXIValuatorInfo)/4;
+ info->label = dce->valuators[axisnumber].name;
+ info->min.integral = dce->valuators[axisnumber].min;
+ info->min.frac = 0;
+ info->max.integral = dce->valuators[axisnumber].max;
+ info->max.frac = 0;
+ /* FIXME: value */
+ info->value.integral = 0;
+ info->value.frac = 0;
+ info->resolution = dce->valuators[axisnumber].resolution;
+ info->number = axisnumber;
+ info->mode = dce->valuators[axisnumber].mode; /* Server doesn't have per-axis mode yet */
+ info->sourceid = dce->deviceid;
+
+ return info->length * 4;
+}
+
/**
* Send an XI2 DeviceChangedEvent to all interested clients.
*/
@@ -723,13 +786,13 @@ XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChanged
if (dce->buttons.num_buttons)
{
dcce->num_classes++;
- ptr += ListButtonInfo(device, (xXIButtonInfo*)ptr);
+ ptr += AppendButtonInfo(dce, (xXIButtonInfo*)ptr);
}
if (nkeys)
{
dcce->num_classes++;
- ptr += ListKeyInfo(device, (xXIKeyInfo*)ptr);
+ ptr += AppendKeyInfo(dce, (xXIKeyInfo*)ptr);
}
if (dce->num_valuators)
@@ -738,7 +801,7 @@ XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChanged
dcce->num_classes += dce->num_valuators;
for (i = 0; i < dce->num_valuators; i++)
- ptr += ListValuatorInfo(device, (xXIValuatorInfo*)ptr, i);
+ ptr += AppendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i);
}
/* we don't actually swap if there's a NullClient, swapping is done