diff --git a/Xi/exevents.c b/Xi/exevents.c index 617aef7b4..3ef32006c 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -162,25 +162,10 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count) /* event is already correct size, see comment in GetPointerEvents */ classbuff = (char*)&xE[1]; - if (master->key) - { - /* we don't actually swap here, swapping is done later */ - CopySwapKeyClass(NullClient, master->key, &classbuff); - dcce->num_classes++; - } - if (master->button) - { - CopySwapButtonClass(NullClient, master->button, &classbuff); - dcce->num_classes++; - } - if (master->valuator) - { - CopySwapValuatorClass(NullClient, master->valuator, &classbuff); - dcce->num_classes++; - } - - SendEventToAllWindows(master, XI_DeviceClassesChangedMask, - xE, 1); + /* we don't actually swap if there's a NullClient, swapping is done + * later when event is delivered. */ + CopySwapClasses(NullClient, master, &dcce->num_classes, &classbuff); + SendEventToAllWindows(master, XI_DeviceClassesChangedMask, xE, 1); return; } diff --git a/Xi/listdev.c b/Xi/listdev.c index 962998efe..1810c9b62 100644 --- a/Xi/listdev.c +++ b/Xi/listdev.c @@ -142,7 +142,7 @@ CopyDeviceName(char **namebuf, char *name) * */ -void +static void CopySwapButtonClass(ClientPtr client, ButtonClassPtr b, char **buf) { char n; @@ -201,7 +201,7 @@ CopySwapDevice(ClientPtr client, DeviceIntPtr d, int num_classes, * */ -void +static void CopySwapKeyClass(ClientPtr client, KeyClassPtr k, char **buf) { char n; @@ -231,7 +231,7 @@ CopySwapKeyClass(ClientPtr client, KeyClassPtr k, char **buf) * */ -int +static int CopySwapValuatorClass(ClientPtr client, ValuatorClassPtr v, char **buf) { int i, j, axes, t_axes; @@ -286,17 +286,24 @@ ListDeviceInfo(ClientPtr client, DeviceIntPtr d, xDeviceInfoPtr dev, { CopyDeviceName(namebuf, d->name); CopySwapDevice(client, d, 0, devbuf); - if (d->key != NULL) { - CopySwapKeyClass(client, d->key, classbuf); - dev->num_classes++; + CopySwapClasses(client, d, &dev->num_classes, classbuf); +} + +void +CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes, + char** classbuf) +{ + if (dev->key != NULL) { + CopySwapKeyClass(client, dev->key, classbuf); + (*num_classes)++; } - if (d->button != NULL) { - CopySwapButtonClass(client, d->button, classbuf); - dev->num_classes++; + if (dev->button != NULL) { + CopySwapButtonClass(client, dev->button, classbuf); + (*num_classes)++; } - if (d->valuator != NULL) { - dev->num_classes += - CopySwapValuatorClass(client, d->valuator, classbuf); + if (dev->valuator != NULL) { + (*num_classes) += + CopySwapValuatorClass(client, dev->valuator, classbuf); } } diff --git a/Xi/listdev.h b/Xi/listdev.h index afdcd6992..22a0d91c8 100644 --- a/Xi/listdev.h +++ b/Xi/listdev.h @@ -44,15 +44,9 @@ void SRepXListInputDevices(ClientPtr /* client */ , ); void -CopySwapKeyClass(ClientPtr /* client */, - KeyClassPtr /* k */, - char** /* buf */); -void -CopySwapButtonClass(ClientPtr /* client */, - ButtonClassPtr /* b */, - char** /* buf */); -int -CopySwapValuatorClass(ClientPtr /* client */, - ValuatorClassPtr /* v */, - char** /* buf */); +CopySwapClasses(ClientPtr /* client */, + DeviceIntPtr /* dev */, + CARD8* /* num_classes */, + char** /* classbuf */); + #endif /* LISTDEV_H */ diff --git a/dix/devices.c b/dix/devices.c index b42337820..2c6d3e1b1 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -79,6 +79,7 @@ SOFTWARE. #include #include "exglobals.h" #include "exevents.h" +#include "listdev.h" /* for CopySwapXXXClass */ /** @file * This file handles input device-related stuff. @@ -2314,9 +2315,50 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) */ if (!master) { + DeviceIntPtr it; /* current root window */ InitializeSprite(dev, dev->spriteInfo->sprite->spriteTrace[0]); dev->spriteInfo->spriteOwner = FALSE; + + /* the master may need to restore the original classes, search for a + * device that is still paired with our master. */ + for (it = inputInfo.devices; it; it = it->next) + if (!it->isMaster && it->u.master == master) + break; + + if (!it) /* no dev is paired with our master */ + { + ClassesPtr classes; + EventList event = { NULL, 0}; + char* classbuf; + + classes = master->devPrivates[MasterDevClassesPrivIdx].ptr; + master->key = classes->key; + master->valuator = classes->valuator; + master->button = classes->button; + master->focus = classes->focus; + master->proximity = classes->proximity; + master->absolute = classes->absolute; + master->kbdfeed = classes->kbdfeed; + master->ptrfeed = classes->ptrfeed; + master->intfeed = classes->intfeed; + master->stringfeed = classes->stringfeed; + master->bell = classes->bell; + master->leds = classes->leds; + + /* Send event to clients */ + CreateClassesChangedEvent(&event, master, master); + deviceClassesChangedEvent *dcce = + (deviceClassesChangedEvent*)event.event; + dcce->deviceid = master->id; + dcce->num_classes = 0; + classbuf = (char*)&event.event[1]; + CopySwapClasses(NullClient, master, &dcce->num_classes, &classbuf); + SendEventToAllWindows(master, XI_DeviceClassesChangedMask, + event.event, 1); + xfree(event.event); + } + } else dev->spriteInfo->sprite = master->spriteInfo->sprite; diff --git a/dix/getevents.c b/dix/getevents.c index 425b60234..e366d2223 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -111,7 +111,7 @@ key_autorepeats(DeviceIntPtr pDev, int key_code) (1 << (key_code & 7))); } -static void +void CreateClassesChangedEvent(EventList* event, DeviceIntPtr master, DeviceIntPtr slave) diff --git a/include/input.h b/include/input.h index d6a38e639..dbf6aee20 100644 --- a/include/input.h +++ b/include/input.h @@ -402,6 +402,9 @@ extern int GetMaximumEventsNum(void); extern EventListPtr InitEventList(int num_events); extern void FreeEventList(EventListPtr list, int num_events); +extern void CreateClassesChangedEvent(EventListPtr event, + DeviceIntPtr master, + DeviceIntPtr slave); extern int GetPointerEvents( EventListPtr events, DeviceIntPtr pDev,