XKBExtDev.c revision 61b2299d
11ab64890Smrg/* $Xorg: XKBExtDev.c,v 1.3 2000/08/17 19:45:01 cpqbld Exp $ */
21ab64890Smrg/************************************************************
31ab64890SmrgCopyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
41ab64890Smrg
51ab64890SmrgPermission to use, copy, modify, and distribute this
61ab64890Smrgsoftware and its documentation for any purpose and without
71ab64890Smrgfee is hereby granted, provided that the above copyright
81ab64890Smrgnotice appear in all copies and that both that copyright
91ab64890Smrgnotice and this permission notice appear in supporting
1061b2299dSmrgdocumentation, and that the name of Silicon Graphics not be
1161b2299dSmrgused in advertising or publicity pertaining to distribution
121ab64890Smrgof the software without specific prior written permission.
1361b2299dSmrgSilicon Graphics makes no representation about the suitability
141ab64890Smrgof this software for any purpose. It is provided "as is"
151ab64890Smrgwithout any express or implied warranty.
161ab64890Smrg
1761b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1861b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
191ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
2061b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2161b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2261b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
231ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
241ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
251ab64890Smrg
261ab64890Smrg********************************************************/
271ab64890Smrg/* $XFree86: xc/lib/X11/XKBExtDev.c,v 3.4 2001/10/28 03:32:33 tsi Exp $ */
281ab64890Smrg
291ab64890Smrg#ifdef HAVE_CONFIG_H
301ab64890Smrg#include <config.h>
311ab64890Smrg#endif
321ab64890Smrg#include <stdio.h>
331ab64890Smrg#define NEED_REPLIES
341ab64890Smrg#define NEED_EVENTS
351ab64890Smrg#define	NEED_MAP_READERS
361ab64890Smrg#include "Xlibint.h"
371ab64890Smrg#include <X11/extensions/XKBproto.h>
381ab64890Smrg#include "XKBlibint.h"
391ab64890Smrg#include <X11/extensions/XI.h>
401ab64890Smrg
411ab64890Smrg/***====================================================================***/
421ab64890Smrg
431ab64890Smrgextern void
441ab64890SmrgXkbNoteDeviceChanges(	XkbDeviceChangesPtr		old,
451ab64890Smrg			XkbExtensionDeviceNotifyEvent *	new,
461ab64890Smrg			unsigned int			wanted)
471ab64890Smrg{
481ab64890Smrg    if ((!old)||(!new)||(!wanted)||((new->reason&wanted)==0))
491ab64890Smrg	return;
501ab64890Smrg    if ((wanted&new->reason)&XkbXI_ButtonActionsMask) {
511ab64890Smrg	if (old->changed&XkbXI_ButtonActionsMask) {
521ab64890Smrg	    int first,last,newLast;
531ab64890Smrg	    if (new->first_btn<old->first_btn)
541ab64890Smrg		 first= new->first_btn;
551ab64890Smrg	    else first= old->first_btn;
561ab64890Smrg	    last= old->first_btn+old->num_btns-1;
571ab64890Smrg	    newLast= new->first_btn+new->num_btns-1;
581ab64890Smrg	    if (newLast>last)
591ab64890Smrg		last= newLast;
601ab64890Smrg	    old->first_btn= first;
611ab64890Smrg	    old->num_btns= (last-first)+1;
621ab64890Smrg	}
631ab64890Smrg	else {
641ab64890Smrg	    old->changed|= XkbXI_ButtonActionsMask;
651ab64890Smrg	    old->first_btn= new->first_btn;
661ab64890Smrg	    old->num_btns= new->num_btns;
671ab64890Smrg	}
681ab64890Smrg    }
691ab64890Smrg    if ((wanted&new->reason)&XkbXI_IndicatorsMask) {
701ab64890Smrg	XkbDeviceLedChangesPtr this;
711ab64890Smrg	if (old->changed&XkbXI_IndicatorsMask) {
721ab64890Smrg	    XkbDeviceLedChangesPtr found;
731ab64890Smrg	    found= NULL;
741ab64890Smrg	    for (this= &old->leds;this&&(!found);this=this->next) {
751ab64890Smrg		if ((this->led_class==new->led_class)&&
761ab64890Smrg						(this->led_id==new->led_id)) {
771ab64890Smrg		    found= this;
781ab64890Smrg		}
791ab64890Smrg	    }
801ab64890Smrg	    if (!found) {
811ab64890Smrg		found= _XkbTypedCalloc(1,XkbDeviceLedChangesRec);
821ab64890Smrg		if (!found)
831ab64890Smrg		    return;
841ab64890Smrg		found->next= old->leds.next;
851ab64890Smrg		found->led_class= new->led_class;
861ab64890Smrg		found->led_id= new->led_id;
871ab64890Smrg		old->leds.next= found;
881ab64890Smrg	    }
891ab64890Smrg	    if ((wanted&new->reason)&XkbXI_IndicatorNamesMask)
901ab64890Smrg		found->defined= new->leds_defined;
911ab64890Smrg	}
921ab64890Smrg	else {
931ab64890Smrg	    old->changed|= ((wanted&new->reason)&XkbXI_IndicatorsMask);
941ab64890Smrg	    old->leds.led_class= new->led_class;
951ab64890Smrg	    old->leds.led_id= new->led_id;
961ab64890Smrg	    old->leds.defined= new->leds_defined;
971ab64890Smrg	    if (old->leds.next) {
981ab64890Smrg		XkbDeviceLedChangesPtr next;
991ab64890Smrg		for (this=old->leds.next;this;this=next) {
1001ab64890Smrg		    next= this->next;
1011ab64890Smrg		    _XkbFree(this);
1021ab64890Smrg		}
1031ab64890Smrg		old->leds.next= NULL;
1041ab64890Smrg	    }
1051ab64890Smrg	}
1061ab64890Smrg    }
1071ab64890Smrg    return;
1081ab64890Smrg}
1091ab64890Smrg
1101ab64890Smrg/***====================================================================***/
1111ab64890Smrg
1121ab64890Smrgstatic Status
1131ab64890Smrg_XkbReadDeviceLedInfo(	XkbReadBufferPtr	buf,
1141ab64890Smrg			unsigned 		present,
1151ab64890Smrg			XkbDeviceInfoPtr 	devi)
1161ab64890Smrg{
1171ab64890Smrgregister unsigned	i,bit;
1181ab64890SmrgXkbDeviceLedInfoPtr	devli;
1191ab64890SmrgxkbDeviceLedsWireDesc *	wireli;
1201ab64890Smrg
1211ab64890Smrg    wireli= _XkbGetTypedRdBufPtr(buf,1,xkbDeviceLedsWireDesc);
1221ab64890Smrg    if (!wireli)
1231ab64890Smrg	return BadLength;
1241ab64890Smrg    devli= XkbAddDeviceLedInfo(devi,wireli->ledClass,wireli->ledID);
1251ab64890Smrg    if (!devli)
1261ab64890Smrg	return BadAlloc;
1271ab64890Smrg    devli->phys_indicators= 	wireli->physIndicators;
1281ab64890Smrg
1291ab64890Smrg    if (present&XkbXI_IndicatorStateMask)
1301ab64890Smrg	devli->state= wireli->state;
1311ab64890Smrg
1321ab64890Smrg    if (present&XkbXI_IndicatorNamesMask) {
1331ab64890Smrg	devli->names_present= 	wireli->namesPresent;
1341ab64890Smrg	if (devli->names_present) {
1351ab64890Smrg	    for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
1361ab64890Smrg		if (wireli->namesPresent&bit) {
1371ab64890Smrg		    if (!_XkbCopyFromReadBuffer(buf,(char *)&devli->names[i],4))
1381ab64890Smrg			return BadLength;
1391ab64890Smrg		}
1401ab64890Smrg	    }
1411ab64890Smrg	}
1421ab64890Smrg    }
1431ab64890Smrg
1441ab64890Smrg    if (present&XkbXI_IndicatorMapsMask) {
1451ab64890Smrg	devli->maps_present= 	wireli->mapsPresent;
1461ab64890Smrg	if (devli->maps_present) {
1471ab64890Smrg	    XkbIndicatorMapPtr	 	im;
1481ab64890Smrg	    xkbIndicatorMapWireDesc *	wireim;
1491ab64890Smrg	    for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
1501ab64890Smrg		if (wireli->mapsPresent&bit) {
1511ab64890Smrg		    wireim= _XkbGetTypedRdBufPtr(buf,1,xkbIndicatorMapWireDesc);
1521ab64890Smrg		    if (!wireim)
1531ab64890Smrg			return BadAlloc;
1541ab64890Smrg		    im= &devli->maps[i];
1551ab64890Smrg		    im->flags= 		wireim->flags;
1561ab64890Smrg		    im->which_groups= 	wireim->whichGroups;
1571ab64890Smrg		    im->groups= 	wireim->groups;
1581ab64890Smrg		    im->which_mods= 	wireim->whichMods;
1591ab64890Smrg		    im->mods.mask= 	wireim->mods;
1601ab64890Smrg		    im->mods.real_mods= wireim->realMods;
1611ab64890Smrg		    im->mods.vmods= 	wireim->virtualMods;
1621ab64890Smrg		    im->ctrls= 		wireim->ctrls;
1631ab64890Smrg		}
1641ab64890Smrg	    }
1651ab64890Smrg	}
1661ab64890Smrg    }
1671ab64890Smrg    return Success;
1681ab64890Smrg}
1691ab64890Smrg
1701ab64890Smrgstatic Status
1711ab64890Smrg_XkbReadGetDeviceInfoReply(	Display *		dpy,
1721ab64890Smrg				xkbGetDeviceInfoReply *	rep,
1731ab64890Smrg				XkbDeviceInfoPtr	devi)
1741ab64890Smrg{
1751ab64890SmrgXkbReadBufferRec	buf;
1761ab64890SmrgXkbAction *		act;
1771ab64890Smrgint			tmp;
1781ab64890Smrg
17961b2299dSmrg    if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4))
1801ab64890Smrg	return BadAlloc;
1811ab64890Smrg
1821ab64890Smrg    if ((rep->totalBtns>0)&&(rep->totalBtns!=devi->num_btns)) {
1831ab64890Smrg	tmp= XkbResizeDeviceButtonActions(devi,rep->totalBtns);
1841ab64890Smrg	if (tmp!=Success)
1851ab64890Smrg	    return tmp;
1861ab64890Smrg    }
1871ab64890Smrg    if (rep->nBtnsWanted>0) {
1881ab64890Smrg	act= &devi->btn_acts[rep->firstBtnWanted];
1891ab64890Smrg	bzero((char *)act,(rep->nBtnsWanted*sizeof(XkbAction)));
1901ab64890Smrg    }
1911ab64890Smrg    if (devi->name!=NULL)
1921ab64890Smrg	_XkbFree(devi->name);
1931ab64890Smrg    if (!_XkbGetReadBufferCountedString(&buf,&devi->name))
1941ab64890Smrg	goto BAILOUT;
1951ab64890Smrg    if (rep->nBtnsRtrn>0) {
1961ab64890Smrg	int size;
1971ab64890Smrg	act= &devi->btn_acts[rep->firstBtnRtrn];
1981ab64890Smrg	size= rep->nBtnsRtrn*SIZEOF(xkbActionWireDesc);
1991ab64890Smrg	if (!_XkbCopyFromReadBuffer(&buf,(char *)act,size))
2001ab64890Smrg	    goto BAILOUT;
2011ab64890Smrg    }
2021ab64890Smrg    if (rep->nDeviceLedFBs>0) {
2031ab64890Smrg	register int 		i;
2041ab64890Smrg	for (i=0;i<rep->nDeviceLedFBs;i++) {
2051ab64890Smrg	    if ((tmp= _XkbReadDeviceLedInfo(&buf,rep->present,devi))!=Success)
2061ab64890Smrg		return tmp;
2071ab64890Smrg	}
2081ab64890Smrg    }
2091ab64890Smrg    tmp= _XkbFreeReadBuffer(&buf);
21061b2299dSmrg    if (tmp)
2111ab64890Smrg	fprintf(stderr,"GetDeviceInfo! Bad length (%d extra bytes)\n",tmp);
2121ab64890Smrg    if (tmp || buf.error)
2131ab64890Smrg	return BadLength;
2141ab64890Smrg    return Success;
2151ab64890SmrgBAILOUT:
2161ab64890Smrg    _XkbFreeReadBuffer(&buf);
2171ab64890Smrg    return BadLength;
2181ab64890Smrg}
2191ab64890Smrg
2201ab64890SmrgXkbDeviceInfoPtr
2211ab64890SmrgXkbGetDeviceInfo(	Display *	dpy,
2221ab64890Smrg			unsigned 	which,
2231ab64890Smrg			unsigned 	deviceSpec,
2241ab64890Smrg			unsigned 	class,
2251ab64890Smrg			unsigned 	id)
2261ab64890Smrg{
2271ab64890Smrg    register xkbGetDeviceInfoReq *	req;
2281ab64890Smrg    xkbGetDeviceInfoReply	 	rep;
2291ab64890Smrg    Status				status;
2301ab64890Smrg    XkbDeviceInfoPtr			devi;
2311ab64890Smrg
2321ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
2331ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
2341ab64890Smrg	return NULL;
2351ab64890Smrg    LockDisplay(dpy);
2361ab64890Smrg    GetReq(kbGetDeviceInfo, req);
2371ab64890Smrg    req->reqType = dpy->xkb_info->codes->major_opcode;
2381ab64890Smrg    req->xkbReqType = X_kbGetDeviceInfo;
2391ab64890Smrg    req->deviceSpec = deviceSpec;
2401ab64890Smrg    req->wanted= which;
2411ab64890Smrg    req->allBtns= ((which&XkbXI_ButtonActionsMask)!=0);
2421ab64890Smrg    req->firstBtn= req->nBtns= 0;
2431ab64890Smrg    req->ledClass= class;
2441ab64890Smrg    req->ledID= id;
2451ab64890Smrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
2461ab64890Smrg	UnlockDisplay(dpy);
2471ab64890Smrg	SyncHandle();
2481ab64890Smrg	return NULL;
2491ab64890Smrg    }
2501ab64890Smrg    devi= XkbAllocDeviceInfo(rep.deviceID,rep.totalBtns,rep.nDeviceLedFBs);
2511ab64890Smrg    if (devi) {
2521ab64890Smrg	devi->supported= rep.supported;
2531ab64890Smrg	devi->unsupported= rep.unsupported;
2541ab64890Smrg	devi->type= rep.devType;
2551ab64890Smrg	devi->has_own_state= rep.hasOwnState;
2561ab64890Smrg	devi->dflt_kbd_fb = rep.dfltKbdFB;
2571ab64890Smrg	devi->dflt_led_fb = rep.dfltLedFB;
2581ab64890Smrg	status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi);
2591ab64890Smrg	if (status!=Success) {
2601ab64890Smrg	    XkbFreeDeviceInfo(devi,XkbXI_AllDeviceFeaturesMask,True);
2611ab64890Smrg	    devi= NULL;
2621ab64890Smrg	}
2631ab64890Smrg    }
2641ab64890Smrg    UnlockDisplay(dpy);
2651ab64890Smrg    SyncHandle();
2661ab64890Smrg    return devi;
2671ab64890Smrg}
2681ab64890Smrg
2691ab64890SmrgStatus
2701ab64890SmrgXkbGetDeviceInfoChanges(	Display *		dpy,
2711ab64890Smrg				XkbDeviceInfoPtr 	devi,
2721ab64890Smrg				XkbDeviceChangesPtr	changes)
2731ab64890Smrg{
2741ab64890Smrg    register xkbGetDeviceInfoReq *	req;
2751ab64890Smrg    xkbGetDeviceInfoReply	 	rep;
2761ab64890Smrg    Status				status;
2771ab64890Smrg
2781ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
2791ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
2801ab64890Smrg	return BadMatch;
2811ab64890Smrg    if ((changes->changed&XkbXI_AllDeviceFeaturesMask)==0)
2821ab64890Smrg	return Success;
2831ab64890Smrg    changes->changed&= ~XkbXI_AllDeviceFeaturesMask;
2841ab64890Smrg    status= Success;
2851ab64890Smrg    LockDisplay(dpy);
2861ab64890Smrg    while ((changes->changed)&&(status==Success)) {
2871ab64890Smrg	GetReq(kbGetDeviceInfo, req);
2881ab64890Smrg	req->reqType = dpy->xkb_info->codes->major_opcode;
2891ab64890Smrg	req->xkbReqType = X_kbGetDeviceInfo;
2901ab64890Smrg	req->deviceSpec = devi->device_spec;
2911ab64890Smrg	req->wanted= changes->changed;
2921ab64890Smrg	req->allBtns= False;
2931ab64890Smrg	if (changes->changed&XkbXI_ButtonActionsMask) {
2941ab64890Smrg	     req->firstBtn= changes->first_btn;
2951ab64890Smrg	     req->nBtns= 	changes->num_btns;
2961ab64890Smrg	     changes->changed&= ~XkbXI_ButtonActionsMask;
2971ab64890Smrg	}
2981ab64890Smrg	else req->firstBtn= req->nBtns= 0;
2991ab64890Smrg	if (changes->changed&XkbXI_IndicatorsMask) {
3001ab64890Smrg	    req->ledClass= changes->leds.led_class;
3011ab64890Smrg	    req->ledID= changes->leds.led_id;
3021ab64890Smrg	    if (changes->leds.next==NULL)
3031ab64890Smrg		changes->changed&= ~XkbXI_IndicatorsMask;
3041ab64890Smrg	    else {
3051ab64890Smrg		XkbDeviceLedChangesPtr next;
3061ab64890Smrg		next= changes->leds.next;
3071ab64890Smrg		changes->leds= *next;
3081ab64890Smrg		_XkbFree(next);
3091ab64890Smrg	    }
3101ab64890Smrg	}
3111ab64890Smrg	else {
3121ab64890Smrg	    req->ledClass= XkbDfltXIClass;
3131ab64890Smrg	    req->ledID= XkbDfltXIId;
3141ab64890Smrg	}
3151ab64890Smrg	if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
3161ab64890Smrg	    status= BadLength;
3171ab64890Smrg	    break;
3181ab64890Smrg	}
3191ab64890Smrg	devi->supported|= rep.supported;
3201ab64890Smrg	devi->unsupported|= rep.unsupported;
3211ab64890Smrg	devi->type= rep.devType;
3221ab64890Smrg	status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi);
3231ab64890Smrg    }
3241ab64890Smrg    UnlockDisplay(dpy);
3251ab64890Smrg    SyncHandle();
3261ab64890Smrg    return status;
3271ab64890Smrg}
3281ab64890Smrg
3291ab64890SmrgStatus
3301ab64890SmrgXkbGetDeviceButtonActions(	Display *		dpy,
3311ab64890Smrg				XkbDeviceInfoPtr	devi,
3321ab64890Smrg				Bool			all,
3331ab64890Smrg				unsigned int		first,
3341ab64890Smrg				unsigned int		num)
3351ab64890Smrg{
3361ab64890Smrg    register xkbGetDeviceInfoReq *	req;
3371ab64890Smrg    xkbGetDeviceInfoReply	 	rep;
3381ab64890Smrg    Status				status;
3391ab64890Smrg
34061b2299dSmrg    if ((dpy->flags & XlibDisplayNoXkb) ||
3411ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
3421ab64890Smrg	return BadMatch;
3431ab64890Smrg    if (!devi)
3441ab64890Smrg	return BadValue;
3451ab64890Smrg    LockDisplay(dpy);
3461ab64890Smrg    GetReq(kbGetDeviceInfo, req);
3471ab64890Smrg    req->reqType = dpy->xkb_info->codes->major_opcode;
3481ab64890Smrg    req->xkbReqType = X_kbGetDeviceInfo;
3491ab64890Smrg    req->deviceSpec = devi->device_spec;
3501ab64890Smrg    req->wanted= XkbXI_ButtonActionsMask;
3511ab64890Smrg    req->allBtns= all;
3521ab64890Smrg    req->firstBtn= first;
3531ab64890Smrg    req->nBtns= num;
3541ab64890Smrg    req->ledClass= XkbDfltXIClass;
3551ab64890Smrg    req->ledID= XkbDfltXIId;
3561ab64890Smrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
3571ab64890Smrg	UnlockDisplay(dpy);
3581ab64890Smrg	SyncHandle();
3591ab64890Smrg	return BadLength;
3601ab64890Smrg    }
3611ab64890Smrg    devi->type= rep.devType;
3621ab64890Smrg    devi->supported= rep.supported;
3631ab64890Smrg    devi->unsupported= rep.unsupported;
3641ab64890Smrg    status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi);
3651ab64890Smrg    UnlockDisplay(dpy);
3661ab64890Smrg    SyncHandle();
3671ab64890Smrg    return status;
3681ab64890Smrg}
3691ab64890Smrg
3701ab64890SmrgStatus
3711ab64890SmrgXkbGetDeviceLedInfo(	Display *		dpy,
3721ab64890Smrg			XkbDeviceInfoPtr	devi,
3731ab64890Smrg			unsigned int		ledClass,
3741ab64890Smrg			unsigned int		ledId,
3751ab64890Smrg			unsigned int		which)
3761ab64890Smrg{
3771ab64890Smrg    register xkbGetDeviceInfoReq *	req;
3781ab64890Smrg    xkbGetDeviceInfoReply	 	rep;
3791ab64890Smrg    Status				status;
3801ab64890Smrg
38161b2299dSmrg    if ((dpy->flags & XlibDisplayNoXkb) ||
3821ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
3831ab64890Smrg	return BadMatch;
3841ab64890Smrg    if (((which&XkbXI_IndicatorsMask)==0)||(which&(~XkbXI_IndicatorsMask)))
3851ab64890Smrg	return BadMatch;
3861ab64890Smrg    if (!devi)
3871ab64890Smrg	return BadValue;
3881ab64890Smrg    LockDisplay(dpy);
3891ab64890Smrg    GetReq(kbGetDeviceInfo, req);
3901ab64890Smrg    req->reqType = dpy->xkb_info->codes->major_opcode;
3911ab64890Smrg    req->xkbReqType = X_kbGetDeviceInfo;
3921ab64890Smrg    req->deviceSpec = devi->device_spec;
3931ab64890Smrg    req->wanted= which;
3941ab64890Smrg    req->allBtns= False;
3951ab64890Smrg    req->firstBtn= req->nBtns= 0;
3961ab64890Smrg    req->ledClass= ledClass;
3971ab64890Smrg    req->ledID= ledId;
3981ab64890Smrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
3991ab64890Smrg	UnlockDisplay(dpy);
4001ab64890Smrg	SyncHandle();
4011ab64890Smrg	return BadLength;
40261b2299dSmrg    }
4031ab64890Smrg    devi->type= rep.devType;
4041ab64890Smrg    devi->supported= rep.supported;
4051ab64890Smrg    devi->unsupported= rep.unsupported;
4061ab64890Smrg    status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi);
4071ab64890Smrg    UnlockDisplay(dpy);
4081ab64890Smrg    SyncHandle();
4091ab64890Smrg    return status;
4101ab64890Smrg}
4111ab64890Smrg
4121ab64890Smrg/***====================================================================***/
4131ab64890Smrg
4141ab64890Smrgtypedef struct _LedInfoStuff {
4151ab64890Smrg	Bool			used;
4161ab64890Smrg	XkbDeviceLedInfoPtr	devli;
4171ab64890Smrg} LedInfoStuff;
4181ab64890Smrg
4191ab64890Smrgtypedef struct _SetLedStuff {
4201ab64890Smrg	unsigned		wanted;
4211ab64890Smrg	int			num_info;
4221ab64890Smrg	int			dflt_class;
4231ab64890Smrg	LedInfoStuff *		dflt_kbd_fb;
4241ab64890Smrg	LedInfoStuff *		dflt_led_fb;
4251ab64890Smrg	LedInfoStuff *		info;
4261ab64890Smrg} SetLedStuff;
4271ab64890Smrg
4281ab64890Smrgstatic void
4291ab64890Smrg_InitLedStuff(SetLedStuff *stuff,unsigned wanted,XkbDeviceInfoPtr devi)
4301ab64890Smrg{
4311ab64890Smrgint				i;
4321ab64890Smrgregister XkbDeviceLedInfoPtr	devli;
4331ab64890Smrg
4341ab64890Smrg    bzero(stuff,sizeof(SetLedStuff));
4351ab64890Smrg    stuff->wanted= wanted;
4361ab64890Smrg    stuff->dflt_class=	XkbXINone;
4371ab64890Smrg    if ((devi->num_leds<1)||((wanted&XkbXI_IndicatorsMask)==0))
4381ab64890Smrg	return;
4391ab64890Smrg    stuff->info= _XkbTypedCalloc(devi->num_leds,LedInfoStuff);
4401ab64890Smrg    if (!stuff->info)
4411ab64890Smrg	return;
4421ab64890Smrg    stuff->num_info= devi->num_leds;
4431ab64890Smrg    for (devli=&devi->leds[0],i=0;i<devi->num_leds;i++,devli++) {
4441ab64890Smrg	stuff->info[i].devli= devli;
4451ab64890Smrg	if (devli->led_class==KbdFeedbackClass) {
4461ab64890Smrg	    stuff->dflt_class= KbdFeedbackClass;
4471ab64890Smrg	    if (stuff->dflt_kbd_fb==NULL)
4481ab64890Smrg		stuff->dflt_kbd_fb= &stuff->info[i];
4491ab64890Smrg	}
4501ab64890Smrg	else if (devli->led_class==LedFeedbackClass) {
4511ab64890Smrg	    if (stuff->dflt_class==XkbXINone)
4521ab64890Smrg		stuff->dflt_class= LedFeedbackClass;
4531ab64890Smrg	    if (stuff->dflt_led_fb==NULL)
4541ab64890Smrg		stuff->dflt_led_fb= &stuff->info[i];
4551ab64890Smrg	}
4561ab64890Smrg    }
4571ab64890Smrg    return;
4581ab64890Smrg}
4591ab64890Smrg
4601ab64890Smrgstatic void
4611ab64890Smrg_FreeLedStuff(SetLedStuff *stuff)
4621ab64890Smrg{
4631ab64890Smrg    if ((stuff->num_info>0)&&(stuff->info!=NULL))
4641ab64890Smrg	_XkbFree(stuff->info);
4651ab64890Smrg    bzero(stuff,sizeof(SetLedStuff));
4661ab64890Smrg    return;
4671ab64890Smrg}
4681ab64890Smrg
4691ab64890Smrgstatic int
4701ab64890Smrg_XkbSizeLedInfo(unsigned changed,XkbDeviceLedInfoPtr devli)
4711ab64890Smrg{
4721ab64890Smrgregister int i,size;
4731ab64890Smrgregister unsigned bit,namesNeeded,mapsNeeded;
4741ab64890Smrg
4751ab64890Smrg    size= SIZEOF(xkbDeviceLedsWireDesc);
4761ab64890Smrg    namesNeeded= mapsNeeded= 0;
4771ab64890Smrg    if (changed&XkbXI_IndicatorNamesMask)
4781ab64890Smrg	namesNeeded= devli->names_present;
4791ab64890Smrg    if (changed&XkbXI_IndicatorMapsMask)
4801ab64890Smrg	mapsNeeded= devli->maps_present;
4811ab64890Smrg    if ((namesNeeded)||(mapsNeeded)) {
4821ab64890Smrg	for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
4831ab64890Smrg	    if (namesNeeded&bit)
4841ab64890Smrg		size+= 4; /* atoms are 4 bytes on the wire */
4851ab64890Smrg	    if (mapsNeeded&bit)
4861ab64890Smrg		size+= SIZEOF(xkbIndicatorMapWireDesc);
4871ab64890Smrg	}
4881ab64890Smrg    }
4891ab64890Smrg    return size;
4901ab64890Smrg}
4911ab64890Smrg
4921ab64890Smrgstatic Bool
4931ab64890Smrg_SizeMatches(	SetLedStuff *		stuff,
4941ab64890Smrg		XkbDeviceLedChangesPtr 	changes,
4951ab64890Smrg		int *			sz_rtrn,
4961ab64890Smrg		int *			nleds_rtrn)
4971ab64890Smrg{
4981ab64890Smrgint		i,nMatch,class,id;
4991ab64890SmrgLedInfoStuff *	linfo;
5001ab64890SmrgBool		match;
5011ab64890Smrg
5021ab64890Smrg    nMatch= 0;
5031ab64890Smrg    class= changes->led_class;
5041ab64890Smrg    id= changes->led_id;
5051ab64890Smrg    if (class==XkbDfltXIClass)
5061ab64890Smrg	class= stuff->dflt_class;
5071ab64890Smrg    for (i=0,linfo=&stuff->info[0];i<stuff->num_info;i++,linfo++) {
5081ab64890Smrg	XkbDeviceLedInfoPtr	devli;
5091ab64890Smrg	LedInfoStuff *		dflt;
5101ab64890Smrg
5111ab64890Smrg	devli= linfo->devli;
5121ab64890Smrg	match= ((class==devli->led_class)||(class==XkbAllXIClasses));
5131ab64890Smrg	if (devli->led_class==KbdFeedbackClass)	dflt= stuff->dflt_kbd_fb;
5141ab64890Smrg	else					dflt= stuff->dflt_led_fb;
5151ab64890Smrg	match = (match && (id == devli->led_id)) ||
5161ab64890Smrg	  (id == XkbAllXIIds) ||
5171ab64890Smrg	  ((id == XkbDfltXIId) &&
5181ab64890Smrg	   (linfo == dflt));
5191ab64890Smrg	if (match) {
5201ab64890Smrg	    if (!linfo->used) {
5211ab64890Smrg		*sz_rtrn+= _XkbSizeLedInfo(stuff->wanted,devli);
5221ab64890Smrg		*nleds_rtrn+= 1;
5231ab64890Smrg		linfo->used= True;
5241ab64890Smrg		if ((class!=XkbAllXIClasses)&&(id!=XkbAllXIIds))
5251ab64890Smrg		    return True;
5261ab64890Smrg	    }
5271ab64890Smrg	    nMatch++;
5281ab64890Smrg	    linfo->used= True;
5291ab64890Smrg	}
5301ab64890Smrg    }
5311ab64890Smrg    return (nMatch>0);
5321ab64890Smrg}
5331ab64890Smrg
5341ab64890Smrg/***====================================================================***/
5351ab64890Smrg
5361ab64890Smrg
5371ab64890Smrgstatic Status
5381ab64890Smrg_XkbSetDeviceInfoSize(	XkbDeviceInfoPtr	devi,
5391ab64890Smrg			XkbDeviceChangesPtr	changes,
5401ab64890Smrg			SetLedStuff *		stuff,
5411ab64890Smrg			int *			sz_rtrn,
5421ab64890Smrg			int *			num_leds_rtrn)
5431ab64890Smrg{
5441ab64890Smrg    *sz_rtrn= 0;
5451ab64890Smrg    if ((changes->changed&XkbXI_ButtonActionsMask)&&(changes->num_btns>0)) {
5461ab64890Smrg	if (!XkbXI_LegalDevBtn(devi,(changes->first_btn+changes->num_btns-1)))
5471ab64890Smrg	    return BadMatch;
5481ab64890Smrg	*sz_rtrn+= changes->num_btns*SIZEOF(xkbActionWireDesc);
5491ab64890Smrg    }
5501ab64890Smrg    else {
5511ab64890Smrg	changes->changed&= ~XkbXI_ButtonActionsMask;
5521ab64890Smrg	changes->first_btn= changes->num_btns= 0;
5531ab64890Smrg    }
5541ab64890Smrg    if ((changes->changed&XkbXI_IndicatorsMask)&&
5551ab64890Smrg				XkbLegalXILedClass(changes->leds.led_class)) {
5561ab64890Smrg	XkbDeviceLedChangesPtr	leds;
5571ab64890Smrg
5581ab64890Smrg	for (leds=&changes->leds;leds!=NULL;leds= leds->next) {
5591ab64890Smrg	    if (!_SizeMatches(stuff,leds,sz_rtrn,num_leds_rtrn))
5601ab64890Smrg		return BadMatch;
5611ab64890Smrg	}
5621ab64890Smrg    }
5631ab64890Smrg    else {
5641ab64890Smrg	changes->changed&= ~XkbXI_IndicatorsMask;
5651ab64890Smrg	*num_leds_rtrn= 0;
5661ab64890Smrg    }
5671ab64890Smrg    return Success;
5681ab64890Smrg}
5691ab64890Smrg
5701ab64890Smrgstatic char *
5711ab64890Smrg_XkbWriteLedInfo(char *wire,unsigned changed,XkbDeviceLedInfoPtr devli)
5721ab64890Smrg{
5731ab64890Smrgregister int 		i;
5741ab64890Smrgregister unsigned 	bit,namesNeeded,mapsNeeded;
5751ab64890SmrgxkbDeviceLedsWireDesc *	lwire;
5761ab64890Smrg
5771ab64890Smrg    namesNeeded= mapsNeeded= 0;
5781ab64890Smrg    if (changed&XkbXI_IndicatorNamesMask)
5791ab64890Smrg	namesNeeded= devli->names_present;
5801ab64890Smrg    if (changed&XkbXI_IndicatorMapsMask)
5811ab64890Smrg	mapsNeeded= devli->maps_present;
5821ab64890Smrg
5831ab64890Smrg    lwire= (xkbDeviceLedsWireDesc *)wire;
5841ab64890Smrg    lwire->ledClass= devli->led_class;
5851ab64890Smrg    lwire->ledID= devli->led_id;
5861ab64890Smrg    lwire->namesPresent= namesNeeded;
5871ab64890Smrg    lwire->mapsPresent=  mapsNeeded;
5881ab64890Smrg    lwire->physIndicators= devli->phys_indicators;
5891ab64890Smrg    lwire->state= devli->state;
5901ab64890Smrg    wire= (char *)&lwire[1];
5911ab64890Smrg    if (namesNeeded) {
5921ab64890Smrg	CARD32 *awire;
5931ab64890Smrg	awire= (CARD32 *)wire;
5941ab64890Smrg	for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
5951ab64890Smrg	    if (namesNeeded&bit) {
5961ab64890Smrg		*awire= (CARD32)devli->names[i];
5971ab64890Smrg		awire++;
5981ab64890Smrg	    }
5991ab64890Smrg	}
6001ab64890Smrg	wire= (char *)awire;
6011ab64890Smrg    }
6021ab64890Smrg    if (mapsNeeded) {
6031ab64890Smrg	xkbIndicatorMapWireDesc *mwire;
6041ab64890Smrg
6051ab64890Smrg	mwire= (xkbIndicatorMapWireDesc *)wire;
6061ab64890Smrg	for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
6071ab64890Smrg	    if (mapsNeeded&bit) {
6081ab64890Smrg		XkbIndicatorMapPtr	map;
6091ab64890Smrg		map= 			&devli->maps[i];
6101ab64890Smrg		mwire->flags= 		map->flags;
6111ab64890Smrg		mwire->whichGroups=	map->which_groups;
6121ab64890Smrg		mwire->groups=		map->groups;
6131ab64890Smrg		mwire->whichMods=	map->which_mods;
6141ab64890Smrg		mwire->mods=		map->mods.mask;
6151ab64890Smrg		mwire->realMods=	map->mods.real_mods;
6161ab64890Smrg		mwire->virtualMods=	map->mods.vmods;
6171ab64890Smrg		mwire->ctrls=		map->ctrls;
6181ab64890Smrg		mwire++;
6191ab64890Smrg	    }
6201ab64890Smrg	}
6211ab64890Smrg	wire= (char *)mwire;
6221ab64890Smrg    }
6231ab64890Smrg    return wire;
6241ab64890Smrg}
6251ab64890Smrg
6261ab64890Smrg
6271ab64890Smrgstatic int
6281ab64890Smrg_XkbWriteSetDeviceInfo(	char *			wire,
6291ab64890Smrg			XkbDeviceChangesPtr	changes,
6301ab64890Smrg			SetLedStuff *		stuff,
6311ab64890Smrg			XkbDeviceInfoPtr	devi)
6321ab64890Smrg{
6331ab64890Smrgchar *start;
6341ab64890Smrg
6351ab64890Smrg    start= wire;
6361ab64890Smrg    if (changes->changed&XkbXI_ButtonActionsMask) {
6371ab64890Smrg	int			size;
6381ab64890Smrg	size= changes->num_btns*SIZEOF(xkbActionWireDesc);
6391ab64890Smrg	memcpy(wire,(char *)&devi->btn_acts[changes->first_btn],size);
6401ab64890Smrg	wire+= size;
6411ab64890Smrg    }
6421ab64890Smrg    if (changes->changed&XkbXI_IndicatorsMask) {
6431ab64890Smrg	register int i;
6441ab64890Smrg	register LedInfoStuff *linfo;
6451ab64890Smrg
6461ab64890Smrg	for (i=0,linfo=&stuff->info[0];i<stuff->num_info;i++,linfo++) {
6471ab64890Smrg	    if (linfo->used) {
6481ab64890Smrg		register char *new_wire;
6491ab64890Smrg		new_wire= _XkbWriteLedInfo(wire,stuff->wanted,linfo->devli);
6501ab64890Smrg		if (!new_wire)
6511ab64890Smrg		    return wire-start;
6521ab64890Smrg		wire= new_wire;
6531ab64890Smrg	    }
6541ab64890Smrg	}
6551ab64890Smrg    }
6561ab64890Smrg    return wire-start;
6571ab64890Smrg}
6581ab64890Smrg
6591ab64890SmrgBool
6601ab64890SmrgXkbSetDeviceInfo(	Display *		dpy,
6611ab64890Smrg			unsigned 		which,
6621ab64890Smrg			XkbDeviceInfoPtr	devi)
6631ab64890Smrg{
6641ab64890Smrg    register xkbSetDeviceInfoReq *req;
6651ab64890Smrg    Status		     	ok = 0;
6661ab64890Smrg    int				size,nLeds;
6671ab64890Smrg    XkbInfoPtr 			xkbi;
6681ab64890Smrg    XkbDeviceChangesRec		changes;
6691ab64890Smrg    SetLedStuff			lstuff;
6701ab64890Smrg
6711ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
6721ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
6731ab64890Smrg	return False;
6741ab64890Smrg    if ((!devi) || (which&(~XkbXI_AllDeviceFeaturesMask)) ||
6751ab64890Smrg	((which&XkbXI_ButtonActionsMask)&&(!XkbXI_DevHasBtnActs(devi)))||
6761ab64890Smrg	((which&XkbXI_IndicatorsMask)&&(!XkbXI_DevHasLeds(devi))))
6771ab64890Smrg	return False;
6781ab64890Smrg
6791ab64890Smrg    bzero((char *)&changes,sizeof(XkbDeviceChangesRec));
6801ab64890Smrg    changes.changed= which;
6811ab64890Smrg    changes.first_btn=		0;
6821ab64890Smrg    changes.num_btns=		devi->num_btns;
6831ab64890Smrg    changes.leds.led_class=	XkbAllXIClasses;
6841ab64890Smrg    changes.leds.led_id=	XkbAllXIIds;
6851ab64890Smrg    changes.leds.defined=	0;
6861ab64890Smrg    size= nLeds= 		0;
6871ab64890Smrg    _InitLedStuff(&lstuff,changes.changed,devi);
6881ab64890Smrg    if (_XkbSetDeviceInfoSize(devi,&changes,&lstuff,&size,&nLeds)!=Success)
6891ab64890Smrg	return False;
6901ab64890Smrg    LockDisplay(dpy);
6911ab64890Smrg    xkbi = dpy->xkb_info;
6921ab64890Smrg    GetReq(kbSetDeviceInfo, req);
6931ab64890Smrg    req->length+=	size/4;
6941ab64890Smrg    req->reqType= 	xkbi->codes->major_opcode;
6951ab64890Smrg    req->xkbReqType= 	X_kbSetDeviceInfo;
6961ab64890Smrg    req->deviceSpec= 	devi->device_spec;
6971ab64890Smrg    req->firstBtn=	changes.first_btn;
6981ab64890Smrg    req->nBtns=		changes.num_btns;
6991ab64890Smrg    req->change=	changes.changed;
7001ab64890Smrg    req->nDeviceLedFBs=	nLeds;
7011ab64890Smrg    if (size>0) {
7021ab64890Smrg	char * 	wire;
7031ab64890Smrg	BufAlloc(char *,wire,size);
7041ab64890Smrg	ok= (wire!=NULL)&&
7051ab64890Smrg		(_XkbWriteSetDeviceInfo(wire,&changes,&lstuff,devi)==size);
7061ab64890Smrg    }
7071ab64890Smrg    UnlockDisplay(dpy);
7081ab64890Smrg    SyncHandle();
7091ab64890Smrg    _FreeLedStuff(&lstuff);
7101ab64890Smrg    /* 12/11/95 (ef) -- XXX!! should clear changes here */
7111ab64890Smrg    return ok;
7121ab64890Smrg}
7131ab64890Smrg
7141ab64890SmrgBool
7151ab64890SmrgXkbChangeDeviceInfo(	Display *		dpy,
7161ab64890Smrg			XkbDeviceInfoPtr	devi,
7171ab64890Smrg			XkbDeviceChangesPtr	changes)
7181ab64890Smrg{
7191ab64890Smrg    register xkbSetDeviceInfoReq *req;
7201ab64890Smrg    Status		     	ok = 0;
7211ab64890Smrg    int				size,nLeds;
7221ab64890Smrg    XkbInfoPtr 			xkbi;
7231ab64890Smrg    SetLedStuff			lstuff;
7241ab64890Smrg
7251ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
7261ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
7271ab64890Smrg	return False;
7281ab64890Smrg    if ((!devi) || (changes->changed&(~XkbXI_AllDeviceFeaturesMask)) ||
7291ab64890Smrg	((changes->changed&XkbXI_ButtonActionsMask)&&
7301ab64890Smrg					(!XkbXI_DevHasBtnActs(devi)))||
7311ab64890Smrg	((changes->changed&XkbXI_IndicatorsMask)&&(!XkbXI_DevHasLeds(devi))))
7321ab64890Smrg	return False;
7331ab64890Smrg
7341ab64890Smrg    size= nLeds= 0;
7351ab64890Smrg    _InitLedStuff(&lstuff,changes->changed,devi);
7361ab64890Smrg    if (_XkbSetDeviceInfoSize(devi,changes,&lstuff,&size,&nLeds)!=Success)
7371ab64890Smrg	return False;
7381ab64890Smrg    LockDisplay(dpy);
7391ab64890Smrg    xkbi = dpy->xkb_info;
7401ab64890Smrg    GetReq(kbSetDeviceInfo, req);
7411ab64890Smrg    req->length+=	size/4;
7421ab64890Smrg    req->reqType= 	xkbi->codes->major_opcode;
7431ab64890Smrg    req->xkbReqType= 	X_kbSetDeviceInfo;
7441ab64890Smrg    req->deviceSpec= 	devi->device_spec;
7451ab64890Smrg    req->firstBtn=	changes->first_btn;
7461ab64890Smrg    req->nBtns=		changes->num_btns;
7471ab64890Smrg    req->change=	changes->changed;
7481ab64890Smrg    req->nDeviceLedFBs=	nLeds;
7491ab64890Smrg    if (size>0) {
7501ab64890Smrg	char * 	wire;
7511ab64890Smrg	BufAlloc(char *,wire,size);
7521ab64890Smrg	ok= (wire!=NULL)&&
7531ab64890Smrg		(_XkbWriteSetDeviceInfo(wire,changes,&lstuff,devi)==size);
7541ab64890Smrg    }
7551ab64890Smrg    UnlockDisplay(dpy);
7561ab64890Smrg    SyncHandle();
7571ab64890Smrg    _FreeLedStuff(&lstuff);
7581ab64890Smrg    /* 12/11/95 (ef) -- XXX!! should clear changes here */
7591ab64890Smrg    return ok;
7601ab64890Smrg}
7611ab64890Smrg
76261b2299dSmrgBool
7631ab64890SmrgXkbSetDeviceLedInfo(	Display *		dpy,
7641ab64890Smrg			XkbDeviceInfoPtr	devi,
7651ab64890Smrg			unsigned 		ledClass,
7661ab64890Smrg			unsigned		ledID,
7671ab64890Smrg			unsigned		which)
7681ab64890Smrg{
7691ab64890Smrg    return False;
7701ab64890Smrg}
7711ab64890Smrg
77261b2299dSmrgBool
7731ab64890SmrgXkbSetDeviceButtonActions(	Display *		dpy,
7741ab64890Smrg				XkbDeviceInfoPtr 	devi,
7751ab64890Smrg				unsigned int		first,
7761ab64890Smrg				unsigned int		nBtns)
7771ab64890Smrg{
7781ab64890Smrg    register xkbSetDeviceInfoReq *req;
7791ab64890Smrg    Status		     	ok = 0;
7801ab64890Smrg    int				size,nLeds;
7811ab64890Smrg    XkbInfoPtr 			xkbi;
7821ab64890Smrg    XkbDeviceChangesRec		changes;
7831ab64890Smrg    SetLedStuff			lstuff;
7841ab64890Smrg
7851ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
7861ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
7871ab64890Smrg	return False;
7881ab64890Smrg    if ((!devi)||(!XkbXI_DevHasBtnActs(devi))||(first+nBtns>devi->num_btns))
7891ab64890Smrg	return False;
7901ab64890Smrg    if (nBtns==0)
7911ab64890Smrg	return True;
7921ab64890Smrg
7931ab64890Smrg    bzero((char *)&changes,sizeof(XkbDeviceChangesRec));
7941ab64890Smrg    changes.changed= 		XkbXI_ButtonActionsMask;
7951ab64890Smrg    changes.first_btn=		first;
7961ab64890Smrg    changes.num_btns=		nBtns;
7971ab64890Smrg    changes.leds.led_class=	XkbXINone;
7981ab64890Smrg    changes.leds.led_id=	XkbXINone;
7991ab64890Smrg    changes.leds.defined=	0;
8001ab64890Smrg    size= nLeds= 		0;
8011ab64890Smrg    if (_XkbSetDeviceInfoSize(devi,&changes,NULL,&size,&nLeds)!=Success)
8021ab64890Smrg	return False;
8031ab64890Smrg    LockDisplay(dpy);
8041ab64890Smrg    xkbi = dpy->xkb_info;
8051ab64890Smrg    GetReq(kbSetDeviceInfo, req);
8061ab64890Smrg    req->length+=	size/4;
8071ab64890Smrg    req->reqType= 	xkbi->codes->major_opcode;
8081ab64890Smrg    req->xkbReqType= 	X_kbSetDeviceInfo;
8091ab64890Smrg    req->deviceSpec= 	devi->device_spec;
8101ab64890Smrg    req->firstBtn=	changes.first_btn;
8111ab64890Smrg    req->nBtns=		changes.num_btns;
8121ab64890Smrg    req->change=	changes.changed;
8131ab64890Smrg    req->nDeviceLedFBs=	nLeds;
8141ab64890Smrg    if (size>0) {
8151ab64890Smrg	char * 	wire;
8161ab64890Smrg	BufAlloc(char *,wire,size);
8171ab64890Smrg	ok= (wire!=NULL)&&
8181ab64890Smrg		(_XkbWriteSetDeviceInfo(wire,&changes,&lstuff,devi)==size);
8191ab64890Smrg    }
8201ab64890Smrg    UnlockDisplay(dpy);
8211ab64890Smrg    SyncHandle();
8221ab64890Smrg    return ok;
8231ab64890Smrg}
824