~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/X11/XKBExtDev.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: XKBExtDev.c,v 1.3 2000/08/17 19:45:01 cpqbld Exp $ */
 
2
/************************************************************
 
3
Copyright (c) 1995 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/lib/X11/XKBExtDev.c,v 3.4 2001/10/28 03:32:33 tsi Exp $ */
 
28
 
 
29
#include <stdio.h>
 
30
#define NEED_REPLIES
 
31
#define NEED_EVENTS
 
32
#define NEED_MAP_READERS
 
33
#include "Xlibint.h"
 
34
#include <X11/extensions/XKBproto.h>
 
35
#include "XKBlibint.h"
 
36
#include <X11/extensions/XI.h>
 
37
 
 
38
/***====================================================================***/
 
39
 
 
40
extern  void
 
41
#if NeedFunctionPrototypes
 
42
XkbNoteDeviceChanges(   XkbDeviceChangesPtr             old,
 
43
                        XkbExtensionDeviceNotifyEvent * new,
 
44
                        unsigned int                    wanted)
 
45
#else
 
46
XkbNoteDeviceChanges(old,new,wanted)
 
47
    XkbDeviceChangesPtr                 old;
 
48
    XkbExtensionDeviceNotifyEvent *     new;
 
49
    unsigned int                        wanted;
 
50
#endif
 
51
{
 
52
    if ((!old)||(!new)||(!wanted)||((new->reason&wanted)==0))
 
53
        return;
 
54
    if ((wanted&new->reason)&XkbXI_ButtonActionsMask) {
 
55
        if (old->changed&XkbXI_ButtonActionsMask) {
 
56
            int first,last,newLast;
 
57
            if (new->first_btn<old->first_btn)
 
58
                 first= new->first_btn;
 
59
            else first= old->first_btn;
 
60
            last= old->first_btn+old->num_btns-1;
 
61
            newLast= new->first_btn+new->num_btns-1;
 
62
            if (newLast>last)
 
63
                last= newLast;
 
64
            old->first_btn= first;
 
65
            old->num_btns= (last-first)+1;
 
66
        }
 
67
        else {
 
68
            old->changed|= XkbXI_ButtonActionsMask;
 
69
            old->first_btn= new->first_btn;
 
70
            old->num_btns= new->num_btns;
 
71
        }
 
72
    }
 
73
    if ((wanted&new->reason)&XkbXI_IndicatorsMask) {
 
74
        XkbDeviceLedChangesPtr this;
 
75
        if (old->changed&XkbXI_IndicatorsMask) {
 
76
            XkbDeviceLedChangesPtr found;
 
77
            found= NULL;
 
78
            for (this= &old->leds;this&&(!found);this=this->next) {
 
79
                if ((this->led_class==new->led_class)&&
 
80
                                                (this->led_id==new->led_id)) {
 
81
                    found= this;
 
82
                }
 
83
            }
 
84
            if (!found) {
 
85
                found= _XkbTypedCalloc(1,XkbDeviceLedChangesRec);
 
86
                if (!found)
 
87
                    return;
 
88
                found->next= old->leds.next;
 
89
                found->led_class= new->led_class;
 
90
                found->led_id= new->led_id;
 
91
                old->leds.next= found;
 
92
            }
 
93
            if ((wanted&new->reason)&XkbXI_IndicatorNamesMask)
 
94
                found->defined= new->leds_defined;
 
95
        }
 
96
        else {
 
97
            old->changed|= ((wanted&new->reason)&XkbXI_IndicatorsMask);
 
98
            old->leds.led_class= new->led_class;
 
99
            old->leds.led_id= new->led_id;
 
100
            old->leds.defined= new->leds_defined;
 
101
            if (old->leds.next) {
 
102
                XkbDeviceLedChangesPtr next;
 
103
                for (this=old->leds.next;this;this=next) {
 
104
                    next= this->next;
 
105
                    _XkbFree(this);
 
106
                }
 
107
                old->leds.next= NULL;
 
108
            }
 
109
        }
 
110
    }
 
111
    return;
 
112
}
 
113
 
 
114
/***====================================================================***/
 
115
 
 
116
static Status
 
117
#if NeedFunctionPrototypes
 
118
_XkbReadDeviceLedInfo(  XkbReadBufferPtr        buf,
 
119
                        unsigned                present,
 
120
                        XkbDeviceInfoPtr        devi)
 
121
#else
 
122
_XkbReadDeviceLedInfo(buf,present,devi)
 
123
    XkbReadBufferPtr    buf;
 
124
    unsigned            present;
 
125
    XkbDeviceInfoPtr    devi;
 
126
#endif
 
127
{
 
128
register unsigned       i,bit;
 
129
XkbDeviceLedInfoPtr     devli;
 
130
xkbDeviceLedsWireDesc * wireli;
 
131
 
 
132
    wireli= _XkbGetTypedRdBufPtr(buf,1,xkbDeviceLedsWireDesc);
 
133
    if (!wireli)
 
134
        return BadLength;
 
135
    devli= XkbAddDeviceLedInfo(devi,wireli->ledClass,wireli->ledID);
 
136
    if (!devli)
 
137
        return BadAlloc;
 
138
    devli->phys_indicators=     wireli->physIndicators;
 
139
 
 
140
    if (present&XkbXI_IndicatorStateMask)
 
141
        devli->state= wireli->state;
 
142
 
 
143
    if (present&XkbXI_IndicatorNamesMask) {
 
144
        devli->names_present=   wireli->namesPresent;
 
145
        if (devli->names_present) {
 
146
            for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
 
147
                if (wireli->namesPresent&bit) {
 
148
                    if (!_XkbCopyFromReadBuffer(buf,(char *)&devli->names[i],4))
 
149
                        return BadLength;
 
150
                }
 
151
            }
 
152
        }
 
153
    }
 
