1/************************************************************
2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4Permission to use, copy, modify, and distribute this
5software and its documentation for any purpose and without
6fee is hereby granted, provided that the above copyright
7notice appear in all copies and that both that copyright
8notice and this permission notice appear in supporting
9documentation, and that the name of Silicon Graphics not be
10used in advertising or publicity pertaining to distribution
11of the software without specific prior written permission.
12Silicon Graphics makes no representation about the suitability
13of this software for any purpose. It is provided "as is"
14without any express or implied warranty.
15
16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25********************************************************/
26
27#ifdef HAVE_DIX_CONFIG_H
28#include <dix-config.h>
29#endif
30
31#include "stdio.h"
32#include <X11/X.h>
33#include <X11/Xproto.h>
34#include "misc.h"
35#include "inputstr.h"
36#include <xkbsrv.h>
37#include "xkbstr.h"
38#include "extnsionst.h"
39#include "xkb.h"
40
41        /*
42         * REQUEST SWAPPING
43         */
44static int _X_COLD
45SProcXkbUseExtension(ClientPtr client)
46{
47    REQUEST(xkbUseExtensionReq);
48
49    swaps(&stuff->length);
50    REQUEST_SIZE_MATCH(xkbUseExtensionReq);
51    swaps(&stuff->wantedMajor);
52    swaps(&stuff->wantedMinor);
53    return ProcXkbUseExtension(client);
54}
55
56static int _X_COLD
57SProcXkbSelectEvents(ClientPtr client)
58{
59    REQUEST(xkbSelectEventsReq);
60
61    swaps(&stuff->length);
62    REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
63    swaps(&stuff->deviceSpec);
64    swaps(&stuff->affectWhich);
65    swaps(&stuff->clear);
66    swaps(&stuff->selectAll);
67    swaps(&stuff->affectMap);
68    swaps(&stuff->map);
69    if ((stuff->affectWhich & (~XkbMapNotifyMask)) != 0) {
70        union {
71            BOOL *b;
72            CARD8 *c8;
73            CARD16 *c16;
74            CARD32 *c32;
75        } from;
76        register unsigned bit, ndx, maskLeft, dataLeft, size;
77
78        from.c8 = (CARD8 *) &stuff[1];
79        dataLeft = (client->req_len * 4) - SIZEOF(xkbSelectEventsReq);
80        maskLeft = (stuff->affectWhich & (~XkbMapNotifyMask));
81        for (ndx = 0, bit = 1; (maskLeft != 0); ndx++, bit <<= 1) {
82            if (((bit & maskLeft) == 0) || (ndx == XkbMapNotify))
83                continue;
84            maskLeft &= ~bit;
85            if ((stuff->selectAll & bit) || (stuff->clear & bit))
86                continue;
87            switch (ndx) {
88            case XkbNewKeyboardNotify:
89            case XkbStateNotify:
90            case XkbNamesNotify:
91            case XkbAccessXNotify:
92            case XkbExtensionDeviceNotify:
93                size = 2;
94                break;
95            case XkbControlsNotify:
96            case XkbIndicatorStateNotify:
97            case XkbIndicatorMapNotify:
98                size = 4;
99                break;
100            case XkbBellNotify:
101            case XkbActionMessage:
102            case XkbCompatMapNotify:
103                size = 1;
104                break;
105            default:
106                client->errorValue = _XkbErrCode2(0x1, bit);
107                return BadValue;
108            }
109            if (dataLeft < (size * 2))
110                return BadLength;
111            if (size == 2) {
112                swaps(&from.c16[0]);
113                swaps(&from.c16[1]);
114            }
115            else if (size == 4) {
116                swapl(&from.c32[0]);
117                swapl(&from.c32[1]);
118            }
119            else {
120                size = 2;
121            }
122            from.c8 += (size * 2);
123            dataLeft -= (size * 2);
124        }
125        if (dataLeft > 2) {
126            ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",
127                   dataLeft);
128            return BadLength;
129        }
130    }
131    return ProcXkbSelectEvents(client);
132}
133
134static int _X_COLD
135SProcXkbBell(ClientPtr client)
136{
137    REQUEST(xkbBellReq);
138
139    swaps(&stuff->length);
140    REQUEST_SIZE_MATCH(xkbBellReq);
141    swaps(&stuff->deviceSpec);
142    swaps(&stuff->bellClass);
143    swaps(&stuff->bellID);
144    swapl(&stuff->name);
145    swapl(&stuff->window);
146    swaps(&stuff->pitch);
147    swaps(&stuff->duration);
148    return ProcXkbBell(client);
149}
150
151static int _X_COLD
152SProcXkbGetState(ClientPtr client)
153{
154    REQUEST(xkbGetStateReq);
155
156    swaps(&stuff->length);
157    REQUEST_SIZE_MATCH(xkbGetStateReq);
158    swaps(&stuff->deviceSpec);
159    return ProcXkbGetState(client);
160}
161
162static int _X_COLD
163SProcXkbLatchLockState(ClientPtr client)
164{
165    REQUEST(xkbLatchLockStateReq);
166
167    swaps(&stuff->length);
168    REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
169    swaps(&stuff->deviceSpec);
170    swaps(&stuff->groupLatch);
171    return ProcXkbLatchLockState(client);
172}
173
174static int _X_COLD
175SProcXkbGetControls(ClientPtr client)
176{
177    REQUEST(xkbGetControlsReq);
178
179    swaps(&stuff->length);
180    REQUEST_SIZE_MATCH(xkbGetControlsReq);
181    swaps(&stuff->deviceSpec);
182    return ProcXkbGetControls(client);
183}
184
185static int _X_COLD
186SProcXkbSetControls(ClientPtr client)
187{
188    REQUEST(xkbSetControlsReq);
189
190    swaps(&stuff->length);
191    REQUEST_SIZE_MATCH(xkbSetControlsReq);
192    swaps(&stuff->deviceSpec);
193    swaps(&stuff->affectInternalVMods);
194    swaps(&stuff->internalVMods);
195    swaps(&stuff->affectIgnoreLockVMods);
196    swaps(&stuff->ignoreLockVMods);
197    swaps(&stuff->axOptions);
198    swapl(&stuff->affectEnabledCtrls);
199    swapl(&stuff->enabledCtrls);
200    swapl(&stuff->changeCtrls);
201    swaps(&stuff->repeatDelay);
202    swaps(&stuff->repeatInterval);
203    swaps(&stuff->slowKeysDelay);
204    swaps(&stuff->debounceDelay);
205    swaps(&stuff->mkDelay);
206    swaps(&stuff->mkInterval);
207    swaps(&stuff->mkTimeToMax);
208    swaps(&stuff->mkMaxSpeed);
209    swaps(&stuff->mkCurve);
210    swaps(&stuff->axTimeout);
211    swapl(&stuff->axtCtrlsMask);
212    swapl(&stuff->axtCtrlsValues);
213    swaps(&stuff->axtOptsMask);
214    swaps(&stuff->axtOptsValues);
215    return ProcXkbSetControls(client);
216}
217
218static int _X_COLD
219SProcXkbGetMap(ClientPtr client)
220{
221    REQUEST(xkbGetMapReq);
222
223    swaps(&stuff->length);
224    REQUEST_SIZE_MATCH(xkbGetMapReq);
225    swaps(&stuff->deviceSpec);
226    swaps(&stuff->full);
227    swaps(&stuff->partial);
228    swaps(&stuff->virtualMods);
229    return ProcXkbGetMap(client);
230}
231
232static int _X_COLD
233SProcXkbSetMap(ClientPtr client)
234{
235    REQUEST(xkbSetMapReq);
236
237    swaps(&stuff->length);
238    REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
239    swaps(&stuff->deviceSpec);
240    swaps(&stuff->present);
241    swaps(&stuff->flags);
242    swaps(&stuff->totalSyms);
243    swaps(&stuff->totalActs);
244    swaps(&stuff->virtualMods);
245    return ProcXkbSetMap(client);
246}
247
248static int _X_COLD
249SProcXkbGetCompatMap(ClientPtr client)
250{
251    REQUEST(xkbGetCompatMapReq);
252
253    swaps(&stuff->length);
254    REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
255    swaps(&stuff->deviceSpec);
256    swaps(&stuff->firstSI);
257    swaps(&stuff->nSI);
258    return ProcXkbGetCompatMap(client);
259}
260
261static int _X_COLD
262SProcXkbSetCompatMap(ClientPtr client)
263{
264    REQUEST(xkbSetCompatMapReq);
265
266    swaps(&stuff->length);
267    REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
268    swaps(&stuff->deviceSpec);
269    swaps(&stuff->firstSI);
270    swaps(&stuff->nSI);
271    return ProcXkbSetCompatMap(client);
272}
273
274static int _X_COLD
275SProcXkbGetIndicatorState(ClientPtr client)
276{
277    REQUEST(xkbGetIndicatorStateReq);
278
279    swaps(&stuff->length);
280    REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq);
281    swaps(&stuff->deviceSpec);
282    return ProcXkbGetIndicatorState(client);
283}
284
285static int _X_COLD
286SProcXkbGetIndicatorMap(ClientPtr client)
287{
288    REQUEST(xkbGetIndicatorMapReq);
289
290    swaps(&stuff->length);
291    REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq);
292    swaps(&stuff->deviceSpec);
293    swapl(&stuff->which);
294    return ProcXkbGetIndicatorMap(client);
295}
296
297static int _X_COLD
298SProcXkbSetIndicatorMap(ClientPtr client)
299{
300    REQUEST(xkbSetIndicatorMapReq);
301
302    swaps(&stuff->length);
303    REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
304    swaps(&stuff->deviceSpec);
305    swapl(&stuff->which);
306    return ProcXkbSetIndicatorMap(client);
307}
308
309static int _X_COLD
310SProcXkbGetNamedIndicator(ClientPtr client)
311{
312    REQUEST(xkbGetNamedIndicatorReq);
313
314    swaps(&stuff->length);
315    REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
316    swaps(&stuff->deviceSpec);
317    swaps(&stuff->ledClass);
318    swaps(&stuff->ledID);
319    swapl(&stuff->indicator);
320    return ProcXkbGetNamedIndicator(client);
321}
322
323static int _X_COLD
324SProcXkbSetNamedIndicator(ClientPtr client)
325{
326    REQUEST(xkbSetNamedIndicatorReq);
327
328    swaps(&stuff->length);
329    REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq);
330    swaps(&stuff->deviceSpec);
331    swaps(&stuff->ledClass);
332    swaps(&stuff->ledID);
333    swapl(&stuff->indicator);
334    swaps(&stuff->virtualMods);
335    swapl(&stuff->ctrls);
336    return ProcXkbSetNamedIndicator(client);
337}
338
339static int _X_COLD
340SProcXkbGetNames(ClientPtr client)
341{
342    REQUEST(xkbGetNamesReq);
343
344    swaps(&stuff->length);
345    REQUEST_SIZE_MATCH(xkbGetNamesReq);
346    swaps(&stuff->deviceSpec);
347    swapl(&stuff->which);
348    return ProcXkbGetNames(client);
349}
350
351static int _X_COLD
352SProcXkbSetNames(ClientPtr client)
353{
354    REQUEST(xkbSetNamesReq);
355
356    swaps(&stuff->length);
357    REQUEST_AT_LEAST_SIZE(xkbSetNamesReq);
358    swaps(&stuff->deviceSpec);
359    swaps(&stuff->virtualMods);
360    swapl(&stuff->which);
361    swapl(&stuff->indicators);
362    swaps(&stuff->totalKTLevelNames);
363    return ProcXkbSetNames(client);
364}
365
366static int _X_COLD
367SProcXkbGetGeometry(ClientPtr client)
368{
369    REQUEST(xkbGetGeometryReq);
370
371    swaps(&stuff->length);
372    REQUEST_SIZE_MATCH(xkbGetGeometryReq);
373    swaps(&stuff->deviceSpec);
374    swapl(&stuff->name);
375    return ProcXkbGetGeometry(client);
376}
377
378static int _X_COLD
379SProcXkbSetGeometry(ClientPtr client)
380{
381    REQUEST(xkbSetGeometryReq);
382
383    swaps(&stuff->length);
384    REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq);
385    swaps(&stuff->deviceSpec);
386    swapl(&stuff->name);
387    swaps(&stuff->widthMM);
388    swaps(&stuff->heightMM);
389    swaps(&stuff->nProperties);
390    swaps(&stuff->nColors);
391    swaps(&stuff->nDoodads);
392    swaps(&stuff->nKeyAliases);
393    return ProcXkbSetGeometry(client);
394}
395
396static int _X_COLD
397SProcXkbPerClientFlags(ClientPtr client)
398{
399    REQUEST(xkbPerClientFlagsReq);
400
401    swaps(&stuff->length);
402    REQUEST_SIZE_MATCH(xkbPerClientFlagsReq);
403    swaps(&stuff->deviceSpec);
404    swapl(&stuff->change);
405    swapl(&stuff->value);
406    swapl(&stuff->ctrlsToChange);
407    swapl(&stuff->autoCtrls);
408    swapl(&stuff->autoCtrlValues);
409    return ProcXkbPerClientFlags(client);
410}
411
412static int _X_COLD
413SProcXkbListComponents(ClientPtr client)
414{
415    REQUEST(xkbListComponentsReq);
416
417    swaps(&stuff->length);
418    REQUEST_AT_LEAST_SIZE(xkbListComponentsReq);
419    swaps(&stuff->deviceSpec);
420    swaps(&stuff->maxNames);
421    return ProcXkbListComponents(client);
422}
423
424static int _X_COLD
425SProcXkbGetKbdByName(ClientPtr client)
426{
427    REQUEST(xkbGetKbdByNameReq);
428
429    swaps(&stuff->length);
430    REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq);
431    swaps(&stuff->deviceSpec);
432    swaps(&stuff->want);
433    swaps(&stuff->need);
434    return ProcXkbGetKbdByName(client);
435}
436
437static int _X_COLD
438SProcXkbGetDeviceInfo(ClientPtr client)
439{
440    REQUEST(xkbGetDeviceInfoReq);
441
442    swaps(&stuff->length);
443    REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq);
444    swaps(&stuff->deviceSpec);
445    swaps(&stuff->wanted);
446    swaps(&stuff->ledClass);
447    swaps(&stuff->ledID);
448    return ProcXkbGetDeviceInfo(client);
449}
450
451static int _X_COLD
452SProcXkbSetDeviceInfo(ClientPtr client)
453{
454    REQUEST(xkbSetDeviceInfoReq);
455
456    swaps(&stuff->length);
457    REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
458    swaps(&stuff->deviceSpec);
459    swaps(&stuff->change);
460    swaps(&stuff->nDeviceLedFBs);
461    return ProcXkbSetDeviceInfo(client);
462}
463
464static int _X_COLD
465SProcXkbSetDebuggingFlags(ClientPtr client)
466{
467    REQUEST(xkbSetDebuggingFlagsReq);
468
469    swaps(&stuff->length);
470    REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq);
471    swapl(&stuff->affectFlags);
472    swapl(&stuff->flags);
473    swapl(&stuff->affectCtrls);
474    swapl(&stuff->ctrls);
475    swaps(&stuff->msgLength);
476    return ProcXkbSetDebuggingFlags(client);
477}
478
479int _X_COLD
480SProcXkbDispatch(ClientPtr client)
481{
482    REQUEST(xReq);
483    switch (stuff->data) {
484    case X_kbUseExtension:
485        return SProcXkbUseExtension(client);
486    case X_kbSelectEvents:
487        return SProcXkbSelectEvents(client);
488    case X_kbBell:
489        return SProcXkbBell(client);
490    case X_kbGetState:
491        return SProcXkbGetState(client);
492    case X_kbLatchLockState:
493        return SProcXkbLatchLockState(client);
494    case X_kbGetControls:
495        return SProcXkbGetControls(client);
496    case X_kbSetControls:
497        return SProcXkbSetControls(client);
498    case X_kbGetMap:
499        return SProcXkbGetMap(client);
500    case X_kbSetMap:
501        return SProcXkbSetMap(client);
502    case X_kbGetCompatMap:
503        return SProcXkbGetCompatMap(client);
504    case X_kbSetCompatMap:
505        return SProcXkbSetCompatMap(client);
506    case X_kbGetIndicatorState:
507        return SProcXkbGetIndicatorState(client);
508    case X_kbGetIndicatorMap:
509        return SProcXkbGetIndicatorMap(client);
510    case X_kbSetIndicatorMap:
511        return SProcXkbSetIndicatorMap(client);
512    case X_kbGetNamedIndicator:
513        return SProcXkbGetNamedIndicator(client);
514    case X_kbSetNamedIndicator:
515        return SProcXkbSetNamedIndicator(client);
516    case X_kbGetNames:
517        return SProcXkbGetNames(client);
518    case X_kbSetNames:
519        return SProcXkbSetNames(client);
520    case X_kbGetGeometry:
521        return SProcXkbGetGeometry(client);
522    case X_kbSetGeometry:
523        return SProcXkbSetGeometry(client);
524    case X_kbPerClientFlags:
525        return SProcXkbPerClientFlags(client);
526    case X_kbListComponents:
527        return SProcXkbListComponents(client);
528    case X_kbGetKbdByName:
529        return SProcXkbGetKbdByName(client);
530    case X_kbGetDeviceInfo:
531        return SProcXkbGetDeviceInfo(client);
532    case X_kbSetDeviceInfo:
533        return SProcXkbSetDeviceInfo(client);
534    case X_kbSetDebuggingFlags:
535        return SProcXkbSetDebuggingFlags(client);
536    default:
537        return BadRequest;
538    }
539}
540