vmod.c revision f46a6179
1/* $Xorg: vmod.c,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */
2/************************************************************
3 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
4
5 Permission to use, copy, modify, and distribute this
6 software and its documentation for any purpose and without
7 fee is hereby granted, provided that the above copyright
8 notice appear in all copies and that both that copyright
9 notice and this permission notice appear in supporting
10 documentation, and that the name of Silicon Graphics not be
11 used in advertising or publicity pertaining to distribution
12 of the software without specific prior written permission.
13 Silicon Graphics makes no representation about the suitability
14 of this software for any purpose. It is provided "as is"
15 without any express or implied warranty.
16
17 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
20 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
21 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
23 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
24 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
26 ********************************************************/
27/* $XFree86: xc/programs/xkbcomp/vmod.c,v 3.3 2001/01/17 23:45:45 dawes Exp $ */
28
29#define	DEBUG_VAR_NOT_LOCAL
30#define	DEBUG_VAR debugFlags
31#include <stdio.h>
32#include "xkbcomp.h"
33#include "tokens.h"
34#include "expr.h"
35#include "misc.h"
36
37#include <X11/extensions/XKB.h>
38#include <X11/extensions/XKBstr.h>
39
40#include "vmod.h"
41
42void
43InitVModInfo(VModInfo *info,XkbDescPtr xkb)
44{
45    ClearVModInfo(info,xkb);
46    info->errorCount= 0;
47    return;
48}
49
50void
51ClearVModInfo(VModInfo *info,XkbDescPtr xkb)
52{
53register int i;
54
55    if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success)
56	return;
57    if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success)
58	return;
59    info->xkb= xkb;
60    info->newlyDefined= info->defined= info->available= 0;
61    if (xkb && xkb->names) {
62	register int bit;
63	for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
64	    if (xkb->names->vmods[i]!=None)
65		info->defined|= bit;
66	}
67    }
68    return;
69}
70
71/***====================================================================***/
72
73Bool
74HandleVModDef(VModDef *stmt,unsigned mergeMode,VModInfo *info)
75{
76register int 	i,bit,nextFree;
77ExprResult 	mod;
78XkbServerMapPtr	srv;
79XkbNamesPtr	names;
80Atom		stmtName;
81
82    srv= info->xkb->server;
83    names= info->xkb->names;
84    stmtName= XkbInternAtom(info->xkb->dpy,XkbAtomGetString(NULL,stmt->name),
85    									False);
86    for (i=0,bit=1,nextFree= -1;i<XkbNumVirtualMods;i++,bit<<=1) {
87	if (info->defined&bit) {
88	    if (names->vmods[i]==stmtName) {	/* already defined */
89		info->available|= bit;
90		if (stmt->value==NULL)
91		    return True;
92		else {
93		    char *str1;
94		    const char *str2 = "";
95		    if (!ExprResolveModMask(stmt->value,&mod,NULL,NULL)) {
96			str1= XkbAtomText(NULL,stmt->name,XkbMessage);
97			ACTION1("Declaration of %s ignored\n",str1);
98			return False;
99		    }
100		    if (mod.uval==srv->vmods[i])
101			return True;
102
103		    str1= XkbAtomText(NULL,stmt->name,XkbMessage);
104		    WARN1("Virtual modifier %s multiply defined\n",str1);
105		    str1= XkbModMaskText(srv->vmods[i],XkbCFile);
106		    if (mergeMode==MergeOverride) {
107			str2= str1;
108			str1= XkbModMaskText(mod.uval,XkbCFile);
109		    }
110		    ACTION2("Using %s, ignoring %s\n",str1,str2);
111		    if (mergeMode==MergeOverride)
112			srv->vmods[i]= mod.uval;
113		    return True;
114		}
115	    }
116	}
117	else if (nextFree<0)
118	    nextFree= i;
119    }
120    if (nextFree<0) {
121	ERROR1("Too many virtual modifiers defined (maximum %d)\n",
122						XkbNumVirtualMods);
123	ACTION("Exiting\n");
124	return False;
125    }
126    info->defined|= (1<<nextFree);
127    info->newlyDefined|= (1<<nextFree);
128    info->available|= (1<<nextFree);
129    names->vmods[nextFree]= stmtName;
130    if (stmt->value==NULL)
131	return True;
132    if (ExprResolveModMask(stmt->value,&mod,NULL,NULL)) {
133	srv->vmods[nextFree]= mod.uval;
134	return True;
135    }
136    ACTION1("Declaration of %s ignored\n",
137    				XkbAtomText(NULL,stmt->name,XkbMessage));
138    return False;
139}
140
141int
142LookupVModIndex(	XPointer	priv,
143			Atom 		elem,
144			Atom 		field,
145			unsigned 	type,
146			ExprResult *	val_rtrn)
147{
148register int	i;
149register char *	fieldStr;
150register char *	modStr;
151XkbDescPtr	xkb;
152
153    xkb= (XkbDescPtr)priv;
154    if ((xkb==NULL)||(xkb->names==NULL)||(elem!=None)||(type!=TypeInt)) {
155	return False;
156    }
157    fieldStr= XkbAtomGetString(xkb->dpy,field);
158    if (fieldStr==NULL)
159	return False;
160    for (i=0;i<XkbNumVirtualMods;i++) {
161	modStr= XkbAtomGetString(xkb->dpy,xkb->names->vmods[i]);
162	if ((modStr!=NULL)&&(uStrCaseCmp(fieldStr,modStr)==0)) {
163	    val_rtrn->uval= i;
164	    return True;
165	}
166    }
167    return False;
168}
169
170int
171LookupVModMask(	XPointer 	priv,
172		Atom 		elem,
173		Atom 		field,
174		unsigned 	type,
175		ExprResult *	val_rtrn)
176{
177    if (LookupVModIndex(priv,elem,field,type,val_rtrn)) {
178	register unsigned ndx= val_rtrn->uval;
179	val_rtrn->uval= (1<<(XkbNumModifiers+ndx));
180	return True;
181    }
182    return False;
183}
184
185int
186FindKeypadVMod(XkbDescPtr xkb)
187{
188Atom name;
189ExprResult rtrn;
190
191    name= XkbInternAtom(xkb->dpy,"NumLock",False);
192    if ((xkb)&&
193	LookupVModIndex((XPointer)xkb,None,name,TypeInt,&rtrn)) {
194	return rtrn.ival;
195    }
196    return -1;
197}
198
199Bool
200ResolveVirtualModifier(ExprDef *def,ExprResult *val_rtrn,VModInfo *info)
201{
202XkbNamesPtr	names;
203
204    names= info->xkb->names;
205    if (def->op==ExprIdent) {
206	register int i,bit;
207	for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
208	    char *str1,*str2;
209	    str1= XkbAtomGetString(info->xkb->dpy,names->vmods[i]);
210	    str2= XkbAtomGetString(NULL,def->value.str);
211	    if ((info->available&bit)&&
212		(uStrCaseCmp(str1,str2)==Equal)) {
213		val_rtrn->uval= i;
214		return True;
215	    }
216	}
217    }
218    if (ExprResolveInteger(def,val_rtrn,NULL,NULL)) {
219	if (val_rtrn->uval<XkbNumVirtualMods)
220	    return True;
221	ERROR2("Illegal virtual modifier %d (must be 0..%d inclusive)\n",
222					val_rtrn->uval,XkbNumVirtualMods-1);
223    }
224    return False;
225}
226