Initialize Tizen 2.3
[framework/uifw/xorg/lib/libx11.git] / src / xkb / XKBNames.c
1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27 #define NEED_MAP_READERS
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include "Xlibint.h"
32 #include <X11/extensions/XKBproto.h>
33 #include "XKBlibint.h"
34
35
36 static Status
37 _XkbReadAtoms(  XkbReadBufferPtr        buf,
38                 Atom *                  atoms,
39                 int                     maxAtoms,
40                 CARD32                  present)
41 {
42 register int i,bit;
43
44     for (i=0,bit=1;(i<maxAtoms)&&(present);i++,bit<<=1) {
45         if (present&bit) {
46             if (!_XkbReadBufferCopy32(buf,(long *)&atoms[i],1))
47                 return BadLength;
48             present&= ~bit;
49         }
50     }
51     return Success;
52 }
53
54 Status
55 _XkbReadGetNamesReply(  Display *               dpy,
56                         xkbGetNamesReply *      rep,
57                         XkbDescPtr              xkb,
58                         int *                   nread_rtrn)
59 {
60     int                          i,len;
61     XkbReadBufferRec             buf;
62     register XkbNamesPtr         names;
63
64     if ( xkb->device_spec == XkbUseCoreKbd )
65         xkb->device_spec = rep->deviceID;
66
67     if ((xkb->names==NULL)&&
68         (XkbAllocNames(xkb,rep->which,
69                                 rep->nRadioGroups,rep->nKeyAliases)!=Success)) {
70         return BadAlloc;
71     }
72     names= xkb->names;
73     if (rep->length==0)
74         return Success;
75
76     if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4))
77         return BadAlloc;
78     if (nread_rtrn)
79         *nread_rtrn= (int)rep->length*4;
80
81     if ((rep->which&XkbKeycodesNameMask)&&
82         (!_XkbReadBufferCopy32(&buf,(long *)&names->keycodes,1)))
83             goto BAILOUT;
84     if ((rep->which&XkbGeometryNameMask)&&
85         (!_XkbReadBufferCopy32(&buf,(long *)&names->geometry,1)))
86             goto BAILOUT;
87     if ((rep->which&XkbSymbolsNameMask)&&
88         (!_XkbReadBufferCopy32(&buf,(long *)&names->symbols,1)))
89             goto BAILOUT;
90     if ((rep->which&XkbPhysSymbolsNameMask)&&
91         (!_XkbReadBufferCopy32(&buf,(long *)&names->phys_symbols,1)))
92             goto BAILOUT;
93     if ((rep->which&XkbTypesNameMask)&&
94         (!_XkbReadBufferCopy32(&buf,(long *)&names->types,1)))
95             goto BAILOUT;
96     if ((rep->which&XkbCompatNameMask)&&
97         (!_XkbReadBufferCopy32(&buf,(long *)&names->compat,1)))
98             goto BAILOUT;
99
100     if ( rep->which & XkbKeyTypeNamesMask ) {
101         XkbClientMapPtr map= xkb->map;
102         XkbKeyTypePtr   type;
103
104         len= rep->nTypes*4;
105         if (map!=NULL) {
106             type= map->types;
107             for (i=0;(i<map->num_types)&&(i<rep->nTypes);i++,type++) {
108                 if (!_XkbReadBufferCopy32(&buf,(long *)&type->name,1))
109                     goto BAILOUT;
110                 len-= 4;
111             }
112         }
113         if ((len>0)&&(!_XkbSkipReadBufferData(&buf,len)))
114             goto BAILOUT;
115     }
116     if ( rep->which&XkbKTLevelNamesMask ) {
117         CARD8 *nLevels;
118         XkbClientMapPtr map= xkb->map;
119         XkbKeyTypePtr   type;
120
121         nLevels=(CARD8*)_XkbGetReadBufferPtr(&buf,XkbPaddedSize(rep->nTypes));
122         if (nLevels==NULL)
123             goto BAILOUT;
124         if (map!=NULL) {
125             type= map->types;
126             for (i=0;i<(int)rep->nTypes;i++,type++) {
127                 if (i>=map->num_types) {
128                     if (!_XkbSkipReadBufferData(&buf,nLevels[i]*4))
129                         goto BAILOUT;
130                     continue;
131                 }
132                 if ((nLevels[i]>0)&&(nLevels[i]!=type->num_levels)) {
133                     goto BAILOUT;
134                 }
135                 if (type->level_names!=NULL)
136                     Xfree(type->level_names);
137                 if (nLevels[i]==0) {
138                     type->level_names= NULL;
139                     continue;
140                 }
141                 type->level_names= _XkbTypedCalloc(nLevels[i],Atom);
142                 if (type->level_names!=NULL) {
143                     if (!_XkbReadBufferCopy32(&buf,(long *)type->level_names,
144                                                                 nLevels[i]))
145                         goto BAILOUT;
146                 }
147                 else {
148                     _XkbSkipReadBufferData(&buf,nLevels[i]*4);
149                 }
150             }
151         }
152         else {
153             for (i=0;i<(int)rep->nTypes;i++) {
154                 _XkbSkipReadBufferData(&buf,nLevels[i]*4);
155             }
156         }
157     }
158     if (rep->which & XkbIndicatorNamesMask) {
159         if (_XkbReadAtoms(&buf,names->indicators,XkbNumIndicators,
160                                                 rep->indicators)!=Success)
161             goto BAILOUT;
162     }
163     if ( rep->which&XkbVirtualModNamesMask ) {
164         if (_XkbReadAtoms(&buf,names->vmods,XkbNumVirtualMods,
165                                         (CARD32)rep->virtualMods)!=Success)
166             goto BAILOUT;
167     }
168     if ( rep->which&XkbGroupNamesMask ) {
169         if (_XkbReadAtoms(&buf,names->groups,XkbNumKbdGroups,
170                                         (CARD32)rep->groupNames)!=Success)
171             goto BAILOUT;
172     }
173     if ( rep->which&XkbKeyNamesMask ) {
174         if (names->keys==NULL) {
175             int nKeys;
176             if (xkb->max_key_code==0) {
177                 xkb->min_key_code= rep->minKeyCode;
178                 xkb->max_key_code= rep->maxKeyCode;
179             }
180             nKeys= xkb->max_key_code+1;
181             names->keys= _XkbTypedCalloc(nKeys,XkbKeyNameRec);
182         }
183         if (names->keys!=NULL) {
184             if (!_XkbCopyFromReadBuffer(&buf,
185                                         (char *)&names->keys[rep->firstKey],
186                                         rep->nKeys*XkbKeyNameLength))
187                 goto BAILOUT;
188         }
189         else _XkbSkipReadBufferData(&buf,rep->nKeys*XkbKeyNameLength);
190     }
191     if ( rep->which&XkbKeyAliasesMask && (rep->nKeyAliases>0) ) {
192         if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,rep->nKeyAliases)!=Success)
193             goto BAILOUT;
194         if (!_XkbCopyFromReadBuffer(&buf,(char *)names->key_aliases,
195                                 rep->nKeyAliases*XkbKeyNameLength*2))
196             goto BAILOUT;
197     }
198     if ( rep->which&XkbRGNamesMask ) {
199         if (rep->nRadioGroups>0) {
200             Atom *rgNames;
201
202             if (names->radio_groups==NULL)
203                 names->radio_groups = _XkbTypedCalloc(rep->nRadioGroups,Atom);
204             else if (names->num_rg<rep->nRadioGroups) {
205                 names->radio_groups = _XkbTypedRealloc(names->radio_groups,
206                                                         rep->nRadioGroups,
207                                                         Atom);
208             }
209             rgNames= names->radio_groups;
210             if (!rgNames) {
211                 goto BAILOUT;
212             }
213             if (!_XkbReadBufferCopy32(&buf,(long *)rgNames,rep->nRadioGroups))
214                 goto BAILOUT;
215             names->num_rg= rep->nRadioGroups;
216         }
217         else if (names->num_rg>0) {
218             names->num_rg= 0;
219             Xfree(names->radio_groups);
220         }
221     }
222     len= _XkbFreeReadBuffer(&buf);
223     if (len!=0)         return BadLength;
224     else                return Success;
225 BAILOUT:
226     _XkbFreeReadBuffer(&buf);
227     return BadLength;
228 }
229
230 Status
231 XkbGetNames(Display *dpy,unsigned which,XkbDescPtr xkb)
232 {
233     register xkbGetNamesReq *req;
234     xkbGetNamesReply         rep;
235     Status                   status;
236     XkbInfoPtr xkbi;
237
238     if ((dpy->flags & XlibDisplayNoXkb) ||
239         (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
240         return BadAccess;
241     LockDisplay(dpy);
242     xkbi = dpy->xkb_info;
243     if (!xkb->names) {
244         xkb->names = _XkbTypedCalloc(1,XkbNamesRec);
245         if (!xkb->names) {
246             UnlockDisplay(dpy);
247             SyncHandle();
248             return BadAlloc;
249         }
250     }
251     GetReq(kbGetNames, req);
252     req->reqType = xkbi->codes->major_opcode;
253     req->xkbReqType = X_kbGetNames;
254     req->deviceSpec = xkb->device_spec;
255     req->which = which;
256     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
257         UnlockDisplay(dpy);
258         SyncHandle();
259         return BadImplementation;
260     }
261
262     status = _XkbReadGetNamesReply(dpy,&rep,xkb,NULL);
263     UnlockDisplay(dpy);
264     SyncHandle();
265     return status;
266 }
267
268 /***====================================================================***/
269
270 static int
271 _XkbCountBits(int nBitsMax,unsigned long mask)
272 {
273 register unsigned long y, nBits;
274
275     y = (mask >> 1) &033333333333;
276     y = mask - y - ((y >>1) & 033333333333);
277     nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077));
278
279     /* nBitsMax really means max+1 */
280     return (nBits < nBitsMax) ? nBits : (nBitsMax - 1);
281 }
282
283 static CARD32
284 _XkbCountAtoms(Atom *atoms,int maxAtoms,int *count)
285 {
286 register unsigned int i,bit,nAtoms;
287 register CARD32 atomsPresent;
288
289     for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) {
290         if (atoms[i]!=None) {
291             atomsPresent|= bit;
292             nAtoms++;
293         }
294     }
295     if (count)
296         *count= nAtoms;
297     return atomsPresent;
298 }
299
300 static void
301 _XkbCopyAtoms(Display *dpy,Atom *atoms,CARD32 mask,int maxAtoms)
302 {
303 register unsigned int i,bit;
304
305     for (i=0,bit=1;i<maxAtoms;i++,bit<<=1) {
306         if (mask&bit)
307             Data32(dpy,&atoms[i],4);
308     }
309     return;
310 }
311
312 Bool
313 XkbSetNames(    Display *       dpy,
314                 unsigned int    which,
315                 unsigned int    firstType,
316                 unsigned int    nTypes,
317                 XkbDescPtr      xkb)
318 {
319     register xkbSetNamesReq *req;
320     int  nLvlNames = 0;
321     XkbInfoPtr xkbi;
322     XkbNamesPtr names;
323     unsigned firstLvlType,nLvlTypes;
324     int nVMods,nLEDs,nRG,nKA,nGroups;
325     int nKeys=0,firstKey=0,nAtoms;
326     CARD32 leds,vmods,groups;
327
328     if ((dpy->flags & XlibDisplayNoXkb) ||
329         (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
330         return False;
331     if ((!xkb)||(!xkb->names))
332         return False;
333     firstLvlType= firstType;
334     nLvlTypes= nTypes;
335     if (nTypes<1)
336         which&= ~(XkbKTLevelNamesMask|XkbKeyTypeNamesMask);
337     else if (firstType<=XkbLastRequiredType) {
338         int     adjust;
339         adjust= XkbLastRequiredType-firstType+1;
340         firstType+= adjust;
341         nTypes-= adjust;
342         if (nTypes<1)
343             which&= ~XkbKeyTypeNamesMask;
344     }
345     names= xkb->names;
346     if (which&(XkbKTLevelNamesMask|XkbKeyTypeNamesMask)) {
347         register int    i;
348         XkbKeyTypePtr   type;
349         if((xkb->map==NULL)||(xkb->map->types==NULL)||(nTypes==0)||
350                                 (firstType+nTypes>xkb->map->num_types)||
351                                 (firstLvlType+nLvlTypes>xkb->map->num_types))
352             return False;
353         if (which&XkbKTLevelNamesMask) {
354             type= &xkb->map->types[firstLvlType];
355             for (i=nLvlNames=0;i<nLvlTypes;i++,type++) {
356                 if (type->level_names!=NULL)
357                     nLvlNames+= type->num_levels;
358             }
359         }
360     }
361
362     nVMods= nLEDs= nRG= nKA= nAtoms= nGroups= 0;
363     LockDisplay(dpy);
364     xkbi = dpy->xkb_info;
365     GetReq(kbSetNames, req);
366     req->reqType = xkbi->codes->major_opcode;
367     req->xkbReqType = X_kbSetNames;
368     req->deviceSpec = xkb->device_spec;
369     req->firstType = firstType;
370     req->nTypes = nTypes;
371     req->firstKey = xkb->min_key_code;
372     req->nKeys = xkb->max_key_code-xkb->min_key_code+1;
373
374     if (which&XkbKeycodesNameMask)
375         nAtoms++;
376     if (which&XkbGeometryNameMask)
377         nAtoms++;
378     if (which&XkbSymbolsNameMask)
379         nAtoms++;
380     if (which&XkbPhysSymbolsNameMask)
381         nAtoms++;
382     if (which&XkbTypesNameMask)
383         nAtoms++;
384     if (which&XkbCompatNameMask)
385         nAtoms++;
386     if (which&XkbKeyTypeNamesMask)
387         nAtoms+= nTypes;
388     if (which&XkbKTLevelNamesMask) {
389         req->firstKTLevel= firstLvlType;
390         req->nKTLevels= nLvlTypes;
391         req->length+= XkbPaddedSize(nLvlTypes)/4; /* room for group widths */
392         nAtoms+= nLvlNames;
393     }
394     else req->firstKTLevel= req->nKTLevels= 0;
395
396     if (which&XkbIndicatorNamesMask) {
397         req->indicators= leds=
398                 _XkbCountAtoms(names->indicators,XkbNumIndicators,&nLEDs);
399         if (nLEDs>0)
400              nAtoms+= nLEDs;
401         else which&= ~XkbIndicatorNamesMask;
402     }
403     else req->indicators= leds= 0;
404
405     if (which&XkbVirtualModNamesMask) {
406         vmods= req->virtualMods= (CARD16)
407                 _XkbCountAtoms(names->vmods,XkbNumVirtualMods,&nVMods);
408         if (nVMods>0)
409              nAtoms+= nVMods;
410         else which&= ~XkbVirtualModNamesMask;
411     }
412     else vmods= req->virtualMods= 0;
413
414     if (which&XkbGroupNamesMask) {
415         groups= req->groupNames= (CARD8)
416                 _XkbCountAtoms(names->groups,XkbNumKbdGroups,&nGroups);
417         if (nGroups>0)
418              nAtoms+= nGroups;
419         else which&= ~XkbGroupNamesMask;
420     }
421     else groups= req->groupNames= 0;
422
423     if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
424         firstKey= req->firstKey;
425         nKeys= req->nKeys;
426         nAtoms+= nKeys; /* technically not atoms, but 4 bytes wide */
427     }
428     else which&= ~XkbKeyNamesMask;
429
430     if (which&XkbKeyAliasesMask) {
431         nKA= ((names->key_aliases!=NULL)?names->num_key_aliases:0);
432         if (nKA>0) {
433             req->nKeyAliases= nKA;
434             nAtoms+= nKA*2; /* not atoms, but 8 bytes on the wire */
435         }
436         else {
437             which&= ~XkbKeyAliasesMask;
438             req->nKeyAliases = 0;
439         }
440     }
441     else req->nKeyAliases= 0;
442
443     if (which&XkbRGNamesMask) {
444         nRG= names->num_rg;
445         if (nRG>0)
446              nAtoms+= nRG;
447         else which&= ~XkbRGNamesMask;
448     }
449
450     req->which= which;
451     req->nRadioGroups= nRG;
452     req->length+= (nAtoms*4)/4;
453
454     if (which&XkbKeycodesNameMask)
455         Data32(dpy,(long *)&names->keycodes,4);
456     if (which&XkbGeometryNameMask)
457         Data32(dpy,(long *)&names->geometry,4);
458     if (which&XkbSymbolsNameMask)
459         Data32(dpy,(long *)&names->symbols,4);
460     if (which&XkbPhysSymbolsNameMask)
461         Data32(dpy,(long *)&names->phys_symbols,4);
462     if (which&XkbTypesNameMask)
463         Data32(dpy,(long *)&names->types,4);
464     if (which&XkbCompatNameMask)
465         Data32(dpy,(long *)&names->compat,4);
466     if (which&XkbKeyTypeNamesMask) {
467         register int            i;
468         register XkbKeyTypePtr  type;
469         type= &xkb->map->types[firstType];
470         for (i=0;i<nTypes;i++,type++) {
471             Data32(dpy,(long *)&type->name,4);
472         }
473     }
474     if (which&XkbKTLevelNamesMask) {
475         XkbKeyTypePtr type;
476         int i;
477         char *tmp;
478
479         BufAlloc(char *,tmp,XkbPaddedSize(nLvlTypes));
480         type = &xkb->map->types[firstLvlType];
481         for (i=0;i<nLvlTypes;i++,type++) {
482             *tmp++ = type->num_levels;
483         }
484         type = &xkb->map->types[firstLvlType];
485         for (i=0;i<nLvlTypes;i++,type++) {
486             if (type->level_names!=NULL)
487                 Data32(dpy,(long *)type->level_names,type->num_levels*4);
488         }
489     }
490     if (which&XkbIndicatorNamesMask)
491         _XkbCopyAtoms(dpy,names->indicators,leds,XkbNumIndicators);
492     if (which&XkbVirtualModNamesMask)
493         _XkbCopyAtoms(dpy,names->vmods,vmods,XkbNumVirtualMods);
494     if (which&XkbGroupNamesMask)
495         _XkbCopyAtoms(dpy,names->groups,groups,XkbNumKbdGroups);
496     if (which&XkbKeyNamesMask) {
497 #ifdef WORD64
498         char *tmp;
499         register int i;
500         BufAlloc(char *,tmp,nKeys*XkbKeyNameLength);
501         for (i=0;i<nKeys;i++,tmp+= XkbKeyNameLength) {
502             tmp[0]= names->keys[firstKey+i].name[0];
503             tmp[1]= names->keys[firstKey+i].name[1];
504             tmp[2]= names->keys[firstKey+i].name[2];
505             tmp[3]= names->keys[firstKey+i].name[3];
506         }
507 #else
508         Data(dpy,(char *)&names->keys[firstKey],nKeys*XkbKeyNameLength);
509 #endif
510     }
511     if (which&XkbKeyAliasesMask) {
512 #ifdef WORD64
513         char *tmp;
514         register int i;
515         BufAlloc(char *,tmp,nKA*XkbKeyNameLength*2);
516         for (i=0;i<nKeys;i++,tmp+= 2*XkbKeyNameLength) {
517             tmp[0]= names->key_aliases[i].real[0];
518             tmp[1]= names->key_aliases[i].real[1];
519             tmp[2]= names->key_aliases[i].real[2];
520             tmp[3]= names->key_aliases[i].real[3];
521             tmp[4]= names->key_aliases[i].alias[0];
522             tmp[5]= names->key_aliases[i].alias[1];
523             tmp[6]= names->key_aliases[i].alias[2];
524             tmp[7]= names->key_aliases[i].alias[3];
525         }
526 #else
527         Data(dpy,(char *)names->key_aliases,nKA*XkbKeyNameLength*2);
528 #endif
529     }
530     if (which&XkbRGNamesMask) {
531         Data32(dpy,(long *)names->radio_groups,nRG*4);
532     }
533     UnlockDisplay(dpy);
534     SyncHandle();
535     return True;
536 }
537
538 Bool
539 XkbChangeNames(Display *dpy,XkbDescPtr xkb,XkbNameChangesPtr changes)
540 {
541     register xkbSetNamesReq *req;
542     int  nLvlNames = 0;
543     XkbInfoPtr xkbi;
544     XkbNamesPtr names;
545     unsigned which,firstType,nTypes;
546     unsigned firstLvlType,nLvlTypes;
547     int nVMods,nLEDs,nRG,nKA,nGroups;
548     int nKeys=0,firstKey=0,nAtoms;
549     CARD32 leds=0,vmods=0,groups=0;
550
551     if ((dpy->flags & XlibDisplayNoXkb) ||
552         (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
553         return False;
554     if ((!xkb)||(!xkb->names)||(!changes))
555         return False;
556     which= changes->changed;
557     firstType= changes->first_type;
558     nTypes= changes->num_types;
559     firstLvlType= changes->first_lvl;;
560     nLvlTypes= changes->num_lvls;
561     if (which&XkbKeyTypeNamesMask) {
562         if (nTypes<1)
563             which&= ~XkbKeyTypeNamesMask;
564         else if (firstType<=XkbLastRequiredType) {
565             int adjust;
566             adjust= XkbLastRequiredType-firstType+1;
567             firstType+= adjust;
568             nTypes-= adjust;
569             if (nTypes<1)
570                 which&= ~XkbKeyTypeNamesMask;
571         }
572     }
573     else firstType= nTypes= 0;
574
575     if (which&XkbKTLevelNamesMask) {
576         if (nLvlTypes<1)
577             which&= ~XkbKTLevelNamesMask;
578     }
579     else firstLvlType= nLvlTypes= 0;
580
581     names= xkb->names;
582     if (which&(XkbKTLevelNamesMask|XkbKeyTypeNamesMask)) {
583         register int    i;
584         XkbKeyTypePtr   type;
585         if((xkb->map==NULL)||(xkb->map->types==NULL)||(nTypes==0)||
586                                 (firstType+nTypes>xkb->map->num_types)||
587                                 (firstLvlType+nLvlTypes>xkb->map->num_types))
588             return False;
589         if (which&XkbKTLevelNamesMask) {
590             type= &xkb->map->types[firstLvlType];
591             for (i=nLvlNames=0;i<nLvlTypes;i++,type++) {
592                 if (type->level_names!=NULL)
593                     nLvlNames+= type->num_levels;
594             }
595         }
596     }
597
598     if (changes->num_keys<1)
599         which&= ~XkbKeyNamesMask;
600     if ((which&XkbKeyNamesMask)==0)
601         changes->first_key= changes->num_keys= 0;
602     else if ((changes->first_key<xkb->min_key_code)||
603              (changes->first_key+changes->num_keys>xkb->max_key_code)) {
604         return False;
605     }
606
607     if ((which&XkbVirtualModNamesMask)==0)
608         changes->changed_vmods= 0;
609     else if (changes->changed_vmods==0)
610         which&= ~XkbVirtualModNamesMask;
611
612     if ((which&XkbIndicatorNamesMask)==0)
613         changes->changed_indicators= 0;
614     else if (changes->changed_indicators==0)
615         which&= ~XkbIndicatorNamesMask;
616
617     if ((which&XkbGroupNamesMask)==0)
618         changes->changed_groups= 0;
619     else if (changes->changed_groups==0)
620         which&= ~XkbGroupNamesMask;
621
622     nVMods= nLEDs= nRG= nKA= nAtoms= nGroups= 0;
623     LockDisplay(dpy);
624     xkbi = dpy->xkb_info;
625     GetReq(kbSetNames, req);
626     req->reqType = xkbi->codes->major_opcode;
627     req->xkbReqType = X_kbSetNames;
628     req->deviceSpec = xkb->device_spec;
629     req->firstType = firstType;
630     req->nTypes = nTypes;
631     req->firstKey = changes->first_key;
632     req->nKeys = changes->num_keys;
633
634     if (which&XkbKeycodesNameMask)
635         nAtoms++;
636     if (which&XkbGeometryNameMask)
637         nAtoms++;
638     if (which&XkbSymbolsNameMask)
639         nAtoms++;
640     if (which&XkbPhysSymbolsNameMask)
641         nAtoms++;
642     if (which&XkbTypesNameMask)
643         nAtoms++;
644     if (which&XkbCompatNameMask)
645         nAtoms++;
646     if (which&XkbKeyTypeNamesMask)
647         nAtoms+= nTypes;
648     if (which&XkbKTLevelNamesMask) {
649         req->firstKTLevel= firstLvlType;
650         req->nKTLevels= nLvlTypes;
651         req->length+= XkbPaddedSize(nLvlTypes)/4; /* room for group widths */
652         nAtoms+= nLvlNames;
653     }
654     else req->firstKTLevel= req->nKTLevels= 0;
655
656     if (which&XkbIndicatorNamesMask) {
657         leds= req->indicators= (CARD32)changes->changed_indicators;
658         nLEDs= _XkbCountBits(XkbNumIndicators,changes->changed_indicators);
659         if (nLEDs>0)
660              nAtoms+= nLEDs;
661         else which&= ~XkbIndicatorNamesMask;
662     }
663     else req->indicators= 0;
664
665     if (which&XkbVirtualModNamesMask) {
666         vmods= req->virtualMods= changes->changed_vmods;
667         nVMods= _XkbCountBits(XkbNumVirtualMods,
668                                         (unsigned long)changes->changed_vmods);
669         if (nVMods>0)
670              nAtoms+= nVMods;
671         else which&= ~XkbVirtualModNamesMask;
672     }
673     else req->virtualMods= 0;
674
675     if (which&XkbGroupNamesMask) {
676         groups= req->groupNames= changes->changed_groups;
677         nGroups= _XkbCountBits(XkbNumKbdGroups,
678                                         (unsigned long)changes->changed_groups);
679         if (nGroups>0)
680              nAtoms+= nGroups;
681         else which&= ~XkbGroupNamesMask;
682     }
683     else req->groupNames= 0;
684
685     if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
686         firstKey= req->firstKey;
687         nKeys= req->nKeys;
688         nAtoms+= nKeys; /* technically not atoms, but 4 bytes wide */
689     }
690     else which&= ~XkbKeyNamesMask;
691
692     if (which&XkbKeyAliasesMask) {
693         nKA= ((names->key_aliases!=NULL)?names->num_key_aliases:0);
694         if (nKA>0)
695             nAtoms+= nKA*2; /* not atoms, but 8 bytes on the wire */
696         else which&= ~XkbKeyAliasesMask;
697     }
698
699     if (which&XkbRGNamesMask) {
700         nRG= names->num_rg;
701         if (nRG>0)
702              nAtoms+= nRG;
703         else which&= ~XkbRGNamesMask;
704     }
705
706     req->which= which;
707     req->nRadioGroups= nRG;
708     req->length+= (nAtoms*4)/4;
709
710     if (which&XkbKeycodesNameMask)
711         Data32(dpy,(long *)&names->keycodes,4);
712     if (which&XkbGeometryNameMask)
713         Data32(dpy,(long *)&names->geometry,4);
714     if (which&XkbSymbolsNameMask)
715         Data32(dpy,(long *)&names->symbols,4);
716     if (which&XkbPhysSymbolsNameMask)
717         Data32(dpy,(long *)&names->phys_symbols,4);
718     if (which&XkbTypesNameMask)
719         Data32(dpy,(long *)&names->types,4);
720     if (which&XkbCompatNameMask)
721         Data32(dpy,(long *)&names->compat,4);
722     if (which&XkbKeyTypeNamesMask) {
723         register int            i;
724         register XkbKeyTypePtr  type;
725         type= &xkb->map->types[firstType];
726         for (i=0;i<nTypes;i++,type++) {
727             Data32(dpy,(long *)&type->name,4);
728         }
729     }
730     if (which&XkbKTLevelNamesMask) {
731         XkbKeyTypePtr type;
732         int i;
733         char *tmp;
734
735         BufAlloc(char *,tmp,XkbPaddedSize(nLvlTypes));
736         type = &xkb->map->types[firstLvlType];
737         for (i=0;i<nLvlTypes;i++,type++) {
738             *tmp++ = type->num_levels;
739         }
740         type = &xkb->map->types[firstLvlType];
741         for (i=0;i<nLvlTypes;i++,type++) {
742             if (type->level_names!=NULL)
743                 Data32(dpy,(long *)type->level_names,type->num_levels*4);
744         }
745     }
746     if (which&XkbIndicatorNamesMask)
747         _XkbCopyAtoms(dpy,names->indicators,leds,XkbNumIndicators);
748     if (which&XkbVirtualModNamesMask)
749         _XkbCopyAtoms(dpy,names->vmods,vmods,XkbNumVirtualMods);
750     if (which&XkbGroupNamesMask)
751         _XkbCopyAtoms(dpy,names->groups,groups,XkbNumKbdGroups);
752     if (which&XkbKeyNamesMask) {
753 #ifdef WORD64
754         char *tmp;
755         register int i;
756         BufAlloc(char *,tmp,nKeys*4);
757         for (i=0;i<nKeys;i++,tmp+= 4) {
758             tmp[0]= names->keys[firstKey+i].name[0];
759             tmp[1]= names->keys[firstKey+i].name[1];
760             tmp[2]= names->keys[firstKey+i].name[2];
761             tmp[3]= names->keys[firstKey+i].name[3];
762         }
763 #else
764         Data(dpy,(char *)&names->keys[firstKey],nKeys*XkbKeyNameLength);
765 #endif
766     }
767     if (which&XkbKeyAliasesMask) {
768 #ifdef WORD64
769         char *tmp;
770         register int i;
771         BufAlloc(char *,tmp,nKA*XkbKeyNameLength*2);
772         for (i=0;i<nKeys;i++,tmp+= 2*XkbKeyNameLength) {
773             tmp[0]= names->key_aliases[i].real[0];
774             tmp[1]= names->key_aliases[i].real[1];
775             tmp[2]= names->key_aliases[i].real[2];
776             tmp[3]= names->key_aliases[i].real[3];
777             tmp[4]= names->key_aliases[i].alias[0];
778             tmp[5]= names->key_aliases[i].alias[1];
779             tmp[6]= names->key_aliases[i].alias[2];
780             tmp[7]= names->key_aliases[i].alias[3];
781         }
782 #else
783         Data(dpy,(char *)names->key_aliases,nKA*XkbKeyNameLength*2);
784 #endif
785     }
786     if (which&XkbRGNamesMask) {
787         Data32(dpy,(long *)names->radio_groups,nRG*4);
788     }
789     UnlockDisplay(dpy);
790     SyncHandle();
791     return True;
792 }
793
794 void
795 XkbNoteNameChanges(     XkbNameChangesPtr       old,
796                         XkbNamesNotifyEvent *   new,
797                         unsigned int            wanted)
798 {
799 int     first,last,old_last,new_last;
800
801     wanted&= new->changed;
802     if ((old==NULL)||(new==NULL)||(wanted==0))
803         return;
804     if (wanted&XkbKeyTypeNamesMask) {
805         if (old->changed&XkbKeyTypeNamesMask) {
806             new_last= (new->first_type+new->num_types-1);
807             old_last= (old->first_type+old->num_types-1);
808
809             if (new->first_type<old->first_type)
810                  first= new->first_type;
811             else first= old->first_type;
812
813             if (old_last>new_last)
814                  last= old_last;
815             else last= new_last;
816
817             old->first_type= first;
818             old->num_types= (last-first)+1;
819         }
820         else {
821             old->first_type= new->first_type;
822             old->num_types= new->num_types;
823         }
824     }
825     if (wanted&XkbKTLevelNamesMask) {
826         if (old->changed&XkbKTLevelNamesMask) {
827             new_last= (new->first_lvl+new->num_lvls-1);
828             old_last= (old->first_lvl+old->num_lvls-1);
829
830             if (new->first_lvl<old->first_lvl)
831                  first= new->first_lvl;
832             else first= old->first_lvl;
833
834             if (old_last>new_last)
835                  last= old_last;
836             else last= new_last;
837
838             old->first_lvl= first;
839             old->num_lvls= (last-first)+1;
840         }
841         else {
842             old->first_lvl= new->first_lvl;
843             old->num_lvls= new->num_lvls;
844         }
845     }
846     if (wanted&XkbIndicatorNamesMask) {
847         if (old->changed&XkbIndicatorNamesMask)
848              old->changed_indicators|= new->changed_indicators;
849         else old->changed_indicators=  new->changed_indicators;
850     }
851     if (wanted&XkbKeyNamesMask) {
852         if (old->changed&XkbKeyNamesMask) {
853             new_last= (new->first_key+new->num_keys-1);
854             old_last= (old->first_key+old->num_keys-1);
855
856             first= old->first_key;
857
858             if (new->first_key<old->first_key)
859                 first= new->first_key;
860             if (old_last>new_last)
861                 new_last= old_last;
862
863             old->first_key= first;
864             old->num_keys= (new_last-first)+1;
865         }
866         else {
867             old->first_key= new->first_key;
868             old->num_keys= new->num_keys;
869         }
870     }
871     if (wanted&XkbVirtualModNamesMask) {
872         if (old->changed&XkbVirtualModNamesMask)
873              old->changed_vmods|= new->changed_vmods;
874         else old->changed_vmods=  new->changed_vmods;
875     }
876     if (wanted&XkbGroupNamesMask) {
877         if (old->changed&XkbGroupNamesMask)
878              old->changed_groups|= new->changed_groups;
879         else old->changed_groups=  new->changed_groups;
880     }
881     if (wanted&XkbRGNamesMask)
882         old->num_rg= new->num_radio_groups;
883     if (wanted&XkbKeyAliasesMask)
884         old->num_aliases= new->num_aliases;
885     old->changed|= wanted;
886     return;
887 }