1*4882a593Smuzhiyun /************************************************************
2*4882a593Smuzhiyun Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun Permission to use, copy, modify, and distribute this
5*4882a593Smuzhiyun software and its documentation for any purpose and without
6*4882a593Smuzhiyun fee is hereby granted, provided that the above copyright
7*4882a593Smuzhiyun notice appear in all copies and that both that copyright
8*4882a593Smuzhiyun notice and this permission notice appear in supporting
9*4882a593Smuzhiyun documentation, and that the name of Silicon Graphics not be
10*4882a593Smuzhiyun used in advertising or publicity pertaining to distribution
11*4882a593Smuzhiyun of the software without specific prior written permission.
12*4882a593Smuzhiyun Silicon Graphics makes no representation about the suitability
13*4882a593Smuzhiyun of this software for any purpose. It is provided "as is"
14*4882a593Smuzhiyun without any express or implied warranty.
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17*4882a593Smuzhiyun SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18*4882a593Smuzhiyun AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19*4882a593Smuzhiyun GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20*4882a593Smuzhiyun DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21*4882a593Smuzhiyun DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22*4882a593Smuzhiyun OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23*4882a593Smuzhiyun THE USE OR PERFORMANCE OF THIS SOFTWARE.
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun ********************************************************/
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
28*4882a593Smuzhiyun #include <dix-config.h>
29*4882a593Smuzhiyun #endif
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include <stdio.h>
32*4882a593Smuzhiyun #include <X11/X.h>
33*4882a593Smuzhiyun #include <X11/Xproto.h>
34*4882a593Smuzhiyun #include "misc.h"
35*4882a593Smuzhiyun #include "inputstr.h"
36*4882a593Smuzhiyun #define XKBSRV_NEED_FILE_FUNCS
37*4882a593Smuzhiyun #include <xkbsrv.h>
38*4882a593Smuzhiyun #include "extnsionst.h"
39*4882a593Smuzhiyun #include "extinit.h"
40*4882a593Smuzhiyun #include "xace.h"
41*4882a593Smuzhiyun #include "xkb.h"
42*4882a593Smuzhiyun #include "protocol-versions.h"
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #include <X11/extensions/XI.h>
45*4882a593Smuzhiyun #include <X11/extensions/XKMformat.h>
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun int XkbEventBase;
48*4882a593Smuzhiyun static int XkbErrorBase;
49*4882a593Smuzhiyun int XkbReqCode;
50*4882a593Smuzhiyun int XkbKeyboardErrorCode;
51*4882a593Smuzhiyun CARD32 xkbDebugFlags = 0;
52*4882a593Smuzhiyun static CARD32 xkbDebugCtrls = 0;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun static RESTYPE RT_XKBCLIENT;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun /***====================================================================***/
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun #define CHK_DEVICE(dev, id, client, access_mode, lf) {\
59*4882a593Smuzhiyun int why;\
60*4882a593Smuzhiyun int tmprc = lf(&(dev), id, client, access_mode, &why);\
61*4882a593Smuzhiyun if (tmprc != Success) {\
62*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(why, id);\
63*4882a593Smuzhiyun return tmprc;\
64*4882a593Smuzhiyun }\
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun #define CHK_KBD_DEVICE(dev, id, client, mode) \
68*4882a593Smuzhiyun CHK_DEVICE(dev, id, client, mode, _XkbLookupKeyboard)
69*4882a593Smuzhiyun #define CHK_LED_DEVICE(dev, id, client, mode) \
70*4882a593Smuzhiyun CHK_DEVICE(dev, id, client, mode, _XkbLookupLedDevice)
71*4882a593Smuzhiyun #define CHK_BELL_DEVICE(dev, id, client, mode) \
72*4882a593Smuzhiyun CHK_DEVICE(dev, id, client, mode, _XkbLookupBellDevice)
73*4882a593Smuzhiyun #define CHK_ANY_DEVICE(dev, id, client, mode) \
74*4882a593Smuzhiyun CHK_DEVICE(dev, id, client, mode, _XkbLookupAnyDevice)
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun #define CHK_ATOM_ONLY2(a,ev,er) {\
77*4882a593Smuzhiyun if (((a)==None)||(!ValidAtom((a)))) {\
78*4882a593Smuzhiyun (ev)= (XID)(a);\
79*4882a593Smuzhiyun return er;\
80*4882a593Smuzhiyun }\
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun #define CHK_ATOM_ONLY(a) \
83*4882a593Smuzhiyun CHK_ATOM_ONLY2(a,client->errorValue,BadAtom)
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun #define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\
86*4882a593Smuzhiyun if (((a)!=None)&&(!ValidAtom((a)))) {\
87*4882a593Smuzhiyun (ev)= (XID)(a);\
88*4882a593Smuzhiyun (er)= BadAtom;\
89*4882a593Smuzhiyun return ret;\
90*4882a593Smuzhiyun }\
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun #define CHK_ATOM_OR_NONE2(a,ev,er) {\
93*4882a593Smuzhiyun if (((a)!=None)&&(!ValidAtom((a)))) {\
94*4882a593Smuzhiyun (ev)= (XID)(a);\
95*4882a593Smuzhiyun return er;\
96*4882a593Smuzhiyun }\
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun #define CHK_ATOM_OR_NONE(a) \
99*4882a593Smuzhiyun CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom)
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun #define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\
102*4882a593Smuzhiyun if ((mask)&(~(legal))) { \
103*4882a593Smuzhiyun (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
104*4882a593Smuzhiyun (er)= BadValue;\
105*4882a593Smuzhiyun return ret;\
106*4882a593Smuzhiyun }\
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun #define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\
109*4882a593Smuzhiyun if ((mask)&(~(legal))) { \
110*4882a593Smuzhiyun (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
111*4882a593Smuzhiyun return er;\
112*4882a593Smuzhiyun }\
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun #define CHK_MASK_LEGAL(err,mask,legal) \
115*4882a593Smuzhiyun CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue)
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun #define CHK_MASK_MATCH(err,affect,value) {\
118*4882a593Smuzhiyun if ((value)&(~(affect))) { \
119*4882a593Smuzhiyun client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\
120*4882a593Smuzhiyun return BadMatch;\
121*4882a593Smuzhiyun }\
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun #define CHK_MASK_OVERLAP(err,m1,m2) {\
124*4882a593Smuzhiyun if ((m1)&(m2)) { \
125*4882a593Smuzhiyun client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\
126*4882a593Smuzhiyun return BadMatch;\
127*4882a593Smuzhiyun }\
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun #define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\
130*4882a593Smuzhiyun if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\
131*4882a593Smuzhiyun (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\
132*4882a593Smuzhiyun return er;\
133*4882a593Smuzhiyun }\
134*4882a593Smuzhiyun else if ( (first)<(x)->min_key_code ) {\
135*4882a593Smuzhiyun (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\
136*4882a593Smuzhiyun return er;\
137*4882a593Smuzhiyun }\
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun #define CHK_KEY_RANGE(err,first,num,x) \
140*4882a593Smuzhiyun CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue)
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun #define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\
143*4882a593Smuzhiyun if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\
144*4882a593Smuzhiyun (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\
145*4882a593Smuzhiyun return er;\
146*4882a593Smuzhiyun }\
147*4882a593Smuzhiyun else if ( (first)<(r)->minKeyCode ) {\
148*4882a593Smuzhiyun (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\
149*4882a593Smuzhiyun return er;\
150*4882a593Smuzhiyun }\
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun #define CHK_REQ_KEY_RANGE(err,first,num,r) \
153*4882a593Smuzhiyun CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue)
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun static Bool
_XkbCheckRequestBounds(ClientPtr client,void * stuff,void * from,void * to)156*4882a593Smuzhiyun _XkbCheckRequestBounds(ClientPtr client, void *stuff, void *from, void *to) {
157*4882a593Smuzhiyun char *cstuff = (char *)stuff;
158*4882a593Smuzhiyun char *cfrom = (char *)from;
159*4882a593Smuzhiyun char *cto = (char *)to;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun return cfrom < cto &&
162*4882a593Smuzhiyun cfrom >= cstuff &&
163*4882a593Smuzhiyun cfrom < cstuff + ((size_t)client->req_len << 2) &&
164*4882a593Smuzhiyun cto >= cstuff &&
165*4882a593Smuzhiyun cto <= cstuff + ((size_t)client->req_len << 2);
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun /***====================================================================***/
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun int
ProcXkbUseExtension(ClientPtr client)171*4882a593Smuzhiyun ProcXkbUseExtension(ClientPtr client)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun REQUEST(xkbUseExtensionReq);
174*4882a593Smuzhiyun xkbUseExtensionReply rep;
175*4882a593Smuzhiyun int supported;
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbUseExtensionReq);
178*4882a593Smuzhiyun if (stuff->wantedMajor != SERVER_XKB_MAJOR_VERSION) {
179*4882a593Smuzhiyun /* pre-release version 0.65 is compatible with 1.00 */
180*4882a593Smuzhiyun supported = ((SERVER_XKB_MAJOR_VERSION == 1) &&
181*4882a593Smuzhiyun (stuff->wantedMajor == 0) && (stuff->wantedMinor == 65));
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun else
184*4882a593Smuzhiyun supported = 1;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun if ((supported) && (!(client->xkbClientFlags & _XkbClientInitialized))) {
187*4882a593Smuzhiyun client->xkbClientFlags = _XkbClientInitialized;
188*4882a593Smuzhiyun if (stuff->wantedMajor == 0)
189*4882a593Smuzhiyun client->xkbClientFlags |= _XkbClientIsAncient;
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun else if (xkbDebugFlags & 0x1) {
192*4882a593Smuzhiyun ErrorF
193*4882a593Smuzhiyun ("[xkb] Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n",
194*4882a593Smuzhiyun client->index, (long) client->clientAsMask, stuff->wantedMajor,
195*4882a593Smuzhiyun stuff->wantedMinor, SERVER_XKB_MAJOR_VERSION,
196*4882a593Smuzhiyun SERVER_XKB_MINOR_VERSION);
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun rep = (xkbUseExtensionReply) {
199*4882a593Smuzhiyun .type = X_Reply,
200*4882a593Smuzhiyun .supported = supported,
201*4882a593Smuzhiyun .sequenceNumber = client->sequence,
202*4882a593Smuzhiyun .length = 0,
203*4882a593Smuzhiyun .serverMajor = SERVER_XKB_MAJOR_VERSION,
204*4882a593Smuzhiyun .serverMinor = SERVER_XKB_MINOR_VERSION
205*4882a593Smuzhiyun };
206*4882a593Smuzhiyun if (client->swapped) {
207*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
208*4882a593Smuzhiyun swaps(&rep.serverMajor);
209*4882a593Smuzhiyun swaps(&rep.serverMinor);
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbUseExtensionReply), &rep);
212*4882a593Smuzhiyun return Success;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun /***====================================================================***/
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun int
ProcXkbSelectEvents(ClientPtr client)218*4882a593Smuzhiyun ProcXkbSelectEvents(ClientPtr client)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun unsigned legal;
221*4882a593Smuzhiyun DeviceIntPtr dev;
222*4882a593Smuzhiyun XkbInterestPtr masks;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun REQUEST(xkbSelectEventsReq);
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
229*4882a593Smuzhiyun return BadAccess;
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixUseAccess);
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun if (((stuff->affectWhich & XkbMapNotifyMask) != 0) && (stuff->affectMap)) {
234*4882a593Smuzhiyun client->mapNotifyMask &= ~stuff->affectMap;
235*4882a593Smuzhiyun client->mapNotifyMask |= (stuff->affectMap & stuff->map);
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun if ((stuff->affectWhich & (~XkbMapNotifyMask)) == 0)
238*4882a593Smuzhiyun return Success;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun masks = XkbFindClientResource((DevicePtr) dev, client);
241*4882a593Smuzhiyun if (!masks) {
242*4882a593Smuzhiyun XID id = FakeClientID(client->index);
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun if (!AddResource(id, RT_XKBCLIENT, dev))
245*4882a593Smuzhiyun return BadAlloc;
246*4882a593Smuzhiyun masks = XkbAddClientResource((DevicePtr) dev, client, id);
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun if (masks) {
249*4882a593Smuzhiyun union {
250*4882a593Smuzhiyun CARD8 *c8;
251*4882a593Smuzhiyun CARD16 *c16;
252*4882a593Smuzhiyun CARD32 *c32;
253*4882a593Smuzhiyun } from, to;
254*4882a593Smuzhiyun register unsigned bit, ndx, maskLeft, dataLeft, size;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun from.c8 = (CARD8 *) &stuff[1];
257*4882a593Smuzhiyun dataLeft = (stuff->length * 4) - SIZEOF(xkbSelectEventsReq);
258*4882a593Smuzhiyun maskLeft = (stuff->affectWhich & (~XkbMapNotifyMask));
259*4882a593Smuzhiyun for (ndx = 0, bit = 1; (maskLeft != 0); ndx++, bit <<= 1) {
260*4882a593Smuzhiyun if ((bit & maskLeft) == 0)
261*4882a593Smuzhiyun continue;
262*4882a593Smuzhiyun maskLeft &= ~bit;
263*4882a593Smuzhiyun switch (ndx) {
264*4882a593Smuzhiyun case XkbNewKeyboardNotify:
265*4882a593Smuzhiyun to.c16 = &client->newKeyboardNotifyMask;
266*4882a593Smuzhiyun legal = XkbAllNewKeyboardEventsMask;
267*4882a593Smuzhiyun size = 2;
268*4882a593Smuzhiyun break;
269*4882a593Smuzhiyun case XkbStateNotify:
270*4882a593Smuzhiyun to.c16 = &masks->stateNotifyMask;
271*4882a593Smuzhiyun legal = XkbAllStateEventsMask;
272*4882a593Smuzhiyun size = 2;
273*4882a593Smuzhiyun break;
274*4882a593Smuzhiyun case XkbControlsNotify:
275*4882a593Smuzhiyun to.c32 = &masks->ctrlsNotifyMask;
276*4882a593Smuzhiyun legal = XkbAllControlEventsMask;
277*4882a593Smuzhiyun size = 4;
278*4882a593Smuzhiyun break;
279*4882a593Smuzhiyun case XkbIndicatorStateNotify:
280*4882a593Smuzhiyun to.c32 = &masks->iStateNotifyMask;
281*4882a593Smuzhiyun legal = XkbAllIndicatorEventsMask;
282*4882a593Smuzhiyun size = 4;
283*4882a593Smuzhiyun break;
284*4882a593Smuzhiyun case XkbIndicatorMapNotify:
285*4882a593Smuzhiyun to.c32 = &masks->iMapNotifyMask;
286*4882a593Smuzhiyun legal = XkbAllIndicatorEventsMask;
287*4882a593Smuzhiyun size = 4;
288*4882a593Smuzhiyun break;
289*4882a593Smuzhiyun case XkbNamesNotify:
290*4882a593Smuzhiyun to.c16 = &masks->namesNotifyMask;
291*4882a593Smuzhiyun legal = XkbAllNameEventsMask;
292*4882a593Smuzhiyun size = 2;
293*4882a593Smuzhiyun break;
294*4882a593Smuzhiyun case XkbCompatMapNotify:
295*4882a593Smuzhiyun to.c8 = &masks->compatNotifyMask;
296*4882a593Smuzhiyun legal = XkbAllCompatMapEventsMask;
297*4882a593Smuzhiyun size = 1;
298*4882a593Smuzhiyun break;
299*4882a593Smuzhiyun case XkbBellNotify:
300*4882a593Smuzhiyun to.c8 = &masks->bellNotifyMask;
301*4882a593Smuzhiyun legal = XkbAllBellEventsMask;
302*4882a593Smuzhiyun size = 1;
303*4882a593Smuzhiyun break;
304*4882a593Smuzhiyun case XkbActionMessage:
305*4882a593Smuzhiyun to.c8 = &masks->actionMessageMask;
306*4882a593Smuzhiyun legal = XkbAllActionMessagesMask;
307*4882a593Smuzhiyun size = 1;
308*4882a593Smuzhiyun break;
309*4882a593Smuzhiyun case XkbAccessXNotify:
310*4882a593Smuzhiyun to.c16 = &masks->accessXNotifyMask;
311*4882a593Smuzhiyun legal = XkbAllAccessXEventsMask;
312*4882a593Smuzhiyun size = 2;
313*4882a593Smuzhiyun break;
314*4882a593Smuzhiyun case XkbExtensionDeviceNotify:
315*4882a593Smuzhiyun to.c16 = &masks->extDevNotifyMask;
316*4882a593Smuzhiyun legal = XkbAllExtensionDeviceEventsMask;
317*4882a593Smuzhiyun size = 2;
318*4882a593Smuzhiyun break;
319*4882a593Smuzhiyun default:
320*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(33, bit);
321*4882a593Smuzhiyun return BadValue;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun if (stuff->clear & bit) {
325*4882a593Smuzhiyun if (size == 2)
326*4882a593Smuzhiyun to.c16[0] = 0;
327*4882a593Smuzhiyun else if (size == 4)
328*4882a593Smuzhiyun to.c32[0] = 0;
329*4882a593Smuzhiyun else
330*4882a593Smuzhiyun to.c8[0] = 0;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun else if (stuff->selectAll & bit) {
333*4882a593Smuzhiyun if (size == 2)
334*4882a593Smuzhiyun to.c16[0] = ~0;
335*4882a593Smuzhiyun else if (size == 4)
336*4882a593Smuzhiyun to.c32[0] = ~0;
337*4882a593Smuzhiyun else
338*4882a593Smuzhiyun to.c8[0] = ~0;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun else {
341*4882a593Smuzhiyun if (dataLeft < (size * 2))
342*4882a593Smuzhiyun return BadLength;
343*4882a593Smuzhiyun if (size == 2) {
344*4882a593Smuzhiyun CHK_MASK_MATCH(ndx, from.c16[0], from.c16[1]);
345*4882a593Smuzhiyun CHK_MASK_LEGAL(ndx, from.c16[0], legal);
346*4882a593Smuzhiyun to.c16[0] &= ~from.c16[0];
347*4882a593Smuzhiyun to.c16[0] |= (from.c16[0] & from.c16[1]);
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun else if (size == 4) {
350*4882a593Smuzhiyun CHK_MASK_MATCH(ndx, from.c32[0], from.c32[1]);
351*4882a593Smuzhiyun CHK_MASK_LEGAL(ndx, from.c32[0], legal);
352*4882a593Smuzhiyun to.c32[0] &= ~from.c32[0];
353*4882a593Smuzhiyun to.c32[0] |= (from.c32[0] & from.c32[1]);
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun else {
356*4882a593Smuzhiyun CHK_MASK_MATCH(ndx, from.c8[0], from.c8[1]);
357*4882a593Smuzhiyun CHK_MASK_LEGAL(ndx, from.c8[0], legal);
358*4882a593Smuzhiyun to.c8[0] &= ~from.c8[0];
359*4882a593Smuzhiyun to.c8[0] |= (from.c8[0] & from.c8[1]);
360*4882a593Smuzhiyun size = 2;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun from.c8 += (size * 2);
363*4882a593Smuzhiyun dataLeft -= (size * 2);
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun if (dataLeft > 2) {
367*4882a593Smuzhiyun ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",
368*4882a593Smuzhiyun dataLeft);
369*4882a593Smuzhiyun return BadLength;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun return Success;
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun return BadAlloc;
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun /***====================================================================***/
377*4882a593Smuzhiyun /**
378*4882a593Smuzhiyun * Ring a bell on the given device for the given client.
379*4882a593Smuzhiyun */
380*4882a593Smuzhiyun static int
_XkbBell(ClientPtr client,DeviceIntPtr dev,WindowPtr pWin,int bellClass,int bellID,int pitch,int duration,int percent,int forceSound,int eventOnly,Atom name)381*4882a593Smuzhiyun _XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin,
382*4882a593Smuzhiyun int bellClass, int bellID, int pitch, int duration,
383*4882a593Smuzhiyun int percent, int forceSound, int eventOnly, Atom name)
384*4882a593Smuzhiyun {
385*4882a593Smuzhiyun int base;
386*4882a593Smuzhiyun void *ctrl;
387*4882a593Smuzhiyun int oldPitch, oldDuration;
388*4882a593Smuzhiyun int newPercent;
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun if (bellClass == KbdFeedbackClass) {
391*4882a593Smuzhiyun KbdFeedbackPtr k;
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun if (bellID == XkbDfltXIId)
394*4882a593Smuzhiyun k = dev->kbdfeed;
395*4882a593Smuzhiyun else {
396*4882a593Smuzhiyun for (k = dev->kbdfeed; k; k = k->next) {
397*4882a593Smuzhiyun if (k->ctrl.id == bellID)
398*4882a593Smuzhiyun break;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun if (!k) {
402*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x5, bellID);
403*4882a593Smuzhiyun return BadValue;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun base = k->ctrl.bell;
406*4882a593Smuzhiyun ctrl = (void *) &(k->ctrl);
407*4882a593Smuzhiyun oldPitch = k->ctrl.bell_pitch;
408*4882a593Smuzhiyun oldDuration = k->ctrl.bell_duration;
409*4882a593Smuzhiyun if (pitch != 0) {
410*4882a593Smuzhiyun if (pitch == -1)
411*4882a593Smuzhiyun k->ctrl.bell_pitch = defaultKeyboardControl.bell_pitch;
412*4882a593Smuzhiyun else
413*4882a593Smuzhiyun k->ctrl.bell_pitch = pitch;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun if (duration != 0) {
416*4882a593Smuzhiyun if (duration == -1)
417*4882a593Smuzhiyun k->ctrl.bell_duration = defaultKeyboardControl.bell_duration;
418*4882a593Smuzhiyun else
419*4882a593Smuzhiyun k->ctrl.bell_duration = duration;
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun else if (bellClass == BellFeedbackClass) {
423*4882a593Smuzhiyun BellFeedbackPtr b;
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun if (bellID == XkbDfltXIId)
426*4882a593Smuzhiyun b = dev->bell;
427*4882a593Smuzhiyun else {
428*4882a593Smuzhiyun for (b = dev->bell; b; b = b->next) {
429*4882a593Smuzhiyun if (b->ctrl.id == bellID)
430*4882a593Smuzhiyun break;
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun if (!b) {
434*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x6, bellID);
435*4882a593Smuzhiyun return BadValue;
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun base = b->ctrl.percent;
438*4882a593Smuzhiyun ctrl = (void *) &(b->ctrl);
439*4882a593Smuzhiyun oldPitch = b->ctrl.pitch;
440*4882a593Smuzhiyun oldDuration = b->ctrl.duration;
441*4882a593Smuzhiyun if (pitch != 0) {
442*4882a593Smuzhiyun if (pitch == -1)
443*4882a593Smuzhiyun b->ctrl.pitch = defaultKeyboardControl.bell_pitch;
444*4882a593Smuzhiyun else
445*4882a593Smuzhiyun b->ctrl.pitch = pitch;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun if (duration != 0) {
448*4882a593Smuzhiyun if (duration == -1)
449*4882a593Smuzhiyun b->ctrl.duration = defaultKeyboardControl.bell_duration;
450*4882a593Smuzhiyun else
451*4882a593Smuzhiyun b->ctrl.duration = duration;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun else {
455*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x7, bellClass);
456*4882a593Smuzhiyun return BadValue;
457*4882a593Smuzhiyun }
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun newPercent = (base * percent) / 100;
460*4882a593Smuzhiyun if (percent < 0)
461*4882a593Smuzhiyun newPercent = base + newPercent;
462*4882a593Smuzhiyun else
463*4882a593Smuzhiyun newPercent = base - newPercent + percent;
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun XkbHandleBell(forceSound, eventOnly,
466*4882a593Smuzhiyun dev, newPercent, ctrl, bellClass, name, pWin, client);
467*4882a593Smuzhiyun if ((pitch != 0) || (duration != 0)) {
468*4882a593Smuzhiyun if (bellClass == KbdFeedbackClass) {
469*4882a593Smuzhiyun KbdFeedbackPtr k;
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun k = (KbdFeedbackPtr) ctrl;
472*4882a593Smuzhiyun if (pitch != 0)
473*4882a593Smuzhiyun k->ctrl.bell_pitch = oldPitch;
474*4882a593Smuzhiyun if (duration != 0)
475*4882a593Smuzhiyun k->ctrl.bell_duration = oldDuration;
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun else {
478*4882a593Smuzhiyun BellFeedbackPtr b;
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun b = (BellFeedbackPtr) ctrl;
481*4882a593Smuzhiyun if (pitch != 0)
482*4882a593Smuzhiyun b->ctrl.pitch = oldPitch;
483*4882a593Smuzhiyun if (duration != 0)
484*4882a593Smuzhiyun b->ctrl.duration = oldDuration;
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun return Success;
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun int
ProcXkbBell(ClientPtr client)492*4882a593Smuzhiyun ProcXkbBell(ClientPtr client)
493*4882a593Smuzhiyun {
494*4882a593Smuzhiyun REQUEST(xkbBellReq);
495*4882a593Smuzhiyun DeviceIntPtr dev;
496*4882a593Smuzhiyun WindowPtr pWin;
497*4882a593Smuzhiyun int rc;
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbBellReq);
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
502*4882a593Smuzhiyun return BadAccess;
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess);
505*4882a593Smuzhiyun CHK_ATOM_OR_NONE(stuff->name);
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun /* device-independent checks request for sane values */
508*4882a593Smuzhiyun if ((stuff->forceSound) && (stuff->eventOnly)) {
509*4882a593Smuzhiyun client->errorValue =
510*4882a593Smuzhiyun _XkbErrCode3(0x1, stuff->forceSound, stuff->eventOnly);
511*4882a593Smuzhiyun return BadMatch;
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun if (stuff->percent < -100 || stuff->percent > 100) {
514*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x2, stuff->percent);
515*4882a593Smuzhiyun return BadValue;
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun if (stuff->duration < -1) {
518*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x3, stuff->duration);
519*4882a593Smuzhiyun return BadValue;
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun if (stuff->pitch < -1) {
522*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x4, stuff->pitch);
523*4882a593Smuzhiyun return BadValue;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun if (stuff->bellClass == XkbDfltXIClass) {
527*4882a593Smuzhiyun if (dev->kbdfeed != NULL)
528*4882a593Smuzhiyun stuff->bellClass = KbdFeedbackClass;
529*4882a593Smuzhiyun else
530*4882a593Smuzhiyun stuff->bellClass = BellFeedbackClass;
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun if (stuff->window != None) {
534*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
535*4882a593Smuzhiyun if (rc != Success) {
536*4882a593Smuzhiyun client->errorValue = stuff->window;
537*4882a593Smuzhiyun return rc;
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun else
541*4882a593Smuzhiyun pWin = NULL;
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun /* Client wants to ring a bell on the core keyboard?
544*4882a593Smuzhiyun Ring the bell on the core keyboard (which does nothing, but if that
545*4882a593Smuzhiyun fails the client is screwed anyway), and then on all extension devices.
546*4882a593Smuzhiyun Fail if the core keyboard fails but not the extension devices. this
547*4882a593Smuzhiyun may cause some keyboards to ding and others to stay silent. Fix
548*4882a593Smuzhiyun your client to use explicit keyboards to avoid this.
549*4882a593Smuzhiyun
550*4882a593Smuzhiyun dev is the device the client requested.
551*4882a593Smuzhiyun */
552*4882a593Smuzhiyun rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID,
553*4882a593Smuzhiyun stuff->pitch, stuff->duration, stuff->percent,
554*4882a593Smuzhiyun stuff->forceSound, stuff->eventOnly, stuff->name);
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) ||
557*4882a593Smuzhiyun (stuff->deviceSpec == XkbUseCorePtr))) {
558*4882a593Smuzhiyun DeviceIntPtr other;
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
561*4882a593Smuzhiyun if ((other != dev) && other->key && !IsMaster(other) &&
562*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) {
563*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess);
564*4882a593Smuzhiyun if (rc == Success)
565*4882a593Smuzhiyun _XkbBell(client, other, pWin, stuff->bellClass,
566*4882a593Smuzhiyun stuff->bellID, stuff->pitch, stuff->duration,
567*4882a593Smuzhiyun stuff->percent, stuff->forceSound,
568*4882a593Smuzhiyun stuff->eventOnly, stuff->name);
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun }
571*4882a593Smuzhiyun rc = Success; /* reset to success, that's what we got for the VCK */
572*4882a593Smuzhiyun }
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun return rc;
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun /***====================================================================***/
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun int
ProcXkbGetState(ClientPtr client)580*4882a593Smuzhiyun ProcXkbGetState(ClientPtr client)
581*4882a593Smuzhiyun {
582*4882a593Smuzhiyun REQUEST(xkbGetStateReq);
583*4882a593Smuzhiyun DeviceIntPtr dev;
584*4882a593Smuzhiyun xkbGetStateReply rep;
585*4882a593Smuzhiyun XkbStateRec *xkb;
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbGetStateReq);
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
590*4882a593Smuzhiyun return BadAccess;
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun xkb = &dev->key->xkbInfo->state;
595*4882a593Smuzhiyun rep = (xkbGetStateReply) {
596*4882a593Smuzhiyun .type = X_Reply,
597*4882a593Smuzhiyun .deviceID = dev->id,
598*4882a593Smuzhiyun .sequenceNumber = client->sequence,
599*4882a593Smuzhiyun .length = 0,
600*4882a593Smuzhiyun .mods = XkbStateFieldFromRec(xkb) & 0xff,
601*4882a593Smuzhiyun .baseMods = xkb->base_mods,
602*4882a593Smuzhiyun .latchedMods = xkb->latched_mods,
603*4882a593Smuzhiyun .lockedMods = xkb->locked_mods,
604*4882a593Smuzhiyun .group = xkb->group,
605*4882a593Smuzhiyun .lockedGroup = xkb->locked_group,
606*4882a593Smuzhiyun .baseGroup = xkb->base_group,
607*4882a593Smuzhiyun .latchedGroup = xkb->latched_group,
608*4882a593Smuzhiyun .compatState = xkb->compat_state,
609*4882a593Smuzhiyun .ptrBtnState = xkb->ptr_buttons
610*4882a593Smuzhiyun };
611*4882a593Smuzhiyun if (client->swapped) {
612*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
613*4882a593Smuzhiyun swaps(&rep.ptrBtnState);
614*4882a593Smuzhiyun }
615*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbGetStateReply), &rep);
616*4882a593Smuzhiyun return Success;
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun /***====================================================================***/
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun int
ProcXkbLatchLockState(ClientPtr client)622*4882a593Smuzhiyun ProcXkbLatchLockState(ClientPtr client)
623*4882a593Smuzhiyun {
624*4882a593Smuzhiyun int status;
625*4882a593Smuzhiyun DeviceIntPtr dev, tmpd;
626*4882a593Smuzhiyun XkbStateRec oldState, *newState;
627*4882a593Smuzhiyun CARD16 changed;
628*4882a593Smuzhiyun xkbStateNotify sn;
629*4882a593Smuzhiyun XkbEventCauseRec cause;
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun REQUEST(xkbLatchLockStateReq);
632*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
635*4882a593Smuzhiyun return BadAccess;
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
638*4882a593Smuzhiyun CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks);
639*4882a593Smuzhiyun CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches);
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun status = Success;
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
644*4882a593Smuzhiyun if ((tmpd == dev) ||
645*4882a593Smuzhiyun (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) {
646*4882a593Smuzhiyun if (!tmpd->key || !tmpd->key->xkbInfo)
647*4882a593Smuzhiyun continue;
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun oldState = tmpd->key->xkbInfo->state;
650*4882a593Smuzhiyun newState = &tmpd->key->xkbInfo->state;
651*4882a593Smuzhiyun if (stuff->affectModLocks) {
652*4882a593Smuzhiyun newState->locked_mods &= ~stuff->affectModLocks;
653*4882a593Smuzhiyun newState->locked_mods |=
654*4882a593Smuzhiyun (stuff->affectModLocks & stuff->modLocks);
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun if (status == Success && stuff->lockGroup)
657*4882a593Smuzhiyun newState->locked_group = stuff->groupLock;
658*4882a593Smuzhiyun if (status == Success && stuff->affectModLatches)
659*4882a593Smuzhiyun status = XkbLatchModifiers(tmpd, stuff->affectModLatches,
660*4882a593Smuzhiyun stuff->modLatches);
661*4882a593Smuzhiyun if (status == Success && stuff->latchGroup)
662*4882a593Smuzhiyun status = XkbLatchGroup(tmpd, stuff->groupLatch);
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun if (status != Success)
665*4882a593Smuzhiyun return status;
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun XkbComputeDerivedState(tmpd->key->xkbInfo);
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun changed = XkbStateChangedFlags(&oldState, newState);
670*4882a593Smuzhiyun if (changed) {
671*4882a593Smuzhiyun sn.keycode = 0;
672*4882a593Smuzhiyun sn.eventType = 0;
673*4882a593Smuzhiyun sn.requestMajor = XkbReqCode;
674*4882a593Smuzhiyun sn.requestMinor = X_kbLatchLockState;
675*4882a593Smuzhiyun sn.changed = changed;
676*4882a593Smuzhiyun XkbSendStateNotify(tmpd, &sn);
677*4882a593Smuzhiyun changed = XkbIndicatorsToUpdate(tmpd, changed, FALSE);
678*4882a593Smuzhiyun if (changed) {
679*4882a593Smuzhiyun XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client);
680*4882a593Smuzhiyun XkbUpdateIndicators(tmpd, changed, TRUE, NULL, &cause);
681*4882a593Smuzhiyun }
682*4882a593Smuzhiyun }
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun return Success;
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun /***====================================================================***/
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun int
ProcXkbGetControls(ClientPtr client)692*4882a593Smuzhiyun ProcXkbGetControls(ClientPtr client)
693*4882a593Smuzhiyun {
694*4882a593Smuzhiyun xkbGetControlsReply rep;
695*4882a593Smuzhiyun XkbControlsPtr xkb;
696*4882a593Smuzhiyun DeviceIntPtr dev;
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun REQUEST(xkbGetControlsReq);
699*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbGetControlsReq);
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
702*4882a593Smuzhiyun return BadAccess;
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun xkb = dev->key->xkbInfo->desc->ctrls;
707*4882a593Smuzhiyun rep = (xkbGetControlsReply) {
708*4882a593Smuzhiyun .type = X_Reply,
709*4882a593Smuzhiyun .deviceID = ((DeviceIntPtr) dev)->id,
710*4882a593Smuzhiyun .sequenceNumber = client->sequence,
711*4882a593Smuzhiyun .length = bytes_to_int32(SIZEOF(xkbGetControlsReply) -
712*4882a593Smuzhiyun SIZEOF(xGenericReply)),
713*4882a593Smuzhiyun .mkDfltBtn = xkb->mk_dflt_btn,
714*4882a593Smuzhiyun .numGroups = xkb->num_groups,
715*4882a593Smuzhiyun .groupsWrap = xkb->groups_wrap,
716*4882a593Smuzhiyun .internalMods = xkb->internal.mask,
717*4882a593Smuzhiyun .ignoreLockMods = xkb->ignore_lock.mask,
718*4882a593Smuzhiyun .internalRealMods = xkb->internal.real_mods,
719*4882a593Smuzhiyun .ignoreLockRealMods = xkb->ignore_lock.real_mods,
720*4882a593Smuzhiyun .internalVMods = xkb->internal.vmods,
721*4882a593Smuzhiyun .ignoreLockVMods = xkb->ignore_lock.vmods,
722*4882a593Smuzhiyun .repeatDelay = xkb->repeat_delay,
723*4882a593Smuzhiyun .repeatInterval = xkb->repeat_interval,
724*4882a593Smuzhiyun .slowKeysDelay = xkb->slow_keys_delay,
725*4882a593Smuzhiyun .debounceDelay = xkb->debounce_delay,
726*4882a593Smuzhiyun .mkDelay = xkb->mk_delay,
727*4882a593Smuzhiyun .mkInterval = xkb->mk_interval,
728*4882a593Smuzhiyun .mkTimeToMax = xkb->mk_time_to_max,
729*4882a593Smuzhiyun .mkMaxSpeed = xkb->mk_max_speed,
730*4882a593Smuzhiyun .mkCurve = xkb->mk_curve,
731*4882a593Smuzhiyun .axOptions = xkb->ax_options,
732*4882a593Smuzhiyun .axTimeout = xkb->ax_timeout,
733*4882a593Smuzhiyun .axtOptsMask = xkb->axt_opts_mask,
734*4882a593Smuzhiyun .axtOptsValues = xkb->axt_opts_values,
735*4882a593Smuzhiyun .axtCtrlsMask = xkb->axt_ctrls_mask,
736*4882a593Smuzhiyun .axtCtrlsValues = xkb->axt_ctrls_values,
737*4882a593Smuzhiyun .enabledCtrls = xkb->enabled_ctrls,
738*4882a593Smuzhiyun };
739*4882a593Smuzhiyun memcpy(rep.perKeyRepeat, xkb->per_key_repeat, XkbPerKeyBitArraySize);
740*4882a593Smuzhiyun if (client->swapped) {
741*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
742*4882a593Smuzhiyun swapl(&rep.length);
743*4882a593Smuzhiyun swaps(&rep.internalVMods);
744*4882a593Smuzhiyun swaps(&rep.ignoreLockVMods);
745*4882a593Smuzhiyun swapl(&rep.enabledCtrls);
746*4882a593Smuzhiyun swaps(&rep.repeatDelay);
747*4882a593Smuzhiyun swaps(&rep.repeatInterval);
748*4882a593Smuzhiyun swaps(&rep.slowKeysDelay);
749*4882a593Smuzhiyun swaps(&rep.debounceDelay);
750*4882a593Smuzhiyun swaps(&rep.mkDelay);
751*4882a593Smuzhiyun swaps(&rep.mkInterval);
752*4882a593Smuzhiyun swaps(&rep.mkTimeToMax);
753*4882a593Smuzhiyun swaps(&rep.mkMaxSpeed);
754*4882a593Smuzhiyun swaps(&rep.mkCurve);
755*4882a593Smuzhiyun swaps(&rep.axTimeout);
756*4882a593Smuzhiyun swapl(&rep.axtCtrlsMask);
757*4882a593Smuzhiyun swapl(&rep.axtCtrlsValues);
758*4882a593Smuzhiyun swaps(&rep.axtOptsMask);
759*4882a593Smuzhiyun swaps(&rep.axtOptsValues);
760*4882a593Smuzhiyun swaps(&rep.axOptions);
761*4882a593Smuzhiyun }
762*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbGetControlsReply), &rep);
763*4882a593Smuzhiyun return Success;
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun int
ProcXkbSetControls(ClientPtr client)767*4882a593Smuzhiyun ProcXkbSetControls(ClientPtr client)
768*4882a593Smuzhiyun {
769*4882a593Smuzhiyun DeviceIntPtr dev, tmpd;
770*4882a593Smuzhiyun XkbSrvInfoPtr xkbi;
771*4882a593Smuzhiyun XkbControlsPtr ctrl;
772*4882a593Smuzhiyun XkbControlsRec new, old;
773*4882a593Smuzhiyun xkbControlsNotify cn;
774*4882a593Smuzhiyun XkbEventCauseRec cause;
775*4882a593Smuzhiyun XkbSrvLedInfoPtr sli;
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun REQUEST(xkbSetControlsReq);
778*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbSetControlsReq);
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
781*4882a593Smuzhiyun return BadAccess;
782*4882a593Smuzhiyun
783*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
784*4882a593Smuzhiyun CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask);
785*4882a593Smuzhiyun
786*4882a593Smuzhiyun for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
787*4882a593Smuzhiyun if (!tmpd->key || !tmpd->key->xkbInfo)
788*4882a593Smuzhiyun continue;
789*4882a593Smuzhiyun if ((tmpd == dev) ||
790*4882a593Smuzhiyun (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) {
791*4882a593Smuzhiyun xkbi = tmpd->key->xkbInfo;
792*4882a593Smuzhiyun ctrl = xkbi->desc->ctrls;
793*4882a593Smuzhiyun new = *ctrl;
794*4882a593Smuzhiyun XkbSetCauseXkbReq(&cause, X_kbSetControls, client);
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun if (stuff->changeCtrls & XkbInternalModsMask) {
797*4882a593Smuzhiyun CHK_MASK_MATCH(0x02, stuff->affectInternalMods,
798*4882a593Smuzhiyun stuff->internalMods);
799*4882a593Smuzhiyun CHK_MASK_MATCH(0x03, stuff->affectInternalVMods,
800*4882a593Smuzhiyun stuff->internalVMods);
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun new.internal.real_mods &= ~(stuff->affectInternalMods);
803*4882a593Smuzhiyun new.internal.real_mods |= (stuff->affectInternalMods &
804*4882a593Smuzhiyun stuff->internalMods);
805*4882a593Smuzhiyun new.internal.vmods &= ~(stuff->affectInternalVMods);
806*4882a593Smuzhiyun new.internal.vmods |= (stuff->affectInternalVMods &
807*4882a593Smuzhiyun stuff->internalVMods);
808*4882a593Smuzhiyun new.internal.mask = new.internal.real_mods |
809*4882a593Smuzhiyun XkbMaskForVMask(xkbi->desc, new.internal.vmods);
810*4882a593Smuzhiyun }
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun if (stuff->changeCtrls & XkbIgnoreLockModsMask) {
813*4882a593Smuzhiyun CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods,
814*4882a593Smuzhiyun stuff->ignoreLockMods);
815*4882a593Smuzhiyun CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods,
816*4882a593Smuzhiyun stuff->ignoreLockVMods);
817*4882a593Smuzhiyun
818*4882a593Smuzhiyun new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods);
819*4882a593Smuzhiyun new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods &
820*4882a593Smuzhiyun stuff->ignoreLockMods);
821*4882a593Smuzhiyun new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods);
822*4882a593Smuzhiyun new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods &
823*4882a593Smuzhiyun stuff->ignoreLockVMods);
824*4882a593Smuzhiyun new.ignore_lock.mask = new.ignore_lock.real_mods |
825*4882a593Smuzhiyun XkbMaskForVMask(xkbi->desc, new.ignore_lock.vmods);
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun
828*4882a593Smuzhiyun CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls,
829*4882a593Smuzhiyun stuff->enabledCtrls);
830*4882a593Smuzhiyun if (stuff->affectEnabledCtrls) {
831*4882a593Smuzhiyun CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls,
832*4882a593Smuzhiyun XkbAllBooleanCtrlsMask);
833*4882a593Smuzhiyun
834*4882a593Smuzhiyun new.enabled_ctrls &= ~(stuff->affectEnabledCtrls);
835*4882a593Smuzhiyun new.enabled_ctrls |= (stuff->affectEnabledCtrls &
836*4882a593Smuzhiyun stuff->enabledCtrls);
837*4882a593Smuzhiyun }
838*4882a593Smuzhiyun
839*4882a593Smuzhiyun if (stuff->changeCtrls & XkbRepeatKeysMask) {
840*4882a593Smuzhiyun if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) {
841*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay,
842*4882a593Smuzhiyun stuff->repeatInterval);
843*4882a593Smuzhiyun return BadValue;
844*4882a593Smuzhiyun }
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun new.repeat_delay = stuff->repeatDelay;
847*4882a593Smuzhiyun new.repeat_interval = stuff->repeatInterval;
848*4882a593Smuzhiyun }
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun if (stuff->changeCtrls & XkbSlowKeysMask) {
851*4882a593Smuzhiyun if (stuff->slowKeysDelay < 1) {
852*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x09,
853*4882a593Smuzhiyun stuff->slowKeysDelay);
854*4882a593Smuzhiyun return BadValue;
855*4882a593Smuzhiyun }
856*4882a593Smuzhiyun
857*4882a593Smuzhiyun new.slow_keys_delay = stuff->slowKeysDelay;
858*4882a593Smuzhiyun }
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun if (stuff->changeCtrls & XkbBounceKeysMask) {
861*4882a593Smuzhiyun if (stuff->debounceDelay < 1) {
862*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x0A,
863*4882a593Smuzhiyun stuff->debounceDelay);
864*4882a593Smuzhiyun return BadValue;
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun new.debounce_delay = stuff->debounceDelay;
868*4882a593Smuzhiyun }
869*4882a593Smuzhiyun
870*4882a593Smuzhiyun if (stuff->changeCtrls & XkbMouseKeysMask) {
871*4882a593Smuzhiyun if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) {
872*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn);
873*4882a593Smuzhiyun return BadValue;
874*4882a593Smuzhiyun }
875*4882a593Smuzhiyun
876*4882a593Smuzhiyun new.mk_dflt_btn = stuff->mkDfltBtn;
877*4882a593Smuzhiyun }
878*4882a593Smuzhiyun
879*4882a593Smuzhiyun if (stuff->changeCtrls & XkbMouseKeysAccelMask) {
880*4882a593Smuzhiyun if (stuff->mkDelay < 1 || stuff->mkInterval < 1 ||
881*4882a593Smuzhiyun stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 ||
882*4882a593Smuzhiyun stuff->mkCurve < -1000) {
883*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x0C, 0);
884*4882a593Smuzhiyun return BadValue;
885*4882a593Smuzhiyun }
886*4882a593Smuzhiyun
887*4882a593Smuzhiyun new.mk_delay = stuff->mkDelay;
888*4882a593Smuzhiyun new.mk_interval = stuff->mkInterval;
889*4882a593Smuzhiyun new.mk_time_to_max = stuff->mkTimeToMax;
890*4882a593Smuzhiyun new.mk_max_speed = stuff->mkMaxSpeed;
891*4882a593Smuzhiyun new.mk_curve = stuff->mkCurve;
892*4882a593Smuzhiyun AccessXComputeCurveFactor(xkbi, &new);
893*4882a593Smuzhiyun }
894*4882a593Smuzhiyun
895*4882a593Smuzhiyun if (stuff->changeCtrls & XkbGroupsWrapMask) {
896*4882a593Smuzhiyun unsigned act, num;
897*4882a593Smuzhiyun
898*4882a593Smuzhiyun act = XkbOutOfRangeGroupAction(stuff->groupsWrap);
899*4882a593Smuzhiyun switch (act) {
900*4882a593Smuzhiyun case XkbRedirectIntoRange:
901*4882a593Smuzhiyun num = XkbOutOfRangeGroupNumber(stuff->groupsWrap);
902*4882a593Smuzhiyun if (num >= new.num_groups) {
903*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x0D, new.num_groups,
904*4882a593Smuzhiyun num);
905*4882a593Smuzhiyun return BadValue;
906*4882a593Smuzhiyun }
907*4882a593Smuzhiyun case XkbWrapIntoRange:
908*4882a593Smuzhiyun case XkbClampIntoRange:
909*4882a593Smuzhiyun break;
910*4882a593Smuzhiyun default:
911*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x0E, act);
912*4882a593Smuzhiyun return BadValue;
913*4882a593Smuzhiyun }
914*4882a593Smuzhiyun
915*4882a593Smuzhiyun new.groups_wrap = stuff->groupsWrap;
916*4882a593Smuzhiyun }
917*4882a593Smuzhiyun
918*4882a593Smuzhiyun CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask);
919*4882a593Smuzhiyun if (stuff->changeCtrls & XkbAccessXKeysMask) {
920*4882a593Smuzhiyun new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask;
921*4882a593Smuzhiyun }
922*4882a593Smuzhiyun else {
923*4882a593Smuzhiyun if (stuff->changeCtrls & XkbStickyKeysMask) {
924*4882a593Smuzhiyun new.ax_options &= ~(XkbAX_SKOptionsMask);
925*4882a593Smuzhiyun new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask);
926*4882a593Smuzhiyun }
927*4882a593Smuzhiyun
928*4882a593Smuzhiyun if (stuff->changeCtrls & XkbAccessXFeedbackMask) {
929*4882a593Smuzhiyun new.ax_options &= ~(XkbAX_FBOptionsMask);
930*4882a593Smuzhiyun new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask);
931*4882a593Smuzhiyun }
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun if (stuff->changeCtrls & XkbAccessXTimeoutMask) {
935*4882a593Smuzhiyun if (stuff->axTimeout < 1) {
936*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout);
937*4882a593Smuzhiyun return BadValue;
938*4882a593Smuzhiyun }
939*4882a593Smuzhiyun CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask,
940*4882a593Smuzhiyun stuff->axtCtrlsValues);
941*4882a593Smuzhiyun CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask,
942*4882a593Smuzhiyun XkbAllBooleanCtrlsMask);
943*4882a593Smuzhiyun CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues);
944*4882a593Smuzhiyun CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask);
945*4882a593Smuzhiyun new.ax_timeout = stuff->axTimeout;
946*4882a593Smuzhiyun new.axt_ctrls_mask = stuff->axtCtrlsMask;
947*4882a593Smuzhiyun new.axt_ctrls_values = (stuff->axtCtrlsValues &
948*4882a593Smuzhiyun stuff->axtCtrlsMask);
949*4882a593Smuzhiyun new.axt_opts_mask = stuff->axtOptsMask;
950*4882a593Smuzhiyun new.axt_opts_values = (stuff->axtOptsValues &
951*4882a593Smuzhiyun stuff->axtOptsMask);
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun if (stuff->changeCtrls & XkbPerKeyRepeatMask) {
955*4882a593Smuzhiyun memcpy(new.per_key_repeat, stuff->perKeyRepeat,
956*4882a593Smuzhiyun XkbPerKeyBitArraySize);
957*4882a593Smuzhiyun if (xkbi->repeatKey &&
958*4882a593Smuzhiyun !BitIsOn(new.per_key_repeat, xkbi->repeatKey)) {
959*4882a593Smuzhiyun AccessXCancelRepeatKey(xkbi, xkbi->repeatKey);
960*4882a593Smuzhiyun }
961*4882a593Smuzhiyun }
962*4882a593Smuzhiyun
963*4882a593Smuzhiyun old = *ctrl;
964*4882a593Smuzhiyun *ctrl = new;
965*4882a593Smuzhiyun XkbDDXChangeControls(tmpd, &old, ctrl);
966*4882a593Smuzhiyun
967*4882a593Smuzhiyun if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, FALSE)) {
968*4882a593Smuzhiyun cn.keycode = 0;
969*4882a593Smuzhiyun cn.eventType = 0;
970*4882a593Smuzhiyun cn.requestMajor = XkbReqCode;
971*4882a593Smuzhiyun cn.requestMinor = X_kbSetControls;
972*4882a593Smuzhiyun XkbSendControlsNotify(tmpd, &cn);
973*4882a593Smuzhiyun }
974*4882a593Smuzhiyun
975*4882a593Smuzhiyun sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0);
976*4882a593Smuzhiyun if (sli)
977*4882a593Smuzhiyun XkbUpdateIndicators(tmpd, sli->usesControls, TRUE, NULL,
978*4882a593Smuzhiyun &cause);
979*4882a593Smuzhiyun
980*4882a593Smuzhiyun /* If sticky keys were disabled, clear all locks and latches */
981*4882a593Smuzhiyun if ((old.enabled_ctrls & XkbStickyKeysMask) &&
982*4882a593Smuzhiyun !(ctrl->enabled_ctrls & XkbStickyKeysMask))
983*4882a593Smuzhiyun XkbClearAllLatchesAndLocks(tmpd, xkbi, TRUE, &cause);
984*4882a593Smuzhiyun }
985*4882a593Smuzhiyun }
986*4882a593Smuzhiyun
987*4882a593Smuzhiyun return Success;
988*4882a593Smuzhiyun }
989*4882a593Smuzhiyun
990*4882a593Smuzhiyun /***====================================================================***/
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun static int
XkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply * rep)993*4882a593Smuzhiyun XkbSizeKeyTypes(XkbDescPtr xkb, xkbGetMapReply * rep)
994*4882a593Smuzhiyun {
995*4882a593Smuzhiyun XkbKeyTypeRec *type;
996*4882a593Smuzhiyun unsigned i, len;
997*4882a593Smuzhiyun
998*4882a593Smuzhiyun len = 0;
999*4882a593Smuzhiyun if (((rep->present & XkbKeyTypesMask) == 0) || (rep->nTypes < 1) ||
1000*4882a593Smuzhiyun (!xkb) || (!xkb->map) || (!xkb->map->types)) {
1001*4882a593Smuzhiyun rep->present &= ~XkbKeyTypesMask;
1002*4882a593Smuzhiyun rep->firstType = rep->nTypes = 0;
1003*4882a593Smuzhiyun return 0;
1004*4882a593Smuzhiyun }
1005*4882a593Smuzhiyun type = &xkb->map->types[rep->firstType];
1006*4882a593Smuzhiyun for (i = 0; i < rep->nTypes; i++, type++) {
1007*4882a593Smuzhiyun len += SIZEOF(xkbKeyTypeWireDesc);
1008*4882a593Smuzhiyun if (type->map_count > 0) {
1009*4882a593Smuzhiyun len += (type->map_count * SIZEOF(xkbKTMapEntryWireDesc));
1010*4882a593Smuzhiyun if (type->preserve)
1011*4882a593Smuzhiyun len += (type->map_count * SIZEOF(xkbModsWireDesc));
1012*4882a593Smuzhiyun }
1013*4882a593Smuzhiyun }
1014*4882a593Smuzhiyun return len;
1015*4882a593Smuzhiyun }
1016*4882a593Smuzhiyun
1017*4882a593Smuzhiyun static char *
XkbWriteKeyTypes(XkbDescPtr xkb,xkbGetMapReply * rep,char * buf,ClientPtr client)1018*4882a593Smuzhiyun XkbWriteKeyTypes(XkbDescPtr xkb,
1019*4882a593Smuzhiyun xkbGetMapReply * rep, char *buf, ClientPtr client)
1020*4882a593Smuzhiyun {
1021*4882a593Smuzhiyun XkbKeyTypePtr type;
1022*4882a593Smuzhiyun unsigned i;
1023*4882a593Smuzhiyun xkbKeyTypeWireDesc *wire;
1024*4882a593Smuzhiyun
1025*4882a593Smuzhiyun type = &xkb->map->types[rep->firstType];
1026*4882a593Smuzhiyun for (i = 0; i < rep->nTypes; i++, type++) {
1027*4882a593Smuzhiyun register unsigned n;
1028*4882a593Smuzhiyun
1029*4882a593Smuzhiyun wire = (xkbKeyTypeWireDesc *) buf;
1030*4882a593Smuzhiyun wire->mask = type->mods.mask;
1031*4882a593Smuzhiyun wire->realMods = type->mods.real_mods;
1032*4882a593Smuzhiyun wire->virtualMods = type->mods.vmods;
1033*4882a593Smuzhiyun wire->numLevels = type->num_levels;
1034*4882a593Smuzhiyun wire->nMapEntries = type->map_count;
1035*4882a593Smuzhiyun wire->preserve = (type->preserve != NULL);
1036*4882a593Smuzhiyun if (client->swapped) {
1037*4882a593Smuzhiyun swaps(&wire->virtualMods);
1038*4882a593Smuzhiyun }
1039*4882a593Smuzhiyun
1040*4882a593Smuzhiyun buf = (char *) &wire[1];
1041*4882a593Smuzhiyun if (wire->nMapEntries > 0) {
1042*4882a593Smuzhiyun xkbKTMapEntryWireDesc *ewire;
1043*4882a593Smuzhiyun XkbKTMapEntryPtr entry;
1044*4882a593Smuzhiyun
1045*4882a593Smuzhiyun ewire = (xkbKTMapEntryWireDesc *) buf;
1046*4882a593Smuzhiyun entry = type->map;
1047*4882a593Smuzhiyun for (n = 0; n < type->map_count; n++, ewire++, entry++) {
1048*4882a593Smuzhiyun ewire->active = entry->active;
1049*4882a593Smuzhiyun ewire->mask = entry->mods.mask;
1050*4882a593Smuzhiyun ewire->level = entry->level;
1051*4882a593Smuzhiyun ewire->realMods = entry->mods.real_mods;
1052*4882a593Smuzhiyun ewire->virtualMods = entry->mods.vmods;
1053*4882a593Smuzhiyun if (client->swapped) {
1054*4882a593Smuzhiyun swaps(&ewire->virtualMods);
1055*4882a593Smuzhiyun }
1056*4882a593Smuzhiyun }
1057*4882a593Smuzhiyun buf = (char *) ewire;
1058*4882a593Smuzhiyun if (type->preserve != NULL) {
1059*4882a593Smuzhiyun xkbModsWireDesc *pwire;
1060*4882a593Smuzhiyun XkbModsPtr preserve;
1061*4882a593Smuzhiyun
1062*4882a593Smuzhiyun pwire = (xkbModsWireDesc *) buf;
1063*4882a593Smuzhiyun preserve = type->preserve;
1064*4882a593Smuzhiyun for (n = 0; n < type->map_count; n++, pwire++, preserve++) {
1065*4882a593Smuzhiyun pwire->mask = preserve->mask;
1066*4882a593Smuzhiyun pwire->realMods = preserve->real_mods;
1067*4882a593Smuzhiyun pwire->virtualMods = preserve->vmods;
1068*4882a593Smuzhiyun if (client->swapped) {
1069*4882a593Smuzhiyun swaps(&pwire->virtualMods);
1070*4882a593Smuzhiyun }
1071*4882a593Smuzhiyun }
1072*4882a593Smuzhiyun buf = (char *) pwire;
1073*4882a593Smuzhiyun }
1074*4882a593Smuzhiyun }
1075*4882a593Smuzhiyun }
1076*4882a593Smuzhiyun return buf;
1077*4882a593Smuzhiyun }
1078*4882a593Smuzhiyun
1079*4882a593Smuzhiyun static int
XkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply * rep)1080*4882a593Smuzhiyun XkbSizeKeySyms(XkbDescPtr xkb, xkbGetMapReply * rep)
1081*4882a593Smuzhiyun {
1082*4882a593Smuzhiyun XkbSymMapPtr symMap;
1083*4882a593Smuzhiyun unsigned i, len;
1084*4882a593Smuzhiyun unsigned nSyms, nSymsThisKey;
1085*4882a593Smuzhiyun
1086*4882a593Smuzhiyun if (((rep->present & XkbKeySymsMask) == 0) || (rep->nKeySyms < 1) ||
1087*4882a593Smuzhiyun (!xkb) || (!xkb->map) || (!xkb->map->key_sym_map)) {
1088*4882a593Smuzhiyun rep->present &= ~XkbKeySymsMask;
1089*4882a593Smuzhiyun rep->firstKeySym = rep->nKeySyms = 0;
1090*4882a593Smuzhiyun rep->totalSyms = 0;
1091*4882a593Smuzhiyun return 0;
1092*4882a593Smuzhiyun }
1093*4882a593Smuzhiyun len = rep->nKeySyms * SIZEOF(xkbSymMapWireDesc);
1094*4882a593Smuzhiyun symMap = &xkb->map->key_sym_map[rep->firstKeySym];
1095*4882a593Smuzhiyun for (i = nSyms = 0; i < rep->nKeySyms; i++, symMap++) {
1096*4882a593Smuzhiyun if (symMap->offset != 0) {
1097*4882a593Smuzhiyun nSymsThisKey = XkbNumGroups(symMap->group_info) * symMap->width;
1098*4882a593Smuzhiyun nSyms += nSymsThisKey;
1099*4882a593Smuzhiyun }
1100*4882a593Smuzhiyun }
1101*4882a593Smuzhiyun len += nSyms * 4;
1102*4882a593Smuzhiyun rep->totalSyms = nSyms;
1103*4882a593Smuzhiyun return len;
1104*4882a593Smuzhiyun }
1105*4882a593Smuzhiyun
1106*4882a593Smuzhiyun static int
XkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply * rep)1107*4882a593Smuzhiyun XkbSizeVirtualMods(XkbDescPtr xkb, xkbGetMapReply * rep)
1108*4882a593Smuzhiyun {
1109*4882a593Smuzhiyun register unsigned i, nMods, bit;
1110*4882a593Smuzhiyun
1111*4882a593Smuzhiyun if (((rep->present & XkbVirtualModsMask) == 0) || (rep->virtualMods == 0) ||
1112*4882a593Smuzhiyun (!xkb) || (!xkb->server)) {
1113*4882a593Smuzhiyun rep->present &= ~XkbVirtualModsMask;
1114*4882a593Smuzhiyun rep->virtualMods = 0;
1115*4882a593Smuzhiyun return 0;
1116*4882a593Smuzhiyun }
1117*4882a593Smuzhiyun for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
1118*4882a593Smuzhiyun if (rep->virtualMods & bit)
1119*4882a593Smuzhiyun nMods++;
1120*4882a593Smuzhiyun }
1121*4882a593Smuzhiyun return XkbPaddedSize(nMods);
1122*4882a593Smuzhiyun }
1123*4882a593Smuzhiyun
1124*4882a593Smuzhiyun static char *
XkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply * rep,char * buf,ClientPtr client)1125*4882a593Smuzhiyun XkbWriteKeySyms(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf,
1126*4882a593Smuzhiyun ClientPtr client)
1127*4882a593Smuzhiyun {
1128*4882a593Smuzhiyun register KeySym *pSym;
1129*4882a593Smuzhiyun XkbSymMapPtr symMap;
1130*4882a593Smuzhiyun xkbSymMapWireDesc *outMap;
1131*4882a593Smuzhiyun register unsigned i;
1132*4882a593Smuzhiyun
1133*4882a593Smuzhiyun symMap = &xkb->map->key_sym_map[rep->firstKeySym];
1134*4882a593Smuzhiyun for (i = 0; i < rep->nKeySyms; i++, symMap++) {
1135*4882a593Smuzhiyun outMap = (xkbSymMapWireDesc *) buf;
1136*4882a593Smuzhiyun outMap->ktIndex[0] = symMap->kt_index[0];
1137*4882a593Smuzhiyun outMap->ktIndex[1] = symMap->kt_index[1];
1138*4882a593Smuzhiyun outMap->ktIndex[2] = symMap->kt_index[2];
1139*4882a593Smuzhiyun outMap->ktIndex[3] = symMap->kt_index[3];
1140*4882a593Smuzhiyun outMap->groupInfo = symMap->group_info;
1141*4882a593Smuzhiyun outMap->width = symMap->width;
1142*4882a593Smuzhiyun outMap->nSyms = symMap->width * XkbNumGroups(symMap->group_info);
1143*4882a593Smuzhiyun buf = (char *) &outMap[1];
1144*4882a593Smuzhiyun if (outMap->nSyms == 0)
1145*4882a593Smuzhiyun continue;
1146*4882a593Smuzhiyun
1147*4882a593Smuzhiyun pSym = &xkb->map->syms[symMap->offset];
1148*4882a593Smuzhiyun memcpy((char *) buf, (char *) pSym, outMap->nSyms * 4);
1149*4882a593Smuzhiyun if (client->swapped) {
1150*4882a593Smuzhiyun register int nSyms = outMap->nSyms;
1151*4882a593Smuzhiyun
1152*4882a593Smuzhiyun swaps(&outMap->nSyms);
1153*4882a593Smuzhiyun while (nSyms-- > 0) {
1154*4882a593Smuzhiyun swapl((int *) buf);
1155*4882a593Smuzhiyun buf += 4;
1156*4882a593Smuzhiyun }
1157*4882a593Smuzhiyun }
1158*4882a593Smuzhiyun else
1159*4882a593Smuzhiyun buf += outMap->nSyms * 4;
1160*4882a593Smuzhiyun }
1161*4882a593Smuzhiyun return buf;
1162*4882a593Smuzhiyun }
1163*4882a593Smuzhiyun
1164*4882a593Smuzhiyun static int
XkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply * rep)1165*4882a593Smuzhiyun XkbSizeKeyActions(XkbDescPtr xkb, xkbGetMapReply * rep)
1166*4882a593Smuzhiyun {
1167*4882a593Smuzhiyun unsigned i, len, nActs;
1168*4882a593Smuzhiyun register KeyCode firstKey;
1169*4882a593Smuzhiyun
1170*4882a593Smuzhiyun if (((rep->present & XkbKeyActionsMask) == 0) || (rep->nKeyActs < 1) ||
1171*4882a593Smuzhiyun (!xkb) || (!xkb->server) || (!xkb->server->key_acts)) {
1172*4882a593Smuzhiyun rep->present &= ~XkbKeyActionsMask;
1173*4882a593Smuzhiyun rep->firstKeyAct = rep->nKeyActs = 0;
1174*4882a593Smuzhiyun rep->totalActs = 0;
1175*4882a593Smuzhiyun return 0;
1176*4882a593Smuzhiyun }
1177*4882a593Smuzhiyun firstKey = rep->firstKeyAct;
1178*4882a593Smuzhiyun for (nActs = i = 0; i < rep->nKeyActs; i++) {
1179*4882a593Smuzhiyun if (xkb->server->key_acts[i + firstKey] != 0)
1180*4882a593Smuzhiyun nActs += XkbKeyNumActions(xkb, i + firstKey);
1181*4882a593Smuzhiyun }
1182*4882a593Smuzhiyun len = XkbPaddedSize(rep->nKeyActs) + (nActs * SIZEOF(xkbActionWireDesc));
1183*4882a593Smuzhiyun rep->totalActs = nActs;
1184*4882a593Smuzhiyun return len;
1185*4882a593Smuzhiyun }
1186*4882a593Smuzhiyun
1187*4882a593Smuzhiyun static char *
XkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply * rep,char * buf,ClientPtr client)1188*4882a593Smuzhiyun XkbWriteKeyActions(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf,
1189*4882a593Smuzhiyun ClientPtr client)
1190*4882a593Smuzhiyun {
1191*4882a593Smuzhiyun unsigned i;
1192*4882a593Smuzhiyun CARD8 *numDesc;
1193*4882a593Smuzhiyun XkbAnyAction *actDesc;
1194*4882a593Smuzhiyun
1195*4882a593Smuzhiyun numDesc = (CARD8 *) buf;
1196*4882a593Smuzhiyun for (i = 0; i < rep->nKeyActs; i++) {
1197*4882a593Smuzhiyun if (xkb->server->key_acts[i + rep->firstKeyAct] == 0)
1198*4882a593Smuzhiyun numDesc[i] = 0;
1199*4882a593Smuzhiyun else
1200*4882a593Smuzhiyun numDesc[i] = XkbKeyNumActions(xkb, (i + rep->firstKeyAct));
1201*4882a593Smuzhiyun }
1202*4882a593Smuzhiyun buf += XkbPaddedSize(rep->nKeyActs);
1203*4882a593Smuzhiyun
1204*4882a593Smuzhiyun actDesc = (XkbAnyAction *) buf;
1205*4882a593Smuzhiyun for (i = 0; i < rep->nKeyActs; i++) {
1206*4882a593Smuzhiyun if (xkb->server->key_acts[i + rep->firstKeyAct] != 0) {
1207*4882a593Smuzhiyun unsigned int num;
1208*4882a593Smuzhiyun
1209*4882a593Smuzhiyun num = XkbKeyNumActions(xkb, (i + rep->firstKeyAct));
1210*4882a593Smuzhiyun memcpy((char *) actDesc,
1211*4882a593Smuzhiyun (char *) XkbKeyActionsPtr(xkb, (i + rep->firstKeyAct)),
1212*4882a593Smuzhiyun num * SIZEOF(xkbActionWireDesc));
1213*4882a593Smuzhiyun actDesc += num;
1214*4882a593Smuzhiyun }
1215*4882a593Smuzhiyun }
1216*4882a593Smuzhiyun buf = (char *) actDesc;
1217*4882a593Smuzhiyun return buf;
1218*4882a593Smuzhiyun }
1219*4882a593Smuzhiyun
1220*4882a593Smuzhiyun static int
XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply * rep)1221*4882a593Smuzhiyun XkbSizeKeyBehaviors(XkbDescPtr xkb, xkbGetMapReply * rep)
1222*4882a593Smuzhiyun {
1223*4882a593Smuzhiyun unsigned i, len, nBhvr;
1224*4882a593Smuzhiyun XkbBehavior *bhv;
1225*4882a593Smuzhiyun
1226*4882a593Smuzhiyun if (((rep->present & XkbKeyBehaviorsMask) == 0) || (rep->nKeyBehaviors < 1)
1227*4882a593Smuzhiyun || (!xkb) || (!xkb->server) || (!xkb->server->behaviors)) {
1228*4882a593Smuzhiyun rep->present &= ~XkbKeyBehaviorsMask;
1229*4882a593Smuzhiyun rep->firstKeyBehavior = rep->nKeyBehaviors = 0;
1230*4882a593Smuzhiyun rep->totalKeyBehaviors = 0;
1231*4882a593Smuzhiyun return 0;
1232*4882a593Smuzhiyun }
1233*4882a593Smuzhiyun bhv = &xkb->server->behaviors[rep->firstKeyBehavior];
1234*4882a593Smuzhiyun for (nBhvr = i = 0; i < rep->nKeyBehaviors; i++, bhv++) {
1235*4882a593Smuzhiyun if (bhv->type != XkbKB_Default)
1236*4882a593Smuzhiyun nBhvr++;
1237*4882a593Smuzhiyun }
1238*4882a593Smuzhiyun len = nBhvr * SIZEOF(xkbBehaviorWireDesc);
1239*4882a593Smuzhiyun rep->totalKeyBehaviors = nBhvr;
1240*4882a593Smuzhiyun return len;
1241*4882a593Smuzhiyun }
1242*4882a593Smuzhiyun
1243*4882a593Smuzhiyun static char *
XkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply * rep,char * buf,ClientPtr client)1244*4882a593Smuzhiyun XkbWriteKeyBehaviors(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf,
1245*4882a593Smuzhiyun ClientPtr client)
1246*4882a593Smuzhiyun {
1247*4882a593Smuzhiyun unsigned i;
1248*4882a593Smuzhiyun xkbBehaviorWireDesc *wire;
1249*4882a593Smuzhiyun XkbBehavior *pBhvr;
1250*4882a593Smuzhiyun
1251*4882a593Smuzhiyun wire = (xkbBehaviorWireDesc *) buf;
1252*4882a593Smuzhiyun pBhvr = &xkb->server->behaviors[rep->firstKeyBehavior];
1253*4882a593Smuzhiyun for (i = 0; i < rep->nKeyBehaviors; i++, pBhvr++) {
1254*4882a593Smuzhiyun if (pBhvr->type != XkbKB_Default) {
1255*4882a593Smuzhiyun wire->key = i + rep->firstKeyBehavior;
1256*4882a593Smuzhiyun wire->type = pBhvr->type;
1257*4882a593Smuzhiyun wire->data = pBhvr->data;
1258*4882a593Smuzhiyun wire++;
1259*4882a593Smuzhiyun }
1260*4882a593Smuzhiyun }
1261*4882a593Smuzhiyun buf = (char *) wire;
1262*4882a593Smuzhiyun return buf;
1263*4882a593Smuzhiyun }
1264*4882a593Smuzhiyun
1265*4882a593Smuzhiyun static int
XkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply * rep)1266*4882a593Smuzhiyun XkbSizeExplicit(XkbDescPtr xkb, xkbGetMapReply * rep)
1267*4882a593Smuzhiyun {
1268*4882a593Smuzhiyun unsigned i, len, nRtrn;
1269*4882a593Smuzhiyun
1270*4882a593Smuzhiyun if (((rep->present & XkbExplicitComponentsMask) == 0) ||
1271*4882a593Smuzhiyun (rep->nKeyExplicit < 1) || (!xkb) || (!xkb->server) ||
1272*4882a593Smuzhiyun (!xkb->server->explicit)) {
1273*4882a593Smuzhiyun rep->present &= ~XkbExplicitComponentsMask;
1274*4882a593Smuzhiyun rep->firstKeyExplicit = rep->nKeyExplicit = 0;
1275*4882a593Smuzhiyun rep->totalKeyExplicit = 0;
1276*4882a593Smuzhiyun return 0;
1277*4882a593Smuzhiyun }
1278*4882a593Smuzhiyun for (nRtrn = i = 0; i < rep->nKeyExplicit; i++) {
1279*4882a593Smuzhiyun if (xkb->server->explicit[i + rep->firstKeyExplicit] != 0)
1280*4882a593Smuzhiyun nRtrn++;
1281*4882a593Smuzhiyun }
1282*4882a593Smuzhiyun rep->totalKeyExplicit = nRtrn;
1283*4882a593Smuzhiyun len = XkbPaddedSize(nRtrn * 2); /* two bytes per non-zero explicit component */
1284*4882a593Smuzhiyun return len;
1285*4882a593Smuzhiyun }
1286*4882a593Smuzhiyun
1287*4882a593Smuzhiyun static char *
XkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply * rep,char * buf,ClientPtr client)1288*4882a593Smuzhiyun XkbWriteExplicit(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf,
1289*4882a593Smuzhiyun ClientPtr client)
1290*4882a593Smuzhiyun {
1291*4882a593Smuzhiyun unsigned i;
1292*4882a593Smuzhiyun char *start;
1293*4882a593Smuzhiyun unsigned char *pExp;
1294*4882a593Smuzhiyun
1295*4882a593Smuzhiyun start = buf;
1296*4882a593Smuzhiyun pExp = &xkb->server->explicit[rep->firstKeyExplicit];
1297*4882a593Smuzhiyun for (i = 0; i < rep->nKeyExplicit; i++, pExp++) {
1298*4882a593Smuzhiyun if (*pExp != 0) {
1299*4882a593Smuzhiyun *buf++ = i + rep->firstKeyExplicit;
1300*4882a593Smuzhiyun *buf++ = *pExp;
1301*4882a593Smuzhiyun }
1302*4882a593Smuzhiyun }
1303*4882a593Smuzhiyun i = XkbPaddedSize(buf - start) - (buf - start); /* pad to word boundary */
1304*4882a593Smuzhiyun return buf + i;
1305*4882a593Smuzhiyun }
1306*4882a593Smuzhiyun
1307*4882a593Smuzhiyun static int
XkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply * rep)1308*4882a593Smuzhiyun XkbSizeModifierMap(XkbDescPtr xkb, xkbGetMapReply * rep)
1309*4882a593Smuzhiyun {
1310*4882a593Smuzhiyun unsigned i, len, nRtrn;
1311*4882a593Smuzhiyun
1312*4882a593Smuzhiyun if (((rep->present & XkbModifierMapMask) == 0) || (rep->nModMapKeys < 1) ||
1313*4882a593Smuzhiyun (!xkb) || (!xkb->map) || (!xkb->map->modmap)) {
1314*4882a593Smuzhiyun rep->present &= ~XkbModifierMapMask;
1315*4882a593Smuzhiyun rep->firstModMapKey = rep->nModMapKeys = 0;
1316*4882a593Smuzhiyun rep->totalModMapKeys = 0;
1317*4882a593Smuzhiyun return 0;
1318*4882a593Smuzhiyun }
1319*4882a593Smuzhiyun for (nRtrn = i = 0; i < rep->nModMapKeys; i++) {
1320*4882a593Smuzhiyun if (xkb->map->modmap[i + rep->firstModMapKey] != 0)
1321*4882a593Smuzhiyun nRtrn++;
1322*4882a593Smuzhiyun }
1323*4882a593Smuzhiyun rep->totalModMapKeys = nRtrn;
1324*4882a593Smuzhiyun len = XkbPaddedSize(nRtrn * 2); /* two bytes per non-zero modmap component */
1325*4882a593Smuzhiyun return len;
1326*4882a593Smuzhiyun }
1327*4882a593Smuzhiyun
1328*4882a593Smuzhiyun static char *
XkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply * rep,char * buf,ClientPtr client)1329*4882a593Smuzhiyun XkbWriteModifierMap(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf,
1330*4882a593Smuzhiyun ClientPtr client)
1331*4882a593Smuzhiyun {
1332*4882a593Smuzhiyun unsigned i;
1333*4882a593Smuzhiyun char *start;
1334*4882a593Smuzhiyun unsigned char *pMap;
1335*4882a593Smuzhiyun
1336*4882a593Smuzhiyun start = buf;
1337*4882a593Smuzhiyun pMap = &xkb->map->modmap[rep->firstModMapKey];
1338*4882a593Smuzhiyun for (i = 0; i < rep->nModMapKeys; i++, pMap++) {
1339*4882a593Smuzhiyun if (*pMap != 0) {
1340*4882a593Smuzhiyun *buf++ = i + rep->firstModMapKey;
1341*4882a593Smuzhiyun *buf++ = *pMap;
1342*4882a593Smuzhiyun }
1343*4882a593Smuzhiyun }
1344*4882a593Smuzhiyun i = XkbPaddedSize(buf - start) - (buf - start); /* pad to word boundary */
1345*4882a593Smuzhiyun return buf + i;
1346*4882a593Smuzhiyun }
1347*4882a593Smuzhiyun
1348*4882a593Smuzhiyun static int
XkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply * rep)1349*4882a593Smuzhiyun XkbSizeVirtualModMap(XkbDescPtr xkb, xkbGetMapReply * rep)
1350*4882a593Smuzhiyun {
1351*4882a593Smuzhiyun unsigned i, len, nRtrn;
1352*4882a593Smuzhiyun
1353*4882a593Smuzhiyun if (((rep->present & XkbVirtualModMapMask) == 0) || (rep->nVModMapKeys < 1)
1354*4882a593Smuzhiyun || (!xkb) || (!xkb->server) || (!xkb->server->vmodmap)) {
1355*4882a593Smuzhiyun rep->present &= ~XkbVirtualModMapMask;
1356*4882a593Smuzhiyun rep->firstVModMapKey = rep->nVModMapKeys = 0;
1357*4882a593Smuzhiyun rep->totalVModMapKeys = 0;
1358*4882a593Smuzhiyun return 0;
1359*4882a593Smuzhiyun }
1360*4882a593Smuzhiyun for (nRtrn = i = 0; i < rep->nVModMapKeys; i++) {
1361*4882a593Smuzhiyun if (xkb->server->vmodmap[i + rep->firstVModMapKey] != 0)
1362*4882a593Smuzhiyun nRtrn++;
1363*4882a593Smuzhiyun }
1364*4882a593Smuzhiyun rep->totalVModMapKeys = nRtrn;
1365*4882a593Smuzhiyun len = nRtrn * SIZEOF(xkbVModMapWireDesc);
1366*4882a593Smuzhiyun return len;
1367*4882a593Smuzhiyun }
1368*4882a593Smuzhiyun
1369*4882a593Smuzhiyun static char *
XkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply * rep,char * buf,ClientPtr client)1370*4882a593Smuzhiyun XkbWriteVirtualModMap(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf,
1371*4882a593Smuzhiyun ClientPtr client)
1372*4882a593Smuzhiyun {
1373*4882a593Smuzhiyun unsigned i;
1374*4882a593Smuzhiyun xkbVModMapWireDesc *wire;
1375*4882a593Smuzhiyun unsigned short *pMap;
1376*4882a593Smuzhiyun
1377*4882a593Smuzhiyun wire = (xkbVModMapWireDesc *) buf;
1378*4882a593Smuzhiyun pMap = &xkb->server->vmodmap[rep->firstVModMapKey];
1379*4882a593Smuzhiyun for (i = 0; i < rep->nVModMapKeys; i++, pMap++) {
1380*4882a593Smuzhiyun if (*pMap != 0) {
1381*4882a593Smuzhiyun wire->key = i + rep->firstVModMapKey;
1382*4882a593Smuzhiyun wire->vmods = *pMap;
1383*4882a593Smuzhiyun wire++;
1384*4882a593Smuzhiyun }
1385*4882a593Smuzhiyun }
1386*4882a593Smuzhiyun return (char *) wire;
1387*4882a593Smuzhiyun }
1388*4882a593Smuzhiyun
1389*4882a593Smuzhiyun static Status
XkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply * rep)1390*4882a593Smuzhiyun XkbComputeGetMapReplySize(XkbDescPtr xkb, xkbGetMapReply * rep)
1391*4882a593Smuzhiyun {
1392*4882a593Smuzhiyun int len;
1393*4882a593Smuzhiyun
1394*4882a593Smuzhiyun rep->minKeyCode = xkb->min_key_code;
1395*4882a593Smuzhiyun rep->maxKeyCode = xkb->max_key_code;
1396*4882a593Smuzhiyun len = XkbSizeKeyTypes(xkb, rep);
1397*4882a593Smuzhiyun len += XkbSizeKeySyms(xkb, rep);
1398*4882a593Smuzhiyun len += XkbSizeKeyActions(xkb, rep);
1399*4882a593Smuzhiyun len += XkbSizeKeyBehaviors(xkb, rep);
1400*4882a593Smuzhiyun len += XkbSizeVirtualMods(xkb, rep);
1401*4882a593Smuzhiyun len += XkbSizeExplicit(xkb, rep);
1402*4882a593Smuzhiyun len += XkbSizeModifierMap(xkb, rep);
1403*4882a593Smuzhiyun len += XkbSizeVirtualModMap(xkb, rep);
1404*4882a593Smuzhiyun rep->length += (len / 4);
1405*4882a593Smuzhiyun return Success;
1406*4882a593Smuzhiyun }
1407*4882a593Smuzhiyun
1408*4882a593Smuzhiyun static int
XkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply * rep)1409*4882a593Smuzhiyun XkbSendMap(ClientPtr client, XkbDescPtr xkb, xkbGetMapReply * rep)
1410*4882a593Smuzhiyun {
1411*4882a593Smuzhiyun unsigned i, len;
1412*4882a593Smuzhiyun char *desc, *start;
1413*4882a593Smuzhiyun
1414*4882a593Smuzhiyun len = (rep->length * 4) - (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply));
1415*4882a593Smuzhiyun start = desc = calloc(1, len);
1416*4882a593Smuzhiyun if (!start)
1417*4882a593Smuzhiyun return BadAlloc;
1418*4882a593Smuzhiyun if (rep->nTypes > 0)
1419*4882a593Smuzhiyun desc = XkbWriteKeyTypes(xkb, rep, desc, client);
1420*4882a593Smuzhiyun if (rep->nKeySyms > 0)
1421*4882a593Smuzhiyun desc = XkbWriteKeySyms(xkb, rep, desc, client);
1422*4882a593Smuzhiyun if (rep->nKeyActs > 0)
1423*4882a593Smuzhiyun desc = XkbWriteKeyActions(xkb, rep, desc, client);
1424*4882a593Smuzhiyun if (rep->totalKeyBehaviors > 0)
1425*4882a593Smuzhiyun desc = XkbWriteKeyBehaviors(xkb, rep, desc, client);
1426*4882a593Smuzhiyun if (rep->virtualMods) {
1427*4882a593Smuzhiyun register int sz, bit;
1428*4882a593Smuzhiyun
1429*4882a593Smuzhiyun for (i = sz = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
1430*4882a593Smuzhiyun if (rep->virtualMods & bit) {
1431*4882a593Smuzhiyun desc[sz++] = xkb->server->vmods[i];
1432*4882a593Smuzhiyun }
1433*4882a593Smuzhiyun }
1434*4882a593Smuzhiyun desc += XkbPaddedSize(sz);
1435*4882a593Smuzhiyun }
1436*4882a593Smuzhiyun if (rep->totalKeyExplicit > 0)
1437*4882a593Smuzhiyun desc = XkbWriteExplicit(xkb, rep, desc, client);
1438*4882a593Smuzhiyun if (rep->totalModMapKeys > 0)
1439*4882a593Smuzhiyun desc = XkbWriteModifierMap(xkb, rep, desc, client);
1440*4882a593Smuzhiyun if (rep->totalVModMapKeys > 0)
1441*4882a593Smuzhiyun desc = XkbWriteVirtualModMap(xkb, rep, desc, client);
1442*4882a593Smuzhiyun if ((desc - start) != (len)) {
1443*4882a593Smuzhiyun ErrorF
1444*4882a593Smuzhiyun ("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n",
1445*4882a593Smuzhiyun len, (unsigned long) (desc - start));
1446*4882a593Smuzhiyun }
1447*4882a593Smuzhiyun if (client->swapped) {
1448*4882a593Smuzhiyun swaps(&rep->sequenceNumber);
1449*4882a593Smuzhiyun swapl(&rep->length);
1450*4882a593Smuzhiyun swaps(&rep->present);
1451*4882a593Smuzhiyun swaps(&rep->totalSyms);
1452*4882a593Smuzhiyun swaps(&rep->totalActs);
1453*4882a593Smuzhiyun }
1454*4882a593Smuzhiyun WriteToClient(client, (i = SIZEOF(xkbGetMapReply)), rep);
1455*4882a593Smuzhiyun WriteToClient(client, len, start);
1456*4882a593Smuzhiyun free((char *) start);
1457*4882a593Smuzhiyun return Success;
1458*4882a593Smuzhiyun }
1459*4882a593Smuzhiyun
1460*4882a593Smuzhiyun int
ProcXkbGetMap(ClientPtr client)1461*4882a593Smuzhiyun ProcXkbGetMap(ClientPtr client)
1462*4882a593Smuzhiyun {
1463*4882a593Smuzhiyun DeviceIntPtr dev;
1464*4882a593Smuzhiyun xkbGetMapReply rep;
1465*4882a593Smuzhiyun XkbDescRec *xkb;
1466*4882a593Smuzhiyun int n, status;
1467*4882a593Smuzhiyun
1468*4882a593Smuzhiyun REQUEST(xkbGetMapReq);
1469*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbGetMapReq);
1470*4882a593Smuzhiyun
1471*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
1472*4882a593Smuzhiyun return BadAccess;
1473*4882a593Smuzhiyun
1474*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
1475*4882a593Smuzhiyun CHK_MASK_OVERLAP(0x01, stuff->full, stuff->partial);
1476*4882a593Smuzhiyun CHK_MASK_LEGAL(0x02, stuff->full, XkbAllMapComponentsMask);
1477*4882a593Smuzhiyun CHK_MASK_LEGAL(0x03, stuff->partial, XkbAllMapComponentsMask);
1478*4882a593Smuzhiyun
1479*4882a593Smuzhiyun xkb = dev->key->xkbInfo->desc;
1480*4882a593Smuzhiyun rep = (xkbGetMapReply) {
1481*4882a593Smuzhiyun .type = X_Reply,
1482*4882a593Smuzhiyun .deviceID = dev->id,
1483*4882a593Smuzhiyun .sequenceNumber = client->sequence,
1484*4882a593Smuzhiyun .length = (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2,
1485*4882a593Smuzhiyun .present = stuff->partial | stuff->full,
1486*4882a593Smuzhiyun .minKeyCode = xkb->min_key_code,
1487*4882a593Smuzhiyun .maxKeyCode = xkb->max_key_code
1488*4882a593Smuzhiyun };
1489*4882a593Smuzhiyun
1490*4882a593Smuzhiyun if (stuff->full & XkbKeyTypesMask) {
1491*4882a593Smuzhiyun rep.firstType = 0;
1492*4882a593Smuzhiyun rep.nTypes = xkb->map->num_types;
1493*4882a593Smuzhiyun }
1494*4882a593Smuzhiyun else if (stuff->partial & XkbKeyTypesMask) {
1495*4882a593Smuzhiyun if (((unsigned) stuff->firstType + stuff->nTypes) > xkb->map->num_types) {
1496*4882a593Smuzhiyun client->errorValue = _XkbErrCode4(0x04, xkb->map->num_types,
1497*4882a593Smuzhiyun stuff->firstType, stuff->nTypes);
1498*4882a593Smuzhiyun return BadValue;
1499*4882a593Smuzhiyun }
1500*4882a593Smuzhiyun rep.firstType = stuff->firstType;
1501*4882a593Smuzhiyun rep.nTypes = stuff->nTypes;
1502*4882a593Smuzhiyun }
1503*4882a593Smuzhiyun else
1504*4882a593Smuzhiyun rep.nTypes = 0;
1505*4882a593Smuzhiyun rep.totalTypes = xkb->map->num_types;
1506*4882a593Smuzhiyun
1507*4882a593Smuzhiyun n = XkbNumKeys(xkb);
1508*4882a593Smuzhiyun if (stuff->full & XkbKeySymsMask) {
1509*4882a593Smuzhiyun rep.firstKeySym = xkb->min_key_code;
1510*4882a593Smuzhiyun rep.nKeySyms = n;
1511*4882a593Smuzhiyun }
1512*4882a593Smuzhiyun else if (stuff->partial & XkbKeySymsMask) {
1513*4882a593Smuzhiyun CHK_KEY_RANGE(0x05, stuff->firstKeySym, stuff->nKeySyms, xkb);
1514*4882a593Smuzhiyun rep.firstKeySym = stuff->firstKeySym;
1515*4882a593Smuzhiyun rep.nKeySyms = stuff->nKeySyms;
1516*4882a593Smuzhiyun }
1517*4882a593Smuzhiyun else
1518*4882a593Smuzhiyun rep.nKeySyms = 0;
1519*4882a593Smuzhiyun rep.totalSyms = 0;
1520*4882a593Smuzhiyun
1521*4882a593Smuzhiyun if (stuff->full & XkbKeyActionsMask) {
1522*4882a593Smuzhiyun rep.firstKeyAct = xkb->min_key_code;
1523*4882a593Smuzhiyun rep.nKeyActs = n;
1524*4882a593Smuzhiyun }
1525*4882a593Smuzhiyun else if (stuff->partial & XkbKeyActionsMask) {
1526*4882a593Smuzhiyun CHK_KEY_RANGE(0x07, stuff->firstKeyAct, stuff->nKeyActs, xkb);
1527*4882a593Smuzhiyun rep.firstKeyAct = stuff->firstKeyAct;
1528*4882a593Smuzhiyun rep.nKeyActs = stuff->nKeyActs;
1529*4882a593Smuzhiyun }
1530*4882a593Smuzhiyun else
1531*4882a593Smuzhiyun rep.nKeyActs = 0;
1532*4882a593Smuzhiyun rep.totalActs = 0;
1533*4882a593Smuzhiyun
1534*4882a593Smuzhiyun if (stuff->full & XkbKeyBehaviorsMask) {
1535*4882a593Smuzhiyun rep.firstKeyBehavior = xkb->min_key_code;
1536*4882a593Smuzhiyun rep.nKeyBehaviors = n;
1537*4882a593Smuzhiyun }
1538*4882a593Smuzhiyun else if (stuff->partial & XkbKeyBehaviorsMask) {
1539*4882a593Smuzhiyun CHK_KEY_RANGE(0x09, stuff->firstKeyBehavior, stuff->nKeyBehaviors, xkb);
1540*4882a593Smuzhiyun rep.firstKeyBehavior = stuff->firstKeyBehavior;
1541*4882a593Smuzhiyun rep.nKeyBehaviors = stuff->nKeyBehaviors;
1542*4882a593Smuzhiyun }
1543*4882a593Smuzhiyun else
1544*4882a593Smuzhiyun rep.nKeyBehaviors = 0;
1545*4882a593Smuzhiyun rep.totalKeyBehaviors = 0;
1546*4882a593Smuzhiyun
1547*4882a593Smuzhiyun if (stuff->full & XkbVirtualModsMask)
1548*4882a593Smuzhiyun rep.virtualMods = ~0;
1549*4882a593Smuzhiyun else if (stuff->partial & XkbVirtualModsMask)
1550*4882a593Smuzhiyun rep.virtualMods = stuff->virtualMods;
1551*4882a593Smuzhiyun
1552*4882a593Smuzhiyun if (stuff->full & XkbExplicitComponentsMask) {
1553*4882a593Smuzhiyun rep.firstKeyExplicit = xkb->min_key_code;
1554*4882a593Smuzhiyun rep.nKeyExplicit = n;
1555*4882a593Smuzhiyun }
1556*4882a593Smuzhiyun else if (stuff->partial & XkbExplicitComponentsMask) {
1557*4882a593Smuzhiyun CHK_KEY_RANGE(0x0B, stuff->firstKeyExplicit, stuff->nKeyExplicit, xkb);
1558*4882a593Smuzhiyun rep.firstKeyExplicit = stuff->firstKeyExplicit;
1559*4882a593Smuzhiyun rep.nKeyExplicit = stuff->nKeyExplicit;
1560*4882a593Smuzhiyun }
1561*4882a593Smuzhiyun else
1562*4882a593Smuzhiyun rep.nKeyExplicit = 0;
1563*4882a593Smuzhiyun rep.totalKeyExplicit = 0;
1564*4882a593Smuzhiyun
1565*4882a593Smuzhiyun if (stuff->full & XkbModifierMapMask) {
1566*4882a593Smuzhiyun rep.firstModMapKey = xkb->min_key_code;
1567*4882a593Smuzhiyun rep.nModMapKeys = n;
1568*4882a593Smuzhiyun }
1569*4882a593Smuzhiyun else if (stuff->partial & XkbModifierMapMask) {
1570*4882a593Smuzhiyun CHK_KEY_RANGE(0x0D, stuff->firstModMapKey, stuff->nModMapKeys, xkb);
1571*4882a593Smuzhiyun rep.firstModMapKey = stuff->firstModMapKey;
1572*4882a593Smuzhiyun rep.nModMapKeys = stuff->nModMapKeys;
1573*4882a593Smuzhiyun }
1574*4882a593Smuzhiyun else
1575*4882a593Smuzhiyun rep.nModMapKeys = 0;
1576*4882a593Smuzhiyun rep.totalModMapKeys = 0;
1577*4882a593Smuzhiyun
1578*4882a593Smuzhiyun if (stuff->full & XkbVirtualModMapMask) {
1579*4882a593Smuzhiyun rep.firstVModMapKey = xkb->min_key_code;
1580*4882a593Smuzhiyun rep.nVModMapKeys = n;
1581*4882a593Smuzhiyun }
1582*4882a593Smuzhiyun else if (stuff->partial & XkbVirtualModMapMask) {
1583*4882a593Smuzhiyun CHK_KEY_RANGE(0x0F, stuff->firstVModMapKey, stuff->nVModMapKeys, xkb);
1584*4882a593Smuzhiyun rep.firstVModMapKey = stuff->firstVModMapKey;
1585*4882a593Smuzhiyun rep.nVModMapKeys = stuff->nVModMapKeys;
1586*4882a593Smuzhiyun }
1587*4882a593Smuzhiyun else
1588*4882a593Smuzhiyun rep.nVModMapKeys = 0;
1589*4882a593Smuzhiyun rep.totalVModMapKeys = 0;
1590*4882a593Smuzhiyun
1591*4882a593Smuzhiyun if ((status = XkbComputeGetMapReplySize(xkb, &rep)) != Success)
1592*4882a593Smuzhiyun return status;
1593*4882a593Smuzhiyun return XkbSendMap(client, xkb, &rep);
1594*4882a593Smuzhiyun }
1595*4882a593Smuzhiyun
1596*4882a593Smuzhiyun /***====================================================================***/
1597*4882a593Smuzhiyun
1598*4882a593Smuzhiyun static int
CheckKeyTypes(ClientPtr client,XkbDescPtr xkb,xkbSetMapReq * req,xkbKeyTypeWireDesc ** wireRtrn,int * nMapsRtrn,CARD8 * mapWidthRtrn)1599*4882a593Smuzhiyun CheckKeyTypes(ClientPtr client,
1600*4882a593Smuzhiyun XkbDescPtr xkb,
1601*4882a593Smuzhiyun xkbSetMapReq * req,
1602*4882a593Smuzhiyun xkbKeyTypeWireDesc ** wireRtrn,
1603*4882a593Smuzhiyun int *nMapsRtrn, CARD8 *mapWidthRtrn)
1604*4882a593Smuzhiyun {
1605*4882a593Smuzhiyun unsigned nMaps;
1606*4882a593Smuzhiyun register unsigned i, n;
1607*4882a593Smuzhiyun register CARD8 *map;
1608*4882a593Smuzhiyun register xkbKeyTypeWireDesc *wire = *wireRtrn;
1609*4882a593Smuzhiyun
1610*4882a593Smuzhiyun if (req->firstType > ((unsigned) xkb->map->num_types)) {
1611*4882a593Smuzhiyun *nMapsRtrn = _XkbErrCode3(0x01, req->firstType, xkb->map->num_types);
1612*4882a593Smuzhiyun return 0;
1613*4882a593Smuzhiyun }
1614*4882a593Smuzhiyun if (req->flags & XkbSetMapResizeTypes) {
1615*4882a593Smuzhiyun nMaps = req->firstType + req->nTypes;
1616*4882a593Smuzhiyun if (nMaps < XkbNumRequiredTypes) { /* canonical types must be there */
1617*4882a593Smuzhiyun *nMapsRtrn = _XkbErrCode4(0x02, req->firstType, req->nTypes, 4);
1618*4882a593Smuzhiyun return 0;
1619*4882a593Smuzhiyun }
1620*4882a593Smuzhiyun }
1621*4882a593Smuzhiyun else if (req->present & XkbKeyTypesMask) {
1622*4882a593Smuzhiyun nMaps = xkb->map->num_types;
1623*4882a593Smuzhiyun if ((req->firstType + req->nTypes) > nMaps) {
1624*4882a593Smuzhiyun *nMapsRtrn = req->firstType + req->nTypes;
1625*4882a593Smuzhiyun return 0;
1626*4882a593Smuzhiyun }
1627*4882a593Smuzhiyun }
1628*4882a593Smuzhiyun else {
1629*4882a593Smuzhiyun *nMapsRtrn = xkb->map->num_types;
1630*4882a593Smuzhiyun for (i = 0; i < xkb->map->num_types; i++) {
1631*4882a593Smuzhiyun mapWidthRtrn[i] = xkb->map->types[i].num_levels;
1632*4882a593Smuzhiyun }
1633*4882a593Smuzhiyun return 1;
1634*4882a593Smuzhiyun }
1635*4882a593Smuzhiyun
1636*4882a593Smuzhiyun for (i = 0; i < req->firstType; i++) {
1637*4882a593Smuzhiyun mapWidthRtrn[i] = xkb->map->types[i].num_levels;
1638*4882a593Smuzhiyun }
1639*4882a593Smuzhiyun for (i = 0; i < req->nTypes; i++) {
1640*4882a593Smuzhiyun unsigned width;
1641*4882a593Smuzhiyun
1642*4882a593Smuzhiyun if (client->swapped) {
1643*4882a593Smuzhiyun swaps(&wire->virtualMods);
1644*4882a593Smuzhiyun }
1645*4882a593Smuzhiyun n = i + req->firstType;
1646*4882a593Smuzhiyun width = wire->numLevels;
1647*4882a593Smuzhiyun if (width < 1) {
1648*4882a593Smuzhiyun *nMapsRtrn = _XkbErrCode3(0x04, n, width);
1649*4882a593Smuzhiyun return 0;
1650*4882a593Smuzhiyun }
1651*4882a593Smuzhiyun else if ((n == XkbOneLevelIndex) && (width != 1)) { /* must be width 1 */
1652*4882a593Smuzhiyun *nMapsRtrn = _XkbErrCode3(0x05, n, width);
1653*4882a593Smuzhiyun return 0;
1654*4882a593Smuzhiyun }
1655*4882a593Smuzhiyun else if ((width != 2) &&
1656*4882a593Smuzhiyun ((n == XkbTwoLevelIndex) || (n == XkbKeypadIndex) ||
1657*4882a593Smuzhiyun (n == XkbAlphabeticIndex))) {
1658*4882a593Smuzhiyun /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */
1659*4882a593Smuzhiyun *nMapsRtrn = _XkbErrCode3(0x05, n, width);
1660*4882a593Smuzhiyun return 0;
1661*4882a593Smuzhiyun }
1662*4882a593Smuzhiyun if (wire->nMapEntries > 0) {
1663*4882a593Smuzhiyun xkbKTSetMapEntryWireDesc *mapWire;
1664*4882a593Smuzhiyun xkbModsWireDesc *preWire;
1665*4882a593Smuzhiyun
1666*4882a593Smuzhiyun mapWire = (xkbKTSetMapEntryWireDesc *) &wire[1];
1667*4882a593Smuzhiyun preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries];
1668*4882a593Smuzhiyun for (n = 0; n < wire->nMapEntries; n++) {
1669*4882a593Smuzhiyun if (client->swapped) {
1670*4882a593Smuzhiyun swaps(&mapWire[n].virtualMods);
1671*4882a593Smuzhiyun }
1672*4882a593Smuzhiyun if (mapWire[n].realMods & (~wire->realMods)) {
1673*4882a593Smuzhiyun *nMapsRtrn = _XkbErrCode4(0x06, n, mapWire[n].realMods,
1674*4882a593Smuzhiyun wire->realMods);
1675*4882a593Smuzhiyun return 0;
1676*4882a593Smuzhiyun }
1677*4882a593Smuzhiyun if (mapWire[n].virtualMods & (~wire->virtualMods)) {
1678*4882a593Smuzhiyun *nMapsRtrn = _XkbErrCode3(0x07, n, mapWire[n].virtualMods);
1679*4882a593Smuzhiyun return 0;
1680*4882a593Smuzhiyun }
1681*4882a593Smuzhiyun if (mapWire[n].level >= wire->numLevels) {
1682*4882a593Smuzhiyun *nMapsRtrn = _XkbErrCode4(0x08, n, wire->numLevels,
1683*4882a593Smuzhiyun mapWire[n].level);
1684*4882a593Smuzhiyun return 0;
1685*4882a593Smuzhiyun }
1686*4882a593Smuzhiyun if (wire->preserve) {
1687*4882a593Smuzhiyun if (client->swapped) {
1688*4882a593Smuzhiyun swaps(&preWire[n].virtualMods);
1689*4882a593Smuzhiyun }
1690*4882a593Smuzhiyun if (preWire[n].realMods & (~mapWire[n].realMods)) {
1691*4882a593Smuzhiyun *nMapsRtrn = _XkbErrCode4(0x09, n, preWire[n].realMods,
1692*4882a593Smuzhiyun mapWire[n].realMods);
1693*4882a593Smuzhiyun return 0;
1694*4882a593Smuzhiyun }
1695*4882a593Smuzhiyun if (preWire[n].virtualMods & (~mapWire[n].virtualMods)) {
1696*4882a593Smuzhiyun *nMapsRtrn =
1697*4882a593Smuzhiyun _XkbErrCode3(0x0a, n, preWire[n].virtualMods);
1698*4882a593Smuzhiyun return 0;
1699*4882a593Smuzhiyun }
1700*4882a593Smuzhiyun }
1701*4882a593Smuzhiyun }
1702*4882a593Smuzhiyun if (wire->preserve)
1703*4882a593Smuzhiyun map = (CARD8 *) &preWire[wire->nMapEntries];
1704*4882a593Smuzhiyun else
1705*4882a593Smuzhiyun map = (CARD8 *) &mapWire[wire->nMapEntries];
1706*4882a593Smuzhiyun }
1707*4882a593Smuzhiyun else
1708*4882a593Smuzhiyun map = (CARD8 *) &wire[1];
1709*4882a593Smuzhiyun mapWidthRtrn[i + req->firstType] = wire->numLevels;
1710*4882a593Smuzhiyun wire = (xkbKeyTypeWireDesc *) map;
1711*4882a593Smuzhiyun }
1712*4882a593Smuzhiyun for (i = req->firstType + req->nTypes; i < nMaps; i++) {
1713*4882a593Smuzhiyun mapWidthRtrn[i] = xkb->map->types[i].num_levels;
1714*4882a593Smuzhiyun }
1715*4882a593Smuzhiyun *nMapsRtrn = nMaps;
1716*4882a593Smuzhiyun *wireRtrn = wire;
1717*4882a593Smuzhiyun return 1;
1718*4882a593Smuzhiyun }
1719*4882a593Smuzhiyun
1720*4882a593Smuzhiyun static int
CheckKeySyms(ClientPtr client,XkbDescPtr xkb,xkbSetMapReq * req,int nTypes,CARD8 * mapWidths,CARD16 * symsPerKey,xkbSymMapWireDesc ** wireRtrn,int * errorRtrn)1721*4882a593Smuzhiyun CheckKeySyms(ClientPtr client,
1722*4882a593Smuzhiyun XkbDescPtr xkb,
1723*4882a593Smuzhiyun xkbSetMapReq * req,
1724*4882a593Smuzhiyun int nTypes,
1725*4882a593Smuzhiyun CARD8 *mapWidths,
1726*4882a593Smuzhiyun CARD16 *symsPerKey, xkbSymMapWireDesc ** wireRtrn, int *errorRtrn)
1727*4882a593Smuzhiyun {
1728*4882a593Smuzhiyun register unsigned i;
1729*4882a593Smuzhiyun XkbSymMapPtr map;
1730*4882a593Smuzhiyun xkbSymMapWireDesc *wire = *wireRtrn;
1731*4882a593Smuzhiyun
1732*4882a593Smuzhiyun if (!(XkbKeySymsMask & req->present))
1733*4882a593Smuzhiyun return 1;
1734*4882a593Smuzhiyun CHK_REQ_KEY_RANGE2(0x11, req->firstKeySym, req->nKeySyms, req, (*errorRtrn),
1735*4882a593Smuzhiyun 0);
1736*4882a593Smuzhiyun for (i = 0; i < req->nKeySyms; i++) {
1737*4882a593Smuzhiyun KeySym *pSyms;
1738*4882a593Smuzhiyun register unsigned nG;
1739*4882a593Smuzhiyun
1740*4882a593Smuzhiyun if (client->swapped) {
1741*4882a593Smuzhiyun swaps(&wire->nSyms);
1742*4882a593Smuzhiyun }
1743*4882a593Smuzhiyun nG = XkbNumGroups(wire->groupInfo);
1744*4882a593Smuzhiyun if (nG > XkbNumKbdGroups) {
1745*4882a593Smuzhiyun *errorRtrn = _XkbErrCode3(0x14, i + req->firstKeySym, nG);
1746*4882a593Smuzhiyun return 0;
1747*4882a593Smuzhiyun }
1748*4882a593Smuzhiyun if (nG > 0) {
1749*4882a593Smuzhiyun register int g, w;
1750*4882a593Smuzhiyun
1751*4882a593Smuzhiyun for (g = w = 0; g < nG; g++) {
1752*4882a593Smuzhiyun if (wire->ktIndex[g] >= (unsigned) nTypes) {
1753*4882a593Smuzhiyun *errorRtrn = _XkbErrCode4(0x15, i + req->firstKeySym, g,
1754*4882a593Smuzhiyun wire->ktIndex[g]);
1755*4882a593Smuzhiyun return 0;
1756*4882a593Smuzhiyun }
1757*4882a593Smuzhiyun if (mapWidths[wire->ktIndex[g]] > w)
1758*4882a593Smuzhiyun w = mapWidths[wire->ktIndex[g]];
1759*4882a593Smuzhiyun }
1760*4882a593Smuzhiyun if (wire->width != w) {
1761*4882a593Smuzhiyun *errorRtrn =
1762*4882a593Smuzhiyun _XkbErrCode3(0x16, i + req->firstKeySym, wire->width);
1763*4882a593Smuzhiyun return 0;
1764*4882a593Smuzhiyun }
1765*4882a593Smuzhiyun w *= nG;
1766*4882a593Smuzhiyun symsPerKey[i + req->firstKeySym] = w;
1767*4882a593Smuzhiyun if (w != wire->nSyms) {
1768*4882a593Smuzhiyun *errorRtrn =
1769*4882a593Smuzhiyun _XkbErrCode4(0x16, i + req->firstKeySym, wire->nSyms, w);
1770*4882a593Smuzhiyun return 0;
1771*4882a593Smuzhiyun }
1772*4882a593Smuzhiyun }
1773*4882a593Smuzhiyun else if (wire->nSyms != 0) {
1774*4882a593Smuzhiyun *errorRtrn = _XkbErrCode3(0x17, i + req->firstKeySym, wire->nSyms);
1775*4882a593Smuzhiyun return 0;
1776*4882a593Smuzhiyun }
1777*4882a593Smuzhiyun pSyms = (KeySym *) &wire[1];
1778*4882a593Smuzhiyun wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms];
1779*4882a593Smuzhiyun }
1780*4882a593Smuzhiyun
1781*4882a593Smuzhiyun map = &xkb->map->key_sym_map[i];
1782*4882a593Smuzhiyun for (; i <= (unsigned) xkb->max_key_code; i++, map++) {
1783*4882a593Smuzhiyun register int g, nG, w;
1784*4882a593Smuzhiyun
1785*4882a593Smuzhiyun nG = XkbKeyNumGroups(xkb, i);
1786*4882a593Smuzhiyun for (w = g = 0; g < nG; g++) {
1787*4882a593Smuzhiyun if (map->kt_index[g] >= (unsigned) nTypes) {
1788*4882a593Smuzhiyun *errorRtrn = _XkbErrCode4(0x18, i, g, map->kt_index[g]);
1789*4882a593Smuzhiyun return 0;
1790*4882a593Smuzhiyun }
1791*4882a593Smuzhiyun if (mapWidths[map->kt_index[g]] > w)
1792*4882a593Smuzhiyun w = mapWidths[map->kt_index[g]];
1793*4882a593Smuzhiyun }
1794*4882a593Smuzhiyun symsPerKey[i] = w * nG;
1795*4882a593Smuzhiyun }
1796*4882a593Smuzhiyun *wireRtrn = wire;
1797*4882a593Smuzhiyun return 1;
1798*4882a593Smuzhiyun }
1799*4882a593Smuzhiyun
1800*4882a593Smuzhiyun static int
CheckKeyActions(XkbDescPtr xkb,xkbSetMapReq * req,int nTypes,CARD8 * mapWidths,CARD16 * symsPerKey,CARD8 ** wireRtrn,int * nActsRtrn)1801*4882a593Smuzhiyun CheckKeyActions(XkbDescPtr xkb,
1802*4882a593Smuzhiyun xkbSetMapReq * req,
1803*4882a593Smuzhiyun int nTypes,
1804*4882a593Smuzhiyun CARD8 *mapWidths,
1805*4882a593Smuzhiyun CARD16 *symsPerKey, CARD8 **wireRtrn, int *nActsRtrn)
1806*4882a593Smuzhiyun {
1807*4882a593Smuzhiyun int nActs;
1808*4882a593Smuzhiyun CARD8 *wire = *wireRtrn;
1809*4882a593Smuzhiyun register unsigned i;
1810*4882a593Smuzhiyun
1811*4882a593Smuzhiyun if (!(XkbKeyActionsMask & req->present))
1812*4882a593Smuzhiyun return 1;
1813*4882a593Smuzhiyun CHK_REQ_KEY_RANGE2(0x21, req->firstKeyAct, req->nKeyActs, req, (*nActsRtrn),
1814*4882a593Smuzhiyun 0);
1815*4882a593Smuzhiyun for (nActs = i = 0; i < req->nKeyActs; i++) {
1816*4882a593Smuzhiyun if (wire[0] != 0) {
1817*4882a593Smuzhiyun if (wire[0] == symsPerKey[i + req->firstKeyAct])
1818*4882a593Smuzhiyun nActs += wire[0];
1819*4882a593Smuzhiyun else {
1820*4882a593Smuzhiyun *nActsRtrn = _XkbErrCode3(0x23, i + req->firstKeyAct, wire[0]);
1821*4882a593Smuzhiyun return 0;
1822*4882a593Smuzhiyun }
1823*4882a593Smuzhiyun }
1824*4882a593Smuzhiyun wire++;
1825*4882a593Smuzhiyun }
1826*4882a593Smuzhiyun if (req->nKeyActs % 4)
1827*4882a593Smuzhiyun wire += 4 - (req->nKeyActs % 4);
1828*4882a593Smuzhiyun *wireRtrn = (CARD8 *) (((XkbAnyAction *) wire) + nActs);
1829*4882a593Smuzhiyun *nActsRtrn = nActs;
1830*4882a593Smuzhiyun return 1;
1831*4882a593Smuzhiyun }
1832*4882a593Smuzhiyun
1833*4882a593Smuzhiyun static int
CheckKeyBehaviors(XkbDescPtr xkb,xkbSetMapReq * req,xkbBehaviorWireDesc ** wireRtrn,int * errorRtrn)1834*4882a593Smuzhiyun CheckKeyBehaviors(XkbDescPtr xkb,
1835*4882a593Smuzhiyun xkbSetMapReq * req,
1836*4882a593Smuzhiyun xkbBehaviorWireDesc ** wireRtrn, int *errorRtrn)
1837*4882a593Smuzhiyun {
1838*4882a593Smuzhiyun register xkbBehaviorWireDesc *wire = *wireRtrn;
1839*4882a593Smuzhiyun register XkbServerMapPtr server = xkb->server;
1840*4882a593Smuzhiyun register unsigned i;
1841*4882a593Smuzhiyun unsigned first, last;
1842*4882a593Smuzhiyun
1843*4882a593Smuzhiyun if (((req->present & XkbKeyBehaviorsMask) == 0) || (req->nKeyBehaviors < 1)) {
1844*4882a593Smuzhiyun req->present &= ~XkbKeyBehaviorsMask;
1845*4882a593Smuzhiyun req->nKeyBehaviors = 0;
1846*4882a593Smuzhiyun return 1;
1847*4882a593Smuzhiyun }
1848*4882a593Smuzhiyun first = req->firstKeyBehavior;
1849*4882a593Smuzhiyun last = req->firstKeyBehavior + req->nKeyBehaviors - 1;
1850*4882a593Smuzhiyun if (first < req->minKeyCode) {
1851*4882a593Smuzhiyun *errorRtrn = _XkbErrCode3(0x31, first, req->minKeyCode);
1852*4882a593Smuzhiyun return 0;
1853*4882a593Smuzhiyun }
1854*4882a593Smuzhiyun if (last > req->maxKeyCode) {
1855*4882a593Smuzhiyun *errorRtrn = _XkbErrCode3(0x32, last, req->maxKeyCode);
1856*4882a593Smuzhiyun return 0;
1857*4882a593Smuzhiyun }
1858*4882a593Smuzhiyun
1859*4882a593Smuzhiyun for (i = 0; i < req->totalKeyBehaviors; i++, wire++) {
1860*4882a593Smuzhiyun if ((wire->key < first) || (wire->key > last)) {
1861*4882a593Smuzhiyun *errorRtrn = _XkbErrCode4(0x33, first, last, wire->key);
1862*4882a593Smuzhiyun return 0;
1863*4882a593Smuzhiyun }
1864*4882a593Smuzhiyun if ((wire->type & XkbKB_Permanent) &&
1865*4882a593Smuzhiyun ((server->behaviors[wire->key].type != wire->type) ||
1866*4882a593Smuzhiyun (server->behaviors[wire->key].data != wire->data))) {
1867*4882a593Smuzhiyun *errorRtrn = _XkbErrCode3(0x33, wire->key, wire->type);
1868*4882a593Smuzhiyun return 0;
1869*4882a593Smuzhiyun }
1870*4882a593Smuzhiyun if ((wire->type == XkbKB_RadioGroup) &&
1871*4882a593Smuzhiyun ((wire->data & (~XkbKB_RGAllowNone)) > XkbMaxRadioGroups)) {
1872*4882a593Smuzhiyun *errorRtrn = _XkbErrCode4(0x34, wire->key, wire->data,
1873*4882a593Smuzhiyun XkbMaxRadioGroups);
1874*4882a593Smuzhiyun return 0;
1875*4882a593Smuzhiyun }
1876*4882a593Smuzhiyun if ((wire->type == XkbKB_Overlay1) || (wire->type == XkbKB_Overlay2)) {
1877*4882a593Smuzhiyun CHK_KEY_RANGE2(0x35, wire->key, 1, xkb, *errorRtrn, 0);
1878*4882a593Smuzhiyun }
1879*4882a593Smuzhiyun }
1880*4882a593Smuzhiyun *wireRtrn = wire;
1881*4882a593Smuzhiyun return 1;
1882*4882a593Smuzhiyun }
1883*4882a593Smuzhiyun
1884*4882a593Smuzhiyun static int
CheckVirtualMods(XkbDescRec * xkb,xkbSetMapReq * req,CARD8 ** wireRtrn,int * errorRtrn)1885*4882a593Smuzhiyun CheckVirtualMods(XkbDescRec * xkb,
1886*4882a593Smuzhiyun xkbSetMapReq * req, CARD8 **wireRtrn, int *errorRtrn)
1887*4882a593Smuzhiyun {
1888*4882a593Smuzhiyun register CARD8 *wire = *wireRtrn;
1889*4882a593Smuzhiyun register unsigned i, nMods, bit;
1890*4882a593Smuzhiyun
1891*4882a593Smuzhiyun if (((req->present & XkbVirtualModsMask) == 0) || (req->virtualMods == 0))
1892*4882a593Smuzhiyun return 1;
1893*4882a593Smuzhiyun for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
1894*4882a593Smuzhiyun if (req->virtualMods & bit)
1895*4882a593Smuzhiyun nMods++;
1896*4882a593Smuzhiyun }
1897*4882a593Smuzhiyun *wireRtrn = (wire + XkbPaddedSize(nMods));
1898*4882a593Smuzhiyun return 1;
1899*4882a593Smuzhiyun }
1900*4882a593Smuzhiyun
1901*4882a593Smuzhiyun static int
CheckKeyExplicit(XkbDescPtr xkb,xkbSetMapReq * req,CARD8 ** wireRtrn,int * errorRtrn)1902*4882a593Smuzhiyun CheckKeyExplicit(XkbDescPtr xkb,
1903*4882a593Smuzhiyun xkbSetMapReq * req, CARD8 **wireRtrn, int *errorRtrn)
1904*4882a593Smuzhiyun {
1905*4882a593Smuzhiyun register CARD8 *wire = *wireRtrn;
1906*4882a593Smuzhiyun CARD8 *start;
1907*4882a593Smuzhiyun register unsigned i;
1908*4882a593Smuzhiyun int first, last;
1909*4882a593Smuzhiyun
1910*4882a593Smuzhiyun if (((req->present & XkbExplicitComponentsMask) == 0) ||
1911*4882a593Smuzhiyun (req->nKeyExplicit < 1)) {
1912*4882a593Smuzhiyun req->present &= ~XkbExplicitComponentsMask;
1913*4882a593Smuzhiyun req->nKeyExplicit = 0;
1914*4882a593Smuzhiyun return 1;
1915*4882a593Smuzhiyun }
1916*4882a593Smuzhiyun first = req->firstKeyExplicit;
1917*4882a593Smuzhiyun last = first + req->nKeyExplicit - 1;
1918*4882a593Smuzhiyun if (first < req->minKeyCode) {
1919*4882a593Smuzhiyun *errorRtrn = _XkbErrCode3(0x51, first, req->minKeyCode);
1920*4882a593Smuzhiyun return 0;
1921*4882a593Smuzhiyun }
1922*4882a593Smuzhiyun if (last > req->maxKeyCode) {
1923*4882a593Smuzhiyun *errorRtrn = _XkbErrCode3(0x52, last, req->maxKeyCode);
1924*4882a593Smuzhiyun return 0;
1925*4882a593Smuzhiyun }
1926*4882a593Smuzhiyun start = wire;
1927*4882a593Smuzhiyun for (i = 0; i < req->totalKeyExplicit; i++, wire += 2) {
1928*4882a593Smuzhiyun if ((wire[0] < first) || (wire[0] > last)) {
1929*4882a593Smuzhiyun *errorRtrn = _XkbErrCode4(0x53, first, last, wire[0]);
1930*4882a593Smuzhiyun return 0;
1931*4882a593Smuzhiyun }
1932*4882a593Smuzhiyun if (wire[1] & (~XkbAllExplicitMask)) {
1933*4882a593Smuzhiyun *errorRtrn = _XkbErrCode3(0x52, ~XkbAllExplicitMask, wire[1]);
1934*4882a593Smuzhiyun return 0;
1935*4882a593Smuzhiyun }
1936*4882a593Smuzhiyun }
1937*4882a593Smuzhiyun wire += XkbPaddedSize(wire - start) - (wire - start);
1938*4882a593Smuzhiyun *wireRtrn = wire;
1939*4882a593Smuzhiyun return 1;
1940*4882a593Smuzhiyun }
1941*4882a593Smuzhiyun
1942*4882a593Smuzhiyun static int
CheckModifierMap(XkbDescPtr xkb,xkbSetMapReq * req,CARD8 ** wireRtrn,int * errRtrn)1943*4882a593Smuzhiyun CheckModifierMap(XkbDescPtr xkb, xkbSetMapReq * req, CARD8 **wireRtrn,
1944*4882a593Smuzhiyun int *errRtrn)
1945*4882a593Smuzhiyun {
1946*4882a593Smuzhiyun register CARD8 *wire = *wireRtrn;
1947*4882a593Smuzhiyun CARD8 *start;
1948*4882a593Smuzhiyun register unsigned i;
1949*4882a593Smuzhiyun int first, last;
1950*4882a593Smuzhiyun
1951*4882a593Smuzhiyun if (((req->present & XkbModifierMapMask) == 0) || (req->nModMapKeys < 1)) {
1952*4882a593Smuzhiyun req->present &= ~XkbModifierMapMask;
1953*4882a593Smuzhiyun req->nModMapKeys = 0;
1954*4882a593Smuzhiyun return 1;
1955*4882a593Smuzhiyun }
1956*4882a593Smuzhiyun first = req->firstModMapKey;
1957*4882a593Smuzhiyun last = first + req->nModMapKeys - 1;
1958*4882a593Smuzhiyun if (first < req->minKeyCode) {
1959*4882a593Smuzhiyun *errRtrn = _XkbErrCode3(0x61, first, req->minKeyCode);
1960*4882a593Smuzhiyun return 0;
1961*4882a593Smuzhiyun }
1962*4882a593Smuzhiyun if (last > req->maxKeyCode) {
1963*4882a593Smuzhiyun *errRtrn = _XkbErrCode3(0x62, last, req->maxKeyCode);
1964*4882a593Smuzhiyun return 0;
1965*4882a593Smuzhiyun }
1966*4882a593Smuzhiyun start = wire;
1967*4882a593Smuzhiyun for (i = 0; i < req->totalModMapKeys; i++, wire += 2) {
1968*4882a593Smuzhiyun if ((wire[0] < first) || (wire[0] > last)) {
1969*4882a593Smuzhiyun *errRtrn = _XkbErrCode4(0x63, first, last, wire[0]);
1970*4882a593Smuzhiyun return 0;
1971*4882a593Smuzhiyun }
1972*4882a593Smuzhiyun }
1973*4882a593Smuzhiyun wire += XkbPaddedSize(wire - start) - (wire - start);
1974*4882a593Smuzhiyun *wireRtrn = wire;
1975*4882a593Smuzhiyun return 1;
1976*4882a593Smuzhiyun }
1977*4882a593Smuzhiyun
1978*4882a593Smuzhiyun static int
CheckVirtualModMap(XkbDescPtr xkb,xkbSetMapReq * req,xkbVModMapWireDesc ** wireRtrn,int * errRtrn)1979*4882a593Smuzhiyun CheckVirtualModMap(XkbDescPtr xkb,
1980*4882a593Smuzhiyun xkbSetMapReq * req,
1981*4882a593Smuzhiyun xkbVModMapWireDesc ** wireRtrn, int *errRtrn)
1982*4882a593Smuzhiyun {
1983*4882a593Smuzhiyun register xkbVModMapWireDesc *wire = *wireRtrn;
1984*4882a593Smuzhiyun register unsigned i;
1985*4882a593Smuzhiyun int first, last;
1986*4882a593Smuzhiyun
1987*4882a593Smuzhiyun if (((req->present & XkbVirtualModMapMask) == 0) || (req->nVModMapKeys < 1)) {
1988*4882a593Smuzhiyun req->present &= ~XkbVirtualModMapMask;
1989*4882a593Smuzhiyun req->nVModMapKeys = 0;
1990*4882a593Smuzhiyun return 1;
1991*4882a593Smuzhiyun }
1992*4882a593Smuzhiyun first = req->firstVModMapKey;
1993*4882a593Smuzhiyun last = first + req->nVModMapKeys - 1;
1994*4882a593Smuzhiyun if (first < req->minKeyCode) {
1995*4882a593Smuzhiyun *errRtrn = _XkbErrCode3(0x71, first, req->minKeyCode);
1996*4882a593Smuzhiyun return 0;
1997*4882a593Smuzhiyun }
1998*4882a593Smuzhiyun if (last > req->maxKeyCode) {
1999*4882a593Smuzhiyun *errRtrn = _XkbErrCode3(0x72, last, req->maxKeyCode);
2000*4882a593Smuzhiyun return 0;
2001*4882a593Smuzhiyun }
2002*4882a593Smuzhiyun for (i = 0; i < req->totalVModMapKeys; i++, wire++) {
2003*4882a593Smuzhiyun if ((wire->key < first) || (wire->key > last)) {
2004*4882a593Smuzhiyun *errRtrn = _XkbErrCode4(0x73, first, last, wire->key);
2005*4882a593Smuzhiyun return 0;
2006*4882a593Smuzhiyun }
2007*4882a593Smuzhiyun }
2008*4882a593Smuzhiyun *wireRtrn = wire;
2009*4882a593Smuzhiyun return 1;
2010*4882a593Smuzhiyun }
2011*4882a593Smuzhiyun
2012*4882a593Smuzhiyun static char *
SetKeyTypes(XkbDescPtr xkb,xkbSetMapReq * req,xkbKeyTypeWireDesc * wire,XkbChangesPtr changes)2013*4882a593Smuzhiyun SetKeyTypes(XkbDescPtr xkb,
2014*4882a593Smuzhiyun xkbSetMapReq * req,
2015*4882a593Smuzhiyun xkbKeyTypeWireDesc * wire, XkbChangesPtr changes)
2016*4882a593Smuzhiyun {
2017*4882a593Smuzhiyun register unsigned i;
2018*4882a593Smuzhiyun unsigned first, last;
2019*4882a593Smuzhiyun CARD8 *map;
2020*4882a593Smuzhiyun
2021*4882a593Smuzhiyun if ((unsigned) (req->firstType + req->nTypes) > xkb->map->size_types) {
2022*4882a593Smuzhiyun i = req->firstType + req->nTypes;
2023*4882a593Smuzhiyun if (XkbAllocClientMap(xkb, XkbKeyTypesMask, i) != Success) {
2024*4882a593Smuzhiyun return NULL;
2025*4882a593Smuzhiyun }
2026*4882a593Smuzhiyun }
2027*4882a593Smuzhiyun if ((unsigned) (req->firstType + req->nTypes) > xkb->map->num_types)
2028*4882a593Smuzhiyun xkb->map->num_types = req->firstType + req->nTypes;
2029*4882a593Smuzhiyun
2030*4882a593Smuzhiyun for (i = 0; i < req->nTypes; i++) {
2031*4882a593Smuzhiyun XkbKeyTypePtr pOld;
2032*4882a593Smuzhiyun register unsigned n;
2033*4882a593Smuzhiyun
2034*4882a593Smuzhiyun if (XkbResizeKeyType(xkb, i + req->firstType, wire->nMapEntries,
2035*4882a593Smuzhiyun wire->preserve, wire->numLevels) != Success) {
2036*4882a593Smuzhiyun return NULL;
2037*4882a593Smuzhiyun }
2038*4882a593Smuzhiyun pOld = &xkb->map->types[i + req->firstType];
2039*4882a593Smuzhiyun map = (CARD8 *) &wire[1];
2040*4882a593Smuzhiyun
2041*4882a593Smuzhiyun pOld->mods.real_mods = wire->realMods;
2042*4882a593Smuzhiyun pOld->mods.vmods = wire->virtualMods;
2043*4882a593Smuzhiyun pOld->num_levels = wire->numLevels;
2044*4882a593Smuzhiyun pOld->map_count = wire->nMapEntries;
2045*4882a593Smuzhiyun
2046*4882a593Smuzhiyun pOld->mods.mask = pOld->mods.real_mods |
2047*4882a593Smuzhiyun XkbMaskForVMask(xkb, pOld->mods.vmods);
2048*4882a593Smuzhiyun
2049*4882a593Smuzhiyun if (wire->nMapEntries) {
2050*4882a593Smuzhiyun xkbKTSetMapEntryWireDesc *mapWire;
2051*4882a593Smuzhiyun xkbModsWireDesc *preWire;
2052*4882a593Smuzhiyun unsigned tmp;
2053*4882a593Smuzhiyun
2054*4882a593Smuzhiyun mapWire = (xkbKTSetMapEntryWireDesc *) map;
2055*4882a593Smuzhiyun preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries];
2056*4882a593Smuzhiyun for (n = 0; n < wire->nMapEntries; n++) {
2057*4882a593Smuzhiyun pOld->map[n].active = 1;
2058*4882a593Smuzhiyun pOld->map[n].mods.mask = mapWire[n].realMods;
2059*4882a593Smuzhiyun pOld->map[n].mods.real_mods = mapWire[n].realMods;
2060*4882a593Smuzhiyun pOld->map[n].mods.vmods = mapWire[n].virtualMods;
2061*4882a593Smuzhiyun pOld->map[n].level = mapWire[n].level;
2062*4882a593Smuzhiyun if (mapWire[n].virtualMods != 0) {
2063*4882a593Smuzhiyun tmp = XkbMaskForVMask(xkb, mapWire[n].virtualMods);
2064*4882a593Smuzhiyun pOld->map[n].active = (tmp != 0);
2065*4882a593Smuzhiyun pOld->map[n].mods.mask |= tmp;
2066*4882a593Smuzhiyun }
2067*4882a593Smuzhiyun if (wire->preserve) {
2068*4882a593Smuzhiyun pOld->preserve[n].real_mods = preWire[n].realMods;
2069*4882a593Smuzhiyun pOld->preserve[n].vmods = preWire[n].virtualMods;
2070*4882a593Smuzhiyun tmp = XkbMaskForVMask(xkb, preWire[n].virtualMods);
2071*4882a593Smuzhiyun pOld->preserve[n].mask = preWire[n].realMods | tmp;
2072*4882a593Smuzhiyun }
2073*4882a593Smuzhiyun }
2074*4882a593Smuzhiyun if (wire->preserve)
2075*4882a593Smuzhiyun map = (CARD8 *) &preWire[wire->nMapEntries];
2076*4882a593Smuzhiyun else
2077*4882a593Smuzhiyun map = (CARD8 *) &mapWire[wire->nMapEntries];
2078*4882a593Smuzhiyun }
2079*4882a593Smuzhiyun else
2080*4882a593Smuzhiyun map = (CARD8 *) &wire[1];
2081*4882a593Smuzhiyun wire = (xkbKeyTypeWireDesc *) map;
2082*4882a593Smuzhiyun }
2083*4882a593Smuzhiyun first = req->firstType;
2084*4882a593Smuzhiyun last = first + req->nTypes - 1; /* last changed type */
2085*4882a593Smuzhiyun if (changes->map.changed & XkbKeyTypesMask) {
2086*4882a593Smuzhiyun int oldLast;
2087*4882a593Smuzhiyun
2088*4882a593Smuzhiyun oldLast = changes->map.first_type + changes->map.num_types - 1;
2089*4882a593Smuzhiyun if (changes->map.first_type < first)
2090*4882a593Smuzhiyun first = changes->map.first_type;
2091*4882a593Smuzhiyun if (oldLast > last)
2092*4882a593Smuzhiyun last = oldLast;
2093*4882a593Smuzhiyun }
2094*4882a593Smuzhiyun changes->map.changed |= XkbKeyTypesMask;
2095*4882a593Smuzhiyun changes->map.first_type = first;
2096*4882a593Smuzhiyun changes->map.num_types = (last - first) + 1;
2097*4882a593Smuzhiyun return (char *) wire;
2098*4882a593Smuzhiyun }
2099*4882a593Smuzhiyun
2100*4882a593Smuzhiyun static char *
SetKeySyms(ClientPtr client,XkbDescPtr xkb,xkbSetMapReq * req,xkbSymMapWireDesc * wire,XkbChangesPtr changes,DeviceIntPtr dev)2101*4882a593Smuzhiyun SetKeySyms(ClientPtr client,
2102*4882a593Smuzhiyun XkbDescPtr xkb,
2103*4882a593Smuzhiyun xkbSetMapReq * req,
2104*4882a593Smuzhiyun xkbSymMapWireDesc * wire, XkbChangesPtr changes, DeviceIntPtr dev)
2105*4882a593Smuzhiyun {
2106*4882a593Smuzhiyun register unsigned i, s;
2107*4882a593Smuzhiyun XkbSymMapPtr oldMap;
2108*4882a593Smuzhiyun KeySym *newSyms;
2109*4882a593Smuzhiyun KeySym *pSyms;
2110*4882a593Smuzhiyun unsigned first, last;
2111*4882a593Smuzhiyun
2112*4882a593Smuzhiyun oldMap = &xkb->map->key_sym_map[req->firstKeySym];
2113*4882a593Smuzhiyun for (i = 0; i < req->nKeySyms; i++, oldMap++) {
2114*4882a593Smuzhiyun pSyms = (KeySym *) &wire[1];
2115*4882a593Smuzhiyun if (wire->nSyms > 0) {
2116*4882a593Smuzhiyun newSyms = XkbResizeKeySyms(xkb, i + req->firstKeySym, wire->nSyms);
2117*4882a593Smuzhiyun for (s = 0; s < wire->nSyms; s++) {
2118*4882a593Smuzhiyun newSyms[s] = pSyms[s];
2119*4882a593Smuzhiyun }
2120*4882a593Smuzhiyun if (client->swapped) {
2121*4882a593Smuzhiyun for (s = 0; s < wire->nSyms; s++) {
2122*4882a593Smuzhiyun swapl(&newSyms[s]);
2123*4882a593Smuzhiyun }
2124*4882a593Smuzhiyun }
2125*4882a593Smuzhiyun }
2126*4882a593Smuzhiyun if (XkbKeyHasActions(xkb, i + req->firstKeySym))
2127*4882a593Smuzhiyun XkbResizeKeyActions(xkb, i + req->firstKeySym,
2128*4882a593Smuzhiyun XkbNumGroups(wire->groupInfo) * wire->width);
2129*4882a593Smuzhiyun oldMap->kt_index[0] = wire->ktIndex[0];
2130*4882a593Smuzhiyun oldMap->kt_index[1] = wire->ktIndex[1];
2131*4882a593Smuzhiyun oldMap->kt_index[2] = wire->ktIndex[2];
2132*4882a593Smuzhiyun oldMap->kt_index[3] = wire->ktIndex[3];
2133*4882a593Smuzhiyun oldMap->group_info = wire->groupInfo;
2134*4882a593Smuzhiyun oldMap->width = wire->width;
2135*4882a593Smuzhiyun wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms];
2136*4882a593Smuzhiyun }
2137*4882a593Smuzhiyun first = req->firstKeySym;
2138*4882a593Smuzhiyun last = first + req->nKeySyms - 1;
2139*4882a593Smuzhiyun if (changes->map.changed & XkbKeySymsMask) {
2140*4882a593Smuzhiyun int oldLast =
2141*4882a593Smuzhiyun (changes->map.first_key_sym + changes->map.num_key_syms - 1);
2142*4882a593Smuzhiyun if (changes->map.first_key_sym < first)
2143*4882a593Smuzhiyun first = changes->map.first_key_sym;
2144*4882a593Smuzhiyun if (oldLast > last)
2145*4882a593Smuzhiyun last = oldLast;
2146*4882a593Smuzhiyun }
2147*4882a593Smuzhiyun changes->map.changed |= XkbKeySymsMask;
2148*4882a593Smuzhiyun changes->map.first_key_sym = first;
2149*4882a593Smuzhiyun changes->map.num_key_syms = (last - first + 1);
2150*4882a593Smuzhiyun
2151*4882a593Smuzhiyun s = 0;
2152*4882a593Smuzhiyun for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
2153*4882a593Smuzhiyun if (XkbKeyNumGroups(xkb, i) > s)
2154*4882a593Smuzhiyun s = XkbKeyNumGroups(xkb, i);
2155*4882a593Smuzhiyun }
2156*4882a593Smuzhiyun if (s != xkb->ctrls->num_groups) {
2157*4882a593Smuzhiyun xkbControlsNotify cn;
2158*4882a593Smuzhiyun XkbControlsRec old;
2159*4882a593Smuzhiyun
2160*4882a593Smuzhiyun cn.keycode = 0;
2161*4882a593Smuzhiyun cn.eventType = 0;
2162*4882a593Smuzhiyun cn.requestMajor = XkbReqCode;
2163*4882a593Smuzhiyun cn.requestMinor = X_kbSetMap;
2164*4882a593Smuzhiyun old = *xkb->ctrls;
2165*4882a593Smuzhiyun xkb->ctrls->num_groups = s;
2166*4882a593Smuzhiyun if (XkbComputeControlsNotify(dev, &old, xkb->ctrls, &cn, FALSE))
2167*4882a593Smuzhiyun XkbSendControlsNotify(dev, &cn);
2168*4882a593Smuzhiyun }
2169*4882a593Smuzhiyun return (char *) wire;
2170*4882a593Smuzhiyun }
2171*4882a593Smuzhiyun
2172*4882a593Smuzhiyun static char *
SetKeyActions(XkbDescPtr xkb,xkbSetMapReq * req,CARD8 * wire,XkbChangesPtr changes)2173*4882a593Smuzhiyun SetKeyActions(XkbDescPtr xkb,
2174*4882a593Smuzhiyun xkbSetMapReq * req, CARD8 *wire, XkbChangesPtr changes)
2175*4882a593Smuzhiyun {
2176*4882a593Smuzhiyun register unsigned i, first, last;
2177*4882a593Smuzhiyun CARD8 *nActs = wire;
2178*4882a593Smuzhiyun XkbAction *newActs;
2179*4882a593Smuzhiyun
2180*4882a593Smuzhiyun wire += XkbPaddedSize(req->nKeyActs);
2181*4882a593Smuzhiyun for (i = 0; i < req->nKeyActs; i++) {
2182*4882a593Smuzhiyun if (nActs[i] == 0)
2183*4882a593Smuzhiyun xkb->server->key_acts[i + req->firstKeyAct] = 0;
2184*4882a593Smuzhiyun else {
2185*4882a593Smuzhiyun newActs = XkbResizeKeyActions(xkb, i + req->firstKeyAct, nActs[i]);
2186*4882a593Smuzhiyun memcpy((char *) newActs, (char *) wire,
2187*4882a593Smuzhiyun nActs[i] * SIZEOF(xkbActionWireDesc));
2188*4882a593Smuzhiyun wire += nActs[i] * SIZEOF(xkbActionWireDesc);
2189*4882a593Smuzhiyun }
2190*4882a593Smuzhiyun }
2191*4882a593Smuzhiyun first = req->firstKeyAct;
2192*4882a593Smuzhiyun last = (first + req->nKeyActs - 1);
2193*4882a593Smuzhiyun if (changes->map.changed & XkbKeyActionsMask) {
2194*4882a593Smuzhiyun int oldLast;
2195*4882a593Smuzhiyun
2196*4882a593Smuzhiyun oldLast = changes->map.first_key_act + changes->map.num_key_acts - 1;
2197*4882a593Smuzhiyun if (changes->map.first_key_act < first)
2198*4882a593Smuzhiyun first = changes->map.first_key_act;
2199*4882a593Smuzhiyun if (oldLast > last)
2200*4882a593Smuzhiyun last = oldLast;
2201*4882a593Smuzhiyun }
2202*4882a593Smuzhiyun changes->map.changed |= XkbKeyActionsMask;
2203*4882a593Smuzhiyun changes->map.first_key_act = first;
2204*4882a593Smuzhiyun changes->map.num_key_acts = (last - first + 1);
2205*4882a593Smuzhiyun return (char *) wire;
2206*4882a593Smuzhiyun }
2207*4882a593Smuzhiyun
2208*4882a593Smuzhiyun static char *
SetKeyBehaviors(XkbSrvInfoPtr xkbi,xkbSetMapReq * req,xkbBehaviorWireDesc * wire,XkbChangesPtr changes)2209*4882a593Smuzhiyun SetKeyBehaviors(XkbSrvInfoPtr xkbi,
2210*4882a593Smuzhiyun xkbSetMapReq * req,
2211*4882a593Smuzhiyun xkbBehaviorWireDesc * wire, XkbChangesPtr changes)
2212*4882a593Smuzhiyun {
2213*4882a593Smuzhiyun register unsigned i;
2214*4882a593Smuzhiyun int maxRG = -1;
2215*4882a593Smuzhiyun XkbDescPtr xkb = xkbi->desc;
2216*4882a593Smuzhiyun XkbServerMapPtr server = xkb->server;
2217*4882a593Smuzhiyun unsigned first, last;
2218*4882a593Smuzhiyun
2219*4882a593Smuzhiyun first = req->firstKeyBehavior;
2220*4882a593Smuzhiyun last = req->firstKeyBehavior + req->nKeyBehaviors - 1;
2221*4882a593Smuzhiyun memset(&server->behaviors[first], 0,
2222*4882a593Smuzhiyun req->nKeyBehaviors * sizeof(XkbBehavior));
2223*4882a593Smuzhiyun for (i = 0; i < req->totalKeyBehaviors; i++) {
2224*4882a593Smuzhiyun if ((server->behaviors[wire->key].type & XkbKB_Permanent) == 0) {
2225*4882a593Smuzhiyun server->behaviors[wire->key].type = wire->type;
2226*4882a593Smuzhiyun server->behaviors[wire->key].data = wire->data;
2227*4882a593Smuzhiyun if ((wire->type == XkbKB_RadioGroup) &&
2228*4882a593Smuzhiyun (((int) wire->data) > maxRG))
2229*4882a593Smuzhiyun maxRG = wire->data + 1;
2230*4882a593Smuzhiyun }
2231*4882a593Smuzhiyun wire++;
2232*4882a593Smuzhiyun }
2233*4882a593Smuzhiyun
2234*4882a593Smuzhiyun if (maxRG > (int) xkbi->nRadioGroups) {
2235*4882a593Smuzhiyun if (xkbi->radioGroups)
2236*4882a593Smuzhiyun xkbi->radioGroups = reallocarray(xkbi->radioGroups, maxRG,
2237*4882a593Smuzhiyun sizeof(XkbRadioGroupRec));
2238*4882a593Smuzhiyun else
2239*4882a593Smuzhiyun xkbi->radioGroups = calloc(maxRG, sizeof(XkbRadioGroupRec));
2240*4882a593Smuzhiyun if (xkbi->radioGroups) {
2241*4882a593Smuzhiyun if (xkbi->nRadioGroups)
2242*4882a593Smuzhiyun memset(&xkbi->radioGroups[xkbi->nRadioGroups], 0,
2243*4882a593Smuzhiyun (maxRG - xkbi->nRadioGroups) * sizeof(XkbRadioGroupRec));
2244*4882a593Smuzhiyun xkbi->nRadioGroups = maxRG;
2245*4882a593Smuzhiyun }
2246*4882a593Smuzhiyun else
2247*4882a593Smuzhiyun xkbi->nRadioGroups = 0;
2248*4882a593Smuzhiyun /* should compute members here */
2249*4882a593Smuzhiyun }
2250*4882a593Smuzhiyun if (changes->map.changed & XkbKeyBehaviorsMask) {
2251*4882a593Smuzhiyun unsigned oldLast;
2252*4882a593Smuzhiyun
2253*4882a593Smuzhiyun oldLast = changes->map.first_key_behavior +
2254*4882a593Smuzhiyun changes->map.num_key_behaviors - 1;
2255*4882a593Smuzhiyun if (changes->map.first_key_behavior < req->firstKeyBehavior)
2256*4882a593Smuzhiyun first = changes->map.first_key_behavior;
2257*4882a593Smuzhiyun if (oldLast > last)
2258*4882a593Smuzhiyun last = oldLast;
2259*4882a593Smuzhiyun }
2260*4882a593Smuzhiyun changes->map.changed |= XkbKeyBehaviorsMask;
2261*4882a593Smuzhiyun changes->map.first_key_behavior = first;
2262*4882a593Smuzhiyun changes->map.num_key_behaviors = (last - first + 1);
2263*4882a593Smuzhiyun return (char *) wire;
2264*4882a593Smuzhiyun }
2265*4882a593Smuzhiyun
2266*4882a593Smuzhiyun static char *
SetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq * req,CARD8 * wire,XkbChangesPtr changes)2267*4882a593Smuzhiyun SetVirtualMods(XkbSrvInfoPtr xkbi, xkbSetMapReq * req, CARD8 *wire,
2268*4882a593Smuzhiyun XkbChangesPtr changes)
2269*4882a593Smuzhiyun {
2270*4882a593Smuzhiyun register int i, bit, nMods;
2271*4882a593Smuzhiyun XkbServerMapPtr srv = xkbi->desc->server;
2272*4882a593Smuzhiyun
2273*4882a593Smuzhiyun if (((req->present & XkbVirtualModsMask) == 0) || (req->virtualMods == 0))
2274*4882a593Smuzhiyun return (char *) wire;
2275*4882a593Smuzhiyun for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
2276*4882a593Smuzhiyun if (req->virtualMods & bit) {
2277*4882a593Smuzhiyun if (srv->vmods[i] != wire[nMods]) {
2278*4882a593Smuzhiyun changes->map.changed |= XkbVirtualModsMask;
2279*4882a593Smuzhiyun changes->map.vmods |= bit;
2280*4882a593Smuzhiyun srv->vmods[i] = wire[nMods];
2281*4882a593Smuzhiyun }
2282*4882a593Smuzhiyun nMods++;
2283*4882a593Smuzhiyun }
2284*4882a593Smuzhiyun }
2285*4882a593Smuzhiyun return (char *) (wire + XkbPaddedSize(nMods));
2286*4882a593Smuzhiyun }
2287*4882a593Smuzhiyun
2288*4882a593Smuzhiyun static char *
SetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq * req,CARD8 * wire,XkbChangesPtr changes)2289*4882a593Smuzhiyun SetKeyExplicit(XkbSrvInfoPtr xkbi, xkbSetMapReq * req, CARD8 *wire,
2290*4882a593Smuzhiyun XkbChangesPtr changes)
2291*4882a593Smuzhiyun {
2292*4882a593Smuzhiyun register unsigned i, first, last;
2293*4882a593Smuzhiyun XkbServerMapPtr xkb = xkbi->desc->server;
2294*4882a593Smuzhiyun CARD8 *start;
2295*4882a593Smuzhiyun
2296*4882a593Smuzhiyun start = wire;
2297*4882a593Smuzhiyun first = req->firstKeyExplicit;
2298*4882a593Smuzhiyun last = req->firstKeyExplicit + req->nKeyExplicit - 1;
2299*4882a593Smuzhiyun memset(&xkb->explicit[first], 0, req->nKeyExplicit);
2300*4882a593Smuzhiyun for (i = 0; i < req->totalKeyExplicit; i++, wire += 2) {
2301*4882a593Smuzhiyun xkb->explicit[wire[0]] = wire[1];
2302*4882a593Smuzhiyun }
2303*4882a593Smuzhiyun if (first > 0) {
2304*4882a593Smuzhiyun if (changes->map.changed & XkbExplicitComponentsMask) {
2305*4882a593Smuzhiyun int oldLast;
2306*4882a593Smuzhiyun
2307*4882a593Smuzhiyun oldLast = changes->map.first_key_explicit +
2308*4882a593Smuzhiyun changes->map.num_key_explicit - 1;
2309*4882a593Smuzhiyun if (changes->map.first_key_explicit < first)
2310*4882a593Smuzhiyun first = changes->map.first_key_explicit;
2311*4882a593Smuzhiyun if (oldLast > last)
2312*4882a593Smuzhiyun last = oldLast;
2313*4882a593Smuzhiyun }
2314*4882a593Smuzhiyun changes->map.first_key_explicit = first;
2315*4882a593Smuzhiyun changes->map.num_key_explicit = (last - first) + 1;
2316*4882a593Smuzhiyun }
2317*4882a593Smuzhiyun wire += XkbPaddedSize(wire - start) - (wire - start);
2318*4882a593Smuzhiyun return (char *) wire;
2319*4882a593Smuzhiyun }
2320*4882a593Smuzhiyun
2321*4882a593Smuzhiyun static char *
SetModifierMap(XkbSrvInfoPtr xkbi,xkbSetMapReq * req,CARD8 * wire,XkbChangesPtr changes)2322*4882a593Smuzhiyun SetModifierMap(XkbSrvInfoPtr xkbi,
2323*4882a593Smuzhiyun xkbSetMapReq * req, CARD8 *wire, XkbChangesPtr changes)
2324*4882a593Smuzhiyun {
2325*4882a593Smuzhiyun register unsigned i, first, last;
2326*4882a593Smuzhiyun XkbClientMapPtr xkb = xkbi->desc->map;
2327*4882a593Smuzhiyun CARD8 *start;
2328*4882a593Smuzhiyun
2329*4882a593Smuzhiyun start = wire;
2330*4882a593Smuzhiyun first = req->firstModMapKey;
2331*4882a593Smuzhiyun last = req->firstModMapKey + req->nModMapKeys - 1;
2332*4882a593Smuzhiyun memset(&xkb->modmap[first], 0, req->nModMapKeys);
2333*4882a593Smuzhiyun for (i = 0; i < req->totalModMapKeys; i++, wire += 2) {
2334*4882a593Smuzhiyun xkb->modmap[wire[0]] = wire[1];
2335*4882a593Smuzhiyun }
2336*4882a593Smuzhiyun if (first > 0) {
2337*4882a593Smuzhiyun if (changes->map.changed & XkbModifierMapMask) {
2338*4882a593Smuzhiyun int oldLast;
2339*4882a593Smuzhiyun
2340*4882a593Smuzhiyun oldLast = changes->map.first_modmap_key +
2341*4882a593Smuzhiyun changes->map.num_modmap_keys - 1;
2342*4882a593Smuzhiyun if (changes->map.first_modmap_key < first)
2343*4882a593Smuzhiyun first = changes->map.first_modmap_key;
2344*4882a593Smuzhiyun if (oldLast > last)
2345*4882a593Smuzhiyun last = oldLast;
2346*4882a593Smuzhiyun }
2347*4882a593Smuzhiyun changes->map.first_modmap_key = first;
2348*4882a593Smuzhiyun changes->map.num_modmap_keys = (last - first) + 1;
2349*4882a593Smuzhiyun }
2350*4882a593Smuzhiyun wire += XkbPaddedSize(wire - start) - (wire - start);
2351*4882a593Smuzhiyun return (char *) wire;
2352*4882a593Smuzhiyun }
2353*4882a593Smuzhiyun
2354*4882a593Smuzhiyun static char *
SetVirtualModMap(XkbSrvInfoPtr xkbi,xkbSetMapReq * req,xkbVModMapWireDesc * wire,XkbChangesPtr changes)2355*4882a593Smuzhiyun SetVirtualModMap(XkbSrvInfoPtr xkbi,
2356*4882a593Smuzhiyun xkbSetMapReq * req,
2357*4882a593Smuzhiyun xkbVModMapWireDesc * wire, XkbChangesPtr changes)
2358*4882a593Smuzhiyun {
2359*4882a593Smuzhiyun register unsigned i, first, last;
2360*4882a593Smuzhiyun XkbServerMapPtr srv = xkbi->desc->server;
2361*4882a593Smuzhiyun
2362*4882a593Smuzhiyun first = req->firstVModMapKey;
2363*4882a593Smuzhiyun last = req->firstVModMapKey + req->nVModMapKeys - 1;
2364*4882a593Smuzhiyun memset(&srv->vmodmap[first], 0, req->nVModMapKeys * sizeof(unsigned short));
2365*4882a593Smuzhiyun for (i = 0; i < req->totalVModMapKeys; i++, wire++) {
2366*4882a593Smuzhiyun srv->vmodmap[wire->key] = wire->vmods;
2367*4882a593Smuzhiyun }
2368*4882a593Smuzhiyun if (first > 0) {
2369*4882a593Smuzhiyun if (changes->map.changed & XkbVirtualModMapMask) {
2370*4882a593Smuzhiyun int oldLast;
2371*4882a593Smuzhiyun
2372*4882a593Smuzhiyun oldLast = changes->map.first_vmodmap_key +
2373*4882a593Smuzhiyun changes->map.num_vmodmap_keys - 1;
2374*4882a593Smuzhiyun if (changes->map.first_vmodmap_key < first)
2375*4882a593Smuzhiyun first = changes->map.first_vmodmap_key;
2376*4882a593Smuzhiyun if (oldLast > last)
2377*4882a593Smuzhiyun last = oldLast;
2378*4882a593Smuzhiyun }
2379*4882a593Smuzhiyun changes->map.first_vmodmap_key = first;
2380*4882a593Smuzhiyun changes->map.num_vmodmap_keys = (last - first) + 1;
2381*4882a593Smuzhiyun }
2382*4882a593Smuzhiyun return (char *) wire;
2383*4882a593Smuzhiyun }
2384*4882a593Smuzhiyun
2385*4882a593Smuzhiyun #define _add_check_len(new) \
2386*4882a593Smuzhiyun if (len > UINT32_MAX - (new) || len > req_len - (new)) goto bad; \
2387*4882a593Smuzhiyun else len += new
2388*4882a593Smuzhiyun
2389*4882a593Smuzhiyun /**
2390*4882a593Smuzhiyun * Check the length of the SetMap request
2391*4882a593Smuzhiyun */
2392*4882a593Smuzhiyun static int
_XkbSetMapCheckLength(xkbSetMapReq * req)2393*4882a593Smuzhiyun _XkbSetMapCheckLength(xkbSetMapReq *req)
2394*4882a593Smuzhiyun {
2395*4882a593Smuzhiyun size_t len = sz_xkbSetMapReq, req_len = req->length << 2;
2396*4882a593Smuzhiyun xkbKeyTypeWireDesc *keytype;
2397*4882a593Smuzhiyun xkbSymMapWireDesc *symmap;
2398*4882a593Smuzhiyun BOOL preserve;
2399*4882a593Smuzhiyun int i, map_count, nSyms;
2400*4882a593Smuzhiyun
2401*4882a593Smuzhiyun if (req_len < len)
2402*4882a593Smuzhiyun goto bad;
2403*4882a593Smuzhiyun /* types */
2404*4882a593Smuzhiyun if (req->present & XkbKeyTypesMask) {
2405*4882a593Smuzhiyun keytype = (xkbKeyTypeWireDesc *)(req + 1);
2406*4882a593Smuzhiyun for (i = 0; i < req->nTypes; i++) {
2407*4882a593Smuzhiyun _add_check_len(XkbPaddedSize(sz_xkbKeyTypeWireDesc));
2408*4882a593Smuzhiyun if (req->flags & XkbSetMapResizeTypes) {
2409*4882a593Smuzhiyun _add_check_len(keytype->nMapEntries
2410*4882a593Smuzhiyun * sz_xkbKTSetMapEntryWireDesc);
2411*4882a593Smuzhiyun preserve = keytype->preserve;
2412*4882a593Smuzhiyun map_count = keytype->nMapEntries;
2413*4882a593Smuzhiyun if (preserve) {
2414*4882a593Smuzhiyun _add_check_len(map_count * sz_xkbModsWireDesc);
2415*4882a593Smuzhiyun }
2416*4882a593Smuzhiyun keytype += 1;
2417*4882a593Smuzhiyun keytype = (xkbKeyTypeWireDesc *)
2418*4882a593Smuzhiyun ((xkbKTSetMapEntryWireDesc *)keytype + map_count);
2419*4882a593Smuzhiyun if (preserve)
2420*4882a593Smuzhiyun keytype = (xkbKeyTypeWireDesc *)
2421*4882a593Smuzhiyun ((xkbModsWireDesc *)keytype + map_count);
2422*4882a593Smuzhiyun }
2423*4882a593Smuzhiyun }
2424*4882a593Smuzhiyun }
2425*4882a593Smuzhiyun /* syms */
2426*4882a593Smuzhiyun if (req->present & XkbKeySymsMask) {
2427*4882a593Smuzhiyun symmap = (xkbSymMapWireDesc *)((char *)req + len);
2428*4882a593Smuzhiyun for (i = 0; i < req->nKeySyms; i++) {
2429*4882a593Smuzhiyun _add_check_len(sz_xkbSymMapWireDesc);
2430*4882a593Smuzhiyun nSyms = symmap->nSyms;
2431*4882a593Smuzhiyun _add_check_len(nSyms*sizeof(CARD32));
2432*4882a593Smuzhiyun symmap += 1;
2433*4882a593Smuzhiyun symmap = (xkbSymMapWireDesc *)((CARD32 *)symmap + nSyms);
2434*4882a593Smuzhiyun }
2435*4882a593Smuzhiyun }
2436*4882a593Smuzhiyun /* actions */
2437*4882a593Smuzhiyun if (req->present & XkbKeyActionsMask) {
2438*4882a593Smuzhiyun _add_check_len(req->totalActs * sz_xkbActionWireDesc
2439*4882a593Smuzhiyun + XkbPaddedSize(req->nKeyActs));
2440*4882a593Smuzhiyun }
2441*4882a593Smuzhiyun /* behaviours */
2442*4882a593Smuzhiyun if (req->present & XkbKeyBehaviorsMask) {
2443*4882a593Smuzhiyun _add_check_len(req->totalKeyBehaviors * sz_xkbBehaviorWireDesc);
2444*4882a593Smuzhiyun }
2445*4882a593Smuzhiyun /* vmods */
2446*4882a593Smuzhiyun if (req->present & XkbVirtualModsMask) {
2447*4882a593Smuzhiyun _add_check_len(XkbPaddedSize(Ones(req->virtualMods)));
2448*4882a593Smuzhiyun }
2449*4882a593Smuzhiyun /* explicit */
2450*4882a593Smuzhiyun if (req->present & XkbExplicitComponentsMask) {
2451*4882a593Smuzhiyun /* two bytes per non-zero explicit componen */
2452*4882a593Smuzhiyun _add_check_len(XkbPaddedSize(req->totalKeyExplicit * sizeof(CARD16)));
2453*4882a593Smuzhiyun }
2454*4882a593Smuzhiyun /* modmap */
2455*4882a593Smuzhiyun if (req->present & XkbModifierMapMask) {
2456*4882a593Smuzhiyun /* two bytes per non-zero modmap component */
2457*4882a593Smuzhiyun _add_check_len(XkbPaddedSize(req->totalModMapKeys * sizeof(CARD16)));
2458*4882a593Smuzhiyun }
2459*4882a593Smuzhiyun /* vmodmap */
2460*4882a593Smuzhiyun if (req->present & XkbVirtualModMapMask) {
2461*4882a593Smuzhiyun _add_check_len(req->totalVModMapKeys * sz_xkbVModMapWireDesc);
2462*4882a593Smuzhiyun }
2463*4882a593Smuzhiyun if (len == req_len)
2464*4882a593Smuzhiyun return Success;
2465*4882a593Smuzhiyun bad:
2466*4882a593Smuzhiyun ErrorF("[xkb] BOGUS LENGTH in SetMap: expected %ld got %ld\n",
2467*4882a593Smuzhiyun len, req_len);
2468*4882a593Smuzhiyun return BadLength;
2469*4882a593Smuzhiyun }
2470*4882a593Smuzhiyun
2471*4882a593Smuzhiyun
2472*4882a593Smuzhiyun /**
2473*4882a593Smuzhiyun * Check if the given request can be applied to the given device but don't
2474*4882a593Smuzhiyun * actually do anything..
2475*4882a593Smuzhiyun */
2476*4882a593Smuzhiyun static int
_XkbSetMapChecks(ClientPtr client,DeviceIntPtr dev,xkbSetMapReq * req,char * values)2477*4882a593Smuzhiyun _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
2478*4882a593Smuzhiyun char *values)
2479*4882a593Smuzhiyun {
2480*4882a593Smuzhiyun XkbSrvInfoPtr xkbi;
2481*4882a593Smuzhiyun XkbDescPtr xkb;
2482*4882a593Smuzhiyun int error;
2483*4882a593Smuzhiyun int nTypes = 0, nActions;
2484*4882a593Smuzhiyun CARD8 mapWidths[XkbMaxLegalKeyCode + 1] = { 0 };
2485*4882a593Smuzhiyun CARD16 symsPerKey[XkbMaxLegalKeyCode + 1] = { 0 };
2486*4882a593Smuzhiyun XkbSymMapPtr map;
2487*4882a593Smuzhiyun int i;
2488*4882a593Smuzhiyun
2489*4882a593Smuzhiyun if (!dev->key)
2490*4882a593Smuzhiyun return 0;
2491*4882a593Smuzhiyun
2492*4882a593Smuzhiyun xkbi = dev->key->xkbInfo;
2493*4882a593Smuzhiyun xkb = xkbi->desc;
2494*4882a593Smuzhiyun
2495*4882a593Smuzhiyun if ((xkb->min_key_code != req->minKeyCode) ||
2496*4882a593Smuzhiyun (xkb->max_key_code != req->maxKeyCode)) {
2497*4882a593Smuzhiyun if (client->xkbClientFlags & _XkbClientIsAncient) {
2498*4882a593Smuzhiyun /* pre 1.0 versions of Xlib have a bug */
2499*4882a593Smuzhiyun req->minKeyCode = xkb->min_key_code;
2500*4882a593Smuzhiyun req->maxKeyCode = xkb->max_key_code;
2501*4882a593Smuzhiyun }
2502*4882a593Smuzhiyun else {
2503*4882a593Smuzhiyun if (!XkbIsLegalKeycode(req->minKeyCode)) {
2504*4882a593Smuzhiyun client->errorValue =
2505*4882a593Smuzhiyun _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode);
2506*4882a593Smuzhiyun return BadValue;
2507*4882a593Smuzhiyun }
2508*4882a593Smuzhiyun if (req->minKeyCode > req->maxKeyCode) {
2509*4882a593Smuzhiyun client->errorValue =
2510*4882a593Smuzhiyun _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode);
2511*4882a593Smuzhiyun return BadMatch;
2512*4882a593Smuzhiyun }
2513*4882a593Smuzhiyun }
2514*4882a593Smuzhiyun }
2515*4882a593Smuzhiyun
2516*4882a593Smuzhiyun if ((req->present & XkbKeyTypesMask) &&
2517*4882a593Smuzhiyun (!CheckKeyTypes(client, xkb, req, (xkbKeyTypeWireDesc **) &values,
2518*4882a593Smuzhiyun &nTypes, mapWidths))) {
2519*4882a593Smuzhiyun client->errorValue = nTypes;
2520*4882a593Smuzhiyun return BadValue;
2521*4882a593Smuzhiyun }
2522*4882a593Smuzhiyun
2523*4882a593Smuzhiyun /* symsPerKey/mapWidths must be filled regardless of client-side flags */
2524*4882a593Smuzhiyun map = &xkb->map->key_sym_map[xkb->min_key_code];
2525*4882a593Smuzhiyun for (i = xkb->min_key_code; i < xkb->max_key_code; i++, map++) {
2526*4882a593Smuzhiyun register int g, ng, w;
2527*4882a593Smuzhiyun
2528*4882a593Smuzhiyun ng = XkbNumGroups(map->group_info);
2529*4882a593Smuzhiyun for (w = g = 0; g < ng; g++) {
2530*4882a593Smuzhiyun if (map->kt_index[g] >= (unsigned) nTypes) {
2531*4882a593Smuzhiyun client->errorValue = _XkbErrCode4(0x13, i, g, map->kt_index[g]);
2532*4882a593Smuzhiyun return 0;
2533*4882a593Smuzhiyun }
2534*4882a593Smuzhiyun if (mapWidths[map->kt_index[g]] > w)
2535*4882a593Smuzhiyun w = mapWidths[map->kt_index[g]];
2536*4882a593Smuzhiyun }
2537*4882a593Smuzhiyun symsPerKey[i] = w * ng;
2538*4882a593Smuzhiyun }
2539*4882a593Smuzhiyun
2540*4882a593Smuzhiyun if ((req->present & XkbKeySymsMask) &&
2541*4882a593Smuzhiyun (!CheckKeySyms(client, xkb, req, nTypes, mapWidths, symsPerKey,
2542*4882a593Smuzhiyun (xkbSymMapWireDesc **) &values, &error))) {
2543*4882a593Smuzhiyun client->errorValue = error;
2544*4882a593Smuzhiyun return BadValue;
2545*4882a593Smuzhiyun }
2546*4882a593Smuzhiyun
2547*4882a593Smuzhiyun if ((req->present & XkbKeyActionsMask) &&
2548*4882a593Smuzhiyun (!CheckKeyActions(xkb, req, nTypes, mapWidths, symsPerKey,
2549*4882a593Smuzhiyun (CARD8 **) &values, &nActions))) {
2550*4882a593Smuzhiyun client->errorValue = nActions;
2551*4882a593Smuzhiyun return BadValue;
2552*4882a593Smuzhiyun }
2553*4882a593Smuzhiyun
2554*4882a593Smuzhiyun if ((req->present & XkbKeyBehaviorsMask) &&
2555*4882a593Smuzhiyun (!CheckKeyBehaviors
2556*4882a593Smuzhiyun (xkb, req, (xkbBehaviorWireDesc **) &values, &error))) {
2557*4882a593Smuzhiyun client->errorValue = error;
2558*4882a593Smuzhiyun return BadValue;
2559*4882a593Smuzhiyun }
2560*4882a593Smuzhiyun
2561*4882a593Smuzhiyun if ((req->present & XkbVirtualModsMask) &&
2562*4882a593Smuzhiyun (!CheckVirtualMods(xkb, req, (CARD8 **) &values, &error))) {
2563*4882a593Smuzhiyun client->errorValue = error;
2564*4882a593Smuzhiyun return BadValue;
2565*4882a593Smuzhiyun }
2566*4882a593Smuzhiyun if ((req->present & XkbExplicitComponentsMask) &&
2567*4882a593Smuzhiyun (!CheckKeyExplicit(xkb, req, (CARD8 **) &values, &error))) {
2568*4882a593Smuzhiyun client->errorValue = error;
2569*4882a593Smuzhiyun return BadValue;
2570*4882a593Smuzhiyun }
2571*4882a593Smuzhiyun if ((req->present & XkbModifierMapMask) &&
2572*4882a593Smuzhiyun (!CheckModifierMap(xkb, req, (CARD8 **) &values, &error))) {
2573*4882a593Smuzhiyun client->errorValue = error;
2574*4882a593Smuzhiyun return BadValue;
2575*4882a593Smuzhiyun }
2576*4882a593Smuzhiyun if ((req->present & XkbVirtualModMapMask) &&
2577*4882a593Smuzhiyun (!CheckVirtualModMap
2578*4882a593Smuzhiyun (xkb, req, (xkbVModMapWireDesc **) &values, &error))) {
2579*4882a593Smuzhiyun client->errorValue = error;
2580*4882a593Smuzhiyun return BadValue;
2581*4882a593Smuzhiyun }
2582*4882a593Smuzhiyun
2583*4882a593Smuzhiyun if (((values - ((char *) req)) / 4) != req->length) {
2584*4882a593Smuzhiyun ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n");
2585*4882a593Smuzhiyun client->errorValue = values - ((char *) &req[1]);
2586*4882a593Smuzhiyun return BadLength;
2587*4882a593Smuzhiyun }
2588*4882a593Smuzhiyun
2589*4882a593Smuzhiyun return Success;
2590*4882a593Smuzhiyun }
2591*4882a593Smuzhiyun
2592*4882a593Smuzhiyun /**
2593*4882a593Smuzhiyun * Apply the given request on the given device.
2594*4882a593Smuzhiyun */
2595*4882a593Smuzhiyun static int
_XkbSetMap(ClientPtr client,DeviceIntPtr dev,xkbSetMapReq * req,char * values)2596*4882a593Smuzhiyun _XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, char *values)
2597*4882a593Smuzhiyun {
2598*4882a593Smuzhiyun XkbEventCauseRec cause;
2599*4882a593Smuzhiyun XkbChangesRec change;
2600*4882a593Smuzhiyun Bool sentNKN;
2601*4882a593Smuzhiyun XkbSrvInfoPtr xkbi;
2602*4882a593Smuzhiyun XkbDescPtr xkb;
2603*4882a593Smuzhiyun
2604*4882a593Smuzhiyun if (!dev->key)
2605*4882a593Smuzhiyun return Success;
2606*4882a593Smuzhiyun
2607*4882a593Smuzhiyun xkbi = dev->key->xkbInfo;
2608*4882a593Smuzhiyun xkb = xkbi->desc;
2609*4882a593Smuzhiyun
2610*4882a593Smuzhiyun XkbSetCauseXkbReq(&cause, X_kbSetMap, client);
2611*4882a593Smuzhiyun memset(&change, 0, sizeof(change));
2612*4882a593Smuzhiyun sentNKN = FALSE;
2613*4882a593Smuzhiyun if ((xkb->min_key_code != req->minKeyCode) ||
2614*4882a593Smuzhiyun (xkb->max_key_code != req->maxKeyCode)) {
2615*4882a593Smuzhiyun Status status;
2616*4882a593Smuzhiyun xkbNewKeyboardNotify nkn;
2617*4882a593Smuzhiyun
2618*4882a593Smuzhiyun nkn.deviceID = nkn.oldDeviceID = dev->id;
2619*4882a593Smuzhiyun nkn.oldMinKeyCode = xkb->min_key_code;
2620*4882a593Smuzhiyun nkn.oldMaxKeyCode = xkb->max_key_code;
2621*4882a593Smuzhiyun status = XkbChangeKeycodeRange(xkb, req->minKeyCode,
2622*4882a593Smuzhiyun req->maxKeyCode, &change);
2623*4882a593Smuzhiyun if (status != Success)
2624*4882a593Smuzhiyun return status; /* oh-oh. what about the other keyboards? */
2625*4882a593Smuzhiyun nkn.minKeyCode = xkb->min_key_code;
2626*4882a593Smuzhiyun nkn.maxKeyCode = xkb->max_key_code;
2627*4882a593Smuzhiyun nkn.requestMajor = XkbReqCode;
2628*4882a593Smuzhiyun nkn.requestMinor = X_kbSetMap;
2629*4882a593Smuzhiyun nkn.changed = XkbNKN_KeycodesMask;
2630*4882a593Smuzhiyun XkbSendNewKeyboardNotify(dev, &nkn);
2631*4882a593Smuzhiyun sentNKN = TRUE;
2632*4882a593Smuzhiyun }
2633*4882a593Smuzhiyun
2634*4882a593Smuzhiyun if (req->present & XkbKeyTypesMask) {
2635*4882a593Smuzhiyun values = SetKeyTypes(xkb, req, (xkbKeyTypeWireDesc *) values, &change);
2636*4882a593Smuzhiyun if (!values)
2637*4882a593Smuzhiyun goto allocFailure;
2638*4882a593Smuzhiyun }
2639*4882a593Smuzhiyun if (req->present & XkbKeySymsMask) {
2640*4882a593Smuzhiyun values =
2641*4882a593Smuzhiyun SetKeySyms(client, xkb, req, (xkbSymMapWireDesc *) values, &change,
2642*4882a593Smuzhiyun dev);
2643*4882a593Smuzhiyun if (!values)
2644*4882a593Smuzhiyun goto allocFailure;
2645*4882a593Smuzhiyun }
2646*4882a593Smuzhiyun if (req->present & XkbKeyActionsMask) {
2647*4882a593Smuzhiyun values = SetKeyActions(xkb, req, (CARD8 *) values, &change);
2648*4882a593Smuzhiyun if (!values)
2649*4882a593Smuzhiyun goto allocFailure;
2650*4882a593Smuzhiyun }
2651*4882a593Smuzhiyun if (req->present & XkbKeyBehaviorsMask) {
2652*4882a593Smuzhiyun values =
2653*4882a593Smuzhiyun SetKeyBehaviors(xkbi, req, (xkbBehaviorWireDesc *) values, &change);
2654*4882a593Smuzhiyun if (!values)
2655*4882a593Smuzhiyun goto allocFailure;
2656*4882a593Smuzhiyun }
2657*4882a593Smuzhiyun if (req->present & XkbVirtualModsMask)
2658*4882a593Smuzhiyun values = SetVirtualMods(xkbi, req, (CARD8 *) values, &change);
2659*4882a593Smuzhiyun if (req->present & XkbExplicitComponentsMask)
2660*4882a593Smuzhiyun values = SetKeyExplicit(xkbi, req, (CARD8 *) values, &change);
2661*4882a593Smuzhiyun if (req->present & XkbModifierMapMask)
2662*4882a593Smuzhiyun values = SetModifierMap(xkbi, req, (CARD8 *) values, &change);
2663*4882a593Smuzhiyun if (req->present & XkbVirtualModMapMask)
2664*4882a593Smuzhiyun values =
2665*4882a593Smuzhiyun SetVirtualModMap(xkbi, req, (xkbVModMapWireDesc *) values, &change);
2666*4882a593Smuzhiyun if (((values - ((char *) req)) / 4) != req->length) {
2667*4882a593Smuzhiyun ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n");
2668*4882a593Smuzhiyun client->errorValue = values - ((char *) &req[1]);
2669*4882a593Smuzhiyun return BadLength;
2670*4882a593Smuzhiyun }
2671*4882a593Smuzhiyun if (req->flags & XkbSetMapRecomputeActions) {
2672*4882a593Smuzhiyun KeyCode first, last, firstMM, lastMM;
2673*4882a593Smuzhiyun
2674*4882a593Smuzhiyun if (change.map.num_key_syms > 0) {
2675*4882a593Smuzhiyun first = change.map.first_key_sym;
2676*4882a593Smuzhiyun last = first + change.map.num_key_syms - 1;
2677*4882a593Smuzhiyun }
2678*4882a593Smuzhiyun else
2679*4882a593Smuzhiyun first = last = 0;
2680*4882a593Smuzhiyun if (change.map.num_modmap_keys > 0) {
2681*4882a593Smuzhiyun firstMM = change.map.first_modmap_key;
2682*4882a593Smuzhiyun lastMM = firstMM + change.map.num_modmap_keys - 1;
2683*4882a593Smuzhiyun }
2684*4882a593Smuzhiyun else
2685*4882a593Smuzhiyun firstMM = lastMM = 0;
2686*4882a593Smuzhiyun if ((last > 0) && (lastMM > 0)) {
2687*4882a593Smuzhiyun if (firstMM < first)
2688*4882a593Smuzhiyun first = firstMM;
2689*4882a593Smuzhiyun if (lastMM > last)
2690*4882a593Smuzhiyun last = lastMM;
2691*4882a593Smuzhiyun }
2692*4882a593Smuzhiyun else if (lastMM > 0) {
2693*4882a593Smuzhiyun first = firstMM;
2694*4882a593Smuzhiyun last = lastMM;
2695*4882a593Smuzhiyun }
2696*4882a593Smuzhiyun if (last > 0) {
2697*4882a593Smuzhiyun unsigned check = 0;
2698*4882a593Smuzhiyun
2699*4882a593Smuzhiyun XkbUpdateActions(dev, first, (last - first + 1), &change, &check,
2700*4882a593Smuzhiyun &cause);
2701*4882a593Smuzhiyun if (check)
2702*4882a593Smuzhiyun XkbCheckSecondaryEffects(xkbi, check, &change, &cause);
2703*4882a593Smuzhiyun }
2704*4882a593Smuzhiyun }
2705*4882a593Smuzhiyun if (!sentNKN)
2706*4882a593Smuzhiyun XkbSendNotification(dev, &change, &cause);
2707*4882a593Smuzhiyun
2708*4882a593Smuzhiyun return Success;
2709*4882a593Smuzhiyun allocFailure:
2710*4882a593Smuzhiyun return BadAlloc;
2711*4882a593Smuzhiyun }
2712*4882a593Smuzhiyun
2713*4882a593Smuzhiyun int
ProcXkbSetMap(ClientPtr client)2714*4882a593Smuzhiyun ProcXkbSetMap(ClientPtr client)
2715*4882a593Smuzhiyun {
2716*4882a593Smuzhiyun DeviceIntPtr dev;
2717*4882a593Smuzhiyun char *tmp;
2718*4882a593Smuzhiyun int rc;
2719*4882a593Smuzhiyun
2720*4882a593Smuzhiyun REQUEST(xkbSetMapReq);
2721*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
2722*4882a593Smuzhiyun
2723*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
2724*4882a593Smuzhiyun return BadAccess;
2725*4882a593Smuzhiyun
2726*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
2727*4882a593Smuzhiyun CHK_MASK_LEGAL(0x01, stuff->present, XkbAllMapComponentsMask);
2728*4882a593Smuzhiyun
2729*4882a593Smuzhiyun /* first verify the request length carefully */
2730*4882a593Smuzhiyun rc = _XkbSetMapCheckLength(stuff);
2731*4882a593Smuzhiyun if (rc != Success)
2732*4882a593Smuzhiyun return rc;
2733*4882a593Smuzhiyun
2734*4882a593Smuzhiyun tmp = (char *) &stuff[1];
2735*4882a593Smuzhiyun
2736*4882a593Smuzhiyun /* Check if we can to the SetMap on the requested device. If this
2737*4882a593Smuzhiyun succeeds, do the same thing for all extension devices (if needed).
2738*4882a593Smuzhiyun If any of them fails, fail. */
2739*4882a593Smuzhiyun rc = _XkbSetMapChecks(client, dev, stuff, tmp);
2740*4882a593Smuzhiyun
2741*4882a593Smuzhiyun if (rc != Success)
2742*4882a593Smuzhiyun return rc;
2743*4882a593Smuzhiyun
2744*4882a593Smuzhiyun DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD);
2745*4882a593Smuzhiyun
2746*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd) {
2747*4882a593Smuzhiyun DeviceIntPtr other;
2748*4882a593Smuzhiyun
2749*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
2750*4882a593Smuzhiyun if ((other != dev) && other->key && !IsMaster(other) &&
2751*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) {
2752*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
2753*4882a593Smuzhiyun DixManageAccess);
2754*4882a593Smuzhiyun if (rc == Success) {
2755*4882a593Smuzhiyun rc = _XkbSetMapChecks(client, other, stuff, tmp);
2756*4882a593Smuzhiyun if (rc != Success)
2757*4882a593Smuzhiyun return rc;
2758*4882a593Smuzhiyun }
2759*4882a593Smuzhiyun }
2760*4882a593Smuzhiyun }
2761*4882a593Smuzhiyun } else {
2762*4882a593Smuzhiyun DeviceIntPtr other;
2763*4882a593Smuzhiyun
2764*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
2765*4882a593Smuzhiyun if (other != dev && GetMaster(other, MASTER_KEYBOARD) != dev &&
2766*4882a593Smuzhiyun (other != master || dev != master->lastSlave))
2767*4882a593Smuzhiyun continue;
2768*4882a593Smuzhiyun
2769*4882a593Smuzhiyun rc = _XkbSetMapChecks(client, other, stuff, tmp);
2770*4882a593Smuzhiyun if (rc != Success)
2771*4882a593Smuzhiyun return rc;
2772*4882a593Smuzhiyun }
2773*4882a593Smuzhiyun }
2774*4882a593Smuzhiyun
2775*4882a593Smuzhiyun /* We know now that we will succeed with the SetMap. In theory anyway. */
2776*4882a593Smuzhiyun rc = _XkbSetMap(client, dev, stuff, tmp);
2777*4882a593Smuzhiyun if (rc != Success)
2778*4882a593Smuzhiyun return rc;
2779*4882a593Smuzhiyun
2780*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd) {
2781*4882a593Smuzhiyun DeviceIntPtr other;
2782*4882a593Smuzhiyun
2783*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
2784*4882a593Smuzhiyun if ((other != dev) && other->key && !IsMaster(other) &&
2785*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) {
2786*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
2787*4882a593Smuzhiyun DixManageAccess);
2788*4882a593Smuzhiyun if (rc == Success)
2789*4882a593Smuzhiyun _XkbSetMap(client, other, stuff, tmp);
2790*4882a593Smuzhiyun /* ignore rc. if the SetMap failed although the check above
2791*4882a593Smuzhiyun reported true there isn't much we can do. we still need to
2792*4882a593Smuzhiyun set all other devices, hoping that at least they stay in
2793*4882a593Smuzhiyun sync. */
2794*4882a593Smuzhiyun }
2795*4882a593Smuzhiyun }
2796*4882a593Smuzhiyun } else {
2797*4882a593Smuzhiyun DeviceIntPtr other;
2798*4882a593Smuzhiyun
2799*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
2800*4882a593Smuzhiyun if (other != dev && GetMaster(other, MASTER_KEYBOARD) != dev &&
2801*4882a593Smuzhiyun (other != master || dev != master->lastSlave))
2802*4882a593Smuzhiyun continue;
2803*4882a593Smuzhiyun
2804*4882a593Smuzhiyun _XkbSetMap(client, other, stuff, tmp); //ignore rc
2805*4882a593Smuzhiyun }
2806*4882a593Smuzhiyun }
2807*4882a593Smuzhiyun
2808*4882a593Smuzhiyun return Success;
2809*4882a593Smuzhiyun }
2810*4882a593Smuzhiyun
2811*4882a593Smuzhiyun /***====================================================================***/
2812*4882a593Smuzhiyun
2813*4882a593Smuzhiyun static Status
XkbComputeGetCompatMapReplySize(XkbCompatMapPtr compat,xkbGetCompatMapReply * rep)2814*4882a593Smuzhiyun XkbComputeGetCompatMapReplySize(XkbCompatMapPtr compat,
2815*4882a593Smuzhiyun xkbGetCompatMapReply * rep)
2816*4882a593Smuzhiyun {
2817*4882a593Smuzhiyun unsigned size, nGroups;
2818*4882a593Smuzhiyun
2819*4882a593Smuzhiyun nGroups = 0;
2820*4882a593Smuzhiyun if (rep->groups != 0) {
2821*4882a593Smuzhiyun register int i, bit;
2822*4882a593Smuzhiyun
2823*4882a593Smuzhiyun for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
2824*4882a593Smuzhiyun if (rep->groups & bit)
2825*4882a593Smuzhiyun nGroups++;
2826*4882a593Smuzhiyun }
2827*4882a593Smuzhiyun }
2828*4882a593Smuzhiyun size = nGroups * SIZEOF(xkbModsWireDesc);
2829*4882a593Smuzhiyun size += (rep->nSI * SIZEOF(xkbSymInterpretWireDesc));
2830*4882a593Smuzhiyun rep->length = size / 4;
2831*4882a593Smuzhiyun return Success;
2832*4882a593Smuzhiyun }
2833*4882a593Smuzhiyun
2834*4882a593Smuzhiyun static int
XkbSendCompatMap(ClientPtr client,XkbCompatMapPtr compat,xkbGetCompatMapReply * rep)2835*4882a593Smuzhiyun XkbSendCompatMap(ClientPtr client,
2836*4882a593Smuzhiyun XkbCompatMapPtr compat, xkbGetCompatMapReply * rep)
2837*4882a593Smuzhiyun {
2838*4882a593Smuzhiyun char *data;
2839*4882a593Smuzhiyun int size;
2840*4882a593Smuzhiyun
2841*4882a593Smuzhiyun if (rep->length > 0) {
2842*4882a593Smuzhiyun data = xallocarray(rep->length, 4);
2843*4882a593Smuzhiyun if (data) {
2844*4882a593Smuzhiyun register unsigned i, bit;
2845*4882a593Smuzhiyun xkbModsWireDesc *grp;
2846*4882a593Smuzhiyun XkbSymInterpretPtr sym = &compat->sym_interpret[rep->firstSI];
2847*4882a593Smuzhiyun xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) data;
2848*4882a593Smuzhiyun
2849*4882a593Smuzhiyun size = rep->length * 4;
2850*4882a593Smuzhiyun
2851*4882a593Smuzhiyun for (i = 0; i < rep->nSI; i++, sym++, wire++) {
2852*4882a593Smuzhiyun wire->sym = sym->sym;
2853*4882a593Smuzhiyun wire->mods = sym->mods;
2854*4882a593Smuzhiyun wire->match = sym->match;
2855*4882a593Smuzhiyun wire->virtualMod = sym->virtual_mod;
2856*4882a593Smuzhiyun wire->flags = sym->flags;
2857*4882a593Smuzhiyun memcpy((char *) &wire->act, (char *) &sym->act,
2858*4882a593Smuzhiyun sz_xkbActionWireDesc);
2859*4882a593Smuzhiyun if (client->swapped) {
2860*4882a593Smuzhiyun swapl(&wire->sym);
2861*4882a593Smuzhiyun }
2862*4882a593Smuzhiyun }
2863*4882a593Smuzhiyun if (rep->groups) {
2864*4882a593Smuzhiyun grp = (xkbModsWireDesc *) wire;
2865*4882a593Smuzhiyun for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
2866*4882a593Smuzhiyun if (rep->groups & bit) {
2867*4882a593Smuzhiyun grp->mask = compat->groups[i].mask;
2868*4882a593Smuzhiyun grp->realMods = compat->groups[i].real_mods;
2869*4882a593Smuzhiyun grp->virtualMods = compat->groups[i].vmods;
2870*4882a593Smuzhiyun if (client->swapped) {
2871*4882a593Smuzhiyun swaps(&grp->virtualMods);
2872*4882a593Smuzhiyun }
2873*4882a593Smuzhiyun grp++;
2874*4882a593Smuzhiyun }
2875*4882a593Smuzhiyun }
2876*4882a593Smuzhiyun wire = (xkbSymInterpretWireDesc *) grp;
2877*4882a593Smuzhiyun }
2878*4882a593Smuzhiyun }
2879*4882a593Smuzhiyun else
2880*4882a593Smuzhiyun return BadAlloc;
2881*4882a593Smuzhiyun }
2882*4882a593Smuzhiyun else
2883*4882a593Smuzhiyun data = NULL;
2884*4882a593Smuzhiyun
2885*4882a593Smuzhiyun if (client->swapped) {
2886*4882a593Smuzhiyun swaps(&rep->sequenceNumber);
2887*4882a593Smuzhiyun swapl(&rep->length);
2888*4882a593Smuzhiyun swaps(&rep->firstSI);
2889*4882a593Smuzhiyun swaps(&rep->nSI);
2890*4882a593Smuzhiyun swaps(&rep->nTotalSI);
2891*4882a593Smuzhiyun }
2892*4882a593Smuzhiyun
2893*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbGetCompatMapReply), rep);
2894*4882a593Smuzhiyun if (data) {
2895*4882a593Smuzhiyun WriteToClient(client, size, data);
2896*4882a593Smuzhiyun free((char *) data);
2897*4882a593Smuzhiyun }
2898*4882a593Smuzhiyun return Success;
2899*4882a593Smuzhiyun }
2900*4882a593Smuzhiyun
2901*4882a593Smuzhiyun int
ProcXkbGetCompatMap(ClientPtr client)2902*4882a593Smuzhiyun ProcXkbGetCompatMap(ClientPtr client)
2903*4882a593Smuzhiyun {
2904*4882a593Smuzhiyun xkbGetCompatMapReply rep;
2905*4882a593Smuzhiyun DeviceIntPtr dev;
2906*4882a593Smuzhiyun XkbDescPtr xkb;
2907*4882a593Smuzhiyun XkbCompatMapPtr compat;
2908*4882a593Smuzhiyun
2909*4882a593Smuzhiyun REQUEST(xkbGetCompatMapReq);
2910*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
2911*4882a593Smuzhiyun
2912*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
2913*4882a593Smuzhiyun return BadAccess;
2914*4882a593Smuzhiyun
2915*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
2916*4882a593Smuzhiyun
2917*4882a593Smuzhiyun xkb = dev->key->xkbInfo->desc;
2918*4882a593Smuzhiyun compat = xkb->compat;
2919*4882a593Smuzhiyun
2920*4882a593Smuzhiyun rep = (xkbGetCompatMapReply) {
2921*4882a593Smuzhiyun .type = X_Reply,
2922*4882a593Smuzhiyun .sequenceNumber = client->sequence,
2923*4882a593Smuzhiyun .length = 0,
2924*4882a593Smuzhiyun .deviceID = dev->id,
2925*4882a593Smuzhiyun .firstSI = stuff->firstSI,
2926*4882a593Smuzhiyun .nSI = stuff->nSI
2927*4882a593Smuzhiyun };
2928*4882a593Smuzhiyun if (stuff->getAllSI) {
2929*4882a593Smuzhiyun rep.firstSI = 0;
2930*4882a593Smuzhiyun rep.nSI = compat->num_si;
2931*4882a593Smuzhiyun }
2932*4882a593Smuzhiyun else if ((((unsigned) stuff->nSI) > 0) &&
2933*4882a593Smuzhiyun ((unsigned) (stuff->firstSI + stuff->nSI - 1) >= compat->num_si)) {
2934*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x05, compat->num_si);
2935*4882a593Smuzhiyun return BadValue;
2936*4882a593Smuzhiyun }
2937*4882a593Smuzhiyun rep.nTotalSI = compat->num_si;
2938*4882a593Smuzhiyun rep.groups = stuff->groups;
2939*4882a593Smuzhiyun XkbComputeGetCompatMapReplySize(compat, &rep);
2940*4882a593Smuzhiyun return XkbSendCompatMap(client, compat, &rep);
2941*4882a593Smuzhiyun }
2942*4882a593Smuzhiyun
2943*4882a593Smuzhiyun /**
2944*4882a593Smuzhiyun * Apply the given request on the given device.
2945*4882a593Smuzhiyun * If dryRun is TRUE, then value checks are performed, but the device isn't
2946*4882a593Smuzhiyun * modified.
2947*4882a593Smuzhiyun */
2948*4882a593Smuzhiyun static int
_XkbSetCompatMap(ClientPtr client,DeviceIntPtr dev,xkbSetCompatMapReq * req,char * data,BOOL dryRun)2949*4882a593Smuzhiyun _XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
2950*4882a593Smuzhiyun xkbSetCompatMapReq * req, char *data, BOOL dryRun)
2951*4882a593Smuzhiyun {
2952*4882a593Smuzhiyun XkbSrvInfoPtr xkbi;
2953*4882a593Smuzhiyun XkbDescPtr xkb;
2954*4882a593Smuzhiyun XkbCompatMapPtr compat;
2955*4882a593Smuzhiyun int nGroups;
2956*4882a593Smuzhiyun unsigned i, bit;
2957*4882a593Smuzhiyun
2958*4882a593Smuzhiyun xkbi = dev->key->xkbInfo;
2959*4882a593Smuzhiyun xkb = xkbi->desc;
2960*4882a593Smuzhiyun compat = xkb->compat;
2961*4882a593Smuzhiyun
2962*4882a593Smuzhiyun if ((req->nSI > 0) || (req->truncateSI)) {
2963*4882a593Smuzhiyun xkbSymInterpretWireDesc *wire;
2964*4882a593Smuzhiyun
2965*4882a593Smuzhiyun if (req->firstSI > compat->num_si) {
2966*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x02, compat->num_si);
2967*4882a593Smuzhiyun return BadValue;
2968*4882a593Smuzhiyun }
2969*4882a593Smuzhiyun wire = (xkbSymInterpretWireDesc *) data;
2970*4882a593Smuzhiyun wire += req->nSI;
2971*4882a593Smuzhiyun data = (char *) wire;
2972*4882a593Smuzhiyun }
2973*4882a593Smuzhiyun
2974*4882a593Smuzhiyun nGroups = 0;
2975*4882a593Smuzhiyun if (req->groups != 0) {
2976*4882a593Smuzhiyun for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
2977*4882a593Smuzhiyun if (req->groups & bit)
2978*4882a593Smuzhiyun nGroups++;
2979*4882a593Smuzhiyun }
2980*4882a593Smuzhiyun }
2981*4882a593Smuzhiyun data += nGroups * SIZEOF(xkbModsWireDesc);
2982*4882a593Smuzhiyun if (((data - ((char *) req)) / 4) != req->length) {
2983*4882a593Smuzhiyun return BadLength;
2984*4882a593Smuzhiyun }
2985*4882a593Smuzhiyun
2986*4882a593Smuzhiyun /* Done all the checks we can do */
2987*4882a593Smuzhiyun if (dryRun)
2988*4882a593Smuzhiyun return Success;
2989*4882a593Smuzhiyun
2990*4882a593Smuzhiyun data = (char *) &req[1];
2991*4882a593Smuzhiyun if (req->nSI > 0) {
2992*4882a593Smuzhiyun xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) data;
2993*4882a593Smuzhiyun XkbSymInterpretPtr sym;
2994*4882a593Smuzhiyun unsigned int skipped = 0;
2995*4882a593Smuzhiyun
2996*4882a593Smuzhiyun if ((unsigned) (req->firstSI + req->nSI) > compat->num_si) {
2997*4882a593Smuzhiyun compat->num_si = req->firstSI + req->nSI;
2998*4882a593Smuzhiyun compat->sym_interpret = reallocarray(compat->sym_interpret,
2999*4882a593Smuzhiyun compat->num_si,
3000*4882a593Smuzhiyun sizeof(XkbSymInterpretRec));
3001*4882a593Smuzhiyun if (!compat->sym_interpret) {
3002*4882a593Smuzhiyun compat->num_si = 0;
3003*4882a593Smuzhiyun return BadAlloc;
3004*4882a593Smuzhiyun }
3005*4882a593Smuzhiyun }
3006*4882a593Smuzhiyun else if (req->truncateSI) {
3007*4882a593Smuzhiyun compat->num_si = req->firstSI + req->nSI;
3008*4882a593Smuzhiyun }
3009*4882a593Smuzhiyun sym = &compat->sym_interpret[req->firstSI];
3010*4882a593Smuzhiyun for (i = 0; i < req->nSI; i++, wire++) {
3011*4882a593Smuzhiyun if (client->swapped) {
3012*4882a593Smuzhiyun swapl(&wire->sym);
3013*4882a593Smuzhiyun }
3014*4882a593Smuzhiyun if (wire->sym == NoSymbol && wire->match == XkbSI_AnyOfOrNone &&
3015*4882a593Smuzhiyun (wire->mods & 0xff) == 0xff &&
3016*4882a593Smuzhiyun wire->act.type == XkbSA_XFree86Private) {
3017*4882a593Smuzhiyun ErrorF("XKB: Skipping broken Any+AnyOfOrNone(All) -> Private "
3018*4882a593Smuzhiyun "action from client\n");
3019*4882a593Smuzhiyun skipped++;
3020*4882a593Smuzhiyun continue;
3021*4882a593Smuzhiyun }
3022*4882a593Smuzhiyun sym->sym = wire->sym;
3023*4882a593Smuzhiyun sym->mods = wire->mods;
3024*4882a593Smuzhiyun sym->match = wire->match;
3025*4882a593Smuzhiyun sym->flags = wire->flags;
3026*4882a593Smuzhiyun sym->virtual_mod = wire->virtualMod;
3027*4882a593Smuzhiyun memcpy((char *) &sym->act, (char *) &wire->act,
3028*4882a593Smuzhiyun SIZEOF(xkbActionWireDesc));
3029*4882a593Smuzhiyun sym++;
3030*4882a593Smuzhiyun }
3031*4882a593Smuzhiyun if (skipped) {
3032*4882a593Smuzhiyun if (req->firstSI + req->nSI < compat->num_si)
3033*4882a593Smuzhiyun memmove(sym, sym + skipped,
3034*4882a593Smuzhiyun (compat->num_si - req->firstSI - req->nSI) *
3035*4882a593Smuzhiyun sizeof(*sym));
3036*4882a593Smuzhiyun compat->num_si -= skipped;
3037*4882a593Smuzhiyun }
3038*4882a593Smuzhiyun data = (char *) wire;
3039*4882a593Smuzhiyun }
3040*4882a593Smuzhiyun else if (req->truncateSI) {
3041*4882a593Smuzhiyun compat->num_si = req->firstSI;
3042*4882a593Smuzhiyun }
3043*4882a593Smuzhiyun
3044*4882a593Smuzhiyun if (req->groups != 0) {
3045*4882a593Smuzhiyun xkbModsWireDesc *wire = (xkbModsWireDesc *) data;
3046*4882a593Smuzhiyun
3047*4882a593Smuzhiyun for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
3048*4882a593Smuzhiyun if (req->groups & bit) {
3049*4882a593Smuzhiyun if (client->swapped) {
3050*4882a593Smuzhiyun swaps(&wire->virtualMods);
3051*4882a593Smuzhiyun }
3052*4882a593Smuzhiyun compat->groups[i].mask = wire->realMods;
3053*4882a593Smuzhiyun compat->groups[i].real_mods = wire->realMods;
3054*4882a593Smuzhiyun compat->groups[i].vmods = wire->virtualMods;
3055*4882a593Smuzhiyun if (wire->virtualMods != 0) {
3056*4882a593Smuzhiyun unsigned tmp;
3057*4882a593Smuzhiyun
3058*4882a593Smuzhiyun tmp = XkbMaskForVMask(xkb, wire->virtualMods);
3059*4882a593Smuzhiyun compat->groups[i].mask |= tmp;
3060*4882a593Smuzhiyun }
3061*4882a593Smuzhiyun data += SIZEOF(xkbModsWireDesc);
3062*4882a593Smuzhiyun wire = (xkbModsWireDesc *) data;
3063*4882a593Smuzhiyun }
3064*4882a593Smuzhiyun }
3065*4882a593Smuzhiyun }
3066*4882a593Smuzhiyun i = XkbPaddedSize((data - ((char *) req)));
3067*4882a593Smuzhiyun if ((i / 4) != req->length) {
3068*4882a593Smuzhiyun ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n");
3069*4882a593Smuzhiyun return BadLength;
3070*4882a593Smuzhiyun }
3071*4882a593Smuzhiyun
3072*4882a593Smuzhiyun if (dev->xkb_interest) {
3073*4882a593Smuzhiyun xkbCompatMapNotify ev;
3074*4882a593Smuzhiyun
3075*4882a593Smuzhiyun ev.deviceID = dev->id;
3076*4882a593Smuzhiyun ev.changedGroups = req->groups;
3077*4882a593Smuzhiyun ev.firstSI = req->firstSI;
3078*4882a593Smuzhiyun ev.nSI = req->nSI;
3079*4882a593Smuzhiyun ev.nTotalSI = compat->num_si;
3080*4882a593Smuzhiyun XkbSendCompatMapNotify(dev, &ev);
3081*4882a593Smuzhiyun }
3082*4882a593Smuzhiyun
3083*4882a593Smuzhiyun if (req->recomputeActions) {
3084*4882a593Smuzhiyun XkbChangesRec change;
3085*4882a593Smuzhiyun unsigned check;
3086*4882a593Smuzhiyun XkbEventCauseRec cause;
3087*4882a593Smuzhiyun
3088*4882a593Smuzhiyun XkbSetCauseXkbReq(&cause, X_kbSetCompatMap, client);
3089*4882a593Smuzhiyun memset(&change, 0, sizeof(XkbChangesRec));
3090*4882a593Smuzhiyun XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &change,
3091*4882a593Smuzhiyun &check, &cause);
3092*4882a593Smuzhiyun if (check)
3093*4882a593Smuzhiyun XkbCheckSecondaryEffects(xkbi, check, &change, &cause);
3094*4882a593Smuzhiyun XkbSendNotification(dev, &change, &cause);
3095*4882a593Smuzhiyun }
3096*4882a593Smuzhiyun return Success;
3097*4882a593Smuzhiyun }
3098*4882a593Smuzhiyun
3099*4882a593Smuzhiyun int
ProcXkbSetCompatMap(ClientPtr client)3100*4882a593Smuzhiyun ProcXkbSetCompatMap(ClientPtr client)
3101*4882a593Smuzhiyun {
3102*4882a593Smuzhiyun DeviceIntPtr dev;
3103*4882a593Smuzhiyun char *data;
3104*4882a593Smuzhiyun int rc;
3105*4882a593Smuzhiyun
3106*4882a593Smuzhiyun REQUEST(xkbSetCompatMapReq);
3107*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
3108*4882a593Smuzhiyun
3109*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
3110*4882a593Smuzhiyun return BadAccess;
3111*4882a593Smuzhiyun
3112*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
3113*4882a593Smuzhiyun
3114*4882a593Smuzhiyun data = (char *) &stuff[1];
3115*4882a593Smuzhiyun
3116*4882a593Smuzhiyun /* check first using a dry-run */
3117*4882a593Smuzhiyun rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE);
3118*4882a593Smuzhiyun if (rc != Success)
3119*4882a593Smuzhiyun return rc;
3120*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd) {
3121*4882a593Smuzhiyun DeviceIntPtr other;
3122*4882a593Smuzhiyun
3123*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
3124*4882a593Smuzhiyun if ((other != dev) && other->key && !IsMaster(other) &&
3125*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) {
3126*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
3127*4882a593Smuzhiyun DixManageAccess);
3128*4882a593Smuzhiyun if (rc == Success) {
3129*4882a593Smuzhiyun /* dry-run */
3130*4882a593Smuzhiyun rc = _XkbSetCompatMap(client, other, stuff, data, TRUE);
3131*4882a593Smuzhiyun if (rc != Success)
3132*4882a593Smuzhiyun return rc;
3133*4882a593Smuzhiyun }
3134*4882a593Smuzhiyun }
3135*4882a593Smuzhiyun }
3136*4882a593Smuzhiyun }
3137*4882a593Smuzhiyun
3138*4882a593Smuzhiyun /* Yay, the dry-runs succeed. Let's apply */
3139*4882a593Smuzhiyun rc = _XkbSetCompatMap(client, dev, stuff, data, FALSE);
3140*4882a593Smuzhiyun if (rc != Success)
3141*4882a593Smuzhiyun return rc;
3142*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd) {
3143*4882a593Smuzhiyun DeviceIntPtr other;
3144*4882a593Smuzhiyun
3145*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
3146*4882a593Smuzhiyun if ((other != dev) && other->key && !IsMaster(other) &&
3147*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) {
3148*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
3149*4882a593Smuzhiyun DixManageAccess);
3150*4882a593Smuzhiyun if (rc == Success) {
3151*4882a593Smuzhiyun rc = _XkbSetCompatMap(client, other, stuff, data, FALSE);
3152*4882a593Smuzhiyun if (rc != Success)
3153*4882a593Smuzhiyun return rc;
3154*4882a593Smuzhiyun }
3155*4882a593Smuzhiyun }
3156*4882a593Smuzhiyun }
3157*4882a593Smuzhiyun }
3158*4882a593Smuzhiyun
3159*4882a593Smuzhiyun return Success;
3160*4882a593Smuzhiyun }
3161*4882a593Smuzhiyun
3162*4882a593Smuzhiyun /***====================================================================***/
3163*4882a593Smuzhiyun
3164*4882a593Smuzhiyun int
ProcXkbGetIndicatorState(ClientPtr client)3165*4882a593Smuzhiyun ProcXkbGetIndicatorState(ClientPtr client)
3166*4882a593Smuzhiyun {
3167*4882a593Smuzhiyun xkbGetIndicatorStateReply rep;
3168*4882a593Smuzhiyun XkbSrvLedInfoPtr sli;
3169*4882a593Smuzhiyun DeviceIntPtr dev;
3170*4882a593Smuzhiyun
3171*4882a593Smuzhiyun REQUEST(xkbGetIndicatorStateReq);
3172*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq);
3173*4882a593Smuzhiyun
3174*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
3175*4882a593Smuzhiyun return BadAccess;
3176*4882a593Smuzhiyun
3177*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess);
3178*4882a593Smuzhiyun
3179*4882a593Smuzhiyun sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId,
3180*4882a593Smuzhiyun XkbXI_IndicatorStateMask);
3181*4882a593Smuzhiyun if (!sli)
3182*4882a593Smuzhiyun return BadAlloc;
3183*4882a593Smuzhiyun
3184*4882a593Smuzhiyun rep = (xkbGetIndicatorStateReply) {
3185*4882a593Smuzhiyun .type = X_Reply,
3186*4882a593Smuzhiyun .deviceID = dev->id,
3187*4882a593Smuzhiyun .sequenceNumber = client->sequence,
3188*4882a593Smuzhiyun .length = 0,
3189*4882a593Smuzhiyun .state = sli->effectiveState
3190*4882a593Smuzhiyun };
3191*4882a593Smuzhiyun
3192*4882a593Smuzhiyun if (client->swapped) {
3193*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
3194*4882a593Smuzhiyun swapl(&rep.state);
3195*4882a593Smuzhiyun }
3196*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), &rep);
3197*4882a593Smuzhiyun return Success;
3198*4882a593Smuzhiyun }
3199*4882a593Smuzhiyun
3200*4882a593Smuzhiyun /***====================================================================***/
3201*4882a593Smuzhiyun
3202*4882a593Smuzhiyun static Status
XkbComputeGetIndicatorMapReplySize(XkbIndicatorPtr indicators,xkbGetIndicatorMapReply * rep)3203*4882a593Smuzhiyun XkbComputeGetIndicatorMapReplySize(XkbIndicatorPtr indicators,
3204*4882a593Smuzhiyun xkbGetIndicatorMapReply * rep)
3205*4882a593Smuzhiyun {
3206*4882a593Smuzhiyun register int i, bit;
3207*4882a593Smuzhiyun int nIndicators;
3208*4882a593Smuzhiyun
3209*4882a593Smuzhiyun rep->realIndicators = indicators->phys_indicators;
3210*4882a593Smuzhiyun for (i = nIndicators = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
3211*4882a593Smuzhiyun if (rep->which & bit)
3212*4882a593Smuzhiyun nIndicators++;
3213*4882a593Smuzhiyun }
3214*4882a593Smuzhiyun rep->length = (nIndicators * SIZEOF(xkbIndicatorMapWireDesc)) / 4;
3215*4882a593Smuzhiyun rep->nIndicators = nIndicators;
3216*4882a593Smuzhiyun return Success;
3217*4882a593Smuzhiyun }
3218*4882a593Smuzhiyun
3219*4882a593Smuzhiyun static int
XkbSendIndicatorMap(ClientPtr client,XkbIndicatorPtr indicators,xkbGetIndicatorMapReply * rep)3220*4882a593Smuzhiyun XkbSendIndicatorMap(ClientPtr client,
3221*4882a593Smuzhiyun XkbIndicatorPtr indicators, xkbGetIndicatorMapReply * rep)
3222*4882a593Smuzhiyun {
3223*4882a593Smuzhiyun int length;
3224*4882a593Smuzhiyun CARD8 *map;
3225*4882a593Smuzhiyun register int i;
3226*4882a593Smuzhiyun register unsigned bit;
3227*4882a593Smuzhiyun
3228*4882a593Smuzhiyun if (rep->length > 0) {
3229*4882a593Smuzhiyun CARD8 *to;
3230*4882a593Smuzhiyun
3231*4882a593Smuzhiyun to = map = xallocarray(rep->length, 4);
3232*4882a593Smuzhiyun if (map) {
3233*4882a593Smuzhiyun xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *) to;
3234*4882a593Smuzhiyun
3235*4882a593Smuzhiyun length = rep->length * 4;
3236*4882a593Smuzhiyun
3237*4882a593Smuzhiyun for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
3238*4882a593Smuzhiyun if (rep->which & bit) {
3239*4882a593Smuzhiyun wire->flags = indicators->maps[i].flags;
3240*4882a593Smuzhiyun wire->whichGroups = indicators->maps[i].which_groups;
3241*4882a593Smuzhiyun wire->groups = indicators->maps[i].groups;
3242*4882a593Smuzhiyun wire->whichMods = indicators->maps[i].which_mods;
3243*4882a593Smuzhiyun wire->mods = indicators->maps[i].mods.mask;
3244*4882a593Smuzhiyun wire->realMods = indicators->maps[i].mods.real_mods;
3245*4882a593Smuzhiyun wire->virtualMods = indicators->maps[i].mods.vmods;
3246*4882a593Smuzhiyun wire->ctrls = indicators->maps[i].ctrls;
3247*4882a593Smuzhiyun if (client->swapped) {
3248*4882a593Smuzhiyun swaps(&wire->virtualMods);
3249*4882a593Smuzhiyun swapl(&wire->ctrls);
3250*4882a593Smuzhiyun }
3251*4882a593Smuzhiyun wire++;
3252*4882a593Smuzhiyun }
3253*4882a593Smuzhiyun }
3254*4882a593Smuzhiyun to = (CARD8 *) wire;
3255*4882a593Smuzhiyun if ((to - map) != length) {
3256*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0xff, length);
3257*4882a593Smuzhiyun free(map);
3258*4882a593Smuzhiyun return BadLength;
3259*4882a593Smuzhiyun }
3260*4882a593Smuzhiyun }
3261*4882a593Smuzhiyun else
3262*4882a593Smuzhiyun return BadAlloc;
3263*4882a593Smuzhiyun }
3264*4882a593Smuzhiyun else
3265*4882a593Smuzhiyun map = NULL;
3266*4882a593Smuzhiyun if (client->swapped) {
3267*4882a593Smuzhiyun swaps(&rep->sequenceNumber);
3268*4882a593Smuzhiyun swapl(&rep->length);
3269*4882a593Smuzhiyun swapl(&rep->which);
3270*4882a593Smuzhiyun swapl(&rep->realIndicators);
3271*4882a593Smuzhiyun }
3272*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), rep);
3273*4882a593Smuzhiyun if (map) {
3274*4882a593Smuzhiyun WriteToClient(client, length, map);
3275*4882a593Smuzhiyun free((char *) map);
3276*4882a593Smuzhiyun }
3277*4882a593Smuzhiyun return Success;
3278*4882a593Smuzhiyun }
3279*4882a593Smuzhiyun
3280*4882a593Smuzhiyun int
ProcXkbGetIndicatorMap(ClientPtr client)3281*4882a593Smuzhiyun ProcXkbGetIndicatorMap(ClientPtr client)
3282*4882a593Smuzhiyun {
3283*4882a593Smuzhiyun xkbGetIndicatorMapReply rep;
3284*4882a593Smuzhiyun DeviceIntPtr dev;
3285*4882a593Smuzhiyun XkbDescPtr xkb;
3286*4882a593Smuzhiyun XkbIndicatorPtr leds;
3287*4882a593Smuzhiyun
3288*4882a593Smuzhiyun REQUEST(xkbGetIndicatorMapReq);
3289*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq);
3290*4882a593Smuzhiyun
3291*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
3292*4882a593Smuzhiyun return BadAccess;
3293*4882a593Smuzhiyun
3294*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
3295*4882a593Smuzhiyun
3296*4882a593Smuzhiyun xkb = dev->key->xkbInfo->desc;
3297*4882a593Smuzhiyun leds = xkb->indicators;
3298*4882a593Smuzhiyun
3299*4882a593Smuzhiyun rep = (xkbGetIndicatorMapReply) {
3300*4882a593Smuzhiyun .type = X_Reply,
3301*4882a593Smuzhiyun .deviceID = dev->id,
3302*4882a593Smuzhiyun .sequenceNumber = client->sequence,
3303*4882a593Smuzhiyun .length = 0,
3304*4882a593Smuzhiyun .which = stuff->which
3305*4882a593Smuzhiyun };
3306*4882a593Smuzhiyun XkbComputeGetIndicatorMapReplySize(leds, &rep);
3307*4882a593Smuzhiyun return XkbSendIndicatorMap(client, leds, &rep);
3308*4882a593Smuzhiyun }
3309*4882a593Smuzhiyun
3310*4882a593Smuzhiyun /**
3311*4882a593Smuzhiyun * Apply the given map to the given device. Which specifies which components
3312*4882a593Smuzhiyun * to apply.
3313*4882a593Smuzhiyun */
3314*4882a593Smuzhiyun static int
_XkbSetIndicatorMap(ClientPtr client,DeviceIntPtr dev,int which,xkbIndicatorMapWireDesc * desc)3315*4882a593Smuzhiyun _XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev,
3316*4882a593Smuzhiyun int which, xkbIndicatorMapWireDesc * desc)
3317*4882a593Smuzhiyun {
3318*4882a593Smuzhiyun XkbSrvInfoPtr xkbi;
3319*4882a593Smuzhiyun XkbSrvLedInfoPtr sli;
3320*4882a593Smuzhiyun XkbEventCauseRec cause;
3321*4882a593Smuzhiyun int i, bit;
3322*4882a593Smuzhiyun
3323*4882a593Smuzhiyun xkbi = dev->key->xkbInfo;
3324*4882a593Smuzhiyun
3325*4882a593Smuzhiyun sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId,
3326*4882a593Smuzhiyun XkbXI_IndicatorMapsMask);
3327*4882a593Smuzhiyun if (!sli)
3328*4882a593Smuzhiyun return BadAlloc;
3329*4882a593Smuzhiyun
3330*4882a593Smuzhiyun for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
3331*4882a593Smuzhiyun if (which & bit) {
3332*4882a593Smuzhiyun sli->maps[i].flags = desc->flags;
3333*4882a593Smuzhiyun sli->maps[i].which_groups = desc->whichGroups;
3334*4882a593Smuzhiyun sli->maps[i].groups = desc->groups;
3335*4882a593Smuzhiyun sli->maps[i].which_mods = desc->whichMods;
3336*4882a593Smuzhiyun sli->maps[i].mods.mask = desc->mods;
3337*4882a593Smuzhiyun sli->maps[i].mods.real_mods = desc->mods;
3338*4882a593Smuzhiyun sli->maps[i].mods.vmods = desc->virtualMods;
3339*4882a593Smuzhiyun sli->maps[i].ctrls = desc->ctrls;
3340*4882a593Smuzhiyun if (desc->virtualMods != 0) {
3341*4882a593Smuzhiyun unsigned tmp;
3342*4882a593Smuzhiyun
3343*4882a593Smuzhiyun tmp = XkbMaskForVMask(xkbi->desc, desc->virtualMods);
3344*4882a593Smuzhiyun sli->maps[i].mods.mask = desc->mods | tmp;
3345*4882a593Smuzhiyun }
3346*4882a593Smuzhiyun desc++;
3347*4882a593Smuzhiyun }
3348*4882a593Smuzhiyun }
3349*4882a593Smuzhiyun
3350*4882a593Smuzhiyun XkbSetCauseXkbReq(&cause, X_kbSetIndicatorMap, client);
3351*4882a593Smuzhiyun XkbApplyLedMapChanges(dev, sli, which, NULL, NULL, &cause);
3352*4882a593Smuzhiyun
3353*4882a593Smuzhiyun return Success;
3354*4882a593Smuzhiyun }
3355*4882a593Smuzhiyun
3356*4882a593Smuzhiyun int
ProcXkbSetIndicatorMap(ClientPtr client)3357*4882a593Smuzhiyun ProcXkbSetIndicatorMap(ClientPtr client)
3358*4882a593Smuzhiyun {
3359*4882a593Smuzhiyun int i, bit;
3360*4882a593Smuzhiyun int nIndicators;
3361*4882a593Smuzhiyun DeviceIntPtr dev;
3362*4882a593Smuzhiyun xkbIndicatorMapWireDesc *from;
3363*4882a593Smuzhiyun int rc;
3364*4882a593Smuzhiyun
3365*4882a593Smuzhiyun REQUEST(xkbSetIndicatorMapReq);
3366*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
3367*4882a593Smuzhiyun
3368*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
3369*4882a593Smuzhiyun return BadAccess;
3370*4882a593Smuzhiyun
3371*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
3372*4882a593Smuzhiyun
3373*4882a593Smuzhiyun if (stuff->which == 0)
3374*4882a593Smuzhiyun return Success;
3375*4882a593Smuzhiyun
3376*4882a593Smuzhiyun for (nIndicators = i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
3377*4882a593Smuzhiyun if (stuff->which & bit)
3378*4882a593Smuzhiyun nIndicators++;
3379*4882a593Smuzhiyun }
3380*4882a593Smuzhiyun if (stuff->length != ((SIZEOF(xkbSetIndicatorMapReq) +
3381*4882a593Smuzhiyun (nIndicators * SIZEOF(xkbIndicatorMapWireDesc))) /
3382*4882a593Smuzhiyun 4)) {
3383*4882a593Smuzhiyun return BadLength;
3384*4882a593Smuzhiyun }
3385*4882a593Smuzhiyun
3386*4882a593Smuzhiyun from = (xkbIndicatorMapWireDesc *) &stuff[1];
3387*4882a593Smuzhiyun for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
3388*4882a593Smuzhiyun if (stuff->which & bit) {
3389*4882a593Smuzhiyun if (client->swapped) {
3390*4882a593Smuzhiyun swaps(&from->virtualMods);
3391*4882a593Smuzhiyun swapl(&from->ctrls);
3392*4882a593Smuzhiyun }
3393*4882a593Smuzhiyun CHK_MASK_LEGAL(i, from->whichGroups, XkbIM_UseAnyGroup);
3394*4882a593Smuzhiyun CHK_MASK_LEGAL(i, from->whichMods, XkbIM_UseAnyMods);
3395*4882a593Smuzhiyun from++;
3396*4882a593Smuzhiyun }
3397*4882a593Smuzhiyun }
3398*4882a593Smuzhiyun
3399*4882a593Smuzhiyun from = (xkbIndicatorMapWireDesc *) &stuff[1];
3400*4882a593Smuzhiyun rc = _XkbSetIndicatorMap(client, dev, stuff->which, from);
3401*4882a593Smuzhiyun if (rc != Success)
3402*4882a593Smuzhiyun return rc;
3403*4882a593Smuzhiyun
3404*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd) {
3405*4882a593Smuzhiyun DeviceIntPtr other;
3406*4882a593Smuzhiyun
3407*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
3408*4882a593Smuzhiyun if ((other != dev) && other->key && !IsMaster(other) &&
3409*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) {
3410*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
3411*4882a593Smuzhiyun DixSetAttrAccess);
3412*4882a593Smuzhiyun if (rc == Success)
3413*4882a593Smuzhiyun _XkbSetIndicatorMap(client, other, stuff->which, from);
3414*4882a593Smuzhiyun }
3415*4882a593Smuzhiyun }
3416*4882a593Smuzhiyun }
3417*4882a593Smuzhiyun
3418*4882a593Smuzhiyun return Success;
3419*4882a593Smuzhiyun }
3420*4882a593Smuzhiyun
3421*4882a593Smuzhiyun /***====================================================================***/
3422*4882a593Smuzhiyun
3423*4882a593Smuzhiyun int
ProcXkbGetNamedIndicator(ClientPtr client)3424*4882a593Smuzhiyun ProcXkbGetNamedIndicator(ClientPtr client)
3425*4882a593Smuzhiyun {
3426*4882a593Smuzhiyun DeviceIntPtr dev;
3427*4882a593Smuzhiyun xkbGetNamedIndicatorReply rep;
3428*4882a593Smuzhiyun register int i = 0;
3429*4882a593Smuzhiyun XkbSrvLedInfoPtr sli;
3430*4882a593Smuzhiyun XkbIndicatorMapPtr map = NULL;
3431*4882a593Smuzhiyun
3432*4882a593Smuzhiyun REQUEST(xkbGetNamedIndicatorReq);
3433*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
3434*4882a593Smuzhiyun
3435*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
3436*4882a593Smuzhiyun return BadAccess;
3437*4882a593Smuzhiyun
3438*4882a593Smuzhiyun CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess);
3439*4882a593Smuzhiyun CHK_ATOM_ONLY(stuff->indicator);
3440*4882a593Smuzhiyun
3441*4882a593Smuzhiyun sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID, 0);
3442*4882a593Smuzhiyun if (!sli)
3443*4882a593Smuzhiyun return BadAlloc;
3444*4882a593Smuzhiyun
3445*4882a593Smuzhiyun i = 0;
3446*4882a593Smuzhiyun map = NULL;
3447*4882a593Smuzhiyun if ((sli->names) && (sli->maps)) {
3448*4882a593Smuzhiyun for (i = 0; i < XkbNumIndicators; i++) {
3449*4882a593Smuzhiyun if (stuff->indicator == sli->names[i]) {
3450*4882a593Smuzhiyun map = &sli->maps[i];
3451*4882a593Smuzhiyun break;
3452*4882a593Smuzhiyun }
3453*4882a593Smuzhiyun }
3454*4882a593Smuzhiyun }
3455*4882a593Smuzhiyun
3456*4882a593Smuzhiyun rep = (xkbGetNamedIndicatorReply) {
3457*4882a593Smuzhiyun .type = X_Reply,
3458*4882a593Smuzhiyun .sequenceNumber = client->sequence,
3459*4882a593Smuzhiyun .length = 0,
3460*4882a593Smuzhiyun .deviceID = dev->id,
3461*4882a593Smuzhiyun .indicator = stuff->indicator
3462*4882a593Smuzhiyun };
3463*4882a593Smuzhiyun if (map != NULL) {
3464*4882a593Smuzhiyun rep.found = TRUE;
3465*4882a593Smuzhiyun rep.on = ((sli->effectiveState & (1 << i)) != 0);
3466*4882a593Smuzhiyun rep.realIndicator = ((sli->physIndicators & (1 << i)) != 0);
3467*4882a593Smuzhiyun rep.ndx = i;
3468*4882a593Smuzhiyun rep.flags = map->flags;
3469*4882a593Smuzhiyun rep.whichGroups = map->which_groups;
3470*4882a593Smuzhiyun rep.groups = map->groups;
3471*4882a593Smuzhiyun rep.whichMods = map->which_mods;
3472*4882a593Smuzhiyun rep.mods = map->mods.mask;
3473*4882a593Smuzhiyun rep.realMods = map->mods.real_mods;
3474*4882a593Smuzhiyun rep.virtualMods = map->mods.vmods;
3475*4882a593Smuzhiyun rep.ctrls = map->ctrls;
3476*4882a593Smuzhiyun rep.supported = TRUE;
3477*4882a593Smuzhiyun }
3478*4882a593Smuzhiyun else {
3479*4882a593Smuzhiyun rep.found = FALSE;
3480*4882a593Smuzhiyun rep.on = FALSE;
3481*4882a593Smuzhiyun rep.realIndicator = FALSE;
3482*4882a593Smuzhiyun rep.ndx = XkbNoIndicator;
3483*4882a593Smuzhiyun rep.flags = 0;
3484*4882a593Smuzhiyun rep.whichGroups = 0;
3485*4882a593Smuzhiyun rep.groups = 0;
3486*4882a593Smuzhiyun rep.whichMods = 0;
3487*4882a593Smuzhiyun rep.mods = 0;
3488*4882a593Smuzhiyun rep.realMods = 0;
3489*4882a593Smuzhiyun rep.virtualMods = 0;
3490*4882a593Smuzhiyun rep.ctrls = 0;
3491*4882a593Smuzhiyun rep.supported = TRUE;
3492*4882a593Smuzhiyun }
3493*4882a593Smuzhiyun if (client->swapped) {
3494*4882a593Smuzhiyun swapl(&rep.length);
3495*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
3496*4882a593Smuzhiyun swapl(&rep.indicator);
3497*4882a593Smuzhiyun swaps(&rep.virtualMods);
3498*4882a593Smuzhiyun swapl(&rep.ctrls);
3499*4882a593Smuzhiyun }
3500*4882a593Smuzhiyun
3501*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbGetNamedIndicatorReply), &rep);
3502*4882a593Smuzhiyun return Success;
3503*4882a593Smuzhiyun }
3504*4882a593Smuzhiyun
3505*4882a593Smuzhiyun /**
3506*4882a593Smuzhiyun * Find the IM on the device.
3507*4882a593Smuzhiyun * Returns the map, or NULL if the map doesn't exist.
3508*4882a593Smuzhiyun * If the return value is NULL, led_return is undefined. Otherwise, led_return
3509*4882a593Smuzhiyun * is set to the led index of the map.
3510*4882a593Smuzhiyun */
3511*4882a593Smuzhiyun static XkbIndicatorMapPtr
_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli,Atom indicator,int * led_return)3512*4882a593Smuzhiyun _XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator, int *led_return)
3513*4882a593Smuzhiyun {
3514*4882a593Smuzhiyun XkbIndicatorMapPtr map;
3515*4882a593Smuzhiyun
3516*4882a593Smuzhiyun /* search for the right indicator */
3517*4882a593Smuzhiyun map = NULL;
3518*4882a593Smuzhiyun if (sli->names && sli->maps) {
3519*4882a593Smuzhiyun int led;
3520*4882a593Smuzhiyun
3521*4882a593Smuzhiyun for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) {
3522*4882a593Smuzhiyun if (sli->names[led] == indicator) {
3523*4882a593Smuzhiyun map = &sli->maps[led];
3524*4882a593Smuzhiyun *led_return = led;
3525*4882a593Smuzhiyun break;
3526*4882a593Smuzhiyun }
3527*4882a593Smuzhiyun }
3528*4882a593Smuzhiyun }
3529*4882a593Smuzhiyun
3530*4882a593Smuzhiyun return map;
3531*4882a593Smuzhiyun }
3532*4882a593Smuzhiyun
3533*4882a593Smuzhiyun /**
3534*4882a593Smuzhiyun * Creates an indicator map on the device. If dryRun is TRUE, it only checks
3535*4882a593Smuzhiyun * if creation is possible, but doesn't actually create it.
3536*4882a593Smuzhiyun */
3537*4882a593Smuzhiyun static int
_XkbCreateIndicatorMap(DeviceIntPtr dev,Atom indicator,int ledClass,int ledID,XkbIndicatorMapPtr * map_return,int * led_return,Bool dryRun)3538*4882a593Smuzhiyun _XkbCreateIndicatorMap(DeviceIntPtr dev, Atom indicator,
3539*4882a593Smuzhiyun int ledClass, int ledID,
3540*4882a593Smuzhiyun XkbIndicatorMapPtr * map_return, int *led_return,
3541*4882a593Smuzhiyun Bool dryRun)
3542*4882a593Smuzhiyun {
3543*4882a593Smuzhiyun XkbSrvLedInfoPtr sli;
3544*4882a593Smuzhiyun XkbIndicatorMapPtr map;
3545*4882a593Smuzhiyun int led;
3546*4882a593Smuzhiyun
3547*4882a593Smuzhiyun sli = XkbFindSrvLedInfo(dev, ledClass, ledID, XkbXI_IndicatorsMask);
3548*4882a593Smuzhiyun if (!sli)
3549*4882a593Smuzhiyun return BadAlloc;
3550*4882a593Smuzhiyun
3551*4882a593Smuzhiyun map = _XkbFindNamedIndicatorMap(sli, indicator, &led);
3552*4882a593Smuzhiyun
3553*4882a593Smuzhiyun if (!map) {
3554*4882a593Smuzhiyun /* find first unused indicator maps and assign the name to it */
3555*4882a593Smuzhiyun for (led = 0, map = NULL; (led < XkbNumIndicators) && (map == NULL);
3556*4882a593Smuzhiyun led++) {
3557*4882a593Smuzhiyun if ((sli->names) && (sli->maps) && (sli->names[led] == None) &&
3558*4882a593Smuzhiyun (!XkbIM_InUse(&sli->maps[led]))) {
3559*4882a593Smuzhiyun map = &sli->maps[led];
3560*4882a593Smuzhiyun if (!dryRun)
3561*4882a593Smuzhiyun sli->names[led] = indicator;
3562*4882a593Smuzhiyun break;
3563*4882a593Smuzhiyun }
3564*4882a593Smuzhiyun }
3565*4882a593Smuzhiyun }
3566*4882a593Smuzhiyun
3567*4882a593Smuzhiyun if (!map)
3568*4882a593Smuzhiyun return BadAlloc;
3569*4882a593Smuzhiyun
3570*4882a593Smuzhiyun *led_return = led;
3571*4882a593Smuzhiyun *map_return = map;
3572*4882a593Smuzhiyun return Success;
3573*4882a593Smuzhiyun }
3574*4882a593Smuzhiyun
3575*4882a593Smuzhiyun static int
_XkbSetNamedIndicator(ClientPtr client,DeviceIntPtr dev,xkbSetNamedIndicatorReq * stuff)3576*4882a593Smuzhiyun _XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev,
3577*4882a593Smuzhiyun xkbSetNamedIndicatorReq * stuff)
3578*4882a593Smuzhiyun {
3579*4882a593Smuzhiyun unsigned int extDevReason;
3580*4882a593Smuzhiyun unsigned int statec, namec, mapc;
3581*4882a593Smuzhiyun XkbSrvLedInfoPtr sli;
3582*4882a593Smuzhiyun int led = 0;
3583*4882a593Smuzhiyun XkbIndicatorMapPtr map;
3584*4882a593Smuzhiyun DeviceIntPtr kbd;
3585*4882a593Smuzhiyun XkbEventCauseRec cause;
3586*4882a593Smuzhiyun xkbExtensionDeviceNotify ed;
3587*4882a593Smuzhiyun XkbChangesRec changes;
3588*4882a593Smuzhiyun int rc;
3589*4882a593Smuzhiyun
3590*4882a593Smuzhiyun rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass,
3591*4882a593Smuzhiyun stuff->ledID, &map, &led, FALSE);
3592*4882a593Smuzhiyun if (rc != Success || !map) /* oh-oh */
3593*4882a593Smuzhiyun return rc;
3594*4882a593Smuzhiyun
3595*4882a593Smuzhiyun sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID,
3596*4882a593Smuzhiyun XkbXI_IndicatorsMask);
3597*4882a593Smuzhiyun if (!sli)
3598*4882a593Smuzhiyun return BadAlloc;
3599*4882a593Smuzhiyun
3600*4882a593Smuzhiyun namec = mapc = statec = 0;
3601*4882a593Smuzhiyun extDevReason = 0;
3602*4882a593Smuzhiyun
3603*4882a593Smuzhiyun namec |= (1 << led);
3604*4882a593Smuzhiyun sli->namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0);
3605*4882a593Smuzhiyun extDevReason |= XkbXI_IndicatorNamesMask;
3606*4882a593Smuzhiyun
3607*4882a593Smuzhiyun if (stuff->setMap) {
3608*4882a593Smuzhiyun map->flags = stuff->flags;
3609*4882a593Smuzhiyun map->which_groups = stuff->whichGroups;
3610*4882a593Smuzhiyun map->groups = stuff->groups;
3611*4882a593Smuzhiyun map->which_mods = stuff->whichMods;
3612*4882a593Smuzhiyun map->mods.mask = stuff->realMods;
3613*4882a593Smuzhiyun map->mods.real_mods = stuff->realMods;
3614*4882a593Smuzhiyun map->mods.vmods = stuff->virtualMods;
3615*4882a593Smuzhiyun map->ctrls = stuff->ctrls;
3616*4882a593Smuzhiyun mapc |= (1 << led);
3617*4882a593Smuzhiyun }
3618*4882a593Smuzhiyun
3619*4882a593Smuzhiyun if ((stuff->setState) && ((map->flags & XkbIM_NoExplicit) == 0)) {
3620*4882a593Smuzhiyun if (stuff->on)
3621*4882a593Smuzhiyun sli->explicitState |= (1 << led);
3622*4882a593Smuzhiyun else
3623*4882a593Smuzhiyun sli->explicitState &= ~(1 << led);
3624*4882a593Smuzhiyun statec |= ((sli->effectiveState ^ sli->explicitState) & (1 << led));
3625*4882a593Smuzhiyun }
3626*4882a593Smuzhiyun
3627*4882a593Smuzhiyun memset((char *) &ed, 0, sizeof(xkbExtensionDeviceNotify));
3628*4882a593Smuzhiyun memset((char *) &changes, 0, sizeof(XkbChangesRec));
3629*4882a593Smuzhiyun XkbSetCauseXkbReq(&cause, X_kbSetNamedIndicator, client);
3630*4882a593Smuzhiyun if (namec)
3631*4882a593Smuzhiyun XkbApplyLedNameChanges(dev, sli, namec, &ed, &changes, &cause);
3632*4882a593Smuzhiyun if (mapc)
3633*4882a593Smuzhiyun XkbApplyLedMapChanges(dev, sli, mapc, &ed, &changes, &cause);
3634*4882a593Smuzhiyun if (statec)
3635*4882a593Smuzhiyun XkbApplyLedStateChanges(dev, sli, statec, &ed, &changes, &cause);
3636*4882a593Smuzhiyun
3637*4882a593Smuzhiyun kbd = dev;
3638*4882a593Smuzhiyun if ((sli->flags & XkbSLI_HasOwnState) == 0)
3639*4882a593Smuzhiyun kbd = inputInfo.keyboard;
3640*4882a593Smuzhiyun XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause);
3641*4882a593Smuzhiyun
3642*4882a593Smuzhiyun return Success;
3643*4882a593Smuzhiyun }
3644*4882a593Smuzhiyun
3645*4882a593Smuzhiyun int
ProcXkbSetNamedIndicator(ClientPtr client)3646*4882a593Smuzhiyun ProcXkbSetNamedIndicator(ClientPtr client)
3647*4882a593Smuzhiyun {
3648*4882a593Smuzhiyun int rc;
3649*4882a593Smuzhiyun DeviceIntPtr dev;
3650*4882a593Smuzhiyun int led = 0;
3651*4882a593Smuzhiyun XkbIndicatorMapPtr map;
3652*4882a593Smuzhiyun
3653*4882a593Smuzhiyun REQUEST(xkbSetNamedIndicatorReq);
3654*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq);
3655*4882a593Smuzhiyun
3656*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
3657*4882a593Smuzhiyun return BadAccess;
3658*4882a593Smuzhiyun
3659*4882a593Smuzhiyun CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
3660*4882a593Smuzhiyun CHK_ATOM_ONLY(stuff->indicator);
3661*4882a593Smuzhiyun CHK_MASK_LEGAL(0x10, stuff->whichGroups, XkbIM_UseAnyGroup);
3662*4882a593Smuzhiyun CHK_MASK_LEGAL(0x11, stuff->whichMods, XkbIM_UseAnyMods);
3663*4882a593Smuzhiyun
3664*4882a593Smuzhiyun /* Dry-run for checks */
3665*4882a593Smuzhiyun rc = _XkbCreateIndicatorMap(dev, stuff->indicator,
3666*4882a593Smuzhiyun stuff->ledClass, stuff->ledID,
3667*4882a593Smuzhiyun &map, &led, TRUE);
3668*4882a593Smuzhiyun if (rc != Success || !map) /* couldn't be created or didn't exist */
3669*4882a593Smuzhiyun return rc;
3670*4882a593Smuzhiyun
3671*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd ||
3672*4882a593Smuzhiyun stuff->deviceSpec == XkbUseCorePtr) {
3673*4882a593Smuzhiyun DeviceIntPtr other;
3674*4882a593Smuzhiyun
3675*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
3676*4882a593Smuzhiyun if ((other != dev) && !IsMaster(other) &&
3677*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev && (other->kbdfeed ||
3678*4882a593Smuzhiyun other->leds) &&
3679*4882a593Smuzhiyun (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess)
3680*4882a593Smuzhiyun == Success)) {
3681*4882a593Smuzhiyun rc = _XkbCreateIndicatorMap(other, stuff->indicator,
3682*4882a593Smuzhiyun stuff->ledClass, stuff->ledID, &map,
3683*4882a593Smuzhiyun &led, TRUE);
3684*4882a593Smuzhiyun if (rc != Success || !map)
3685*4882a593Smuzhiyun return rc;
3686*4882a593Smuzhiyun }
3687*4882a593Smuzhiyun }
3688*4882a593Smuzhiyun }
3689*4882a593Smuzhiyun
3690*4882a593Smuzhiyun /* All checks passed, let's do it */
3691*4882a593Smuzhiyun rc = _XkbSetNamedIndicator(client, dev, stuff);
3692*4882a593Smuzhiyun if (rc != Success)
3693*4882a593Smuzhiyun return rc;
3694*4882a593Smuzhiyun
3695*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd ||
3696*4882a593Smuzhiyun stuff->deviceSpec == XkbUseCorePtr) {
3697*4882a593Smuzhiyun DeviceIntPtr other;
3698*4882a593Smuzhiyun
3699*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
3700*4882a593Smuzhiyun if ((other != dev) && !IsMaster(other) &&
3701*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev && (other->kbdfeed ||
3702*4882a593Smuzhiyun other->leds) &&
3703*4882a593Smuzhiyun (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess)
3704*4882a593Smuzhiyun == Success)) {
3705*4882a593Smuzhiyun _XkbSetNamedIndicator(client, other, stuff);
3706*4882a593Smuzhiyun }
3707*4882a593Smuzhiyun }
3708*4882a593Smuzhiyun }
3709*4882a593Smuzhiyun
3710*4882a593Smuzhiyun return Success;
3711*4882a593Smuzhiyun }
3712*4882a593Smuzhiyun
3713*4882a593Smuzhiyun /***====================================================================***/
3714*4882a593Smuzhiyun
3715*4882a593Smuzhiyun static CARD32
_XkbCountAtoms(Atom * atoms,int maxAtoms,int * count)3716*4882a593Smuzhiyun _XkbCountAtoms(Atom *atoms, int maxAtoms, int *count)
3717*4882a593Smuzhiyun {
3718*4882a593Smuzhiyun register unsigned int i, bit, nAtoms;
3719*4882a593Smuzhiyun register CARD32 atomsPresent;
3720*4882a593Smuzhiyun
3721*4882a593Smuzhiyun for (i = nAtoms = atomsPresent = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) {
3722*4882a593Smuzhiyun if (atoms[i] != None) {
3723*4882a593Smuzhiyun atomsPresent |= bit;
3724*4882a593Smuzhiyun nAtoms++;
3725*4882a593Smuzhiyun }
3726*4882a593Smuzhiyun }
3727*4882a593Smuzhiyun if (count)
3728*4882a593Smuzhiyun *count = nAtoms;
3729*4882a593Smuzhiyun return atomsPresent;
3730*4882a593Smuzhiyun }
3731*4882a593Smuzhiyun
3732*4882a593Smuzhiyun static char *
_XkbWriteAtoms(char * wire,Atom * atoms,int maxAtoms,int swap)3733*4882a593Smuzhiyun _XkbWriteAtoms(char *wire, Atom *atoms, int maxAtoms, int swap)
3734*4882a593Smuzhiyun {
3735*4882a593Smuzhiyun register unsigned int i;
3736*4882a593Smuzhiyun Atom *atm;
3737*4882a593Smuzhiyun
3738*4882a593Smuzhiyun atm = (Atom *) wire;
3739*4882a593Smuzhiyun for (i = 0; i < maxAtoms; i++) {
3740*4882a593Smuzhiyun if (atoms[i] != None) {
3741*4882a593Smuzhiyun *atm = atoms[i];
3742*4882a593Smuzhiyun if (swap) {
3743*4882a593Smuzhiyun swapl(atm);
3744*4882a593Smuzhiyun }
3745*4882a593Smuzhiyun atm++;
3746*4882a593Smuzhiyun }
3747*4882a593Smuzhiyun }
3748*4882a593Smuzhiyun return (char *) atm;
3749*4882a593Smuzhiyun }
3750*4882a593Smuzhiyun
3751*4882a593Smuzhiyun static Status
XkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply * rep)3752*4882a593Smuzhiyun XkbComputeGetNamesReplySize(XkbDescPtr xkb, xkbGetNamesReply * rep)
3753*4882a593Smuzhiyun {
3754*4882a593Smuzhiyun register unsigned which, length;
3755*4882a593Smuzhiyun register int i;
3756*4882a593Smuzhiyun
3757*4882a593Smuzhiyun rep->minKeyCode = xkb->min_key_code;
3758*4882a593Smuzhiyun rep->maxKeyCode = xkb->max_key_code;
3759*4882a593Smuzhiyun which = rep->which;
3760*4882a593Smuzhiyun length = 0;
3761*4882a593Smuzhiyun if (xkb->names != NULL) {
3762*4882a593Smuzhiyun if (which & XkbKeycodesNameMask)
3763*4882a593Smuzhiyun length++;
3764*4882a593Smuzhiyun if (which & XkbGeometryNameMask)
3765*4882a593Smuzhiyun length++;
3766*4882a593Smuzhiyun if (which & XkbSymbolsNameMask)
3767*4882a593Smuzhiyun length++;
3768*4882a593Smuzhiyun if (which & XkbPhysSymbolsNameMask)
3769*4882a593Smuzhiyun length++;
3770*4882a593Smuzhiyun if (which & XkbTypesNameMask)
3771*4882a593Smuzhiyun length++;
3772*4882a593Smuzhiyun if (which & XkbCompatNameMask)
3773*4882a593Smuzhiyun length++;
3774*4882a593Smuzhiyun }
3775*4882a593Smuzhiyun else
3776*4882a593Smuzhiyun which &= ~XkbComponentNamesMask;
3777*4882a593Smuzhiyun
3778*4882a593Smuzhiyun if (xkb->map != NULL) {
3779*4882a593Smuzhiyun if (which & XkbKeyTypeNamesMask)
3780*4882a593Smuzhiyun length += xkb->map->num_types;
3781*4882a593Smuzhiyun rep->nTypes = xkb->map->num_types;
3782*4882a593Smuzhiyun if (which & XkbKTLevelNamesMask) {
3783*4882a593Smuzhiyun XkbKeyTypePtr pType = xkb->map->types;
3784*4882a593Smuzhiyun int nKTLevels = 0;
3785*4882a593Smuzhiyun
3786*4882a593Smuzhiyun length += XkbPaddedSize(xkb->map->num_types) / 4;
3787*4882a593Smuzhiyun for (i = 0; i < xkb->map->num_types; i++, pType++) {
3788*4882a593Smuzhiyun if (pType->level_names != NULL)
3789*4882a593Smuzhiyun nKTLevels += pType->num_levels;
3790*4882a593Smuzhiyun }
3791*4882a593Smuzhiyun rep->nKTLevels = nKTLevels;
3792*4882a593Smuzhiyun length += nKTLevels;
3793*4882a593Smuzhiyun }
3794*4882a593Smuzhiyun }
3795*4882a593Smuzhiyun else {
3796*4882a593Smuzhiyun rep->nTypes = 0;
3797*4882a593Smuzhiyun rep->nKTLevels = 0;
3798*4882a593Smuzhiyun which &= ~(XkbKeyTypeNamesMask | XkbKTLevelNamesMask);
3799*4882a593Smuzhiyun }
3800*4882a593Smuzhiyun
3801*4882a593Smuzhiyun rep->minKeyCode = xkb->min_key_code;
3802*4882a593Smuzhiyun rep->maxKeyCode = xkb->max_key_code;
3803*4882a593Smuzhiyun rep->indicators = 0;
3804*4882a593Smuzhiyun rep->virtualMods = 0;
3805*4882a593Smuzhiyun rep->groupNames = 0;
3806*4882a593Smuzhiyun if (xkb->names != NULL) {
3807*4882a593Smuzhiyun if (which & XkbIndicatorNamesMask) {
3808*4882a593Smuzhiyun int nLeds;
3809*4882a593Smuzhiyun
3810*4882a593Smuzhiyun rep->indicators =
3811*4882a593Smuzhiyun _XkbCountAtoms(xkb->names->indicators, XkbNumIndicators,
3812*4882a593Smuzhiyun &nLeds);
3813*4882a593Smuzhiyun length += nLeds;
3814*4882a593Smuzhiyun if (nLeds == 0)
3815*4882a593Smuzhiyun which &= ~XkbIndicatorNamesMask;
3816*4882a593Smuzhiyun }
3817*4882a593Smuzhiyun
3818*4882a593Smuzhiyun if (which & XkbVirtualModNamesMask) {
3819*4882a593Smuzhiyun int nVMods;
3820*4882a593Smuzhiyun
3821*4882a593Smuzhiyun rep->virtualMods =
3822*4882a593Smuzhiyun _XkbCountAtoms(xkb->names->vmods, XkbNumVirtualMods, &nVMods);
3823*4882a593Smuzhiyun length += nVMods;
3824*4882a593Smuzhiyun if (nVMods == 0)
3825*4882a593Smuzhiyun which &= ~XkbVirtualModNamesMask;
3826*4882a593Smuzhiyun }
3827*4882a593Smuzhiyun
3828*4882a593Smuzhiyun if (which & XkbGroupNamesMask) {
3829*4882a593Smuzhiyun int nGroups;
3830*4882a593Smuzhiyun
3831*4882a593Smuzhiyun rep->groupNames =
3832*4882a593Smuzhiyun _XkbCountAtoms(xkb->names->groups, XkbNumKbdGroups, &nGroups);
3833*4882a593Smuzhiyun length += nGroups;
3834*4882a593Smuzhiyun if (nGroups == 0)
3835*4882a593Smuzhiyun which &= ~XkbGroupNamesMask;
3836*4882a593Smuzhiyun }
3837*4882a593Smuzhiyun
3838*4882a593Smuzhiyun if ((which & XkbKeyNamesMask) && (xkb->names->keys))
3839*4882a593Smuzhiyun length += rep->nKeys;
3840*4882a593Smuzhiyun else
3841*4882a593Smuzhiyun which &= ~XkbKeyNamesMask;
3842*4882a593Smuzhiyun
3843*4882a593Smuzhiyun if ((which & XkbKeyAliasesMask) &&
3844*4882a593Smuzhiyun (xkb->names->key_aliases) && (xkb->names->num_key_aliases > 0)) {
3845*4882a593Smuzhiyun rep->nKeyAliases = xkb->names->num_key_aliases;
3846*4882a593Smuzhiyun length += rep->nKeyAliases * 2;
3847*4882a593Smuzhiyun }
3848*4882a593Smuzhiyun else {
3849*4882a593Smuzhiyun which &= ~XkbKeyAliasesMask;
3850*4882a593Smuzhiyun rep->nKeyAliases = 0;
3851*4882a593Smuzhiyun }
3852*4882a593Smuzhiyun
3853*4882a593Smuzhiyun if ((which & XkbRGNamesMask) && (xkb->names->num_rg > 0))
3854*4882a593Smuzhiyun length += xkb->names->num_rg;
3855*4882a593Smuzhiyun else
3856*4882a593Smuzhiyun which &= ~XkbRGNamesMask;
3857*4882a593Smuzhiyun }
3858*4882a593Smuzhiyun else {
3859*4882a593Smuzhiyun which &= ~(XkbIndicatorNamesMask | XkbVirtualModNamesMask);
3860*4882a593Smuzhiyun which &= ~(XkbGroupNamesMask | XkbKeyNamesMask | XkbKeyAliasesMask);
3861*4882a593Smuzhiyun which &= ~XkbRGNamesMask;
3862*4882a593Smuzhiyun }
3863*4882a593Smuzhiyun
3864*4882a593Smuzhiyun rep->length = length;
3865*4882a593Smuzhiyun rep->which = which;
3866*4882a593Smuzhiyun return Success;
3867*4882a593Smuzhiyun }
3868*4882a593Smuzhiyun
3869*4882a593Smuzhiyun static int
XkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply * rep)3870*4882a593Smuzhiyun XkbSendNames(ClientPtr client, XkbDescPtr xkb, xkbGetNamesReply * rep)
3871*4882a593Smuzhiyun {
3872*4882a593Smuzhiyun register unsigned i, length, which;
3873*4882a593Smuzhiyun char *start;
3874*4882a593Smuzhiyun char *desc;
3875*4882a593Smuzhiyun
3876*4882a593Smuzhiyun length = rep->length * 4;
3877*4882a593Smuzhiyun which = rep->which;
3878*4882a593Smuzhiyun if (client->swapped) {
3879*4882a593Smuzhiyun swaps(&rep->sequenceNumber);
3880*4882a593Smuzhiyun swapl(&rep->length);
3881*4882a593Smuzhiyun swapl(&rep->which);
3882*4882a593Smuzhiyun swaps(&rep->virtualMods);
3883*4882a593Smuzhiyun swapl(&rep->indicators);
3884*4882a593Smuzhiyun }
3885*4882a593Smuzhiyun
3886*4882a593Smuzhiyun start = desc = calloc(1, length);
3887*4882a593Smuzhiyun if (!start)
3888*4882a593Smuzhiyun return BadAlloc;
3889*4882a593Smuzhiyun if (xkb->names) {
3890*4882a593Smuzhiyun if (which & XkbKeycodesNameMask) {
3891*4882a593Smuzhiyun *((CARD32 *) desc) = xkb->names->keycodes;
3892*4882a593Smuzhiyun if (client->swapped) {
3893*4882a593Smuzhiyun swapl((int *) desc);
3894*4882a593Smuzhiyun }
3895*4882a593Smuzhiyun desc += 4;
3896*4882a593Smuzhiyun }
3897*4882a593Smuzhiyun if (which & XkbGeometryNameMask) {
3898*4882a593Smuzhiyun *((CARD32 *) desc) = xkb->names->geometry;
3899*4882a593Smuzhiyun if (client->swapped) {
3900*4882a593Smuzhiyun swapl((int *) desc);
3901*4882a593Smuzhiyun }
3902*4882a593Smuzhiyun desc += 4;
3903*4882a593Smuzhiyun }
3904*4882a593Smuzhiyun if (which & XkbSymbolsNameMask) {
3905*4882a593Smuzhiyun *((CARD32 *) desc) = xkb->names->symbols;
3906*4882a593Smuzhiyun if (client->swapped) {
3907*4882a593Smuzhiyun swapl((int *) desc);
3908*4882a593Smuzhiyun }
3909*4882a593Smuzhiyun desc += 4;
3910*4882a593Smuzhiyun }
3911*4882a593Smuzhiyun if (which & XkbPhysSymbolsNameMask) {
3912*4882a593Smuzhiyun register CARD32 *atm = (CARD32 *) desc;
3913*4882a593Smuzhiyun
3914*4882a593Smuzhiyun atm[0] = (CARD32) xkb->names->phys_symbols;
3915*4882a593Smuzhiyun if (client->swapped) {
3916*4882a593Smuzhiyun swapl(&atm[0]);
3917*4882a593Smuzhiyun }
3918*4882a593Smuzhiyun desc += 4;
3919*4882a593Smuzhiyun }
3920*4882a593Smuzhiyun if (which & XkbTypesNameMask) {
3921*4882a593Smuzhiyun *((CARD32 *) desc) = (CARD32) xkb->names->types;
3922*4882a593Smuzhiyun if (client->swapped) {
3923*4882a593Smuzhiyun swapl((int *) desc);
3924*4882a593Smuzhiyun }
3925*4882a593Smuzhiyun desc += 4;
3926*4882a593Smuzhiyun }
3927*4882a593Smuzhiyun if (which & XkbCompatNameMask) {
3928*4882a593Smuzhiyun *((CARD32 *) desc) = (CARD32) xkb->names->compat;
3929*4882a593Smuzhiyun if (client->swapped) {
3930*4882a593Smuzhiyun swapl((int *) desc);
3931*4882a593Smuzhiyun }
3932*4882a593Smuzhiyun desc += 4;
3933*4882a593Smuzhiyun }
3934*4882a593Smuzhiyun if (which & XkbKeyTypeNamesMask) {
3935*4882a593Smuzhiyun register CARD32 *atm = (CARD32 *) desc;
3936*4882a593Smuzhiyun register XkbKeyTypePtr type = xkb->map->types;
3937*4882a593Smuzhiyun
3938*4882a593Smuzhiyun for (i = 0; i < xkb->map->num_types; i++, atm++, type++) {
3939*4882a593Smuzhiyun *atm = (CARD32) type->name;
3940*4882a593Smuzhiyun if (client->swapped) {
3941*4882a593Smuzhiyun swapl(atm);
3942*4882a593Smuzhiyun }
3943*4882a593Smuzhiyun }
3944*4882a593Smuzhiyun desc = (char *) atm;
3945*4882a593Smuzhiyun }
3946*4882a593Smuzhiyun if (which & XkbKTLevelNamesMask && xkb->map) {
3947*4882a593Smuzhiyun XkbKeyTypePtr type = xkb->map->types;
3948*4882a593Smuzhiyun register CARD32 *atm;
3949*4882a593Smuzhiyun
3950*4882a593Smuzhiyun for (i = 0; i < rep->nTypes; i++, type++) {
3951*4882a593Smuzhiyun *desc++ = type->num_levels;
3952*4882a593Smuzhiyun }
3953*4882a593Smuzhiyun desc += XkbPaddedSize(rep->nTypes) - rep->nTypes;
3954*4882a593Smuzhiyun
3955*4882a593Smuzhiyun atm = (CARD32 *) desc;
3956*4882a593Smuzhiyun type = xkb->map->types;
3957*4882a593Smuzhiyun for (i = 0; i < xkb->map->num_types; i++, type++) {
3958*4882a593Smuzhiyun register unsigned l;
3959*4882a593Smuzhiyun
3960*4882a593Smuzhiyun if (type->level_names) {
3961*4882a593Smuzhiyun for (l = 0; l < type->num_levels; l++, atm++) {
3962*4882a593Smuzhiyun *atm = type->level_names[l];
3963*4882a593Smuzhiyun if (client->swapped) {
3964*4882a593Smuzhiyun swapl(atm);
3965*4882a593Smuzhiyun }
3966*4882a593Smuzhiyun }
3967*4882a593Smuzhiyun desc += type->num_levels * 4;
3968*4882a593Smuzhiyun }
3969*4882a593Smuzhiyun }
3970*4882a593Smuzhiyun }
3971*4882a593Smuzhiyun if (which & XkbIndicatorNamesMask) {
3972*4882a593Smuzhiyun desc =
3973*4882a593Smuzhiyun _XkbWriteAtoms(desc, xkb->names->indicators, XkbNumIndicators,
3974*4882a593Smuzhiyun client->swapped);
3975*4882a593Smuzhiyun }
3976*4882a593Smuzhiyun if (which & XkbVirtualModNamesMask) {
3977*4882a593Smuzhiyun desc = _XkbWriteAtoms(desc, xkb->names->vmods, XkbNumVirtualMods,
3978*4882a593Smuzhiyun client->swapped);
3979*4882a593Smuzhiyun }
3980*4882a593Smuzhiyun if (which & XkbGroupNamesMask) {
3981*4882a593Smuzhiyun desc = _XkbWriteAtoms(desc, xkb->names->groups, XkbNumKbdGroups,
3982*4882a593Smuzhiyun client->swapped);
3983*4882a593Smuzhiyun }
3984*4882a593Smuzhiyun if (which & XkbKeyNamesMask) {
3985*4882a593Smuzhiyun for (i = 0; i < rep->nKeys; i++, desc += sizeof(XkbKeyNameRec)) {
3986*4882a593Smuzhiyun *((XkbKeyNamePtr) desc) = xkb->names->keys[i + rep->firstKey];
3987*4882a593Smuzhiyun }
3988*4882a593Smuzhiyun }
3989*4882a593Smuzhiyun if (which & XkbKeyAliasesMask) {
3990*4882a593Smuzhiyun XkbKeyAliasPtr pAl;
3991*4882a593Smuzhiyun
3992*4882a593Smuzhiyun pAl = xkb->names->key_aliases;
3993*4882a593Smuzhiyun for (i = 0; i < rep->nKeyAliases;
3994*4882a593Smuzhiyun i++, pAl++, desc += 2 * XkbKeyNameLength) {
3995*4882a593Smuzhiyun *((XkbKeyAliasPtr) desc) = *pAl;
3996*4882a593Smuzhiyun }
3997*4882a593Smuzhiyun }
3998*4882a593Smuzhiyun if ((which & XkbRGNamesMask) && (rep->nRadioGroups > 0)) {
3999*4882a593Smuzhiyun register CARD32 *atm = (CARD32 *) desc;
4000*4882a593Smuzhiyun
4001*4882a593Smuzhiyun for (i = 0; i < rep->nRadioGroups; i++, atm++) {
4002*4882a593Smuzhiyun *atm = (CARD32) xkb->names->radio_groups[i];
4003*4882a593Smuzhiyun if (client->swapped) {
4004*4882a593Smuzhiyun swapl(atm);
4005*4882a593Smuzhiyun }
4006*4882a593Smuzhiyun }
4007*4882a593Smuzhiyun desc += rep->nRadioGroups * 4;
4008*4882a593Smuzhiyun }
4009*4882a593Smuzhiyun }
4010*4882a593Smuzhiyun
4011*4882a593Smuzhiyun if ((desc - start) != (length)) {
4012*4882a593Smuzhiyun ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n",
4013*4882a593Smuzhiyun length, (unsigned long) (desc - start));
4014*4882a593Smuzhiyun }
4015*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbGetNamesReply), rep);
4016*4882a593Smuzhiyun WriteToClient(client, length, start);
4017*4882a593Smuzhiyun free((char *) start);
4018*4882a593Smuzhiyun return Success;
4019*4882a593Smuzhiyun }
4020*4882a593Smuzhiyun
4021*4882a593Smuzhiyun int
ProcXkbGetNames(ClientPtr client)4022*4882a593Smuzhiyun ProcXkbGetNames(ClientPtr client)
4023*4882a593Smuzhiyun {
4024*4882a593Smuzhiyun DeviceIntPtr dev;
4025*4882a593Smuzhiyun XkbDescPtr xkb;
4026*4882a593Smuzhiyun xkbGetNamesReply rep;
4027*4882a593Smuzhiyun
4028*4882a593Smuzhiyun REQUEST(xkbGetNamesReq);
4029*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbGetNamesReq);
4030*4882a593Smuzhiyun
4031*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
4032*4882a593Smuzhiyun return BadAccess;
4033*4882a593Smuzhiyun
4034*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
4035*4882a593Smuzhiyun CHK_MASK_LEGAL(0x01, stuff->which, XkbAllNamesMask);
4036*4882a593Smuzhiyun
4037*4882a593Smuzhiyun xkb = dev->key->xkbInfo->desc;
4038*4882a593Smuzhiyun rep = (xkbGetNamesReply) {
4039*4882a593Smuzhiyun .type = X_Reply,
4040*4882a593Smuzhiyun .deviceID = dev->id,
4041*4882a593Smuzhiyun .sequenceNumber = client->sequence,
4042*4882a593Smuzhiyun .length = 0,
4043*4882a593Smuzhiyun .which = stuff->which,
4044*4882a593Smuzhiyun .nTypes = xkb->map->num_types,
4045*4882a593Smuzhiyun .firstKey = xkb->min_key_code,
4046*4882a593Smuzhiyun .nKeys = XkbNumKeys(xkb),
4047*4882a593Smuzhiyun .nKeyAliases = xkb->names ? xkb->names->num_key_aliases : 0,
4048*4882a593Smuzhiyun .nRadioGroups = xkb->names ? xkb->names->num_rg : 0
4049*4882a593Smuzhiyun };
4050*4882a593Smuzhiyun XkbComputeGetNamesReplySize(xkb, &rep);
4051*4882a593Smuzhiyun return XkbSendNames(client, xkb, &rep);
4052*4882a593Smuzhiyun }
4053*4882a593Smuzhiyun
4054*4882a593Smuzhiyun /***====================================================================***/
4055*4882a593Smuzhiyun
4056*4882a593Smuzhiyun static CARD32 *
_XkbCheckAtoms(CARD32 * wire,int nAtoms,int swapped,Atom * pError)4057*4882a593Smuzhiyun _XkbCheckAtoms(CARD32 *wire, int nAtoms, int swapped, Atom *pError)
4058*4882a593Smuzhiyun {
4059*4882a593Smuzhiyun register int i;
4060*4882a593Smuzhiyun
4061*4882a593Smuzhiyun for (i = 0; i < nAtoms; i++, wire++) {
4062*4882a593Smuzhiyun if (swapped) {
4063*4882a593Smuzhiyun swapl(wire);
4064*4882a593Smuzhiyun }
4065*4882a593Smuzhiyun if ((((Atom) *wire) != None) && (!ValidAtom((Atom) *wire))) {
4066*4882a593Smuzhiyun *pError = ((Atom) *wire);
4067*4882a593Smuzhiyun return NULL;
4068*4882a593Smuzhiyun }
4069*4882a593Smuzhiyun }
4070*4882a593Smuzhiyun return wire;
4071*4882a593Smuzhiyun }
4072*4882a593Smuzhiyun
4073*4882a593Smuzhiyun static CARD32 *
_XkbCheckMaskedAtoms(CARD32 * wire,int nAtoms,CARD32 present,int swapped,Atom * pError)4074*4882a593Smuzhiyun _XkbCheckMaskedAtoms(CARD32 *wire, int nAtoms, CARD32 present, int swapped,
4075*4882a593Smuzhiyun Atom *pError)
4076*4882a593Smuzhiyun {
4077*4882a593Smuzhiyun register unsigned i, bit;
4078*4882a593Smuzhiyun
4079*4882a593Smuzhiyun for (i = 0, bit = 1; (i < nAtoms) && (present); i++, bit <<= 1) {
4080*4882a593Smuzhiyun if ((present & bit) == 0)
4081*4882a593Smuzhiyun continue;
4082*4882a593Smuzhiyun if (swapped) {
4083*4882a593Smuzhiyun swapl(wire);
4084*4882a593Smuzhiyun }
4085*4882a593Smuzhiyun if ((((Atom) *wire) != None) && (!ValidAtom(((Atom) *wire)))) {
4086*4882a593Smuzhiyun *pError = (Atom) *wire;
4087*4882a593Smuzhiyun return NULL;
4088*4882a593Smuzhiyun }
4089*4882a593Smuzhiyun wire++;
4090*4882a593Smuzhiyun }
4091*4882a593Smuzhiyun return wire;
4092*4882a593Smuzhiyun }
4093*4882a593Smuzhiyun
4094*4882a593Smuzhiyun static Atom *
_XkbCopyMaskedAtoms(Atom * wire,Atom * dest,int nAtoms,CARD32 present)4095*4882a593Smuzhiyun _XkbCopyMaskedAtoms(Atom *wire, Atom *dest, int nAtoms, CARD32 present)
4096*4882a593Smuzhiyun {
4097*4882a593Smuzhiyun register int i, bit;
4098*4882a593Smuzhiyun
4099*4882a593Smuzhiyun for (i = 0, bit = 1; (i < nAtoms) && (present); i++, bit <<= 1) {
4100*4882a593Smuzhiyun if ((present & bit) == 0)
4101*4882a593Smuzhiyun continue;
4102*4882a593Smuzhiyun dest[i] = *wire++;
4103*4882a593Smuzhiyun }
4104*4882a593Smuzhiyun return wire;
4105*4882a593Smuzhiyun }
4106*4882a593Smuzhiyun
4107*4882a593Smuzhiyun static Bool
_XkbCheckTypeName(Atom name,int typeNdx)4108*4882a593Smuzhiyun _XkbCheckTypeName(Atom name, int typeNdx)
4109*4882a593Smuzhiyun {
4110*4882a593Smuzhiyun const char *str;
4111*4882a593Smuzhiyun
4112*4882a593Smuzhiyun str = NameForAtom(name);
4113*4882a593Smuzhiyun if ((strcmp(str, "ONE_LEVEL") == 0) || (strcmp(str, "TWO_LEVEL") == 0) ||
4114*4882a593Smuzhiyun (strcmp(str, "ALPHABETIC") == 0) || (strcmp(str, "KEYPAD") == 0))
4115*4882a593Smuzhiyun return FALSE;
4116*4882a593Smuzhiyun return TRUE;
4117*4882a593Smuzhiyun }
4118*4882a593Smuzhiyun
4119*4882a593Smuzhiyun /**
4120*4882a593Smuzhiyun * Check the device-dependent data in the request against the device. Returns
4121*4882a593Smuzhiyun * Success, or the appropriate error code.
4122*4882a593Smuzhiyun */
4123*4882a593Smuzhiyun static int
_XkbSetNamesCheck(ClientPtr client,DeviceIntPtr dev,xkbSetNamesReq * stuff,CARD32 * data)4124*4882a593Smuzhiyun _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev,
4125*4882a593Smuzhiyun xkbSetNamesReq * stuff, CARD32 *data)
4126*4882a593Smuzhiyun {
4127*4882a593Smuzhiyun XkbDescRec *xkb;
4128*4882a593Smuzhiyun CARD32 *tmp;
4129*4882a593Smuzhiyun Atom bad = None;
4130*4882a593Smuzhiyun
4131*4882a593Smuzhiyun tmp = data;
4132*4882a593Smuzhiyun xkb = dev->key->xkbInfo->desc;
4133*4882a593Smuzhiyun
4134*4882a593Smuzhiyun if (stuff->which & XkbKeyTypeNamesMask) {
4135*4882a593Smuzhiyun int i;
4136*4882a593Smuzhiyun CARD32 *old;
4137*4882a593Smuzhiyun
4138*4882a593Smuzhiyun if (stuff->nTypes < 1) {
4139*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x02, stuff->nTypes);
4140*4882a593Smuzhiyun return BadValue;
4141*4882a593Smuzhiyun }
4142*4882a593Smuzhiyun if ((unsigned) (stuff->firstType + stuff->nTypes - 1) >=
4143*4882a593Smuzhiyun xkb->map->num_types) {
4144*4882a593Smuzhiyun client->errorValue =
4145*4882a593Smuzhiyun _XkbErrCode4(0x03, stuff->firstType, stuff->nTypes,
4146*4882a593Smuzhiyun xkb->map->num_types);
4147*4882a593Smuzhiyun return BadValue;
4148*4882a593Smuzhiyun }
4149*4882a593Smuzhiyun if (((unsigned) stuff->firstType) <= XkbLastRequiredType) {
4150*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x04, stuff->firstType);
4151*4882a593Smuzhiyun return BadAccess;
4152*4882a593Smuzhiyun }
4153*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + stuff->nTypes))
4154*4882a593Smuzhiyun return BadLength;
4155*4882a593Smuzhiyun old = tmp;
4156*4882a593Smuzhiyun tmp = _XkbCheckAtoms(tmp, stuff->nTypes, client->swapped, &bad);
4157*4882a593Smuzhiyun if (!tmp) {
4158*4882a593Smuzhiyun client->errorValue = bad;
4159*4882a593Smuzhiyun return BadAtom;
4160*4882a593Smuzhiyun }
4161*4882a593Smuzhiyun for (i = 0; i < stuff->nTypes; i++, old++) {
4162*4882a593Smuzhiyun if (!_XkbCheckTypeName((Atom) *old, stuff->firstType + i))
4163*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x05, i);
4164*4882a593Smuzhiyun }
4165*4882a593Smuzhiyun }
4166*4882a593Smuzhiyun if (stuff->which & XkbKTLevelNamesMask) {
4167*4882a593Smuzhiyun unsigned i;
4168*4882a593Smuzhiyun XkbKeyTypePtr type;
4169*4882a593Smuzhiyun CARD8 *width;
4170*4882a593Smuzhiyun
4171*4882a593Smuzhiyun if (stuff->nKTLevels < 1) {
4172*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x05, stuff->nKTLevels);
4173*4882a593Smuzhiyun return BadValue;
4174*4882a593Smuzhiyun }
4175*4882a593Smuzhiyun if ((unsigned) (stuff->firstKTLevel + stuff->nKTLevels - 1) >=
4176*4882a593Smuzhiyun xkb->map->num_types) {
4177*4882a593Smuzhiyun client->errorValue = _XkbErrCode4(0x06, stuff->firstKTLevel,
4178*4882a593Smuzhiyun stuff->nKTLevels,
4179*4882a593Smuzhiyun xkb->map->num_types);
4180*4882a593Smuzhiyun return BadValue;
4181*4882a593Smuzhiyun }
4182*4882a593Smuzhiyun width = (CARD8 *) tmp;
4183*4882a593Smuzhiyun tmp = (CARD32 *) (((char *) tmp) + XkbPaddedSize(stuff->nKTLevels));
4184*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, width, tmp))
4185*4882a593Smuzhiyun return BadLength;
4186*4882a593Smuzhiyun type = &xkb->map->types[stuff->firstKTLevel];
4187*4882a593Smuzhiyun for (i = 0; i < stuff->nKTLevels; i++, type++) {
4188*4882a593Smuzhiyun if (width[i] == 0)
4189*4882a593Smuzhiyun continue;
4190*4882a593Smuzhiyun else if (width[i] != type->num_levels) {
4191*4882a593Smuzhiyun client->errorValue = _XkbErrCode4(0x07, i + stuff->firstKTLevel,
4192*4882a593Smuzhiyun type->num_levels, width[i]);
4193*4882a593Smuzhiyun return BadMatch;
4194*4882a593Smuzhiyun }
4195*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + width[i]))
4196*4882a593Smuzhiyun return BadLength;
4197*4882a593Smuzhiyun tmp = _XkbCheckAtoms(tmp, width[i], client->swapped, &bad);
4198*4882a593Smuzhiyun if (!tmp) {
4199*4882a593Smuzhiyun client->errorValue = bad;
4200*4882a593Smuzhiyun return BadAtom;
4201*4882a593Smuzhiyun }
4202*4882a593Smuzhiyun }
4203*4882a593Smuzhiyun }
4204*4882a593Smuzhiyun if (stuff->which & XkbIndicatorNamesMask) {
4205*4882a593Smuzhiyun if (stuff->indicators == 0) {
4206*4882a593Smuzhiyun client->errorValue = 0x08;
4207*4882a593Smuzhiyun return BadMatch;
4208*4882a593Smuzhiyun }
4209*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp,
4210*4882a593Smuzhiyun tmp + Ones(stuff->indicators)))
4211*4882a593Smuzhiyun return BadLength;
4212*4882a593Smuzhiyun tmp = _XkbCheckMaskedAtoms(tmp, XkbNumIndicators, stuff->indicators,
4213*4882a593Smuzhiyun client->swapped, &bad);
4214*4882a593Smuzhiyun if (!tmp) {
4215*4882a593Smuzhiyun client->errorValue = bad;
4216*4882a593Smuzhiyun return BadAtom;
4217*4882a593Smuzhiyun }
4218*4882a593Smuzhiyun }
4219*4882a593Smuzhiyun if (stuff->which & XkbVirtualModNamesMask) {
4220*4882a593Smuzhiyun if (stuff->virtualMods == 0) {
4221*4882a593Smuzhiyun client->errorValue = 0x09;
4222*4882a593Smuzhiyun return BadMatch;
4223*4882a593Smuzhiyun }
4224*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp,
4225*4882a593Smuzhiyun tmp + Ones(stuff->virtualMods)))
4226*4882a593Smuzhiyun return BadLength;
4227*4882a593Smuzhiyun tmp = _XkbCheckMaskedAtoms(tmp, XkbNumVirtualMods,
4228*4882a593Smuzhiyun (CARD32) stuff->virtualMods,
4229*4882a593Smuzhiyun client->swapped, &bad);
4230*4882a593Smuzhiyun if (!tmp) {
4231*4882a593Smuzhiyun client->errorValue = bad;
4232*4882a593Smuzhiyun return BadAtom;
4233*4882a593Smuzhiyun }
4234*4882a593Smuzhiyun }
4235*4882a593Smuzhiyun if (stuff->which & XkbGroupNamesMask) {
4236*4882a593Smuzhiyun if (stuff->groupNames == 0) {
4237*4882a593Smuzhiyun client->errorValue = 0x0a;
4238*4882a593Smuzhiyun return BadMatch;
4239*4882a593Smuzhiyun }
4240*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp,
4241*4882a593Smuzhiyun tmp + Ones(stuff->groupNames)))
4242*4882a593Smuzhiyun return BadLength;
4243*4882a593Smuzhiyun tmp = _XkbCheckMaskedAtoms(tmp, XkbNumKbdGroups,
4244*4882a593Smuzhiyun (CARD32) stuff->groupNames,
4245*4882a593Smuzhiyun client->swapped, &bad);
4246*4882a593Smuzhiyun if (!tmp) {
4247*4882a593Smuzhiyun client->errorValue = bad;
4248*4882a593Smuzhiyun return BadAtom;
4249*4882a593Smuzhiyun }
4250*4882a593Smuzhiyun }
4251*4882a593Smuzhiyun if (stuff->which & XkbKeyNamesMask) {
4252*4882a593Smuzhiyun if (stuff->firstKey < (unsigned) xkb->min_key_code) {
4253*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x0b, xkb->min_key_code,
4254*4882a593Smuzhiyun stuff->firstKey);
4255*4882a593Smuzhiyun return BadValue;
4256*4882a593Smuzhiyun }
4257*4882a593Smuzhiyun if (((unsigned) (stuff->firstKey + stuff->nKeys - 1) >
4258*4882a593Smuzhiyun xkb->max_key_code) || (stuff->nKeys < 1)) {
4259*4882a593Smuzhiyun client->errorValue =
4260*4882a593Smuzhiyun _XkbErrCode4(0x0c, xkb->max_key_code, stuff->firstKey,
4261*4882a593Smuzhiyun stuff->nKeys);
4262*4882a593Smuzhiyun return BadValue;
4263*4882a593Smuzhiyun }
4264*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + stuff->nKeys))
4265*4882a593Smuzhiyun return BadLength;
4266*4882a593Smuzhiyun tmp += stuff->nKeys;
4267*4882a593Smuzhiyun }
4268*4882a593Smuzhiyun if ((stuff->which & XkbKeyAliasesMask) && (stuff->nKeyAliases > 0)) {
4269*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp,
4270*4882a593Smuzhiyun tmp + (stuff->nKeyAliases * 2)))
4271*4882a593Smuzhiyun return BadLength;
4272*4882a593Smuzhiyun tmp += stuff->nKeyAliases * 2;
4273*4882a593Smuzhiyun }
4274*4882a593Smuzhiyun if (stuff->which & XkbRGNamesMask) {
4275*4882a593Smuzhiyun if (stuff->nRadioGroups < 1) {
4276*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x0d, stuff->nRadioGroups);
4277*4882a593Smuzhiyun return BadValue;
4278*4882a593Smuzhiyun }
4279*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp,
4280*4882a593Smuzhiyun tmp + stuff->nRadioGroups))
4281*4882a593Smuzhiyun return BadLength;
4282*4882a593Smuzhiyun tmp = _XkbCheckAtoms(tmp, stuff->nRadioGroups, client->swapped, &bad);
4283*4882a593Smuzhiyun if (!tmp) {
4284*4882a593Smuzhiyun client->errorValue = bad;
4285*4882a593Smuzhiyun return BadAtom;
4286*4882a593Smuzhiyun }
4287*4882a593Smuzhiyun }
4288*4882a593Smuzhiyun if ((tmp - ((CARD32 *) stuff)) != stuff->length) {
4289*4882a593Smuzhiyun client->errorValue = stuff->length;
4290*4882a593Smuzhiyun return BadLength;
4291*4882a593Smuzhiyun }
4292*4882a593Smuzhiyun
4293*4882a593Smuzhiyun return Success;
4294*4882a593Smuzhiyun }
4295*4882a593Smuzhiyun
4296*4882a593Smuzhiyun static int
_XkbSetNames(ClientPtr client,DeviceIntPtr dev,xkbSetNamesReq * stuff)4297*4882a593Smuzhiyun _XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq * stuff)
4298*4882a593Smuzhiyun {
4299*4882a593Smuzhiyun XkbDescRec *xkb;
4300*4882a593Smuzhiyun XkbNamesRec *names;
4301*4882a593Smuzhiyun CARD32 *tmp;
4302*4882a593Smuzhiyun xkbNamesNotify nn;
4303*4882a593Smuzhiyun
4304*4882a593Smuzhiyun tmp = (CARD32 *) &stuff[1];
4305*4882a593Smuzhiyun xkb = dev->key->xkbInfo->desc;
4306*4882a593Smuzhiyun names = xkb->names;
4307*4882a593Smuzhiyun
4308*4882a593Smuzhiyun if (XkbAllocNames(xkb, stuff->which, stuff->nRadioGroups,
4309*4882a593Smuzhiyun stuff->nKeyAliases) != Success) {
4310*4882a593Smuzhiyun return BadAlloc;
4311*4882a593Smuzhiyun }
4312*4882a593Smuzhiyun
4313*4882a593Smuzhiyun memset(&nn, 0, sizeof(xkbNamesNotify));
4314*4882a593Smuzhiyun nn.changed = stuff->which;
4315*4882a593Smuzhiyun tmp = (CARD32 *) &stuff[1];
4316*4882a593Smuzhiyun if (stuff->which & XkbKeycodesNameMask)
4317*4882a593Smuzhiyun names->keycodes = *tmp++;
4318*4882a593Smuzhiyun if (stuff->which & XkbGeometryNameMask)
4319*4882a593Smuzhiyun names->geometry = *tmp++;
4320*4882a593Smuzhiyun if (stuff->which & XkbSymbolsNameMask)
4321*4882a593Smuzhiyun names->symbols = *tmp++;
4322*4882a593Smuzhiyun if (stuff->which & XkbPhysSymbolsNameMask)
4323*4882a593Smuzhiyun names->phys_symbols = *tmp++;
4324*4882a593Smuzhiyun if (stuff->which & XkbTypesNameMask)
4325*4882a593Smuzhiyun names->types = *tmp++;
4326*4882a593Smuzhiyun if (stuff->which & XkbCompatNameMask)
4327*4882a593Smuzhiyun names->compat = *tmp++;
4328*4882a593Smuzhiyun if ((stuff->which & XkbKeyTypeNamesMask) && (stuff->nTypes > 0)) {
4329*4882a593Smuzhiyun register unsigned i;
4330*4882a593Smuzhiyun register XkbKeyTypePtr type;
4331*4882a593Smuzhiyun
4332*4882a593Smuzhiyun type = &xkb->map->types[stuff->firstType];
4333*4882a593Smuzhiyun for (i = 0; i < stuff->nTypes; i++, type++) {
4334*4882a593Smuzhiyun type->name = *tmp++;
4335*4882a593Smuzhiyun }
4336*4882a593Smuzhiyun nn.firstType = stuff->firstType;
4337*4882a593Smuzhiyun nn.nTypes = stuff->nTypes;
4338*4882a593Smuzhiyun }
4339*4882a593Smuzhiyun if (stuff->which & XkbKTLevelNamesMask) {
4340*4882a593Smuzhiyun register XkbKeyTypePtr type;
4341*4882a593Smuzhiyun register unsigned i;
4342*4882a593Smuzhiyun CARD8 *width;
4343*4882a593Smuzhiyun
4344*4882a593Smuzhiyun width = (CARD8 *) tmp;
4345*4882a593Smuzhiyun tmp = (CARD32 *) (((char *) tmp) + XkbPaddedSize(stuff->nKTLevels));
4346*4882a593Smuzhiyun type = &xkb->map->types[stuff->firstKTLevel];
4347*4882a593Smuzhiyun for (i = 0; i < stuff->nKTLevels; i++, type++) {
4348*4882a593Smuzhiyun if (width[i] > 0) {
4349*4882a593Smuzhiyun if (type->level_names) {
4350*4882a593Smuzhiyun register unsigned n;
4351*4882a593Smuzhiyun
4352*4882a593Smuzhiyun for (n = 0; n < width[i]; n++) {
4353*4882a593Smuzhiyun type->level_names[n] = tmp[n];
4354*4882a593Smuzhiyun }
4355*4882a593Smuzhiyun }
4356*4882a593Smuzhiyun tmp += width[i];
4357*4882a593Smuzhiyun }
4358*4882a593Smuzhiyun }
4359*4882a593Smuzhiyun nn.firstLevelName = 0;
4360*4882a593Smuzhiyun nn.nLevelNames = stuff->nTypes;
4361*4882a593Smuzhiyun }
4362*4882a593Smuzhiyun if (stuff->which & XkbIndicatorNamesMask) {
4363*4882a593Smuzhiyun tmp = _XkbCopyMaskedAtoms(tmp, names->indicators, XkbNumIndicators,
4364*4882a593Smuzhiyun stuff->indicators);
4365*4882a593Smuzhiyun nn.changedIndicators = stuff->indicators;
4366*4882a593Smuzhiyun }
4367*4882a593Smuzhiyun if (stuff->which & XkbVirtualModNamesMask) {
4368*4882a593Smuzhiyun tmp = _XkbCopyMaskedAtoms(tmp, names->vmods, XkbNumVirtualMods,
4369*4882a593Smuzhiyun stuff->virtualMods);
4370*4882a593Smuzhiyun nn.changedVirtualMods = stuff->virtualMods;
4371*4882a593Smuzhiyun }
4372*4882a593Smuzhiyun if (stuff->which & XkbGroupNamesMask) {
4373*4882a593Smuzhiyun tmp = _XkbCopyMaskedAtoms(tmp, names->groups, XkbNumKbdGroups,
4374*4882a593Smuzhiyun stuff->groupNames);
4375*4882a593Smuzhiyun nn.changedVirtualMods = stuff->groupNames;
4376*4882a593Smuzhiyun }
4377*4882a593Smuzhiyun if (stuff->which & XkbKeyNamesMask) {
4378*4882a593Smuzhiyun memcpy((char *) &names->keys[stuff->firstKey], (char *) tmp,
4379*4882a593Smuzhiyun stuff->nKeys * XkbKeyNameLength);
4380*4882a593Smuzhiyun tmp += stuff->nKeys;
4381*4882a593Smuzhiyun nn.firstKey = stuff->firstKey;
4382*4882a593Smuzhiyun nn.nKeys = stuff->nKeys;
4383*4882a593Smuzhiyun }
4384*4882a593Smuzhiyun if (stuff->which & XkbKeyAliasesMask) {
4385*4882a593Smuzhiyun if (stuff->nKeyAliases > 0) {
4386*4882a593Smuzhiyun register int na = stuff->nKeyAliases;
4387*4882a593Smuzhiyun
4388*4882a593Smuzhiyun if (XkbAllocNames(xkb, XkbKeyAliasesMask, 0, na) != Success)
4389*4882a593Smuzhiyun return BadAlloc;
4390*4882a593Smuzhiyun memcpy((char *) names->key_aliases, (char *) tmp,
4391*4882a593Smuzhiyun stuff->nKeyAliases * sizeof(XkbKeyAliasRec));
4392*4882a593Smuzhiyun tmp += stuff->nKeyAliases * 2;
4393*4882a593Smuzhiyun }
4394*4882a593Smuzhiyun else if (names->key_aliases != NULL) {
4395*4882a593Smuzhiyun free(names->key_aliases);
4396*4882a593Smuzhiyun names->key_aliases = NULL;
4397*4882a593Smuzhiyun names->num_key_aliases = 0;
4398*4882a593Smuzhiyun }
4399*4882a593Smuzhiyun nn.nAliases = names->num_key_aliases;
4400*4882a593Smuzhiyun }
4401*4882a593Smuzhiyun if (stuff->which & XkbRGNamesMask) {
4402*4882a593Smuzhiyun if (stuff->nRadioGroups > 0) {
4403*4882a593Smuzhiyun register unsigned i, nrg;
4404*4882a593Smuzhiyun
4405*4882a593Smuzhiyun nrg = stuff->nRadioGroups;
4406*4882a593Smuzhiyun if (XkbAllocNames(xkb, XkbRGNamesMask, nrg, 0) != Success)
4407*4882a593Smuzhiyun return BadAlloc;
4408*4882a593Smuzhiyun
4409*4882a593Smuzhiyun for (i = 0; i < stuff->nRadioGroups; i++) {
4410*4882a593Smuzhiyun names->radio_groups[i] = tmp[i];
4411*4882a593Smuzhiyun }
4412*4882a593Smuzhiyun tmp += stuff->nRadioGroups;
4413*4882a593Smuzhiyun }
4414*4882a593Smuzhiyun else if (names->radio_groups) {
4415*4882a593Smuzhiyun free(names->radio_groups);
4416*4882a593Smuzhiyun names->radio_groups = NULL;
4417*4882a593Smuzhiyun names->num_rg = 0;
4418*4882a593Smuzhiyun }
4419*4882a593Smuzhiyun nn.nRadioGroups = names->num_rg;
4420*4882a593Smuzhiyun }
4421*4882a593Smuzhiyun if (nn.changed) {
4422*4882a593Smuzhiyun Bool needExtEvent;
4423*4882a593Smuzhiyun
4424*4882a593Smuzhiyun needExtEvent = (nn.changed & XkbIndicatorNamesMask) != 0;
4425*4882a593Smuzhiyun XkbSendNamesNotify(dev, &nn);
4426*4882a593Smuzhiyun if (needExtEvent) {
4427*4882a593Smuzhiyun XkbSrvLedInfoPtr sli;
4428*4882a593Smuzhiyun xkbExtensionDeviceNotify edev;
4429*4882a593Smuzhiyun register int i;
4430*4882a593Smuzhiyun register unsigned bit;
4431*4882a593Smuzhiyun
4432*4882a593Smuzhiyun sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId,
4433*4882a593Smuzhiyun XkbXI_IndicatorsMask);
4434*4882a593Smuzhiyun sli->namesPresent = 0;
4435*4882a593Smuzhiyun for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
4436*4882a593Smuzhiyun if (names->indicators[i] != None)
4437*4882a593Smuzhiyun sli->namesPresent |= bit;
4438*4882a593Smuzhiyun }
4439*4882a593Smuzhiyun memset(&edev, 0, sizeof(xkbExtensionDeviceNotify));
4440*4882a593Smuzhiyun edev.reason = XkbXI_IndicatorNamesMask;
4441*4882a593Smuzhiyun edev.ledClass = KbdFeedbackClass;
4442*4882a593Smuzhiyun edev.ledID = dev->kbdfeed->ctrl.id;
4443*4882a593Smuzhiyun edev.ledsDefined = sli->namesPresent | sli->mapsPresent;
4444*4882a593Smuzhiyun edev.ledState = sli->effectiveState;
4445*4882a593Smuzhiyun edev.firstBtn = 0;
4446*4882a593Smuzhiyun edev.nBtns = 0;
4447*4882a593Smuzhiyun edev.supported = XkbXI_AllFeaturesMask;
4448*4882a593Smuzhiyun edev.unsupported = 0;
4449*4882a593Smuzhiyun XkbSendExtensionDeviceNotify(dev, client, &edev);
4450*4882a593Smuzhiyun }
4451*4882a593Smuzhiyun }
4452*4882a593Smuzhiyun return Success;
4453*4882a593Smuzhiyun }
4454*4882a593Smuzhiyun
4455*4882a593Smuzhiyun int
ProcXkbSetNames(ClientPtr client)4456*4882a593Smuzhiyun ProcXkbSetNames(ClientPtr client)
4457*4882a593Smuzhiyun {
4458*4882a593Smuzhiyun DeviceIntPtr dev;
4459*4882a593Smuzhiyun CARD32 *tmp;
4460*4882a593Smuzhiyun Atom bad;
4461*4882a593Smuzhiyun int rc;
4462*4882a593Smuzhiyun
4463*4882a593Smuzhiyun REQUEST(xkbSetNamesReq);
4464*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xkbSetNamesReq);
4465*4882a593Smuzhiyun
4466*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
4467*4882a593Smuzhiyun return BadAccess;
4468*4882a593Smuzhiyun
4469*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
4470*4882a593Smuzhiyun CHK_MASK_LEGAL(0x01, stuff->which, XkbAllNamesMask);
4471*4882a593Smuzhiyun
4472*4882a593Smuzhiyun /* check device-independent stuff */
4473*4882a593Smuzhiyun tmp = (CARD32 *) &stuff[1];
4474*4882a593Smuzhiyun
4475*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1))
4476*4882a593Smuzhiyun return BadLength;
4477*4882a593Smuzhiyun if (stuff->which & XkbKeycodesNameMask) {
4478*4882a593Smuzhiyun tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad);
4479*4882a593Smuzhiyun if (!tmp) {
4480*4882a593Smuzhiyun client->errorValue = bad;
4481*4882a593Smuzhiyun return BadAtom;
4482*4882a593Smuzhiyun }
4483*4882a593Smuzhiyun }
4484*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1))
4485*4882a593Smuzhiyun return BadLength;
4486*4882a593Smuzhiyun if (stuff->which & XkbGeometryNameMask) {
4487*4882a593Smuzhiyun tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad);
4488*4882a593Smuzhiyun if (!tmp) {
4489*4882a593Smuzhiyun client->errorValue = bad;
4490*4882a593Smuzhiyun return BadAtom;
4491*4882a593Smuzhiyun }
4492*4882a593Smuzhiyun }
4493*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1))
4494*4882a593Smuzhiyun return BadLength;
4495*4882a593Smuzhiyun if (stuff->which & XkbSymbolsNameMask) {
4496*4882a593Smuzhiyun tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad);
4497*4882a593Smuzhiyun if (!tmp) {
4498*4882a593Smuzhiyun client->errorValue = bad;
4499*4882a593Smuzhiyun return BadAtom;
4500*4882a593Smuzhiyun }
4501*4882a593Smuzhiyun }
4502*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1))
4503*4882a593Smuzhiyun return BadLength;
4504*4882a593Smuzhiyun if (stuff->which & XkbPhysSymbolsNameMask) {
4505*4882a593Smuzhiyun tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad);
4506*4882a593Smuzhiyun if (!tmp) {
4507*4882a593Smuzhiyun client->errorValue = bad;
4508*4882a593Smuzhiyun return BadAtom;
4509*4882a593Smuzhiyun }
4510*4882a593Smuzhiyun }
4511*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1))
4512*4882a593Smuzhiyun return BadLength;
4513*4882a593Smuzhiyun if (stuff->which & XkbTypesNameMask) {
4514*4882a593Smuzhiyun tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad);
4515*4882a593Smuzhiyun if (!tmp) {
4516*4882a593Smuzhiyun client->errorValue = bad;
4517*4882a593Smuzhiyun return BadAtom;
4518*4882a593Smuzhiyun }
4519*4882a593Smuzhiyun }
4520*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1))
4521*4882a593Smuzhiyun return BadLength;
4522*4882a593Smuzhiyun if (stuff->which & XkbCompatNameMask) {
4523*4882a593Smuzhiyun tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad);
4524*4882a593Smuzhiyun if (!tmp) {
4525*4882a593Smuzhiyun client->errorValue = bad;
4526*4882a593Smuzhiyun return BadAtom;
4527*4882a593Smuzhiyun }
4528*4882a593Smuzhiyun }
4529*4882a593Smuzhiyun
4530*4882a593Smuzhiyun /* start of device-dependent tests */
4531*4882a593Smuzhiyun rc = _XkbSetNamesCheck(client, dev, stuff, tmp);
4532*4882a593Smuzhiyun if (rc != Success)
4533*4882a593Smuzhiyun return rc;
4534*4882a593Smuzhiyun
4535*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd) {
4536*4882a593Smuzhiyun DeviceIntPtr other;
4537*4882a593Smuzhiyun
4538*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
4539*4882a593Smuzhiyun if ((other != dev) && other->key && !IsMaster(other) &&
4540*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) {
4541*4882a593Smuzhiyun
4542*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
4543*4882a593Smuzhiyun DixManageAccess);
4544*4882a593Smuzhiyun if (rc == Success) {
4545*4882a593Smuzhiyun rc = _XkbSetNamesCheck(client, other, stuff, tmp);
4546*4882a593Smuzhiyun if (rc != Success)
4547*4882a593Smuzhiyun return rc;
4548*4882a593Smuzhiyun }
4549*4882a593Smuzhiyun }
4550*4882a593Smuzhiyun }
4551*4882a593Smuzhiyun }
4552*4882a593Smuzhiyun
4553*4882a593Smuzhiyun /* everything is okay -- update names */
4554*4882a593Smuzhiyun
4555*4882a593Smuzhiyun rc = _XkbSetNames(client, dev, stuff);
4556*4882a593Smuzhiyun if (rc != Success)
4557*4882a593Smuzhiyun return rc;
4558*4882a593Smuzhiyun
4559*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd) {
4560*4882a593Smuzhiyun DeviceIntPtr other;
4561*4882a593Smuzhiyun
4562*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
4563*4882a593Smuzhiyun if ((other != dev) && other->key && !IsMaster(other) &&
4564*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) {
4565*4882a593Smuzhiyun
4566*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
4567*4882a593Smuzhiyun DixManageAccess);
4568*4882a593Smuzhiyun if (rc == Success)
4569*4882a593Smuzhiyun _XkbSetNames(client, other, stuff);
4570*4882a593Smuzhiyun }
4571*4882a593Smuzhiyun }
4572*4882a593Smuzhiyun }
4573*4882a593Smuzhiyun
4574*4882a593Smuzhiyun /* everything is okay -- update names */
4575*4882a593Smuzhiyun
4576*4882a593Smuzhiyun return Success;
4577*4882a593Smuzhiyun }
4578*4882a593Smuzhiyun
4579*4882a593Smuzhiyun /***====================================================================***/
4580*4882a593Smuzhiyun
4581*4882a593Smuzhiyun #include "xkbgeom.h"
4582*4882a593Smuzhiyun
4583*4882a593Smuzhiyun #define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4)
4584*4882a593Smuzhiyun
4585*4882a593Smuzhiyun /**
4586*4882a593Smuzhiyun * Write the zero-terminated string str into wire as a pascal string with a
4587*4882a593Smuzhiyun * 16-bit length field prefixed before the actual string.
4588*4882a593Smuzhiyun *
4589*4882a593Smuzhiyun * @param wire The destination array, usually the wire struct
4590*4882a593Smuzhiyun * @param str The source string as zero-terminated C string
4591*4882a593Smuzhiyun * @param swap If TRUE, the length field is swapped.
4592*4882a593Smuzhiyun *
4593*4882a593Smuzhiyun * @return The input string in the format <string length><string> with a
4594*4882a593Smuzhiyun * (swapped) 16 bit string length, non-zero terminated.
4595*4882a593Smuzhiyun */
4596*4882a593Smuzhiyun static char *
XkbWriteCountedString(char * wire,const char * str,Bool swap)4597*4882a593Smuzhiyun XkbWriteCountedString(char *wire, const char *str, Bool swap)
4598*4882a593Smuzhiyun {
4599*4882a593Smuzhiyun CARD16 len, *pLen, paddedLen;
4600*4882a593Smuzhiyun
4601*4882a593Smuzhiyun if (!str)
4602*4882a593Smuzhiyun return wire;
4603*4882a593Smuzhiyun
4604*4882a593Smuzhiyun len = strlen(str);
4605*4882a593Smuzhiyun pLen = (CARD16 *) wire;
4606*4882a593Smuzhiyun *pLen = len;
4607*4882a593Smuzhiyun if (swap) {
4608*4882a593Smuzhiyun swaps(pLen);
4609*4882a593Smuzhiyun }
4610*4882a593Smuzhiyun paddedLen = pad_to_int32(sizeof(len) + len) - sizeof(len);
4611*4882a593Smuzhiyun strncpy(&wire[sizeof(len)], str, paddedLen);
4612*4882a593Smuzhiyun wire += sizeof(len) + paddedLen;
4613*4882a593Smuzhiyun return wire;
4614*4882a593Smuzhiyun }
4615*4882a593Smuzhiyun
4616*4882a593Smuzhiyun static int
XkbSizeGeomProperties(XkbGeometryPtr geom)4617*4882a593Smuzhiyun XkbSizeGeomProperties(XkbGeometryPtr geom)
4618*4882a593Smuzhiyun {
4619*4882a593Smuzhiyun register int i, size;
4620*4882a593Smuzhiyun XkbPropertyPtr prop;
4621*4882a593Smuzhiyun
4622*4882a593Smuzhiyun for (size = i = 0, prop = geom->properties; i < geom->num_properties;
4623*4882a593Smuzhiyun i++, prop++) {
4624*4882a593Smuzhiyun size += XkbSizeCountedString(prop->name);
4625*4882a593Smuzhiyun size += XkbSizeCountedString(prop->value);
4626*4882a593Smuzhiyun }
4627*4882a593Smuzhiyun return size;
4628*4882a593Smuzhiyun }
4629*4882a593Smuzhiyun
4630*4882a593Smuzhiyun static char *
XkbWriteGeomProperties(char * wire,XkbGeometryPtr geom,Bool swap)4631*4882a593Smuzhiyun XkbWriteGeomProperties(char *wire, XkbGeometryPtr geom, Bool swap)
4632*4882a593Smuzhiyun {
4633*4882a593Smuzhiyun register int i;
4634*4882a593Smuzhiyun register XkbPropertyPtr prop;
4635*4882a593Smuzhiyun
4636*4882a593Smuzhiyun for (i = 0, prop = geom->properties; i < geom->num_properties; i++, prop++) {
4637*4882a593Smuzhiyun wire = XkbWriteCountedString(wire, prop->name, swap);
4638*4882a593Smuzhiyun wire = XkbWriteCountedString(wire, prop->value, swap);
4639*4882a593Smuzhiyun }
4640*4882a593Smuzhiyun return wire;
4641*4882a593Smuzhiyun }
4642*4882a593Smuzhiyun
4643*4882a593Smuzhiyun static int
XkbSizeGeomKeyAliases(XkbGeometryPtr geom)4644*4882a593Smuzhiyun XkbSizeGeomKeyAliases(XkbGeometryPtr geom)
4645*4882a593Smuzhiyun {
4646*4882a593Smuzhiyun return geom->num_key_aliases * (2 * XkbKeyNameLength);
4647*4882a593Smuzhiyun }
4648*4882a593Smuzhiyun
4649*4882a593Smuzhiyun static char *
XkbWriteGeomKeyAliases(char * wire,XkbGeometryPtr geom,Bool swap)4650*4882a593Smuzhiyun XkbWriteGeomKeyAliases(char *wire, XkbGeometryPtr geom, Bool swap)
4651*4882a593Smuzhiyun {
4652*4882a593Smuzhiyun register int sz;
4653*4882a593Smuzhiyun
4654*4882a593Smuzhiyun sz = geom->num_key_aliases * (XkbKeyNameLength * 2);
4655*4882a593Smuzhiyun if (sz > 0) {
4656*4882a593Smuzhiyun memcpy(wire, (char *) geom->key_aliases, sz);
4657*4882a593Smuzhiyun wire += sz;
4658*4882a593Smuzhiyun }
4659*4882a593Smuzhiyun return wire;
4660*4882a593Smuzhiyun }
4661*4882a593Smuzhiyun
4662*4882a593Smuzhiyun static int
XkbSizeGeomColors(XkbGeometryPtr geom)4663*4882a593Smuzhiyun XkbSizeGeomColors(XkbGeometryPtr geom)
4664*4882a593Smuzhiyun {
4665*4882a593Smuzhiyun register int i, size;
4666*4882a593Smuzhiyun register XkbColorPtr color;
4667*4882a593Smuzhiyun
4668*4882a593Smuzhiyun for (i = size = 0, color = geom->colors; i < geom->num_colors; i++, color++) {
4669*4882a593Smuzhiyun size += XkbSizeCountedString(color->spec);
4670*4882a593Smuzhiyun }
4671*4882a593Smuzhiyun return size;
4672*4882a593Smuzhiyun }
4673*4882a593Smuzhiyun
4674*4882a593Smuzhiyun static char *
XkbWriteGeomColors(char * wire,XkbGeometryPtr geom,Bool swap)4675*4882a593Smuzhiyun XkbWriteGeomColors(char *wire, XkbGeometryPtr geom, Bool swap)
4676*4882a593Smuzhiyun {
4677*4882a593Smuzhiyun register int i;
4678*4882a593Smuzhiyun register XkbColorPtr color;
4679*4882a593Smuzhiyun
4680*4882a593Smuzhiyun for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) {
4681*4882a593Smuzhiyun wire = XkbWriteCountedString(wire, color->spec, swap);
4682*4882a593Smuzhiyun }
4683*4882a593Smuzhiyun return wire;
4684*4882a593Smuzhiyun }
4685*4882a593Smuzhiyun
4686*4882a593Smuzhiyun static int
XkbSizeGeomShapes(XkbGeometryPtr geom)4687*4882a593Smuzhiyun XkbSizeGeomShapes(XkbGeometryPtr geom)
4688*4882a593Smuzhiyun {
4689*4882a593Smuzhiyun register int i, size;
4690*4882a593Smuzhiyun register XkbShapePtr shape;
4691*4882a593Smuzhiyun
4692*4882a593Smuzhiyun for (i = size = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) {
4693*4882a593Smuzhiyun register int n;
4694*4882a593Smuzhiyun register XkbOutlinePtr ol;
4695*4882a593Smuzhiyun
4696*4882a593Smuzhiyun size += SIZEOF(xkbShapeWireDesc);
4697*4882a593Smuzhiyun for (n = 0, ol = shape->outlines; n < shape->num_outlines; n++, ol++) {
4698*4882a593Smuzhiyun size += SIZEOF(xkbOutlineWireDesc);
4699*4882a593Smuzhiyun size += ol->num_points * SIZEOF(xkbPointWireDesc);
4700*4882a593Smuzhiyun }
4701*4882a593Smuzhiyun }
4702*4882a593Smuzhiyun return size;
4703*4882a593Smuzhiyun }
4704*4882a593Smuzhiyun
4705*4882a593Smuzhiyun static char *
XkbWriteGeomShapes(char * wire,XkbGeometryPtr geom,Bool swap)4706*4882a593Smuzhiyun XkbWriteGeomShapes(char *wire, XkbGeometryPtr geom, Bool swap)
4707*4882a593Smuzhiyun {
4708*4882a593Smuzhiyun int i;
4709*4882a593Smuzhiyun XkbShapePtr shape;
4710*4882a593Smuzhiyun xkbShapeWireDesc *shapeWire;
4711*4882a593Smuzhiyun
4712*4882a593Smuzhiyun for (i = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) {
4713*4882a593Smuzhiyun register int o;
4714*4882a593Smuzhiyun XkbOutlinePtr ol;
4715*4882a593Smuzhiyun xkbOutlineWireDesc *olWire;
4716*4882a593Smuzhiyun
4717*4882a593Smuzhiyun shapeWire = (xkbShapeWireDesc *) wire;
4718*4882a593Smuzhiyun shapeWire->name = shape->name;
4719*4882a593Smuzhiyun shapeWire->nOutlines = shape->num_outlines;
4720*4882a593Smuzhiyun if (shape->primary != NULL)
4721*4882a593Smuzhiyun shapeWire->primaryNdx = XkbOutlineIndex(shape, shape->primary);
4722*4882a593Smuzhiyun else
4723*4882a593Smuzhiyun shapeWire->primaryNdx = XkbNoShape;
4724*4882a593Smuzhiyun if (shape->approx != NULL)
4725*4882a593Smuzhiyun shapeWire->approxNdx = XkbOutlineIndex(shape, shape->approx);
4726*4882a593Smuzhiyun else
4727*4882a593Smuzhiyun shapeWire->approxNdx = XkbNoShape;
4728*4882a593Smuzhiyun shapeWire->pad = 0;
4729*4882a593Smuzhiyun if (swap) {
4730*4882a593Smuzhiyun swapl(&shapeWire->name);
4731*4882a593Smuzhiyun }
4732*4882a593Smuzhiyun wire = (char *) &shapeWire[1];
4733*4882a593Smuzhiyun for (o = 0, ol = shape->outlines; o < shape->num_outlines; o++, ol++) {
4734*4882a593Smuzhiyun register int p;
4735*4882a593Smuzhiyun XkbPointPtr pt;
4736*4882a593Smuzhiyun xkbPointWireDesc *ptWire;
4737*4882a593Smuzhiyun
4738*4882a593Smuzhiyun olWire = (xkbOutlineWireDesc *) wire;
4739*4882a593Smuzhiyun olWire->nPoints = ol->num_points;
4740*4882a593Smuzhiyun olWire->cornerRadius = ol->corner_radius;
4741*4882a593Smuzhiyun olWire->pad = 0;
4742*4882a593Smuzhiyun wire = (char *) &olWire[1];
4743*4882a593Smuzhiyun ptWire = (xkbPointWireDesc *) wire;
4744*4882a593Smuzhiyun for (p = 0, pt = ol->points; p < ol->num_points; p++, pt++) {
4745*4882a593Smuzhiyun ptWire[p].x = pt->x;
4746*4882a593Smuzhiyun ptWire[p].y = pt->y;
4747*4882a593Smuzhiyun if (swap) {
4748*4882a593Smuzhiyun swaps(&ptWire[p].x);
4749*4882a593Smuzhiyun swaps(&ptWire[p].y);
4750*4882a593Smuzhiyun }
4751*4882a593Smuzhiyun }
4752*4882a593Smuzhiyun wire = (char *) &ptWire[ol->num_points];
4753*4882a593Smuzhiyun }
4754*4882a593Smuzhiyun }
4755*4882a593Smuzhiyun return wire;
4756*4882a593Smuzhiyun }
4757*4882a593Smuzhiyun
4758*4882a593Smuzhiyun static int
XkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad)4759*4882a593Smuzhiyun XkbSizeGeomDoodads(int num_doodads, XkbDoodadPtr doodad)
4760*4882a593Smuzhiyun {
4761*4882a593Smuzhiyun register int i, size;
4762*4882a593Smuzhiyun
4763*4882a593Smuzhiyun for (i = size = 0; i < num_doodads; i++, doodad++) {
4764*4882a593Smuzhiyun size += SIZEOF(xkbAnyDoodadWireDesc);
4765*4882a593Smuzhiyun if (doodad->any.type == XkbTextDoodad) {
4766*4882a593Smuzhiyun size += XkbSizeCountedString(doodad->text.text);
4767*4882a593Smuzhiyun size += XkbSizeCountedString(doodad->text.font);
4768*4882a593Smuzhiyun }
4769*4882a593Smuzhiyun else if (doodad->any.type == XkbLogoDoodad) {
4770*4882a593Smuzhiyun size += XkbSizeCountedString(doodad->logo.logo_name);
4771*4882a593Smuzhiyun }
4772*4882a593Smuzhiyun }
4773*4882a593Smuzhiyun return size;
4774*4882a593Smuzhiyun }
4775*4882a593Smuzhiyun
4776*4882a593Smuzhiyun static char *
XkbWriteGeomDoodads(char * wire,int num_doodads,XkbDoodadPtr doodad,Bool swap)4777*4882a593Smuzhiyun XkbWriteGeomDoodads(char *wire, int num_doodads, XkbDoodadPtr doodad, Bool swap)
4778*4882a593Smuzhiyun {
4779*4882a593Smuzhiyun register int i;
4780*4882a593Smuzhiyun xkbDoodadWireDesc *doodadWire;
4781*4882a593Smuzhiyun
4782*4882a593Smuzhiyun for (i = 0; i < num_doodads; i++, doodad++) {
4783*4882a593Smuzhiyun doodadWire = (xkbDoodadWireDesc *) wire;
4784*4882a593Smuzhiyun wire = (char *) &doodadWire[1];
4785*4882a593Smuzhiyun memset(doodadWire, 0, SIZEOF(xkbDoodadWireDesc));
4786*4882a593Smuzhiyun doodadWire->any.name = doodad->any.name;
4787*4882a593Smuzhiyun doodadWire->any.type = doodad->any.type;
4788*4882a593Smuzhiyun doodadWire->any.priority = doodad->any.priority;
4789*4882a593Smuzhiyun doodadWire->any.top = doodad->any.top;
4790*4882a593Smuzhiyun doodadWire->any.left = doodad->any.left;
4791*4882a593Smuzhiyun if (swap) {
4792*4882a593Smuzhiyun swapl(&doodadWire->any.name);
4793*4882a593Smuzhiyun swaps(&doodadWire->any.top);
4794*4882a593Smuzhiyun swaps(&doodadWire->any.left);
4795*4882a593Smuzhiyun }
4796*4882a593Smuzhiyun switch (doodad->any.type) {
4797*4882a593Smuzhiyun case XkbOutlineDoodad:
4798*4882a593Smuzhiyun case XkbSolidDoodad:
4799*4882a593Smuzhiyun doodadWire->shape.angle = doodad->shape.angle;
4800*4882a593Smuzhiyun doodadWire->shape.colorNdx = doodad->shape.color_ndx;
4801*4882a593Smuzhiyun doodadWire->shape.shapeNdx = doodad->shape.shape_ndx;
4802*4882a593Smuzhiyun if (swap) {
4803*4882a593Smuzhiyun swaps(&doodadWire->shape.angle);
4804*4882a593Smuzhiyun }
4805*4882a593Smuzhiyun break;
4806*4882a593Smuzhiyun case XkbTextDoodad:
4807*4882a593Smuzhiyun doodadWire->text.angle = doodad->text.angle;
4808*4882a593Smuzhiyun doodadWire->text.width = doodad->text.width;
4809*4882a593Smuzhiyun doodadWire->text.height = doodad->text.height;
4810*4882a593Smuzhiyun doodadWire->text.colorNdx = doodad->text.color_ndx;
4811*4882a593Smuzhiyun if (swap) {
4812*4882a593Smuzhiyun swaps(&doodadWire->text.angle);
4813*4882a593Smuzhiyun swaps(&doodadWire->text.width);
4814*4882a593Smuzhiyun swaps(&doodadWire->text.height);
4815*4882a593Smuzhiyun }
4816*4882a593Smuzhiyun wire = XkbWriteCountedString(wire, doodad->text.text, swap);
4817*4882a593Smuzhiyun wire = XkbWriteCountedString(wire, doodad->text.font, swap);
4818*4882a593Smuzhiyun break;
4819*4882a593Smuzhiyun case XkbIndicatorDoodad:
4820*4882a593Smuzhiyun doodadWire->indicator.shapeNdx = doodad->indicator.shape_ndx;
4821*4882a593Smuzhiyun doodadWire->indicator.onColorNdx = doodad->indicator.on_color_ndx;
4822*4882a593Smuzhiyun doodadWire->indicator.offColorNdx = doodad->indicator.off_color_ndx;
4823*4882a593Smuzhiyun break;
4824*4882a593Smuzhiyun case XkbLogoDoodad:
4825*4882a593Smuzhiyun doodadWire->logo.angle = doodad->logo.angle;
4826*4882a593Smuzhiyun doodadWire->logo.colorNdx = doodad->logo.color_ndx;
4827*4882a593Smuzhiyun doodadWire->logo.shapeNdx = doodad->logo.shape_ndx;
4828*4882a593Smuzhiyun wire = XkbWriteCountedString(wire, doodad->logo.logo_name, swap);
4829*4882a593Smuzhiyun break;
4830*4882a593Smuzhiyun default:
4831*4882a593Smuzhiyun ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n",
4832*4882a593Smuzhiyun doodad->any.type);
4833*4882a593Smuzhiyun ErrorF("[xkb] Ignored\n");
4834*4882a593Smuzhiyun break;
4835*4882a593Smuzhiyun }
4836*4882a593Smuzhiyun }
4837*4882a593Smuzhiyun return wire;
4838*4882a593Smuzhiyun }
4839*4882a593Smuzhiyun
4840*4882a593Smuzhiyun static char *
XkbWriteGeomOverlay(char * wire,XkbOverlayPtr ol,Bool swap)4841*4882a593Smuzhiyun XkbWriteGeomOverlay(char *wire, XkbOverlayPtr ol, Bool swap)
4842*4882a593Smuzhiyun {
4843*4882a593Smuzhiyun register int r;
4844*4882a593Smuzhiyun XkbOverlayRowPtr row;
4845*4882a593Smuzhiyun xkbOverlayWireDesc *olWire;
4846*4882a593Smuzhiyun
4847*4882a593Smuzhiyun olWire = (xkbOverlayWireDesc *) wire;
4848*4882a593Smuzhiyun olWire->name = ol->name;
4849*4882a593Smuzhiyun olWire->nRows = ol->num_rows;
4850*4882a593Smuzhiyun olWire->pad1 = 0;
4851*4882a593Smuzhiyun olWire->pad2 = 0;
4852*4882a593Smuzhiyun if (swap) {
4853*4882a593Smuzhiyun swapl(&olWire->name);
4854*4882a593Smuzhiyun }
4855*4882a593Smuzhiyun wire = (char *) &olWire[1];
4856*4882a593Smuzhiyun for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) {
4857*4882a593Smuzhiyun unsigned int k;
4858*4882a593Smuzhiyun XkbOverlayKeyPtr key;
4859*4882a593Smuzhiyun xkbOverlayRowWireDesc *rowWire;
4860*4882a593Smuzhiyun
4861*4882a593Smuzhiyun rowWire = (xkbOverlayRowWireDesc *) wire;
4862*4882a593Smuzhiyun rowWire->rowUnder = row->row_under;
4863*4882a593Smuzhiyun rowWire->nKeys = row->num_keys;
4864*4882a593Smuzhiyun rowWire->pad1 = 0;
4865*4882a593Smuzhiyun wire = (char *) &rowWire[1];
4866*4882a593Smuzhiyun for (k = 0, key = row->keys; k < row->num_keys; k++, key++) {
4867*4882a593Smuzhiyun xkbOverlayKeyWireDesc *keyWire;
4868*4882a593Smuzhiyun
4869*4882a593Smuzhiyun keyWire = (xkbOverlayKeyWireDesc *) wire;
4870*4882a593Smuzhiyun memcpy(keyWire->over, key->over.name, XkbKeyNameLength);
4871*4882a593Smuzhiyun memcpy(keyWire->under, key->under.name, XkbKeyNameLength);
4872*4882a593Smuzhiyun wire = (char *) &keyWire[1];
4873*4882a593Smuzhiyun }
4874*4882a593Smuzhiyun }
4875*4882a593Smuzhiyun return wire;
4876*4882a593Smuzhiyun }
4877*4882a593Smuzhiyun
4878*4882a593Smuzhiyun static int
XkbSizeGeomSections(XkbGeometryPtr geom)4879*4882a593Smuzhiyun XkbSizeGeomSections(XkbGeometryPtr geom)
4880*4882a593Smuzhiyun {
4881*4882a593Smuzhiyun register int i, size;
4882*4882a593Smuzhiyun XkbSectionPtr section;
4883*4882a593Smuzhiyun
4884*4882a593Smuzhiyun for (i = size = 0, section = geom->sections; i < geom->num_sections;
4885*4882a593Smuzhiyun i++, section++) {
4886*4882a593Smuzhiyun size += SIZEOF(xkbSectionWireDesc);
4887*4882a593Smuzhiyun if (section->rows) {
4888*4882a593Smuzhiyun int r;
4889*4882a593Smuzhiyun XkbRowPtr row;
4890*4882a593Smuzhiyun
4891*4882a593Smuzhiyun for (r = 0, row = section->rows; r < section->num_rows; row++, r++) {
4892*4882a593Smuzhiyun size += SIZEOF(xkbRowWireDesc);
4893*4882a593Smuzhiyun size += row->num_keys * SIZEOF(xkbKeyWireDesc);
4894*4882a593Smuzhiyun }
4895*4882a593Smuzhiyun }
4896*4882a593Smuzhiyun if (section->doodads)
4897*4882a593Smuzhiyun size += XkbSizeGeomDoodads(section->num_doodads, section->doodads);
4898*4882a593Smuzhiyun if (section->overlays) {
4899*4882a593Smuzhiyun int o;
4900*4882a593Smuzhiyun XkbOverlayPtr ol;
4901*4882a593Smuzhiyun
4902*4882a593Smuzhiyun for (o = 0, ol = section->overlays; o < section->num_overlays;
4903*4882a593Smuzhiyun o++, ol++) {
4904*4882a593Smuzhiyun int r;
4905*4882a593Smuzhiyun XkbOverlayRowPtr row;
4906*4882a593Smuzhiyun
4907*4882a593Smuzhiyun size += SIZEOF(xkbOverlayWireDesc);
4908*4882a593Smuzhiyun for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) {
4909*4882a593Smuzhiyun size += SIZEOF(xkbOverlayRowWireDesc);
4910*4882a593Smuzhiyun size += row->num_keys * SIZEOF(xkbOverlayKeyWireDesc);
4911*4882a593Smuzhiyun }
4912*4882a593Smuzhiyun }
4913*4882a593Smuzhiyun }
4914*4882a593Smuzhiyun }
4915*4882a593Smuzhiyun return size;
4916*4882a593Smuzhiyun }
4917*4882a593Smuzhiyun
4918*4882a593Smuzhiyun static char *
XkbWriteGeomSections(char * wire,XkbGeometryPtr geom,Bool swap)4919*4882a593Smuzhiyun XkbWriteGeomSections(char *wire, XkbGeometryPtr geom, Bool swap)
4920*4882a593Smuzhiyun {
4921*4882a593Smuzhiyun register int i;
4922*4882a593Smuzhiyun XkbSectionPtr section;
4923*4882a593Smuzhiyun xkbSectionWireDesc *sectionWire;
4924*4882a593Smuzhiyun
4925*4882a593Smuzhiyun for (i = 0, section = geom->sections; i < geom->num_sections;
4926*4882a593Smuzhiyun i++, section++) {
4927*4882a593Smuzhiyun sectionWire = (xkbSectionWireDesc *) wire;
4928*4882a593Smuzhiyun sectionWire->name = section->name;
4929*4882a593Smuzhiyun sectionWire->top = section->top;
4930*4882a593Smuzhiyun sectionWire->left = section->left;
4931*4882a593Smuzhiyun sectionWire->width = section->width;
4932*4882a593Smuzhiyun sectionWire->height = section->height;
4933*4882a593Smuzhiyun sectionWire->angle = section->angle;
4934*4882a593Smuzhiyun sectionWire->priority = section->priority;
4935*4882a593Smuzhiyun sectionWire->nRows = section->num_rows;
4936*4882a593Smuzhiyun sectionWire->nDoodads = section->num_doodads;
4937*4882a593Smuzhiyun sectionWire->nOverlays = section->num_overlays;
4938*4882a593Smuzhiyun sectionWire->pad = 0;
4939*4882a593Smuzhiyun if (swap) {
4940*4882a593Smuzhiyun swapl(§ionWire->name);
4941*4882a593Smuzhiyun swaps(§ionWire->top);
4942*4882a593Smuzhiyun swaps(§ionWire->left);
4943*4882a593Smuzhiyun swaps(§ionWire->width);
4944*4882a593Smuzhiyun swaps(§ionWire->height);
4945*4882a593Smuzhiyun swaps(§ionWire->angle);
4946*4882a593Smuzhiyun }
4947*4882a593Smuzhiyun wire = (char *) §ionWire[1];
4948*4882a593Smuzhiyun if (section->rows) {
4949*4882a593Smuzhiyun int r;
4950*4882a593Smuzhiyun XkbRowPtr row;
4951*4882a593Smuzhiyun xkbRowWireDesc *rowWire;
4952*4882a593Smuzhiyun
4953*4882a593Smuzhiyun for (r = 0, row = section->rows; r < section->num_rows; r++, row++) {
4954*4882a593Smuzhiyun rowWire = (xkbRowWireDesc *) wire;
4955*4882a593Smuzhiyun rowWire->top = row->top;
4956*4882a593Smuzhiyun rowWire->left = row->left;
4957*4882a593Smuzhiyun rowWire->nKeys = row->num_keys;
4958*4882a593Smuzhiyun rowWire->vertical = row->vertical;
4959*4882a593Smuzhiyun rowWire->pad = 0;
4960*4882a593Smuzhiyun if (swap) {
4961*4882a593Smuzhiyun swaps(&rowWire->top);
4962*4882a593Smuzhiyun swaps(&rowWire->left);
4963*4882a593Smuzhiyun }
4964*4882a593Smuzhiyun wire = (char *) &rowWire[1];
4965*4882a593Smuzhiyun if (row->keys) {
4966*4882a593Smuzhiyun int k;
4967*4882a593Smuzhiyun XkbKeyPtr key;
4968*4882a593Smuzhiyun xkbKeyWireDesc *keyWire;
4969*4882a593Smuzhiyun
4970*4882a593Smuzhiyun keyWire = (xkbKeyWireDesc *) wire;
4971*4882a593Smuzhiyun for (k = 0, key = row->keys; k < row->num_keys; k++, key++) {
4972*4882a593Smuzhiyun memcpy(keyWire[k].name, key->name.name,
4973*4882a593Smuzhiyun XkbKeyNameLength);
4974*4882a593Smuzhiyun keyWire[k].gap = key->gap;
4975*4882a593Smuzhiyun keyWire[k].shapeNdx = key->shape_ndx;
4976*4882a593Smuzhiyun keyWire[k].colorNdx = key->color_ndx;
4977*4882a593Smuzhiyun if (swap) {
4978*4882a593Smuzhiyun swaps(&keyWire[k].gap);
4979*4882a593Smuzhiyun }
4980*4882a593Smuzhiyun }
4981*4882a593Smuzhiyun wire = (char *) &keyWire[row->num_keys];
4982*4882a593Smuzhiyun }
4983*4882a593Smuzhiyun }
4984*4882a593Smuzhiyun }
4985*4882a593Smuzhiyun if (section->doodads) {
4986*4882a593Smuzhiyun wire = XkbWriteGeomDoodads(wire,
4987*4882a593Smuzhiyun section->num_doodads, section->doodads,
4988*4882a593Smuzhiyun swap);
4989*4882a593Smuzhiyun }
4990*4882a593Smuzhiyun if (section->overlays) {
4991*4882a593Smuzhiyun register int o;
4992*4882a593Smuzhiyun
4993*4882a593Smuzhiyun for (o = 0; o < section->num_overlays; o++) {
4994*4882a593Smuzhiyun wire = XkbWriteGeomOverlay(wire, §ion->overlays[o], swap);
4995*4882a593Smuzhiyun }
4996*4882a593Smuzhiyun }
4997*4882a593Smuzhiyun }
4998*4882a593Smuzhiyun return wire;
4999*4882a593Smuzhiyun }
5000*4882a593Smuzhiyun
5001*4882a593Smuzhiyun static Status
XkbComputeGetGeometryReplySize(XkbGeometryPtr geom,xkbGetGeometryReply * rep,Atom name)5002*4882a593Smuzhiyun XkbComputeGetGeometryReplySize(XkbGeometryPtr geom,
5003*4882a593Smuzhiyun xkbGetGeometryReply * rep, Atom name)
5004*4882a593Smuzhiyun {
5005*4882a593Smuzhiyun int len;
5006*4882a593Smuzhiyun
5007*4882a593Smuzhiyun if (geom != NULL) {
5008*4882a593Smuzhiyun len = XkbSizeCountedString(geom->label_font);
5009*4882a593Smuzhiyun len += XkbSizeGeomProperties(geom);
5010*4882a593Smuzhiyun len += XkbSizeGeomColors(geom);
5011*4882a593Smuzhiyun len += XkbSizeGeomShapes(geom);
5012*4882a593Smuzhiyun len += XkbSizeGeomSections(geom);
5013*4882a593Smuzhiyun len += XkbSizeGeomDoodads(geom->num_doodads, geom->doodads);
5014*4882a593Smuzhiyun len += XkbSizeGeomKeyAliases(geom);
5015*4882a593Smuzhiyun rep->length = len / 4;
5016*4882a593Smuzhiyun rep->found = TRUE;
5017*4882a593Smuzhiyun rep->name = geom->name;
5018*4882a593Smuzhiyun rep->widthMM = geom->width_mm;
5019*4882a593Smuzhiyun rep->heightMM = geom->height_mm;
5020*4882a593Smuzhiyun rep->nProperties = geom->num_properties;
5021*4882a593Smuzhiyun rep->nColors = geom->num_colors;
5022*4882a593Smuzhiyun rep->nShapes = geom->num_shapes;
5023*4882a593Smuzhiyun rep->nSections = geom->num_sections;
5024*4882a593Smuzhiyun rep->nDoodads = geom->num_doodads;
5025*4882a593Smuzhiyun rep->nKeyAliases = geom->num_key_aliases;
5026*4882a593Smuzhiyun rep->baseColorNdx = XkbGeomColorIndex(geom, geom->base_color);
5027*4882a593Smuzhiyun rep->labelColorNdx = XkbGeomColorIndex(geom, geom->label_color);
5028*4882a593Smuzhiyun }
5029*4882a593Smuzhiyun else {
5030*4882a593Smuzhiyun rep->length = 0;
5031*4882a593Smuzhiyun rep->found = FALSE;
5032*4882a593Smuzhiyun rep->name = name;
5033*4882a593Smuzhiyun rep->widthMM = rep->heightMM = 0;
5034*4882a593Smuzhiyun rep->nProperties = rep->nColors = rep->nShapes = 0;
5035*4882a593Smuzhiyun rep->nSections = rep->nDoodads = 0;
5036*4882a593Smuzhiyun rep->nKeyAliases = 0;
5037*4882a593Smuzhiyun rep->labelColorNdx = rep->baseColorNdx = 0;
5038*4882a593Smuzhiyun }
5039*4882a593Smuzhiyun return Success;
5040*4882a593Smuzhiyun }
5041*4882a593Smuzhiyun static int
XkbSendGeometry(ClientPtr client,XkbGeometryPtr geom,xkbGetGeometryReply * rep,Bool freeGeom)5042*4882a593Smuzhiyun XkbSendGeometry(ClientPtr client,
5043*4882a593Smuzhiyun XkbGeometryPtr geom, xkbGetGeometryReply * rep, Bool freeGeom)
5044*4882a593Smuzhiyun {
5045*4882a593Smuzhiyun char *desc, *start;
5046*4882a593Smuzhiyun int len;
5047*4882a593Smuzhiyun
5048*4882a593Smuzhiyun if (geom != NULL) {
5049*4882a593Smuzhiyun start = desc = xallocarray(rep->length, 4);
5050*4882a593Smuzhiyun if (!start)
5051*4882a593Smuzhiyun return BadAlloc;
5052*4882a593Smuzhiyun len = rep->length * 4;
5053*4882a593Smuzhiyun desc = XkbWriteCountedString(desc, geom->label_font, client->swapped);
5054*4882a593Smuzhiyun if (rep->nProperties > 0)
5055*4882a593Smuzhiyun desc = XkbWriteGeomProperties(desc, geom, client->swapped);
5056*4882a593Smuzhiyun if (rep->nColors > 0)
5057*4882a593Smuzhiyun desc = XkbWriteGeomColors(desc, geom, client->swapped);
5058*4882a593Smuzhiyun if (rep->nShapes > 0)
5059*4882a593Smuzhiyun desc = XkbWriteGeomShapes(desc, geom, client->swapped);
5060*4882a593Smuzhiyun if (rep->nSections > 0)
5061*4882a593Smuzhiyun desc = XkbWriteGeomSections(desc, geom, client->swapped);
5062*4882a593Smuzhiyun if (rep->nDoodads > 0)
5063*4882a593Smuzhiyun desc = XkbWriteGeomDoodads(desc, geom->num_doodads, geom->doodads,
5064*4882a593Smuzhiyun client->swapped);
5065*4882a593Smuzhiyun if (rep->nKeyAliases > 0)
5066*4882a593Smuzhiyun desc = XkbWriteGeomKeyAliases(desc, geom, client->swapped);
5067*4882a593Smuzhiyun if ((desc - start) != (len)) {
5068*4882a593Smuzhiyun ErrorF
5069*4882a593Smuzhiyun ("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n",
5070*4882a593Smuzhiyun len, (unsigned long) (desc - start));
5071*4882a593Smuzhiyun }
5072*4882a593Smuzhiyun }
5073*4882a593Smuzhiyun else {
5074*4882a593Smuzhiyun len = 0;
5075*4882a593Smuzhiyun start = NULL;
5076*4882a593Smuzhiyun }
5077*4882a593Smuzhiyun if (client->swapped) {
5078*4882a593Smuzhiyun swaps(&rep->sequenceNumber);
5079*4882a593Smuzhiyun swapl(&rep->length);
5080*4882a593Smuzhiyun swapl(&rep->name);
5081*4882a593Smuzhiyun swaps(&rep->widthMM);
5082*4882a593Smuzhiyun swaps(&rep->heightMM);
5083*4882a593Smuzhiyun swaps(&rep->nProperties);
5084*4882a593Smuzhiyun swaps(&rep->nColors);
5085*4882a593Smuzhiyun swaps(&rep->nShapes);
5086*4882a593Smuzhiyun swaps(&rep->nSections);
5087*4882a593Smuzhiyun swaps(&rep->nDoodads);
5088*4882a593Smuzhiyun swaps(&rep->nKeyAliases);
5089*4882a593Smuzhiyun }
5090*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbGetGeometryReply), rep);
5091*4882a593Smuzhiyun if (len > 0)
5092*4882a593Smuzhiyun WriteToClient(client, len, start);
5093*4882a593Smuzhiyun if (start != NULL)
5094*4882a593Smuzhiyun free((char *) start);
5095*4882a593Smuzhiyun if (freeGeom)
5096*4882a593Smuzhiyun XkbFreeGeometry(geom, XkbGeomAllMask, TRUE);
5097*4882a593Smuzhiyun return Success;
5098*4882a593Smuzhiyun }
5099*4882a593Smuzhiyun
5100*4882a593Smuzhiyun int
ProcXkbGetGeometry(ClientPtr client)5101*4882a593Smuzhiyun ProcXkbGetGeometry(ClientPtr client)
5102*4882a593Smuzhiyun {
5103*4882a593Smuzhiyun DeviceIntPtr dev;
5104*4882a593Smuzhiyun xkbGetGeometryReply rep;
5105*4882a593Smuzhiyun XkbGeometryPtr geom;
5106*4882a593Smuzhiyun Bool shouldFree;
5107*4882a593Smuzhiyun Status status;
5108*4882a593Smuzhiyun
5109*4882a593Smuzhiyun REQUEST(xkbGetGeometryReq);
5110*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbGetGeometryReq);
5111*4882a593Smuzhiyun
5112*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
5113*4882a593Smuzhiyun return BadAccess;
5114*4882a593Smuzhiyun
5115*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
5116*4882a593Smuzhiyun CHK_ATOM_OR_NONE(stuff->name);
5117*4882a593Smuzhiyun
5118*4882a593Smuzhiyun geom = XkbLookupNamedGeometry(dev, stuff->name, &shouldFree);
5119*4882a593Smuzhiyun rep = (xkbGetGeometryReply) {
5120*4882a593Smuzhiyun .type = X_Reply,
5121*4882a593Smuzhiyun .deviceID = dev->id,
5122*4882a593Smuzhiyun .sequenceNumber = client->sequence,
5123*4882a593Smuzhiyun .length = 0
5124*4882a593Smuzhiyun };
5125*4882a593Smuzhiyun status = XkbComputeGetGeometryReplySize(geom, &rep, stuff->name);
5126*4882a593Smuzhiyun if (status != Success)
5127*4882a593Smuzhiyun return status;
5128*4882a593Smuzhiyun else
5129*4882a593Smuzhiyun return XkbSendGeometry(client, geom, &rep, shouldFree);
5130*4882a593Smuzhiyun }
5131*4882a593Smuzhiyun
5132*4882a593Smuzhiyun /***====================================================================***/
5133*4882a593Smuzhiyun
5134*4882a593Smuzhiyun static Status
_GetCountedString(char ** wire_inout,ClientPtr client,char ** str)5135*4882a593Smuzhiyun _GetCountedString(char **wire_inout, ClientPtr client, char **str)
5136*4882a593Smuzhiyun {
5137*4882a593Smuzhiyun char *wire, *next;
5138*4882a593Smuzhiyun CARD16 len;
5139*4882a593Smuzhiyun
5140*4882a593Smuzhiyun wire = *wire_inout;
5141*4882a593Smuzhiyun len = *(CARD16 *) wire;
5142*4882a593Smuzhiyun if (client->swapped) {
5143*4882a593Smuzhiyun swaps(&len);
5144*4882a593Smuzhiyun }
5145*4882a593Smuzhiyun next = wire + XkbPaddedSize(len + 2);
5146*4882a593Smuzhiyun /* Check we're still within the size of the request */
5147*4882a593Smuzhiyun if (client->req_len <
5148*4882a593Smuzhiyun bytes_to_int32(next - (char *) client->requestBuffer))
5149*4882a593Smuzhiyun return BadValue;
5150*4882a593Smuzhiyun *str = malloc(len + 1);
5151*4882a593Smuzhiyun if (!*str)
5152*4882a593Smuzhiyun return BadAlloc;
5153*4882a593Smuzhiyun memcpy(*str, &wire[2], len);
5154*4882a593Smuzhiyun *(*str + len) = '\0';
5155*4882a593Smuzhiyun *wire_inout = next;
5156*4882a593Smuzhiyun return Success;
5157*4882a593Smuzhiyun }
5158*4882a593Smuzhiyun
5159*4882a593Smuzhiyun static Status
_CheckSetDoodad(char ** wire_inout,XkbGeometryPtr geom,XkbSectionPtr section,ClientPtr client)5160*4882a593Smuzhiyun _CheckSetDoodad(char **wire_inout,
5161*4882a593Smuzhiyun XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client)
5162*4882a593Smuzhiyun {
5163*4882a593Smuzhiyun char *wire;
5164*4882a593Smuzhiyun xkbDoodadWireDesc *dWire;
5165*4882a593Smuzhiyun xkbAnyDoodadWireDesc any;
5166*4882a593Smuzhiyun xkbTextDoodadWireDesc text;
5167*4882a593Smuzhiyun XkbDoodadPtr doodad;
5168*4882a593Smuzhiyun Status status;
5169*4882a593Smuzhiyun
5170*4882a593Smuzhiyun dWire = (xkbDoodadWireDesc *) (*wire_inout);
5171*4882a593Smuzhiyun any = dWire->any;
5172*4882a593Smuzhiyun wire = (char *) &dWire[1];
5173*4882a593Smuzhiyun if (client->swapped) {
5174*4882a593Smuzhiyun swapl(&any.name);
5175*4882a593Smuzhiyun swaps(&any.top);
5176*4882a593Smuzhiyun swaps(&any.left);
5177*4882a593Smuzhiyun swaps(&any.angle);
5178*4882a593Smuzhiyun }
5179*4882a593Smuzhiyun CHK_ATOM_ONLY(dWire->any.name);
5180*4882a593Smuzhiyun doodad = XkbAddGeomDoodad(geom, section, any.name);
5181*4882a593Smuzhiyun if (!doodad)
5182*4882a593Smuzhiyun return BadAlloc;
5183*4882a593Smuzhiyun doodad->any.type = dWire->any.type;
5184*4882a593Smuzhiyun doodad->any.priority = dWire->any.priority;
5185*4882a593Smuzhiyun doodad->any.top = any.top;
5186*4882a593Smuzhiyun doodad->any.left = any.left;
5187*4882a593Smuzhiyun doodad->any.angle = any.angle;
5188*4882a593Smuzhiyun switch (doodad->any.type) {
5189*4882a593Smuzhiyun case XkbOutlineDoodad:
5190*4882a593Smuzhiyun case XkbSolidDoodad:
5191*4882a593Smuzhiyun if (dWire->shape.colorNdx >= geom->num_colors) {
5192*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x40, geom->num_colors,
5193*4882a593Smuzhiyun dWire->shape.colorNdx);
5194*4882a593Smuzhiyun return BadMatch;
5195*4882a593Smuzhiyun }
5196*4882a593Smuzhiyun if (dWire->shape.shapeNdx >= geom->num_shapes) {
5197*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x41, geom->num_shapes,
5198*4882a593Smuzhiyun dWire->shape.shapeNdx);
5199*4882a593Smuzhiyun return BadMatch;
5200*4882a593Smuzhiyun }
5201*4882a593Smuzhiyun doodad->shape.color_ndx = dWire->shape.colorNdx;
5202*4882a593Smuzhiyun doodad->shape.shape_ndx = dWire->shape.shapeNdx;
5203*4882a593Smuzhiyun break;
5204*4882a593Smuzhiyun case XkbTextDoodad:
5205*4882a593Smuzhiyun if (dWire->text.colorNdx >= geom->num_colors) {
5206*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x42, geom->num_colors,
5207*4882a593Smuzhiyun dWire->text.colorNdx);
5208*4882a593Smuzhiyun return BadMatch;
5209*4882a593Smuzhiyun }
5210*4882a593Smuzhiyun text = dWire->text;
5211*4882a593Smuzhiyun if (client->swapped) {
5212*4882a593Smuzhiyun swaps(&text.width);
5213*4882a593Smuzhiyun swaps(&text.height);
5214*4882a593Smuzhiyun }
5215*4882a593Smuzhiyun doodad->text.width = text.width;
5216*4882a593Smuzhiyun doodad->text.height = text.height;
5217*4882a593Smuzhiyun doodad->text.color_ndx = dWire->text.colorNdx;
5218*4882a593Smuzhiyun status = _GetCountedString(&wire, client, &doodad->text.text);
5219*4882a593Smuzhiyun if (status != Success)
5220*4882a593Smuzhiyun return status;
5221*4882a593Smuzhiyun status = _GetCountedString(&wire, client, &doodad->text.font);
5222*4882a593Smuzhiyun if (status != Success) {
5223*4882a593Smuzhiyun free (doodad->text.text);
5224*4882a593Smuzhiyun return status;
5225*4882a593Smuzhiyun }
5226*4882a593Smuzhiyun break;
5227*4882a593Smuzhiyun case XkbIndicatorDoodad:
5228*4882a593Smuzhiyun if (dWire->indicator.onColorNdx >= geom->num_colors) {
5229*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x43, geom->num_colors,
5230*4882a593Smuzhiyun dWire->indicator.onColorNdx);
5231*4882a593Smuzhiyun return BadMatch;
5232*4882a593Smuzhiyun }
5233*4882a593Smuzhiyun if (dWire->indicator.offColorNdx >= geom->num_colors) {
5234*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x44, geom->num_colors,
5235*4882a593Smuzhiyun dWire->indicator.offColorNdx);
5236*4882a593Smuzhiyun return BadMatch;
5237*4882a593Smuzhiyun }
5238*4882a593Smuzhiyun if (dWire->indicator.shapeNdx >= geom->num_shapes) {
5239*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x45, geom->num_shapes,
5240*4882a593Smuzhiyun dWire->indicator.shapeNdx);
5241*4882a593Smuzhiyun return BadMatch;
5242*4882a593Smuzhiyun }
5243*4882a593Smuzhiyun doodad->indicator.shape_ndx = dWire->indicator.shapeNdx;
5244*4882a593Smuzhiyun doodad->indicator.on_color_ndx = dWire->indicator.onColorNdx;
5245*4882a593Smuzhiyun doodad->indicator.off_color_ndx = dWire->indicator.offColorNdx;
5246*4882a593Smuzhiyun break;
5247*4882a593Smuzhiyun case XkbLogoDoodad:
5248*4882a593Smuzhiyun if (dWire->logo.colorNdx >= geom->num_colors) {
5249*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x46, geom->num_colors,
5250*4882a593Smuzhiyun dWire->logo.colorNdx);
5251*4882a593Smuzhiyun return BadMatch;
5252*4882a593Smuzhiyun }
5253*4882a593Smuzhiyun if (dWire->logo.shapeNdx >= geom->num_shapes) {
5254*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x47, geom->num_shapes,
5255*4882a593Smuzhiyun dWire->logo.shapeNdx);
5256*4882a593Smuzhiyun return BadMatch;
5257*4882a593Smuzhiyun }
5258*4882a593Smuzhiyun doodad->logo.color_ndx = dWire->logo.colorNdx;
5259*4882a593Smuzhiyun doodad->logo.shape_ndx = dWire->logo.shapeNdx;
5260*4882a593Smuzhiyun status = _GetCountedString(&wire, client, &doodad->logo.logo_name);
5261*4882a593Smuzhiyun if (status != Success)
5262*4882a593Smuzhiyun return status;
5263*4882a593Smuzhiyun break;
5264*4882a593Smuzhiyun default:
5265*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x4F, dWire->any.type);
5266*4882a593Smuzhiyun return BadValue;
5267*4882a593Smuzhiyun }
5268*4882a593Smuzhiyun *wire_inout = wire;
5269*4882a593Smuzhiyun return Success;
5270*4882a593Smuzhiyun }
5271*4882a593Smuzhiyun
5272*4882a593Smuzhiyun static Status
_CheckSetOverlay(char ** wire_inout,XkbGeometryPtr geom,XkbSectionPtr section,ClientPtr client)5273*4882a593Smuzhiyun _CheckSetOverlay(char **wire_inout,
5274*4882a593Smuzhiyun XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client)
5275*4882a593Smuzhiyun {
5276*4882a593Smuzhiyun register int r;
5277*4882a593Smuzhiyun char *wire;
5278*4882a593Smuzhiyun XkbOverlayPtr ol;
5279*4882a593Smuzhiyun xkbOverlayWireDesc *olWire;
5280*4882a593Smuzhiyun xkbOverlayRowWireDesc *rWire;
5281*4882a593Smuzhiyun
5282*4882a593Smuzhiyun wire = *wire_inout;
5283*4882a593Smuzhiyun olWire = (xkbOverlayWireDesc *) wire;
5284*4882a593Smuzhiyun if (client->swapped) {
5285*4882a593Smuzhiyun swapl(&olWire->name);
5286*4882a593Smuzhiyun }
5287*4882a593Smuzhiyun CHK_ATOM_ONLY(olWire->name);
5288*4882a593Smuzhiyun ol = XkbAddGeomOverlay(section, olWire->name, olWire->nRows);
5289*4882a593Smuzhiyun rWire = (xkbOverlayRowWireDesc *) &olWire[1];
5290*4882a593Smuzhiyun for (r = 0; r < olWire->nRows; r++) {
5291*4882a593Smuzhiyun register int k;
5292*4882a593Smuzhiyun xkbOverlayKeyWireDesc *kWire;
5293*4882a593Smuzhiyun XkbOverlayRowPtr row;
5294*4882a593Smuzhiyun
5295*4882a593Smuzhiyun if (rWire->rowUnder > section->num_rows) {
5296*4882a593Smuzhiyun client->errorValue = _XkbErrCode4(0x20, r, section->num_rows,
5297*4882a593Smuzhiyun rWire->rowUnder);
5298*4882a593Smuzhiyun return BadMatch;
5299*4882a593Smuzhiyun }
5300*4882a593Smuzhiyun row = XkbAddGeomOverlayRow(ol, rWire->rowUnder, rWire->nKeys);
5301*4882a593Smuzhiyun kWire = (xkbOverlayKeyWireDesc *) &rWire[1];
5302*4882a593Smuzhiyun for (k = 0; k < rWire->nKeys; k++, kWire++) {
5303*4882a593Smuzhiyun if (XkbAddGeomOverlayKey(ol, row,
5304*4882a593Smuzhiyun (char *) kWire->over,
5305*4882a593Smuzhiyun (char *) kWire->under) == NULL) {
5306*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x21, r, k);
5307*4882a593Smuzhiyun return BadMatch;
5308*4882a593Smuzhiyun }
5309*4882a593Smuzhiyun }
5310*4882a593Smuzhiyun rWire = (xkbOverlayRowWireDesc *) kWire;
5311*4882a593Smuzhiyun }
5312*4882a593Smuzhiyun olWire = (xkbOverlayWireDesc *) rWire;
5313*4882a593Smuzhiyun wire = (char *) olWire;
5314*4882a593Smuzhiyun *wire_inout = wire;
5315*4882a593Smuzhiyun return Success;
5316*4882a593Smuzhiyun }
5317*4882a593Smuzhiyun
5318*4882a593Smuzhiyun static Status
_CheckSetSections(XkbGeometryPtr geom,xkbSetGeometryReq * req,char ** wire_inout,ClientPtr client)5319*4882a593Smuzhiyun _CheckSetSections(XkbGeometryPtr geom,
5320*4882a593Smuzhiyun xkbSetGeometryReq * req, char **wire_inout, ClientPtr client)
5321*4882a593Smuzhiyun {
5322*4882a593Smuzhiyun Status status;
5323*4882a593Smuzhiyun register int s;
5324*4882a593Smuzhiyun char *wire;
5325*4882a593Smuzhiyun xkbSectionWireDesc *sWire;
5326*4882a593Smuzhiyun XkbSectionPtr section;
5327*4882a593Smuzhiyun
5328*4882a593Smuzhiyun wire = *wire_inout;
5329*4882a593Smuzhiyun if (req->nSections < 1)
5330*4882a593Smuzhiyun return Success;
5331*4882a593Smuzhiyun sWire = (xkbSectionWireDesc *) wire;
5332*4882a593Smuzhiyun for (s = 0; s < req->nSections; s++) {
5333*4882a593Smuzhiyun register int r;
5334*4882a593Smuzhiyun xkbRowWireDesc *rWire;
5335*4882a593Smuzhiyun
5336*4882a593Smuzhiyun if (client->swapped) {
5337*4882a593Smuzhiyun swapl(&sWire->name);
5338*4882a593Smuzhiyun swaps(&sWire->top);
5339*4882a593Smuzhiyun swaps(&sWire->left);
5340*4882a593Smuzhiyun swaps(&sWire->width);
5341*4882a593Smuzhiyun swaps(&sWire->height);
5342*4882a593Smuzhiyun swaps(&sWire->angle);
5343*4882a593Smuzhiyun }
5344*4882a593Smuzhiyun CHK_ATOM_ONLY(sWire->name);
5345*4882a593Smuzhiyun section = XkbAddGeomSection(geom, sWire->name, sWire->nRows,
5346*4882a593Smuzhiyun sWire->nDoodads, sWire->nOverlays);
5347*4882a593Smuzhiyun if (!section)
5348*4882a593Smuzhiyun return BadAlloc;
5349*4882a593Smuzhiyun section->priority = sWire->priority;
5350*4882a593Smuzhiyun section->top = sWire->top;
5351*4882a593Smuzhiyun section->left = sWire->left;
5352*4882a593Smuzhiyun section->width = sWire->width;
5353*4882a593Smuzhiyun section->height = sWire->height;
5354*4882a593Smuzhiyun section->angle = sWire->angle;
5355*4882a593Smuzhiyun rWire = (xkbRowWireDesc *) &sWire[1];
5356*4882a593Smuzhiyun for (r = 0; r < sWire->nRows; r++) {
5357*4882a593Smuzhiyun register int k;
5358*4882a593Smuzhiyun XkbRowPtr row;
5359*4882a593Smuzhiyun xkbKeyWireDesc *kWire;
5360*4882a593Smuzhiyun
5361*4882a593Smuzhiyun if (client->swapped) {
5362*4882a593Smuzhiyun swaps(&rWire->top);
5363*4882a593Smuzhiyun swaps(&rWire->left);
5364*4882a593Smuzhiyun }
5365*4882a593Smuzhiyun row = XkbAddGeomRow(section, rWire->nKeys);
5366*4882a593Smuzhiyun if (!row)
5367*4882a593Smuzhiyun return BadAlloc;
5368*4882a593Smuzhiyun row->top = rWire->top;
5369*4882a593Smuzhiyun row->left = rWire->left;
5370*4882a593Smuzhiyun row->vertical = rWire->vertical;
5371*4882a593Smuzhiyun kWire = (xkbKeyWireDesc *) &rWire[1];
5372*4882a593Smuzhiyun for (k = 0; k < rWire->nKeys; k++) {
5373*4882a593Smuzhiyun XkbKeyPtr key;
5374*4882a593Smuzhiyun
5375*4882a593Smuzhiyun key = XkbAddGeomKey(row);
5376*4882a593Smuzhiyun if (!key)
5377*4882a593Smuzhiyun return BadAlloc;
5378*4882a593Smuzhiyun memcpy(key->name.name, kWire[k].name, XkbKeyNameLength);
5379*4882a593Smuzhiyun key->gap = kWire[k].gap;
5380*4882a593Smuzhiyun key->shape_ndx = kWire[k].shapeNdx;
5381*4882a593Smuzhiyun key->color_ndx = kWire[k].colorNdx;
5382*4882a593Smuzhiyun if (key->shape_ndx >= geom->num_shapes) {
5383*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x10, key->shape_ndx,
5384*4882a593Smuzhiyun geom->num_shapes);
5385*4882a593Smuzhiyun return BadMatch;
5386*4882a593Smuzhiyun }
5387*4882a593Smuzhiyun if (key->color_ndx >= geom->num_colors) {
5388*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x11, key->color_ndx,
5389*4882a593Smuzhiyun geom->num_colors);
5390*4882a593Smuzhiyun return BadMatch;
5391*4882a593Smuzhiyun }
5392*4882a593Smuzhiyun }
5393*4882a593Smuzhiyun rWire = (xkbRowWireDesc *) &kWire[rWire->nKeys];
5394*4882a593Smuzhiyun }
5395*4882a593Smuzhiyun wire = (char *) rWire;
5396*4882a593Smuzhiyun if (sWire->nDoodads > 0) {
5397*4882a593Smuzhiyun register int d;
5398*4882a593Smuzhiyun
5399*4882a593Smuzhiyun for (d = 0; d < sWire->nDoodads; d++) {
5400*4882a593Smuzhiyun status = _CheckSetDoodad(&wire, geom, section, client);
5401*4882a593Smuzhiyun if (status != Success)
5402*4882a593Smuzhiyun return status;
5403*4882a593Smuzhiyun }
5404*4882a593Smuzhiyun }
5405*4882a593Smuzhiyun if (sWire->nOverlays > 0) {
5406*4882a593Smuzhiyun register int o;
5407*4882a593Smuzhiyun
5408*4882a593Smuzhiyun for (o = 0; o < sWire->nOverlays; o++) {
5409*4882a593Smuzhiyun status = _CheckSetOverlay(&wire, geom, section, client);
5410*4882a593Smuzhiyun if (status != Success)
5411*4882a593Smuzhiyun return status;
5412*4882a593Smuzhiyun }
5413*4882a593Smuzhiyun }
5414*4882a593Smuzhiyun sWire = (xkbSectionWireDesc *) wire;
5415*4882a593Smuzhiyun }
5416*4882a593Smuzhiyun wire = (char *) sWire;
5417*4882a593Smuzhiyun *wire_inout = wire;
5418*4882a593Smuzhiyun return Success;
5419*4882a593Smuzhiyun }
5420*4882a593Smuzhiyun
5421*4882a593Smuzhiyun static Status
_CheckSetShapes(XkbGeometryPtr geom,xkbSetGeometryReq * req,char ** wire_inout,ClientPtr client)5422*4882a593Smuzhiyun _CheckSetShapes(XkbGeometryPtr geom,
5423*4882a593Smuzhiyun xkbSetGeometryReq * req, char **wire_inout, ClientPtr client)
5424*4882a593Smuzhiyun {
5425*4882a593Smuzhiyun register int i;
5426*4882a593Smuzhiyun char *wire;
5427*4882a593Smuzhiyun
5428*4882a593Smuzhiyun wire = *wire_inout;
5429*4882a593Smuzhiyun if (req->nShapes < 1) {
5430*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(0x06, req->nShapes);
5431*4882a593Smuzhiyun return BadValue;
5432*4882a593Smuzhiyun }
5433*4882a593Smuzhiyun else {
5434*4882a593Smuzhiyun xkbShapeWireDesc *shapeWire;
5435*4882a593Smuzhiyun XkbShapePtr shape;
5436*4882a593Smuzhiyun register int o;
5437*4882a593Smuzhiyun
5438*4882a593Smuzhiyun shapeWire = (xkbShapeWireDesc *) wire;
5439*4882a593Smuzhiyun for (i = 0; i < req->nShapes; i++) {
5440*4882a593Smuzhiyun xkbOutlineWireDesc *olWire;
5441*4882a593Smuzhiyun XkbOutlinePtr ol;
5442*4882a593Smuzhiyun
5443*4882a593Smuzhiyun shape =
5444*4882a593Smuzhiyun XkbAddGeomShape(geom, shapeWire->name, shapeWire->nOutlines);
5445*4882a593Smuzhiyun if (!shape)
5446*4882a593Smuzhiyun return BadAlloc;
5447*4882a593Smuzhiyun olWire = (xkbOutlineWireDesc *) (&shapeWire[1]);
5448*4882a593Smuzhiyun for (o = 0; o < shapeWire->nOutlines; o++) {
5449*4882a593Smuzhiyun register int p;
5450*4882a593Smuzhiyun XkbPointPtr pt;
5451*4882a593Smuzhiyun xkbPointWireDesc *ptWire;
5452*4882a593Smuzhiyun
5453*4882a593Smuzhiyun ol = XkbAddGeomOutline(shape, olWire->nPoints);
5454*4882a593Smuzhiyun if (!ol)
5455*4882a593Smuzhiyun return BadAlloc;
5456*4882a593Smuzhiyun ol->corner_radius = olWire->cornerRadius;
5457*4882a593Smuzhiyun ptWire = (xkbPointWireDesc *) &olWire[1];
5458*4882a593Smuzhiyun for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++) {
5459*4882a593Smuzhiyun pt->x = ptWire[p].x;
5460*4882a593Smuzhiyun pt->y = ptWire[p].y;
5461*4882a593Smuzhiyun if (client->swapped) {
5462*4882a593Smuzhiyun swaps(&pt->x);
5463*4882a593Smuzhiyun swaps(&pt->y);
5464*4882a593Smuzhiyun }
5465*4882a593Smuzhiyun }
5466*4882a593Smuzhiyun ol->num_points = olWire->nPoints;
5467*4882a593Smuzhiyun olWire = (xkbOutlineWireDesc *) (&ptWire[olWire->nPoints]);
5468*4882a593Smuzhiyun }
5469*4882a593Smuzhiyun if (shapeWire->primaryNdx != XkbNoShape)
5470*4882a593Smuzhiyun shape->primary = &shape->outlines[shapeWire->primaryNdx];
5471*4882a593Smuzhiyun if (shapeWire->approxNdx != XkbNoShape)
5472*4882a593Smuzhiyun shape->approx = &shape->outlines[shapeWire->approxNdx];
5473*4882a593Smuzhiyun shapeWire = (xkbShapeWireDesc *) olWire;
5474*4882a593Smuzhiyun }
5475*4882a593Smuzhiyun wire = (char *) shapeWire;
5476*4882a593Smuzhiyun }
5477*4882a593Smuzhiyun if (geom->num_shapes != req->nShapes) {
5478*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x07, geom->num_shapes, req->nShapes);
5479*4882a593Smuzhiyun return BadMatch;
5480*4882a593Smuzhiyun }
5481*4882a593Smuzhiyun
5482*4882a593Smuzhiyun *wire_inout = wire;
5483*4882a593Smuzhiyun return Success;
5484*4882a593Smuzhiyun }
5485*4882a593Smuzhiyun
5486*4882a593Smuzhiyun static Status
_CheckSetGeom(XkbGeometryPtr geom,xkbSetGeometryReq * req,ClientPtr client)5487*4882a593Smuzhiyun _CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client)
5488*4882a593Smuzhiyun {
5489*4882a593Smuzhiyun register int i;
5490*4882a593Smuzhiyun Status status;
5491*4882a593Smuzhiyun char *wire;
5492*4882a593Smuzhiyun
5493*4882a593Smuzhiyun wire = (char *) &req[1];
5494*4882a593Smuzhiyun status = _GetCountedString(&wire, client, &geom->label_font);
5495*4882a593Smuzhiyun if (status != Success)
5496*4882a593Smuzhiyun return status;
5497*4882a593Smuzhiyun
5498*4882a593Smuzhiyun for (i = 0; i < req->nProperties; i++) {
5499*4882a593Smuzhiyun char *name, *val;
5500*4882a593Smuzhiyun
5501*4882a593Smuzhiyun status = _GetCountedString(&wire, client, &name);
5502*4882a593Smuzhiyun if (status != Success)
5503*4882a593Smuzhiyun return status;
5504*4882a593Smuzhiyun status = _GetCountedString(&wire, client, &val);
5505*4882a593Smuzhiyun if (status != Success) {
5506*4882a593Smuzhiyun free(name);
5507*4882a593Smuzhiyun return status;
5508*4882a593Smuzhiyun }
5509*4882a593Smuzhiyun if (XkbAddGeomProperty(geom, name, val) == NULL) {
5510*4882a593Smuzhiyun free(name);
5511*4882a593Smuzhiyun free(val);
5512*4882a593Smuzhiyun return BadAlloc;
5513*4882a593Smuzhiyun }
5514*4882a593Smuzhiyun free(name);
5515*4882a593Smuzhiyun free(val);
5516*4882a593Smuzhiyun }
5517*4882a593Smuzhiyun
5518*4882a593Smuzhiyun if (req->nColors < 2) {
5519*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x01, 2, req->nColors);
5520*4882a593Smuzhiyun return BadValue;
5521*4882a593Smuzhiyun }
5522*4882a593Smuzhiyun if (req->baseColorNdx > req->nColors) {
5523*4882a593Smuzhiyun client->errorValue =
5524*4882a593Smuzhiyun _XkbErrCode3(0x03, req->nColors, req->baseColorNdx);
5525*4882a593Smuzhiyun return BadMatch;
5526*4882a593Smuzhiyun }
5527*4882a593Smuzhiyun if (req->labelColorNdx > req->nColors) {
5528*4882a593Smuzhiyun client->errorValue =
5529*4882a593Smuzhiyun _XkbErrCode3(0x03, req->nColors, req->labelColorNdx);
5530*4882a593Smuzhiyun return BadMatch;
5531*4882a593Smuzhiyun }
5532*4882a593Smuzhiyun if (req->labelColorNdx == req->baseColorNdx) {
5533*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x04, req->baseColorNdx,
5534*4882a593Smuzhiyun req->labelColorNdx);
5535*4882a593Smuzhiyun return BadMatch;
5536*4882a593Smuzhiyun }
5537*4882a593Smuzhiyun
5538*4882a593Smuzhiyun for (i = 0; i < req->nColors; i++) {
5539*4882a593Smuzhiyun char *name;
5540*4882a593Smuzhiyun
5541*4882a593Smuzhiyun status = _GetCountedString(&wire, client, &name);
5542*4882a593Smuzhiyun if (status != Success)
5543*4882a593Smuzhiyun return status;
5544*4882a593Smuzhiyun if (!XkbAddGeomColor(geom, name, geom->num_colors)) {
5545*4882a593Smuzhiyun free(name);
5546*4882a593Smuzhiyun return BadAlloc;
5547*4882a593Smuzhiyun }
5548*4882a593Smuzhiyun free(name);
5549*4882a593Smuzhiyun }
5550*4882a593Smuzhiyun if (req->nColors != geom->num_colors) {
5551*4882a593Smuzhiyun client->errorValue = _XkbErrCode3(0x05, req->nColors, geom->num_colors);
5552*4882a593Smuzhiyun return BadMatch;
5553*4882a593Smuzhiyun }
5554*4882a593Smuzhiyun geom->label_color = &geom->colors[req->labelColorNdx];
5555*4882a593Smuzhiyun geom->base_color = &geom->colors[req->baseColorNdx];
5556*4882a593Smuzhiyun
5557*4882a593Smuzhiyun if ((status = _CheckSetShapes(geom, req, &wire, client)) != Success)
5558*4882a593Smuzhiyun return status;
5559*4882a593Smuzhiyun
5560*4882a593Smuzhiyun if ((status = _CheckSetSections(geom, req, &wire, client)) != Success)
5561*4882a593Smuzhiyun return status;
5562*4882a593Smuzhiyun
5563*4882a593Smuzhiyun for (i = 0; i < req->nDoodads; i++) {
5564*4882a593Smuzhiyun status = _CheckSetDoodad(&wire, geom, NULL, client);
5565*4882a593Smuzhiyun if (status != Success)
5566*4882a593Smuzhiyun return status;
5567*4882a593Smuzhiyun }
5568*4882a593Smuzhiyun
5569*4882a593Smuzhiyun for (i = 0; i < req->nKeyAliases; i++) {
5570*4882a593Smuzhiyun if (XkbAddGeomKeyAlias(geom, &wire[XkbKeyNameLength], wire) == NULL)
5571*4882a593Smuzhiyun return BadAlloc;
5572*4882a593Smuzhiyun wire += 2 * XkbKeyNameLength;
5573*4882a593Smuzhiyun }
5574*4882a593Smuzhiyun return Success;
5575*4882a593Smuzhiyun }
5576*4882a593Smuzhiyun
5577*4882a593Smuzhiyun static int
_XkbSetGeometry(ClientPtr client,DeviceIntPtr dev,xkbSetGeometryReq * stuff)5578*4882a593Smuzhiyun _XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq * stuff)
5579*4882a593Smuzhiyun {
5580*4882a593Smuzhiyun XkbDescPtr xkb;
5581*4882a593Smuzhiyun Bool new_name;
5582*4882a593Smuzhiyun xkbNewKeyboardNotify nkn;
5583*4882a593Smuzhiyun XkbGeometryPtr geom, old;
5584*4882a593Smuzhiyun XkbGeometrySizesRec sizes;
5585*4882a593Smuzhiyun Status status;
5586*4882a593Smuzhiyun
5587*4882a593Smuzhiyun xkb = dev->key->xkbInfo->desc;
5588*4882a593Smuzhiyun old = xkb->geom;
5589*4882a593Smuzhiyun xkb->geom = NULL;
5590*4882a593Smuzhiyun
5591*4882a593Smuzhiyun sizes.which = XkbGeomAllMask;
5592*4882a593Smuzhiyun sizes.num_properties = stuff->nProperties;
5593*4882a593Smuzhiyun sizes.num_colors = stuff->nColors;
5594*4882a593Smuzhiyun sizes.num_shapes = stuff->nShapes;
5595*4882a593Smuzhiyun sizes.num_sections = stuff->nSections;
5596*4882a593Smuzhiyun sizes.num_doodads = stuff->nDoodads;
5597*4882a593Smuzhiyun sizes.num_key_aliases = stuff->nKeyAliases;
5598*4882a593Smuzhiyun if ((status = XkbAllocGeometry(xkb, &sizes)) != Success) {
5599*4882a593Smuzhiyun xkb->geom = old;
5600*4882a593Smuzhiyun return status;
5601*4882a593Smuzhiyun }
5602*4882a593Smuzhiyun geom = xkb->geom;
5603*4882a593Smuzhiyun geom->name = stuff->name;
5604*4882a593Smuzhiyun geom->width_mm = stuff->widthMM;
5605*4882a593Smuzhiyun geom->height_mm = stuff->heightMM;
5606*4882a593Smuzhiyun if ((status = _CheckSetGeom(geom, stuff, client)) != Success) {
5607*4882a593Smuzhiyun XkbFreeGeometry(geom, XkbGeomAllMask, TRUE);
5608*4882a593Smuzhiyun xkb->geom = old;
5609*4882a593Smuzhiyun return status;
5610*4882a593Smuzhiyun }
5611*4882a593Smuzhiyun new_name = (xkb->names->geometry != geom->name);
5612*4882a593Smuzhiyun xkb->names->geometry = geom->name;
5613*4882a593Smuzhiyun if (old)
5614*4882a593Smuzhiyun XkbFreeGeometry(old, XkbGeomAllMask, TRUE);
5615*4882a593Smuzhiyun if (new_name) {
5616*4882a593Smuzhiyun xkbNamesNotify nn;
5617*4882a593Smuzhiyun
5618*4882a593Smuzhiyun memset(&nn, 0, sizeof(xkbNamesNotify));
5619*4882a593Smuzhiyun nn.changed = XkbGeometryNameMask;
5620*4882a593Smuzhiyun XkbSendNamesNotify(dev, &nn);
5621*4882a593Smuzhiyun }
5622*4882a593Smuzhiyun nkn.deviceID = nkn.oldDeviceID = dev->id;
5623*4882a593Smuzhiyun nkn.minKeyCode = nkn.oldMinKeyCode = xkb->min_key_code;
5624*4882a593Smuzhiyun nkn.maxKeyCode = nkn.oldMaxKeyCode = xkb->max_key_code;
5625*4882a593Smuzhiyun nkn.requestMajor = XkbReqCode;
5626*4882a593Smuzhiyun nkn.requestMinor = X_kbSetGeometry;
5627*4882a593Smuzhiyun nkn.changed = XkbNKN_GeometryMask;
5628*4882a593Smuzhiyun XkbSendNewKeyboardNotify(dev, &nkn);
5629*4882a593Smuzhiyun return Success;
5630*4882a593Smuzhiyun }
5631*4882a593Smuzhiyun
5632*4882a593Smuzhiyun int
ProcXkbSetGeometry(ClientPtr client)5633*4882a593Smuzhiyun ProcXkbSetGeometry(ClientPtr client)
5634*4882a593Smuzhiyun {
5635*4882a593Smuzhiyun DeviceIntPtr dev;
5636*4882a593Smuzhiyun int rc;
5637*4882a593Smuzhiyun
5638*4882a593Smuzhiyun REQUEST(xkbSetGeometryReq);
5639*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq);
5640*4882a593Smuzhiyun
5641*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
5642*4882a593Smuzhiyun return BadAccess;
5643*4882a593Smuzhiyun
5644*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
5645*4882a593Smuzhiyun CHK_ATOM_OR_NONE(stuff->name);
5646*4882a593Smuzhiyun
5647*4882a593Smuzhiyun rc = _XkbSetGeometry(client, dev, stuff);
5648*4882a593Smuzhiyun if (rc != Success)
5649*4882a593Smuzhiyun return rc;
5650*4882a593Smuzhiyun
5651*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd) {
5652*4882a593Smuzhiyun DeviceIntPtr other;
5653*4882a593Smuzhiyun
5654*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
5655*4882a593Smuzhiyun if ((other != dev) && other->key && !IsMaster(other) &&
5656*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) {
5657*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
5658*4882a593Smuzhiyun DixManageAccess);
5659*4882a593Smuzhiyun if (rc == Success)
5660*4882a593Smuzhiyun _XkbSetGeometry(client, other, stuff);
5661*4882a593Smuzhiyun }
5662*4882a593Smuzhiyun }
5663*4882a593Smuzhiyun }
5664*4882a593Smuzhiyun
5665*4882a593Smuzhiyun return Success;
5666*4882a593Smuzhiyun }
5667*4882a593Smuzhiyun
5668*4882a593Smuzhiyun /***====================================================================***/
5669*4882a593Smuzhiyun
5670*4882a593Smuzhiyun int
ProcXkbPerClientFlags(ClientPtr client)5671*4882a593Smuzhiyun ProcXkbPerClientFlags(ClientPtr client)
5672*4882a593Smuzhiyun {
5673*4882a593Smuzhiyun DeviceIntPtr dev;
5674*4882a593Smuzhiyun xkbPerClientFlagsReply rep;
5675*4882a593Smuzhiyun XkbInterestPtr interest;
5676*4882a593Smuzhiyun Mask access_mode = DixGetAttrAccess | DixSetAttrAccess;
5677*4882a593Smuzhiyun
5678*4882a593Smuzhiyun REQUEST(xkbPerClientFlagsReq);
5679*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbPerClientFlagsReq);
5680*4882a593Smuzhiyun
5681*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
5682*4882a593Smuzhiyun return BadAccess;
5683*4882a593Smuzhiyun
5684*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode);
5685*4882a593Smuzhiyun CHK_MASK_LEGAL(0x01, stuff->change, XkbPCF_AllFlagsMask);
5686*4882a593Smuzhiyun CHK_MASK_MATCH(0x02, stuff->change, stuff->value);
5687*4882a593Smuzhiyun
5688*4882a593Smuzhiyun interest = XkbFindClientResource((DevicePtr) dev, client);
5689*4882a593Smuzhiyun if (stuff->change) {
5690*4882a593Smuzhiyun client->xkbClientFlags &= ~stuff->change;
5691*4882a593Smuzhiyun client->xkbClientFlags |= stuff->value;
5692*4882a593Smuzhiyun }
5693*4882a593Smuzhiyun if (stuff->change & XkbPCF_AutoResetControlsMask) {
5694*4882a593Smuzhiyun Bool want;
5695*4882a593Smuzhiyun
5696*4882a593Smuzhiyun want = stuff->value & XkbPCF_AutoResetControlsMask;
5697*4882a593Smuzhiyun if (interest && !want) {
5698*4882a593Smuzhiyun interest->autoCtrls = interest->autoCtrlValues = 0;
5699*4882a593Smuzhiyun }
5700*4882a593Smuzhiyun else if (want && (!interest)) {
5701*4882a593Smuzhiyun XID id = FakeClientID(client->index);
5702*4882a593Smuzhiyun
5703*4882a593Smuzhiyun if (!AddResource(id, RT_XKBCLIENT, dev))
5704*4882a593Smuzhiyun return BadAlloc;
5705*4882a593Smuzhiyun interest = XkbAddClientResource((DevicePtr) dev, client, id);
5706*4882a593Smuzhiyun if (!interest)
5707*4882a593Smuzhiyun return BadAlloc;
5708*4882a593Smuzhiyun }
5709*4882a593Smuzhiyun if (interest && want) {
5710*4882a593Smuzhiyun register unsigned affect;
5711*4882a593Smuzhiyun
5712*4882a593Smuzhiyun affect = stuff->ctrlsToChange;
5713*4882a593Smuzhiyun
5714*4882a593Smuzhiyun CHK_MASK_LEGAL(0x03, affect, XkbAllBooleanCtrlsMask);
5715*4882a593Smuzhiyun CHK_MASK_MATCH(0x04, affect, stuff->autoCtrls);
5716*4882a593Smuzhiyun CHK_MASK_MATCH(0x05, stuff->autoCtrls, stuff->autoCtrlValues);
5717*4882a593Smuzhiyun
5718*4882a593Smuzhiyun interest->autoCtrls &= ~affect;
5719*4882a593Smuzhiyun interest->autoCtrlValues &= ~affect;
5720*4882a593Smuzhiyun interest->autoCtrls |= stuff->autoCtrls & affect;
5721*4882a593Smuzhiyun interest->autoCtrlValues |= stuff->autoCtrlValues & affect;
5722*4882a593Smuzhiyun }
5723*4882a593Smuzhiyun }
5724*4882a593Smuzhiyun
5725*4882a593Smuzhiyun rep = (xkbPerClientFlagsReply) {
5726*4882a593Smuzhiyun .type = X_Reply,
5727*4882a593Smuzhiyun .sequenceNumber = client->sequence,
5728*4882a593Smuzhiyun .length = 0,
5729*4882a593Smuzhiyun .supported = XkbPCF_AllFlagsMask,
5730*4882a593Smuzhiyun .value = client->xkbClientFlags & XkbPCF_AllFlagsMask,
5731*4882a593Smuzhiyun .autoCtrls = interest ? interest->autoCtrls : 0,
5732*4882a593Smuzhiyun .autoCtrlValues = interest ? interest->autoCtrlValues : 0,
5733*4882a593Smuzhiyun };
5734*4882a593Smuzhiyun if (client->swapped) {
5735*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
5736*4882a593Smuzhiyun swapl(&rep.supported);
5737*4882a593Smuzhiyun swapl(&rep.value);
5738*4882a593Smuzhiyun swapl(&rep.autoCtrls);
5739*4882a593Smuzhiyun swapl(&rep.autoCtrlValues);
5740*4882a593Smuzhiyun }
5741*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbPerClientFlagsReply), &rep);
5742*4882a593Smuzhiyun return Success;
5743*4882a593Smuzhiyun }
5744*4882a593Smuzhiyun
5745*4882a593Smuzhiyun /***====================================================================***/
5746*4882a593Smuzhiyun
5747*4882a593Smuzhiyun /* all latin-1 alphanumerics, plus parens, minus, underscore, slash */
5748*4882a593Smuzhiyun /* and wildcards */
5749*4882a593Smuzhiyun static unsigned char componentSpecLegal[] = {
5750*4882a593Smuzhiyun 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87,
5751*4882a593Smuzhiyun 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
5752*4882a593Smuzhiyun 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5753*4882a593Smuzhiyun 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
5754*4882a593Smuzhiyun };
5755*4882a593Smuzhiyun
5756*4882a593Smuzhiyun /* same as above but accepts percent, plus and bar too */
5757*4882a593Smuzhiyun static unsigned char componentExprLegal[] = {
5758*4882a593Smuzhiyun 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87,
5759*4882a593Smuzhiyun 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17,
5760*4882a593Smuzhiyun 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5761*4882a593Smuzhiyun 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
5762*4882a593Smuzhiyun };
5763*4882a593Smuzhiyun
5764*4882a593Smuzhiyun static char *
GetComponentSpec(unsigned char ** pWire,Bool allowExpr,int * errRtrn)5765*4882a593Smuzhiyun GetComponentSpec(unsigned char **pWire, Bool allowExpr, int *errRtrn)
5766*4882a593Smuzhiyun {
5767*4882a593Smuzhiyun int len;
5768*4882a593Smuzhiyun register int i;
5769*4882a593Smuzhiyun unsigned char *wire, *str, *tmp, *legal;
5770*4882a593Smuzhiyun
5771*4882a593Smuzhiyun if (allowExpr)
5772*4882a593Smuzhiyun legal = &componentExprLegal[0];
5773*4882a593Smuzhiyun else
5774*4882a593Smuzhiyun legal = &componentSpecLegal[0];
5775*4882a593Smuzhiyun
5776*4882a593Smuzhiyun wire = *pWire;
5777*4882a593Smuzhiyun len = (*(unsigned char *) wire++);
5778*4882a593Smuzhiyun if (len > 0) {
5779*4882a593Smuzhiyun str = calloc(1, len + 1);
5780*4882a593Smuzhiyun if (str) {
5781*4882a593Smuzhiyun tmp = str;
5782*4882a593Smuzhiyun for (i = 0; i < len; i++) {
5783*4882a593Smuzhiyun if (legal[(*wire) / 8] & (1 << ((*wire) % 8)))
5784*4882a593Smuzhiyun *tmp++ = *wire++;
5785*4882a593Smuzhiyun else
5786*4882a593Smuzhiyun wire++;
5787*4882a593Smuzhiyun }
5788*4882a593Smuzhiyun if (tmp != str)
5789*4882a593Smuzhiyun *tmp++ = '\0';
5790*4882a593Smuzhiyun else {
5791*4882a593Smuzhiyun free(str);
5792*4882a593Smuzhiyun str = NULL;
5793*4882a593Smuzhiyun }
5794*4882a593Smuzhiyun }
5795*4882a593Smuzhiyun else {
5796*4882a593Smuzhiyun *errRtrn = BadAlloc;
5797*4882a593Smuzhiyun }
5798*4882a593Smuzhiyun }
5799*4882a593Smuzhiyun else {
5800*4882a593Smuzhiyun str = NULL;
5801*4882a593Smuzhiyun }
5802*4882a593Smuzhiyun *pWire = wire;
5803*4882a593Smuzhiyun return (char *) str;
5804*4882a593Smuzhiyun }
5805*4882a593Smuzhiyun
5806*4882a593Smuzhiyun /***====================================================================***/
5807*4882a593Smuzhiyun
5808*4882a593Smuzhiyun int
ProcXkbListComponents(ClientPtr client)5809*4882a593Smuzhiyun ProcXkbListComponents(ClientPtr client)
5810*4882a593Smuzhiyun {
5811*4882a593Smuzhiyun DeviceIntPtr dev;
5812*4882a593Smuzhiyun xkbListComponentsReply rep;
5813*4882a593Smuzhiyun unsigned len;
5814*4882a593Smuzhiyun unsigned char *str;
5815*4882a593Smuzhiyun uint8_t size;
5816*4882a593Smuzhiyun int i;
5817*4882a593Smuzhiyun
5818*4882a593Smuzhiyun REQUEST(xkbListComponentsReq);
5819*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xkbListComponentsReq);
5820*4882a593Smuzhiyun
5821*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
5822*4882a593Smuzhiyun return BadAccess;
5823*4882a593Smuzhiyun
5824*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
5825*4882a593Smuzhiyun
5826*4882a593Smuzhiyun /* The request is followed by six Pascal strings (i.e. size in characters
5827*4882a593Smuzhiyun * followed by a string pattern) describing what the client wants us to
5828*4882a593Smuzhiyun * list. We don't care, but might as well check they haven't got the
5829*4882a593Smuzhiyun * length wrong. */
5830*4882a593Smuzhiyun str = (unsigned char *) &stuff[1];
5831*4882a593Smuzhiyun for (i = 0; i < 6; i++) {
5832*4882a593Smuzhiyun size = *((uint8_t *)str);
5833*4882a593Smuzhiyun len = (str + size + 1) - ((unsigned char *) stuff);
5834*4882a593Smuzhiyun if ((XkbPaddedSize(len) / 4) > stuff->length)
5835*4882a593Smuzhiyun return BadLength;
5836*4882a593Smuzhiyun str += (size + 1);
5837*4882a593Smuzhiyun }
5838*4882a593Smuzhiyun if ((XkbPaddedSize(len) / 4) != stuff->length)
5839*4882a593Smuzhiyun return BadLength;
5840*4882a593Smuzhiyun rep = (xkbListComponentsReply) {
5841*4882a593Smuzhiyun .type = X_Reply,
5842*4882a593Smuzhiyun .deviceID = dev->id,
5843*4882a593Smuzhiyun .sequenceNumber = client->sequence,
5844*4882a593Smuzhiyun .length = 0,
5845*4882a593Smuzhiyun .nKeymaps = 0,
5846*4882a593Smuzhiyun .nKeycodes = 0,
5847*4882a593Smuzhiyun .nTypes = 0,
5848*4882a593Smuzhiyun .nCompatMaps = 0,
5849*4882a593Smuzhiyun .nSymbols = 0,
5850*4882a593Smuzhiyun .nGeometries = 0,
5851*4882a593Smuzhiyun .extra = 0
5852*4882a593Smuzhiyun };
5853*4882a593Smuzhiyun if (client->swapped) {
5854*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
5855*4882a593Smuzhiyun swapl(&rep.length);
5856*4882a593Smuzhiyun swaps(&rep.nKeymaps);
5857*4882a593Smuzhiyun swaps(&rep.nKeycodes);
5858*4882a593Smuzhiyun swaps(&rep.nTypes);
5859*4882a593Smuzhiyun swaps(&rep.nCompatMaps);
5860*4882a593Smuzhiyun swaps(&rep.nSymbols);
5861*4882a593Smuzhiyun swaps(&rep.nGeometries);
5862*4882a593Smuzhiyun swaps(&rep.extra);
5863*4882a593Smuzhiyun }
5864*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbListComponentsReply), &rep);
5865*4882a593Smuzhiyun return Success;
5866*4882a593Smuzhiyun }
5867*4882a593Smuzhiyun
5868*4882a593Smuzhiyun /***====================================================================***/
5869*4882a593Smuzhiyun int
ProcXkbGetKbdByName(ClientPtr client)5870*4882a593Smuzhiyun ProcXkbGetKbdByName(ClientPtr client)
5871*4882a593Smuzhiyun {
5872*4882a593Smuzhiyun DeviceIntPtr dev;
5873*4882a593Smuzhiyun DeviceIntPtr tmpd;
5874*4882a593Smuzhiyun DeviceIntPtr master;
5875*4882a593Smuzhiyun xkbGetKbdByNameReply rep = { 0 };
5876*4882a593Smuzhiyun xkbGetMapReply mrep = { 0 };
5877*4882a593Smuzhiyun xkbGetCompatMapReply crep = { 0 };
5878*4882a593Smuzhiyun xkbGetIndicatorMapReply irep = { 0 };
5879*4882a593Smuzhiyun xkbGetNamesReply nrep = { 0 };
5880*4882a593Smuzhiyun xkbGetGeometryReply grep = { 0 };
5881*4882a593Smuzhiyun XkbComponentNamesRec names = { 0 };
5882*4882a593Smuzhiyun XkbDescPtr xkb, new;
5883*4882a593Smuzhiyun XkbEventCauseRec cause;
5884*4882a593Smuzhiyun unsigned char *str;
5885*4882a593Smuzhiyun char mapFile[PATH_MAX];
5886*4882a593Smuzhiyun unsigned len;
5887*4882a593Smuzhiyun unsigned fwant, fneed, reported;
5888*4882a593Smuzhiyun int status;
5889*4882a593Smuzhiyun Bool geom_changed;
5890*4882a593Smuzhiyun XkbSrvLedInfoPtr old_sli;
5891*4882a593Smuzhiyun XkbSrvLedInfoPtr sli;
5892*4882a593Smuzhiyun Mask access_mode = DixGetAttrAccess | DixManageAccess;
5893*4882a593Smuzhiyun
5894*4882a593Smuzhiyun REQUEST(xkbGetKbdByNameReq);
5895*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq);
5896*4882a593Smuzhiyun
5897*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
5898*4882a593Smuzhiyun return BadAccess;
5899*4882a593Smuzhiyun
5900*4882a593Smuzhiyun CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode);
5901*4882a593Smuzhiyun master = GetMaster(dev, MASTER_KEYBOARD);
5902*4882a593Smuzhiyun
5903*4882a593Smuzhiyun xkb = dev->key->xkbInfo->desc;
5904*4882a593Smuzhiyun status = Success;
5905*4882a593Smuzhiyun str = (unsigned char *) &stuff[1];
5906*4882a593Smuzhiyun if (GetComponentSpec(&str, TRUE, &status)) /* keymap, unsupported */
5907*4882a593Smuzhiyun return BadMatch;
5908*4882a593Smuzhiyun names.keycodes = GetComponentSpec(&str, TRUE, &status);
5909*4882a593Smuzhiyun names.types = GetComponentSpec(&str, TRUE, &status);
5910*4882a593Smuzhiyun names.compat = GetComponentSpec(&str, TRUE, &status);
5911*4882a593Smuzhiyun names.symbols = GetComponentSpec(&str, TRUE, &status);
5912*4882a593Smuzhiyun names.geometry = GetComponentSpec(&str, TRUE, &status);
5913*4882a593Smuzhiyun if (status != Success)
5914*4882a593Smuzhiyun return status;
5915*4882a593Smuzhiyun len = str - ((unsigned char *) stuff);
5916*4882a593Smuzhiyun if ((XkbPaddedSize(len) / 4) != stuff->length)
5917*4882a593Smuzhiyun return BadLength;
5918*4882a593Smuzhiyun
5919*4882a593Smuzhiyun CHK_MASK_LEGAL(0x01, stuff->want, XkbGBN_AllComponentsMask);
5920*4882a593Smuzhiyun CHK_MASK_LEGAL(0x02, stuff->need, XkbGBN_AllComponentsMask);
5921*4882a593Smuzhiyun
5922*4882a593Smuzhiyun if (stuff->load)
5923*4882a593Smuzhiyun fwant = XkbGBN_AllComponentsMask;
5924*4882a593Smuzhiyun else
5925*4882a593Smuzhiyun fwant = stuff->want | stuff->need;
5926*4882a593Smuzhiyun if ((!names.compat) &&
5927*4882a593Smuzhiyun (fwant & (XkbGBN_CompatMapMask | XkbGBN_IndicatorMapMask))) {
5928*4882a593Smuzhiyun names.compat = Xstrdup("%");
5929*4882a593Smuzhiyun }
5930*4882a593Smuzhiyun if ((!names.types) && (fwant & (XkbGBN_TypesMask))) {
5931*4882a593Smuzhiyun names.types = Xstrdup("%");
5932*4882a593Smuzhiyun }
5933*4882a593Smuzhiyun if ((!names.symbols) && (fwant & XkbGBN_SymbolsMask)) {
5934*4882a593Smuzhiyun names.symbols = Xstrdup("%");
5935*4882a593Smuzhiyun }
5936*4882a593Smuzhiyun geom_changed = ((names.geometry != NULL) &&
5937*4882a593Smuzhiyun (strcmp(names.geometry, "%") != 0));
5938*4882a593Smuzhiyun if ((!names.geometry) && (fwant & XkbGBN_GeometryMask)) {
5939*4882a593Smuzhiyun names.geometry = Xstrdup("%");
5940*4882a593Smuzhiyun geom_changed = FALSE;
5941*4882a593Smuzhiyun }
5942*4882a593Smuzhiyun
5943*4882a593Smuzhiyun memset(mapFile, 0, PATH_MAX);
5944*4882a593Smuzhiyun rep.type = X_Reply;
5945*4882a593Smuzhiyun rep.deviceID = dev->id;
5946*4882a593Smuzhiyun rep.sequenceNumber = client->sequence;
5947*4882a593Smuzhiyun rep.length = 0;
5948*4882a593Smuzhiyun rep.minKeyCode = xkb->min_key_code;
5949*4882a593Smuzhiyun rep.maxKeyCode = xkb->max_key_code;
5950*4882a593Smuzhiyun rep.loaded = FALSE;
5951*4882a593Smuzhiyun fwant =
5952*4882a593Smuzhiyun XkbConvertGetByNameComponents(TRUE, stuff->want) | XkmVirtualModsMask;
5953*4882a593Smuzhiyun fneed = XkbConvertGetByNameComponents(TRUE, stuff->need);
5954*4882a593Smuzhiyun rep.reported = XkbConvertGetByNameComponents(FALSE, fwant | fneed);
5955*4882a593Smuzhiyun if (stuff->load) {
5956*4882a593Smuzhiyun fneed |= XkmKeymapRequired;
5957*4882a593Smuzhiyun fwant |= XkmKeymapLegal;
5958*4882a593Smuzhiyun }
5959*4882a593Smuzhiyun if ((fwant | fneed) & XkmSymbolsMask) {
5960*4882a593Smuzhiyun fneed |= XkmKeyNamesIndex | XkmTypesIndex;
5961*4882a593Smuzhiyun fwant |= XkmIndicatorsIndex;
5962*4882a593Smuzhiyun }
5963*4882a593Smuzhiyun
5964*4882a593Smuzhiyun /* We pass dev in here so we can get the old names out if needed. */
5965*4882a593Smuzhiyun rep.found = XkbDDXLoadKeymapByNames(dev, &names, fwant, fneed, &new,
5966*4882a593Smuzhiyun mapFile, PATH_MAX);
5967*4882a593Smuzhiyun rep.newKeyboard = FALSE;
5968*4882a593Smuzhiyun rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
5969*4882a593Smuzhiyun
5970*4882a593Smuzhiyun stuff->want |= stuff->need;
5971*4882a593Smuzhiyun if (new == NULL)
5972*4882a593Smuzhiyun rep.reported = 0;
5973*4882a593Smuzhiyun else {
5974*4882a593Smuzhiyun if (stuff->load)
5975*4882a593Smuzhiyun rep.loaded = TRUE;
5976*4882a593Smuzhiyun if (stuff->load ||
5977*4882a593Smuzhiyun ((rep.reported & XkbGBN_SymbolsMask) && (new->compat))) {
5978*4882a593Smuzhiyun XkbChangesRec changes;
5979*4882a593Smuzhiyun
5980*4882a593Smuzhiyun memset(&changes, 0, sizeof(changes));
5981*4882a593Smuzhiyun XkbUpdateDescActions(new,
5982*4882a593Smuzhiyun new->min_key_code, XkbNumKeys(new), &changes);
5983*4882a593Smuzhiyun }
5984*4882a593Smuzhiyun
5985*4882a593Smuzhiyun if (new->map == NULL)
5986*4882a593Smuzhiyun rep.reported &= ~(XkbGBN_SymbolsMask | XkbGBN_TypesMask);
5987*4882a593Smuzhiyun else if (rep.reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) {
5988*4882a593Smuzhiyun mrep.type = X_Reply;
5989*4882a593Smuzhiyun mrep.deviceID = dev->id;
5990*4882a593Smuzhiyun mrep.sequenceNumber = client->sequence;
5991*4882a593Smuzhiyun mrep.length =
5992*4882a593Smuzhiyun ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2);
5993*4882a593Smuzhiyun mrep.minKeyCode = new->min_key_code;
5994*4882a593Smuzhiyun mrep.maxKeyCode = new->max_key_code;
5995*4882a593Smuzhiyun mrep.present = 0;
5996*4882a593Smuzhiyun mrep.totalSyms = mrep.totalActs =
5997*4882a593Smuzhiyun mrep.totalKeyBehaviors = mrep.totalKeyExplicit =
5998*4882a593Smuzhiyun mrep.totalModMapKeys = mrep.totalVModMapKeys = 0;
5999*4882a593Smuzhiyun if (rep.reported & (XkbGBN_TypesMask | XkbGBN_ClientSymbolsMask)) {
6000*4882a593Smuzhiyun mrep.present |= XkbKeyTypesMask;
6001*4882a593Smuzhiyun mrep.firstType = 0;
6002*4882a593Smuzhiyun mrep.nTypes = mrep.totalTypes = new->map->num_types;
6003*4882a593Smuzhiyun }
6004*4882a593Smuzhiyun else {
6005*4882a593Smuzhiyun mrep.firstType = mrep.nTypes = 0;
6006*4882a593Smuzhiyun mrep.totalTypes = 0;
6007*4882a593Smuzhiyun }
6008*4882a593Smuzhiyun if (rep.reported & XkbGBN_ClientSymbolsMask) {
6009*4882a593Smuzhiyun mrep.present |= (XkbKeySymsMask | XkbModifierMapMask);
6010*4882a593Smuzhiyun mrep.firstKeySym = mrep.firstModMapKey = new->min_key_code;
6011*4882a593Smuzhiyun mrep.nKeySyms = mrep.nModMapKeys = XkbNumKeys(new);
6012*4882a593Smuzhiyun }
6013*4882a593Smuzhiyun else {
6014*4882a593Smuzhiyun mrep.firstKeySym = mrep.firstModMapKey = 0;
6015*4882a593Smuzhiyun mrep.nKeySyms = mrep.nModMapKeys = 0;
6016*4882a593Smuzhiyun }
6017*4882a593Smuzhiyun if (rep.reported & XkbGBN_ServerSymbolsMask) {
6018*4882a593Smuzhiyun mrep.present |= XkbAllServerInfoMask;
6019*4882a593Smuzhiyun mrep.virtualMods = ~0;
6020*4882a593Smuzhiyun mrep.firstKeyAct = mrep.firstKeyBehavior =
6021*4882a593Smuzhiyun mrep.firstKeyExplicit = new->min_key_code;
6022*4882a593Smuzhiyun mrep.nKeyActs = mrep.nKeyBehaviors =
6023*4882a593Smuzhiyun mrep.nKeyExplicit = XkbNumKeys(new);
6024*4882a593Smuzhiyun mrep.firstVModMapKey = new->min_key_code;
6025*4882a593Smuzhiyun mrep.nVModMapKeys = XkbNumKeys(new);
6026*4882a593Smuzhiyun }
6027*4882a593Smuzhiyun else {
6028*4882a593Smuzhiyun mrep.virtualMods = 0;
6029*4882a593Smuzhiyun mrep.firstKeyAct = mrep.firstKeyBehavior =
6030*4882a593Smuzhiyun mrep.firstKeyExplicit = 0;
6031*4882a593Smuzhiyun mrep.nKeyActs = mrep.nKeyBehaviors = mrep.nKeyExplicit = 0;
6032*4882a593Smuzhiyun }
6033*4882a593Smuzhiyun XkbComputeGetMapReplySize(new, &mrep);
6034*4882a593Smuzhiyun rep.length += SIZEOF(xGenericReply) / 4 + mrep.length;
6035*4882a593Smuzhiyun }
6036*4882a593Smuzhiyun if (new->compat == NULL)
6037*4882a593Smuzhiyun rep.reported &= ~XkbGBN_CompatMapMask;
6038*4882a593Smuzhiyun else if (rep.reported & XkbGBN_CompatMapMask) {
6039*4882a593Smuzhiyun crep.type = X_Reply;
6040*4882a593Smuzhiyun crep.deviceID = dev->id;
6041*4882a593Smuzhiyun crep.sequenceNumber = client->sequence;
6042*4882a593Smuzhiyun crep.length = 0;
6043*4882a593Smuzhiyun crep.groups = XkbAllGroupsMask;
6044*4882a593Smuzhiyun crep.firstSI = 0;
6045*4882a593Smuzhiyun crep.nSI = crep.nTotalSI = new->compat->num_si;
6046*4882a593Smuzhiyun XkbComputeGetCompatMapReplySize(new->compat, &crep);
6047*4882a593Smuzhiyun rep.length += SIZEOF(xGenericReply) / 4 + crep.length;
6048*4882a593Smuzhiyun }
6049*4882a593Smuzhiyun if (new->indicators == NULL)
6050*4882a593Smuzhiyun rep.reported &= ~XkbGBN_IndicatorMapMask;
6051*4882a593Smuzhiyun else if (rep.reported & XkbGBN_IndicatorMapMask) {
6052*4882a593Smuzhiyun irep.type = X_Reply;
6053*4882a593Smuzhiyun irep.deviceID = dev->id;
6054*4882a593Smuzhiyun irep.sequenceNumber = client->sequence;
6055*4882a593Smuzhiyun irep.length = 0;
6056*4882a593Smuzhiyun irep.which = XkbAllIndicatorsMask;
6057*4882a593Smuzhiyun XkbComputeGetIndicatorMapReplySize(new->indicators, &irep);
6058*4882a593Smuzhiyun rep.length += SIZEOF(xGenericReply) / 4 + irep.length;
6059*4882a593Smuzhiyun }
6060*4882a593Smuzhiyun if (new->names == NULL)
6061*4882a593Smuzhiyun rep.reported &= ~(XkbGBN_OtherNamesMask | XkbGBN_KeyNamesMask);
6062*4882a593Smuzhiyun else if (rep.reported & (XkbGBN_OtherNamesMask | XkbGBN_KeyNamesMask)) {
6063*4882a593Smuzhiyun nrep.type = X_Reply;
6064*4882a593Smuzhiyun nrep.deviceID = dev->id;
6065*4882a593Smuzhiyun nrep.sequenceNumber = client->sequence;
6066*4882a593Smuzhiyun nrep.length = 0;
6067*4882a593Smuzhiyun nrep.minKeyCode = new->min_key_code;
6068*4882a593Smuzhiyun nrep.maxKeyCode = new->max_key_code;
6069*4882a593Smuzhiyun if (rep.reported & XkbGBN_OtherNamesMask) {
6070*4882a593Smuzhiyun nrep.which = XkbAllNamesMask;
6071*4882a593Smuzhiyun if (new->map != NULL)
6072*4882a593Smuzhiyun nrep.nTypes = new->map->num_types;
6073*4882a593Smuzhiyun else
6074*4882a593Smuzhiyun nrep.nTypes = 0;
6075*4882a593Smuzhiyun nrep.nKTLevels = 0;
6076*4882a593Smuzhiyun nrep.groupNames = XkbAllGroupsMask;
6077*4882a593Smuzhiyun nrep.virtualMods = XkbAllVirtualModsMask;
6078*4882a593Smuzhiyun nrep.indicators = XkbAllIndicatorsMask;
6079*4882a593Smuzhiyun nrep.nRadioGroups = new->names->num_rg;
6080*4882a593Smuzhiyun }
6081*4882a593Smuzhiyun else {
6082*4882a593Smuzhiyun nrep.which = 0;
6083*4882a593Smuzhiyun nrep.nTypes = 0;
6084*4882a593Smuzhiyun nrep.nKTLevels = 0;
6085*4882a593Smuzhiyun nrep.groupNames = 0;
6086*4882a593Smuzhiyun nrep.virtualMods = 0;
6087*4882a593Smuzhiyun nrep.indicators = 0;
6088*4882a593Smuzhiyun nrep.nRadioGroups = 0;
6089*4882a593Smuzhiyun }
6090*4882a593Smuzhiyun if (rep.reported & XkbGBN_KeyNamesMask) {
6091*4882a593Smuzhiyun nrep.which |= XkbKeyNamesMask;
6092*4882a593Smuzhiyun nrep.firstKey = new->min_key_code;
6093*4882a593Smuzhiyun nrep.nKeys = XkbNumKeys(new);
6094*4882a593Smuzhiyun nrep.nKeyAliases = new->names->num_key_aliases;
6095*4882a593Smuzhiyun if (nrep.nKeyAliases)
6096*4882a593Smuzhiyun nrep.which |= XkbKeyAliasesMask;
6097*4882a593Smuzhiyun }
6098*4882a593Smuzhiyun else {
6099*4882a593Smuzhiyun nrep.which &= ~(XkbKeyNamesMask | XkbKeyAliasesMask);
6100*4882a593Smuzhiyun nrep.firstKey = nrep.nKeys = 0;
6101*4882a593Smuzhiyun nrep.nKeyAliases = 0;
6102*4882a593Smuzhiyun }
6103*4882a593Smuzhiyun XkbComputeGetNamesReplySize(new, &nrep);
6104*4882a593Smuzhiyun rep.length += SIZEOF(xGenericReply) / 4 + nrep.length;
6105*4882a593Smuzhiyun }
6106*4882a593Smuzhiyun if (new->geom == NULL)
6107*4882a593Smuzhiyun rep.reported &= ~XkbGBN_GeometryMask;
6108*4882a593Smuzhiyun else if (rep.reported & XkbGBN_GeometryMask) {
6109*4882a593Smuzhiyun grep.type = X_Reply;
6110*4882a593Smuzhiyun grep.deviceID = dev->id;
6111*4882a593Smuzhiyun grep.sequenceNumber = client->sequence;
6112*4882a593Smuzhiyun grep.length = 0;
6113*4882a593Smuzhiyun grep.found = TRUE;
6114*4882a593Smuzhiyun grep.pad = 0;
6115*4882a593Smuzhiyun grep.widthMM = grep.heightMM = 0;
6116*4882a593Smuzhiyun grep.nProperties = grep.nColors = grep.nShapes = 0;
6117*4882a593Smuzhiyun grep.nSections = grep.nDoodads = 0;
6118*4882a593Smuzhiyun grep.baseColorNdx = grep.labelColorNdx = 0;
6119*4882a593Smuzhiyun XkbComputeGetGeometryReplySize(new->geom, &grep, None);
6120*4882a593Smuzhiyun rep.length += SIZEOF(xGenericReply) / 4 + grep.length;
6121*4882a593Smuzhiyun }
6122*4882a593Smuzhiyun }
6123*4882a593Smuzhiyun
6124*4882a593Smuzhiyun reported = rep.reported;
6125*4882a593Smuzhiyun if (client->swapped) {
6126*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
6127*4882a593Smuzhiyun swapl(&rep.length);
6128*4882a593Smuzhiyun swaps(&rep.found);
6129*4882a593Smuzhiyun swaps(&rep.reported);
6130*4882a593Smuzhiyun }
6131*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbGetKbdByNameReply), &rep);
6132*4882a593Smuzhiyun if (reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask))
6133*4882a593Smuzhiyun XkbSendMap(client, new, &mrep);
6134*4882a593Smuzhiyun if (reported & XkbGBN_CompatMapMask)
6135*4882a593Smuzhiyun XkbSendCompatMap(client, new->compat, &crep);
6136*4882a593Smuzhiyun if (reported & XkbGBN_IndicatorMapMask)
6137*4882a593Smuzhiyun XkbSendIndicatorMap(client, new->indicators, &irep);
6138*4882a593Smuzhiyun if (reported & (XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask))
6139*4882a593Smuzhiyun XkbSendNames(client, new, &nrep);
6140*4882a593Smuzhiyun if (reported & XkbGBN_GeometryMask)
6141*4882a593Smuzhiyun XkbSendGeometry(client, new->geom, &grep, FALSE);
6142*4882a593Smuzhiyun if (rep.loaded) {
6143*4882a593Smuzhiyun XkbDescPtr old_xkb;
6144*4882a593Smuzhiyun xkbNewKeyboardNotify nkn;
6145*4882a593Smuzhiyun
6146*4882a593Smuzhiyun old_xkb = xkb;
6147*4882a593Smuzhiyun xkb = new;
6148*4882a593Smuzhiyun dev->key->xkbInfo->desc = xkb;
6149*4882a593Smuzhiyun new = old_xkb; /* so it'll get freed automatically */
6150*4882a593Smuzhiyun
6151*4882a593Smuzhiyun XkbCopyControls(xkb, old_xkb);
6152*4882a593Smuzhiyun
6153*4882a593Smuzhiyun nkn.deviceID = nkn.oldDeviceID = dev->id;
6154*4882a593Smuzhiyun nkn.minKeyCode = new->min_key_code;
6155*4882a593Smuzhiyun nkn.maxKeyCode = new->max_key_code;
6156*4882a593Smuzhiyun nkn.oldMinKeyCode = xkb->min_key_code;
6157*4882a593Smuzhiyun nkn.oldMaxKeyCode = xkb->max_key_code;
6158*4882a593Smuzhiyun nkn.requestMajor = XkbReqCode;
6159*4882a593Smuzhiyun nkn.requestMinor = X_kbGetKbdByName;
6160*4882a593Smuzhiyun nkn.changed = XkbNKN_KeycodesMask;
6161*4882a593Smuzhiyun if (geom_changed)
6162*4882a593Smuzhiyun nkn.changed |= XkbNKN_GeometryMask;
6163*4882a593Smuzhiyun XkbSendNewKeyboardNotify(dev, &nkn);
6164*4882a593Smuzhiyun
6165*4882a593Smuzhiyun /* Update the map and LED info on the device itself, as well as
6166*4882a593Smuzhiyun * any slaves if it's an MD, or its MD if it's an SD and was the
6167*4882a593Smuzhiyun * last device used on that MD. */
6168*4882a593Smuzhiyun for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
6169*4882a593Smuzhiyun if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev &&
6170*4882a593Smuzhiyun (tmpd != master || dev != master->lastSlave))
6171*4882a593Smuzhiyun continue;
6172*4882a593Smuzhiyun
6173*4882a593Smuzhiyun if (tmpd != dev)
6174*4882a593Smuzhiyun XkbDeviceApplyKeymap(tmpd, xkb);
6175*4882a593Smuzhiyun
6176*4882a593Smuzhiyun if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
6177*4882a593Smuzhiyun old_sli = tmpd->kbdfeed->xkb_sli;
6178*4882a593Smuzhiyun tmpd->kbdfeed->xkb_sli = NULL;
6179*4882a593Smuzhiyun sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0);
6180*4882a593Smuzhiyun if (sli) {
6181*4882a593Smuzhiyun sli->explicitState = old_sli->explicitState;
6182*4882a593Smuzhiyun sli->effectiveState = old_sli->effectiveState;
6183*4882a593Smuzhiyun }
6184*4882a593Smuzhiyun tmpd->kbdfeed->xkb_sli = sli;
6185*4882a593Smuzhiyun XkbFreeSrvLedInfo(old_sli);
6186*4882a593Smuzhiyun }
6187*4882a593Smuzhiyun }
6188*4882a593Smuzhiyun }
6189*4882a593Smuzhiyun if ((new != NULL) && (new != xkb)) {
6190*4882a593Smuzhiyun XkbFreeKeyboard(new, XkbAllComponentsMask, TRUE);
6191*4882a593Smuzhiyun new = NULL;
6192*4882a593Smuzhiyun }
6193*4882a593Smuzhiyun XkbFreeComponentNames(&names, FALSE);
6194*4882a593Smuzhiyun XkbSetCauseXkbReq(&cause, X_kbGetKbdByName, client);
6195*4882a593Smuzhiyun XkbUpdateAllDeviceIndicators(NULL, &cause);
6196*4882a593Smuzhiyun
6197*4882a593Smuzhiyun return Success;
6198*4882a593Smuzhiyun }
6199*4882a593Smuzhiyun
6200*4882a593Smuzhiyun /***====================================================================***/
6201*4882a593Smuzhiyun
6202*4882a593Smuzhiyun static int
ComputeDeviceLedInfoSize(DeviceIntPtr dev,unsigned int what,XkbSrvLedInfoPtr sli)6203*4882a593Smuzhiyun ComputeDeviceLedInfoSize(DeviceIntPtr dev,
6204*4882a593Smuzhiyun unsigned int what, XkbSrvLedInfoPtr sli)
6205*4882a593Smuzhiyun {
6206*4882a593Smuzhiyun int nNames, nMaps;
6207*4882a593Smuzhiyun register unsigned n, bit;
6208*4882a593Smuzhiyun
6209*4882a593Smuzhiyun if (sli == NULL)
6210*4882a593Smuzhiyun return 0;
6211*4882a593Smuzhiyun nNames = nMaps = 0;
6212*4882a593Smuzhiyun if ((what & XkbXI_IndicatorNamesMask) == 0)
6213*4882a593Smuzhiyun sli->namesPresent = 0;
6214*4882a593Smuzhiyun if ((what & XkbXI_IndicatorMapsMask) == 0)
6215*4882a593Smuzhiyun sli->mapsPresent = 0;
6216*4882a593Smuzhiyun
6217*4882a593Smuzhiyun for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) {
6218*4882a593Smuzhiyun if (sli->names && sli->names[n] != None) {
6219*4882a593Smuzhiyun sli->namesPresent |= bit;
6220*4882a593Smuzhiyun nNames++;
6221*4882a593Smuzhiyun }
6222*4882a593Smuzhiyun if (sli->maps && XkbIM_InUse(&sli->maps[n])) {
6223*4882a593Smuzhiyun sli->mapsPresent |= bit;
6224*4882a593Smuzhiyun nMaps++;
6225*4882a593Smuzhiyun }
6226*4882a593Smuzhiyun }
6227*4882a593Smuzhiyun return (nNames * 4) + (nMaps * SIZEOF(xkbIndicatorMapWireDesc));
6228*4882a593Smuzhiyun }
6229*4882a593Smuzhiyun
6230*4882a593Smuzhiyun static int
CheckDeviceLedFBs(DeviceIntPtr dev,int class,int id,xkbGetDeviceInfoReply * rep,ClientPtr client)6231*4882a593Smuzhiyun CheckDeviceLedFBs(DeviceIntPtr dev,
6232*4882a593Smuzhiyun int class,
6233*4882a593Smuzhiyun int id, xkbGetDeviceInfoReply * rep, ClientPtr client)
6234*4882a593Smuzhiyun {
6235*4882a593Smuzhiyun int nFBs = 0;
6236*4882a593Smuzhiyun int length = 0;
6237*4882a593Smuzhiyun Bool classOk;
6238*4882a593Smuzhiyun
6239*4882a593Smuzhiyun if (class == XkbDfltXIClass) {
6240*4882a593Smuzhiyun if (dev->kbdfeed)
6241*4882a593Smuzhiyun class = KbdFeedbackClass;
6242*4882a593Smuzhiyun else if (dev->leds)
6243*4882a593Smuzhiyun class = LedFeedbackClass;
6244*4882a593Smuzhiyun else {
6245*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(XkbErr_BadClass, class);
6246*4882a593Smuzhiyun return XkbKeyboardErrorCode;
6247*4882a593Smuzhiyun }
6248*4882a593Smuzhiyun }
6249*4882a593Smuzhiyun classOk = FALSE;
6250*4882a593Smuzhiyun if ((dev->kbdfeed) &&
6251*4882a593Smuzhiyun ((class == KbdFeedbackClass) || (class == XkbAllXIClasses))) {
6252*4882a593Smuzhiyun KbdFeedbackPtr kf;
6253*4882a593Smuzhiyun
6254*4882a593Smuzhiyun classOk = TRUE;
6255*4882a593Smuzhiyun for (kf = dev->kbdfeed; (kf); kf = kf->next) {
6256*4882a593Smuzhiyun if ((id != XkbAllXIIds) && (id != XkbDfltXIId) &&
6257*4882a593Smuzhiyun (id != kf->ctrl.id))
6258*4882a593Smuzhiyun continue;
6259*4882a593Smuzhiyun nFBs++;
6260*4882a593Smuzhiyun length += SIZEOF(xkbDeviceLedsWireDesc);
6261*4882a593Smuzhiyun if (!kf->xkb_sli)
6262*4882a593Smuzhiyun kf->xkb_sli = XkbAllocSrvLedInfo(dev, kf, NULL, 0);
6263*4882a593Smuzhiyun length += ComputeDeviceLedInfoSize(dev, rep->present, kf->xkb_sli);
6264*4882a593Smuzhiyun if (id != XkbAllXIIds)
6265*4882a593Smuzhiyun break;
6266*4882a593Smuzhiyun }
6267*4882a593Smuzhiyun }
6268*4882a593Smuzhiyun if ((dev->leds) &&
6269*4882a593Smuzhiyun ((class == LedFeedbackClass) || (class == XkbAllXIClasses))) {
6270*4882a593Smuzhiyun LedFeedbackPtr lf;
6271*4882a593Smuzhiyun
6272*4882a593Smuzhiyun classOk = TRUE;
6273*4882a593Smuzhiyun for (lf = dev->leds; (lf); lf = lf->next) {
6274*4882a593Smuzhiyun if ((id != XkbAllXIIds) && (id != XkbDfltXIId) &&
6275*4882a593Smuzhiyun (id != lf->ctrl.id))
6276*4882a593Smuzhiyun continue;
6277*4882a593Smuzhiyun nFBs++;
6278*4882a593Smuzhiyun length += SIZEOF(xkbDeviceLedsWireDesc);
6279*4882a593Smuzhiyun if (!lf->xkb_sli)
6280*4882a593Smuzhiyun lf->xkb_sli = XkbAllocSrvLedInfo(dev, NULL, lf, 0);
6281*4882a593Smuzhiyun length += ComputeDeviceLedInfoSize(dev, rep->present, lf->xkb_sli);
6282*4882a593Smuzhiyun if (id != XkbAllXIIds)
6283*4882a593Smuzhiyun break;
6284*4882a593Smuzhiyun }
6285*4882a593Smuzhiyun }
6286*4882a593Smuzhiyun if (nFBs > 0) {
6287*4882a593Smuzhiyun rep->nDeviceLedFBs = nFBs;
6288*4882a593Smuzhiyun rep->length += (length / 4);
6289*4882a593Smuzhiyun return Success;
6290*4882a593Smuzhiyun }
6291*4882a593Smuzhiyun if (classOk)
6292*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(XkbErr_BadId, id);
6293*4882a593Smuzhiyun else
6294*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(XkbErr_BadClass, class);
6295*4882a593Smuzhiyun return XkbKeyboardErrorCode;
6296*4882a593Smuzhiyun }
6297*4882a593Smuzhiyun
6298*4882a593Smuzhiyun static int
SendDeviceLedInfo(XkbSrvLedInfoPtr sli,ClientPtr client)6299*4882a593Smuzhiyun SendDeviceLedInfo(XkbSrvLedInfoPtr sli, ClientPtr client)
6300*4882a593Smuzhiyun {
6301*4882a593Smuzhiyun xkbDeviceLedsWireDesc wire;
6302*4882a593Smuzhiyun int length;
6303*4882a593Smuzhiyun
6304*4882a593Smuzhiyun length = 0;
6305*4882a593Smuzhiyun wire.ledClass = sli->class;
6306*4882a593Smuzhiyun wire.ledID = sli->id;
6307*4882a593Smuzhiyun wire.namesPresent = sli->namesPresent;
6308*4882a593Smuzhiyun wire.mapsPresent = sli->mapsPresent;
6309*4882a593Smuzhiyun wire.physIndicators = sli->physIndicators;
6310*4882a593Smuzhiyun wire.state = sli->effectiveState;
6311*4882a593Smuzhiyun if (client->swapped) {
6312*4882a593Smuzhiyun swaps(&wire.ledClass);
6313*4882a593Smuzhiyun swaps(&wire.ledID);
6314*4882a593Smuzhiyun swapl(&wire.namesPresent);
6315*4882a593Smuzhiyun swapl(&wire.mapsPresent);
6316*4882a593Smuzhiyun swapl(&wire.physIndicators);
6317*4882a593Smuzhiyun swapl(&wire.state);
6318*4882a593Smuzhiyun }
6319*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbDeviceLedsWireDesc), &wire);
6320*4882a593Smuzhiyun length += SIZEOF(xkbDeviceLedsWireDesc);
6321*4882a593Smuzhiyun if (sli->namesPresent | sli->mapsPresent) {
6322*4882a593Smuzhiyun register unsigned i, bit;
6323*4882a593Smuzhiyun
6324*4882a593Smuzhiyun if (sli->namesPresent) {
6325*4882a593Smuzhiyun CARD32 awire;
6326*4882a593Smuzhiyun
6327*4882a593Smuzhiyun for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
6328*4882a593Smuzhiyun if (sli->namesPresent & bit) {
6329*4882a593Smuzhiyun awire = (CARD32) sli->names[i];
6330*4882a593Smuzhiyun if (client->swapped) {
6331*4882a593Smuzhiyun swapl(&awire);
6332*4882a593Smuzhiyun }
6333*4882a593Smuzhiyun WriteToClient(client, 4, &awire);
6334*4882a593Smuzhiyun length += 4;
6335*4882a593Smuzhiyun }
6336*4882a593Smuzhiyun }
6337*4882a593Smuzhiyun }
6338*4882a593Smuzhiyun if (sli->mapsPresent) {
6339*4882a593Smuzhiyun for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
6340*4882a593Smuzhiyun xkbIndicatorMapWireDesc iwire;
6341*4882a593Smuzhiyun
6342*4882a593Smuzhiyun if (sli->mapsPresent & bit) {
6343*4882a593Smuzhiyun iwire.flags = sli->maps[i].flags;
6344*4882a593Smuzhiyun iwire.whichGroups = sli->maps[i].which_groups;
6345*4882a593Smuzhiyun iwire.groups = sli->maps[i].groups;
6346*4882a593Smuzhiyun iwire.whichMods = sli->maps[i].which_mods;
6347*4882a593Smuzhiyun iwire.mods = sli->maps[i].mods.mask;
6348*4882a593Smuzhiyun iwire.realMods = sli->maps[i].mods.real_mods;
6349*4882a593Smuzhiyun iwire.virtualMods = sli->maps[i].mods.vmods;
6350*4882a593Smuzhiyun iwire.ctrls = sli->maps[i].ctrls;
6351*4882a593Smuzhiyun if (client->swapped) {
6352*4882a593Smuzhiyun swaps(&iwire.virtualMods);
6353*4882a593Smuzhiyun swapl(&iwire.ctrls);
6354*4882a593Smuzhiyun }
6355*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbIndicatorMapWireDesc),
6356*4882a593Smuzhiyun &iwire);
6357*4882a593Smuzhiyun length += SIZEOF(xkbIndicatorMapWireDesc);
6358*4882a593Smuzhiyun }
6359*4882a593Smuzhiyun }
6360*4882a593Smuzhiyun }
6361*4882a593Smuzhiyun }
6362*4882a593Smuzhiyun return length;
6363*4882a593Smuzhiyun }
6364*4882a593Smuzhiyun
6365*4882a593Smuzhiyun static int
SendDeviceLedFBs(DeviceIntPtr dev,int class,int id,unsigned wantLength,ClientPtr client)6366*4882a593Smuzhiyun SendDeviceLedFBs(DeviceIntPtr dev,
6367*4882a593Smuzhiyun int class, int id, unsigned wantLength, ClientPtr client)
6368*4882a593Smuzhiyun {
6369*4882a593Smuzhiyun int length = 0;
6370*4882a593Smuzhiyun
6371*4882a593Smuzhiyun if (class == XkbDfltXIClass) {
6372*4882a593Smuzhiyun if (dev->kbdfeed)
6373*4882a593Smuzhiyun class = KbdFeedbackClass;
6374*4882a593Smuzhiyun else if (dev->leds)
6375*4882a593Smuzhiyun class = LedFeedbackClass;
6376*4882a593Smuzhiyun }
6377*4882a593Smuzhiyun if ((dev->kbdfeed) &&
6378*4882a593Smuzhiyun ((class == KbdFeedbackClass) || (class == XkbAllXIClasses))) {
6379*4882a593Smuzhiyun KbdFeedbackPtr kf;
6380*4882a593Smuzhiyun
6381*4882a593Smuzhiyun for (kf = dev->kbdfeed; (kf); kf = kf->next) {
6382*4882a593Smuzhiyun if ((id == XkbAllXIIds) || (id == XkbDfltXIId) ||
6383*4882a593Smuzhiyun (id == kf->ctrl.id)) {
6384*4882a593Smuzhiyun length += SendDeviceLedInfo(kf->xkb_sli, client);
6385*4882a593Smuzhiyun if (id != XkbAllXIIds)
6386*4882a593Smuzhiyun break;
6387*4882a593Smuzhiyun }
6388*4882a593Smuzhiyun }
6389*4882a593Smuzhiyun }
6390*4882a593Smuzhiyun if ((dev->leds) &&
6391*4882a593Smuzhiyun ((class == LedFeedbackClass) || (class == XkbAllXIClasses))) {
6392*4882a593Smuzhiyun LedFeedbackPtr lf;
6393*4882a593Smuzhiyun
6394*4882a593Smuzhiyun for (lf = dev->leds; (lf); lf = lf->next) {
6395*4882a593Smuzhiyun if ((id == XkbAllXIIds) || (id == XkbDfltXIId) ||
6396*4882a593Smuzhiyun (id == lf->ctrl.id)) {
6397*4882a593Smuzhiyun length += SendDeviceLedInfo(lf->xkb_sli, client);
6398*4882a593Smuzhiyun if (id != XkbAllXIIds)
6399*4882a593Smuzhiyun break;
6400*4882a593Smuzhiyun }
6401*4882a593Smuzhiyun }
6402*4882a593Smuzhiyun }
6403*4882a593Smuzhiyun if (length == wantLength)
6404*4882a593Smuzhiyun return Success;
6405*4882a593Smuzhiyun else
6406*4882a593Smuzhiyun return BadLength;
6407*4882a593Smuzhiyun }
6408*4882a593Smuzhiyun
6409*4882a593Smuzhiyun int
ProcXkbGetDeviceInfo(ClientPtr client)6410*4882a593Smuzhiyun ProcXkbGetDeviceInfo(ClientPtr client)
6411*4882a593Smuzhiyun {
6412*4882a593Smuzhiyun DeviceIntPtr dev;
6413*4882a593Smuzhiyun xkbGetDeviceInfoReply rep;
6414*4882a593Smuzhiyun int status, nDeviceLedFBs;
6415*4882a593Smuzhiyun unsigned length, nameLen;
6416*4882a593Smuzhiyun CARD16 ledClass, ledID;
6417*4882a593Smuzhiyun unsigned wanted;
6418*4882a593Smuzhiyun char *str;
6419*4882a593Smuzhiyun
6420*4882a593Smuzhiyun REQUEST(xkbGetDeviceInfoReq);
6421*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq);
6422*4882a593Smuzhiyun
6423*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
6424*4882a593Smuzhiyun return BadAccess;
6425*4882a593Smuzhiyun
6426*4882a593Smuzhiyun wanted = stuff->wanted;
6427*4882a593Smuzhiyun
6428*4882a593Smuzhiyun CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
6429*4882a593Smuzhiyun CHK_MASK_LEGAL(0x01, wanted, XkbXI_AllDeviceFeaturesMask);
6430*4882a593Smuzhiyun
6431*4882a593Smuzhiyun if ((!dev->button) || ((stuff->nBtns < 1) && (!stuff->allBtns)))
6432*4882a593Smuzhiyun wanted &= ~XkbXI_ButtonActionsMask;
6433*4882a593Smuzhiyun if ((!dev->kbdfeed) && (!dev->leds))
6434*4882a593Smuzhiyun wanted &= ~XkbXI_IndicatorsMask;
6435*4882a593Smuzhiyun
6436*4882a593Smuzhiyun nameLen = XkbSizeCountedString(dev->name);
6437*4882a593Smuzhiyun rep = (xkbGetDeviceInfoReply) {
6438*4882a593Smuzhiyun .type = X_Reply,
6439*4882a593Smuzhiyun .deviceID = dev->id,
6440*4882a593Smuzhiyun .sequenceNumber = client->sequence,
6441*4882a593Smuzhiyun .length = nameLen / 4,
6442*4882a593Smuzhiyun .present = wanted,
6443*4882a593Smuzhiyun .supported = XkbXI_AllDeviceFeaturesMask,
6444*4882a593Smuzhiyun .unsupported = 0,
6445*4882a593Smuzhiyun .nDeviceLedFBs = 0,
6446*4882a593Smuzhiyun .firstBtnWanted = 0,
6447*4882a593Smuzhiyun .nBtnsWanted = 0,
6448*4882a593Smuzhiyun .firstBtnRtrn = 0,
6449*4882a593Smuzhiyun .nBtnsRtrn = 0,
6450*4882a593Smuzhiyun .totalBtns = dev->button ? dev->button->numButtons : 0,
6451*4882a593Smuzhiyun .hasOwnState = (dev->key && dev->key->xkbInfo),
6452*4882a593Smuzhiyun .dfltKbdFB = dev->kbdfeed ? dev->kbdfeed->ctrl.id : XkbXINone,
6453*4882a593Smuzhiyun .dfltLedFB = dev->leds ? dev->leds->ctrl.id : XkbXINone,
6454*4882a593Smuzhiyun .devType = dev->xinput_type
6455*4882a593Smuzhiyun };
6456*4882a593Smuzhiyun
6457*4882a593Smuzhiyun ledClass = stuff->ledClass;
6458*4882a593Smuzhiyun ledID = stuff->ledID;
6459*4882a593Smuzhiyun
6460*4882a593Smuzhiyun if (wanted & XkbXI_ButtonActionsMask) {
6461*4882a593Smuzhiyun if (stuff->allBtns) {
6462*4882a593Smuzhiyun stuff->firstBtn = 0;
6463*4882a593Smuzhiyun stuff->nBtns = dev->button->numButtons;
6464*4882a593Smuzhiyun }
6465*4882a593Smuzhiyun
6466*4882a593Smuzhiyun if ((stuff->firstBtn + stuff->nBtns) > dev->button->numButtons) {
6467*4882a593Smuzhiyun client->errorValue = _XkbErrCode4(0x02, dev->button->numButtons,
6468*4882a593Smuzhiyun stuff->firstBtn, stuff->nBtns);
6469*4882a593Smuzhiyun return BadValue;
6470*4882a593Smuzhiyun }
6471*4882a593Smuzhiyun else {
6472*4882a593Smuzhiyun rep.firstBtnWanted = stuff->firstBtn;
6473*4882a593Smuzhiyun rep.nBtnsWanted = stuff->nBtns;
6474*4882a593Smuzhiyun if (dev->button->xkb_acts != NULL) {
6475*4882a593Smuzhiyun XkbAction *act;
6476*4882a593Smuzhiyun register int i;
6477*4882a593Smuzhiyun
6478*4882a593Smuzhiyun rep.firstBtnRtrn = stuff->firstBtn;
6479*4882a593Smuzhiyun rep.nBtnsRtrn = stuff->nBtns;
6480*4882a593Smuzhiyun act = &dev->button->xkb_acts[rep.firstBtnWanted];
6481*4882a593Smuzhiyun for (i = 0; i < rep.nBtnsRtrn; i++, act++) {
6482*4882a593Smuzhiyun if (act->type != XkbSA_NoAction)
6483*4882a593Smuzhiyun break;
6484*4882a593Smuzhiyun }
6485*4882a593Smuzhiyun rep.firstBtnRtrn += i;
6486*4882a593Smuzhiyun rep.nBtnsRtrn -= i;
6487*4882a593Smuzhiyun act =
6488*4882a593Smuzhiyun &dev->button->xkb_acts[rep.firstBtnRtrn + rep.nBtnsRtrn -
6489*4882a593Smuzhiyun 1];
6490*4882a593Smuzhiyun for (i = 0; i < rep.nBtnsRtrn; i++, act--) {
6491*4882a593Smuzhiyun if (act->type != XkbSA_NoAction)
6492*4882a593Smuzhiyun break;
6493*4882a593Smuzhiyun }
6494*4882a593Smuzhiyun rep.nBtnsRtrn -= i;
6495*4882a593Smuzhiyun }
6496*4882a593Smuzhiyun rep.length += (rep.nBtnsRtrn * SIZEOF(xkbActionWireDesc)) / 4;
6497*4882a593Smuzhiyun }
6498*4882a593Smuzhiyun }
6499*4882a593Smuzhiyun
6500*4882a593Smuzhiyun if (wanted & XkbXI_IndicatorsMask) {
6501*4882a593Smuzhiyun status = CheckDeviceLedFBs(dev, ledClass, ledID, &rep, client);
6502*4882a593Smuzhiyun if (status != Success)
6503*4882a593Smuzhiyun return status;
6504*4882a593Smuzhiyun }
6505*4882a593Smuzhiyun length = rep.length * 4;
6506*4882a593Smuzhiyun nDeviceLedFBs = rep.nDeviceLedFBs;
6507*4882a593Smuzhiyun if (client->swapped) {
6508*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
6509*4882a593Smuzhiyun swapl(&rep.length);
6510*4882a593Smuzhiyun swaps(&rep.present);
6511*4882a593Smuzhiyun swaps(&rep.supported);
6512*4882a593Smuzhiyun swaps(&rep.unsupported);
6513*4882a593Smuzhiyun swaps(&rep.nDeviceLedFBs);
6514*4882a593Smuzhiyun swaps(&rep.dfltKbdFB);
6515*4882a593Smuzhiyun swaps(&rep.dfltLedFB);
6516*4882a593Smuzhiyun swapl(&rep.devType);
6517*4882a593Smuzhiyun }
6518*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbGetDeviceInfoReply), &rep);
6519*4882a593Smuzhiyun
6520*4882a593Smuzhiyun str = malloc(nameLen);
6521*4882a593Smuzhiyun if (!str)
6522*4882a593Smuzhiyun return BadAlloc;
6523*4882a593Smuzhiyun XkbWriteCountedString(str, dev->name, client->swapped);
6524*4882a593Smuzhiyun WriteToClient(client, nameLen, str);
6525*4882a593Smuzhiyun free(str);
6526*4882a593Smuzhiyun length -= nameLen;
6527*4882a593Smuzhiyun
6528*4882a593Smuzhiyun if (rep.nBtnsRtrn > 0) {
6529*4882a593Smuzhiyun int sz;
6530*4882a593Smuzhiyun xkbActionWireDesc *awire;
6531*4882a593Smuzhiyun
6532*4882a593Smuzhiyun sz = rep.nBtnsRtrn * SIZEOF(xkbActionWireDesc);
6533*4882a593Smuzhiyun awire = (xkbActionWireDesc *) &dev->button->xkb_acts[rep.firstBtnRtrn];
6534*4882a593Smuzhiyun WriteToClient(client, sz, awire);
6535*4882a593Smuzhiyun length -= sz;
6536*4882a593Smuzhiyun }
6537*4882a593Smuzhiyun if (nDeviceLedFBs > 0) {
6538*4882a593Smuzhiyun status = SendDeviceLedFBs(dev, ledClass, ledID, length, client);
6539*4882a593Smuzhiyun if (status != Success)
6540*4882a593Smuzhiyun return status;
6541*4882a593Smuzhiyun }
6542*4882a593Smuzhiyun else if (length != 0) {
6543*4882a593Smuzhiyun ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n");
6544*4882a593Smuzhiyun ErrorF("[xkb] Wrote %d fewer bytes than expected\n",
6545*4882a593Smuzhiyun length);
6546*4882a593Smuzhiyun return BadLength;
6547*4882a593Smuzhiyun }
6548*4882a593Smuzhiyun return Success;
6549*4882a593Smuzhiyun }
6550*4882a593Smuzhiyun
6551*4882a593Smuzhiyun static char *
CheckSetDeviceIndicators(char * wire,DeviceIntPtr dev,int num,int * status_rtrn,ClientPtr client)6552*4882a593Smuzhiyun CheckSetDeviceIndicators(char *wire,
6553*4882a593Smuzhiyun DeviceIntPtr dev,
6554*4882a593Smuzhiyun int num, int *status_rtrn, ClientPtr client)
6555*4882a593Smuzhiyun {
6556*4882a593Smuzhiyun xkbDeviceLedsWireDesc *ledWire;
6557*4882a593Smuzhiyun int i;
6558*4882a593Smuzhiyun XkbSrvLedInfoPtr sli;
6559*4882a593Smuzhiyun
6560*4882a593Smuzhiyun ledWire = (xkbDeviceLedsWireDesc *) wire;
6561*4882a593Smuzhiyun for (i = 0; i < num; i++) {
6562*4882a593Smuzhiyun if (client->swapped) {
6563*4882a593Smuzhiyun swaps(&ledWire->ledClass);
6564*4882a593Smuzhiyun swaps(&ledWire->ledID);
6565*4882a593Smuzhiyun swapl(&ledWire->namesPresent);
6566*4882a593Smuzhiyun swapl(&ledWire->mapsPresent);
6567*4882a593Smuzhiyun swapl(&ledWire->physIndicators);
6568*4882a593Smuzhiyun }
6569*4882a593Smuzhiyun
6570*4882a593Smuzhiyun sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID,
6571*4882a593Smuzhiyun XkbXI_IndicatorsMask);
6572*4882a593Smuzhiyun if (sli != NULL) {
6573*4882a593Smuzhiyun register int n;
6574*4882a593Smuzhiyun register unsigned bit;
6575*4882a593Smuzhiyun int nMaps, nNames;
6576*4882a593Smuzhiyun CARD32 *atomWire;
6577*4882a593Smuzhiyun xkbIndicatorMapWireDesc *mapWire;
6578*4882a593Smuzhiyun
6579*4882a593Smuzhiyun nMaps = nNames = 0;
6580*4882a593Smuzhiyun for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) {
6581*4882a593Smuzhiyun if (ledWire->namesPresent & bit)
6582*4882a593Smuzhiyun nNames++;
6583*4882a593Smuzhiyun if (ledWire->mapsPresent & bit)
6584*4882a593Smuzhiyun nMaps++;
6585*4882a593Smuzhiyun }
6586*4882a593Smuzhiyun atomWire = (CARD32 *) &ledWire[1];
6587*4882a593Smuzhiyun if (nNames > 0) {
6588*4882a593Smuzhiyun for (n = 0; n < nNames; n++) {
6589*4882a593Smuzhiyun if (client->swapped) {
6590*4882a593Smuzhiyun swapl(atomWire);
6591*4882a593Smuzhiyun }
6592*4882a593Smuzhiyun CHK_ATOM_OR_NONE3(((Atom) (*atomWire)), client->errorValue,
6593*4882a593Smuzhiyun *status_rtrn, NULL);
6594*4882a593Smuzhiyun atomWire++;
6595*4882a593Smuzhiyun }
6596*4882a593Smuzhiyun }
6597*4882a593Smuzhiyun mapWire = (xkbIndicatorMapWireDesc *) atomWire;
6598*4882a593Smuzhiyun if (nMaps > 0) {
6599*4882a593Smuzhiyun for (n = 0; n < nMaps; n++) {
6600*4882a593Smuzhiyun if (client->swapped) {
6601*4882a593Smuzhiyun swaps(&mapWire->virtualMods);
6602*4882a593Smuzhiyun swapl(&mapWire->ctrls);
6603*4882a593Smuzhiyun }
6604*4882a593Smuzhiyun CHK_MASK_LEGAL3(0x21, mapWire->whichGroups,
6605*4882a593Smuzhiyun XkbIM_UseAnyGroup,
6606*4882a593Smuzhiyun client->errorValue, *status_rtrn, NULL);
6607*4882a593Smuzhiyun CHK_MASK_LEGAL3(0x22, mapWire->whichMods, XkbIM_UseAnyMods,
6608*4882a593Smuzhiyun client->errorValue, *status_rtrn, NULL);
6609*4882a593Smuzhiyun mapWire++;
6610*4882a593Smuzhiyun }
6611*4882a593Smuzhiyun }
6612*4882a593Smuzhiyun ledWire = (xkbDeviceLedsWireDesc *) mapWire;
6613*4882a593Smuzhiyun }
6614*4882a593Smuzhiyun else {
6615*4882a593Smuzhiyun /* SHOULD NEVER HAPPEN */
6616*4882a593Smuzhiyun return (char *) ledWire;
6617*4882a593Smuzhiyun }
6618*4882a593Smuzhiyun }
6619*4882a593Smuzhiyun return (char *) ledWire;
6620*4882a593Smuzhiyun }
6621*4882a593Smuzhiyun
6622*4882a593Smuzhiyun static char *
SetDeviceIndicators(char * wire,DeviceIntPtr dev,unsigned changed,int num,int * status_rtrn,ClientPtr client,xkbExtensionDeviceNotify * ev,xkbSetDeviceInfoReq * stuff)6623*4882a593Smuzhiyun SetDeviceIndicators(char *wire,
6624*4882a593Smuzhiyun DeviceIntPtr dev,
6625*4882a593Smuzhiyun unsigned changed,
6626*4882a593Smuzhiyun int num,
6627*4882a593Smuzhiyun int *status_rtrn,
6628*4882a593Smuzhiyun ClientPtr client,
6629*4882a593Smuzhiyun xkbExtensionDeviceNotify * ev,
6630*4882a593Smuzhiyun xkbSetDeviceInfoReq * stuff)
6631*4882a593Smuzhiyun {
6632*4882a593Smuzhiyun xkbDeviceLedsWireDesc *ledWire;
6633*4882a593Smuzhiyun int i;
6634*4882a593Smuzhiyun XkbEventCauseRec cause;
6635*4882a593Smuzhiyun unsigned namec, mapc, statec;
6636*4882a593Smuzhiyun xkbExtensionDeviceNotify ed;
6637*4882a593Smuzhiyun XkbChangesRec changes;
6638*4882a593Smuzhiyun DeviceIntPtr kbd;
6639*4882a593Smuzhiyun
6640*4882a593Smuzhiyun memset((char *) &ed, 0, sizeof(xkbExtensionDeviceNotify));
6641*4882a593Smuzhiyun memset((char *) &changes, 0, sizeof(XkbChangesRec));
6642*4882a593Smuzhiyun XkbSetCauseXkbReq(&cause, X_kbSetDeviceInfo, client);
6643*4882a593Smuzhiyun ledWire = (xkbDeviceLedsWireDesc *) wire;
6644*4882a593Smuzhiyun for (i = 0; i < num; i++) {
6645*4882a593Smuzhiyun register int n;
6646*4882a593Smuzhiyun register unsigned bit;
6647*4882a593Smuzhiyun CARD32 *atomWire;
6648*4882a593Smuzhiyun xkbIndicatorMapWireDesc *mapWire;
6649*4882a593Smuzhiyun XkbSrvLedInfoPtr sli;
6650*4882a593Smuzhiyun
6651*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, ledWire, ledWire + 1)) {
6652*4882a593Smuzhiyun *status_rtrn = BadLength;
6653*4882a593Smuzhiyun return (char *) ledWire;
6654*4882a593Smuzhiyun }
6655*4882a593Smuzhiyun
6656*4882a593Smuzhiyun namec = mapc = statec = 0;
6657*4882a593Smuzhiyun sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID,
6658*4882a593Smuzhiyun XkbXI_IndicatorMapsMask);
6659*4882a593Smuzhiyun if (!sli) {
6660*4882a593Smuzhiyun /* SHOULD NEVER HAPPEN!! */
6661*4882a593Smuzhiyun return (char *) ledWire;
6662*4882a593Smuzhiyun }
6663*4882a593Smuzhiyun
6664*4882a593Smuzhiyun atomWire = (CARD32 *) &ledWire[1];
6665*4882a593Smuzhiyun if (changed & XkbXI_IndicatorNamesMask) {
6666*4882a593Smuzhiyun namec = sli->namesPresent | ledWire->namesPresent;
6667*4882a593Smuzhiyun memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom));
6668*4882a593Smuzhiyun }
6669*4882a593Smuzhiyun if (ledWire->namesPresent) {
6670*4882a593Smuzhiyun sli->namesPresent = ledWire->namesPresent;
6671*4882a593Smuzhiyun memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom));
6672*4882a593Smuzhiyun for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) {
6673*4882a593Smuzhiyun if (ledWire->namesPresent & bit) {
6674*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, atomWire, atomWire + 1)) {
6675*4882a593Smuzhiyun *status_rtrn = BadLength;
6676*4882a593Smuzhiyun return (char *) atomWire;
6677*4882a593Smuzhiyun }
6678*4882a593Smuzhiyun sli->names[n] = (Atom) *atomWire;
6679*4882a593Smuzhiyun if (sli->names[n] == None)
6680*4882a593Smuzhiyun ledWire->namesPresent &= ~bit;
6681*4882a593Smuzhiyun atomWire++;
6682*4882a593Smuzhiyun }
6683*4882a593Smuzhiyun }
6684*4882a593Smuzhiyun }
6685*4882a593Smuzhiyun mapWire = (xkbIndicatorMapWireDesc *) atomWire;
6686*4882a593Smuzhiyun if (changed & XkbXI_IndicatorMapsMask) {
6687*4882a593Smuzhiyun mapc = sli->mapsPresent | ledWire->mapsPresent;
6688*4882a593Smuzhiyun sli->mapsPresent = ledWire->mapsPresent;
6689*4882a593Smuzhiyun memset((char *) sli->maps, 0,
6690*4882a593Smuzhiyun XkbNumIndicators * sizeof(XkbIndicatorMapRec));
6691*4882a593Smuzhiyun }
6692*4882a593Smuzhiyun if (ledWire->mapsPresent) {
6693*4882a593Smuzhiyun for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) {
6694*4882a593Smuzhiyun if (ledWire->mapsPresent & bit) {
6695*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, mapWire, mapWire + 1)) {
6696*4882a593Smuzhiyun *status_rtrn = BadLength;
6697*4882a593Smuzhiyun return (char *) mapWire;
6698*4882a593Smuzhiyun }
6699*4882a593Smuzhiyun sli->maps[n].flags = mapWire->flags;
6700*4882a593Smuzhiyun sli->maps[n].which_groups = mapWire->whichGroups;
6701*4882a593Smuzhiyun sli->maps[n].groups = mapWire->groups;
6702*4882a593Smuzhiyun sli->maps[n].which_mods = mapWire->whichMods;
6703*4882a593Smuzhiyun sli->maps[n].mods.mask = mapWire->mods;
6704*4882a593Smuzhiyun sli->maps[n].mods.real_mods = mapWire->realMods;
6705*4882a593Smuzhiyun sli->maps[n].mods.vmods = mapWire->virtualMods;
6706*4882a593Smuzhiyun sli->maps[n].ctrls = mapWire->ctrls;
6707*4882a593Smuzhiyun mapWire++;
6708*4882a593Smuzhiyun }
6709*4882a593Smuzhiyun }
6710*4882a593Smuzhiyun }
6711*4882a593Smuzhiyun if (changed & XkbXI_IndicatorStateMask) {
6712*4882a593Smuzhiyun statec = sli->effectiveState ^ ledWire->state;
6713*4882a593Smuzhiyun sli->explicitState &= ~statec;
6714*4882a593Smuzhiyun sli->explicitState |= (ledWire->state & statec);
6715*4882a593Smuzhiyun }
6716*4882a593Smuzhiyun if (namec)
6717*4882a593Smuzhiyun XkbApplyLedNameChanges(dev, sli, namec, &ed, &changes, &cause);
6718*4882a593Smuzhiyun if (mapc)
6719*4882a593Smuzhiyun XkbApplyLedMapChanges(dev, sli, mapc, &ed, &changes, &cause);
6720*4882a593Smuzhiyun if (statec)
6721*4882a593Smuzhiyun XkbApplyLedStateChanges(dev, sli, statec, &ed, &changes, &cause);
6722*4882a593Smuzhiyun
6723*4882a593Smuzhiyun kbd = dev;
6724*4882a593Smuzhiyun if ((sli->flags & XkbSLI_HasOwnState) == 0)
6725*4882a593Smuzhiyun kbd = inputInfo.keyboard;
6726*4882a593Smuzhiyun
6727*4882a593Smuzhiyun XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause);
6728*4882a593Smuzhiyun ledWire = (xkbDeviceLedsWireDesc *) mapWire;
6729*4882a593Smuzhiyun }
6730*4882a593Smuzhiyun return (char *) ledWire;
6731*4882a593Smuzhiyun }
6732*4882a593Smuzhiyun
6733*4882a593Smuzhiyun static int
_XkbSetDeviceInfo(ClientPtr client,DeviceIntPtr dev,xkbSetDeviceInfoReq * stuff)6734*4882a593Smuzhiyun _XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev,
6735*4882a593Smuzhiyun xkbSetDeviceInfoReq * stuff)
6736*4882a593Smuzhiyun {
6737*4882a593Smuzhiyun char *wire;
6738*4882a593Smuzhiyun
6739*4882a593Smuzhiyun wire = (char *) &stuff[1];
6740*4882a593Smuzhiyun if (stuff->change & XkbXI_ButtonActionsMask) {
6741*4882a593Smuzhiyun if (!dev->button) {
6742*4882a593Smuzhiyun client->errorValue = _XkbErrCode2(XkbErr_BadClass, ButtonClass);
6743*4882a593Smuzhiyun return XkbKeyboardErrorCode;
6744*4882a593Smuzhiyun }
6745*4882a593Smuzhiyun if ((stuff->firstBtn + stuff->nBtns) > dev->button->numButtons) {
6746*4882a593Smuzhiyun client->errorValue =
6747*4882a593Smuzhiyun _XkbErrCode4(0x02, stuff->firstBtn, stuff->nBtns,
6748*4882a593Smuzhiyun dev->button->numButtons);
6749*4882a593Smuzhiyun return BadMatch;
6750*4882a593Smuzhiyun }
6751*4882a593Smuzhiyun wire += (stuff->nBtns * SIZEOF(xkbActionWireDesc));
6752*4882a593Smuzhiyun }
6753*4882a593Smuzhiyun if (stuff->change & XkbXI_IndicatorsMask) {
6754*4882a593Smuzhiyun int status = Success;
6755*4882a593Smuzhiyun
6756*4882a593Smuzhiyun wire = CheckSetDeviceIndicators(wire, dev, stuff->nDeviceLedFBs,
6757*4882a593Smuzhiyun &status, client);
6758*4882a593Smuzhiyun if (status != Success)
6759*4882a593Smuzhiyun return status;
6760*4882a593Smuzhiyun }
6761*4882a593Smuzhiyun if (((wire - ((char *) stuff)) / 4) != stuff->length)
6762*4882a593Smuzhiyun return BadLength;
6763*4882a593Smuzhiyun
6764*4882a593Smuzhiyun return Success;
6765*4882a593Smuzhiyun }
6766*4882a593Smuzhiyun
6767*4882a593Smuzhiyun static int
_XkbSetDeviceInfoCheck(ClientPtr client,DeviceIntPtr dev,xkbSetDeviceInfoReq * stuff)6768*4882a593Smuzhiyun _XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
6769*4882a593Smuzhiyun xkbSetDeviceInfoReq * stuff)
6770*4882a593Smuzhiyun {
6771*4882a593Smuzhiyun char *wire;
6772*4882a593Smuzhiyun xkbExtensionDeviceNotify ed;
6773*4882a593Smuzhiyun
6774*4882a593Smuzhiyun memset((char *) &ed, 0, SIZEOF(xkbExtensionDeviceNotify));
6775*4882a593Smuzhiyun ed.deviceID = dev->id;
6776*4882a593Smuzhiyun wire = (char *) &stuff[1];
6777*4882a593Smuzhiyun if (stuff->change & XkbXI_ButtonActionsMask) {
6778*4882a593Smuzhiyun int nBtns, sz, i;
6779*4882a593Smuzhiyun XkbAction *acts;
6780*4882a593Smuzhiyun DeviceIntPtr kbd;
6781*4882a593Smuzhiyun
6782*4882a593Smuzhiyun nBtns = dev->button->numButtons;
6783*4882a593Smuzhiyun acts = dev->button->xkb_acts;
6784*4882a593Smuzhiyun if (acts == NULL) {
6785*4882a593Smuzhiyun acts = calloc(nBtns, sizeof(XkbAction));
6786*4882a593Smuzhiyun if (!acts)
6787*4882a593Smuzhiyun return BadAlloc;
6788*4882a593Smuzhiyun dev->button->xkb_acts = acts;
6789*4882a593Smuzhiyun }
6790*4882a593Smuzhiyun if (stuff->firstBtn + stuff->nBtns > nBtns)
6791*4882a593Smuzhiyun return BadValue;
6792*4882a593Smuzhiyun sz = stuff->nBtns * SIZEOF(xkbActionWireDesc);
6793*4882a593Smuzhiyun if (!_XkbCheckRequestBounds(client, stuff, wire, (char *) wire + sz))
6794*4882a593Smuzhiyun return BadLength;
6795*4882a593Smuzhiyun memcpy((char *) &acts[stuff->firstBtn], (char *) wire, sz);
6796*4882a593Smuzhiyun wire += sz;
6797*4882a593Smuzhiyun ed.reason |= XkbXI_ButtonActionsMask;
6798*4882a593Smuzhiyun ed.firstBtn = stuff->firstBtn;
6799*4882a593Smuzhiyun ed.nBtns = stuff->nBtns;
6800*4882a593Smuzhiyun
6801*4882a593Smuzhiyun if (dev->key)
6802*4882a593Smuzhiyun kbd = dev;
6803*4882a593Smuzhiyun else
6804*4882a593Smuzhiyun kbd = inputInfo.keyboard;
6805*4882a593Smuzhiyun acts = &dev->button->xkb_acts[stuff->firstBtn];
6806*4882a593Smuzhiyun for (i = 0; i < stuff->nBtns; i++, acts++) {
6807*4882a593Smuzhiyun if (acts->type != XkbSA_NoAction)
6808*4882a593Smuzhiyun XkbSetActionKeyMods(kbd->key->xkbInfo->desc, acts, 0);
6809*4882a593Smuzhiyun }
6810*4882a593Smuzhiyun }
6811*4882a593Smuzhiyun if (stuff->change & XkbXI_IndicatorsMask) {
6812*4882a593Smuzhiyun int status = Success;
6813*4882a593Smuzhiyun
6814*4882a593Smuzhiyun wire = SetDeviceIndicators(wire, dev, stuff->change,
6815*4882a593Smuzhiyun stuff->nDeviceLedFBs, &status, client, &ed,
6816*4882a593Smuzhiyun stuff);
6817*4882a593Smuzhiyun if (status != Success)
6818*4882a593Smuzhiyun return status;
6819*4882a593Smuzhiyun }
6820*4882a593Smuzhiyun if ((stuff->change) && (ed.reason))
6821*4882a593Smuzhiyun XkbSendExtensionDeviceNotify(dev, client, &ed);
6822*4882a593Smuzhiyun return Success;
6823*4882a593Smuzhiyun }
6824*4882a593Smuzhiyun
6825*4882a593Smuzhiyun int
ProcXkbSetDeviceInfo(ClientPtr client)6826*4882a593Smuzhiyun ProcXkbSetDeviceInfo(ClientPtr client)
6827*4882a593Smuzhiyun {
6828*4882a593Smuzhiyun DeviceIntPtr dev;
6829*4882a593Smuzhiyun int rc;
6830*4882a593Smuzhiyun
6831*4882a593Smuzhiyun REQUEST(xkbSetDeviceInfoReq);
6832*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
6833*4882a593Smuzhiyun
6834*4882a593Smuzhiyun if (!(client->xkbClientFlags & _XkbClientInitialized))
6835*4882a593Smuzhiyun return BadAccess;
6836*4882a593Smuzhiyun
6837*4882a593Smuzhiyun CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
6838*4882a593Smuzhiyun CHK_MASK_LEGAL(0x01, stuff->change, XkbXI_AllFeaturesMask);
6839*4882a593Smuzhiyun
6840*4882a593Smuzhiyun rc = _XkbSetDeviceInfoCheck(client, dev, stuff);
6841*4882a593Smuzhiyun
6842*4882a593Smuzhiyun if (rc != Success)
6843*4882a593Smuzhiyun return rc;
6844*4882a593Smuzhiyun
6845*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd ||
6846*4882a593Smuzhiyun stuff->deviceSpec == XkbUseCorePtr) {
6847*4882a593Smuzhiyun DeviceIntPtr other;
6848*4882a593Smuzhiyun
6849*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
6850*4882a593Smuzhiyun if (((other != dev) && !IsMaster(other) &&
6851*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) &&
6852*4882a593Smuzhiyun ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
6853*4882a593Smuzhiyun (stuff->deviceSpec == XkbUseCorePtr && other->button))) {
6854*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
6855*4882a593Smuzhiyun DixManageAccess);
6856*4882a593Smuzhiyun if (rc == Success) {
6857*4882a593Smuzhiyun rc = _XkbSetDeviceInfoCheck(client, other, stuff);
6858*4882a593Smuzhiyun if (rc != Success)
6859*4882a593Smuzhiyun return rc;
6860*4882a593Smuzhiyun }
6861*4882a593Smuzhiyun }
6862*4882a593Smuzhiyun }
6863*4882a593Smuzhiyun }
6864*4882a593Smuzhiyun
6865*4882a593Smuzhiyun /* checks done, apply */
6866*4882a593Smuzhiyun rc = _XkbSetDeviceInfo(client, dev, stuff);
6867*4882a593Smuzhiyun if (rc != Success)
6868*4882a593Smuzhiyun return rc;
6869*4882a593Smuzhiyun
6870*4882a593Smuzhiyun if (stuff->deviceSpec == XkbUseCoreKbd ||
6871*4882a593Smuzhiyun stuff->deviceSpec == XkbUseCorePtr) {
6872*4882a593Smuzhiyun DeviceIntPtr other;
6873*4882a593Smuzhiyun
6874*4882a593Smuzhiyun for (other = inputInfo.devices; other; other = other->next) {
6875*4882a593Smuzhiyun if (((other != dev) && !IsMaster(other) &&
6876*4882a593Smuzhiyun GetMaster(other, MASTER_KEYBOARD) == dev) &&
6877*4882a593Smuzhiyun ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
6878*4882a593Smuzhiyun (stuff->deviceSpec == XkbUseCorePtr && other->button))) {
6879*4882a593Smuzhiyun rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
6880*4882a593Smuzhiyun DixManageAccess);
6881*4882a593Smuzhiyun if (rc == Success) {
6882*4882a593Smuzhiyun rc = _XkbSetDeviceInfo(client, other, stuff);
6883*4882a593Smuzhiyun if (rc != Success)
6884*4882a593Smuzhiyun return rc;
6885*4882a593Smuzhiyun }
6886*4882a593Smuzhiyun }
6887*4882a593Smuzhiyun }
6888*4882a593Smuzhiyun }
6889*4882a593Smuzhiyun
6890*4882a593Smuzhiyun return Success;
6891*4882a593Smuzhiyun }
6892*4882a593Smuzhiyun
6893*4882a593Smuzhiyun /***====================================================================***/
6894*4882a593Smuzhiyun
6895*4882a593Smuzhiyun int
ProcXkbSetDebuggingFlags(ClientPtr client)6896*4882a593Smuzhiyun ProcXkbSetDebuggingFlags(ClientPtr client)
6897*4882a593Smuzhiyun {
6898*4882a593Smuzhiyun CARD32 newFlags, newCtrls, extraLength;
6899*4882a593Smuzhiyun xkbSetDebuggingFlagsReply rep;
6900*4882a593Smuzhiyun int rc;
6901*4882a593Smuzhiyun
6902*4882a593Smuzhiyun REQUEST(xkbSetDebuggingFlagsReq);
6903*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq);
6904*4882a593Smuzhiyun
6905*4882a593Smuzhiyun rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess);
6906*4882a593Smuzhiyun if (rc != Success)
6907*4882a593Smuzhiyun return rc;
6908*4882a593Smuzhiyun
6909*4882a593Smuzhiyun newFlags = xkbDebugFlags & (~stuff->affectFlags);
6910*4882a593Smuzhiyun newFlags |= (stuff->flags & stuff->affectFlags);
6911*4882a593Smuzhiyun newCtrls = xkbDebugCtrls & (~stuff->affectCtrls);
6912*4882a593Smuzhiyun newCtrls |= (stuff->ctrls & stuff->affectCtrls);
6913*4882a593Smuzhiyun if (xkbDebugFlags || newFlags || stuff->msgLength) {
6914*4882a593Smuzhiyun ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n",
6915*4882a593Smuzhiyun (long) newFlags);
6916*4882a593Smuzhiyun if (newCtrls != xkbDebugCtrls)
6917*4882a593Smuzhiyun ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n",
6918*4882a593Smuzhiyun (long) newCtrls);
6919*4882a593Smuzhiyun }
6920*4882a593Smuzhiyun extraLength = (stuff->length << 2) - sz_xkbSetDebuggingFlagsReq;
6921*4882a593Smuzhiyun if (stuff->msgLength > 0) {
6922*4882a593Smuzhiyun char *msg;
6923*4882a593Smuzhiyun
6924*4882a593Smuzhiyun if (extraLength < XkbPaddedSize(stuff->msgLength)) {
6925*4882a593Smuzhiyun ErrorF
6926*4882a593Smuzhiyun ("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n",
6927*4882a593Smuzhiyun stuff->msgLength, (long) extraLength,
6928*4882a593Smuzhiyun XkbPaddedSize(stuff->msgLength));
6929*4882a593Smuzhiyun return BadLength;
6930*4882a593Smuzhiyun }
6931*4882a593Smuzhiyun msg = (char *) &stuff[1];
6932*4882a593Smuzhiyun if (msg[stuff->msgLength - 1] != '\0') {
6933*4882a593Smuzhiyun ErrorF("[xkb] XkbDebug: message not null-terminated\n");
6934*4882a593Smuzhiyun return BadValue;
6935*4882a593Smuzhiyun }
6936*4882a593Smuzhiyun ErrorF("[xkb] XkbDebug: %s\n", msg);
6937*4882a593Smuzhiyun }
6938*4882a593Smuzhiyun xkbDebugFlags = newFlags;
6939*4882a593Smuzhiyun xkbDebugCtrls = newCtrls;
6940*4882a593Smuzhiyun
6941*4882a593Smuzhiyun rep = (xkbSetDebuggingFlagsReply) {
6942*4882a593Smuzhiyun .type = X_Reply,
6943*4882a593Smuzhiyun .sequenceNumber = client->sequence,
6944*4882a593Smuzhiyun .length = 0,
6945*4882a593Smuzhiyun .currentFlags = newFlags,
6946*4882a593Smuzhiyun .currentCtrls = newCtrls,
6947*4882a593Smuzhiyun .supportedFlags = ~0,
6948*4882a593Smuzhiyun .supportedCtrls = ~0
6949*4882a593Smuzhiyun };
6950*4882a593Smuzhiyun if (client->swapped) {
6951*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
6952*4882a593Smuzhiyun swapl(&rep.currentFlags);
6953*4882a593Smuzhiyun swapl(&rep.currentCtrls);
6954*4882a593Smuzhiyun swapl(&rep.supportedFlags);
6955*4882a593Smuzhiyun swapl(&rep.supportedCtrls);
6956*4882a593Smuzhiyun }
6957*4882a593Smuzhiyun WriteToClient(client, SIZEOF(xkbSetDebuggingFlagsReply), &rep);
6958*4882a593Smuzhiyun return Success;
6959*4882a593Smuzhiyun }
6960*4882a593Smuzhiyun
6961*4882a593Smuzhiyun /***====================================================================***/
6962*4882a593Smuzhiyun
6963*4882a593Smuzhiyun static int
ProcXkbDispatch(ClientPtr client)6964*4882a593Smuzhiyun ProcXkbDispatch(ClientPtr client)
6965*4882a593Smuzhiyun {
6966*4882a593Smuzhiyun REQUEST(xReq);
6967*4882a593Smuzhiyun switch (stuff->data) {
6968*4882a593Smuzhiyun case X_kbUseExtension:
6969*4882a593Smuzhiyun return ProcXkbUseExtension(client);
6970*4882a593Smuzhiyun case X_kbSelectEvents:
6971*4882a593Smuzhiyun return ProcXkbSelectEvents(client);
6972*4882a593Smuzhiyun case X_kbBell:
6973*4882a593Smuzhiyun return ProcXkbBell(client);
6974*4882a593Smuzhiyun case X_kbGetState:
6975*4882a593Smuzhiyun return ProcXkbGetState(client);
6976*4882a593Smuzhiyun case X_kbLatchLockState:
6977*4882a593Smuzhiyun return ProcXkbLatchLockState(client);
6978*4882a593Smuzhiyun case X_kbGetControls:
6979*4882a593Smuzhiyun return ProcXkbGetControls(client);
6980*4882a593Smuzhiyun case X_kbSetControls:
6981*4882a593Smuzhiyun return ProcXkbSetControls(client);
6982*4882a593Smuzhiyun case X_kbGetMap:
6983*4882a593Smuzhiyun return ProcXkbGetMap(client);
6984*4882a593Smuzhiyun case X_kbSetMap:
6985*4882a593Smuzhiyun return ProcXkbSetMap(client);
6986*4882a593Smuzhiyun case X_kbGetCompatMap:
6987*4882a593Smuzhiyun return ProcXkbGetCompatMap(client);
6988*4882a593Smuzhiyun case X_kbSetCompatMap:
6989*4882a593Smuzhiyun return ProcXkbSetCompatMap(client);
6990*4882a593Smuzhiyun case X_kbGetIndicatorState:
6991*4882a593Smuzhiyun return ProcXkbGetIndicatorState(client);
6992*4882a593Smuzhiyun case X_kbGetIndicatorMap:
6993*4882a593Smuzhiyun return ProcXkbGetIndicatorMap(client);
6994*4882a593Smuzhiyun case X_kbSetIndicatorMap:
6995*4882a593Smuzhiyun return ProcXkbSetIndicatorMap(client);
6996*4882a593Smuzhiyun case X_kbGetNamedIndicator:
6997*4882a593Smuzhiyun return ProcXkbGetNamedIndicator(client);
6998*4882a593Smuzhiyun case X_kbSetNamedIndicator:
6999*4882a593Smuzhiyun return ProcXkbSetNamedIndicator(client);
7000*4882a593Smuzhiyun case X_kbGetNames:
7001*4882a593Smuzhiyun return ProcXkbGetNames(client);
7002*4882a593Smuzhiyun case X_kbSetNames:
7003*4882a593Smuzhiyun return ProcXkbSetNames(client);
7004*4882a593Smuzhiyun case X_kbGetGeometry:
7005*4882a593Smuzhiyun return ProcXkbGetGeometry(client);
7006*4882a593Smuzhiyun case X_kbSetGeometry:
7007*4882a593Smuzhiyun return ProcXkbSetGeometry(client);
7008*4882a593Smuzhiyun case X_kbPerClientFlags:
7009*4882a593Smuzhiyun return ProcXkbPerClientFlags(client);
7010*4882a593Smuzhiyun case X_kbListComponents:
7011*4882a593Smuzhiyun return ProcXkbListComponents(client);
7012*4882a593Smuzhiyun case X_kbGetKbdByName:
7013*4882a593Smuzhiyun return ProcXkbGetKbdByName(client);
7014*4882a593Smuzhiyun case X_kbGetDeviceInfo:
7015*4882a593Smuzhiyun return ProcXkbGetDeviceInfo(client);
7016*4882a593Smuzhiyun case X_kbSetDeviceInfo:
7017*4882a593Smuzhiyun return ProcXkbSetDeviceInfo(client);
7018*4882a593Smuzhiyun case X_kbSetDebuggingFlags:
7019*4882a593Smuzhiyun return ProcXkbSetDebuggingFlags(client);
7020*4882a593Smuzhiyun default:
7021*4882a593Smuzhiyun return BadRequest;
7022*4882a593Smuzhiyun }
7023*4882a593Smuzhiyun }
7024*4882a593Smuzhiyun
7025*4882a593Smuzhiyun static int
XkbClientGone(void * data,XID id)7026*4882a593Smuzhiyun XkbClientGone(void *data, XID id)
7027*4882a593Smuzhiyun {
7028*4882a593Smuzhiyun DevicePtr pXDev = (DevicePtr) data;
7029*4882a593Smuzhiyun
7030*4882a593Smuzhiyun if (!XkbRemoveResourceClient(pXDev, id)) {
7031*4882a593Smuzhiyun ErrorF
7032*4882a593Smuzhiyun ("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n");
7033*4882a593Smuzhiyun }
7034*4882a593Smuzhiyun return 1;
7035*4882a593Smuzhiyun }
7036*4882a593Smuzhiyun
7037*4882a593Smuzhiyun void
XkbExtensionInit(void)7038*4882a593Smuzhiyun XkbExtensionInit(void)
7039*4882a593Smuzhiyun {
7040*4882a593Smuzhiyun ExtensionEntry *extEntry;
7041*4882a593Smuzhiyun
7042*4882a593Smuzhiyun RT_XKBCLIENT = CreateNewResourceType(XkbClientGone, "XkbClient");
7043*4882a593Smuzhiyun if (!RT_XKBCLIENT)
7044*4882a593Smuzhiyun return;
7045*4882a593Smuzhiyun
7046*4882a593Smuzhiyun if (!XkbInitPrivates())
7047*4882a593Smuzhiyun return;
7048*4882a593Smuzhiyun
7049*4882a593Smuzhiyun if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors,
7050*4882a593Smuzhiyun ProcXkbDispatch, SProcXkbDispatch,
7051*4882a593Smuzhiyun NULL, StandardMinorOpcode))) {
7052*4882a593Smuzhiyun XkbReqCode = (unsigned char) extEntry->base;
7053*4882a593Smuzhiyun XkbEventBase = (unsigned char) extEntry->eventBase;
7054*4882a593Smuzhiyun XkbErrorBase = (unsigned char) extEntry->errorBase;
7055*4882a593Smuzhiyun XkbKeyboardErrorCode = XkbErrorBase + XkbKeyboard;
7056*4882a593Smuzhiyun }
7057*4882a593Smuzhiyun return;
7058*4882a593Smuzhiyun }
7059