dix: Add FreeDeviceClass and FreeFeedbackClass for centralised xfree.

Ensures that we only have one way of freeing a device class to avoid leaks in
ChangeMasterDeviceClasses and other places.
This commit is contained in:
Peter Hutterer 2007-11-15 15:43:44 +10:30
parent 18833d648f
commit b40646dc10
4 changed files with 190 additions and 123 deletions

View File

@ -288,34 +288,7 @@ ChangeMasterDeviceClasses(DeviceIntPtr device,
master->public.devicePrivate = device->public.devicePrivate; master->public.devicePrivate = device->public.devicePrivate;
if (master->key) FreeAllDeviceClasses(&master->key);
xfree(master->key->modifierKeyMap);
#ifdef XKB
if (master->key && master->key->xkbInfo)
XkbFreeInfo(master->key->xkbInfo);
#endif
xfree(master->key); master->key = NULL;
xfree(master->valuator); master->valuator = NULL;
/* XXX: xkb_acts needs to be freed for master->button */
xfree(master->button); master->button = NULL;
xfree(master->focus); master->focus = NULL;
xfree(master->proximity); master->proximity = NULL;
xfree(master->absolute); master->absolute = NULL;
#ifdef XKB
if (master->kbdfeed && master->kbdfeed->xkb_sli)
XkbFreeSrvLedInfo(master->kbdfeed->xkb_sli);
#endif
xfree(master->kbdfeed); master->kbdfeed = NULL;
xfree(master->ptrfeed); master->ptrfeed = NULL;
xfree(master->stringfeed); master->stringfeed = NULL;
xfree(master->bell); master->bell = NULL;
#ifdef XKB
if (master->leds && master->leds->xkb_sli)
XkbFreeSrvLedInfo(master->leds->xkb_sli);
#endif
xfree(master->leds); master->leds = NULL;
xfree(master->intfeed); master->intfeed = NULL;
DeepCopyDeviceClasses(device, master); DeepCopyDeviceClasses(device, master);
/* event is already correct size, see comment in GetPointerEvents */ /* event is already correct size, see comment in GetPointerEvents */

View File

@ -85,22 +85,6 @@ SOFTWARE.
* This file handles input device-related stuff. * This file handles input device-related stuff.
*/ */
typedef struct {
KeyClassPtr key;
ValuatorClassPtr valuator;
ButtonClassPtr button;
FocusClassPtr focus;
ProximityClassPtr proximity;
AbsoluteClassPtr absolute;
KbdFeedbackPtr kbdfeed;
PtrFeedbackPtr ptrfeed;
IntegerFeedbackPtr intfeed;
StringFeedbackPtr stringfeed;
BellFeedbackPtr bell;
LedFeedbackPtr leds;
} ClassesRec, *ClassesPtr;
int CoreDevicePrivatesIndex = 0; int CoreDevicePrivatesIndex = 0;
static int CoreDevicePrivatesGeneration = -1; static int CoreDevicePrivatesGeneration = -1;
int MasterDevClassesPrivIdx = -1; int MasterDevClassesPrivIdx = -1;
@ -638,6 +622,174 @@ InitAndStartDevices(WindowPtr root)
return Success; return Success;
} }
_X_EXPORT void
FreeAllDeviceClasses(ClassesPtr classes)
{
if (!classes)
return;
FreeDeviceClass(KeyClass, (pointer)&classes->key);
FreeDeviceClass(ValuatorClass, (pointer)&classes->valuator);
FreeDeviceClass(ButtonClass, (pointer)&classes->button);
FreeDeviceClass(FocusClass, (pointer)&classes->focus);
FreeDeviceClass(ProximityClass, (pointer)&classes->proximity);
FreeFeedbackClass(KbdFeedbackClass, (pointer)&classes->kbdfeed);
FreeFeedbackClass(PtrFeedbackClass, (pointer)&classes->ptrfeed);
FreeFeedbackClass(IntegerFeedbackClass, (pointer)&classes->intfeed);
FreeFeedbackClass(StringFeedbackClass, (pointer)&classes->stringfeed);
FreeFeedbackClass(BellFeedbackClass, (pointer)&classes->bell);
FreeFeedbackClass(LedFeedbackClass, (pointer)&classes->leds);
}
/**
* Free the given device class and reset the pointer to NULL.
*/
_X_EXPORT void
FreeDeviceClass(int type, pointer *class)
{
if (!(*class))
return;
switch(type)
{
case KeyClass:
{
KeyClassPtr* k = (KeyClassPtr*)class;
#ifdef XKB
if ((*k)->xkbInfo)
XkbFreeInfo((*k)->xkbInfo);
#endif
xfree((*k)->curKeySyms.map);
xfree((*k)->modifierKeyMap);
xfree((*k));
break;
}
case ButtonClass:
{
ButtonClassPtr *b = (ButtonClassPtr*)class;
#ifdef XKB
if ((*b)->xkb_acts)
xfree((*b)->xkb_acts);
#endif
xfree((*b));
break;
}
case ValuatorClass:
{
ValuatorClassPtr *v = (ValuatorClassPtr*)class;
/* Counterpart to 'biggest hack ever' in init. */
if ((*v)->motion && (*v)->GetMotionProc == GetMotionHistory)
xfree((*v)->motion);
xfree((*v));
break;
}
case FocusClass:
{
FocusClassPtr *f = (FocusClassPtr*)class;
xfree((*f)->trace);
xfree((*f));
break;
}
case ProximityClass:
{
ProximityClassPtr *p = (ProximityClassPtr*)class;
xfree((*p));
break;
}
}
*class = NULL;
}
_X_EXPORT void
FreeFeedbackClass(int type, pointer *class)
{
if (!(*class))
return;
switch(type)
{
case KbdFeedbackClass:
{
KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr*)class;
KbdFeedbackPtr k, knext;
for (k = (*kbdfeed); k; k = knext) {
knext = k->next;
#ifdef XKB
if (k->xkb_sli)
XkbFreeSrvLedInfo(k->xkb_sli);
#endif
xfree(k);
}
break;
}
case PtrFeedbackClass:
{
PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr*)class;
PtrFeedbackPtr p, pnext;
for (p = (*ptrfeed); p; p = pnext) {
pnext = p->next;
xfree(p);
}
break;
}
case IntegerFeedbackClass:
{
IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr*)class;
IntegerFeedbackPtr i, inext;
for (i = (*intfeed); i; i = inext) {
inext = i->next;
xfree(i);
}
break;
}
case StringFeedbackClass:
{
StringFeedbackPtr *stringfeed = (StringFeedbackPtr*)class;
StringFeedbackPtr s, snext;
for (s = (*stringfeed); s; s = snext) {
snext = s->next;
xfree(s->ctrl.symbols_supported);
xfree(s->ctrl.symbols_displayed);
xfree(s);
}
break;
}
case BellFeedbackClass:
{
BellFeedbackPtr *bell = (BellFeedbackPtr*)class;
BellFeedbackPtr b, bnext;
for (b = (*bell); b; b = bnext) {
bnext = b->next;
xfree(b);
}
break;
}
case LedFeedbackClass:
{
LedFeedbackPtr *leds = (LedFeedbackPtr*)class;
LedFeedbackPtr l, lnext;
for (l = (*leds); l; l = lnext) {
lnext = l->next;
#ifdef XKB
if (l->xkb_sli)
XkbFreeSrvLedInfo(l->xkb_sli);
#endif
xfree(l);
}
break;
}
}
*class = NULL;
}
/** /**
* Close down a device and free all resources. * Close down a device and free all resources.
* Once closed down, the driver will probably not expect you that you'll ever * Once closed down, the driver will probably not expect you that you'll ever
@ -648,12 +800,6 @@ InitAndStartDevices(WindowPtr root)
static void static void
CloseDevice(DeviceIntPtr dev) CloseDevice(DeviceIntPtr dev)
{ {
KbdFeedbackPtr k, knext;
PtrFeedbackPtr p, pnext;
IntegerFeedbackPtr i, inext;
StringFeedbackPtr s, snext;
BellFeedbackPtr b, bnext;
LedFeedbackPtr l, lnext;
ScreenPtr screen = screenInfo.screens[0]; ScreenPtr screen = screenInfo.screens[0];
ClassesPtr classes; ClassesPtr classes;
int j; int j;
@ -675,79 +821,7 @@ CloseDevice(DeviceIntPtr dev)
else else
classes = (ClassesPtr)&dev->key; classes = (ClassesPtr)&dev->key;
if (classes->key) { FreeAllDeviceClasses(classes);
#ifdef XKB
if (classes->key->xkbInfo)
XkbFreeInfo(classes->key->xkbInfo);
#endif
xfree(classes->key->curKeySyms.map);
xfree(classes->key->modifierKeyMap);
xfree(classes->key);
}
if (classes->valuator) {
/* Counterpart to 'biggest hack ever' in init. */
if (classes->valuator->motion &&
classes->valuator->GetMotionProc == GetMotionHistory)
xfree(classes->valuator->motion);
xfree(classes->valuator);
}
if (classes->button) {
#ifdef XKB
if (classes->button->xkb_acts)
xfree(classes->button->xkb_acts);
#endif
xfree(classes->button);
}
if (classes->focus) {
xfree(classes->focus->trace);
xfree(classes->focus);
}
if (classes->proximity)
xfree(classes->proximity);
for (k = classes->kbdfeed; k; k = knext) {
knext = k->next;
#ifdef XKB
if (k->xkb_sli)
XkbFreeSrvLedInfo(k->xkb_sli);
#endif
xfree(k);
}
for (p = classes->ptrfeed; p; p = pnext) {
pnext = p->next;
xfree(p);
}
for (i = classes->intfeed; i; i = inext) {
inext = i->next;
xfree(i);
}
for (s = classes->stringfeed; s; s = snext) {
snext = s->next;
xfree(s->ctrl.symbols_supported);
xfree(s->ctrl.symbols_displayed);
xfree(s);
}
for (b = classes->bell; b; b = bnext) {
bnext = b->next;
xfree(b);
}
for (l = classes->leds; l; l = lnext) {
lnext = l->next;
#ifdef XKB
if (l->xkb_sli)
XkbFreeSrvLedInfo(l->xkb_sli);
#endif
xfree(l);
}
#ifdef XKB #ifdef XKB
while (dev->xkb_interest) while (dev->xkb_interest)

