From 6271df6953bea462be7e9e01744e5dd46841e867 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 8 Apr 2008 08:42:58 +0930 Subject: [PATCH 1/4] xkb: don't overwrite CtrlProc in the second run of XkbFinishDeviceInit. XkbFinishDeviceInit is called once when the device is initialised, but also when a class copy causes the key class of a device to change. In this case, overwriting the CtrlProc of the KeybdFeedbackClass with XkbDDXKeybdCtrlProc sets up a nice recursive loop of XkbDDXKeybdCtrlProc calling itself until the cows come home. --- xkb/xkbInit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c index ce5de077e..0d5d15ef3 100644 --- a/xkb/xkbInit.c +++ b/xkb/xkbInit.c @@ -726,7 +726,10 @@ XkbSrvLedInfoPtr sli; if (pXDev && pXDev->key && pXDev->key->xkbInfo && pXDev->kbdfeed) { xkbi= pXDev->key->xkbInfo; xkb= xkbi->desc; - if (pXDev->kbdfeed) { + /* If we come from DeepCopyDeviceClasses, the CtrlProc was already set + * to XkbDDXKeybdCtrlProc, overwriting it leads to happy recursion. + */ + if (pXDev->kbdfeed && pXDev->kbdfeed->CtrlProc != XkbDDXKeybdCtrlProc) { xkbi->kbdProc= pXDev->kbdfeed->CtrlProc; pXDev->kbdfeed->CtrlProc= XkbDDXKeybdCtrlProc; } From ea05cf0813b2b7c8cd2151cb935820753ae7997a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 8 Apr 2008 22:09:11 +0930 Subject: [PATCH 2/4] Xi: check if source has a key class before copying. --- Xi/exevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 225d3e524..757d57a23 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -378,7 +378,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) } ALLOC_COPY_CLASS_IF(key, KeyClassRec); - if (to->key) + if (to->key && from->key) { #ifdef XKB to->key->xkbInfo = NULL; From 60c38d248c1a89392c2c6695c3802f4b54e4c00b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 9 Apr 2008 07:46:53 +0930 Subject: [PATCH 3/4] Xi: plug memory leak, free previous motion history before allocating new. --- Xi/exevents.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Xi/exevents.c b/Xi/exevents.c index 757d57a23..4c967b212 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -390,6 +390,8 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) if (from->valuator) { ValuatorClassPtr v; + if (to->valuator) + xfree(to->valuator->motion); to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) + from->valuator->numAxes * sizeof(AxisInfo) + from->valuator->numAxes * sizeof(unsigned int)); From 389dae73cc0f3693f49807fd2de146c454ba9783 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 9 Apr 2008 08:26:00 +0930 Subject: [PATCH 4/4] Xi: If device "to" has a class but "from" doesn't, free the class in "to". --- Xi/exevents.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Xi/exevents.c b/Xi/exevents.c index 4c967b212..f28952fdc 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -241,6 +241,9 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) k = &(*k)->next; } + } else if (to->kbdfeed && !from->kbdfeed) + { + FreeFeedbackClass(KbdFeedbackClass, (pointer)&to->kbdfeed); } if (from->ptrfeed) @@ -264,6 +267,9 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) p = &(*p)->next; } + } else if (to->ptrfeed && !from->ptrfeed) + { + FreeFeedbackClass(PtrFeedbackClass, (pointer)&to->ptrfeed); } if (from->intfeed) @@ -286,6 +292,9 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) i = &(*i)->next; } + } else if (to->intfeed && !from->intfeed) + { + FreeFeedbackClass(IntegerFeedbackClass, (pointer)&to->intfeed); } if (from->stringfeed) @@ -308,6 +317,9 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) s = &(*s)->next; } + } else if (to->stringfeed && !from->stringfeed) + { + FreeFeedbackClass(StringFeedbackClass, (pointer)&to->stringfeed); } if (from->bell) @@ -331,6 +343,9 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) b = &(*b)->next; } + } else if (to->bell && !from->bell) + { + FreeFeedbackClass(BellFeedbackClass, (pointer)&to->bell); } if (from->leds) @@ -354,6 +369,9 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) l = &(*l)->next; } + } else if (to->leds && !from->leds) + { + FreeFeedbackClass(LedFeedbackClass, (pointer)&to->leds); } } @@ -385,6 +403,9 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) #endif to->key->curKeySyms.map = NULL; CopyKeyClass(from, to); + } else if (to->key && !from->key) + { + FreeDeviceClass(KeyClass, (pointer)&to->key); } if (from->valuator) @@ -406,6 +427,9 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo)); v->axisVal = (int*)(v->axes + from->valuator->numAxes); + } else if (to->valuator && !from->valuator) + { + FreeDeviceClass(ValuatorClass, (pointer)&to->valuator); } ALLOC_COPY_CLASS_IF(button, ButtonClassRec); @@ -429,10 +453,28 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) to->button->xkb_acts = NULL; /* XXX: XkbAction needs to be copied */ #endif + } else if (to->button && !from->button) + { + FreeDeviceClass(ButtonClass, (pointer)&to->button); } + + ALLOC_COPY_CLASS_IF(focus, FocusClassRec); + if (to->focus && !from->focus) + { + FreeDeviceClass(FocusClass, (pointer)&to->focus); + } ALLOC_COPY_CLASS_IF(proximity, ProximityClassRec); + if (to->proximity && !from->proximity) + { + FreeDeviceClass(ProximityClass, (pointer)&to->proximity); + } ALLOC_COPY_CLASS_IF(absolute, AbsoluteClassRec); + if (to->absolute && !from->absolute) + { + xfree(to->absolute); + to->absolute = NULL; + } DeepCopyFeedbackClasses(from, to); }