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>
#endif
#include "inputstr.h"
#include <X11/X.h>
#include <X11/Xproto.h>
#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h>
#include <X11/extensions/XI2proto.h>
#include <X11/extensions/geproto.h>
#include "inputstr.h"
#include "windowstr.h"
#include "miscstruct.h"
#include "region.h"
@ -73,6 +74,7 @@ SOFTWARE.
#include "scrnintstr.h"
#include "listdev.h" /* for CopySwapXXXClass */
#include "xace.h"
#include "querydev.h" /* For List*Info */
#include <X11/extensions/XKBproto.h>
#include "xkbsrv.h"
@ -654,15 +656,78 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
* @param device The slave device
* @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
ChangeMasterDeviceClasses(DeviceIntPtr device,
DeviceChangedEvent *dce)
ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
{
DeviceIntPtr master = device->u.master;
deviceClassesChangedEvent *dcce;
char* classbuff;
int len = sizeof(xEvent);
int namelen = 0; /* dummy */
if (device->isMaster)
return;
@ -670,34 +735,11 @@ ChangeMasterDeviceClasses(DeviceIntPtr device,
if (!master) /* if device was set floating between SIGIO and now */
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;
/* FIXME: the classes may have changed since we generated the event. */
DeepCopyDeviceClasses(device, master);
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);
XISendDeviceChangedEvent(device, master, dce);
}
/**

View File

@ -627,49 +627,111 @@ SDeviceLeaveNotifyEvent (xXILeaveEvent *from, xXILeaveEvent *to)
}
static void
SDeviceClassesChangedEvent(deviceClassesChangedEvent* from,
deviceClassesChangedEvent* to)
SDeviceChangedEvent(xXIDeviceChangedEvent* from, xXIDeviceChangedEvent* to)
{
char n;
int i, j;
xAnyClassPtr any;
xXIAnyInfo *any;
*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);
swaps(&to->num_classes, n);
swaps(&to->sourceid, n);
/* now swap the actual classes */
any = (xAnyClassPtr)&to[1];
any = (xXIAnyInfo*)&to[1];
for (i = 0; i < to->num_classes; i++)
{
switch(any->class)
swaps(&any->type, n);
swaps(&any->length, n);
switch(any->type)
{
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;
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;
case ValuatorClass:
{
xValuatorInfoPtr v = (xValuatorInfoPtr)any;
xAxisInfoPtr a = (xAxisInfoPtr)&v[1];
swapl(&v->motion_buffer_size, n);
for (j = 0; j < v->num_axes; j++)
{
swapl(&a->min_value, n);
swapl(&a->max_value, n);
swapl(&a->resolution, n);
a++;
}
xXIValuatorInfo* ai = (xXIValuatorInfo*)any;
swapl(&ai->name, n);
swapl(&ai->min.integral, n);
swapl(&ai->min.frac, n);
swapl(&ai->max.integral, n);
swapl(&ai->max.frac, n);
swapl(&ai->resolution, n);
swaps(&ai->number, n);
}
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:
SDeviceLeaveNotifyEvent((xXILeaveEvent*)from, (xXILeaveEvent*)to);
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)
{
int chunks;
@ -273,22 +273,7 @@ CopySwapValuatorClass(ClientPtr client, ValuatorClassPtr v, char **buf)
return (i);
}
/***********************************************************************
*
* 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);
}
void
CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes,
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.

View File

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

View File

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

View File

@ -39,4 +39,7 @@ void SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep);
int SizeDeviceClasses(DeviceIntPtr dev);
int ListDeviceClasses(DeviceIntPtr dev, char* any, uint16_t* nclasses);
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 */

View File

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

View File

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

View File

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