misc.c revision f46a6179
1f46a6179Smrg/* $Xorg: misc.c,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */
2f46a6179Smrg/************************************************************
3f46a6179Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
4f46a6179Smrg
5f46a6179Smrg Permission to use, copy, modify, and distribute this
6f46a6179Smrg software and its documentation for any purpose and without
7f46a6179Smrg fee is hereby granted, provided that the above copyright
8f46a6179Smrg notice appear in all copies and that both that copyright
9f46a6179Smrg notice and this permission notice appear in supporting
10f46a6179Smrg documentation, and that the name of Silicon Graphics not be
11f46a6179Smrg used in advertising or publicity pertaining to distribution
12f46a6179Smrg of the software without specific prior written permission.
13f46a6179Smrg Silicon Graphics makes no representation about the suitability
14f46a6179Smrg of this software for any purpose. It is provided "as is"
15f46a6179Smrg without any express or implied warranty.
16f46a6179Smrg
17f46a6179Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18f46a6179Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
20f46a6179Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
21f46a6179Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22f46a6179Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
23f46a6179Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
24f46a6179Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
25f46a6179Smrg
26f46a6179Smrg ********************************************************/
27f46a6179Smrg/* $XFree86: xc/programs/xkbcomp/misc.c,v 3.4 2001/01/17 23:45:44 dawes Exp $ */
28f46a6179Smrg
29f46a6179Smrg#include "xkbcomp.h"
30f46a6179Smrg#include "xkbpath.h"
31f46a6179Smrg#include "tokens.h"
32f46a6179Smrg#include "keycodes.h"
33f46a6179Smrg#include "misc.h"
34f46a6179Smrg#include <X11/keysym.h>
35f46a6179Smrg#include "parseutils.h"
36f46a6179Smrg
37f46a6179Smrg#include <X11/extensions/XKBgeom.h>
38f46a6179Smrg
39f46a6179Smrg/***====================================================================***/
40f46a6179Smrg
41f46a6179SmrgBool
42f46a6179SmrgProcessIncludeFile(	IncludeStmt	*	stmt,
43f46a6179Smrg			unsigned		file_type,
44f46a6179Smrg			XkbFile **		file_rtrn,
45f46a6179Smrg			unsigned *		merge_rtrn)
46f46a6179Smrg{
47f46a6179SmrgFILE	*file;
48f46a6179SmrgXkbFile	*rtrn,*mapToUse;
49f46a6179Smrgchar	 oldFile[1024];
50f46a6179Smrgint	 oldLine = lineNum;
51f46a6179Smrg
52f46a6179Smrg    rtrn= XkbFindFileInCache(stmt->file,file_type,&stmt->path);
53f46a6179Smrg    if (rtrn==NULL) {
54f46a6179Smrg	file= XkbFindFileInPath(stmt->file,file_type,&stmt->path);
55f46a6179Smrg	if (file==NULL) {
56f46a6179Smrg	    ERROR2("Can't find file \"%s\" for %s include\n",stmt->file,
57f46a6179Smrg					XkbDirectoryForInclude(file_type));
58f46a6179Smrg	    ACTION("Exiting\n");
59f46a6179Smrg	    return False;
60f46a6179Smrg	}
61f46a6179Smrg	strcpy(oldFile,scanFile);
62f46a6179Smrg	oldLine= lineNum;
63f46a6179Smrg	setScanState(stmt->file,1);
64f46a6179Smrg	if (debugFlags&2)
65f46a6179Smrg	    INFO1("About to parse include file %s\n",stmt->file);
66f46a6179Smrg	if ((XKBParseFile(file,&rtrn)==0)||(rtrn==NULL)) {
67f46a6179Smrg	    setScanState(oldFile,oldLine);
68f46a6179Smrg	    ERROR1("Error interpreting include file \"%s\"\n",stmt->file);
69f46a6179Smrg	    ACTION("Exiting\n");
70f46a6179Smrg	    fclose(file);
71f46a6179Smrg	    return False;
72f46a6179Smrg	}
73f46a6179Smrg	fclose(file);
74f46a6179Smrg	XkbAddFileToCache(stmt->file,file_type,stmt->path,rtrn);
75f46a6179Smrg    }
76f46a6179Smrg    mapToUse= rtrn;
77f46a6179Smrg    if (stmt->map!=NULL) {
78f46a6179Smrg	while ((mapToUse)&&((!uStringEqual(mapToUse->name,stmt->map))||
79f46a6179Smrg						(mapToUse->type!=file_type))) {
80f46a6179Smrg	    mapToUse= (XkbFile *)mapToUse->common.next;
81f46a6179Smrg	}
82f46a6179Smrg	if (!mapToUse) {
83f46a6179Smrg	    ERROR3("No %s named \"%s\" in the include file \"%s\"\n",
84f46a6179Smrg					XkbConfigText(file_type,XkbMessage),
85f46a6179Smrg    					stmt->map,stmt->file);
86f46a6179Smrg	    ACTION("Exiting\n");
87f46a6179Smrg	    return False;
88f46a6179Smrg	}
89f46a6179Smrg    }
90f46a6179Smrg    else if ((rtrn->common.next!=NULL)&&(warningLevel>5)) {
91f46a6179Smrg	WARN1("No map in include statement, but \"%s\" contains several\n",
92f46a6179Smrg								stmt->file);
93f46a6179Smrg	ACTION1("Using first defined map, \"%s\"\n",rtrn->name);
94f46a6179Smrg    }
95f46a6179Smrg    setScanState(oldFile,oldLine);
96f46a6179Smrg    if (mapToUse->type!=file_type) {
97f46a6179Smrg	ERROR2("Include file wrong type (expected %s, got %s)\n",
98f46a6179Smrg				XkbConfigText(file_type,XkbMessage),
99f46a6179Smrg				XkbConfigText(mapToUse->type,XkbMessage));
100f46a6179Smrg	ACTION1("Include file \"%s\" ignored\n",stmt->file);
101f46a6179Smrg	return False;
102f46a6179Smrg    }
103f46a6179Smrg    /* FIXME: we have to check recursive includes here (or somewhere) */
104f46a6179Smrg
105f46a6179Smrg    mapToUse->compiled= True;
106f46a6179Smrg    *file_rtrn= mapToUse;
107f46a6179Smrg    *merge_rtrn= stmt->merge;
108f46a6179Smrg    return True;
109f46a6179Smrg}
110f46a6179Smrg
111f46a6179Smrg/***====================================================================***/
112f46a6179Smrg
113f46a6179Smrgint
114f46a6179SmrgReportNotArray(const char *type, const char *field, const char *name)
115f46a6179Smrg{
116f46a6179Smrg    ERROR2("The %s %s field is not an array\n",type,field);
117f46a6179Smrg    ACTION1("Ignoring illegal assignment in %s\n",name);
118f46a6179Smrg    return False;
119f46a6179Smrg}
120f46a6179Smrg
121f46a6179Smrgint
122f46a6179SmrgReportShouldBeArray(const char *type, const char *field, char *name)
123f46a6179Smrg{
124f46a6179Smrg    ERROR2("Missing subscript for %s %s\n",type,field);
125f46a6179Smrg    ACTION1("Ignoring illegal assignment in %s\n",name);
126f46a6179Smrg    return False;
127f46a6179Smrg}
128f46a6179Smrg
129f46a6179Smrgint
130f46a6179SmrgReportBadType(const char *type, const char *field,
131f46a6179Smrg              const char *name, const char *wanted)
132f46a6179Smrg{
133f46a6179Smrg    ERROR3("The %s %s field must be a %s\n",type,field,wanted);
134f46a6179Smrg    ACTION1("Ignoring illegal assignment in %s\n",name);
135f46a6179Smrg    return False;
136f46a6179Smrg}
137f46a6179Smrg
138f46a6179Smrgint
139f46a6179SmrgReportBadIndexType(char *type,char *field,char *name,char *wanted)
140f46a6179Smrg{
141f46a6179Smrg    ERROR3("Index for the %s %s field must be a %s\n",type,field,wanted);
142f46a6179Smrg    ACTION1("Ignoring assignment to illegal field in %s\n",name);
143f46a6179Smrg    return False;
144f46a6179Smrg}
145f46a6179Smrg
146f46a6179Smrgint
147f46a6179SmrgReportBadField(const char *type, const char *field, const char *name)
148f46a6179Smrg{
149f46a6179Smrg    ERROR3("Unknown %s field %s in %s\n",type,field,name);
150f46a6179Smrg    ACTION1("Ignoring assignment to unknown field in %s\n",name);
151f46a6179Smrg    return False;
152f46a6179Smrg}
153f46a6179Smrg
154f46a6179Smrgint
155f46a6179SmrgReportMultipleDefs(char *type,char *field,char *name)
156f46a6179Smrg{
157f46a6179Smrg    WARN3("Multiple definitions of %s in %s \"%s\"\n",field,type,name);
158f46a6179Smrg    ACTION("Using last definition\n");
159f46a6179Smrg    return False;
160f46a6179Smrg}
161f46a6179Smrg
162f46a6179Smrg/***====================================================================***/
163f46a6179Smrg
164f46a6179SmrgBool
165f46a6179SmrgUseNewField(	unsigned	field,
166f46a6179Smrg		CommonInfo *	oldDefs,
167f46a6179Smrg		CommonInfo *	newDefs,
168f46a6179Smrg		unsigned *	pCollide)
169f46a6179Smrg{
170f46a6179SmrgBool	useNew;
171f46a6179Smrg
172f46a6179Smrg    useNew= False;
173f46a6179Smrg    if (oldDefs->defined&field) {
174f46a6179Smrg	if (newDefs->defined&field) {
175f46a6179Smrg	    if (((oldDefs->fileID==newDefs->fileID)&&(warningLevel>0))||
176f46a6179Smrg							(warningLevel>9)) {
177f46a6179Smrg		*pCollide|= field;
178f46a6179Smrg	    }
179f46a6179Smrg	    if (newDefs->merge!=MergeAugment)
180f46a6179Smrg		useNew= True;
181f46a6179Smrg	}
182f46a6179Smrg    }
183f46a6179Smrg    else if (newDefs->defined&field)
184f46a6179Smrg	useNew= True;
185f46a6179Smrg    return useNew;
186f46a6179Smrg}
187f46a6179Smrg
188f46a6179SmrgBool
189f46a6179SmrgMergeNewField(	unsigned	field,
190f46a6179Smrg		CommonInfo * 	oldDefs,
191f46a6179Smrg		CommonInfo *	newDefs,
192f46a6179Smrg		unsigned *	pCollide)
193f46a6179Smrg{
194f46a6179Smrg    if ((oldDefs->defined&field)&&(newDefs->defined&field)) {
195f46a6179Smrg	if (((oldDefs->fileID==newDefs->fileID)&&(warningLevel>0))||
196f46a6179Smrg						 (warningLevel>9)) {
197f46a6179Smrg	    *pCollide|= field;
198f46a6179Smrg	}
199f46a6179Smrg	if (newDefs->merge==MergeAugment)
200f46a6179Smrg	    return True;
201f46a6179Smrg    }
202f46a6179Smrg    return False;
203f46a6179Smrg}
204f46a6179Smrg
205f46a6179SmrgXPointer
206f46a6179SmrgClearCommonInfo(CommonInfo *cmn)
207f46a6179Smrg{
208f46a6179Smrg    if (cmn!=NULL) {
209f46a6179Smrg	CommonInfo *this,*next;
210f46a6179Smrg	for (this=cmn;this!=NULL;this=next) {
211f46a6179Smrg	    next= this->next;
212f46a6179Smrg	    uFree(this);
213f46a6179Smrg	}
214f46a6179Smrg    }
215f46a6179Smrg    return NULL;
216f46a6179Smrg}
217f46a6179Smrg
218f46a6179SmrgXPointer
219f46a6179SmrgAddCommonInfo(CommonInfo *old,CommonInfo *new)
220f46a6179Smrg{
221f46a6179SmrgCommonInfo *	first;
222f46a6179Smrg
223f46a6179Smrg    first= old;
224f46a6179Smrg    while ( old && old->next ) {
225f46a6179Smrg	old= old->next;
226f46a6179Smrg    }
227f46a6179Smrg    new->next= NULL;
228f46a6179Smrg    if (old) {
229f46a6179Smrg	old->next= new;
230f46a6179Smrg	return (XPointer)first;
231f46a6179Smrg    }
232f46a6179Smrg    return (XPointer)new;
233f46a6179Smrg}
234f46a6179Smrg
235f46a6179Smrg/***====================================================================***/
236f46a6179Smrg
237f46a6179Smrgtypedef struct _KeyNameDesc {
238f46a6179Smrg	KeySym	level1;
239f46a6179Smrg	KeySym	level2;
240f46a6179Smrg	char	name[5];
241f46a6179Smrg	Bool	used;
242f46a6179Smrg} KeyNameDesc;
243f46a6179Smrg
244f46a6179SmrgKeyNameDesc dfltKeys[] = {
245f46a6179Smrg	{	XK_Escape,	NoSymbol,	"ESC\0"		},
246f46a6179Smrg	{	XK_quoteleft,	XK_asciitilde,	"TLDE"		},
247f46a6179Smrg	{	XK_1,		XK_exclam,	"AE01"		},
248f46a6179Smrg	{	XK_2,		XK_at,		"AE02"		},
249f46a6179Smrg	{	XK_3,		XK_numbersign,	"AE03"		},
250f46a6179Smrg	{	XK_4,		XK_dollar,	"AE04"		},
251f46a6179Smrg	{	XK_5,		XK_percent,	"AE05"		},
252f46a6179Smrg	{	XK_6,		XK_asciicircum,	"AE06"		},
253f46a6179Smrg	{	XK_7,		XK_ampersand,	"AE07"		},
254f46a6179Smrg	{	XK_8,		XK_asterisk,	"AE08"		},
255f46a6179Smrg	{	XK_9,		XK_parenleft,	"AE09"		},
256f46a6179Smrg	{	XK_0,		XK_parenright,	"AE10"		},
257f46a6179Smrg	{	XK_minus,	XK_underscore,	"AE11"		},
258f46a6179Smrg	{	XK_equal,	XK_plus,	"AE12"		},
259f46a6179Smrg	{	XK_BackSpace,	NoSymbol,	"BKSP"		},
260f46a6179Smrg	{	XK_Tab,		NoSymbol,	"TAB\0"		},
261f46a6179Smrg	{	XK_q,		XK_Q,		"AD01"		},
262f46a6179Smrg	{	XK_w,		XK_W,		"AD02"		},
263f46a6179Smrg	{	XK_e,		XK_E,		"AD03"		},
264f46a6179Smrg	{	XK_r,		XK_R,		"AD04"		},
265f46a6179Smrg	{	XK_t,		XK_T,		"AD05"		},
266f46a6179Smrg	{	XK_y,		XK_Y,		"AD06"		},
267f46a6179Smrg	{	XK_u,		XK_U,		"AD07"		},
268f46a6179Smrg	{	XK_i,		XK_I,		"AD08"		},
269f46a6179Smrg	{	XK_o,		XK_O,		"AD09"		},
270f46a6179Smrg	{	XK_p,		XK_P,		"AD10"		},
271f46a6179Smrg	{	XK_bracketleft,	XK_braceleft,	"AD11"		},
272f46a6179Smrg	{	XK_bracketright,XK_braceright,	"AD12"		},
273f46a6179Smrg	{	XK_Return,	NoSymbol,	"RTRN"		},
274f46a6179Smrg	{	XK_Caps_Lock,	NoSymbol,	"CAPS"		},
275f46a6179Smrg	{	XK_a,		XK_A,		"AC01"		},
276f46a6179Smrg	{	XK_s,		XK_S,		"AC02"		},
277f46a6179Smrg	{	XK_d,		XK_D,		"AC03"		},
278f46a6179Smrg	{	XK_f,		XK_F,		"AC04"		},
279f46a6179Smrg	{	XK_g,		XK_G,		"AC05"		},
280f46a6179Smrg	{	XK_h,		XK_H,		"AC06"		},
281f46a6179Smrg	{	XK_j,		XK_J,		"AC07"		},
282f46a6179Smrg	{	XK_k,		XK_K,		"AC08"		},
283f46a6179Smrg	{	XK_l,		XK_L,		"AC09"		},
284f46a6179Smrg	{	XK_semicolon,	XK_colon,	"AC10"		},
285f46a6179Smrg	{	XK_quoteright,	XK_quotedbl,	"AC11"		},
286f46a6179Smrg	{	XK_Shift_L,	NoSymbol,	"LFSH"		},
287f46a6179Smrg	{	XK_z,		XK_Z,		"AB01"		},
288f46a6179Smrg	{	XK_x,		XK_X,		"AB02"		},
289f46a6179Smrg	{	XK_c,		XK_C,		"AB03"		},
290f46a6179Smrg	{	XK_v,		XK_V,		"AB04"		},
291f46a6179Smrg	{	XK_b,		XK_B,		"AB05"		},
292f46a6179Smrg	{	XK_n,		XK_N,		"AB06"		},
293f46a6179Smrg	{	XK_m,		XK_M,		"AB07"		},
294f46a6179Smrg	{	XK_comma,	XK_less,	"AB08"		},
295f46a6179Smrg	{	XK_period,	XK_greater,	"AB09"		},
296f46a6179Smrg	{	XK_slash,	XK_question,	"AB10"		},
297f46a6179Smrg	{	XK_backslash,	XK_bar,		"BKSL"		},
298f46a6179Smrg	{	XK_Control_L,	NoSymbol,	"LCTL"		},
299f46a6179Smrg	{	XK_space,	NoSymbol,	"SPCE"		},
300f46a6179Smrg	{	XK_Shift_R,	NoSymbol,	"RTSH"		},
301f46a6179Smrg	{	XK_Alt_L,	NoSymbol,	"LALT"		},
302f46a6179Smrg	{	XK_space,	NoSymbol,	"SPCE"		},
303f46a6179Smrg	{	XK_Control_R,	NoSymbol,	"RCTL"		},
304f46a6179Smrg	{	XK_Alt_R,	NoSymbol,	"RALT"		},
305f46a6179Smrg	{	XK_F1,		NoSymbol,	"FK01"		},
306f46a6179Smrg	{	XK_F2,		NoSymbol,	"FK02"		},
307f46a6179Smrg	{	XK_F3,		NoSymbol,	"FK03"		},
308f46a6179Smrg	{	XK_F4,		NoSymbol,	"FK04"		},
309f46a6179Smrg	{	XK_F5,		NoSymbol,	"FK05"		},
310f46a6179Smrg	{	XK_F6,		NoSymbol,	"FK06"		},
311f46a6179Smrg	{	XK_F7,		NoSymbol,	"FK07"		},
312f46a6179Smrg	{	XK_F8,		NoSymbol,	"FK08"		},
313f46a6179Smrg	{	XK_F9,		NoSymbol,	"FK09"		},
314f46a6179Smrg	{	XK_F10,		NoSymbol,	"FK10"		},
315f46a6179Smrg	{	XK_F11,		NoSymbol,	"FK11"		},
316f46a6179Smrg	{	XK_F12,		NoSymbol,	"FK12"		},
317f46a6179Smrg	{	XK_Print,	NoSymbol,	"PRSC"		},
318f46a6179Smrg	{	XK_Scroll_Lock,	NoSymbol,	"SCLK"		},
319f46a6179Smrg	{	XK_Pause,	NoSymbol,	"PAUS"		},
320f46a6179Smrg	{	XK_Insert,	NoSymbol,	"INS\0"		},
321f46a6179Smrg	{	XK_Home,	NoSymbol,	"HOME"		},
322f46a6179Smrg	{	XK_Prior,	NoSymbol,	"PGUP"		},
323f46a6179Smrg	{	XK_Delete,	NoSymbol,	"DELE"		},
324f46a6179Smrg	{	XK_End,		NoSymbol,	"END"		},
325f46a6179Smrg	{	XK_Next,	NoSymbol,	"PGDN"		},
326f46a6179Smrg	{	XK_Up,		NoSymbol,	"UP\0\0"	},
327f46a6179Smrg	{	XK_Left,	NoSymbol,	"LEFT"		},
328f46a6179Smrg	{	XK_Down,	NoSymbol,	"DOWN"		},
329f46a6179Smrg	{	XK_Right,	NoSymbol,	"RGHT"		},
330f46a6179Smrg	{	XK_Num_Lock,	NoSymbol,	"NMLK"		},
331f46a6179Smrg	{	XK_KP_Divide,	NoSymbol,	"KPDV"		},
332f46a6179Smrg	{	XK_KP_Multiply,	NoSymbol,	"KPMU"		},
333f46a6179Smrg	{	XK_KP_Subtract,	NoSymbol,	"KPSU"		},
334f46a6179Smrg	{	NoSymbol,	XK_KP_7,	"KP7\0"		},
335f46a6179Smrg	{	NoSymbol,	XK_KP_8,	"KP8\0"		},
336f46a6179Smrg	{	NoSymbol,	XK_KP_9,	"KP9\0"		},
337f46a6179Smrg	{	XK_KP_Add,	NoSymbol,	"KPAD"		},
338f46a6179Smrg	{	NoSymbol,	XK_KP_4,	"KP4\0"		},
339f46a6179Smrg	{	NoSymbol,	XK_KP_5,	"KP5\0"		},
340f46a6179Smrg	{	NoSymbol,	XK_KP_6,	"KP6\0"		},
341f46a6179Smrg	{	NoSymbol,	XK_KP_1,	"KP1\0"		},
342f46a6179Smrg	{	NoSymbol,	XK_KP_2,	"KP2\0"		},
343f46a6179Smrg	{	NoSymbol,	XK_KP_3,	"KP3\0"		},
344f46a6179Smrg	{	XK_KP_Enter,	NoSymbol,	"KPEN"		},
345f46a6179Smrg	{	NoSymbol,	XK_KP_0,	"KP0\0"		},
346f46a6179Smrg	{	XK_KP_Delete,	NoSymbol,	"KPDL"		},
347f46a6179Smrg	{	XK_less,	XK_greater,	"LSGT"		},
348f46a6179Smrg	{	XK_KP_Separator,NoSymbol,	"KPCO"		},
349f46a6179Smrg	{	XK_Find,	NoSymbol,	"FIND"		},
350f46a6179Smrg	{	NoSymbol,	NoSymbol,	"\0\0\0\0"	}
351f46a6179Smrg};
352f46a6179Smrg
353f46a6179SmrgStatus
354f46a6179SmrgComputeKbdDefaults(XkbDescPtr xkb)
355f46a6179Smrg{
356f46a6179SmrgStatus		rtrn;
357f46a6179Smrgregister int	i,tmp,nUnknown;
358f46a6179SmrgKeyNameDesc *	name;
359f46a6179SmrgKeySym *	syms;
360f46a6179Smrg
361f46a6179Smrg    if ((xkb->names==NULL)||(xkb->names->keys==NULL)) {
362f46a6179Smrg	if ((rtrn=XkbAllocNames(xkb,XkbKeyNamesMask,0,0))!=Success)
363f46a6179Smrg	    return rtrn;
364f46a6179Smrg    }
365f46a6179Smrg    for (name=dfltKeys;(name->name[0]!='\0');name++) {
366f46a6179Smrg	name->used= False;
367f46a6179Smrg    }
368f46a6179Smrg    nUnknown= 0;
369f46a6179Smrg    for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
370f46a6179Smrg	tmp= XkbKeyNumSyms(xkb,i);
371f46a6179Smrg	if ((xkb->names->keys[i].name[0]=='\0')&&(tmp>0)) {
372f46a6179Smrg	    tmp= XkbKeyGroupsWidth(xkb,i);
373f46a6179Smrg	    syms= XkbKeySymsPtr(xkb,i);
374f46a6179Smrg	    for (name=dfltKeys;(name->name[0]!='\0');name++) {
375f46a6179Smrg		Bool match= True;
376f46a6179Smrg		if (((name->level1!=syms[0])&&(name->level1!=NoSymbol))||
377f46a6179Smrg		   ((name->level2!=NoSymbol)&&(tmp<2))||
378f46a6179Smrg		   ((name->level2!=syms[1])&&(name->level2!=NoSymbol))) {
379f46a6179Smrg		    match= False;
380f46a6179Smrg		}
381f46a6179Smrg		if (match) {
382f46a6179Smrg		    if (!name->used) {
383f46a6179Smrg			memcpy(xkb->names->keys[i].name,name->name,
384f46a6179Smrg							XkbKeyNameLength);
385f46a6179Smrg			name->used= True;
386f46a6179Smrg		    }
387f46a6179Smrg		    else {
388f46a6179Smrg			if (warningLevel>2) {
389f46a6179Smrg			    WARN1("Several keys match pattern for %s\n",
390f46a6179Smrg				XkbKeyNameText(name->name,XkbMessage));
391f46a6179Smrg			    ACTION2("Using <U%03d> for key %d\n",nUnknown,i);
392f46a6179Smrg			}
393f46a6179Smrg			sprintf(xkb->names->keys[i].name,"U%03d",nUnknown++);
394f46a6179Smrg		    }
395f46a6179Smrg		    break;
396f46a6179Smrg		}
397f46a6179Smrg	    }
398f46a6179Smrg	    if (xkb->names->keys[i].name[0]=='\0') {
399f46a6179Smrg		if (warningLevel>2) {
400f46a6179Smrg		    WARN1("Key %d does not match any defaults\n",i);
401f46a6179Smrg		    ACTION1("Using name <U%03d>\n",nUnknown);
402f46a6179Smrg		    sprintf(xkb->names->keys[i].name,"U%03d",nUnknown++);
403f46a6179Smrg		}
404f46a6179Smrg	    }
405f46a6179Smrg	}
406f46a6179Smrg    }
407f46a6179Smrg    return Success;
408f46a6179Smrg}
409f46a6179Smrg
410f46a6179SmrgBool
411f46a6179SmrgFindNamedKey(	XkbDescPtr	xkb,
412f46a6179Smrg		unsigned long	name,
413f46a6179Smrg		unsigned int *	kc_rtrn,
414f46a6179Smrg		Bool		use_aliases,
415f46a6179Smrg		Bool		create,
416f46a6179Smrg		int		start_from)
417f46a6179Smrg{
418f46a6179Smrgregister unsigned n;
419f46a6179Smrg
420f46a6179Smrg    if (start_from<xkb->min_key_code) {
421f46a6179Smrg	start_from= xkb->min_key_code;
422f46a6179Smrg    }
423f46a6179Smrg    else if (start_from>xkb->max_key_code) {
424f46a6179Smrg	return False;
425f46a6179Smrg    }
426f46a6179Smrg
427f46a6179Smrg    *kc_rtrn= 0;	/* some callers rely on this */
428f46a6179Smrg    if (xkb&&xkb->names&&xkb->names->keys) {
429f46a6179Smrg	for (n=start_from;n<=xkb->max_key_code;n++) {
430f46a6179Smrg	    unsigned long tmp;
431f46a6179Smrg	    tmp= KeyNameToLong(xkb->names->keys[n].name);
432f46a6179Smrg	    if (tmp==name) {
433f46a6179Smrg		*kc_rtrn= n;
434f46a6179Smrg		return True;
435f46a6179Smrg	    }
436f46a6179Smrg	}
437f46a6179Smrg	if (use_aliases) {
438f46a6179Smrg	    unsigned long new_name;
439f46a6179Smrg	    if (FindKeyNameForAlias(xkb,name,&new_name))
440f46a6179Smrg		return FindNamedKey(xkb,new_name,kc_rtrn,False,create,0);
441f46a6179Smrg	}
442f46a6179Smrg    }
443f46a6179Smrg    if (create) {
444f46a6179Smrg	if ((!xkb->names)||(!xkb->names->keys)) {
445f46a6179Smrg	    if (xkb->min_key_code<XkbMinLegalKeyCode) {
446f46a6179Smrg		xkb->min_key_code= XkbMinLegalKeyCode;
447f46a6179Smrg		xkb->max_key_code= XkbMaxLegalKeyCode;
448f46a6179Smrg	    }
449f46a6179Smrg	    if (XkbAllocNames(xkb,XkbKeyNamesMask,0,0)!=Success) {
450f46a6179Smrg		if (warningLevel>0) {
451f46a6179Smrg		    WARN("Couldn't allocate key names in FindNamedKey\n");
452f46a6179Smrg		    ACTION1("Key \"%s\" not automatically created\n",
453f46a6179Smrg						longText(name,XkbMessage));
454f46a6179Smrg		}
455f46a6179Smrg		return False;
456f46a6179Smrg	    }
457f46a6179Smrg	}
458f46a6179Smrg	for (n=xkb->min_key_code;n<=xkb->max_key_code;n++) {
459f46a6179Smrg	    if (xkb->names->keys[n].name[0]=='\0') {
460f46a6179Smrg		char buf[XkbKeyNameLength+1];
461f46a6179Smrg		LongToKeyName(name,buf);
462f46a6179Smrg		memcpy(xkb->names->keys[n].name,buf,XkbKeyNameLength);
463f46a6179Smrg		*kc_rtrn= n;
464f46a6179Smrg		return True;
465f46a6179Smrg	    }
466f46a6179Smrg	}
467f46a6179Smrg    }
468f46a6179Smrg    return False;
469f46a6179Smrg}
470f46a6179Smrg
471f46a6179SmrgBool
472f46a6179SmrgFindKeyNameForAlias(XkbDescPtr xkb,unsigned long lname,unsigned long *real_name)
473f46a6179Smrg{
474f46a6179Smrgregister int	i;
475f46a6179Smrgchar		name[XkbKeyNameLength+1];
476f46a6179Smrg
477f46a6179Smrg    if (xkb&&xkb->geom&&xkb->geom->key_aliases) {
478f46a6179Smrg	XkbKeyAliasPtr	a;
479f46a6179Smrg	a= xkb->geom->key_aliases;
480f46a6179Smrg	LongToKeyName(lname,name);
481f46a6179Smrg	name[XkbKeyNameLength]= '\0';
482f46a6179Smrg	for (i=0;i<xkb->geom->num_key_aliases;i++,a++) {
483f46a6179Smrg	    if (strncmp(name,a->alias,XkbKeyNameLength)==0) {
484f46a6179Smrg		*real_name= KeyNameToLong(a->real);
485f46a6179Smrg		return True;
486f46a6179Smrg	    }
487f46a6179Smrg	}
488f46a6179Smrg    }
489f46a6179Smrg    if (xkb&&xkb->names&&xkb->names->key_aliases) {
490f46a6179Smrg	XkbKeyAliasPtr	a;
491f46a6179Smrg	a= xkb->names->key_aliases;
492f46a6179Smrg	LongToKeyName(lname,name);
493f46a6179Smrg	name[XkbKeyNameLength]= '\0';
494f46a6179Smrg	for (i=0;i<xkb->names->num_key_aliases;i++,a++) {
495f46a6179Smrg	    if (strncmp(name,a->alias,XkbKeyNameLength)==0) {
496f46a6179Smrg		*real_name= KeyNameToLong(a->real);
497f46a6179Smrg		return True;
498f46a6179Smrg	    }
499f46a6179Smrg	}
500f46a6179Smrg    }
501f46a6179Smrg    return False;
502f46a6179Smrg}
503