diff --git a/Xi/exevents.c b/Xi/exevents.c index 885148734..fe11694b9 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -56,12 +56,13 @@ SOFTWARE. #include #endif +#include "inputstr.h" #include #include #include #include +#include #include -#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 #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); } /** diff --git a/Xi/extinit.c b/Xi/extinit.c index 8452186a5..5e87451f5 100644 --- a/Xi/extinit.c +++ b/Xi/extinit.c @@ -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; } } diff --git a/Xi/listdev.c b/Xi/listdev.c index 925d0ecbf..e7d0a9d68 100644 --- a/Xi/listdev.c +++ b/Xi/listdev.c @@ -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. diff --git a/Xi/listdev.h b/Xi/listdev.h index 39ea2d635..b0d2dd5e2 100644 --- a/Xi/listdev.h +++ b/Xi/listdev.h @@ -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 */ diff --git a/Xi/querydev.c b/Xi/querydev.c index 0d90fa926..c7ee0e162 100644 --- a/Xi/querydev.c +++ b/Xi/querydev.c @@ -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; diff --git a/Xi/querydev.h b/Xi/querydev.h index 92ab2bd77..34e87bdde 100644 --- a/Xi/querydev.h +++ b/Xi/querydev.h @@ -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 */ diff --git a/dix/devices.c b/dix/devices.c index ca0da070a..0795d30ea 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -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); } } diff --git a/dix/eventconvert.c b/dix/eventconvert.c index c3328d63f..553d95330 100644 --- a/dix/eventconvert.c +++ b/dix/eventconvert.c @@ -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 */ diff --git a/include/exevents.h b/include/exevents.h index d09ad3c5b..4ee7084ef 100644 --- a/include/exevents.h +++ b/include/exevents.h @@ -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 */