diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2009-06-18 14:40:20 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2009-06-18 15:50:47 +1000 |
commit | e92dcb6ce07aa3cfb53e8bad5701481c106c4094 (patch) | |
tree | 4008c4a7c54a0f193830412ff04c52efac2d78f9 /dix | |
parent | 280b7f92d729ec910ffa3d18dce7bbc215be7a3c (diff) |
input: unify button numbers on master devices.
Master devices provide the union of all attached slave devices' buttons,
i.e. the number of buttons on the master device is always the number of
buttons of the slave device with the highest number of buttons. When slaves
are attached or detached, the master device adjusts the button number to
reflect the new buttons.
On a slave switch, this slave's button labels are copied into the master (up
to slave->num_buttons). The remaining button labels (if any) stay as they
are. Thus, if any of the higher buttons is still pressed, it reflects the
label of the last pressed device that provided this button.
If two devices press the same button and it is differently labelled the last
pressed one will be reflected in the master device.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'dix')
-rw-r--r-- | dix/devices.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/dix/devices.c b/dix/devices.c index 3d190657e..b237e03b1 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -109,6 +109,7 @@ DevPrivateKey XTstDevicePrivateKey = &XTstDevicePrivateKeyIndex; */ DeviceIntPtr vxtstpointer, vxtstkeyboard; +static void RecalculateMasterButtons(DeviceIntPtr slave); /** * DIX property handler. @@ -369,6 +370,8 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) XISendDeviceHierarchyEvent(flags); } + RecalculateMasterButtons(dev); + return TRUE; } @@ -460,6 +463,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) flags[dev->id] = XIDeviceDisabled; XISendDeviceHierarchyEvent(flags); } + + RecalculateMasterButtons(dev); + return TRUE; } @@ -2260,6 +2266,77 @@ ProcQueryKeymap(ClientPtr client) return Success; } + +/** + * Recalculate the number of buttons for the master device. The number of + * buttons on the master device is equal to the number of buttons on the + * slave device with the highest number of buttons. + */ +static void +RecalculateMasterButtons(DeviceIntPtr slave) +{ + DeviceIntPtr dev, master; + int maxbuttons = 0; + + if (!slave->button || IsMaster(slave)) + return; + + master = GetMaster(slave, MASTER_POINTER); + if (!master) + return; + + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (IsMaster(dev) || + dev->u.master != master || + !dev->button) + continue; + + maxbuttons = max(maxbuttons, dev->button->numButtons); + } + + if (master->button->numButtons != maxbuttons) + { + int i; + DeviceChangedEvent event; + + memset(&event, 0, sizeof(event)); + + master->button->numButtons = maxbuttons; + + event.header = ET_Internal; + event.type = ET_DeviceChanged; + event.time = CurrentTime; + event.deviceid = master->id; + event.flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE; + event.buttons.num_buttons = maxbuttons; + memcpy(&event.buttons.names, master->button->labels, maxbuttons * + sizeof(Atom)); + + if (master->valuator) + { + event.num_valuators = master->valuator->numAxes; + for (i = 0; i < event.num_valuators; i++) + { + event.valuators[i].min = master->valuator->axes[i].min_value; + event.valuators[i].max = master->valuator->axes[i].max_value; + event.valuators[i].resolution = master->valuator->axes[i].resolution; + /* This should, eventually, be a per-axis mode */ + event.valuators[i].mode = master->valuator->mode; + event.valuators[i].name = master->valuator->axes[i].label; + } + } + + if (master->key) + { + event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code; + event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code; + } + + XISendDeviceChangedEvent(master, master, &event); + } +} + /** * Attach device 'dev' to device 'master'. * Client is set to the client that issued the request, or NULL if it comes @@ -2323,6 +2400,8 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) dev->spriteInfo->paired = master; dev->spriteInfo->spriteOwner = FALSE; + RecalculateMasterButtons(master); + if (!oldmaster) { /* Attaching a floating SD makes it disappear to XI 1 clients */ |