1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #elif defined(HAVE_CONFIG_H)
35 #include <X11/Xproto.h>
38 #include <X11/keysym.h>
39 #define XKBSRV_NEED_FILE_FUNCS
42 /***====================================================================***/
45 XkbAllocClientMap(XkbDescPtr xkb
, unsigned which
, unsigned nTotalTypes
)
51 ((nTotalTypes
> 0) && (nTotalTypes
< XkbNumRequiredTypes
)))
53 if ((which
& XkbKeySymsMask
) &&
54 ((!XkbIsLegalKeycode(xkb
->min_key_code
)) ||
55 (!XkbIsLegalKeycode(xkb
->max_key_code
)) ||
56 (xkb
->max_key_code
< xkb
->min_key_code
))) {
57 DebugF("bad keycode (%d,%d) in XkbAllocClientMap\n",
58 xkb
->min_key_code
, xkb
->max_key_code
);
62 if (xkb
->map
== NULL
) {
63 map
= calloc(1, sizeof(XkbClientMapRec
));
71 if ((which
& XkbKeyTypesMask
) && (nTotalTypes
> 0)) {
72 if (map
->types
== NULL
) {
73 map
->types
= calloc(nTotalTypes
, sizeof(XkbKeyTypeRec
));
74 if (map
->types
== NULL
)
77 map
->size_types
= nTotalTypes
;
79 else if (map
->size_types
< nTotalTypes
) {
80 XkbKeyTypeRec
*prev_types
= map
->types
;
83 realloc(map
->types
, nTotalTypes
* sizeof(XkbKeyTypeRec
));
84 if (map
->types
== NULL
) {
86 map
->num_types
= map
->size_types
= 0;
89 map
->size_types
= nTotalTypes
;
90 memset(&map
->types
[map
->num_types
], 0,
92 map
->num_types
) * sizeof(XkbKeyTypeRec
)));
95 if (which
& XkbKeySymsMask
) {
96 int nKeys
= XkbNumKeys(xkb
);
98 if (map
->syms
== NULL
) {
99 map
->size_syms
= (nKeys
* 15) / 10;
100 map
->syms
= calloc(map
->size_syms
, sizeof(KeySym
));
106 map
->syms
[0] = NoSymbol
;
108 if (map
->key_sym_map
== NULL
) {
109 i
= xkb
->max_key_code
+ 1;
110 map
->key_sym_map
= calloc(i
, sizeof(XkbSymMapRec
));
111 if (map
->key_sym_map
== NULL
)
115 if (which
& XkbModifierMapMask
) {
116 if ((!XkbIsLegalKeycode(xkb
->min_key_code
)) ||
117 (!XkbIsLegalKeycode(xkb
->max_key_code
)) ||
118 (xkb
->max_key_code
< xkb
->min_key_code
))
120 if (map
->modmap
== NULL
) {
121 i
= xkb
->max_key_code
+ 1;
122 map
->modmap
= calloc(i
, sizeof(unsigned char));
123 if (map
->modmap
== NULL
)
131 XkbAllocServerMap(XkbDescPtr xkb
, unsigned which
, unsigned nNewActions
)
138 if (xkb
->server
== NULL
) {
139 map
= calloc(1, sizeof(XkbServerMapRec
));
142 for (i
= 0; i
< XkbNumVirtualMods
; i
++) {
143 map
->vmods
[i
] = XkbNoModifierMask
;
149 if (which
& XkbExplicitComponentsMask
) {
150 if ((!XkbIsLegalKeycode(xkb
->min_key_code
)) ||
151 (!XkbIsLegalKeycode(xkb
->max_key_code
)) ||
152 (xkb
->max_key_code
< xkb
->min_key_code
))
154 if (map
->explicit == NULL
) {
155 i
= xkb
->max_key_code
+ 1;
156 map
->explicit = calloc(i
, sizeof(unsigned char));
157 if (map
->explicit == NULL
)
161 if (which
& XkbKeyActionsMask
) {
162 if ((!XkbIsLegalKeycode(xkb
->min_key_code
)) ||
163 (!XkbIsLegalKeycode(xkb
->max_key_code
)) ||
164 (xkb
->max_key_code
< xkb
->min_key_code
))
168 if (map
->acts
== NULL
) {
169 map
->acts
= calloc((nNewActions
+ 1), sizeof(XkbAction
));
170 if (map
->acts
== NULL
)
173 map
->size_acts
= nNewActions
+ 1;
175 else if ((map
->size_acts
- map
->num_acts
) < nNewActions
) {
177 XkbAction
*prev_acts
= map
->acts
;
179 need
= map
->num_acts
+ nNewActions
;
180 map
->acts
= realloc(map
->acts
, need
* sizeof(XkbAction
));
181 if (map
->acts
== NULL
) {
183 map
->num_acts
= map
->size_acts
= 0;
186 map
->size_acts
= need
;
187 memset(&map
->acts
[map
->num_acts
], 0,
188 ((map
->size_acts
- map
->num_acts
) * sizeof(XkbAction
)));
190 if (map
->key_acts
== NULL
) {
191 i
= xkb
->max_key_code
+ 1;
192 map
->key_acts
= calloc(i
, sizeof(unsigned short));
193 if (map
->key_acts
== NULL
)
197 if (which
& XkbKeyBehaviorsMask
) {
198 if ((!XkbIsLegalKeycode(xkb
->min_key_code
)) ||
199 (!XkbIsLegalKeycode(xkb
->max_key_code
)) ||
200 (xkb
->max_key_code
< xkb
->min_key_code
))
202 if (map
->behaviors
== NULL
) {
203 i
= xkb
->max_key_code
+ 1;
204 map
->behaviors
= calloc(i
, sizeof(XkbBehavior
));
205 if (map
->behaviors
== NULL
)
209 if (which
& XkbVirtualModMapMask
) {
210 if ((!XkbIsLegalKeycode(xkb
->min_key_code
)) ||
211 (!XkbIsLegalKeycode(xkb
->max_key_code
)) ||
212 (xkb
->max_key_code
< xkb
->min_key_code
))
214 if (map
->vmodmap
== NULL
) {
215 i
= xkb
->max_key_code
+ 1;
216 map
->vmodmap
= calloc(i
, sizeof(unsigned short));
217 if (map
->vmodmap
== NULL
)
224 /***====================================================================***/
227 XkbCopyKeyType(XkbKeyTypePtr from
, XkbKeyTypePtr into
)
229 if ((!from
) || (!into
))
233 free(into
->preserve
);
234 into
->preserve
= NULL
;
235 free(into
->level_names
);
236 into
->level_names
= NULL
;
238 if ((from
->map
) && (into
->map_count
> 0)) {
239 into
->map
= calloc(into
->map_count
, sizeof(XkbKTMapEntryRec
));
242 memcpy(into
->map
, from
->map
,
243 into
->map_count
* sizeof(XkbKTMapEntryRec
));
245 if ((from
->preserve
) && (into
->map_count
> 0)) {
246 into
->preserve
= calloc(into
->map_count
, sizeof(XkbModsRec
));
249 memcpy(into
->preserve
, from
->preserve
,
250 into
->map_count
* sizeof(XkbModsRec
));
252 if ((from
->level_names
) && (into
->num_levels
> 0)) {
253 into
->level_names
= calloc(into
->num_levels
, sizeof(Atom
));
254 if (!into
->level_names
)
256 memcpy(into
->level_names
, from
->level_names
,
257 into
->num_levels
* sizeof(Atom
));
263 XkbCopyKeyTypes(XkbKeyTypePtr from
, XkbKeyTypePtr into
, int num_types
)
265 register int i
, rtrn
;
267 if ((!from
) || (!into
) || (num_types
< 0))
269 for (i
= 0; i
< num_types
; i
++) {
270 if ((rtrn
= XkbCopyKeyType(from
++, into
++)) != Success
)
277 XkbResizeKeyType(XkbDescPtr xkb
,
279 int map_count
, Bool want_preserve
, int new_num_lvls
)
282 KeyCode matchingKeys
[XkbMaxKeyCount
], nMatchingKeys
;
284 if ((type_ndx
< 0) || (type_ndx
>= xkb
->map
->num_types
) || (map_count
< 0)
285 || (new_num_lvls
< 1))
288 case XkbOneLevelIndex
:
289 if (new_num_lvls
!= 1)
292 case XkbTwoLevelIndex
:
293 case XkbAlphabeticIndex
:
295 if (new_num_lvls
!= 2)
299 type
= &xkb
->map
->types
[type_ndx
];
300 if (map_count
== 0) {
303 free(type
->preserve
);
304 type
->preserve
= NULL
;
308 XkbKTMapEntryRec
*prev_map
= type
->map
;
310 if ((map_count
> type
->map_count
) || (type
->map
== NULL
))
312 realloc(type
->map
, map_count
* sizeof(XkbKTMapEntryRec
));
318 XkbModsRec
*prev_preserve
= type
->preserve
;
320 if ((map_count
> type
->map_count
) || (type
->preserve
== NULL
)) {
321 type
->preserve
= realloc(type
->preserve
,
322 map_count
* sizeof(XkbModsRec
));
324 if (!type
->preserve
) {
330 free(type
->preserve
);
331 type
->preserve
= NULL
;
333 type
->map_count
= map_count
;
336 if ((new_num_lvls
> type
->num_levels
) || (type
->level_names
== NULL
)) {
337 Atom
*prev_level_names
= type
->level_names
;
339 type
->level_names
= realloc(type
->level_names
,
340 new_num_lvls
* sizeof(Atom
));
341 if (!type
->level_names
) {
342 free(prev_level_names
);
348 * If the width of the type changed, we might have to resize the symbol
349 * maps for any keys that use the type for one or more groups. This is
350 * expensive, so we'll try to cull out any keys that are obviously okay:
352 * - keys that have a group width <= the old width are okay (because
353 * they could not possibly have been associated with the old type)
354 * If the key type increased in size:
355 * - keys that already have a group width >= to the new width are okay
356 * + keys that have a group width >= the old width but < the new width
357 * might have to be enlarged.
358 * If the key type decreased in size:
359 * - keys that have a group width > the old width don't have to be
360 * resized (because they must have some other wider type associated
362 * + keys that have a group width == the old width might have to be
364 * The possibilities marked with '+' require us to examine the key types
365 * associated with each group for the key.
367 memset(matchingKeys
, 0, XkbMaxKeyCount
* sizeof(KeyCode
));
369 if (new_num_lvls
> type
->num_levels
) {
372 int width
, match
, nResize
;
373 register int i
, g
, nSyms
;
376 for (nTotal
= 1, i
= xkb
->min_key_code
; i
<= xkb
->max_key_code
; i
++) {
377 width
= XkbKeyGroupsWidth(xkb
, i
);
378 if (width
< type
->num_levels
|| width
>= new_num_lvls
) {
379 nTotal
+= XkbKeyNumSyms(xkb
,i
);
382 for (match
= 0, g
= XkbKeyNumGroups(xkb
, i
) - 1;
383 (g
>= 0) && (!match
); g
--) {
384 if (XkbKeyKeyTypeIndex(xkb
, i
, g
) == type_ndx
) {
385 matchingKeys
[nMatchingKeys
++] = i
;
390 nTotal
+= XkbKeyNumSyms(xkb
, i
);
392 nTotal
+= XkbKeyNumGroups(xkb
, i
) * new_num_lvls
;
399 xkb
->map
->size_syms
= (nTotal
* 15) / 10;
400 newSyms
= calloc(xkb
->map
->size_syms
, sizeof(KeySym
));
405 for (i
= xkb
->min_key_code
; i
<= xkb
->max_key_code
; i
++) {
406 if (matchingKeys
[nextMatch
] == i
) {
410 width
= XkbKeyGroupsWidth(xkb
, i
);
411 pOld
= XkbKeySymsPtr(xkb
, i
);
412 for (g
= XkbKeyNumGroups(xkb
, i
) - 1; g
>= 0; g
--) {
413 memcpy(&newSyms
[nSyms
+ (new_num_lvls
* g
)],
414 &pOld
[width
* g
], width
* sizeof(KeySym
));
416 xkb
->map
->key_sym_map
[i
].offset
= nSyms
;
417 nSyms
+= XkbKeyNumGroups(xkb
, i
) * new_num_lvls
;
420 memcpy(&newSyms
[nSyms
], XkbKeySymsPtr(xkb
, i
),
421 XkbKeyNumSyms(xkb
, i
) * sizeof(KeySym
));
422 xkb
->map
->key_sym_map
[i
].offset
= nSyms
;
423 nSyms
+= XkbKeyNumSyms(xkb
, i
);
426 type
->num_levels
= new_num_lvls
;
427 free(xkb
->map
->syms
);
428 xkb
->map
->syms
= newSyms
;
429 xkb
->map
->num_syms
= nSyms
;
433 else if (new_num_lvls
< type
->num_levels
) {
437 for (i
= xkb
->min_key_code
; i
<= xkb
->max_key_code
; i
++) {
438 width
= XkbKeyGroupsWidth(xkb
, i
);
439 if (width
< type
->num_levels
)
441 for (match
= 0, g
= XkbKeyNumGroups(xkb
, i
) - 1;
442 (g
>= 0) && (!match
); g
--) {
443 if (XkbKeyKeyTypeIndex(xkb
, i
, g
) == type_ndx
) {
444 matchingKeys
[nMatchingKeys
++] = i
;
450 if (nMatchingKeys
> 0) {
454 if (new_num_lvls
> type
->num_levels
)
455 firstClear
= type
->num_levels
;
457 firstClear
= new_num_lvls
;
458 for (i
= 0; i
< nMatchingKeys
; i
++) {
462 key
= matchingKeys
[i
];
463 width
= XkbKeyGroupsWidth(xkb
, key
);
464 nClear
= width
- firstClear
;
465 pSyms
= XkbKeySymsPtr(xkb
, key
);
466 for (g
= XkbKeyNumGroups(xkb
, key
) - 1; g
>= 0; g
--) {
467 if (XkbKeyKeyTypeIndex(xkb
, key
, g
) == type_ndx
) {
469 memset(&pSyms
[g
* width
+ firstClear
], 0,
470 nClear
* sizeof(KeySym
));
475 type
->num_levels
= new_num_lvls
;
480 XkbResizeKeySyms(XkbDescPtr xkb
, int key
, int needed
)
482 register int i
, nSyms
, nKeySyms
;
487 xkb
->map
->key_sym_map
[key
].offset
= 0;
488 return xkb
->map
->syms
;
490 nOldSyms
= XkbKeyNumSyms(xkb
, key
);
491 if (nOldSyms
>= (unsigned) needed
) {
492 return XkbKeySymsPtr(xkb
, key
);
494 if (xkb
->map
->size_syms
- xkb
->map
->num_syms
>= (unsigned) needed
) {
496 memcpy(&xkb
->map
->syms
[xkb
->map
->num_syms
], XkbKeySymsPtr(xkb
, key
),
497 nOldSyms
* sizeof(KeySym
));
499 if ((needed
- nOldSyms
) > 0) {
501 syms
[xkb
->map
->num_syms
+ XkbKeyNumSyms(xkb
, key
)], 0,
502 (needed
- nOldSyms
) * sizeof(KeySym
));
504 xkb
->map
->key_sym_map
[key
].offset
= xkb
->map
->num_syms
;
505 xkb
->map
->num_syms
+= needed
;
506 return &xkb
->map
->syms
[xkb
->map
->key_sym_map
[key
].offset
];
508 xkb
->map
->size_syms
+= (needed
> 32 ? needed
: 32);
509 newSyms
= calloc(xkb
->map
->size_syms
, sizeof(KeySym
));
512 newSyms
[0] = NoSymbol
;
514 for (i
= xkb
->min_key_code
; i
<= (int) xkb
->max_key_code
; i
++) {
517 nCopy
= nKeySyms
= XkbKeyNumSyms(xkb
, i
);
518 if ((nKeySyms
== 0) && (i
!= key
))
523 memcpy(&newSyms
[nSyms
], XkbKeySymsPtr(xkb
, i
),
524 nCopy
* sizeof(KeySym
));
525 if (nKeySyms
> nCopy
)
526 memset(&newSyms
[nSyms
+ nCopy
], 0,
527 (nKeySyms
- nCopy
) * sizeof(KeySym
));
528 xkb
->map
->key_sym_map
[i
].offset
= nSyms
;
531 free(xkb
->map
->syms
);
532 xkb
->map
->syms
= newSyms
;
533 xkb
->map
->num_syms
= nSyms
;
534 return &xkb
->map
->syms
[xkb
->map
->key_sym_map
[key
].offset
];
538 _ExtendRange(unsigned int old_flags
,
540 KeyCode newKC
, KeyCode
*old_min
, unsigned char *old_num
)
542 if ((old_flags
& flag
) == 0) {
548 int last
= (*old_min
) + (*old_num
) - 1;
550 if (newKC
< *old_min
) {
552 *old_num
= (last
- newKC
) + 1;
554 else if (newKC
> last
) {
555 *old_num
= (newKC
- (*old_min
)) + 1;
562 XkbChangeKeycodeRange(XkbDescPtr xkb
,
563 int minKC
, int maxKC
, XkbChangesPtr changes
)
567 if ((!xkb
) || (minKC
< XkbMinLegalKeyCode
) || (maxKC
> XkbMaxLegalKeyCode
))
571 if (minKC
< xkb
->min_key_code
) {
573 changes
->map
.min_key_code
= minKC
;
574 tmp
= xkb
->min_key_code
- minKC
;
576 if (xkb
->map
->key_sym_map
) {
577 memset((char *) &xkb
->map
->key_sym_map
[minKC
], 0,
578 tmp
* sizeof(XkbSymMapRec
));
580 changes
->map
.changed
= _ExtendRange(changes
->map
.changed
,
581 XkbKeySymsMask
, minKC
,
588 if (xkb
->map
->modmap
) {
589 memset((char *) &xkb
->map
->modmap
[minKC
], 0, tmp
);
591 changes
->map
.changed
= _ExtendRange(changes
->map
.changed
,
602 if (xkb
->server
->behaviors
) {
603 memset((char *) &xkb
->server
->behaviors
[minKC
], 0,
604 tmp
* sizeof(XkbBehavior
));
606 changes
->map
.changed
= _ExtendRange(changes
->map
.changed
,
615 if (xkb
->server
->key_acts
) {
616 memset((char *) &xkb
->server
->key_acts
[minKC
], 0,
617 tmp
* sizeof(unsigned short));
619 changes
->map
.changed
= _ExtendRange(changes
->map
.changed
,
628 if (xkb
->server
->vmodmap
) {
629 memset((char *) &xkb
->server
->vmodmap
[minKC
], 0,
630 tmp
* sizeof(unsigned short));
632 changes
->map
.changed
= _ExtendRange(changes
->map
.changed
,
633 XkbVirtualModMapMask
,
642 if ((xkb
->names
) && (xkb
->names
->keys
)) {
643 memset((char *) &xkb
->names
->keys
[minKC
], 0,
644 tmp
* sizeof(XkbKeyNameRec
));
646 changes
->names
.changed
= _ExtendRange(changes
->names
.changed
,
647 XkbKeyNamesMask
, minKC
,
648 &changes
->names
.first_key
,
649 &changes
->names
.num_keys
);
652 xkb
->min_key_code
= minKC
;
654 if (maxKC
> xkb
->max_key_code
) {
656 changes
->map
.max_key_code
= maxKC
;
657 tmp
= maxKC
- xkb
->max_key_code
;
659 if (xkb
->map
->key_sym_map
) {
660 XkbSymMapRec
*prev_key_sym_map
= xkb
->map
->key_sym_map
;
662 xkb
->map
->key_sym_map
= realloc(xkb
->map
->key_sym_map
,
664 1) * sizeof(XkbSymMapRec
));
665 if (!xkb
->map
->key_sym_map
) {
666 free(prev_key_sym_map
);
669 memset((char *) &xkb
->map
->key_sym_map
[xkb
->max_key_code
], 0,
670 tmp
* sizeof(XkbSymMapRec
));
672 changes
->map
.changed
= _ExtendRange(changes
->map
.changed
,
673 XkbKeySymsMask
, maxKC
,
680 if (xkb
->map
->modmap
) {
681 unsigned char *prev_modmap
= xkb
->map
->modmap
;
683 xkb
->map
->modmap
= realloc(xkb
->map
->modmap
,
684 (maxKC
+ 1) * sizeof(unsigned char));
685 if (!xkb
->map
->modmap
) {
689 memset((char *) &xkb
->map
->modmap
[xkb
->max_key_code
], 0, tmp
);
691 changes
->map
.changed
= _ExtendRange(changes
->map
.changed
,
702 if (xkb
->server
->behaviors
) {
703 XkbBehavior
*prev_behaviors
= xkb
->server
->behaviors
;
705 xkb
->server
->behaviors
= realloc(xkb
->server
->behaviors
,
707 1) * sizeof(XkbBehavior
));
708 if (!xkb
->server
->behaviors
) {
709 free(prev_behaviors
);
712 memset((char *) &xkb
->server
->behaviors
[xkb
->max_key_code
], 0,
713 tmp
* sizeof(XkbBehavior
));
715 changes
->map
.changed
= _ExtendRange(changes
->map
.changed
,
724 if (xkb
->server
->key_acts
) {
725 unsigned short *prev_key_acts
= xkb
->server
->key_acts
;
727 xkb
->server
->key_acts
= realloc(xkb
->server
->key_acts
,
729 1) * sizeof(unsigned short));
730 if (!xkb
->server
->key_acts
) {
734 memset((char *) &xkb
->server
->key_acts
[xkb
->max_key_code
], 0,
735 tmp
* sizeof(unsigned short));
737 changes
->map
.changed
= _ExtendRange(changes
->map
.changed
,
746 if (xkb
->server
->vmodmap
) {
747 unsigned short *prev_vmodmap
= xkb
->server
->vmodmap
;
749 xkb
->server
->vmodmap
= realloc(xkb
->server
->vmodmap
,
751 1) * sizeof(unsigned short));
752 if (!xkb
->server
->vmodmap
) {
756 memset((char *) &xkb
->server
->vmodmap
[xkb
->max_key_code
], 0,
757 tmp
* sizeof(unsigned short));
759 changes
->map
.changed
= _ExtendRange(changes
->map
.changed
,
760 XkbVirtualModMapMask
,
769 if ((xkb
->names
) && (xkb
->names
->keys
)) {
770 XkbKeyNameRec
*prev_keys
= xkb
->names
->keys
;
772 xkb
->names
->keys
= realloc(xkb
->names
->keys
,
773 (maxKC
+ 1) * sizeof(XkbKeyNameRec
));
774 if (!xkb
->names
->keys
) {
778 memset((char *) &xkb
->names
->keys
[xkb
->max_key_code
], 0,
779 tmp
* sizeof(XkbKeyNameRec
));
781 changes
->names
.changed
= _ExtendRange(changes
->names
.changed
,
782 XkbKeyNamesMask
, maxKC
,
783 &changes
->names
.first_key
,
784 &changes
->names
.num_keys
);
787 xkb
->max_key_code
= maxKC
;
793 XkbResizeKeyActions(XkbDescPtr xkb
, int key
, int needed
)
795 register int i
, nActs
;
799 xkb
->server
->key_acts
[key
] = 0;
802 if (XkbKeyHasActions(xkb
, key
) &&
803 (XkbKeyNumSyms(xkb
, key
) >= (unsigned) needed
))
804 return XkbKeyActionsPtr(xkb
, key
);
805 if (xkb
->server
->size_acts
- xkb
->server
->num_acts
>= (unsigned) needed
) {
806 xkb
->server
->key_acts
[key
] = xkb
->server
->num_acts
;
807 xkb
->server
->num_acts
+= needed
;
808 return &xkb
->server
->acts
[xkb
->server
->key_acts
[key
]];
810 xkb
->server
->size_acts
= xkb
->server
->num_acts
+ needed
+ 8;
811 newActs
= calloc(xkb
->server
->size_acts
, sizeof(XkbAction
));
814 newActs
[0].type
= XkbSA_NoAction
;
816 for (i
= xkb
->min_key_code
; i
<= (int) xkb
->max_key_code
; i
++) {
819 if ((xkb
->server
->key_acts
[i
] == 0) && (i
!= key
))
822 nCopy
= nKeyActs
= XkbKeyNumActions(xkb
, i
);
830 memcpy(&newActs
[nActs
], XkbKeyActionsPtr(xkb
, i
),
831 nCopy
* sizeof(XkbAction
));
832 if (nCopy
< nKeyActs
)
833 memset(&newActs
[nActs
+ nCopy
], 0,
834 (nKeyActs
- nCopy
) * sizeof(XkbAction
));
835 xkb
->server
->key_acts
[i
] = nActs
;
838 free(xkb
->server
->acts
);
839 xkb
->server
->acts
= newActs
;
840 xkb
->server
->num_acts
= nActs
;
841 return &xkb
->server
->acts
[xkb
->server
->key_acts
[key
]];
845 XkbFreeClientMap(XkbDescPtr xkb
, unsigned what
, Bool freeMap
)
849 if ((xkb
== NULL
) || (xkb
->map
== NULL
))
852 what
= XkbAllClientInfoMask
;
854 if (what
& XkbKeyTypesMask
) {
855 if (map
->types
!= NULL
) {
856 if (map
->num_types
> 0) {
860 for (i
= 0, type
= map
->types
; i
< map
->num_types
; i
++, type
++) {
863 free(type
->preserve
);
864 type
->preserve
= NULL
;
866 free(type
->level_names
);
867 type
->level_names
= NULL
;
871 map
->num_types
= map
->size_types
= 0;
875 if (what
& XkbKeySymsMask
) {
876 free(map
->key_sym_map
);
877 map
->key_sym_map
= NULL
;
878 if (map
->syms
!= NULL
) {
880 map
->size_syms
= map
->num_syms
= 0;
884 if ((what
& XkbModifierMapMask
) && (map
->modmap
!= NULL
)) {
896 XkbFreeServerMap(XkbDescPtr xkb
, unsigned what
, Bool freeMap
)
900 if ((xkb
== NULL
) || (xkb
->server
== NULL
))
903 what
= XkbAllServerInfoMask
;
905 if ((what
& XkbExplicitComponentsMask
) && (map
->explicit != NULL
)) {
907 map
->explicit = NULL
;
909 if (what
& XkbKeyActionsMask
) {
911 map
->key_acts
= NULL
;
912 if (map
->acts
!= NULL
) {
914 map
->num_acts
= map
->size_acts
= 0;
918 if ((what
& XkbKeyBehaviorsMask
) && (map
->behaviors
!= NULL
)) {
919 free(map
->behaviors
);
920 map
->behaviors
= NULL
;
922 if ((what
& XkbVirtualModMapMask
) && (map
->vmodmap
!= NULL
)) {