summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2009-06-18 14:40:20 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2009-06-18 15:50:47 +1000
commite92dcb6ce07aa3cfb53e8bad5701481c106c4094 (patch)
tree4008c4a7c54a0f193830412ff04c52efac2d78f9
parent280b7f92d729ec910ffa3d18dce7bbc215be7a3c (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>
-rw-r--r--Xi/exevents.c11
-rw-r--r--dix/devices.c79
-rw-r--r--include/events.h2
3 files changed, 86 insertions, 6 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 8b69a3ad3..e54af094e 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -588,6 +588,8 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
} else
xfree(to->button->xkb_acts);
+ memcpy(to->button->labels, from->button->labels,
+ from->button->numButtons * sizeof(Atom));
to->button->sourceid = from->id;
} else if (to->button && !from->button)
{
@@ -670,10 +672,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dc
/**
- * Change MD to look like SD by copying all classes over. An event is sent to
- * all interested clients.
- * @param device The slave device
- * @param dcce Pointer to the event struct.
+ * Send an XI2 DeviceChangedEvent to all interested clients.
*/
void
XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce)
@@ -700,7 +699,7 @@ XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChanged
len += sizeof(CARD32) * nkeys; /* keycodes */
}
- dcce = xalloc(len);
+ dcce = xcalloc(1, len);
if (!dcce)
{
ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
@@ -713,7 +712,7 @@ XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChanged
dcce->time = GetTimeInMillis();
dcce->deviceid = master->id;
dcce->sourceid = device->id;
- dcce->reason = XISlaveSwitch;
+ dcce->reason = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
dcce->num_classes = 0;
dcce->length = (len - sizeof(xEvent))/4;
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 */
diff --git a/include/events.h b/include/events.h
index d44188b67..f6405c5c2 100644
--- a/include/events.h
+++ b/include/events.h
@@ -119,6 +119,8 @@ typedef struct
* pointer event or a keyboard event */
#define DEVCHANGE_POINTER_EVENT 0x4
#define DEVCHANGE_KEYBOARD_EVENT 0x8
+/* device capabilities changed */
+#define DEVCHANGE_DEVICE_CHANGE 0x10
/**
* Sent whenever a device's capabilities have changed.