xref: /OK3568_Linux_fs/external/xserver/xkb/xkbInit.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /************************************************************
2*4882a593Smuzhiyun Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun Permission to use, copy, modify, and distribute this
5*4882a593Smuzhiyun software and its documentation for any purpose and without
6*4882a593Smuzhiyun fee is hereby granted, provided that the above copyright
7*4882a593Smuzhiyun notice appear in all copies and that both that copyright
8*4882a593Smuzhiyun notice and this permission notice appear in supporting
9*4882a593Smuzhiyun documentation, and that the name of Silicon Graphics not be
10*4882a593Smuzhiyun used in advertising or publicity pertaining to distribution
11*4882a593Smuzhiyun of the software without specific prior written permission.
12*4882a593Smuzhiyun Silicon Graphics makes no representation about the suitability
13*4882a593Smuzhiyun of this software for any purpose. It is provided "as is"
14*4882a593Smuzhiyun without any express or implied warranty.
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17*4882a593Smuzhiyun SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18*4882a593Smuzhiyun AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19*4882a593Smuzhiyun GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20*4882a593Smuzhiyun DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21*4882a593Smuzhiyun DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22*4882a593Smuzhiyun OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23*4882a593Smuzhiyun THE USE OR PERFORMANCE OF THIS SOFTWARE.
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun ********************************************************/
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
28*4882a593Smuzhiyun #include <dix-config.h>
29*4882a593Smuzhiyun #endif
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #include <xkb-config.h>
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #include <stdio.h>
34*4882a593Smuzhiyun #include <stdlib.h>
35*4882a593Smuzhiyun #include <ctype.h>
36*4882a593Smuzhiyun #include <unistd.h>
37*4882a593Smuzhiyun #include <math.h>
38*4882a593Smuzhiyun #include <X11/X.h>
39*4882a593Smuzhiyun #include <X11/Xproto.h>
40*4882a593Smuzhiyun #include <X11/keysym.h>
41*4882a593Smuzhiyun #include <X11/Xatom.h>
42*4882a593Smuzhiyun #include "misc.h"
43*4882a593Smuzhiyun #include "inputstr.h"
44*4882a593Smuzhiyun #include "opaque.h"
45*4882a593Smuzhiyun #include "property.h"
46*4882a593Smuzhiyun #include "scrnintstr.h"
47*4882a593Smuzhiyun #define	XKBSRV_NEED_FILE_FUNCS
48*4882a593Smuzhiyun #include <xkbsrv.h>
49*4882a593Smuzhiyun #include "xkbgeom.h"
50*4882a593Smuzhiyun #include <X11/extensions/XKMformat.h>
51*4882a593Smuzhiyun #include "xkbfile.h"
52*4882a593Smuzhiyun #include "xkb.h"
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define	CREATE_ATOM(s)	MakeAtom(s,sizeof(s)-1,1)
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun #if defined(__alpha) || defined(__alpha__)
57*4882a593Smuzhiyun #define	LED_COMPOSE	2
58*4882a593Smuzhiyun #define LED_CAPS	3
59*4882a593Smuzhiyun #define	LED_SCROLL	4
60*4882a593Smuzhiyun #define	LED_NUM		5
61*4882a593Smuzhiyun #define	PHYS_LEDS	0x1f
62*4882a593Smuzhiyun #else
63*4882a593Smuzhiyun #ifdef __sun
64*4882a593Smuzhiyun #define LED_NUM		1
65*4882a593Smuzhiyun #define	LED_SCROLL	2
66*4882a593Smuzhiyun #define	LED_COMPOSE	3
67*4882a593Smuzhiyun #define LED_CAPS	4
68*4882a593Smuzhiyun #define	PHYS_LEDS	0x0f
69*4882a593Smuzhiyun #else
70*4882a593Smuzhiyun #define	LED_CAPS	1
71*4882a593Smuzhiyun #define	LED_NUM		2
72*4882a593Smuzhiyun #define	LED_SCROLL	3
73*4882a593Smuzhiyun #define	PHYS_LEDS	0x07
74*4882a593Smuzhiyun #endif
75*4882a593Smuzhiyun #endif
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun #define	MAX_TOC	16
78*4882a593Smuzhiyun typedef struct _SrvXkmInfo {
79*4882a593Smuzhiyun     DeviceIntPtr dev;
80*4882a593Smuzhiyun     FILE *file;
81*4882a593Smuzhiyun     XkbDescPtr xkb;
82*4882a593Smuzhiyun } SrvXkmInfo;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun /***====================================================================***/
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun #ifndef XKB_DFLT_RULES_PROP
87*4882a593Smuzhiyun #define	XKB_DFLT_RULES_PROP	TRUE
88*4882a593Smuzhiyun #endif
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun const char *XkbBaseDirectory = XKB_BASE_DIRECTORY;
91*4882a593Smuzhiyun const char *XkbBinDirectory = XKB_BIN_DIRECTORY;
92*4882a593Smuzhiyun static int XkbWantAccessX = 0;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun static char *XkbRulesDflt = NULL;
95*4882a593Smuzhiyun static char *XkbModelDflt = NULL;
96*4882a593Smuzhiyun static char *XkbLayoutDflt = NULL;
97*4882a593Smuzhiyun static char *XkbVariantDflt = NULL;
98*4882a593Smuzhiyun static char *XkbOptionsDflt = NULL;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun static char *XkbRulesUsed = NULL;
101*4882a593Smuzhiyun static char *XkbModelUsed = NULL;
102*4882a593Smuzhiyun static char *XkbLayoutUsed = NULL;
103*4882a593Smuzhiyun static char *XkbVariantUsed = NULL;
104*4882a593Smuzhiyun static char *XkbOptionsUsed = NULL;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun static XkbDescPtr xkb_cached_map = NULL;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun static Bool XkbWantRulesProp = XKB_DFLT_RULES_PROP;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun /***====================================================================***/
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun /**
113*4882a593Smuzhiyun  * Get the current default XKB rules.
114*4882a593Smuzhiyun  * Caller must free the data in rmlvo.
115*4882a593Smuzhiyun  */
116*4882a593Smuzhiyun void
XkbGetRulesDflts(XkbRMLVOSet * rmlvo)117*4882a593Smuzhiyun XkbGetRulesDflts(XkbRMLVOSet * rmlvo)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun     rmlvo->rules = strdup(XkbRulesDflt ? XkbRulesDflt : XKB_DFLT_RULES);
120*4882a593Smuzhiyun     rmlvo->model = strdup(XkbModelDflt ? XkbModelDflt : XKB_DFLT_MODEL);
121*4882a593Smuzhiyun     rmlvo->layout = strdup(XkbLayoutDflt ? XkbLayoutDflt : XKB_DFLT_LAYOUT);
122*4882a593Smuzhiyun     rmlvo->variant = strdup(XkbVariantDflt ? XkbVariantDflt : XKB_DFLT_VARIANT);
123*4882a593Smuzhiyun     rmlvo->options = strdup(XkbOptionsDflt ? XkbOptionsDflt : XKB_DFLT_OPTIONS);
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun void
XkbFreeRMLVOSet(XkbRMLVOSet * rmlvo,Bool freeRMLVO)127*4882a593Smuzhiyun XkbFreeRMLVOSet(XkbRMLVOSet * rmlvo, Bool freeRMLVO)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun     if (!rmlvo)
130*4882a593Smuzhiyun         return;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun     free(rmlvo->rules);
133*4882a593Smuzhiyun     free(rmlvo->model);
134*4882a593Smuzhiyun     free(rmlvo->layout);
135*4882a593Smuzhiyun     free(rmlvo->variant);
136*4882a593Smuzhiyun     free(rmlvo->options);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun     if (freeRMLVO)
139*4882a593Smuzhiyun         free(rmlvo);
140*4882a593Smuzhiyun     else
141*4882a593Smuzhiyun         memset(rmlvo, 0, sizeof(XkbRMLVOSet));
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun static Bool
XkbWriteRulesProp(ClientPtr client,void * closure)145*4882a593Smuzhiyun XkbWriteRulesProp(ClientPtr client, void *closure)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun     int len, out;
148*4882a593Smuzhiyun     Atom name;
149*4882a593Smuzhiyun     char *pval;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun     len = (XkbRulesUsed ? strlen(XkbRulesUsed) : 0);
152*4882a593Smuzhiyun     len += (XkbModelUsed ? strlen(XkbModelUsed) : 0);
153*4882a593Smuzhiyun     len += (XkbLayoutUsed ? strlen(XkbLayoutUsed) : 0);
154*4882a593Smuzhiyun     len += (XkbVariantUsed ? strlen(XkbVariantUsed) : 0);
155*4882a593Smuzhiyun     len += (XkbOptionsUsed ? strlen(XkbOptionsUsed) : 0);
156*4882a593Smuzhiyun     if (len < 1)
157*4882a593Smuzhiyun         return TRUE;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun     len += 5;                   /* trailing NULs */
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun     name =
162*4882a593Smuzhiyun         MakeAtom(_XKB_RF_NAMES_PROP_ATOM, strlen(_XKB_RF_NAMES_PROP_ATOM), 1);
163*4882a593Smuzhiyun     if (name == None) {
164*4882a593Smuzhiyun         ErrorF("[xkb] Atom error: %s not created\n", _XKB_RF_NAMES_PROP_ATOM);
165*4882a593Smuzhiyun         return TRUE;
166*4882a593Smuzhiyun     }
167*4882a593Smuzhiyun     pval = (char *) malloc(len);
168*4882a593Smuzhiyun     if (!pval) {
169*4882a593Smuzhiyun         ErrorF("[xkb] Allocation error: %s proprerty not created\n",
170*4882a593Smuzhiyun                _XKB_RF_NAMES_PROP_ATOM);
171*4882a593Smuzhiyun         return TRUE;
172*4882a593Smuzhiyun     }
173*4882a593Smuzhiyun     out = 0;
174*4882a593Smuzhiyun     if (XkbRulesUsed) {
175*4882a593Smuzhiyun         strcpy(&pval[out], XkbRulesUsed);
176*4882a593Smuzhiyun         out += strlen(XkbRulesUsed);
177*4882a593Smuzhiyun     }
178*4882a593Smuzhiyun     pval[out++] = '\0';
179*4882a593Smuzhiyun     if (XkbModelUsed) {
180*4882a593Smuzhiyun         strcpy(&pval[out], XkbModelUsed);
181*4882a593Smuzhiyun         out += strlen(XkbModelUsed);
182*4882a593Smuzhiyun     }
183*4882a593Smuzhiyun     pval[out++] = '\0';
184*4882a593Smuzhiyun     if (XkbLayoutUsed) {
185*4882a593Smuzhiyun         strcpy(&pval[out], XkbLayoutUsed);
186*4882a593Smuzhiyun         out += strlen(XkbLayoutUsed);
187*4882a593Smuzhiyun     }
188*4882a593Smuzhiyun     pval[out++] = '\0';
189*4882a593Smuzhiyun     if (XkbVariantUsed) {
190*4882a593Smuzhiyun         strcpy(&pval[out], XkbVariantUsed);
191*4882a593Smuzhiyun         out += strlen(XkbVariantUsed);
192*4882a593Smuzhiyun     }
193*4882a593Smuzhiyun     pval[out++] = '\0';
194*4882a593Smuzhiyun     if (XkbOptionsUsed) {
195*4882a593Smuzhiyun         strcpy(&pval[out], XkbOptionsUsed);
196*4882a593Smuzhiyun         out += strlen(XkbOptionsUsed);
197*4882a593Smuzhiyun     }
198*4882a593Smuzhiyun     pval[out++] = '\0';
199*4882a593Smuzhiyun     if (out != len) {
200*4882a593Smuzhiyun         ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
201*4882a593Smuzhiyun                out, len);
202*4882a593Smuzhiyun     }
203*4882a593Smuzhiyun     dixChangeWindowProperty(serverClient, screenInfo.screens[0]->root, name,
204*4882a593Smuzhiyun                             XA_STRING, 8, PropModeReplace, len, pval, TRUE);
205*4882a593Smuzhiyun     free(pval);
206*4882a593Smuzhiyun     return TRUE;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun void
XkbInitRules(XkbRMLVOSet * rmlvo,const char * rules,const char * model,const char * layout,const char * variant,const char * options)210*4882a593Smuzhiyun XkbInitRules(XkbRMLVOSet *rmlvo,
211*4882a593Smuzhiyun              const char *rules,
212*4882a593Smuzhiyun              const char *model,
213*4882a593Smuzhiyun              const char *layout,
214*4882a593Smuzhiyun              const char *variant,
215*4882a593Smuzhiyun              const char *options)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun     rmlvo->rules = rules ? xnfstrdup(rules) : NULL;
218*4882a593Smuzhiyun     rmlvo->model = model ? xnfstrdup(model) : NULL;
219*4882a593Smuzhiyun     rmlvo->layout = layout ? xnfstrdup(layout) : NULL;
220*4882a593Smuzhiyun     rmlvo->variant = variant ? xnfstrdup(variant) : NULL;
221*4882a593Smuzhiyun     rmlvo->options = options ? xnfstrdup(options) : NULL;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun static void
XkbSetRulesUsed(XkbRMLVOSet * rmlvo)225*4882a593Smuzhiyun XkbSetRulesUsed(XkbRMLVOSet * rmlvo)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun     free(XkbRulesUsed);
228*4882a593Smuzhiyun     XkbRulesUsed = (rmlvo->rules ? Xstrdup(rmlvo->rules) : NULL);
229*4882a593Smuzhiyun     free(XkbModelUsed);
230*4882a593Smuzhiyun     XkbModelUsed = (rmlvo->model ? Xstrdup(rmlvo->model) : NULL);
231*4882a593Smuzhiyun     free(XkbLayoutUsed);
232*4882a593Smuzhiyun     XkbLayoutUsed = (rmlvo->layout ? Xstrdup(rmlvo->layout) : NULL);
233*4882a593Smuzhiyun     free(XkbVariantUsed);
234*4882a593Smuzhiyun     XkbVariantUsed = (rmlvo->variant ? Xstrdup(rmlvo->variant) : NULL);
235*4882a593Smuzhiyun     free(XkbOptionsUsed);
236*4882a593Smuzhiyun     XkbOptionsUsed = (rmlvo->options ? Xstrdup(rmlvo->options) : NULL);
237*4882a593Smuzhiyun     if (XkbWantRulesProp)
238*4882a593Smuzhiyun         QueueWorkProc(XkbWriteRulesProp, NULL, NULL);
239*4882a593Smuzhiyun     return;
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun void
XkbSetRulesDflts(XkbRMLVOSet * rmlvo)243*4882a593Smuzhiyun XkbSetRulesDflts(XkbRMLVOSet * rmlvo)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun     if (rmlvo->rules) {
246*4882a593Smuzhiyun         free(XkbRulesDflt);
247*4882a593Smuzhiyun         XkbRulesDflt = Xstrdup(rmlvo->rules);
248*4882a593Smuzhiyun     }
249*4882a593Smuzhiyun     if (rmlvo->model) {
250*4882a593Smuzhiyun         free(XkbModelDflt);
251*4882a593Smuzhiyun         XkbModelDflt = Xstrdup(rmlvo->model);
252*4882a593Smuzhiyun     }
253*4882a593Smuzhiyun     if (rmlvo->layout) {
254*4882a593Smuzhiyun         free(XkbLayoutDflt);
255*4882a593Smuzhiyun         XkbLayoutDflt = Xstrdup(rmlvo->layout);
256*4882a593Smuzhiyun     }
257*4882a593Smuzhiyun     if (rmlvo->variant) {
258*4882a593Smuzhiyun         free(XkbVariantDflt);
259*4882a593Smuzhiyun         XkbVariantDflt = Xstrdup(rmlvo->variant);
260*4882a593Smuzhiyun     }
261*4882a593Smuzhiyun     if (rmlvo->options) {
262*4882a593Smuzhiyun         free(XkbOptionsDflt);
263*4882a593Smuzhiyun         XkbOptionsDflt = Xstrdup(rmlvo->options);
264*4882a593Smuzhiyun     }
265*4882a593Smuzhiyun     return;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun void
XkbDeleteRulesUsed(void)269*4882a593Smuzhiyun XkbDeleteRulesUsed(void)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun     free(XkbRulesUsed);
272*4882a593Smuzhiyun     XkbRulesUsed = NULL;
273*4882a593Smuzhiyun     free(XkbModelUsed);
274*4882a593Smuzhiyun     XkbModelUsed = NULL;
275*4882a593Smuzhiyun     free(XkbLayoutUsed);
276*4882a593Smuzhiyun     XkbLayoutUsed = NULL;
277*4882a593Smuzhiyun     free(XkbVariantUsed);
278*4882a593Smuzhiyun     XkbVariantUsed = NULL;
279*4882a593Smuzhiyun     free(XkbOptionsUsed);
280*4882a593Smuzhiyun     XkbOptionsUsed = NULL;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun void
XkbDeleteRulesDflts(void)284*4882a593Smuzhiyun XkbDeleteRulesDflts(void)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun     free(XkbRulesDflt);
287*4882a593Smuzhiyun     XkbRulesDflt = NULL;
288*4882a593Smuzhiyun     free(XkbModelDflt);
289*4882a593Smuzhiyun     XkbModelDflt = NULL;
290*4882a593Smuzhiyun     free(XkbLayoutDflt);
291*4882a593Smuzhiyun     XkbLayoutDflt = NULL;
292*4882a593Smuzhiyun     free(XkbVariantDflt);
293*4882a593Smuzhiyun     XkbVariantDflt = NULL;
294*4882a593Smuzhiyun     free(XkbOptionsDflt);
295*4882a593Smuzhiyun     XkbOptionsDflt = NULL;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun     XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
298*4882a593Smuzhiyun     xkb_cached_map = NULL;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun #define DIFFERS(a, b) (strcmp((a) ? (a) : "", (b) ? (b) : "") != 0)
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun static Bool
XkbCompareUsedRMLVO(XkbRMLVOSet * rmlvo)304*4882a593Smuzhiyun XkbCompareUsedRMLVO(XkbRMLVOSet * rmlvo)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun     if (DIFFERS(rmlvo->rules, XkbRulesUsed) ||
307*4882a593Smuzhiyun         DIFFERS(rmlvo->model, XkbModelUsed) ||
308*4882a593Smuzhiyun         DIFFERS(rmlvo->layout, XkbLayoutUsed) ||
309*4882a593Smuzhiyun         DIFFERS(rmlvo->variant, XkbVariantUsed) ||
310*4882a593Smuzhiyun         DIFFERS(rmlvo->options, XkbOptionsUsed))
311*4882a593Smuzhiyun         return FALSE;
312*4882a593Smuzhiyun     return TRUE;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun #undef DIFFERS
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun /***====================================================================***/
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun #include "xkbDflts.h"
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun static Bool
XkbInitKeyTypes(XkbDescPtr xkb)322*4882a593Smuzhiyun XkbInitKeyTypes(XkbDescPtr xkb)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun     if (xkb->defined & XkmTypesMask)
325*4882a593Smuzhiyun         return TRUE;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun     initTypeNames(NULL);
328*4882a593Smuzhiyun     if (XkbAllocClientMap(xkb, XkbKeyTypesMask, num_dflt_types) != Success)
329*4882a593Smuzhiyun         return FALSE;
330*4882a593Smuzhiyun     if (XkbCopyKeyTypes(dflt_types, xkb->map->types, num_dflt_types) != Success) {
331*4882a593Smuzhiyun         return FALSE;
332*4882a593Smuzhiyun     }
333*4882a593Smuzhiyun     xkb->map->size_types = xkb->map->num_types = num_dflt_types;
334*4882a593Smuzhiyun     return TRUE;
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun static void
XkbInitRadioGroups(XkbSrvInfoPtr xkbi)338*4882a593Smuzhiyun XkbInitRadioGroups(XkbSrvInfoPtr xkbi)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun     xkbi->nRadioGroups = 0;
341*4882a593Smuzhiyun     xkbi->radioGroups = NULL;
342*4882a593Smuzhiyun     return;
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun static Status
XkbInitCompatStructs(XkbDescPtr xkb)346*4882a593Smuzhiyun XkbInitCompatStructs(XkbDescPtr xkb)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun     register int i;
349*4882a593Smuzhiyun     XkbCompatMapPtr compat;
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun     if (xkb->defined & XkmCompatMapMask)
352*4882a593Smuzhiyun         return TRUE;
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun     if (XkbAllocCompatMap(xkb, XkbAllCompatMask, num_dfltSI) != Success)
355*4882a593Smuzhiyun         return BadAlloc;
356*4882a593Smuzhiyun     compat = xkb->compat;
357*4882a593Smuzhiyun     if (compat->sym_interpret) {
358*4882a593Smuzhiyun         compat->num_si = num_dfltSI;
359*4882a593Smuzhiyun         memcpy((char *) compat->sym_interpret, (char *) dfltSI, sizeof(dfltSI));
360*4882a593Smuzhiyun     }
361*4882a593Smuzhiyun     for (i = 0; i < XkbNumKbdGroups; i++) {
362*4882a593Smuzhiyun         compat->groups[i] = compatMap.groups[i];
363*4882a593Smuzhiyun         if (compat->groups[i].vmods != 0) {
364*4882a593Smuzhiyun             unsigned mask;
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun             mask = XkbMaskForVMask(xkb, compat->groups[i].vmods);
367*4882a593Smuzhiyun             compat->groups[i].mask = compat->groups[i].real_mods | mask;
368*4882a593Smuzhiyun         }
369*4882a593Smuzhiyun         else
370*4882a593Smuzhiyun             compat->groups[i].mask = compat->groups[i].real_mods;
371*4882a593Smuzhiyun     }
372*4882a593Smuzhiyun     return Success;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun static void
XkbInitSemantics(XkbDescPtr xkb)376*4882a593Smuzhiyun XkbInitSemantics(XkbDescPtr xkb)
377*4882a593Smuzhiyun {
378*4882a593Smuzhiyun     XkbInitKeyTypes(xkb);
379*4882a593Smuzhiyun     XkbInitCompatStructs(xkb);
380*4882a593Smuzhiyun     return;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun /***====================================================================***/
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun static Status
XkbInitNames(XkbSrvInfoPtr xkbi)386*4882a593Smuzhiyun XkbInitNames(XkbSrvInfoPtr xkbi)
387*4882a593Smuzhiyun {
388*4882a593Smuzhiyun     XkbDescPtr xkb;
389*4882a593Smuzhiyun     XkbNamesPtr names;
390*4882a593Smuzhiyun     Status rtrn;
391*4882a593Smuzhiyun     Atom unknown;
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun     xkb = xkbi->desc;
394*4882a593Smuzhiyun     if ((rtrn = XkbAllocNames(xkb, XkbAllNamesMask, 0, 0)) != Success)
395*4882a593Smuzhiyun         return rtrn;
396*4882a593Smuzhiyun     unknown = CREATE_ATOM("unknown");
397*4882a593Smuzhiyun     names = xkb->names;
398*4882a593Smuzhiyun     if (names->keycodes == None)
399*4882a593Smuzhiyun         names->keycodes = unknown;
400*4882a593Smuzhiyun     if (names->geometry == None)
401*4882a593Smuzhiyun         names->geometry = unknown;
402*4882a593Smuzhiyun     if (names->phys_symbols == None)
403*4882a593Smuzhiyun         names->phys_symbols = unknown;
404*4882a593Smuzhiyun     if (names->symbols == None)
405*4882a593Smuzhiyun         names->symbols = unknown;
406*4882a593Smuzhiyun     if (names->types == None)
407*4882a593Smuzhiyun         names->types = unknown;
408*4882a593Smuzhiyun     if (names->compat == None)
409*4882a593Smuzhiyun         names->compat = unknown;
410*4882a593Smuzhiyun     if (!(xkb->defined & XkmVirtualModsMask)) {
411*4882a593Smuzhiyun         if (names->vmods[vmod_NumLock] == None)
412*4882a593Smuzhiyun             names->vmods[vmod_NumLock] = CREATE_ATOM("NumLock");
413*4882a593Smuzhiyun         if (names->vmods[vmod_Alt] == None)
414*4882a593Smuzhiyun             names->vmods[vmod_Alt] = CREATE_ATOM("Alt");
415*4882a593Smuzhiyun         if (names->vmods[vmod_AltGr] == None)
416*4882a593Smuzhiyun             names->vmods[vmod_AltGr] = CREATE_ATOM("ModeSwitch");
417*4882a593Smuzhiyun     }
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun     if (!(xkb->defined & XkmIndicatorsMask) ||
420*4882a593Smuzhiyun         !(xkb->defined & XkmGeometryMask)) {
421*4882a593Smuzhiyun         initIndicatorNames(NULL, xkb);
422*4882a593Smuzhiyun         if (names->indicators[LED_CAPS - 1] == None)
423*4882a593Smuzhiyun             names->indicators[LED_CAPS - 1] = CREATE_ATOM("Caps Lock");
424*4882a593Smuzhiyun         if (names->indicators[LED_NUM - 1] == None)
425*4882a593Smuzhiyun             names->indicators[LED_NUM - 1] = CREATE_ATOM("Num Lock");
426*4882a593Smuzhiyun         if (names->indicators[LED_SCROLL - 1] == None)
427*4882a593Smuzhiyun             names->indicators[LED_SCROLL - 1] = CREATE_ATOM("Scroll Lock");
428*4882a593Smuzhiyun #ifdef LED_COMPOSE
429*4882a593Smuzhiyun         if (names->indicators[LED_COMPOSE - 1] == None)
430*4882a593Smuzhiyun             names->indicators[LED_COMPOSE - 1] = CREATE_ATOM("Compose");
431*4882a593Smuzhiyun #endif
432*4882a593Smuzhiyun     }
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun     if (xkb->geom != NULL)
435*4882a593Smuzhiyun         names->geometry = xkb->geom->name;
436*4882a593Smuzhiyun     else
437*4882a593Smuzhiyun         names->geometry = unknown;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun     return Success;
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun static Status
XkbInitIndicatorMap(XkbSrvInfoPtr xkbi)443*4882a593Smuzhiyun XkbInitIndicatorMap(XkbSrvInfoPtr xkbi)
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun     XkbDescPtr xkb;
446*4882a593Smuzhiyun     XkbIndicatorPtr map;
447*4882a593Smuzhiyun     XkbSrvLedInfoPtr sli;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun     xkb = xkbi->desc;
450*4882a593Smuzhiyun     if (XkbAllocIndicatorMaps(xkb) != Success)
451*4882a593Smuzhiyun         return BadAlloc;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun     if (!(xkb->defined & XkmIndicatorsMask)) {
454*4882a593Smuzhiyun         map = xkb->indicators;
455*4882a593Smuzhiyun         map->phys_indicators = PHYS_LEDS;
456*4882a593Smuzhiyun         map->maps[LED_CAPS - 1].flags = XkbIM_NoExplicit;
457*4882a593Smuzhiyun         map->maps[LED_CAPS - 1].which_mods = XkbIM_UseLocked;
458*4882a593Smuzhiyun         map->maps[LED_CAPS - 1].mods.mask = LockMask;
459*4882a593Smuzhiyun         map->maps[LED_CAPS - 1].mods.real_mods = LockMask;
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun         map->maps[LED_NUM - 1].flags = XkbIM_NoExplicit;
462*4882a593Smuzhiyun         map->maps[LED_NUM - 1].which_mods = XkbIM_UseLocked;
463*4882a593Smuzhiyun         map->maps[LED_NUM - 1].mods.mask = 0;
464*4882a593Smuzhiyun         map->maps[LED_NUM - 1].mods.real_mods = 0;
465*4882a593Smuzhiyun         map->maps[LED_NUM - 1].mods.vmods = vmod_NumLockMask;
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun         map->maps[LED_SCROLL - 1].flags = XkbIM_NoExplicit;
468*4882a593Smuzhiyun         map->maps[LED_SCROLL - 1].which_mods = XkbIM_UseLocked;
469*4882a593Smuzhiyun         map->maps[LED_SCROLL - 1].mods.mask = Mod3Mask;
470*4882a593Smuzhiyun         map->maps[LED_SCROLL - 1].mods.real_mods = Mod3Mask;
471*4882a593Smuzhiyun     }
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun     sli = XkbFindSrvLedInfo(xkbi->device, XkbDfltXIClass, XkbDfltXIId, 0);
474*4882a593Smuzhiyun     if (sli)
475*4882a593Smuzhiyun         XkbCheckIndicatorMaps(xkbi->device, sli, XkbAllIndicatorsMask);
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun     return Success;
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun static Status
XkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi)481*4882a593Smuzhiyun XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
482*4882a593Smuzhiyun {
483*4882a593Smuzhiyun     XkbDescPtr xkb;
484*4882a593Smuzhiyun     XkbControlsPtr ctrls;
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun     xkb = xkbi->desc;
487*4882a593Smuzhiyun     /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */
488*4882a593Smuzhiyun     if (XkbAllocControls(xkb, XkbAllControlsMask) != Success)
489*4882a593Smuzhiyun         FatalError("Couldn't allocate keyboard controls\n");
490*4882a593Smuzhiyun     ctrls = xkb->ctrls;
491*4882a593Smuzhiyun     if (!(xkb->defined & XkmSymbolsMask))
492*4882a593Smuzhiyun         ctrls->num_groups = 1;
493*4882a593Smuzhiyun     ctrls->groups_wrap = XkbSetGroupInfo(1, XkbWrapIntoRange, 0);
494*4882a593Smuzhiyun     ctrls->internal.mask = 0;
495*4882a593Smuzhiyun     ctrls->internal.real_mods = 0;
496*4882a593Smuzhiyun     ctrls->internal.vmods = 0;
497*4882a593Smuzhiyun     ctrls->ignore_lock.mask = 0;
498*4882a593Smuzhiyun     ctrls->ignore_lock.real_mods = 0;
499*4882a593Smuzhiyun     ctrls->ignore_lock.vmods = 0;
500*4882a593Smuzhiyun     ctrls->enabled_ctrls = XkbAccessXTimeoutMask | XkbRepeatKeysMask |
501*4882a593Smuzhiyun         XkbMouseKeysAccelMask | XkbAudibleBellMask | XkbIgnoreGroupLockMask;
502*4882a593Smuzhiyun     if (XkbWantAccessX)
503*4882a593Smuzhiyun         ctrls->enabled_ctrls |= XkbAccessXKeysMask;
504*4882a593Smuzhiyun     AccessXInit(pXDev);
505*4882a593Smuzhiyun     return Success;
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun static Status
XkbInitOverlayState(XkbSrvInfoPtr xkbi)509*4882a593Smuzhiyun XkbInitOverlayState(XkbSrvInfoPtr xkbi)
510*4882a593Smuzhiyun {
511*4882a593Smuzhiyun     memset(xkbi->overlay_perkey_state, 0, sizeof(xkbi->overlay_perkey_state));
512*4882a593Smuzhiyun     return Success;
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun static Bool
InitKeyboardDeviceStructInternal(DeviceIntPtr dev,XkbRMLVOSet * rmlvo,const char * keymap,int keymap_length,BellProcPtr bell_func,KbdCtrlProcPtr ctrl_func)516*4882a593Smuzhiyun InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
517*4882a593Smuzhiyun                                  const char *keymap, int keymap_length,
518*4882a593Smuzhiyun                                  BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
519*4882a593Smuzhiyun {
520*4882a593Smuzhiyun     int i;
521*4882a593Smuzhiyun     unsigned int check;
522*4882a593Smuzhiyun     XkbSrvInfoPtr xkbi;
523*4882a593Smuzhiyun     XkbDescPtr xkb;
524*4882a593Smuzhiyun     XkbSrvLedInfoPtr sli;
525*4882a593Smuzhiyun     XkbChangesRec changes;
526*4882a593Smuzhiyun     XkbEventCauseRec cause;
527*4882a593Smuzhiyun     XkbRMLVOSet rmlvo_dflts = { NULL };
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun     BUG_RETURN_VAL(dev == NULL, FALSE);
530*4882a593Smuzhiyun     BUG_RETURN_VAL(dev->key != NULL, FALSE);
531*4882a593Smuzhiyun     BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
532*4882a593Smuzhiyun     BUG_RETURN_VAL(rmlvo && keymap, FALSE);
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun     if (!rmlvo && !keymap) {
535*4882a593Smuzhiyun         rmlvo = &rmlvo_dflts;
536*4882a593Smuzhiyun         XkbGetRulesDflts(rmlvo);
537*4882a593Smuzhiyun     }
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun     memset(&changes, 0, sizeof(changes));
540*4882a593Smuzhiyun     XkbSetCauseUnknown(&cause);
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun     dev->key = calloc(1, sizeof(*dev->key));
543*4882a593Smuzhiyun     if (!dev->key) {
544*4882a593Smuzhiyun         ErrorF("XKB: Failed to allocate key class\n");
545*4882a593Smuzhiyun         return FALSE;
546*4882a593Smuzhiyun     }
547*4882a593Smuzhiyun     dev->key->sourceid = dev->id;
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun     dev->kbdfeed = calloc(1, sizeof(*dev->kbdfeed));
550*4882a593Smuzhiyun     if (!dev->kbdfeed) {
551*4882a593Smuzhiyun         ErrorF("XKB: Failed to allocate key feedback class\n");
552*4882a593Smuzhiyun         goto unwind_key;
553*4882a593Smuzhiyun     }
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun     xkbi = calloc(1, sizeof(*xkbi));
556*4882a593Smuzhiyun     if (!xkbi) {
557*4882a593Smuzhiyun         ErrorF("XKB: Failed to allocate XKB info\n");
558*4882a593Smuzhiyun         goto unwind_kbdfeed;
559*4882a593Smuzhiyun     }
560*4882a593Smuzhiyun     dev->key->xkbInfo = xkbi;
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun     if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
563*4882a593Smuzhiyun         XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
564*4882a593Smuzhiyun         xkb_cached_map = NULL;
565*4882a593Smuzhiyun     }
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun     if (xkb_cached_map)
568*4882a593Smuzhiyun         LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
569*4882a593Smuzhiyun     else {
570*4882a593Smuzhiyun         if (rmlvo)
571*4882a593Smuzhiyun             xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
572*4882a593Smuzhiyun         else
573*4882a593Smuzhiyun             xkb_cached_map = XkbCompileKeymapFromString(dev, keymap, keymap_length);
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun         if (!xkb_cached_map) {
576*4882a593Smuzhiyun             ErrorF("XKB: Failed to compile keymap\n");
577*4882a593Smuzhiyun             goto unwind_info;
578*4882a593Smuzhiyun         }
579*4882a593Smuzhiyun     }
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun     xkb = XkbAllocKeyboard();
582*4882a593Smuzhiyun     if (!xkb) {
583*4882a593Smuzhiyun         ErrorF("XKB: Failed to allocate keyboard description\n");
584*4882a593Smuzhiyun         goto unwind_info;
585*4882a593Smuzhiyun     }
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun     if (!XkbCopyKeymap(xkb, xkb_cached_map)) {
588*4882a593Smuzhiyun         ErrorF("XKB: Failed to copy keymap\n");
589*4882a593Smuzhiyun         goto unwind_desc;
590*4882a593Smuzhiyun     }
591*4882a593Smuzhiyun     xkb->defined = xkb_cached_map->defined;
592*4882a593Smuzhiyun     xkb->flags = xkb_cached_map->flags;
593*4882a593Smuzhiyun     xkb->device_spec = xkb_cached_map->device_spec;
594*4882a593Smuzhiyun     xkbi->desc = xkb;
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun     if (xkb->min_key_code == 0)
597*4882a593Smuzhiyun         xkb->min_key_code = 8;
598*4882a593Smuzhiyun     if (xkb->max_key_code == 0)
599*4882a593Smuzhiyun         xkb->max_key_code = 255;
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun     i = XkbNumKeys(xkb) / 3 + 1;
602*4882a593Smuzhiyun     if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success)
603*4882a593Smuzhiyun         goto unwind_desc;
604*4882a593Smuzhiyun     if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success)
605*4882a593Smuzhiyun         goto unwind_desc;
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun     xkbi->dfltPtrDelta = 1;
608*4882a593Smuzhiyun     xkbi->device = dev;
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun     XkbInitSemantics(xkb);
611*4882a593Smuzhiyun     XkbInitNames(xkbi);
612*4882a593Smuzhiyun     XkbInitRadioGroups(xkbi);
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun     XkbInitControls(dev, xkbi);
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun     XkbInitIndicatorMap(xkbi);
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun     XkbInitOverlayState(xkbi);
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun     XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
621*4882a593Smuzhiyun                      &check, &cause);
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun     if (!dev->focus)
624*4882a593Smuzhiyun         InitFocusClassDeviceStruct(dev);
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun     xkbi->kbdProc = ctrl_func;
627*4882a593Smuzhiyun     dev->kbdfeed->BellProc = bell_func;
628*4882a593Smuzhiyun     dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc;
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun     dev->kbdfeed->ctrl = defaultKeyboardControl;
631*4882a593Smuzhiyun     if (dev->kbdfeed->ctrl.autoRepeat)
632*4882a593Smuzhiyun         xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask;
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun     memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat,
635*4882a593Smuzhiyun            XkbPerKeyBitArraySize);
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun     sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
638*4882a593Smuzhiyun     if (sli)
639*4882a593Smuzhiyun         XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask);
640*4882a593Smuzhiyun     else
641*4882a593Smuzhiyun         DebugF("XKB: No indicator feedback in XkbFinishInit!\n");
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun     dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun     if (rmlvo) {
646*4882a593Smuzhiyun         XkbSetRulesDflts(rmlvo);
647*4882a593Smuzhiyun         XkbSetRulesUsed(rmlvo);
648*4882a593Smuzhiyun     }
649*4882a593Smuzhiyun     XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun     return TRUE;
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun  unwind_desc:
654*4882a593Smuzhiyun     XkbFreeKeyboard(xkb, 0, TRUE);
655*4882a593Smuzhiyun  unwind_info:
656*4882a593Smuzhiyun     free(xkbi);
657*4882a593Smuzhiyun     dev->key->xkbInfo = NULL;
658*4882a593Smuzhiyun  unwind_kbdfeed:
659*4882a593Smuzhiyun     free(dev->kbdfeed);
660*4882a593Smuzhiyun     dev->kbdfeed = NULL;
661*4882a593Smuzhiyun  unwind_key:
662*4882a593Smuzhiyun     free(dev->key);
663*4882a593Smuzhiyun     dev->key = NULL;
664*4882a593Smuzhiyun     return FALSE;
665*4882a593Smuzhiyun }
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun _X_EXPORT Bool
InitKeyboardDeviceStruct(DeviceIntPtr dev,XkbRMLVOSet * rmlvo,BellProcPtr bell_func,KbdCtrlProcPtr ctrl_func)668*4882a593Smuzhiyun InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
669*4882a593Smuzhiyun                          BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
670*4882a593Smuzhiyun {
671*4882a593Smuzhiyun     return InitKeyboardDeviceStructInternal(dev, rmlvo,
672*4882a593Smuzhiyun                                             NULL, 0, bell_func, ctrl_func);
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun _X_EXPORT Bool
InitKeyboardDeviceStructFromString(DeviceIntPtr dev,const char * keymap,int keymap_length,BellProcPtr bell_func,KbdCtrlProcPtr ctrl_func)676*4882a593Smuzhiyun InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
677*4882a593Smuzhiyun                                    const char *keymap, int keymap_length,
678*4882a593Smuzhiyun                                    BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun     return InitKeyboardDeviceStructInternal(dev, NULL,
681*4882a593Smuzhiyun                                             keymap, keymap_length,
682*4882a593Smuzhiyun                                             bell_func, ctrl_func);
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun /***====================================================================***/
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun         /*
688*4882a593Smuzhiyun          * Be very careful about what does and doesn't get freed by this
689*4882a593Smuzhiyun          * function.  To reduce fragmentation, XkbInitDevice allocates a
690*4882a593Smuzhiyun          * single huge block per device and divides it up into most of the
691*4882a593Smuzhiyun          * fixed-size structures for the device.   Don't free anything that
692*4882a593Smuzhiyun          * is part of this larger block.
693*4882a593Smuzhiyun          */
694*4882a593Smuzhiyun void
XkbFreeInfo(XkbSrvInfoPtr xkbi)695*4882a593Smuzhiyun XkbFreeInfo(XkbSrvInfoPtr xkbi)
696*4882a593Smuzhiyun {
697*4882a593Smuzhiyun     free(xkbi->radioGroups);
698*4882a593Smuzhiyun     xkbi->radioGroups = NULL;
699*4882a593Smuzhiyun     if (xkbi->mouseKeyTimer) {
700*4882a593Smuzhiyun         TimerFree(xkbi->mouseKeyTimer);
701*4882a593Smuzhiyun         xkbi->mouseKeyTimer = NULL;
702*4882a593Smuzhiyun     }
703*4882a593Smuzhiyun     if (xkbi->slowKeysTimer) {
704*4882a593Smuzhiyun         TimerFree(xkbi->slowKeysTimer);
705*4882a593Smuzhiyun         xkbi->slowKeysTimer = NULL;
706*4882a593Smuzhiyun     }
707*4882a593Smuzhiyun     if (xkbi->bounceKeysTimer) {
708*4882a593Smuzhiyun         TimerFree(xkbi->bounceKeysTimer);
709*4882a593Smuzhiyun         xkbi->bounceKeysTimer = NULL;
710*4882a593Smuzhiyun     }
711*4882a593Smuzhiyun     if (xkbi->repeatKeyTimer) {
712*4882a593Smuzhiyun         TimerFree(xkbi->repeatKeyTimer);
713*4882a593Smuzhiyun         xkbi->repeatKeyTimer = NULL;
714*4882a593Smuzhiyun     }
715*4882a593Smuzhiyun     if (xkbi->krgTimer) {
716*4882a593Smuzhiyun         TimerFree(xkbi->krgTimer);
717*4882a593Smuzhiyun         xkbi->krgTimer = NULL;
718*4882a593Smuzhiyun     }
719*4882a593Smuzhiyun     xkbi->beepType = _BEEP_NONE;
720*4882a593Smuzhiyun     if (xkbi->beepTimer) {
721*4882a593Smuzhiyun         TimerFree(xkbi->beepTimer);
722*4882a593Smuzhiyun         xkbi->beepTimer = NULL;
723*4882a593Smuzhiyun     }
724*4882a593Smuzhiyun     if (xkbi->desc) {
725*4882a593Smuzhiyun         XkbFreeKeyboard(xkbi->desc, XkbAllComponentsMask, TRUE);
726*4882a593Smuzhiyun         xkbi->desc = NULL;
727*4882a593Smuzhiyun     }
728*4882a593Smuzhiyun     free(xkbi);
729*4882a593Smuzhiyun     return;
730*4882a593Smuzhiyun }
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun /***====================================================================***/
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun extern int XkbDfltRepeatDelay;
735*4882a593Smuzhiyun extern int XkbDfltRepeatInterval;
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun extern unsigned short XkbDfltAccessXTimeout;
738*4882a593Smuzhiyun extern unsigned int XkbDfltAccessXTimeoutMask;
739*4882a593Smuzhiyun extern unsigned int XkbDfltAccessXFeedback;
740*4882a593Smuzhiyun extern unsigned short XkbDfltAccessXOptions;
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun int
XkbProcessArguments(int argc,char * argv[],int i)743*4882a593Smuzhiyun XkbProcessArguments(int argc, char *argv[], int i)
744*4882a593Smuzhiyun {
745*4882a593Smuzhiyun     if (strncmp(argv[i], "-xkbdir", 7) == 0) {
746*4882a593Smuzhiyun         if (++i < argc) {
747*4882a593Smuzhiyun #if !defined(WIN32) && !defined(__CYGWIN__)
748*4882a593Smuzhiyun             if (getuid() != geteuid()) {
749*4882a593Smuzhiyun                 LogMessage(X_WARNING,
750*4882a593Smuzhiyun                            "-xkbdir is not available for setuid X servers\n");
751*4882a593Smuzhiyun                 return -1;
752*4882a593Smuzhiyun             }
753*4882a593Smuzhiyun             else
754*4882a593Smuzhiyun #endif
755*4882a593Smuzhiyun             {
756*4882a593Smuzhiyun                 if (strlen(argv[i]) < PATH_MAX) {
757*4882a593Smuzhiyun                     XkbBaseDirectory = argv[i];
758*4882a593Smuzhiyun                     return 2;
759*4882a593Smuzhiyun                 }
760*4882a593Smuzhiyun                 else {
761*4882a593Smuzhiyun                     LogMessage(X_ERROR, "-xkbdir pathname too long\n");
762*4882a593Smuzhiyun                     return -1;
763*4882a593Smuzhiyun                 }
764*4882a593Smuzhiyun             }
765*4882a593Smuzhiyun         }
766*4882a593Smuzhiyun         else {
767*4882a593Smuzhiyun             return -1;
768*4882a593Smuzhiyun         }
769*4882a593Smuzhiyun     }
770*4882a593Smuzhiyun     else if ((strncmp(argv[i], "-accessx", 8) == 0) ||
771*4882a593Smuzhiyun              (strncmp(argv[i], "+accessx", 8) == 0)) {
772*4882a593Smuzhiyun         int j = 1;
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun         if (argv[i][0] == '-')
775*4882a593Smuzhiyun             XkbWantAccessX = 0;
776*4882a593Smuzhiyun         else {
777*4882a593Smuzhiyun             XkbWantAccessX = 1;
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun             if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
780*4882a593Smuzhiyun                 XkbDfltAccessXTimeout = atoi(argv[++i]);
781*4882a593Smuzhiyun                 j++;
782*4882a593Smuzhiyun 
783*4882a593Smuzhiyun                 if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
784*4882a593Smuzhiyun                     /*
785*4882a593Smuzhiyun                      * presumption that the reasonably useful range of
786*4882a593Smuzhiyun                      * values fits in 0..MAXINT since SunOS 4 doesn't
787*4882a593Smuzhiyun                      * have strtoul.
788*4882a593Smuzhiyun                      */
789*4882a593Smuzhiyun                     XkbDfltAccessXTimeoutMask = (unsigned int)
790*4882a593Smuzhiyun                         strtol(argv[++i], NULL, 16);
791*4882a593Smuzhiyun                     j++;
792*4882a593Smuzhiyun                 }
793*4882a593Smuzhiyun                 if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
794*4882a593Smuzhiyun                     if (argv[++i][0] == '1')
795*4882a593Smuzhiyun                         XkbDfltAccessXFeedback = XkbAccessXFeedbackMask;
796*4882a593Smuzhiyun                     else
797*4882a593Smuzhiyun                         XkbDfltAccessXFeedback = 0;
798*4882a593Smuzhiyun                     j++;
799*4882a593Smuzhiyun                 }
800*4882a593Smuzhiyun                 if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
801*4882a593Smuzhiyun                     XkbDfltAccessXOptions = (unsigned short)
802*4882a593Smuzhiyun                         strtol(argv[++i], NULL, 16);
803*4882a593Smuzhiyun                     j++;
804*4882a593Smuzhiyun                 }
805*4882a593Smuzhiyun             }
806*4882a593Smuzhiyun         }
807*4882a593Smuzhiyun         return j;
808*4882a593Smuzhiyun     }
809*4882a593Smuzhiyun     if ((strcmp(argv[i], "-ardelay") == 0) || (strcmp(argv[i], "-ar1") == 0)) { /* -ardelay int */
810*4882a593Smuzhiyun         if (++i >= argc)
811*4882a593Smuzhiyun             UseMsg();
812*4882a593Smuzhiyun         else
813*4882a593Smuzhiyun             XkbDfltRepeatDelay = (long) atoi(argv[i]);
814*4882a593Smuzhiyun         return 2;
815*4882a593Smuzhiyun     }
816*4882a593Smuzhiyun     if ((strcmp(argv[i], "-arinterval") == 0) || (strcmp(argv[i], "-ar2") == 0)) {      /* -arinterval int */
817*4882a593Smuzhiyun         if (++i >= argc)
818*4882a593Smuzhiyun             UseMsg();
819*4882a593Smuzhiyun         else
820*4882a593Smuzhiyun             XkbDfltRepeatInterval = (long) atoi(argv[i]);
821*4882a593Smuzhiyun         return 2;
822*4882a593Smuzhiyun     }
823*4882a593Smuzhiyun     return 0;
824*4882a593Smuzhiyun }
825*4882a593Smuzhiyun 
826*4882a593Smuzhiyun void
XkbUseMsg(void)827*4882a593Smuzhiyun XkbUseMsg(void)
828*4882a593Smuzhiyun {
829*4882a593Smuzhiyun     ErrorF
830*4882a593Smuzhiyun         ("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n");
831*4882a593Smuzhiyun     ErrorF("                       enable/disable accessx key sequences\n");
832*4882a593Smuzhiyun     ErrorF("-ardelay               set XKB autorepeat delay\n");
833*4882a593Smuzhiyun     ErrorF("-arinterval            set XKB autorepeat interval\n");
834*4882a593Smuzhiyun }
835