~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to xkb/xkb.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

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