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>
This commit is contained in:
parent
8ce4fde76f
commit
55e1ea08d0
|
@ -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.
|
* Send an XI2 DeviceChangedEvent to all interested clients.
|
||||||
*/
|
*/
|
||||||
|
@ -723,13 +786,13 @@ XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChanged
|
||||||
if (dce->buttons.num_buttons)
|
if (dce->buttons.num_buttons)
|
||||||
{
|
{
|
||||||
dcce->num_classes++;
|
dcce->num_classes++;
|
||||||
ptr += ListButtonInfo(device, (xXIButtonInfo*)ptr);
|
ptr += AppendButtonInfo(dce, (xXIButtonInfo*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nkeys)
|
if (nkeys)
|
||||||
{
|
{
|
||||||
dcce->num_classes++;
|
dcce->num_classes++;
|
||||||
ptr += ListKeyInfo(device, (xXIKeyInfo*)ptr);
|
ptr += AppendKeyInfo(dce, (xXIKeyInfo*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dce->num_valuators)
|
if (dce->num_valuators)
|
||||||
|
@ -738,7 +801,7 @@ XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChanged
|
||||||
|
|
||||||
dcce->num_classes += dce->num_valuators;
|
dcce->num_classes += dce->num_valuators;
|
||||||
for (i = 0; i < dce->num_valuators; i++)
|
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
|
/* we don't actually swap if there's a NullClient, swapping is done
|
||||||
|
|
Loading…
Reference in New Issue