Merge whot@wombat:~/potoroo/xserver into mpx

This commit is contained in:
Peter Hutterer 2008-04-14 16:25:58 +09:30
commit 1a9d7205cd
5 changed files with 296 additions and 49 deletions

View File

@ -96,6 +96,9 @@ Bool ShouldFreeInputMasks(WindowPtr /* pWin */ ,
static Bool MakeInputMasks(WindowPtr /* pWin */ static Bool MakeInputMasks(WindowPtr /* pWin */
); );
/* Used to sture classes currently not in use by an MD */
extern DevPrivateKey UnusedClassesPrivateKey;
void void
RegisterOtherDevice(DeviceIntPtr device) RegisterOtherDevice(DeviceIntPtr device)
@ -176,11 +179,16 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
if (dk->maxKeysPerModifier) if (dk->maxKeysPerModifier)
{ {
mk->modifierKeyMap = xcalloc(8, dk->maxKeysPerModifier); mk->modifierKeyMap = xrealloc(mk->modifierKeyMap,
8 * dk->maxKeysPerModifier);
if (!mk->modifierKeyMap) if (!mk->modifierKeyMap)
FatalError("[Xi] no memory for class shift.\n"); FatalError("[Xi] no memory for class shift.\n");
memcpy(mk->modifierKeyMap, dk->modifierKeyMap, memcpy(mk->modifierKeyMap, dk->modifierKeyMap,
(8 * dk->maxKeysPerModifier)); (8 * dk->maxKeysPerModifier));
} else
{
xfree(mk->modifierKeyMap);
mk->modifierKeyMap = NULL;
} }
mk->maxKeysPerModifier = dk->maxKeysPerModifier; mk->maxKeysPerModifier = dk->maxKeysPerModifier;
@ -245,9 +253,19 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
static void static void
DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
{ {
ClassesPtr classes;
if (from->kbdfeed) if (from->kbdfeed)
{ {
KbdFeedbackPtr *k, it; KbdFeedbackPtr *k, it;
if (!to->kbdfeed)
{
classes = dixLookupPrivate(&to->devPrivates,
UnusedClassesPrivateKey);
to->kbdfeed = classes->kbdfeed;
}
k = &to->kbdfeed; k = &to->kbdfeed;
for(it = from->kbdfeed; it; it = it->next) for(it = from->kbdfeed; it; it = it->next)
{ {
@ -263,18 +281,32 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
(*k)->BellProc = it->BellProc; (*k)->BellProc = it->BellProc;
(*k)->CtrlProc = it->CtrlProc; (*k)->CtrlProc = it->CtrlProc;
(*k)->ctrl = it->ctrl; (*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; k = &(*k)->next;
} }
} else if (to->kbdfeed && !from->kbdfeed) } 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) if (from->ptrfeed)
{ {
PtrFeedbackPtr *p, it; PtrFeedbackPtr *p, it;
if (!to->ptrfeed)
{
classes = dixLookupPrivate(&to->devPrivates,
UnusedClassesPrivateKey);
to->ptrfeed = classes->ptrfeed;
}
p = &to->ptrfeed; p = &to->ptrfeed;
for (it = from->ptrfeed; it; it = it->next) for (it = from->ptrfeed; it; it = it->next)
{ {
@ -289,18 +321,28 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
} }
(*p)->CtrlProc = it->CtrlProc; (*p)->CtrlProc = it->CtrlProc;
(*p)->ctrl = it->ctrl; (*p)->ctrl = it->ctrl;
/* XXX: xkb_sli needs to be copied */
p = &(*p)->next; p = &(*p)->next;
} }
} else if (to->ptrfeed && !from->ptrfeed) } 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) if (from->intfeed)
{ {
IntegerFeedbackPtr *i, it; IntegerFeedbackPtr *i, it;
if (!to->intfeed)
{
classes = dixLookupPrivate(&to->devPrivates,
UnusedClassesPrivateKey);
to->intfeed = classes->intfeed;
}
i = &to->intfeed; i = &to->intfeed;
for (it = from->intfeed; it; it = it->next) for (it = from->intfeed; it; it = it->next)
{ {
@ -320,12 +362,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
} }
} else if (to->intfeed && !from->intfeed) } 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) if (from->stringfeed)
{ {
StringFeedbackPtr *s, it; StringFeedbackPtr *s, it;
if (!to->stringfeed)
{
classes = dixLookupPrivate(&to->devPrivates,
UnusedClassesPrivateKey);
to->stringfeed = classes->stringfeed;
}
s = &to->stringfeed; s = &to->stringfeed;
for (it = from->stringfeed; it; it = it->next) for (it = from->stringfeed; it; it = it->next)
{ {
@ -345,12 +398,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
} }
} else if (to->stringfeed && !from->stringfeed) } 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) if (from->bell)
{ {
BellFeedbackPtr *b, it; BellFeedbackPtr *b, it;
if (!to->bell)
{
classes = dixLookupPrivate(&to->devPrivates,
UnusedClassesPrivateKey);
to->bell = classes->bell;
}
b = &to->bell; b = &to->bell;
for (it = from->bell; it; it = it->next) for (it = from->bell; it; it = it->next)
{ {
@ -371,12 +435,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
} }
} else if (to->bell && !from->bell) } 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) if (from->leds)
{ {
LedFeedbackPtr *l, it; LedFeedbackPtr *l, it;
if (!to->leds)
{
classes = dixLookupPrivate(&to->devPrivates,
UnusedClassesPrivateKey);
to->leds = classes->leds;
}
l = &to->leds; l = &to->leds;
for (it = from->leds; it; it = it->next) for (it = from->leds; it; it = it->next)
{ {
@ -391,54 +466,104 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
} }
(*l)->CtrlProc = it->CtrlProc; (*l)->CtrlProc = it->CtrlProc;
(*l)->ctrl = it->ctrl; (*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; l = &(*l)->next;
} }
} else if (to->leds && !from->leds) } 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;
} }
} }
/** /**
* Copies the CONTENT of the classes of device from into the classes in device * Copies the CONTENT of the classes of device from into the classes in device
* to. From and to are identical after finishing. * 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 _X_EXPORT void
DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
{ {
#define ALLOC_COPY_CLASS_IF(field, type) \ ClassesPtr classes;
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)); \
}
ALLOC_COPY_CLASS_IF(key, KeyClassRec); /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the
if (to->key && from->key) * kbdfeed to be set up properly, so let's do the feedback classes first.
*/
DeepCopyFeedbackClasses(from, to);
if (from->key)
{ {
KeyCode *oldModKeyMap;
KeySym *oldMap;
#ifdef XKB #ifdef XKB
to->key->xkbInfo = NULL; struct _XkbSrvInfo *oldXkbInfo;
#endif #endif
to->key->curKeySyms.map = NULL; if (!to->key)
{
classes = dixLookupPrivate(&to->devPrivates,
UnusedClassesPrivateKey);
to->key = classes->key;
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));
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
to->key->xkbInfo = oldXkbInfo;
#endif
CopyKeyClass(from, to); CopyKeyClass(from, to);
} else if (to->key && !from->key) } 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) if (from->valuator)
{ {
ValuatorClassPtr v; ValuatorClassPtr v;
if (to->valuator) if (!to->valuator)
xfree(to->valuator->motion); {
classes = dixLookupPrivate(&to->devPrivates,
UnusedClassesPrivateKey);
to->valuator = classes->valuator;
}
to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) + to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) +
from->valuator->numAxes * sizeof(AxisInfo) + from->valuator->numAxes * sizeof(AxisInfo) +
from->valuator->numAxes * sizeof(unsigned int)); from->valuator->numAxes * sizeof(unsigned int));
@ -455,14 +580,28 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
v->axisVal = (int*)(v->axes + from->valuator->numAxes); v->axisVal = (int*)(v->axes + from->valuator->numAxes);
} else if (to->valuator && !from->valuator) } 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 (from->button)
if (to->button)
{ {
int i; int i;
DeviceIntPtr sd; 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 */ /* merge button states from all attached devices */
for (sd = inputInfo.devices; sd; sd = sd->next) for (sd = inputInfo.devices; sd; sd = sd->next)
@ -481,7 +620,10 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
#endif #endif
} else if (to->button && !from->button) } 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;
} }
@ -495,32 +637,80 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
{ {
if (!to->focus) if (!to->focus)
{ {
to->focus = xcalloc(1, sizeof(FocusClassRec)); WindowPtr *oldTrace;
classes = dixLookupPrivate(&to->devPrivates,
UnusedClassesPrivateKey);
to->focus = classes->focus;
if (!to->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, memcpy(to->focus->trace, from->focus->trace,
from->focus->traceSize * sizeof(WindowPtr)); from->focus->traceSize * sizeof(WindowPtr));
} }
} else if (to->focus) } else if (to->focus)
{ {
/* properly freeing the class would also free the sprite trace, which ClassesPtr classes;
* is still in use by the SD. just xfree the struct. */ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
xfree(to->focus); classes->focus = to->focus;
to->focus = NULL;
} }
ALLOC_COPY_CLASS_IF(proximity, ProximityClassRec); if (from->proximity)
if (to->proximity && !from->proximity)
{ {
FreeDeviceClass(ProximityClass, (pointer)&to->proximity); if (!to->proximity)
} {
ALLOC_COPY_CLASS_IF(absolute, AbsoluteClassRec); classes = dixLookupPrivate(&to->devPrivates,
if (to->absolute && !from->absolute) 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)
{ {
xfree(to->absolute); ClassesPtr classes;
to->absolute = NULL; classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
classes->proximity = to->proximity;
to->proximity = NULL;
}
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)
{
ClassesPtr classes;
classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
classes->absolute = to->absolute;
to->absolute = NULL;
} }
DeepCopyFeedbackClasses(from, to);
} }
/** /**

View File

@ -89,6 +89,8 @@ SOFTWARE.
/* The client that is allowed to change pointer-keyboard pairings. */ /* The client that is allowed to change pointer-keyboard pairings. */
static ClientPtr pairingClient = NULL; static ClientPtr pairingClient = NULL;
DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKey; 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 * 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 pointer;
DeviceIntPtr keyboard; DeviceIntPtr keyboard;
ClassesPtr classes;
*ptr = *keybd = NULL; *ptr = *keybd = NULL;
pointer = AddInputDevice(client, CorePointerProc, TRUE); pointer = AddInputDevice(client, CorePointerProc, TRUE);
@ -2602,6 +2605,13 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr*
keyboard->u.lastSlave = NULL; keyboard->u.lastSlave = NULL;
keyboard->isMaster = TRUE; 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; *ptr = pointer;
*keybd = keyboard; *keybd = keyboard;

