From 4219e94c2f7d431be433eceddfe79760a1ee31a1 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 08:27:31 +0930 Subject: [PATCH 01/11] xkb: Add XkbCopySrvLedInfo, deep-copies a XkbSrvLedInfoRec. --- include/xkbsrv.h | 8 ++++++++ xkb/xkbLEDs.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/xkbsrv.h b/include/xkbsrv.h index fef341a8f..7db9eef0b 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -576,6 +576,14 @@ extern XkbSrvLedInfoPtr XkbAllocSrvLedInfo( unsigned int /* needed_parts */ ); +extern XkbSrvLedInfoPtr XkbCopySrvLedInfo( + DeviceIntPtr /* dev */, + XkbSrvLedInfoPtr /* src */, + KbdFeedbackPtr /* kf */, + LedFeedbackPtr /* lf */ +); + + extern XkbSrvLedInfoPtr XkbFindSrvLedInfo( DeviceIntPtr /* dev */, unsigned int /* class */, diff --git a/xkb/xkbLEDs.c b/xkb/xkbLEDs.c index 55ce12aad..d7ada5749 100644 --- a/xkb/xkbLEDs.c +++ b/xkb/xkbLEDs.c @@ -615,6 +615,45 @@ XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli) return; } +/* + * XkbSrvLedInfoPtr + * XkbCopySrvLedInfo(dev,src,kf,lf) + * + * Takes the given XkbSrvLedInfoPtr and duplicates it. A deep copy is made, + * thus the new copy behaves like the original one and can be freed with + * XkbFreeSrvLedInfo. + */ +XkbSrvLedInfoPtr +XkbCopySrvLedInfo( DeviceIntPtr from, + XkbSrvLedInfoPtr src, + KbdFeedbackPtr kf, + LedFeedbackPtr lf) +{ + XkbSrvLedInfoPtr sli_new; + + if (!src) + goto finish; + + sli_new = _XkbTypedCalloc(1, XkbSrvLedInfoRec); + if (!sli_new) + goto finish; + + memcpy(src, sli_new, sizeof(XkbSrvLedInfoRec)); + if (sli_new->class == KbdFeedbackClass) + sli_new->fb.kf = kf; + else + sli_new->fb.lf = lf; + + if (sli_new->flags & XkbSLI_IsDefault) { + sli_new->names= _XkbTypedCalloc(XkbNumIndicators,Atom); + sli_new->maps= _XkbTypedCalloc(XkbNumIndicators,XkbIndicatorMapRec); + } /* else sli_new->names/maps is pointing to + dev->key->xkbInfo->desc->names->indicators; + dev->key->xkbInfo->desc->names->indicators; */ + +finish: + return sli_new; +} /***====================================================================***/ From bf6679cba40a936d46008c886d204ed521a4971a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 08:28:07 +0930 Subject: [PATCH 02/11] Xi: copy the XkbSrvLedInfo too when copying device classes. --- Xi/exevents.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index a93fef452..815eb7c6c 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -263,7 +263,11 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) (*k)->BellProc = it->BellProc; (*k)->CtrlProc = it->CtrlProc; (*k)->ctrl = it->ctrl; - /* XXX: xkb_sli needs to be copied */ +#ifdef XKB + if ((*k)->xkb_sli) + XkbFreeSrvLedInfo((*k)->xkb_sli); + (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL); +#endif k = &(*k)->next; } @@ -289,7 +293,6 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } (*p)->CtrlProc = it->CtrlProc; (*p)->ctrl = it->ctrl; - /* XXX: xkb_sli needs to be copied */ p = &(*p)->next; } @@ -391,7 +394,11 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } (*l)->CtrlProc = it->CtrlProc; (*l)->ctrl = it->ctrl; - /* XXX: xkb_sli needs to be copied */ +#ifdef XKB + if ((*l)->xkb_sli) + XkbFreeSrvLedInfo((*l)->xkb_sli); + (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l); +#endif l = &(*l)->next; } From 961f6660902163e99727c2dcc1a039f32b083859 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 09:31:16 +0930 Subject: [PATCH 03/11] Xi: modifierKeyMap needs to be set to NULL when copying classes. Otherwise we have a double reference to the same memory area. --- Xi/exevents.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Xi/exevents.c b/Xi/exevents.c index 815eb7c6c..1d4dc51bf 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -434,6 +434,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) #ifdef XKB to->key->xkbInfo = NULL; #endif + to->key->modifierKeyMap = NULL; to->key->curKeySyms.map = NULL; CopyKeyClass(from, to); } else if (to->key && !from->key) From 415c6df0da1197d487456b4c48e2e28e7ded8b8e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 11:46:44 +0930 Subject: [PATCH 04/11] Xi: copy feedback classes first, in some cases xkb relies on kbdfeed. XkbInitIndicatorMap (in XkbInitDevice) calls XkbFindSrvLedInfo. This accesses the devices kbdfeed struct, which is all nice and dandy if it is NULL. When copying the device classes however, kbdfeed may not be NULL and thus XkbFindSrvLedInfo goes on its merry way to do whatever it does. By copying kbdfeed first, we avoid XkbFSLI to reference the "old" kbdfeed struct of the previous SD. --- Xi/exevents.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 1d4dc51bf..6fa08d133 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -416,6 +416,11 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) _X_EXPORT void DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) { + /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the + * kbdfeed to be set up properly, so let's do the feedback classes first. + */ + DeepCopyFeedbackClasses(from, to); + #define ALLOC_COPY_CLASS_IF(field, type) \ if (from->field)\ { \ @@ -528,7 +533,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) to->absolute = NULL; } - DeepCopyFeedbackClasses(from, to); } /** From 3106ba1116e3b9d893f66a93e4a91cc61e23226a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 11:48:06 +0930 Subject: [PATCH 05/11] xkb: two fixes to avoid server crashes. - map can be NULL in some cases, so don't try to dereference it. - don't default to inputInfo.keyboard This is firefighting, I presume something in the class copy may have gone wrong to get a NULL map in the first instance? --- xkb/xkbLEDs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xkb/xkbLEDs.c b/xkb/xkbLEDs.c index d7ada5749..1ea3e1116 100644 --- a/xkb/xkbLEDs.c +++ b/xkb/xkbLEDs.c @@ -447,7 +447,7 @@ XkbIndicatorMapPtr map; XkbDescPtr xkb; if ((sli->flags&XkbSLI_HasOwnState)==0) - dev= inputInfo.keyboard; + return; sli->usesBase&= ~which; sli->usesLatched&= ~which; @@ -462,7 +462,7 @@ XkbDescPtr xkb; if (which&bit) { CARD8 what; - if (!XkbIM_InUse(map)) + if (!map || !XkbIM_InUse(map)) continue; sli->mapsPresent|= bit; From 6faf5b97b92953c331d6540ceb18fd0a77197fea Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 15:42:33 +0930 Subject: [PATCH 06/11] Xi: fix up modifierKeyMap copying. Setting it to NULL isn't correct either. The correct behaviour is to realloc it to the size necessary (or newly alloc it/free it). Otherwise we have a memleak. --- Xi/exevents.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 6fa08d133..cf0e8984b 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -176,11 +176,16 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) if (dk->maxKeysPerModifier) { - mk->modifierKeyMap = xcalloc(8, dk->maxKeysPerModifier); + mk->modifierKeyMap = xrealloc(mk->modifierKeyMap, + 8 * dk->maxKeysPerModifier); if (!mk->modifierKeyMap) FatalError("[Xi] no memory for class shift.\n"); memcpy(mk->modifierKeyMap, dk->modifierKeyMap, (8 * dk->maxKeysPerModifier)); + } else + { + xfree(mk->modifierKeyMap); + mk->modifierKeyMap = NULL; } mk->maxKeysPerModifier = dk->maxKeysPerModifier; @@ -439,7 +444,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) #ifdef XKB to->key->xkbInfo = NULL; #endif - to->key->modifierKeyMap = NULL; to->key->curKeySyms.map = NULL; CopyKeyClass(from, to); } else if (to->key && !from->key) From 755f9e5d7898056cf3bead69ce25a10e23995582 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 16:49:25 +0930 Subject: [PATCH 07/11] dix: Ignore focus for passive grabs if the event is a pointer event. --- dix/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dix/events.c b/dix/events.c index 1b62db05f..e25ec30cf 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3546,7 +3546,7 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE, { int i; WindowPtr pWin = NULL; - FocusClassPtr focus = device->focus; + FocusClassPtr focus = IsPointerEvent(xE) ? NULL : device->focus; xEvent core; BOOL sendCore = (device->isMaster && device->coreEvents); From 3c4c9938f31755c5a59995fdcfa138c99db76bbf Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 16:52:14 +0930 Subject: [PATCH 08/11] Xi: Fix pointer handling in KeyClassRec copy. We don't free the class anymore, so just store the previous pointers, do the memcpy from the SD and then restore the pointers. Plugs a memleak too, before xkbInfo was never freed. --- Xi/exevents.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index cf0e8984b..aee78c669 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -438,13 +438,36 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) memcpy(to->field, from->field, sizeof(type)); \ } - ALLOC_COPY_CLASS_IF(key, KeyClassRec); - if (to->key && from->key) + if (from->key) { + KeyCode *oldModKeyMap; + KeySym *oldMap; #ifdef XKB - to->key->xkbInfo = NULL; + struct _XkbSrvInfo *oldXkbInfo; #endif - to->key->curKeySyms.map = NULL; + + if (!to->key) + { + to->key = xcalloc(1, sizeof(KeyClassRec)); + if (!to->key) + FatalError("[Xi] no memory for class shift.\n"); + } + + + oldModKeyMap = to->key->modifierKeyMap; + oldMap = to->key->curKeySyms.map; +#ifdef XKB + oldXkbInfo = to->key->xkbInfo; +#endif + + memcpy(to->key, from->key, sizeof(KeyClassRec)); + + to->key->modifierKeyMap = oldModKeyMap; + to->key->curKeySyms.map = oldMap; +#ifdef XKB + to->key->xkbInfo = oldXkbInfo; +#endif + CopyKeyClass(from, to); } else if (to->key && !from->key) { From fde3c836628b6cdec3e5d107d6b1b99bc8b86912 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 17:08:51 +0930 Subject: [PATCH 09/11] Xi: copy the KeySyms.map over from the source. --- Xi/exevents.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Xi/exevents.c b/Xi/exevents.c index aee78c669..2a7afa9d4 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -462,6 +462,15 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) memcpy(to->key, from->key, sizeof(KeyClassRec)); + if (!oldMap) /* newly created key struct */ + { + int bytes = (to->key->curKeySyms.maxKeyCode - + to->key->curKeySyms.minKeyCode + 1) * + to->key->curKeySyms.mapWidth; + oldMap = (KeySym *)xcalloc(sizeof(KeySym), bytes); + memcpy(oldMap, from->key->curKeySyms.map, bytes); + } + to->key->modifierKeyMap = oldModKeyMap; to->key->curKeySyms.map = oldMap; #ifdef XKB From cb48d880856fd196ab8e8de5eb1f14944a1b4fff Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 19:48:28 +0930 Subject: [PATCH 10/11] Xi: store unused classes in devPrivates. Rather than freeing/allocing classes each time the device capabilities need to swap, store them in the devPrivates system. When a class is unused, it is pushed into the devPrivates, and later recovered when needed again. This saves us a lot of memory allocations/frees, admittedly on the cost of some memory. --- Xi/exevents.c | 145 ++++++++++++++++++++++++++++++++++++++------------ dix/devices.c | 10 ++++ 2 files changed, 120 insertions(+), 35 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 2a7afa9d4..d99f609e2 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -96,6 +96,9 @@ Bool ShouldFreeInputMasks(WindowPtr /* pWin */ , static Bool MakeInputMasks(WindowPtr /* pWin */ ); +/* Used to sture classes currently not in use by an MD */ +extern DevPrivateKey UnusedClassesPrivateKey; + void RegisterOtherDevice(DeviceIntPtr device) @@ -416,28 +419,22 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) /** * Copies the CONTENT of the classes of device from into the classes in device * to. From and to are identical after finishing. + * + * If to does not have classes from currenly has, the classes are stored in + * to's devPrivates system. Later, we recover it again from there if needed. + * Saves a few memory allocations. */ _X_EXPORT void DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) { + ClassesPtr classes; + /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the * kbdfeed to be set up properly, so let's do the feedback classes first. */ DeepCopyFeedbackClasses(from, to); -#define ALLOC_COPY_CLASS_IF(field, type) \ - if (from->field)\ - { \ - if (!to->field) \ - { \ - to->field = xcalloc(1, sizeof(type)); \ - if (!to->field) \ - FatalError("[Xi] no memory for class shift.\n"); \ - } \ - memcpy(to->field, from->field, sizeof(type)); \ - } - if (from->key) { KeyCode *oldModKeyMap; @@ -445,15 +442,19 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) #ifdef XKB struct _XkbSrvInfo *oldXkbInfo; #endif - if (!to->key) { - to->key = xcalloc(1, sizeof(KeyClassRec)); + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->key = classes->key; if (!to->key) - FatalError("[Xi] no memory for class shift.\n"); + { + to->key = xcalloc(1, sizeof(KeyClassRec)); + if (!to->key) + FatalError("[Xi] no memory for class shift.\n"); + } } - oldModKeyMap = to->key->modifierKeyMap; oldMap = to->key->curKeySyms.map; #ifdef XKB @@ -480,14 +481,22 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) CopyKeyClass(from, to); } else if (to->key && !from->key) { - FreeDeviceClass(KeyClass, (pointer)&to->key); + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->key = to->key; + to->key = NULL; } if (from->valuator) { ValuatorClassPtr v; - if (to->valuator) - xfree(to->valuator->motion); + if (!to->valuator) + { + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->valuator = classes->valuator; + } + to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) + from->valuator->numAxes * sizeof(AxisInfo) + from->valuator->numAxes * sizeof(unsigned int)); @@ -504,14 +513,28 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) v->axisVal = (int*)(v->axes + from->valuator->numAxes); } else if (to->valuator && !from->valuator) { - FreeDeviceClass(ValuatorClass, (pointer)&to->valuator); + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->valuator = to->valuator; + to->valuator = NULL; } - ALLOC_COPY_CLASS_IF(button, ButtonClassRec); - if (to->button) + if (from->button) { int i; DeviceIntPtr sd; + if (!to->button) + { + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->button = classes->button; + if (!to->button) + { + to->button = xcalloc(1, sizeof(ButtonClassRec)); + if (!to->button) + FatalError("[Xi] no memory for class shift.\n"); + } + } /* merge button states from all attached devices */ for (sd = inputInfo.devices; sd; sd = sd->next) @@ -530,7 +553,10 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) #endif } else if (to->button && !from->button) { - FreeDeviceClass(ButtonClass, (pointer)&to->button); + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->button = to->button; + to->button = NULL; } @@ -544,29 +570,78 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) { if (!to->focus) { - to->focus = xcalloc(1, sizeof(FocusClassRec)); + WindowPtr *oldTrace; + + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->focus = classes->focus; if (!to->focus) - FatalError("[Xi] no memory for class shift.\n"); + { + to->focus = xcalloc(1, sizeof(FocusClassRec)); + if (!to->focus) + FatalError("[Xi] no memory for class shift.\n"); + } + oldTrace = to->focus->trace; + memcpy(to->focus, from->focus, sizeof(FocusClassRec)); + to->focus->trace = xrealloc(oldTrace, + to->focus->traceSize * sizeof(WindowPtr)); + if (!to->focus->trace && to->focus->traceSize) + FatalError("[Xi] no memory for trace.\n"); memcpy(to->focus->trace, from->focus->trace, from->focus->traceSize * sizeof(WindowPtr)); } } else if (to->focus) { - /* properly freeing the class would also free the sprite trace, which - * is still in use by the SD. just xfree the struct. */ - xfree(to->focus); + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->focus = to->focus; + to->focus = NULL; } - ALLOC_COPY_CLASS_IF(proximity, ProximityClassRec); - if (to->proximity && !from->proximity) + if (from->proximity) { - FreeDeviceClass(ProximityClass, (pointer)&to->proximity); + if (!to->proximity) + { + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->proximity = classes->proximity; + if (!to->proximity) + { + to->proximity = xcalloc(1, sizeof(ProximityClassRec)); + if (!to->proximity) + FatalError("[Xi] no memory for class shift.\n"); + } + } + memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec)); + } else if (to->proximity) + { + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->proximity = to->proximity; + to->proximity = NULL; } - ALLOC_COPY_CLASS_IF(absolute, AbsoluteClassRec); - if (to->absolute && !from->absolute) + + if (from->absolute) { - xfree(to->absolute); - to->absolute = NULL; + if (!to->absolute) + { + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->absolute = classes->absolute; + if (!to->absolute) + { + to->absolute = xcalloc(1, sizeof(AbsoluteClassRec)); + if (!to->absolute) + FatalError("[Xi] no memory for class shift.\n"); + } + } + memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec)); + } else if (to->absolute) + { + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->absolute = to->absolute; + to->absolute = NULL; } } diff --git a/dix/devices.c b/dix/devices.c index a78a1255d..266a66c61 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -89,6 +89,8 @@ SOFTWARE. /* The client that is allowed to change pointer-keyboard pairings. */ static ClientPtr pairingClient = NULL; DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKey; +/* Used to sture classes currently not in use by an MD */ +DevPrivateKey UnusedClassesPrivateKey = &UnusedClassesPrivateKey; /** * Create a new input device and init it to sane values. The device is added @@ -2550,6 +2552,7 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* { DeviceIntPtr pointer; DeviceIntPtr keyboard; + ClassesPtr classes; *ptr = *keybd = NULL; pointer = AddInputDevice(client, CorePointerProc, TRUE); @@ -2602,6 +2605,13 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* keyboard->u.lastSlave = NULL; keyboard->isMaster = TRUE; + + /* The ClassesRec stores the device classes currently not used. */ + classes = xcalloc(1, sizeof(ClassesRec)); + dixSetPrivate(&pointer->devPrivates, UnusedClassesPrivateKey, classes); + classes = xcalloc(1, sizeof(ClassesRec)); + dixSetPrivate(&keyboard->devPrivates, UnusedClassesPrivateKey, classes); + *ptr = pointer; *keybd = keyboard; From 6866e84e3c607d00d88eab2249c2619d6707c1a4 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 13 Apr 2008 19:57:51 +0930 Subject: [PATCH 11/11] Xi: store feedback classes in devProviates system as well. This is a follow-up to cb48d880856fd196ab8e8de5eb1f14944a1b4fff. --- Xi/exevents.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index d99f609e2..4417e6c61 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -253,9 +253,19 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) static void DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) { + ClassesPtr classes; + if (from->kbdfeed) { KbdFeedbackPtr *k, it; + + if (!to->kbdfeed) + { + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->kbdfeed = classes->kbdfeed; + } + k = &to->kbdfeed; for(it = from->kbdfeed; it; it = it->next) { @@ -281,12 +291,22 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->kbdfeed && !from->kbdfeed) { - FreeFeedbackClass(KbdFeedbackClass, (pointer)&to->kbdfeed); + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->kbdfeed = to->kbdfeed; + to->kbdfeed = NULL; } if (from->ptrfeed) { PtrFeedbackPtr *p, it; + if (!to->ptrfeed) + { + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->ptrfeed = classes->ptrfeed; + } + p = &to->ptrfeed; for (it = from->ptrfeed; it; it = it->next) { @@ -306,12 +326,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->ptrfeed && !from->ptrfeed) { - FreeFeedbackClass(PtrFeedbackClass, (pointer)&to->ptrfeed); + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->ptrfeed = to->ptrfeed; + to->ptrfeed = NULL; } if (from->intfeed) { IntegerFeedbackPtr *i, it; + + if (!to->intfeed) + { + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->intfeed = classes->intfeed; + } + i = &to->intfeed; for (it = from->intfeed; it; it = it->next) { @@ -331,12 +362,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->intfeed && !from->intfeed) { - FreeFeedbackClass(IntegerFeedbackClass, (pointer)&to->intfeed); + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->intfeed = to->intfeed; + to->intfeed = NULL; } if (from->stringfeed) { StringFeedbackPtr *s, it; + + if (!to->stringfeed) + { + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->stringfeed = classes->stringfeed; + } + s = &to->stringfeed; for (it = from->stringfeed; it; it = it->next) { @@ -356,12 +398,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->stringfeed && !from->stringfeed) { - FreeFeedbackClass(StringFeedbackClass, (pointer)&to->stringfeed); + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->stringfeed = to->stringfeed; + to->stringfeed = NULL; } if (from->bell) { BellFeedbackPtr *b, it; + + if (!to->bell) + { + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->bell = classes->bell; + } + b = &to->bell; for (it = from->bell; it; it = it->next) { @@ -382,12 +435,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->bell && !from->bell) { - FreeFeedbackClass(BellFeedbackClass, (pointer)&to->bell); + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->bell = to->bell; + to->bell = NULL; } if (from->leds) { LedFeedbackPtr *l, it; + + if (!to->leds) + { + classes = dixLookupPrivate(&to->devPrivates, + UnusedClassesPrivateKey); + to->leds = classes->leds; + } + l = &to->leds; for (it = from->leds; it; it = it->next) { @@ -412,7 +476,10 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->leds && !from->leds) { - FreeFeedbackClass(LedFeedbackClass, (pointer)&to->leds); + ClassesPtr classes; + classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); + classes->leds = to->leds; + to->leds = NULL; } }