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; | ||||
| } | ||||
| 
 | ||||
| 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, | ||||
|  |  | |||
							
								
								
									
										22
									
								
								Xi/setbmap.c
								
								
								
								
							
							
						
						
									
										22
									
								
								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 = 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; | ||||
| 
 | ||||
|     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); | ||||
|     WriteReplyToClient(client, sizeof(xSetDeviceButtonMappingReply), &rep); | ||||
| 
 | ||||
|     return Success; | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										105
									
								
								dix/inpututils.c
								
								
								
								
							
							
						
						
									
										105
									
								
								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 | ||||
|  |  | |||
|  | @ -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 */, | ||||
|  |  | |||
|  | @ -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( | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue