Xi: Change ChangeMasterDeviceClasses to new XI2 events.

Split ChangeMasterDeviceClasses into an extra XISendDeviceChangedEvent that
assembles the XI2 wire event for the DeviceChanged event. Re-use this when
detaching the last SD.

Not quite perfect yet, we still copy the device classes from the slave now
rather than from the data we had when the event occured. But it's a start.

(We can now unexport SizeDeviceInfo and CopySwapDevices, not needed anymore)

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2009-02-20 16:07:33 +10:00
parent 181e41511d
commit 38bba0c1b7
9 changed files with 217 additions and 119 deletions

View File

@ -56,12 +56,13 @@ SOFTWARE.
#include <dix-config.h> #include <dix-config.h>
#endif #endif
#include "inputstr.h"
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xproto.h> #include <X11/Xproto.h>
#include <X11/extensions/XI.h> #include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h> #include <X11/extensions/XIproto.h>
#include <X11/extensions/XI2proto.h>
#include <X11/extensions/geproto.h> #include <X11/extensions/geproto.h>
#include "inputstr.h"
#include "windowstr.h" #include "windowstr.h"
#include "miscstruct.h" #include "miscstruct.h"
#include "region.h" #include "region.h"
@ -73,6 +74,7 @@ SOFTWARE.
#include "scrnintstr.h" #include "scrnintstr.h"
#include "listdev.h" /* for CopySwapXXXClass */ #include "listdev.h" /* for CopySwapXXXClass */
#include "xace.h" #include "xace.h"
#include "querydev.h" /* For List*Info */
#include <X11/extensions/XKBproto.h> #include <X11/extensions/XKBproto.h>
#include "xkbsrv.h" #include "xkbsrv.h"
@ -654,15 +656,78 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
* @param device The slave device * @param device The slave device
* @param dcce Pointer to the event struct. * @param dcce Pointer to the event struct.
*/ */
void
XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce)
{
xXIDeviceChangedEvent *dcce;
int len = sizeof(xXIDeviceChangedEvent);
int nkeys;
char *ptr;
if (dce->buttons.num_buttons)
{
len += sizeof(xXIButtonInfo);
len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
}
if (dce->num_valuators)
len += sizeof(xXIValuatorInfo) * dce->num_valuators;
nkeys = (dce->keys.max_keycode > 0) ?
dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
if (nkeys > 0)
{
len += sizeof(xXIKeyInfo);
len += sizeof(CARD32) * nkeys; /* keycodes */
}
dcce = xalloc(len);
if (!dcce)
{
ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
return;
}
dcce->type = GenericEvent;
dcce->extension = IReqCode;
dcce->evtype = XI_DeviceChanged;
dcce->time = GetTimeInMillis();
dcce->deviceid = master->id;
dcce->sourceid = device->id;
dcce->reason = SlaveSwitch;
dcce->num_classes = 0;
dcce->length = (len - sizeof(xEvent))/4;
ptr = (char*)&dcce[1];
if (dce->buttons.num_buttons)
{
dcce->num_classes++;
ptr += ListButtonInfo(device, (xXIButtonInfo*)ptr);
}
if (nkeys)
{
dcce->num_classes++;
ptr += ListKeyInfo(device, (xXIKeyInfo*)ptr);
}
if (dce->num_valuators)
{
int i;
dcce->num_classes += dce->num_valuators;
for (i = 0; i < dce->num_valuators; i++)
ptr += ListValuatorInfo(device, (xXIValuatorInfo*)ptr, i);
}
/* we don't actually swap if there's a NullClient, swapping is done
* later when event is delivered. */
SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1);
}
static void static void
ChangeMasterDeviceClasses(DeviceIntPtr device, ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
DeviceChangedEvent *dce)
{ {
DeviceIntPtr master = device->u.master; DeviceIntPtr master = device->u.master;
deviceClassesChangedEvent *dcce;
char* classbuff;
int len = sizeof(xEvent);
int namelen = 0; /* dummy */
if (device->isMaster) if (device->isMaster)
return; return;
@ -670,34 +735,11 @@ ChangeMasterDeviceClasses(DeviceIntPtr device,
if (!master) /* if device was set floating between SIGIO and now */ if (!master) /* if device was set floating between SIGIO and now */
return; return;
SizeDeviceInfo(device, &namelen, &len);
dcce = xalloc(len);
if (!dcce)
{
ErrorF("[Xi] BadAlloc in ChangeMasterDeviceClasses\n");
return;
}
dcce->type = GenericEvent;
dcce->extension = IReqCode;
dcce->evtype = XI_DeviceClassesChangedNotify;
dcce->time = GetTimeInMillis();
dcce->new_slave = device->id;
dcce->deviceid = master->id;
dcce->num_classes = 0;
dcce->length = (len - sizeof(xEvent))/4;
master->public.devicePrivate = device->public.devicePrivate; master->public.devicePrivate = device->public.devicePrivate;
/* FIXME: the classes may have changed since we generated the event. */
DeepCopyDeviceClasses(device, master); DeepCopyDeviceClasses(device, master);
XISendDeviceChangedEvent(device, master, dce);
classbuff = (char*)&dcce[1];
/* we don't actually swap if there's a NullClient, swapping is done
* later when event is delivered. */
CopySwapClasses(NullClient, master, &dcce->num_classes, &classbuff);
SendEventToAllWindows(master, XI_DeviceClassesChangedMask,
(xEvent*)dcce, 1);
} }
/** /**

View File

@ -627,49 +627,111 @@ SDeviceLeaveNotifyEvent (xXILeaveEvent *from, xXILeaveEvent *to)
} }
static void static void
SDeviceClassesChangedEvent(deviceClassesChangedEvent* from, SDeviceChangedEvent(xXIDeviceChangedEvent* from, xXIDeviceChangedEvent* to)
deviceClassesChangedEvent* to)
{ {
char n; char n;
int i, j; int i, j;
xAnyClassPtr any; xXIAnyInfo *any;
*to = *from; *to = *from;
memcpy(&to[1], &from[1], from->length * 4); memcpy(&to[1], &from[1], from->length * 4);
swaps(&to->sequenceNumber, n); swaps(&to->sequenceNumber, n);
swapl(&to->length, n); swapl(&to->length, n);
swaps(&to->evtype, n);
swaps(&to->deviceid, n);
swapl(&to->time, n); swapl(&to->time, n);
swaps(&to->num_classes, n);
swaps(&to->sourceid, n);
/* now swap the actual classes */ /* now swap the actual classes */
any = (xAnyClassPtr)&to[1]; any = (xXIAnyInfo*)&to[1];
for (i = 0; i < to->num_classes; i++) for (i = 0; i < to->num_classes; i++)
{ {
switch(any->class) swaps(&any->type, n);
swaps(&any->length, n);
switch(any->type)
{ {
case KeyClass: case KeyClass:
swaps(&((xKeyInfoPtr)any)->num_keys, n); {
xXIKeyInfo *ki = (xXIKeyInfo*)any;
uint32_t *key = (uint32_t*)&ki[1];
for (j = 0; j < ki->num_keycodes; j++, key++)
swapl(key, n);
swaps(&ki->num_keycodes, n);
}
break; break;
case ButtonClass: case ButtonClass:
swaps(&((xButtonInfoPtr)any)->num_buttons, n); {
xXIButtonInfo *bi = (xXIButtonInfo*)any;
for (j = 0; j < bi->num_buttons; j++)
swapl(&bi[1 + j], n);
swaps(&bi->num_buttons, n);
}
break; break;
case ValuatorClass: case ValuatorClass:
{ {
xValuatorInfoPtr v = (xValuatorInfoPtr)any; xXIValuatorInfo* ai = (xXIValuatorInfo*)any;
xAxisInfoPtr a = (xAxisInfoPtr)&v[1]; swapl(&ai->name, n);
swapl(&ai->min.integral, n);
swapl(&v->motion_buffer_size, n); swapl(&ai->min.frac, n);
for (j = 0; j < v->num_axes; j++) swapl(&ai->max.integral, n);
{ swapl(&ai->max.frac, n);
swapl(&a->min_value, n); swapl(&ai->resolution, n);
swapl(&a->max_value, n); swaps(&ai->number, n);
swapl(&a->resolution, n);
a++;
}
} }
break; break;
} }
any = (xAnyClassPtr)((char*)any + any->length); any = (xXIAnyInfo*)((char*)any + any->length * 4);
}
}
static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to)
{
int i;
char n;
char *ptr;
char *vmask;
*to = *from;
memcpy(&to[1], &from[1], from->length * 4);
swaps(&to->sequenceNumber, n);
swapl(&to->length, n);
swaps(&to->evtype, n);
swaps(&to->deviceid, n);
swapl(&to->time, n);
swapl(&to->root, n);
swapl(&to->event, n);
swapl(&to->child, n);
swapl(&to->root_x.integral, n);
swapl(&to->root_x.frac, n);
swapl(&to->root_y.integral, n);
swapl(&to->root_y.frac, n);
swapl(&to->event_x.integral, n);
swapl(&to->event_x.frac, n);
swapl(&to->event_y.integral, n);
swapl(&to->event_y.frac, n);
swaps(&to->buttons_len, n);
swaps(&to->valuators_len, n);
swaps(&to->sourceid, n);
swapl(&to->mods.base_mods, n);
swapl(&to->mods.latched_mods, n);
swapl(&to->mods.locked_mods, n);
ptr = (char*)(&to[1]);
ptr += from->buttons_len;
vmask = ptr; /* valuator mask */
ptr += from->valuators_len;
for (i = 0; i < from->valuators_len * 32; i++)
{
if (BitIsOn(vmask, i))
{
swapl(((uint32_t*)ptr), n);
ptr += 4;
swapl(((uint32_t*)ptr), n);
ptr += 4;
}
} }
} }
@ -683,6 +745,13 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
case XI_Leave: case XI_Leave:
SDeviceLeaveNotifyEvent((xXILeaveEvent*)from, (xXILeaveEvent*)to); SDeviceLeaveNotifyEvent((xXILeaveEvent*)from, (xXILeaveEvent*)to);
break; break;
case XI_DeviceChanged:
SDeviceChangedEvent((xXIDeviceChangedEvent*)from,
(xXIDeviceChangedEvent*)to);
break;
default:
SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to);
break;
} }
} }

View File

@ -93,7 +93,7 @@ SProcXListInputDevices(ClientPtr client)
* *
*/ */
void static void
SizeDeviceInfo(DeviceIntPtr d, int *namesize, int *size) SizeDeviceInfo(DeviceIntPtr d, int *namesize, int *size)
{ {
int chunks; int chunks;
@ -273,22 +273,7 @@ CopySwapValuatorClass(ClientPtr client, ValuatorClassPtr v, char **buf)
return (i); return (i);
} }
/***********************************************************************
*
* This procedure lists information to be returned for an input device.
*
*/
static void static void
ListDeviceInfo(ClientPtr client, DeviceIntPtr d, xDeviceInfoPtr dev,
char **devbuf, char **classbuf, char **namebuf)
{
CopyDeviceName(namebuf, d->name);
CopySwapDevice(client, d, 0, devbuf);
CopySwapClasses(client, d, &dev->num_classes, classbuf);
}
void
CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes, CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes,
char** classbuf) char** classbuf)
{ {
@ -306,6 +291,22 @@ CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes,
} }
} }
/***********************************************************************
*
* This procedure lists information to be returned for an input device.
*
*/
static void
ListDeviceInfo(ClientPtr client, DeviceIntPtr d, xDeviceInfoPtr dev,
char **devbuf, char **classbuf, char **namebuf)
{
CopyDeviceName(namebuf, d->name);
CopySwapDevice(client, d, 0, devbuf);
CopySwapClasses(client, d, &dev->num_classes, classbuf);
}
/*********************************************************************** /***********************************************************************
* *
* This procedure lists the input devices available to the server. * This procedure lists the input devices available to the server.

View File

@ -43,15 +43,4 @@ void SRepXListInputDevices(ClientPtr /* client */ ,
xListInputDevicesReply * /* rep */ xListInputDevicesReply * /* rep */
); );
void
CopySwapClasses(ClientPtr /* client */,
DeviceIntPtr /* dev */,
CARD8* /* num_classes */,
char** /* classbuf */);
void
SizeDeviceInfo(DeviceIntPtr /* dev */,
int* /* namesize */,
int* /* size */);
#endif /* LISTDEV_H */ #endif /* LISTDEV_H */

View File

@ -219,7 +219,7 @@ SizeDeviceClasses(DeviceIntPtr dev)
* Write button information into info. * Write button information into info.
* @return Number of bytes written into info. * @return Number of bytes written into info.
*/ */
static int int
ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info) ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
{ {
info->type = ButtonClass; info->type = ButtonClass;
@ -250,7 +250,7 @@ SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
* Write key information into info. * Write key information into info.
* @return Number of bytes written into info. * @return Number of bytes written into info.
*/ */
static int int
ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info) ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
{ {
int i; int i;
@ -288,7 +288,7 @@ SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
* *
* @return The number of bytes written into info. * @return The number of bytes written into info.
*/ */
static int int
ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber) ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber)
{ {
ValuatorClassPtr v = dev->valuator; ValuatorClassPtr v = dev->valuator;

View File

@ -39,4 +39,7 @@ void SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep);
int SizeDeviceClasses(DeviceIntPtr dev); int SizeDeviceClasses(DeviceIntPtr dev);
int ListDeviceClasses(DeviceIntPtr dev, char* any, uint16_t* nclasses); int ListDeviceClasses(DeviceIntPtr dev, char* any, uint16_t* nclasses);
int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment); int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment);
int ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info);
int ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info);
int ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber);
#endif /* QUERYDEV_H */ #endif /* QUERYDEV_H */

View File

@ -2217,28 +2217,14 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
if (!it) /* no dev is paired with old master */ if (!it) /* no dev is paired with old master */
{ {
/* XXX: reset to defaults */
EventListPtr event = NULL; EventListPtr event = NULL;
char* classbuf;
int namelen = 0; /* dummy */
int len = sizeof(xEvent);
deviceClassesChangedEvent *dcce;
/* XXX: reset master back to defaults */
event = InitEventList(1); event = InitEventList(1);
SizeDeviceInfo(oldmaster, &namelen, &len); SetMinimumEventSize(event, 1, sizeof(DeviceChangedEvent));
SetMinimumEventSize(event, 1, len);
/* Send event to clients */
CreateClassesChangedEvent(event, oldmaster, oldmaster); CreateClassesChangedEvent(event, oldmaster, oldmaster);
dcce = (deviceClassesChangedEvent*)event->event; XISendDeviceChangedEvent(oldmaster, oldmaster,
dcce->deviceid = oldmaster->id; (DeviceChangedEvent*)event->event);
dcce->num_classes = 0;
dcce->length = (len - sizeof(xEvent))/4;
classbuf = (char*)&event->event[1];
CopySwapClasses(NullClient, oldmaster,
&dcce->num_classes, &classbuf);
SendEventToAllWindows(oldmaster, XI_DeviceClassesChangedMask,
event->event, 1);
FreeEventList(event, 1); FreeEventList(event, 1);
} }
} }

View File

@ -45,13 +45,12 @@
#include "events.h" #include "events.h"
#include "exglobals.h" #include "exglobals.h"
#include "eventconvert.h" #include "eventconvert.h"
#include "listdev.h" #include "querydev.h"
static int countValuators(DeviceEvent *ev, int *first); static int countValuators(DeviceEvent *ev, int *first);
static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv); static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count); static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
static int eventToClassesChanged(DeviceChangedEvent *ev, xEvent **dcce, static int eventToClassesChanged(DeviceChangedEvent *ev, xEvent **dcce);
int *count);
static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi); static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
/** /**
* Convert the given event to the respective core event. * Convert the given event to the respective core event.
@ -127,8 +126,9 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
case ET_ProximityOut: case ET_ProximityOut:
return eventToKeyButtonPointer((DeviceEvent*)ev, xi, count); return eventToKeyButtonPointer((DeviceEvent*)ev, xi, count);
case ET_DeviceChanged: case ET_DeviceChanged:
return eventToClassesChanged((DeviceChangedEvent*)ev, xi, count); *count = 0;
break; *xi = NULL;
return Success;
} }
ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->u.any.type); ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->u.any.type);
@ -162,6 +162,9 @@ EventToXI2(InternalEvent *ev, xEvent **xi)
case ET_ProximityOut: case ET_ProximityOut:
*xi = NULL; *xi = NULL;
return Success; return Success;
case ET_DeviceChanged:
return eventToClassesChanged((DeviceChangedEvent*)ev, xi);
} }
ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->u.any.type); ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->u.any.type);
@ -290,14 +293,12 @@ getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
} }
static int static int
eventToClassesChanged(DeviceChangedEvent *ev, xEvent **xi, int *count) eventToClassesChanged(DeviceChangedEvent *ev, xEvent **xi)
{ {
int len = sizeof(xEvent); int len = sizeof(xEvent);
int namelen = 0; /* dummy */
DeviceIntPtr slave; DeviceIntPtr slave;
int rc; int rc;
deviceClassesChangedEvent *dcce; xXIDeviceChangedEvent *dce;
rc = dixLookupDevice(&slave, ev->new_slaveid, rc = dixLookupDevice(&slave, ev->new_slaveid,
serverClient, DixReadAccess); serverClient, DixReadAccess);
@ -305,21 +306,25 @@ eventToClassesChanged(DeviceChangedEvent *ev, xEvent **xi, int *count)
if (rc != Success) if (rc != Success)
return rc; return rc;
SizeDeviceInfo(slave, &namelen, &len); len += SizeDeviceClasses(slave);
*xi = xcalloc(1, len); *xi = xcalloc(1, len);
if (!(*xi)) if (!(*xi))
return BadAlloc; return BadAlloc;
dcce = (deviceClassesChangedEvent*)(*xi); dce = (xXIDeviceChangedEvent*)(*xi);
dcce->type = GenericEvent; dce->type = GenericEvent;
dcce->extension = IReqCode; dce->extension = IReqCode;
dcce->evtype = XI_DeviceClassesChangedNotify; dce->evtype = XI_DeviceChanged;
dcce->time = GetTimeInMillis(); dce->time = GetTimeInMillis();
dcce->new_slave = slave->id; dce->sourceid = slave->id;
dcce->length = (len - sizeof(xEvent))/4; dce->reason = SlaveSwitch;
dce->length = (len - sizeof(xEvent))/4;
/* FIXME: this should come from the event, not from the device. See
* CreateClassesChangedEvent */
ListDeviceClasses(slave, (char*)&dce[1], &dce->num_classes);
*count = 1;
return Success; return Success;
} }
@ -350,7 +355,6 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
char *ptr; char *ptr;
int32_t *axisval; int32_t *axisval;
/* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
* with MAX_VALUATORS below */ * with MAX_VALUATORS below */
/* btlen is in 4 byte units */ /* btlen is in 4 byte units */

View File

@ -250,4 +250,8 @@ extern _X_EXPORT int XIPropToFloat(
* would it merely be irrelevant and confusing? */ * would it merely be irrelevant and confusing? */
extern _X_EXPORT int XIShouldNotify(ClientPtr client, DeviceIntPtr dev); extern _X_EXPORT int XIShouldNotify(ClientPtr client, DeviceIntPtr dev);
extern void
XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master,
DeviceChangedEvent *dce);
#endif /* EXEVENTS_H */ #endif /* EXEVENTS_H */