154
 
 
155
    if (present&XkbXI_IndicatorMapsMask) {
 
156
        devli->maps_present=    wireli->mapsPresent;
 
157
        if (devli->maps_present) {
 
158
            XkbIndicatorMapPtr          im;
 
159
            xkbIndicatorMapWireDesc *   wireim;
 
160
            for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
 
161
                if (wireli->mapsPresent&bit) {
 
162
                    wireim= _XkbGetTypedRdBufPtr(buf,1,xkbIndicatorMapWireDesc);
 
163
                    if (!wireim)
 
164
                        return BadAlloc;
 
165
                    im= &devli->maps[i];
 
166
                    im->flags=          wireim->flags;
 
167
                    im->which_groups=   wireim->whichGroups;
 
168
                    im->groups=         wireim->groups;
 
169
                    im->which_mods=     wireim->whichMods;
 
170
                    im->mods.mask=      wireim->mods;
 
171
                    im->mods.real_mods= wireim->realMods;
 
172
                    im->mods.vmods=     wireim->virtualMods;
 
173
                    im->ctrls=          wireim->ctrls;
 
174
                }
 
175
            }
 
176
        }
 
177
    }
 
178
    return Success;
 
179
}
 
180
 
 
181
static Status
 
182
#if NeedFunctionPrototypes
 
183
_XkbReadGetDeviceInfoReply(     Display *               dpy,
 
184
                                xkbGetDeviceInfoReply * rep,
 
185
                                XkbDeviceInfoPtr        devi)
 
186
#else
 
187
_XkbReadGetDeviceInfoReply(dpy,rep,devi)
 
188
    Display *                   dpy;
 
189
    xkbGetDeviceInfoReply *     rep;
 
190
    XkbDeviceInfoPtr            devi;
 
191
#endif
 
192
{
 
193
XkbReadBufferRec        buf;
 
194
XkbAction *             act;
 
195
int                     tmp;
 
196
 
 
197
    if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) 
 
198
        return BadAlloc;
 
199
 
 
200
    if ((rep->totalBtns>0)&&(rep->totalBtns!=devi->num_btns)) {
 
201
        tmp= XkbResizeDeviceButtonActions(devi,rep->totalBtns);
 
202
        if (tmp!=Success)
 
203
            return tmp;
 
204
    }
 
205
    if (rep->nBtnsWanted>0) {
 
206
        act= &devi->btn_acts[rep->firstBtnWanted];
 
207
        bzero((char *)act,(rep->nBtnsWanted*sizeof(XkbAction)));
 
208
    }
 
209
    if (devi->name!=NULL)
 
210
        _XkbFree(devi->name);
 
211
    if (!_XkbGetReadBufferCountedString(&buf,&devi->name))
 
212
        goto BAILOUT;
 
213
    if (rep->nBtnsRtrn>0) {
 
214
        int size;
 
215
        act= &devi->btn_acts[rep->firstBtnRtrn];
 
216
        size= rep->nBtnsRtrn*SIZEOF(xkbActionWireDesc);
 
217
        if (!_XkbCopyFromReadBuffer(&buf,(char *)act,size))
 
218
            goto BAILOUT;
 
219
    }
 
220
    if (rep->nDeviceLedFBs>0) {
 
221
        register int            i;
 
222
        for (i=0;i<rep->nDeviceLedFBs;i++) {
 
223
            if ((tmp= _XkbReadDeviceLedInfo(&buf,rep->present,devi))!=Success)
 
224
                return tmp;
 
225
        }
 
226
    }
 
227
    tmp= _XkbFreeReadBuffer(&buf);
 
228
    if (tmp) 
 
229
        fprintf(stderr,"GetDeviceInfo! Bad length (%d extra bytes)\n",tmp);
 
230
    if (tmp || buf.error)
 
231
        return BadLength;
 
232
    return Success;
 
233
BAILOUT:
 
234
    _XkbFreeReadBuffer(&buf);
 
235
    return BadLength;
 
236
}
 
237
 
 
238
XkbDeviceInfoPtr
 
239
#if NeedFunctionPrototypes
 
240
XkbGetDeviceInfo(       Display *       dpy,
 
241
                        unsigned        which,
 
242
                        unsigned        deviceSpec,
 
243
                        unsigned        class,
 
244
                        unsigned        id)
 
245
#else
 
246
XkbGetDeviceInfo(dpy,which,deviceSpec,class,id)
 
247
    Display *   dpy;
 
248
    unsigned    which;
 
249
    unsigned    deviceSpec;
 
250
    unsigned    class;
 
251
    unsigned    id;
 
252
#endif
 
