Input: Centralise pointer map changing
Replace both core and Xi functions with one function that validates the proposed map, and sends out both kinds of notification. Signed-off-by: Daniel Stone <daniel@fooishbar.org> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
f06a9d2e05
commit
bc909f7136
@ -1639,20 +1639,6 @@ SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map)
|
|||||||
return Success;
|
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
|
int
|
||||||
ChangeKeyMapping(ClientPtr client,
|
ChangeKeyMapping(ClientPtr client,
|
||||||
DeviceIntPtr dev,
|
DeviceIntPtr dev,
|
||||||
|
20
Xi/setbmap.c
20
Xi/setbmap.c
@ -107,21 +107,15 @@ ProcXSetDeviceButtonMapping(ClientPtr client)
|
|||||||
rep.sequenceNumber = client->sequence;
|
rep.sequenceNumber = client->sequence;
|
||||||
rep.status = MappingSuccess;
|
rep.status = MappingSuccess;
|
||||||
|
|
||||||
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
|
ret = ApplyPointerMapping(dev, (CARD8 *) &stuff[1], stuff->map_length, client);
|
||||||
if (ret != Success)
|
if (ret == -1)
|
||||||
return ret;
|
return BadValue;
|
||||||
|
else if (ret == MappingBusy)
|
||||||
ret = SetButtonMapping(client, dev, stuff->map_length, (BYTE *) & stuff[1]);
|
|
||||||
|
|
||||||
if (ret == BadValue || ret == BadMatch)
|
|
||||||
return ret;
|
|
||||||
else {
|
|
||||||
rep.status = ret;
|
rep.status = ret;
|
||||||
WriteReplyToClient(client, sizeof(xSetDeviceButtonMappingReply), &rep);
|
else if (ret != Success)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
if (ret != MappingBusy)
|
WriteReplyToClient(client, sizeof(xSetDeviceButtonMappingReply), &rep);
|
||||||
SendDevicePointerMappingNotify(client, dev);
|
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
@ -1396,28 +1396,6 @@ InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
|
|||||||
InitPtrFeedbackClassDeviceStruct(dev, controlProc));
|
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
|
* Check if the given buffer contains elements between low (inclusive) and
|
||||||
* high (inclusive) only.
|
* high (inclusive) only.
|
||||||
@ -1553,31 +1531,6 @@ ProcChangeKeyboardMapping(ClientPtr client)
|
|||||||
return client->noClientException;
|
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
|
int
|
||||||
ProcSetPointerMapping(ClientPtr client)
|
ProcSetPointerMapping(ClientPtr client)
|
||||||
{
|
{
|
||||||
@ -1607,31 +1560,26 @@ ProcSetPointerMapping(ClientPtr client)
|
|||||||
client->errorValue = stuff->nElts;
|
client->errorValue = stuff->nElts;
|
||||||
return BadValue;
|
return BadValue;
|
||||||
}
|
}
|
||||||
if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue))
|
|
||||||
return BadValue;
|
|
||||||
|
|
||||||
/* core protocol specs don't allow for duplicate mappings. */
|
/* Core protocol specs don't allow for duplicate mappings; this check
|
||||||
for (i = 0; i < stuff->nElts; i++)
|
* almost certainly wants disabling through XFixes too. */
|
||||||
{
|
for (i = 0; i < stuff->nElts; i++) {
|
||||||
for (j = i + 1; j < stuff->nElts; j++)
|
for (j = i + 1; j < stuff->nElts; j++) {
|
||||||
{
|
if (map[i] && map[i] == map[j]) {
|
||||||
if (map[i] && map[i] == map[j])
|
|
||||||
{
|
|
||||||
client->errorValue = map[i];
|
client->errorValue = map[i];
|
||||||
return BadValue;
|
return BadValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = DoSetPointerMapping(client, ptr, map, stuff->nElts);
|
ret = ApplyPointerMapping(ptr, map, stuff->nElts, client);
|
||||||
if (ret != Success) {
|
if (ret == MappingBusy)
|
||||||
rep.success = ret;
|
rep.success = ret;
|
||||||
WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
|
else if (ret == -1)
|
||||||
return Success;
|
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);
|
WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
105
dix/inpututils.c
105
dix/inpututils.c
@ -28,6 +28,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "exevents.h"
|
#include "exevents.h"
|
||||||
|
#include "exglobals.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "inputstr.h"
|
#include "inputstr.h"
|
||||||
@ -35,6 +36,110 @@
|
|||||||
#include "xkbsrv.h"
|
#include "xkbsrv.h"
|
||||||
#include "xkbstr.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.
|
/* Check if a modifier map change is okay with the device.
|
||||||
* Returns -1 for BadValue, as it collides with MappingBusy; this particular
|
* Returns -1 for BadValue, as it collides with MappingBusy; this particular
|
||||||
* caveat can be removed with LegalModifier, as we have no other reason to
|
* caveat can be removed with LegalModifier, as we have no other reason to
|
||||||
|
@ -137,10 +137,6 @@ extern _X_EXPORT int SetButtonMapping (
|
|||||||
int /* nElts */,
|
int /* nElts */,
|
||||||
BYTE * /* map */);
|
BYTE * /* map */);
|
||||||
|
|
||||||
extern _X_EXPORT void SendDevicePointerMappingNotify(
|
|
||||||
ClientPtr /* client, */,
|
|
||||||
DeviceIntPtr /* dev */);
|
|
||||||
|
|
||||||
extern _X_EXPORT int ChangeKeyMapping(
|
extern _X_EXPORT int ChangeKeyMapping(
|
||||||
ClientPtr /* client */,
|
ClientPtr /* client */,
|
||||||
DeviceIntPtr /* dev */,
|
DeviceIntPtr /* dev */,
|
||||||
|
@ -368,8 +368,10 @@ extern _X_EXPORT Bool InitKeyboardDeviceStruct(
|
|||||||
BellProcPtr /*bellProc*/,
|
BellProcPtr /*bellProc*/,
|
||||||
KbdCtrlProcPtr /*controlProc*/);
|
KbdCtrlProcPtr /*controlProc*/);
|
||||||
|
|
||||||
extern _X_EXPORT void SendPointerMappingNotify(
|
extern _X_EXPORT int ApplyPointerMapping(
|
||||||
DeviceIntPtr /* pDev */,
|
DeviceIntPtr /* pDev */,
|
||||||
|
CARD8 * /* map */,
|
||||||
|
int /* len */,
|
||||||
ClientPtr /* client */);
|
ClientPtr /* client */);
|
||||||
|
|
||||||
extern _X_EXPORT Bool BadDeviceMap(
|
extern _X_EXPORT Bool BadDeviceMap(
|
||||||
|
Loading…
Reference in New Issue
Block a user