View File

@ -84,6 +84,7 @@ typedef unsigned long Leds;
typedef struct _OtherClients *OtherClientsPtr; typedef struct _OtherClients *OtherClientsPtr;
typedef struct _InputClients *InputClientsPtr; typedef struct _InputClients *InputClientsPtr;
typedef struct _DeviceIntRec *DeviceIntPtr; typedef struct _DeviceIntRec *DeviceIntPtr;
typedef struct _ClassesRec *ClassesPtr;
typedef struct _EventList { typedef struct _EventList {
xEvent* event; xEvent* event;
@ -484,6 +485,9 @@ extern int AllocMasterDevice(char* name,
DeviceIntPtr* keybd); DeviceIntPtr* keybd);
extern void DeepCopyDeviceClasses(DeviceIntPtr from, extern void DeepCopyDeviceClasses(DeviceIntPtr from,
DeviceIntPtr to); DeviceIntPtr to);
extern void FreeDeviceClass(int type, pointer* class);
extern void FreeFeedbackClass(int type, pointer* class);
extern void FreeAllDeviceClasses(ClassesPtr classes);
/* Window/device based access control */ /* Window/device based access control */
extern Bool ACRegisterClient(ClientPtr client); extern Bool ACRegisterClient(ClientPtr client);

View File

@ -283,6 +283,22 @@ typedef struct _LedFeedbackClassRec {
} LedFeedbackClassRec; } LedFeedbackClassRec;
typedef struct _ClassesRec {
KeyClassPtr key;
ValuatorClassPtr valuator;
ButtonClassPtr button;
FocusClassPtr focus;
ProximityClassPtr proximity;
AbsoluteClassPtr absolute;
KbdFeedbackPtr kbdfeed;
PtrFeedbackPtr ptrfeed;
IntegerFeedbackPtr intfeed;
StringFeedbackPtr stringfeed;
BellFeedbackPtr bell;
LedFeedbackPtr leds;
} ClassesRec;
/** /**
* Sprite information for a device. * Sprite information for a device.
*/ */