253
{
 
254
    register xkbGetDeviceInfoReq *      req;
 
255
    xkbGetDeviceInfoReply               rep;
 
256
    Status                              status;
 
257
    XkbDeviceInfoPtr                    devi;
 
258
 
 
259
    if ((dpy->flags & XlibDisplayNoXkb) ||
 
260
        (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
 
261
        return NULL;
 
262
    LockDisplay(dpy);
 
263
    GetReq(kbGetDeviceInfo, req);
 
264
    req->reqType = dpy->xkb_info->codes->major_opcode;
 
265
    req->xkbReqType = X_kbGetDeviceInfo;
 
266
    req->deviceSpec = deviceSpec;
 
267
    req->wanted= which;
 
268
    req->allBtns= ((which&XkbXI_ButtonActionsMask)!=0);
 
269
    req->firstBtn= req->nBtns= 0;
 
270
    req->ledClass= class;
 
271
    req->ledID= id;
 
272
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
 
273
        UnlockDisplay(dpy);
 
274
        SyncHandle();
 
275
        return NULL;
 
276
    }
 
277
    devi= XkbAllocDeviceInfo(rep.deviceID,rep.totalBtns,rep.nDeviceLedFBs);
 
278
    if (devi) {
 
279
        devi->supported= rep.supported;
 
280
        devi->unsupported= rep.unsupported;
 
281
        devi->type= rep.devType;
 
282
        devi->has_own_state= rep.hasOwnState;
 
283
        devi->dflt_kbd_fb = rep.dfltKbdFB;
 
284
        devi->dflt_led_fb = rep.dfltLedFB;
 
285
        status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi);
 
286
        if (status!=Success) {
 
287
            XkbFreeDeviceInfo(devi,XkbXI_AllDeviceFeaturesMask,True);
 
288
            devi= NULL;
 
289
        }
 
290
    }
 
291
    UnlockDisplay(dpy);
 
292
    SyncHandle();
 
293
    return devi;
 
294
}
 
295
 
 
296
Status
 
297
#if NeedFunctionPrototypes
 
298
XkbGetDeviceInfoChanges(        Display *               dpy,
 
299
                                XkbDeviceInfoPtr        devi,
 
300
                                XkbDeviceChangesPtr     changes)
 
301
#else
 
302
XkbGetDeviceInfoChanges(dpy,devi,changes)
 
303
    Display *           dpy;
 
304
    XkbDeviceInfoPtr    devi;
 
305
    XkbDeviceChangesPtr changes;
 
306
#endif
 
307
{
 
308
    register xkbGetDeviceInfoReq *      req;
 
309
    xkbGetDeviceInfoReply               rep;
 
310
    Status                              status;
 
311
 
 
312
    if ((dpy->flags & XlibDisplayNoXkb) ||
 
313
        (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
 
314
        return BadMatch;
 
315
    if ((changes->changed&XkbXI_AllDeviceFeaturesMask)==0)
 
316
        return Success;
 
317
    changes->changed&= ~XkbXI_AllDeviceFeaturesMask;
 
318
    status= Success;
 
319
    LockDisplay(dpy);
 
320
    while ((changes->changed)&&(status==Success)) {
 
321
        GetReq(kbGetDeviceInfo, req);
 
322
        req->reqType = dpy->xkb_info->codes->major_opcode;
 
323
        req->xkbReqType = X_kbGetDeviceInfo;
 
324
        req->deviceSpec = devi->device_spec;
 
325
        req->wanted= changes->changed;
 
326
        req->allBtns= False;
 
327
        if (changes->changed&XkbXI_ButtonActionsMask) {
 
328
             req->firstBtn= changes->first_btn;
 
329
             req->nBtns=        changes->num_btns;
 
330
             changes->changed&= ~XkbXI_ButtonActionsMask;
 
331
        }
 
332
        else req->firstBtn= req->nBtns= 0;
 
333
        if (changes->changed&XkbXI_IndicatorsMask) {
 
334
            req->ledClass= changes->leds.led_class;
 
335
            req->ledID= changes->leds.led_id;
 
336
            if (changes->leds.next==NULL)
 
337
                changes->changed&= ~XkbXI_IndicatorsMask;
 
338
            else {
 
339
                XkbDeviceLedChangesPtr next;
 
340
                next= changes->leds.next;
 
341
                changes->leds= *next;
 
342
                _XkbFree(next);
 
343
            }
 
344
        }
 
345
        else {
 
346
            req->ledClass= XkbDfltXIClass;
 
347
            req->ledID= XkbDfltXIId;
 
348
        }
 
349
        if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
 
350
            status= BadLength;
 
351
            break;
 
352
        }
 
353
        devi->supported|= rep.supported;
 
354
        devi->unsupported|= rep.unsupported;
 
355
        devi->type= rep.devType;
 
356
        status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi);
 
357
    }
 
358
    UnlockDisplay(dpy);
 
359
    SyncHandle();
 
360
    return status;
 
361
}
 
362
 
 
363
Status
 
364
#if NeedFunctionPrototypes
 
365
XkbGetDeviceButtonActions(      Display *               dpy,
 
366
                                XkbDeviceInfoPtr        devi,
 
367
                                Bool                    all,
 
368
                                unsigned int            first,
 
369
                                unsigned int            num)
 
370
#else
 
371
XkbGetDeviceButtonActions(dpy,devi,all,first,num)
 
372
    Display *           dpy;
 
373
    XkbDeviceInfoPtr    devi;
 
374
    Bool                all;
 
375
    unsigned int        first;
 
