summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2008-04-13 19:48:28 +0930
committerPeter Hutterer <peter@cs.unisa.edu.au>2008-04-13 19:48:28 +0930
commitcb48d880856fd196ab8e8de5eb1f14944a1b4fff (patch)
tree4a60003cae628f11189c7bd514a454064ee4547f
parentfde3c836628b6cdec3e5d107d6b1b99bc8b86912 (diff)
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.
-rw-r--r--Xi/exevents.c145
-rw-r--r--dix/devices.c10
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)
+ {
+ 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)
{
- FreeDeviceClass(ProximityClass, (pointer)&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)
+ {
+ 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)
{
- xfree(to->absolute);
- to->absolute = NULL;
+ 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;