summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xi/exevents.c14
-rw-r--r--Xi/setbmap.c24
-rw-r--r--dix/devices.c74
-rw-r--r--dix/inpututils.c105
-rw-r--r--include/exevents.h4
-rw-r--r--include/input.h4
6 files changed, 128 insertions, 97 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 623f71036..76214b973 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1639,20 +1639,6 @@ SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map)
return Success;
}
-void
-SendDevicePointerMappingNotify(ClientPtr client, DeviceIntPtr dev)
-{
- xEvent event;
- deviceMappingNotify *ev = (deviceMappingNotify *) & event;
-
- ev->type = DeviceMappingNotify;
- ev->request = MappingPointer;
- ev->deviceid = dev->id;
- ev->time = currentTime.milliseconds;
-
- SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) ev, 1);
-}
-
int
ChangeKeyMapping(ClientPtr client,
DeviceIntPtr dev,
diff --git a/Xi/setbmap.c b/Xi/setbmap.c
index 0bcfbb8eb..b6f62dddb 100644
--- a/Xi/setbmap.c
+++ b/Xi/setbmap.c
@@ -107,21 +107,15 @@ ProcXSetDeviceButtonMapping(ClientPtr client)
rep.sequenceNumber = client->sequence;
rep.status = MappingSuccess;
- ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
- if (ret != Success)
- return ret;
-
- ret = SetButtonMapping(client, dev, stuff->map_length, (BYTE *) & stuff[1]);
-
- if (ret == BadValue || ret == BadMatch)
- return ret;
- else {
- rep.status = ret;
- WriteReplyToClient(client, sizeof(xSetDeviceButtonMappingReply), &rep);
- }
-
- if (ret != MappingBusy)
- SendDevicePointerMappingNotify(client, dev);
+ ret = ApplyPointerMapping(dev, (CARD8 *) &stuff[1], stuff->map_length, client);
+ if (ret == -1)
+ return BadValue;
+ else if (ret == MappingBusy)
+ rep.status = ret;
+ else if (ret != Success)
+ return ret;
+
+ WriteReplyToClient(client, sizeof(xSetDeviceButtonMappingReply), &rep);
return Success;
}
diff --git a/dix/devices.c b/dix/devices.c
index 33f149ce4..884256c8d 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1396,28 +1396,6 @@ InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
InitPtrFeedbackClassDeviceStruct(dev, controlProc));
}
-_X_EXPORT void
-SendPointerMappingNotify(DeviceIntPtr pDev, ClientPtr client)
-{
- int i;
- xEvent event;
-
- /* 0 is the server client. */
- for (i = 1; i < currentMaxClients; i++) {
- /* Don't send irrelevant events to naïve clients. */
- if (PickPointer(clients[i]) != pDev)
- continue;
-
- if (clients[i] && clients[i]->clientState == ClientStateRunning) {
- event.u.u.type = MappingNotify;
- event.u.u.sequenceNumber = clients[i]->sequence;
- event.u.mappingNotify.request = MappingPointer;
-
- WriteEventsToClient(clients[i], 1, &event);
- }
- }
-}
-
/*
* Check if the given buffer contains elements between low (inclusive) and
* high (inclusive) only.
@@ -1553,31 +1531,6 @@ ProcChangeKeyboardMapping(ClientPtr client)
return client->noClientException;
}
-static int
-DoSetPointerMapping(ClientPtr client, DeviceIntPtr device, BYTE *map, int n)
-{
- int rc, i = 0;
-
- if (!device || !device->button)
- return BadDevice;
-
- rc = XaceHook(XACE_DEVICE_ACCESS, client, device, DixManageAccess);
- if (rc != Success)
- return rc;
-
- for (i = 0; i < n; i++) {
- if ((device->button->map[i + 1] != map[i]) &&
- BitIsOn(device->button->down, i + 1)) {
- return MappingBusy;
- }
- }
-
- for (i = 0; i < n; i++)
- device->button->map[i + 1] = map[i];
-
- return Success;
-}
-
int
ProcSetPointerMapping(ClientPtr client)
{
@@ -1607,31 +1560,26 @@ ProcSetPointerMapping(ClientPtr client)
client->errorValue = stuff->nElts;
return BadValue;
}
- if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue))
- return BadValue;
- /* core protocol specs don't allow for duplicate mappings. */
- for (i = 0; i < stuff->nElts; i++)
- {
- for (j = i + 1; j < stuff->nElts; j++)
- {
- if (map[i] && map[i] == map[j])
- {
+ /* Core protocol specs don't allow for duplicate mappings; this check
+ * almost certainly wants disabling through XFixes too. */
+ for (i = 0; i < stuff->nElts; i++) {
+ for (j = i + 1; j < stuff->nElts; j++) {
+ if (map[i] && map[i] == map[j]) {
client->errorValue = map[i];
return BadValue;
}
}
}
- ret = DoSetPointerMapping(client, ptr, map, stuff->nElts);
- if (ret != Success) {
+ ret = ApplyPointerMapping(ptr, map, stuff->nElts, client);
+ if (ret == MappingBusy)
rep.success = ret;
- WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
- return Success;
- }
+ else if (ret == -1)
+ return BadValue;
+ else if (ret != Success)
+ return ret;
- /* FIXME: Send mapping notifies for masters/slaves as well. */
- SendPointerMappingNotify(ptr, client);
WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
return Success;
}
diff --git a/dix/inpututils.c b/dix/inpututils.c
index 309ef516d..4763382c7 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -28,6 +28,7 @@
#endif
#include "exevents.h"
+#include "exglobals.h"
#include "misc.h"
#include "input.h"
#include "inputstr.h"
@@ -35,6 +36,110 @@
#include "xkbsrv.h"
#include "xkbstr.h"
+/* Check if a button map change is okay with the device.
+ * Returns -1 for BadValue, as it collides with MappingBusy. */
+static int
+check_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, CARD32 *errval_out,
+ ClientPtr client)
+{
+ int i, ret;
+
+ if (!dev || !dev->button)
+ return BadDevice;
+
+ ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
+ if (ret != Success)
+ return ret;
+
+ for (i = 0; i < len; i++) {
+ if (dev->button->map[i + 1] != map[i] && dev->button->down[i + 1])
+ return MappingBusy;
+
+ if (map[i] < 1 || map[i] > 255) {
+ if (errval_out)
+ *errval_out = map[i];
+ return -1;
+ }
+ }
+
+ return Success;
+}
+
+static void
+do_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client)
+{
+ int i;
+ xEvent core_mn;
+ deviceMappingNotify xi_mn;
+
+ /* The map in ButtonClassRec refers to button numbers, whereas the
+ * protocol is zero-indexed. Sigh. */
+ memcpy(&(dev->button->map[1]), map, len);
+
+ core_mn.u.u.type = MappingNotify;
+ core_mn.u.mappingNotify.request = MappingPointer;
+
+ /* 0 is the server client. */
+ for (i = 1; i < currentMaxClients; i++) {
+ /* Don't send irrelevant events to naïve clients. */
+ if (!clients[i] || clients[i]->clientState != ClientStateRunning)
+ continue;
+
+ if (!XIShouldNotify(clients[i], dev))
+ continue;
+
+ core_mn.u.u.sequenceNumber = clients[i]->sequence;
+ WriteEventsToClient(clients[i], 1, &core_mn);
+ }
+
+ xi_mn.type = DeviceMappingNotify;
+ xi_mn.request = MappingPointer;
+ xi_mn.deviceid = dev->id;
+ xi_mn.time = GetTimeInMillis();
+
+ SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1);
+}
+
+/*
+ * Does what it says on the box, both for core and Xi.
+ *
+ * Faithfully reports any errors encountered while trying to apply the map
+ * to the requested device, faithfully ignores any errors encountered while
+ * trying to apply the map to its master/slaves.
+ */
+_X_EXPORT int
+ApplyPointerMapping(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client)
+{
+ int ret;
+ DeviceIntPtr tmp;
+
+ /* If we can't perform the change on the requested device, bail out. */
+ ret = check_butmap_change(dev, map, len, &client->errorValue, client);
+ if (ret != Success)
+ return ret;
+ do_butmap_change(dev, map, len, client);
+
+ /* Change any attached masters/slaves. */
+ if (dev->isMaster) {
+ for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
+ if (!tmp->isMaster && tmp->u.master == dev)
+ if (check_butmap_change(tmp, map, len, NULL, client) == Success)
+ do_butmap_change(tmp, map, len, client);
+ }
+ }
+ else {
+ for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
+ if (tmp->isMaster && tmp->u.lastSlave == dev) {
+ /* If this fails, expect the results to be weird. */
+ if (check_butmap_change(tmp, map, len, NULL, client) == Success)
+ do_butmap_change(tmp, map, len, client);
+ }
+ }
+ }
+
+ return Success;
+}
+
/* Check if a modifier map change is okay with the device.
* Returns -1 for BadValue, as it collides with MappingBusy; this particular
* caveat can be removed with LegalModifier, as we have no other reason to
diff --git a/include/exevents.h b/include/exevents.h
index 46df009a4..ff2922736 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -137,10 +137,6 @@ extern _X_EXPORT int SetButtonMapping (
int /* nElts */,
BYTE * /* map */);
-extern _X_EXPORT void SendDevicePointerMappingNotify(
- ClientPtr /* client, */,
- DeviceIntPtr /* dev */);
-
extern _X_EXPORT int ChangeKeyMapping(
ClientPtr /* client */,
DeviceIntPtr /* dev */,
diff --git a/include/input.h b/include/input.h
index 8a774c963..19d1ae74c 100644
--- a/include/input.h
+++ b/include/input.h
@@ -368,8 +368,10 @@ extern _X_EXPORT Bool InitKeyboardDeviceStruct(
BellProcPtr /*bellProc*/,
KbdCtrlProcPtr /*controlProc*/);
-extern _X_EXPORT void SendPointerMappingNotify(
+extern _X_EXPORT int ApplyPointerMapping(
DeviceIntPtr /* pDev */,
+ CARD8 * /* map */,
+ int /* len */,
ClientPtr /* client */);
extern _X_EXPORT Bool BadDeviceMap(