376
    unsigned int        num;
 
377
#endif
 
378
{
 
379
    register xkbGetDeviceInfoReq *      req;
 
380
    xkbGetDeviceInfoReply               rep;
 
381
    Status                              status;
 
382
 
 
383
    if ((dpy->flags & XlibDisplayNoXkb) || 
 
384
        (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
 
385
        return BadMatch;
 
386
    if (!devi)
 
387
        return BadValue;
 
388
    LockDisplay(dpy);
 
389
    GetReq(kbGetDeviceInfo, req);
 
390
    req->reqType = dpy->xkb_info->codes->major_opcode;
 
391
    req->xkbReqType = X_kbGetDeviceInfo;
 
392
    req->deviceSpec = devi->device_spec;
 
393
    req->wanted= XkbXI_ButtonActionsMask;
 
394
    req->allBtns= all;
 
395
    req->firstBtn= first;
 
396
    req->nBtns= num;
 
397
    req->ledClass= XkbDfltXIClass;
 
398
    req->ledID= XkbDfltXIId;
 
399
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
 
400
        UnlockDisplay(dpy);
 
401
        SyncHandle();
 
402
        return BadLength;
 
403
    }
 
404
    devi->type= rep.devType;
 
405
    devi->supported= rep.supported;
 
406
    devi->unsupported= rep.unsupported;
 
407
    status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi);
 
408
    UnlockDisplay(dpy);
 
409
    SyncHandle();
 
410
    return status;
 
411
}
 
412
 
 
413
Status
 
414
#if NeedFunctionPrototypes
 
415
XkbGetDeviceLedInfo(    Display *               dpy,
 
416
                        XkbDeviceInfoPtr        devi,
 
417
                        unsigned int            ledClass,
 
418
                        unsigned int            ledId,
 
419
                        unsigned int            which)
 
420
#else
 
421
XkbGetDeviceLedInfo(dpy,devi,ledClass,ledId,which)
 
422
    Display *           dpy;
 
423
    XkbDeviceInfoPtr    devi;
 
424
    unsigned int        ledClass;
 
425
    unsigned int        ledId;
 
426
    unsigned int        which;
 
427
#endif
 
428
{
 
429
    register xkbGetDeviceInfoReq *      req;
 
430
    xkbGetDeviceInfoReply               rep;
 
431
    Status                              status;
 
432
 
 
433
    if ((dpy->flags & XlibDisplayNoXkb) || 
 
434
        (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
 
435
        return BadMatch;
 
436
    if (((which&XkbXI_IndicatorsMask)==0)||(which&(~XkbXI_IndicatorsMask)))
 
437
        return BadMatch;
 
438
    if (!devi)
 
439
        return BadValue;
 
440
    LockDisplay(dpy);
 
441
    GetReq(kbGetDeviceInfo, req);
 
442
    req->reqType = dpy->xkb_info->codes->major_opcode;
 
443
    req->xkbReqType = X_kbGetDeviceInfo;
 
444
    req->deviceSpec = devi->device_spec;
 
445
    req->wanted= which;
 
446
    req->allBtns= False;
 
447
    req->firstBtn= req->nBtns= 0;
 
448
    req->ledClass= ledClass;
 
449
    req->ledID= ledId;
 
450
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
 
451
        UnlockDisplay(dpy);
 
452
        SyncHandle();
 
453
        return BadLength;
 
454
    } 
 
455
    devi->type= rep.devType;
 
456
    devi->supported= rep.supported;
 
457
    devi->unsupported= rep.unsupported;
 
458
    status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi);
 
459
    UnlockDisplay(dpy);
 
460
    SyncHandle();
 
461
    return status;
 
462
}
 
463
 
 
464
/***====================================================================***/
 
465
 
 
466
typedef struct _LedInfoStuff {
 
467
        Bool                    used;
 
468
        XkbDeviceLedInfoPtr     devli;
 
469
} LedInfoStuff;
 
470
 
 
471
typedef struct _SetLedStuff {
 
472
        unsigned                wanted;
 
473
        int                     num_info;
 
474
        int                     dflt_class;
 
475
        LedInfoStuff *          dflt_kbd_fb;
 
476
        LedInfoStuff *          dflt_led_fb;
 
477
        LedInfoStuff *          info;
 
478
} SetLedStuff;
 
479
 
 
480
static void
 
481
#if NeedFunctionPrototypes
 
482
_InitLedStuff(SetLedStuff *stuff,unsigned wanted,XkbDeviceInfoPtr devi)
 
483
#else
 
484
_InitLedStuff(stuff,wanted,devi)
 
485
    SetLedStuff  *      stuff;
 
486
    unsigned            wanted;
 
487
    XkbDeviceInfoPtr    devi;
 
488
#endif
 