View File

@ -3546,7 +3546,7 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
{ {
int i; int i;
WindowPtr pWin = NULL; WindowPtr pWin = NULL;
FocusClassPtr focus = device->focus; FocusClassPtr focus = IsPointerEvent(xE) ? NULL : device->focus;
xEvent core; xEvent core;
BOOL sendCore = (device->isMaster && device->coreEvents); BOOL sendCore = (device->isMaster && device->coreEvents);

View File

@ -576,6 +576,14 @@ extern XkbSrvLedInfoPtr XkbAllocSrvLedInfo(
unsigned int /* needed_parts */ unsigned int /* needed_parts */
); );
extern XkbSrvLedInfoPtr XkbCopySrvLedInfo(
DeviceIntPtr /* dev */,
XkbSrvLedInfoPtr /* src */,
KbdFeedbackPtr /* kf */,
LedFeedbackPtr /* lf */
);
extern XkbSrvLedInfoPtr XkbFindSrvLedInfo( extern XkbSrvLedInfoPtr XkbFindSrvLedInfo(
DeviceIntPtr /* dev */, DeviceIntPtr /* dev */,
unsigned int /* class */, unsigned int /* class */,

View File

@ -447,7 +447,7 @@ XkbIndicatorMapPtr map;
XkbDescPtr xkb; XkbDescPtr xkb;
if ((sli->flags&XkbSLI_HasOwnState)==0) if ((sli->flags&XkbSLI_HasOwnState)==0)
dev= inputInfo.keyboard; return;
sli->usesBase&= ~which; sli->usesBase&= ~which;
sli->usesLatched&= ~which; sli->usesLatched&= ~which;
@ -462,7 +462,7 @@ XkbDescPtr xkb;
if (which&bit) { if (which&bit) {
CARD8 what; CARD8 what;
if (!XkbIM_InUse(map)) if (!map || !XkbIM_InUse(map))
continue; continue;
sli->mapsPresent|= bit; sli->mapsPresent|= bit;
@ -615,6 +615,45 @@ XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli)
return; 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;
}
/***====================================================================***/ /***====================================================================***/