489
{
 
490
int                             i;
 
491
register XkbDeviceLedInfoPtr    devli;
 
492
 
 
493
    bzero(stuff,sizeof(SetLedStuff));
 
494
    stuff->wanted= wanted;
 
495
    stuff->dflt_class=  XkbXINone;
 
496
    if ((devi->num_leds<1)||((wanted&XkbXI_IndicatorsMask)==0))
 
497
        return;
 
498
    stuff->info= _XkbTypedCalloc(devi->num_leds,LedInfoStuff);
 
499
    if (!stuff->info)
 
500
        return;
 
501
    stuff->num_info= devi->num_leds;
 
502
    for (devli=&devi->leds[0],i=0;i<devi->num_leds;i++,devli++) {
 
503
        stuff->info[i].devli= devli;
 
504
        if (devli->led_class==KbdFeedbackClass) {
 
505
            stuff->dflt_class= KbdFeedbackClass;
 
506
            if (stuff->dflt_kbd_fb==NULL)
 
507
                stuff->dflt_kbd_fb= &stuff->info[i];
 
508
        }
 
509
        else if (devli->led_class==LedFeedbackClass) {
 
510
            if (stuff->dflt_class==XkbXINone)
 
511
                stuff->dflt_class= LedFeedbackClass;
 
512
            if (stuff->dflt_led_fb==NULL)
 
513
                stuff->dflt_led_fb= &stuff->info[i];
 
514
        }
 
515
    }
 
516
    return;
 
517
}
 
518
 
 
519
static void
 
520
#if NeedFunctionPrototypes
 
521
_FreeLedStuff(SetLedStuff *stuff)
 
522
#else
 
523
_FreeLedStuff(stuff)
 
524
    SetLedStuff *stuff;
 
525
#endif
 
526
{
 
527
    if ((stuff->num_info>0)&&(stuff->info!=NULL))
 
528
        _XkbFree(stuff->info);
 
529
    bzero(stuff,sizeof(SetLedStuff));
 
530
    return;
 
531
}
 
532
 
 
533
static int
 
534
#if NeedFunctionPrototypes
 
535
_XkbSizeLedInfo(unsigned changed,XkbDeviceLedInfoPtr devli)
 
536
#else
 
537
_XkbSizeLedInfo(changed,devli)
 
538
    unsigned            changed;
 
539
    XkbDeviceLedInfoPtr devli;
 
540
#endif
 
541
{
 
542
register int i,size;
 
543
register unsigned bit,namesNeeded,mapsNeeded;
 
544
 
 
545
    size= SIZEOF(xkbDeviceLedsWireDesc);
 
546
    namesNeeded= mapsNeeded= 0;
 
547
    if (changed&XkbXI_IndicatorNamesMask)
 
548
        namesNeeded= devli->names_present;
 
549
    if (changed&XkbXI_IndicatorMapsMask)
 
550
        mapsNeeded= devli->maps_present;
 
551
    if ((namesNeeded)||(mapsNeeded)) {
 
552
        for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
 
553
            if (namesNeeded&bit)
 
554
                size+= 4; /* atoms are 4 bytes on the wire */
 
555
            if (mapsNeeded&bit)
 
556
                size+= SIZEOF(xkbIndicatorMapWireDesc);
 
557
        }
 
558
    }
 
559
    return size;
 
560
}
 
561
 
 
562
static Bool
 
563
#if NeedFunctionPrototypes
 
564
_SizeMatches(   SetLedStuff *           stuff,
 
565
                XkbDeviceLedChangesPtr  changes,
 
566
                int *                   sz_rtrn,
 
567
                int *                   nleds_rtrn)
 
568
#else
 
569
_SizeMatches(stuff,changes,sz_rtrn,nleds_rtrn)
 
570
    SetLedStuff *               stuff;
 
571
    XkbDeviceLedChangesPtr      changes;
 
572
    int *                       sz_rtrn;
 
573
    int *                       nleds_rtrn;
 
574
#endif
 
575
{
 
576
int             i,nMatch,class,id;
 
577
LedInfoStuff *  linfo;
 
578
Bool            match;
 
579
 
 
580
    nMatch= 0;
 
581
    class= changes->led_class;
 
582
    id= changes->led_id;
 
583
    if (class==XkbDfltXIClass)
 
584
        class= stuff->dflt_class;
 
585
    for (i=0,linfo=&stuff->info[0];i<stuff->num_info;i++,linfo++) {
 
586
        XkbDeviceLedInfoPtr     devli;
 
587
        LedInfoStuff *          dflt;
 
588
 
 
589
        devli= linfo->devli;
 
590
        match= ((class==devli->led_class)||(class==XkbAllXIClasses));
 
591
        if (devli->led_class==KbdFeedbackClass) dflt= stuff->dflt_kbd_fb;
 
592
        else                                    dflt= stuff->dflt_led_fb;
 
593
        match = (match && (id == devli->led_id)) ||
 
594
          (id == XkbAllXIIds) ||
 
595
          ((id == XkbDfltXIId) &&
 
596
           (linfo == dflt));
 
597
        if (match) {
 
598
            if (!linfo->used) {
 
599
                *sz_rtrn+= _XkbSizeLedInfo(stuff->wanted,devli);
 
600
                *nleds_rtrn+= 1;
 
601
                linfo->used= True;
 
602
                if ((class!=XkbAllXIClasses)&&(id!=XkbAllXIIds))
 
603
                    return True;
 
604
            }
 
605
            nMatch++;
 
606
            linfo->used= True;
 
607
        }
 
608
    }
 
609
    return (nMatch>0);
 
610
}
 
611
 
 
612
/***====================================================================***/
 
613
 
 
614
 
 
615
static Status
 
616
#if NeedFunctionPrototypes
 
617
_XkbSetDeviceInfoSize(  XkbDeviceInfoPtr        devi,
 
618
                        XkbDeviceChangesPtr     changes,
 
619
                        SetLedStuff *           stuff,
 
620
                        int *                   sz_rtrn,
 
621
                        int *                   num_leds_rtrn)
 
622
#else
 
623
_XkbSetDeviceInfoSize(devi,changes,stuff,sz_rtrn,num_leds_rtrn)
 
624
    XkbDeviceInfoPtr    devi;
 
625
    XkbDeviceChangesPtr changes;
 
626
    SetLedStuff *       stuff;
 
627
    int *               sz_rtrn;
 
628
    int *               num_leds_rtrn;
 
629
#endif
 
630
{
 
631
    *sz_rtrn= 0;
 
632
    if ((changes->changed&XkbXI_ButtonActionsMask)&&(changes->num_btns>0)) {
 
633
        if (!XkbXI_LegalDevBtn(devi,(changes->first_btn+changes->num_btns-1)))
 
634
            return BadMatch;
 
635
        *sz_rtrn+= changes->num_btns*SIZEOF(xkbActionWireDesc);
 
636
    }
 
637
    else {
 
638
        changes->changed&= ~XkbXI_ButtonActionsMask;
 
639
        changes->first_btn= changes->num_btns= 0;
 
640
    }
 
641
    if ((changes->changed&XkbXI_IndicatorsMask)&&
 
642
                                XkbLegalXILedClass(changes->leds.led_class)) {
 
643
        XkbDeviceLedChangesPtr  leds;
 
644
 
 
645
        for (leds=&changes->leds;leds!=NULL;leds= leds->next) {
 
646
            if (!_SizeMatches(stuff,leds,sz_rtrn,num_leds_rtrn))
 
647
                return BadMatch;
 
648
        }
 
649
    }
 
650
    else {
 
651
        changes->changed&= ~XkbXI_IndicatorsMask;
 
652
        *num_leds_rtrn= 0;
 
653
    }
 
654
    return Success;
 
655
}
 
656
 
 
657
static char *
 
658
#if NeedFunctionPrototypes
 
659
_XkbWriteLedInfo(char *wire,unsigned changed,XkbDeviceLedInfoPtr devli)
 
660
#else
 
661
_XkbWriteLedInfo(wire,changed,devli)
 
662
    char *                      wire;
 
663
    unsigned                    changed;
 
664
    XkbDeviceLedInfoPtr         devli;
 
665
#endif
 
666
{
 
667
register int            i;
 
668
register unsigned       bit,namesNeeded,mapsNeeded;
 
669
xkbDeviceLedsWireDesc * lwire;
 
670
 
 
671
    namesNeeded= mapsNeeded= 0;
 
672
    if (changed&XkbXI_IndicatorNamesMask)
 
673
        namesNeeded= devli->names_present;
 
674
    if (changed&XkbXI_IndicatorMapsMask)
 
675
        mapsNeeded= devli->maps_present;
 
676
 
 
677
    lwire= (xkbDeviceLedsWireDesc *)wire;
 
678
    lwire->ledClass= devli->led_class;
 
679
    lwire->ledID= devli->led_id;
 
680
    lwire->namesPresent= namesNeeded;
 
681
    lwire->mapsPresent=  mapsNeeded;
 
682
    lwire->physIndicators= devli->phys_indicators;
 
683
    lwire->state= devli->state;
 
684
    wire= (char *)&lwire[1];
 
685
    if (namesNeeded) {
 
686
        CARD32 *awire;
 
687
        awire= (CARD32 *)wire;
 
688
        for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
 
689
            if (namesNeeded&bit) {
 
690
                *awire= (CARD32)devli->names[i];
 
691
                awire++;
 
692
            }
 
693
        }
 
694
        wire= (char *)awire;
 
695
    }
 
696
    if (mapsNeeded) {
 
697
        xkbIndicatorMapWireDesc *mwire;
 
698
 
 
699
        mwire= (xkbIndicatorMapWireDesc *)wire;
 
700
        for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
 
701
            if (mapsNeeded&bit) {
 
702
                XkbIndicatorMapPtr      map;
 
703
                map=                    &devli->maps[i];
 
704
                mwire->flags=           map->flags;
 
705
                mwire->whichGroups=     map->which_groups;
 
706
                mwire->groups=          map->groups;
 
707
                mwire->whichMods=       map->which_mods;
 
708
                mwire->mods=            map->mods.mask;
 
709
                mwire->realMods=        map->mods.real_mods;
 
710
                mwire->virtualMods=     map->mods.vmods;
 
711
                mwire->ctrls=           map->ctrls;
 
712
                mwire++;
 
713
            }
 
714
        }
 
715
        wire= (char *)mwire;
 
716
    }
 
717
    return wire;
 
718
}
 
719
 
 
720
 
 
721
static int
 
722
#if NeedFunctionPrototypes
 
723
_XkbWriteSetDeviceInfo( char *                  wire,
 
724
                        XkbDeviceChangesPtr     changes,
 
725
                        SetLedStuff *           stuff,
 
726
                        XkbDeviceInfoPtr        devi)
 
727
#else
 
728
_XkbWriteSetDeviceInfo(wire,changes,stuff,devi)
 
729
    char *                      wire;
 
730
    XkbDeviceChangesPtr         changes;
 
731
    SetLedStuff *               stuff;
 
732
    XkbDeviceInfoPtr            devi;
 
733
#endif
 
734
{
 
735
char *start;
 
736
 
 
737
    start= wire;
 
738
    if (changes->changed&XkbXI_ButtonActionsMask) {
 
739
        int                     size;
 
740
        size= changes->num_btns*SIZEOF(xkbActionWireDesc);
 
741
        memcpy(wire,(char *)&devi->btn_acts[changes->first_btn],size);
 
742
        wire+= size;
 
743
    }
 
744
    if (changes->changed&XkbXI_IndicatorsMask) {
 
745
        register int i;
 
746
        register LedInfoStuff *linfo;
 
747
 
 
748
        for (i=0,linfo=&stuff->info[0];i<stuff->num_info;i++,linfo++) {
 
749
            if (linfo->used) {
 
750
                register char *new_wire;
 
751
                new_wire= _XkbWriteLedInfo(wire,stuff->wanted,linfo->devli);
 
752
                if (!new_wire)
 
753
                    return wire-start;
 
754
                wire= new_wire;
 
755
            }
 
756
        }
 
757
    }
 
758
    return wire-start;
 
759
}
 
760
 
 
761
Bool
 
762
#if NeedFunctionPrototypes
 
763
XkbSetDeviceInfo(       Display *               dpy,
 
764
                        unsigned                which,
 
765
                        XkbDeviceInfoPtr        devi)
 
766
#else
 
767
XkbSetDeviceInfo(dpy,which,devi)
 
768
    Display *           dpy;
 
769
    unsigned            which;
 
770
    XkbDeviceInfoPtr    devi;
 
771
#endif
 
772
{
 
773
    register xkbSetDeviceInfoReq *req;
 
774
    Status                      ok = 0;
 
775
    int                         size,nLeds;
 
776
    XkbInfoPtr                  xkbi;
 
777
    XkbDeviceChangesRec         changes;
 
778
    SetLedStuff                 lstuff;
 
779
 
 
780
    if ((dpy->flags & XlibDisplayNoXkb) ||
 
781
        (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
 
782
        return False;
 
783
    if ((!devi) || (which&(~XkbXI_AllDeviceFeaturesMask)) ||
 
784
        ((which&XkbXI_ButtonActionsMask)&&(!XkbXI_DevHasBtnActs(devi)))||
 
785
        ((which&XkbXI_IndicatorsMask)&&(!XkbXI_DevHasLeds(devi))))
 
786
        return False;
 
787
 
 
788
    bzero((char *)&changes,sizeof(XkbDeviceChangesRec));
 
789
    changes.changed= which;
 
790
    changes.first_btn=          0;
 
791
    changes.num_btns=           devi->num_btns;
 
792
    changes.leds.led_class=     XkbAllXIClasses;
 
793
    changes.leds.led_id=        XkbAllXIIds;
 
794
    changes.leds.defined=       0;
 
795
    size= nLeds=                0;
 
796
    _InitLedStuff(&lstuff,changes.changed,devi);
 
797
    if (_XkbSetDeviceInfoSize(devi,&changes,&lstuff,&size,&nLeds)!=Success)
 
798
        return False;
 
799
    LockDisplay(dpy);
 
800
    xkbi = dpy->xkb_info;
 
801
    GetReq(kbSetDeviceInfo, req);
 
802
    req->length+=       size/4;
 
803
    req->reqType=       xkbi->codes->major_opcode;
 
804
    req->xkbReqType=    X_kbSetDeviceInfo;
 
805
    req->deviceSpec=    devi->device_spec;
 
806
    req->firstBtn=      changes.first_btn;
 
807
    req->nBtns=         changes.num_btns;
 
808
    req->change=        changes.changed;
 
809
    req->nDeviceLedFBs= nLeds;
 
810
    if (size>0) {
 
811
        char *  wire;
 
812
        BufAlloc(char *,wire,size);
 
813
        ok= (wire!=NULL)&&
 
814
                (_XkbWriteSetDeviceInfo(wire,&changes,&lstuff,devi)==size);
 
815
    }
 
816
    UnlockDisplay(dpy);
 
817
    SyncHandle();
 
818
    _FreeLedStuff(&lstuff);
 
819
    /* 12/11/95 (ef) -- XXX!! should clear changes here */
 
820
    return ok;
 
821
}
 
822
 
 
823
Bool
 
824
#if NeedFunctionPrototypes
 
825
XkbChangeDeviceInfo(    Display *               dpy,
 
826
                        XkbDeviceInfoPtr        devi,
 
827
                        XkbDeviceChangesPtr     changes)
 
828
#else
 
829
XkbChangeDeviceInfo(dpy,devi,changes)
 
830
    Display *           dpy;
 
831
    XkbDeviceInfoPtr    devi;
 
832
    XkbDeviceChangesPtr changes;
 
833
#endif
 
834
{
 
835
    register xkbSetDeviceInfoReq *req;
 
836
    Status                      ok = 0;
 
837
    int                         size,nLeds;
 
838
    XkbInfoPtr                  xkbi;
 
839
    SetLedStuff                 lstuff;
 
840
 
 
841
    if ((dpy->flags & XlibDisplayNoXkb) ||
 
842
        (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
 
843
        return False;
 
844
    if ((!devi) || (changes->changed&(~XkbXI_AllDeviceFeaturesMask)) ||
 
845
        ((changes->changed&XkbXI_ButtonActionsMask)&&
 
846
                                        (!XkbXI_DevHasBtnActs(devi)))||
 
847
        ((changes->changed&XkbXI_IndicatorsMask)&&(!XkbXI_DevHasLeds(devi))))
 
848
        return False;
 
849
 
 
850
    size= nLeds= 0;
 
851
    _InitLedStuff(&lstuff,changes->changed,devi);
 
852
    if (_XkbSetDeviceInfoSize(devi,changes,&lstuff,&size,&nLeds)!=Success)
 
853
        return False;
 
854
    LockDisplay(dpy);
 
855
    xkbi = dpy->xkb_info;
 
856
    GetReq(kbSetDeviceInfo, req);
 
857
    req->length+=       size/4;
 
858
    req->reqType=       xkbi->codes->major_opcode;
 
859
    req->xkbReqType=    X_kbSetDeviceInfo;
 
860
    req->deviceSpec=    devi->device_spec;
 
861
    req->firstBtn=      changes->first_btn;
 
862
    req->nBtns=         changes->num_btns;
 
863
    req->change=        changes->changed;
 
864
    req->nDeviceLedFBs= nLeds;
 
865
    if (size>0) {
 
866
        char *  wire;
 
867
        BufAlloc(char *,wire,size);
 
868
        ok= (wire!=NULL)&&
 
869
                (_XkbWriteSetDeviceInfo(wire,changes,&lstuff,devi)==size);
 
870
    }
 
871
    UnlockDisplay(dpy);
 
872
    SyncHandle();
 
873
    _FreeLedStuff(&lstuff);
 
874
    /* 12/11/95 (ef) -- XXX!! should clear changes here */
 
875
    return ok;
 
876
}
 
877
 
 
878
Bool 
 
879
#if NeedFunctionPrototypes
 
880
XkbSetDeviceLedInfo(    Display *               dpy,
 
881
                        XkbDeviceInfoPtr        devi,
 
882
                        unsigned                ledClass,
 
883
                        unsigned                ledID,
 
884
                        unsigned                which)
 
885
#else
 
886
XkbSetDeviceLedInfo(dpy,devi,ledClass,ledID,which)
 
887
    Display *           dpy;
 
888
    XkbDeviceInfoPtr    devi;
 
889
    unsigned            ledClass;
 
890
    unsigned            ledID;
 
891
    unsigned            which;
 
892
#endif
 
893
{
 
894
    return False;
 
895
}
 
896
 
 
897
Bool 
 
898
#if NeedFunctionPrototypes
 
899
XkbSetDeviceButtonActions(      Display *               dpy,
 
900
                                XkbDeviceInfoPtr        devi,
 
901
                                unsigned int            first,
 
902
                                unsigned int            nBtns)
 
903
#else
 
904
XkbSetDeviceButtonActions(dpy,devi,first,nBtns)
 
905
        Display *               dpy;
 
906
        XkbDeviceInfoPtr        devi;
 
907
        unsigned int            first;
 
908
        unsigned int            nBtns;
 
909
#endif
 
910
{
 
911
    register xkbSetDeviceInfoReq *req;
 
912
    Status                      ok = 0;
 
913
    int                         size,nLeds;
 
914
    XkbInfoPtr                  xkbi;
 
915
    XkbDeviceChangesRec         changes;
 
916
    SetLedStuff                 lstuff;
 
917
 
 
918
    if ((dpy->flags & XlibDisplayNoXkb) ||
 
919
        (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
 
920
        return False;
 
921
    if ((!devi)||(!XkbXI_DevHasBtnActs(devi))||(first+nBtns>devi->num_btns))
 
922
        return False;
 
923
    if (nBtns==0)
 
924
        return True;
 
925
 
 
926
    bzero((char *)&changes,sizeof(XkbDeviceChangesRec));
 
927
    changes.changed=            XkbXI_ButtonActionsMask;
 
928
    changes.first_btn=          first;
 
929
    changes.num_btns=           nBtns;
 
930
    changes.leds.led_class=     XkbXINone;
 
931
    changes.leds.led_id=        XkbXINone;
 
932
    changes.leds.defined=       0;
 
933
    size= nLeds=                0;
 
934
    if (_XkbSetDeviceInfoSize(devi,&changes,NULL,&size,&nLeds)!=Success)
 
935
        return False;
 
936
    LockDisplay(dpy);
 
937
    xkbi = dpy->xkb_info;
 
938
    GetReq(kbSetDeviceInfo, req);
 
939
    req->length+=       size/4;
 
940
    req->reqType=       xkbi->codes->major_opcode;
 
941
    req->xkbReqType=    X_kbSetDeviceInfo;
 
942
    req->deviceSpec=    devi->device_spec;
 
943
    req->firstBtn=      changes.first_btn;
 
944
    req->nBtns=         changes.num_btns;
 
945
    req->change=        changes.changed;
 
946
    req->nDeviceLedFBs= nLeds;
 
947
    if (size>0) {
 
948
        char *  wire;
 
949
        BufAlloc(char *,wire,size);
 
950
        ok= (wire!=NULL)&&
 
951
                (_XkbWriteSetDeviceInfo(wire,&changes,&lstuff,devi)==size);
 
952
    }
 
953
    UnlockDisplay(dpy);
 
954
    SyncHandle();
 
955
    return ok;
 
956
}