action.c revision f46a6179
1f46a6179Smrg/* $Xorg: action.c,v 1.3 2000/08/17 19:54:30 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/action.c,v 3.10tsi Exp $ */
28f46a6179Smrg
29f46a6179Smrg#include "xkbcomp.h"
30f46a6179Smrg#include "tokens.h"
31f46a6179Smrg#include "expr.h"
32f46a6179Smrg
33f46a6179Smrg#include "keycodes.h"
34f46a6179Smrg#include "vmod.h"
35f46a6179Smrg#include "misc.h"
36f46a6179Smrg#include "action.h"
37f46a6179Smrg#include "misc.h"
38f46a6179Smrg
39f46a6179Smrgstatic Bool	actionsInitialized;
40f46a6179Smrgstatic ExprDef	constTrue;
41f46a6179Smrgstatic ExprDef	constFalse;
42f46a6179Smrg
43f46a6179Smrg/***====================================================================***/
44f46a6179Smrg
45f46a6179Smrgstatic Bool
46f46a6179SmrgstringToAction(char *str,unsigned *type_rtrn)
47f46a6179Smrg{
48f46a6179Smrg    if (str==NULL)
49f46a6179Smrg	return False;
50f46a6179Smrg
51f46a6179Smrg    if (uStrCaseCmp(str,"noaction")==0)	 	*type_rtrn= XkbSA_NoAction;
52f46a6179Smrg    else if (uStrCaseCmp(str,"setmods")==0)	*type_rtrn= XkbSA_SetMods;
53f46a6179Smrg    else if (uStrCaseCmp(str,"latchmods")==0)	*type_rtrn= XkbSA_LatchMods;
54f46a6179Smrg    else if (uStrCaseCmp(str,"lockmods")==0)	*type_rtrn= XkbSA_LockMods;
55f46a6179Smrg    else if (uStrCaseCmp(str,"setgroup")==0)	*type_rtrn= XkbSA_SetGroup;
56f46a6179Smrg    else if (uStrCaseCmp(str,"latchgroup")==0)	*type_rtrn= XkbSA_LatchGroup;
57f46a6179Smrg    else if (uStrCaseCmp(str,"lockgroup")==0)	*type_rtrn= XkbSA_LockGroup;
58f46a6179Smrg    else if (uStrCaseCmp(str,"moveptr")==0)	*type_rtrn= XkbSA_MovePtr;
59f46a6179Smrg    else if (uStrCaseCmp(str,"movepointer")==0)	*type_rtrn= XkbSA_MovePtr;
60f46a6179Smrg    else if (uStrCaseCmp(str,"ptrbtn")==0)	*type_rtrn= XkbSA_PtrBtn;
61f46a6179Smrg    else if (uStrCaseCmp(str,"pointerbutton")==0)
62f46a6179Smrg						*type_rtrn= XkbSA_PtrBtn;
63f46a6179Smrg    else if (uStrCaseCmp(str,"lockptrbtn")==0)	*type_rtrn= XkbSA_LockPtrBtn;
64f46a6179Smrg    else if (uStrCaseCmp(str,"lockpointerbutton")==0)
65f46a6179Smrg						*type_rtrn= XkbSA_LockPtrBtn;
66f46a6179Smrg    else if (uStrCaseCmp(str,"lockptrbutton")==0)
67f46a6179Smrg						*type_rtrn= XkbSA_LockPtrBtn;
68f46a6179Smrg    else if (uStrCaseCmp(str,"lockpointerbtn")==0)
69f46a6179Smrg						*type_rtrn= XkbSA_LockPtrBtn;
70f46a6179Smrg    else if (uStrCaseCmp(str,"setptrdflt")==0)	*type_rtrn= XkbSA_SetPtrDflt;
71f46a6179Smrg    else if (uStrCaseCmp(str,"setpointerdefault")==0)
72f46a6179Smrg						*type_rtrn= XkbSA_SetPtrDflt;
73f46a6179Smrg    else if (uStrCaseCmp(str,"isolock")==0)	*type_rtrn= XkbSA_ISOLock;
74f46a6179Smrg    else if (uStrCaseCmp(str,"terminate")==0)	*type_rtrn= XkbSA_Terminate;
75f46a6179Smrg    else if (uStrCaseCmp(str,"terminateserver")==0)
76f46a6179Smrg						*type_rtrn= XkbSA_Terminate;
77f46a6179Smrg    else if (uStrCaseCmp(str,"switchscreen")==0)*type_rtrn= XkbSA_SwitchScreen;
78f46a6179Smrg    else if (uStrCaseCmp(str,"setcontrols")==0)	*type_rtrn= XkbSA_SetControls;
79f46a6179Smrg    else if (uStrCaseCmp(str,"lockcontrols")==0)*type_rtrn= XkbSA_LockControls;
80f46a6179Smrg    else if (uStrCaseCmp(str,"actionmessage")==0)*type_rtrn= XkbSA_ActionMessage;
81f46a6179Smrg    else if (uStrCaseCmp(str,"messageaction")==0)*type_rtrn= XkbSA_ActionMessage;
82f46a6179Smrg    else if (uStrCaseCmp(str,"message")==0)	*type_rtrn= XkbSA_ActionMessage;
83f46a6179Smrg    else if (uStrCaseCmp(str,"redirect")==0)	*type_rtrn= XkbSA_RedirectKey;
84f46a6179Smrg    else if (uStrCaseCmp(str,"redirectkey")==0)	*type_rtrn= XkbSA_RedirectKey;
85f46a6179Smrg    else if (uStrCaseCmp(str,"devbtn")==0)	*type_rtrn= XkbSA_DeviceBtn;
86f46a6179Smrg    else if (uStrCaseCmp(str,"devicebtn")==0)	*type_rtrn= XkbSA_DeviceBtn;
87f46a6179Smrg    else if (uStrCaseCmp(str,"devbutton")==0)	*type_rtrn= XkbSA_DeviceBtn;
88f46a6179Smrg    else if (uStrCaseCmp(str,"devicebutton")==0)*type_rtrn= XkbSA_DeviceBtn;
89f46a6179Smrg    else if (uStrCaseCmp(str,"lockdevbtn")==0)	*type_rtrn= XkbSA_DeviceBtn;
90f46a6179Smrg    else if (uStrCaseCmp(str,"lockdevicebtn")==0)
91f46a6179Smrg						*type_rtrn= XkbSA_LockDeviceBtn;
92f46a6179Smrg    else if (uStrCaseCmp(str,"lockdevbutton")==0)
93f46a6179Smrg						*type_rtrn= XkbSA_LockDeviceBtn;
94f46a6179Smrg    else if (uStrCaseCmp(str,"lockdevicebutton")==0)
95f46a6179Smrg						*type_rtrn= XkbSA_LockDeviceBtn;
96f46a6179Smrg    else if (uStrCaseCmp(str,"devval")==0)	*type_rtrn=XkbSA_DeviceValuator;
97f46a6179Smrg    else if (uStrCaseCmp(str,"deviceval")==0)	*type_rtrn=XkbSA_DeviceValuator;
98f46a6179Smrg    else if (uStrCaseCmp(str,"devvaluator")==0)	*type_rtrn=XkbSA_DeviceValuator;
99f46a6179Smrg    else if (uStrCaseCmp(str,"devicevaluator")==0)
100f46a6179Smrg						*type_rtrn=XkbSA_DeviceValuator;
101f46a6179Smrg    else if (uStrCaseCmp(str,"private")==0)	*type_rtrn= PrivateAction;
102f46a6179Smrg    else return False;
103f46a6179Smrg    return True;
104f46a6179Smrg}
105f46a6179Smrg
106f46a6179Smrgstatic Bool
107f46a6179SmrgstringToField(char *str,unsigned *field_rtrn)
108f46a6179Smrg{
109f46a6179Smrg
110f46a6179Smrg    if (str==NULL)
111f46a6179Smrg	return False;
112f46a6179Smrg
113f46a6179Smrg    if (uStrCaseCmp(str,"clearlocks")==0)	*field_rtrn= F_ClearLocks;
114f46a6179Smrg    else if (uStrCaseCmp(str,"latchtolock")==0)	*field_rtrn= F_LatchToLock;
115f46a6179Smrg    else if (uStrCaseCmp(str,"genkeyevent")==0)	*field_rtrn= F_GenKeyEvent;
116f46a6179Smrg    else if (uStrCaseCmp(str,"generatekeyevent")==0)
117f46a6179Smrg						*field_rtrn= F_GenKeyEvent;
118f46a6179Smrg    else if (uStrCaseCmp(str,"report")==0)	*field_rtrn= F_Report;
119f46a6179Smrg    else if (uStrCaseCmp(str,"default")==0)	*field_rtrn= F_Default;
120f46a6179Smrg    else if (uStrCaseCmp(str,"affect")==0)	*field_rtrn= F_Affect;
121f46a6179Smrg    else if (uStrCaseCmp(str,"increment")==0)	*field_rtrn= F_Increment;
122f46a6179Smrg    else if (uStrCaseCmp(str,"mods")==0)	*field_rtrn= F_Modifiers;
123f46a6179Smrg    else if (uStrCaseCmp(str,"modifiers")==0)	*field_rtrn= F_Modifiers;
124f46a6179Smrg    else if (uStrCaseCmp(str,"group")==0)	*field_rtrn= F_Group;
125f46a6179Smrg    else if (uStrCaseCmp(str,"x")==0)		*field_rtrn= F_X;
126f46a6179Smrg    else if (uStrCaseCmp(str,"y")==0)		*field_rtrn= F_Y;
127f46a6179Smrg    else if (uStrCaseCmp(str,"accel")==0)	*field_rtrn= F_Accel;
128f46a6179Smrg    else if (uStrCaseCmp(str,"accelerate")==0)	*field_rtrn= F_Accel;
129f46a6179Smrg    else if (uStrCaseCmp(str,"repeat")==0)	*field_rtrn= F_Accel;
130f46a6179Smrg    else if (uStrCaseCmp(str,"button")==0)	*field_rtrn= F_Button;
131f46a6179Smrg    else if (uStrCaseCmp(str,"value")==0)	*field_rtrn= F_Value;
132f46a6179Smrg    else if (uStrCaseCmp(str,"controls")==0)	*field_rtrn= F_Controls;
133f46a6179Smrg    else if (uStrCaseCmp(str,"ctrls")==0)	*field_rtrn= F_Controls;
134f46a6179Smrg    else if (uStrCaseCmp(str,"type")==0)	*field_rtrn= F_Type;
135f46a6179Smrg    else if (uStrCaseCmp(str,"count")==0)	*field_rtrn= F_Count;
136f46a6179Smrg    else if (uStrCaseCmp(str,"screen")==0)	*field_rtrn= F_Screen;
137f46a6179Smrg    else if (uStrCaseCmp(str,"same")==0)	*field_rtrn= F_Same;
138f46a6179Smrg    else if (uStrCaseCmp(str,"sameserver")==0)	*field_rtrn= F_Same;
139f46a6179Smrg    else if (uStrCaseCmp(str,"data")==0)	*field_rtrn= F_Data;
140f46a6179Smrg    else if (uStrCaseCmp(str,"device")==0)	*field_rtrn= F_Device;
141f46a6179Smrg    else if (uStrCaseCmp(str,"dev")==0)		*field_rtrn= F_Device;
142f46a6179Smrg    else if (uStrCaseCmp(str,"key")==0)		*field_rtrn= F_Keycode;
143f46a6179Smrg    else if (uStrCaseCmp(str,"keycode")==0)	*field_rtrn= F_Keycode;
144f46a6179Smrg    else if (uStrCaseCmp(str,"kc")==0)		*field_rtrn= F_Keycode;
145f46a6179Smrg    else if (uStrCaseCmp(str,"clearmods")==0)	*field_rtrn= F_ModsToClear;
146f46a6179Smrg    else if (uStrCaseCmp(str,"clearmodifiers")==0) *field_rtrn= F_ModsToClear;
147f46a6179Smrg    else return False;
148f46a6179Smrg    return True;
149f46a6179Smrg}
150f46a6179Smrg
151f46a6179Smrgstatic char *
152f46a6179SmrgfieldText(unsigned field)
153f46a6179Smrg{
154f46a6179Smrgstatic char buf[32];
155f46a6179Smrg
156f46a6179Smrg    switch (field) {
157f46a6179Smrg	case F_ClearLocks:	strcpy(buf,"clearLocks"); break;
158f46a6179Smrg	case F_LatchToLock:	strcpy(buf,"latchToLock"); break;
159f46a6179Smrg	case F_GenKeyEvent:	strcpy(buf,"genKeyEvent"); break;
160f46a6179Smrg	case F_Report:		strcpy(buf,"report"); break;
161f46a6179Smrg	case F_Default:		strcpy(buf,"default"); break;
162f46a6179Smrg	case F_Affect:		strcpy(buf,"affect"); break;
163f46a6179Smrg	case F_Increment:	strcpy(buf,"increment"); break;
164f46a6179Smrg	case F_Modifiers:	strcpy(buf,"modifiers"); break;
165f46a6179Smrg	case F_Group:		strcpy(buf,"group"); break;
166f46a6179Smrg	case F_X:		strcpy(buf,"x"); break;
167f46a6179Smrg	case F_Y:		strcpy(buf,"y"); break;
168f46a6179Smrg	case F_Accel:		strcpy(buf,"accel"); break;
169f46a6179Smrg	case F_Button:		strcpy(buf,"button"); break;
170f46a6179Smrg	case F_Value:		strcpy(buf,"value"); break;
171f46a6179Smrg	case F_Controls:	strcpy(buf,"controls"); break;
172f46a6179Smrg	case F_Type:		strcpy(buf,"type"); break;
173f46a6179Smrg	case F_Count:		strcpy(buf,"count"); break;
174f46a6179Smrg	case F_Screen:		strcpy(buf,"screen"); break;
175f46a6179Smrg	case F_Same:		strcpy(buf,"sameServer"); break;
176f46a6179Smrg	case F_Data:		strcpy(buf,"data"); break;
177f46a6179Smrg	case F_Device:		strcpy(buf,"device"); break;
178f46a6179Smrg	case F_Keycode:		strcpy(buf,"keycode"); break;
179f46a6179Smrg	case F_ModsToClear:	strcpy(buf,"clearmods"); break;
180f46a6179Smrg	default:		strcpy(buf,"unknown"); break;
181f46a6179Smrg    }
182f46a6179Smrg    return buf;
183f46a6179Smrg}
184f46a6179Smrg
185f46a6179Smrg/***====================================================================***/
186f46a6179Smrg
187f46a6179Smrgstatic Bool
188f46a6179SmrgReportMismatch(unsigned action, unsigned field, const char *type)
189f46a6179Smrg{
190f46a6179Smrg    ERROR2("Value of %s field must be of type %s\n",fieldText(field),type);
191f46a6179Smrg    ACTION1("Action %s definition ignored\n",
192f46a6179Smrg    					XkbActionTypeText(action,XkbMessage));
193f46a6179Smrg    return False;
194f46a6179Smrg}
195f46a6179Smrg
196f46a6179Smrgstatic Bool
197f46a6179SmrgReportIllegal(unsigned action,unsigned field)
198f46a6179Smrg{
199f46a6179Smrg    ERROR2("Field %s is not defined for an action of type %s\n",
200f46a6179Smrg				fieldText(field),
201f46a6179Smrg				XkbActionTypeText(action,XkbMessage));
202f46a6179Smrg    ACTION("Action definition ignored\n");
203f46a6179Smrg    return False;
204f46a6179Smrg}
205f46a6179Smrg
206f46a6179Smrgstatic Bool
207f46a6179SmrgReportActionNotArray(unsigned action,unsigned field)
208f46a6179Smrg{
209f46a6179Smrg    ERROR2("The %s field in the %s action is not an array\n",
210f46a6179Smrg				fieldText(field),
211f46a6179Smrg				XkbActionTypeText(action,XkbMessage));
212f46a6179Smrg    ACTION("Action definition ignored\n");
213f46a6179Smrg    return False;
214f46a6179Smrg}
215f46a6179Smrg
216f46a6179Smrgstatic Bool
217f46a6179SmrgReportNotFound(unsigned action, unsigned field, const char *what, char *bad)
218f46a6179Smrg{
219f46a6179Smrg    ERROR2("%s named %s not found\n",what,bad);
220f46a6179Smrg    ACTION2("Ignoring the %s field of an %s action\n",fieldText(field),
221f46a6179Smrg				XkbActionTypeText(action,XkbMessage));
222f46a6179Smrg    return False;
223f46a6179Smrg}
224f46a6179Smrg
225f46a6179Smrgstatic Bool
226f46a6179SmrgHandleNoAction(	XkbDescPtr	xkb,
227f46a6179Smrg		XkbAnyAction *	action,
228f46a6179Smrg		unsigned	field,
229f46a6179Smrg		ExprDef *	array_ndx,
230f46a6179Smrg		ExprDef *	value)
231f46a6179Smrg{
232f46a6179Smrg    return ReportIllegal(action->type,field);
233f46a6179Smrg}
234f46a6179Smrg
235f46a6179Smrgstatic Bool
236f46a6179SmrgCheckLatchLockFlags(	unsigned	action,
237f46a6179Smrg			unsigned	field,
238f46a6179Smrg			ExprDef *	value,
239f46a6179Smrg			unsigned *	flags_inout)
240f46a6179Smrg{
241f46a6179Smrgunsigned	tmp;
242f46a6179SmrgExprResult	result;
243f46a6179Smrg
244f46a6179Smrg    if (field==F_ClearLocks)		tmp= XkbSA_ClearLocks;
245f46a6179Smrg    else if (field==F_LatchToLock)	tmp= XkbSA_LatchToLock;
246f46a6179Smrg    else 				return False; /* WSGO! */
247f46a6179Smrg    if (!ExprResolveBoolean(value,&result,NULL,NULL))
248f46a6179Smrg	return ReportMismatch(action,field,"boolean");
249f46a6179Smrg    if (result.uval)	*flags_inout|= tmp;
250f46a6179Smrg    else		*flags_inout&= ~tmp;
251f46a6179Smrg    return True;
252f46a6179Smrg}
253f46a6179Smrg
254f46a6179Smrgstatic Bool
255f46a6179SmrgCheckModifierField(	XkbDescPtr	xkb,
256f46a6179Smrg			unsigned	action,
257f46a6179Smrg			ExprDef *	value,
258f46a6179Smrg			unsigned *	flags_inout,
259f46a6179Smrg			unsigned *	mods_rtrn)
260f46a6179Smrg{
261f46a6179SmrgExprResult	rtrn;
262f46a6179Smrg
263f46a6179Smrg    if (value->op==ExprIdent) {
264f46a6179Smrg	register char *valStr;
265f46a6179Smrg	valStr= XkbAtomGetString(NULL,value->value.str);
266f46a6179Smrg	if (valStr&&((uStrCaseCmp(valStr,"usemodmapmods")==0)||
267f46a6179Smrg		     (uStrCaseCmp(valStr,"modmapmods")==0))) {
268f46a6179Smrg
269f46a6179Smrg	    *mods_rtrn= 0;
270f46a6179Smrg	    *flags_inout|= XkbSA_UseModMapMods;
271f46a6179Smrg	    return True;
272f46a6179Smrg	}
273f46a6179Smrg    }
274f46a6179Smrg    if (!ExprResolveModMask(value,&rtrn,LookupVModMask,(XPointer)xkb))
275f46a6179Smrg	return ReportMismatch(action,F_Modifiers,"modifier mask");
276f46a6179Smrg    *mods_rtrn= rtrn.uval;
277f46a6179Smrg    *flags_inout&= ~XkbSA_UseModMapMods;
278f46a6179Smrg    return True;
279f46a6179Smrg}
280f46a6179Smrg
281f46a6179Smrgstatic Bool
282f46a6179SmrgHandleSetLatchMods(	XkbDescPtr	xkb,
283f46a6179Smrg			XkbAnyAction *	action,
284f46a6179Smrg			unsigned	field,
285f46a6179Smrg			ExprDef *	array_ndx,
286f46a6179Smrg			ExprDef *	value)
287f46a6179Smrg{
288f46a6179SmrgXkbModAction *	act;
289f46a6179Smrgunsigned	rtrn;
290f46a6179Smrgunsigned	t1,t2;
291f46a6179Smrg
292f46a6179Smrg    act= (XkbModAction *)action;
293f46a6179Smrg    if (array_ndx!=NULL) {
294f46a6179Smrg	switch (field) {
295f46a6179Smrg	    case F_ClearLocks: case F_LatchToLock:
296f46a6179Smrg	    case F_Modifiers:
297f46a6179Smrg		return ReportActionNotArray(action->type,field);
298f46a6179Smrg	}
299f46a6179Smrg    }
300f46a6179Smrg    switch (field) {
301f46a6179Smrg	case F_ClearLocks:
302f46a6179Smrg	case F_LatchToLock:
303f46a6179Smrg	    rtrn= act->flags;
304f46a6179Smrg	    if (CheckLatchLockFlags(action->type,field,value,&rtrn)) {
305f46a6179Smrg		act->flags= rtrn;
306f46a6179Smrg		return True;
307f46a6179Smrg	    }
308f46a6179Smrg	    return False;
309f46a6179Smrg	case F_Modifiers:
310f46a6179Smrg	    t1= act->flags;
311f46a6179Smrg	    if (CheckModifierField(xkb,action->type,value,&t1,&t2)) {
312f46a6179Smrg		act->flags= t1;
313f46a6179Smrg		act->real_mods= act->mask= (t2&0xff);
314f46a6179Smrg		t2= (t2>>8)&0xffff;
315f46a6179Smrg		XkbSetModActionVMods(act,t2);
316f46a6179Smrg		return True;
317f46a6179Smrg	    }
318f46a6179Smrg	    return False;
319f46a6179Smrg    }
320f46a6179Smrg    return ReportIllegal(action->type,field);
321f46a6179Smrg}
322f46a6179Smrg
323f46a6179Smrgstatic Bool
324f46a6179SmrgHandleLockMods(	XkbDescPtr	xkb,
325f46a6179Smrg		XkbAnyAction *	action,
326f46a6179Smrg		unsigned	field,
327f46a6179Smrg		ExprDef *	array_ndx,
328f46a6179Smrg		ExprDef *	value)
329f46a6179Smrg{
330f46a6179SmrgXkbModAction *	act;
331f46a6179Smrgunsigned	t1,t2;
332f46a6179Smrg
333f46a6179Smrg    act= (XkbModAction *)action;
334f46a6179Smrg    if ((array_ndx!=NULL)&&(field==F_Modifiers))
335f46a6179Smrg	return ReportActionNotArray(action->type,field);
336f46a6179Smrg    switch (field) {
337f46a6179Smrg	case F_Modifiers:
338f46a6179Smrg	    t1= act->flags;
339f46a6179Smrg	    if (CheckModifierField(xkb,action->type,value,&t1,&t2)) {
340f46a6179Smrg		act->flags= t1;
341f46a6179Smrg		act->real_mods= act->mask= (t2&0xff);
342f46a6179Smrg		t2= (t2>>8)&0xffff;
343f46a6179Smrg		XkbSetModActionVMods(act,t2);
344f46a6179Smrg		return True;
345f46a6179Smrg	    }
346f46a6179Smrg	    return False;
347f46a6179Smrg    }
348f46a6179Smrg    return ReportIllegal(action->type,field);
349f46a6179Smrg}
350f46a6179Smrg
351f46a6179Smrgstatic LookupEntry groupNames[] = {
352f46a6179Smrg	{	"group1",	1	},
353f46a6179Smrg	{	"group2",	2	},
354f46a6179Smrg	{	"group3",	3	},
355f46a6179Smrg	{	"group4",	4	},
356f46a6179Smrg	{	"group5",	5	},
357f46a6179Smrg	{	"group6",	6	},
358f46a6179Smrg	{	"group7",	7	},
359f46a6179Smrg	{	"group8",	8	},
360f46a6179Smrg	{	NULL,		0	},
361f46a6179Smrg};
362f46a6179Smrg
363f46a6179Smrgstatic Bool
364f46a6179SmrgCheckGroupField(	unsigned	action,
365f46a6179Smrg			ExprDef *	value,
366f46a6179Smrg			unsigned *	flags_inout,
367f46a6179Smrg			int *		grp_rtrn)
368f46a6179Smrg{
369f46a6179SmrgExprDef *	spec;
370f46a6179SmrgExprResult 	rtrn;
371f46a6179Smrg
372f46a6179Smrg    if ((value->op==OpNegate)||(value->op==OpUnaryPlus)) {
373f46a6179Smrg	*flags_inout&= ~XkbSA_GroupAbsolute;
374f46a6179Smrg	spec= value->value.child;
375f46a6179Smrg    }
376f46a6179Smrg    else {
377f46a6179Smrg	*flags_inout|= XkbSA_GroupAbsolute;
378f46a6179Smrg	spec= value;
379f46a6179Smrg    }
380f46a6179Smrg
381f46a6179Smrg    if (!ExprResolveInteger(spec,&rtrn,SimpleLookup,(XPointer)groupNames))
382f46a6179Smrg	return ReportMismatch(action,F_Group,"integer (range 1..8)");
383f46a6179Smrg    if ((rtrn.ival<1)||(rtrn.ival>XkbNumKbdGroups)) {
384f46a6179Smrg	ERROR2("Illegal group %d (must be in the range 1..%d)\n",rtrn.ival,
385f46a6179Smrg							XkbNumKbdGroups);
386f46a6179Smrg	ACTION1("Action %s definition ignored\n",
387f46a6179Smrg					XkbActionTypeText(action,XkbMessage));
388f46a6179Smrg	return False;
389f46a6179Smrg    }
390f46a6179Smrg    if (value->op==OpNegate)		*grp_rtrn= -rtrn.ival;
391f46a6179Smrg    else if (value->op==OpUnaryPlus)	*grp_rtrn= rtrn.ival;
392f46a6179Smrg    else				*grp_rtrn= rtrn.ival-1;
393f46a6179Smrg    return True;
394f46a6179Smrg}
395f46a6179Smrg
396f46a6179Smrgstatic Bool
397f46a6179SmrgHandleSetLatchGroup(	XkbDescPtr	xkb,
398f46a6179Smrg			XkbAnyAction *	action,
399f46a6179Smrg			unsigned	field,
400f46a6179Smrg			ExprDef *	array_ndx,
401f46a6179Smrg			ExprDef *	value)
402f46a6179Smrg{
403f46a6179SmrgXkbGroupAction *	act;
404f46a6179Smrgunsigned		rtrn;
405f46a6179Smrgunsigned		t1;
406f46a6179Smrgint			t2;
407f46a6179Smrg
408f46a6179Smrg    act= (XkbGroupAction *)action;
409f46a6179Smrg    if (array_ndx!=NULL) {
410f46a6179Smrg	switch (field) {
411f46a6179Smrg	    case F_ClearLocks: case F_LatchToLock:
412f46a6179Smrg	    case F_Group:
413f46a6179Smrg		return ReportActionNotArray(action->type,field);
414f46a6179Smrg	}
415f46a6179Smrg    }
416f46a6179Smrg    switch (field) {
417f46a6179Smrg	case F_ClearLocks:
418f46a6179Smrg	case F_LatchToLock:
419f46a6179Smrg	    rtrn= act->flags;
420f46a6179Smrg	    if (CheckLatchLockFlags(action->type,field,value,&rtrn)) {
421f46a6179Smrg		act->flags= rtrn;
422f46a6179Smrg		return True;
423f46a6179Smrg	    }
424f46a6179Smrg	    return False;
425f46a6179Smrg	case F_Group:
426f46a6179Smrg	    t1= act->flags;
427f46a6179Smrg	    if (CheckGroupField(action->type,value,&t1,&t2)) {
428f46a6179Smrg		act->flags= t1;
429f46a6179Smrg		XkbSASetGroup(act,t2);
430f46a6179Smrg		return True;
431f46a6179Smrg	    }
432f46a6179Smrg	    return False;
433f46a6179Smrg    }
434f46a6179Smrg    return ReportIllegal(action->type,field);
435f46a6179Smrg}
436f46a6179Smrg
437f46a6179Smrgstatic Bool
438f46a6179SmrgHandleLockGroup(	XkbDescPtr	xkb,
439f46a6179Smrg			XkbAnyAction *	action,
440f46a6179Smrg			unsigned	field,
441f46a6179Smrg			ExprDef *	array_ndx,
442f46a6179Smrg			ExprDef *	value)
443f46a6179Smrg{
444f46a6179SmrgXkbGroupAction *	act;
445f46a6179Smrgunsigned		t1;
446f46a6179Smrgint			t2;
447f46a6179Smrg
448f46a6179Smrg    act= (XkbGroupAction *)action;
449f46a6179Smrg    if ((array_ndx!=NULL) && (field==F_Group))
450f46a6179Smrg	return ReportActionNotArray(action->type,field);
451f46a6179Smrg    if (field==F_Group) {
452f46a6179Smrg	t1= act->flags;
453f46a6179Smrg	if (CheckGroupField(action->type,value,&t1,&t2)) {
454f46a6179Smrg	    act->flags= t1;
455f46a6179Smrg	    XkbSASetGroup(act,t2);
456f46a6179Smrg	    return True;
457f46a6179Smrg	}
458f46a6179Smrg	return False;
459f46a6179Smrg    }
460f46a6179Smrg    return ReportIllegal(action->type,field);
461f46a6179Smrg}
462f46a6179Smrg
463f46a6179Smrgstatic Bool
464f46a6179SmrgHandleMovePtr(	XkbDescPtr 	xkb,
465f46a6179Smrg		XkbAnyAction *	action,
466f46a6179Smrg		unsigned	field,
467f46a6179Smrg		ExprDef *	array_ndx,
468f46a6179Smrg		ExprDef *	value)
469f46a6179Smrg{
470f46a6179SmrgExprResult	rtrn;
471f46a6179SmrgXkbPtrAction *	act;
472f46a6179SmrgBool		absolute;
473f46a6179Smrg
474f46a6179Smrg    act= (XkbPtrAction *)action;
475f46a6179Smrg    if ((array_ndx!=NULL)&&((field==F_X)||(field==F_Y)))
476f46a6179Smrg	return ReportActionNotArray(action->type,field);
477f46a6179Smrg
478f46a6179Smrg    if ((field==F_X)||(field==F_Y)) {
479f46a6179Smrg	if ((value->op==OpNegate)||(value->op==OpUnaryPlus))
480f46a6179Smrg	     absolute= False;
481f46a6179Smrg	else absolute= True;
482f46a6179Smrg	if (!ExprResolveInteger(value,&rtrn,NULL,NULL))
483f46a6179Smrg	    return ReportMismatch(action->type,field,"integer");
484f46a6179Smrg	if (field==F_X) {
485f46a6179Smrg	    if (absolute)
486f46a6179Smrg		act->flags|= XkbSA_MoveAbsoluteX;
487f46a6179Smrg	    XkbSetPtrActionX(act,rtrn.ival);
488f46a6179Smrg	}
489f46a6179Smrg	else {
490f46a6179Smrg	    if (absolute)
491f46a6179Smrg		act->flags|= XkbSA_MoveAbsoluteY;
492f46a6179Smrg	    XkbSetPtrActionY(act,rtrn.ival);
493f46a6179Smrg	}
494f46a6179Smrg	return True;
495f46a6179Smrg    }
496f46a6179Smrg    else if (field==F_Accel) {
497f46a6179Smrg	if (!ExprResolveBoolean(value,&rtrn,NULL,NULL))
498f46a6179Smrg	    return ReportMismatch(action->type,field,"boolean");
499f46a6179Smrg	if (rtrn.uval)	act->flags&= ~XkbSA_NoAcceleration;
500f46a6179Smrg	else 			act->flags|= XkbSA_NoAcceleration;
501f46a6179Smrg    }
502f46a6179Smrg    return ReportIllegal(action->type,field);
503f46a6179Smrg}
504f46a6179Smrg
505f46a6179Smrgstatic LookupEntry btnNames[] = {
506f46a6179Smrg	{	"button1",	1	},
507f46a6179Smrg	{	"button2",	2	},
508f46a6179Smrg	{	"button3",	3	},
509f46a6179Smrg	{	"button4",	4	},
510f46a6179Smrg	{	"button5",	5	},
511f46a6179Smrg	{	"default",	0	},
512f46a6179Smrg	{	NULL,		0	}
513f46a6179Smrg};
514f46a6179Smrg
515f46a6179Smrgstatic LookupEntry lockWhich[] = {
516f46a6179Smrg	{	"both",		0					},
517f46a6179Smrg	{	"lock",		XkbSA_LockNoUnlock			},
518f46a6179Smrg	{	"neither",	(XkbSA_LockNoLock|XkbSA_LockNoUnlock)	},
519f46a6179Smrg	{	"unlock",	XkbSA_LockNoLock			},
520f46a6179Smrg	{	NULL,		0	}
521f46a6179Smrg};
522f46a6179Smrg
523f46a6179Smrgstatic Bool
524f46a6179SmrgHandlePtrBtn(	XkbDescPtr 	xkb,
525f46a6179Smrg		XkbAnyAction *	action,
526f46a6179Smrg		unsigned	field,
527f46a6179Smrg		ExprDef *	array_ndx,
528f46a6179Smrg		ExprDef *	value)
529f46a6179Smrg{
530f46a6179SmrgExprResult		rtrn;
531f46a6179SmrgXkbPtrBtnAction	*	act;
532f46a6179Smrg
533f46a6179Smrg    act= (XkbPtrBtnAction *)action;
534f46a6179Smrg    if (field==F_Button) {
535f46a6179Smrg	if (array_ndx!=NULL)
536f46a6179Smrg	    return ReportActionNotArray(action->type,field);
537f46a6179Smrg	if (!ExprResolveInteger(value,&rtrn,SimpleLookup,(XPointer)btnNames))
538f46a6179Smrg	    return ReportMismatch(action->type,field,"integer (range 1..5)");
539f46a6179Smrg	if ((rtrn.ival<0)||(rtrn.ival>5)) {
540f46a6179Smrg	    ERROR("Button must specify default or be in the range 1..5\n");
541f46a6179Smrg	    ACTION1("Illegal button value %d ignored\n",rtrn.ival);
542f46a6179Smrg	    return False;
543f46a6179Smrg	}
544f46a6179Smrg	act->button= rtrn.ival;
545f46a6179Smrg	return True;
546f46a6179Smrg    }
547f46a6179Smrg    else if ((action->type==XkbSA_LockPtrBtn)&&(field==F_Affect)) {
548f46a6179Smrg	if (array_ndx!=NULL)
549f46a6179Smrg	    return ReportActionNotArray(action->type,field);
550f46a6179Smrg	if (!ExprResolveEnum(value,&rtrn,lockWhich))
551f46a6179Smrg	    return ReportMismatch(action->type,field,"lock or unlock");
552f46a6179Smrg	act->flags&= ~(XkbSA_LockNoLock|XkbSA_LockNoUnlock);
553f46a6179Smrg	act->flags|= rtrn.ival;
554f46a6179Smrg	return True;
555f46a6179Smrg    }
556f46a6179Smrg    else if (field==F_Count) {
557f46a6179Smrg	if (array_ndx!=NULL)
558f46a6179Smrg	    return ReportActionNotArray(action->type,field);
559f46a6179Smrg	if (!ExprResolveInteger(value,&rtrn,SimpleLookup,(XPointer)btnNames))
560f46a6179Smrg	    return ReportMismatch(action->type,field,"integer");
561f46a6179Smrg	if ((rtrn.ival<0)||(rtrn.ival>255)) {
562f46a6179Smrg	    ERROR("The count field must have a value in the range 0..255\n");
563f46a6179Smrg	    ACTION1("Illegal count %d ignored\n",rtrn.ival);
564f46a6179Smrg	    return False;
565f46a6179Smrg	}
566f46a6179Smrg	act->count= rtrn.ival;
567f46a6179Smrg	return True;
568f46a6179Smrg    }
569f46a6179Smrg    return ReportIllegal(action->type,field);
570f46a6179Smrg}
571f46a6179Smrg
572f46a6179Smrgstatic LookupEntry ptrDflts[] = {
573f46a6179Smrg	{	"dfltbtn",		XkbSA_AffectDfltBtn	},
574f46a6179Smrg	{	"defaultbutton",	XkbSA_AffectDfltBtn	},
575f46a6179Smrg	{	"button",		XkbSA_AffectDfltBtn	},
576f46a6179Smrg	{ 	NULL,			0			}
577f46a6179Smrg};
578f46a6179Smrg
579f46a6179Smrgstatic Bool
580f46a6179SmrgHandleSetPtrDflt(	XkbDescPtr 	xkb,
581f46a6179Smrg			XkbAnyAction *	action,
582f46a6179Smrg			unsigned	field,
583f46a6179Smrg			ExprDef *	array_ndx,
584f46a6179Smrg			ExprDef *	value)
585f46a6179Smrg{
586f46a6179SmrgExprResult		rtrn;
587f46a6179SmrgXkbPtrDfltAction *	act;
588f46a6179Smrg
589f46a6179Smrg    act= (XkbPtrDfltAction *)action;
590f46a6179Smrg    if (field==F_Affect) {
591f46a6179Smrg	if (array_ndx!=NULL)
592f46a6179Smrg	    return ReportActionNotArray(action->type,field);
593f46a6179Smrg	if (!ExprResolveEnum(value,&rtrn,ptrDflts))
594f46a6179Smrg	    return ReportMismatch(action->type,field,"pointer component");
595f46a6179Smrg	act->affect= rtrn.uval;
596f46a6179Smrg	return True;
597f46a6179Smrg    }
598f46a6179Smrg    else if ((field==F_Button)||(field==F_Value)) {
599f46a6179Smrg	ExprDef *btn;
600f46a6179Smrg	if (array_ndx!=NULL)
601f46a6179Smrg	    return ReportActionNotArray(action->type,field);
602f46a6179Smrg	if ((value->op==OpNegate)||(value->op==OpUnaryPlus))  {
603f46a6179Smrg	    act->flags&= ~XkbSA_DfltBtnAbsolute;
604f46a6179Smrg	    btn= value->value.child;
605f46a6179Smrg	}
606f46a6179Smrg	else {
607f46a6179Smrg	    act->flags|= XkbSA_DfltBtnAbsolute;
608f46a6179Smrg	    btn= value;
609f46a6179Smrg	}
610f46a6179Smrg
611f46a6179Smrg	if (!ExprResolveInteger(btn,&rtrn,SimpleLookup,(XPointer)btnNames))
612f46a6179Smrg	    return ReportMismatch(action->type,field,"integer (range 1..5)");
613f46a6179Smrg	if ((rtrn.ival<0)||(rtrn.ival>5)) {
614f46a6179Smrg	    ERROR("New default button value must be in the range 1..5\n");
615f46a6179Smrg	    ACTION1("Illegal default button value %d ignored\n",rtrn.ival);
616f46a6179Smrg	    return False;
617f46a6179Smrg	}
618f46a6179Smrg	if (rtrn.ival==0) {
619f46a6179Smrg	    ERROR("Cannot set default pointer button to \"default\"\n");
620f46a6179Smrg	    ACTION("Illegal default button setting ignored\n");
621f46a6179Smrg	    return False;
622f46a6179Smrg	}
623f46a6179Smrg	if (value->op==OpNegate)
624f46a6179Smrg	     XkbSASetPtrDfltValue(act,-rtrn.ival);
625f46a6179Smrg	else XkbSASetPtrDfltValue(act,rtrn.ival);
626f46a6179Smrg	return True;
627f46a6179Smrg    }
628f46a6179Smrg    return ReportIllegal(action->type,field);
629f46a6179Smrg}
630f46a6179Smrg
631f46a6179Smrgstatic LookupEntry	isoNames[] = {
632f46a6179Smrg	{	"mods",		XkbSA_ISONoAffectMods	},
633f46a6179Smrg	{	"modifiers",	XkbSA_ISONoAffectMods	},
634f46a6179Smrg	{	"group",	XkbSA_ISONoAffectGroup	},
635f46a6179Smrg	{	"groups",	XkbSA_ISONoAffectGroup	},
636f46a6179Smrg	{	"ptr",		XkbSA_ISONoAffectPtr	},
637f46a6179Smrg	{	"pointer",	XkbSA_ISONoAffectPtr	},
638f46a6179Smrg	{	"ctrls",	XkbSA_ISONoAffectCtrls	},
639f46a6179Smrg	{	"controls",	XkbSA_ISONoAffectCtrls	},
640f46a6179Smrg	{	"all",		~((unsigned)0)		},
641f46a6179Smrg	{	"none",		0			},
642f46a6179Smrg	{	NULL,		0			},
643f46a6179Smrg};
644f46a6179Smrg
645f46a6179Smrgstatic Bool
646f46a6179SmrgHandleISOLock(	XkbDescPtr 	xkb,
647f46a6179Smrg		XkbAnyAction *	action,
648f46a6179Smrg		unsigned	field,
649f46a6179Smrg		ExprDef *	array_ndx,
650f46a6179Smrg		ExprDef *	value)
651f46a6179Smrg{
652f46a6179SmrgExprResult	rtrn;
653f46a6179SmrgXkbISOAction *	act;
654f46a6179Smrgunsigned	flags,mods;
655f46a6179Smrgint		group;
656f46a6179Smrg
657f46a6179Smrg    act= (XkbISOAction *)action;
658f46a6179Smrg    switch (field) {
659f46a6179Smrg	case F_Modifiers:
660f46a6179Smrg	    if (array_ndx!=NULL)
661f46a6179Smrg		return ReportActionNotArray(action->type,field);
662f46a6179Smrg	    flags= act->flags;
663f46a6179Smrg	    if (CheckModifierField(xkb,action->type,value,&flags,&mods)) {
664f46a6179Smrg		act->flags= flags&(~XkbSA_ISODfltIsGroup);
665f46a6179Smrg		act->real_mods= mods&0xff;
666f46a6179Smrg		mods= (mods>>8)&0xff;
667f46a6179Smrg		XkbSetModActionVMods(act,mods);
668f46a6179Smrg		return True;
669f46a6179Smrg	    }
670f46a6179Smrg	    return False;
671f46a6179Smrg	case F_Group:
672f46a6179Smrg	    if (array_ndx!=NULL)
673f46a6179Smrg		return ReportActionNotArray(action->type,field);
674f46a6179Smrg	    flags= act->flags;
675f46a6179Smrg	    if (CheckGroupField(action->type,value,&flags,&group)) {
676f46a6179Smrg		act->flags= flags|XkbSA_ISODfltIsGroup;
677f46a6179Smrg		XkbSASetGroup(act,group);
678f46a6179Smrg		return True;
679f46a6179Smrg	    }
680f46a6179Smrg	    return False;
681f46a6179Smrg	case F_Affect:
682f46a6179Smrg	    if (array_ndx!=NULL)
683f46a6179Smrg		return ReportActionNotArray(action->type,field);
684f46a6179Smrg	    if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)isoNames))
685f46a6179Smrg		return ReportMismatch(action->type,field,"keyboard component");
686f46a6179Smrg	    act->affect= (~rtrn.uval)&XkbSA_ISOAffectMask;
687f46a6179Smrg	    return True;
688f46a6179Smrg    }
689f46a6179Smrg    return ReportIllegal(action->type,field);
690f46a6179Smrg}
691f46a6179Smrg
692f46a6179Smrgstatic Bool
693f46a6179SmrgHandleSwitchScreen(	XkbDescPtr 	xkb,
694f46a6179Smrg			XkbAnyAction *	action,
695f46a6179Smrg			unsigned	field,
696f46a6179Smrg			ExprDef *	array_ndx,
697f46a6179Smrg			ExprDef *	value)
698f46a6179Smrg{
699f46a6179SmrgExprResult		rtrn;
700f46a6179SmrgXkbSwitchScreenAction *	act;
701f46a6179Smrg
702f46a6179Smrg    act= (XkbSwitchScreenAction *)action;
703f46a6179Smrg    if (field==F_Screen) {
704f46a6179Smrg	ExprDef *scrn;
705f46a6179Smrg	if (array_ndx!=NULL)
706f46a6179Smrg	    return ReportActionNotArray(action->type,field);
707f46a6179Smrg	if ((value->op==OpNegate)||(value->op==OpUnaryPlus)) {
708f46a6179Smrg	    act->flags&= ~XkbSA_SwitchAbsolute;
709f46a6179Smrg	    scrn= value->value.child;
710f46a6179Smrg	}
711f46a6179Smrg	else {
712f46a6179Smrg	    act->flags|= XkbSA_SwitchAbsolute;
713f46a6179Smrg	    scrn= value;
714f46a6179Smrg	}
715f46a6179Smrg
716f46a6179Smrg	if (!ExprResolveInteger(scrn,&rtrn,NULL,NULL))
717f46a6179Smrg	    return ReportMismatch(action->type,field,"integer (0..255)");
718f46a6179Smrg	if ((rtrn.ival<0)||(rtrn.ival>255)) {
719f46a6179Smrg	    ERROR("Screen index must be in the range 1..255\n");
720f46a6179Smrg	    ACTION1("Illegal screen value %d ignored\n",rtrn.ival);
721f46a6179Smrg	    return False;
722f46a6179Smrg	}
723f46a6179Smrg	if (value->op==OpNegate)
724f46a6179Smrg	     XkbSASetScreen(act,-rtrn.ival);
725f46a6179Smrg	else XkbSASetScreen(act,rtrn.ival);
726f46a6179Smrg	return True;
727f46a6179Smrg    }
728f46a6179Smrg    else if (field==F_Same) {
729f46a6179Smrg	if (array_ndx!=NULL)
730f46a6179Smrg	    return ReportActionNotArray(action->type,field);
731f46a6179Smrg	if (!ExprResolveBoolean(value,&rtrn,NULL,NULL))
732f46a6179Smrg	    return ReportMismatch(action->type,field,"boolean");
733f46a6179Smrg	if (rtrn.uval)	act->flags&= ~XkbSA_SwitchApplication;
734f46a6179Smrg	else		act->flags|= XkbSA_SwitchApplication;
735f46a6179Smrg	return True;
736f46a6179Smrg    }
737f46a6179Smrg    return ReportIllegal(action->type,field);
738f46a6179Smrg}
739f46a6179Smrg
740f46a6179SmrgLookupEntry	ctrlNames[]= {
741f46a6179Smrg	{	"repeatkeys",		XkbRepeatKeysMask	},
742f46a6179Smrg	{	"repeat",		XkbRepeatKeysMask	},
743f46a6179Smrg	{	"autorepeat",		XkbRepeatKeysMask	},
744f46a6179Smrg	{	"slowkeys",		XkbSlowKeysMask		},
745f46a6179Smrg	{	"bouncekeys",		XkbBounceKeysMask	},
746f46a6179Smrg	{	"stickykeys",		XkbStickyKeysMask	},
747f46a6179Smrg	{	"mousekeys",		XkbMouseKeysMask	},
748f46a6179Smrg	{	"mousekeysaccel",	XkbMouseKeysAccelMask	},
749f46a6179Smrg	{	"accessxkeys",		XkbAccessXKeysMask	},
750f46a6179Smrg	{	"accessxtimeout",	XkbAccessXTimeoutMask	},
751f46a6179Smrg	{	"accessxfeedback",	XkbAccessXFeedbackMask	},
752f46a6179Smrg	{	"audiblebell",		XkbAudibleBellMask	},
753f46a6179Smrg	{	"overlay1",		XkbOverlay1Mask		},
754f46a6179Smrg	{	"overlay2",		XkbOverlay2Mask		},
755f46a6179Smrg	{	"ignoregrouplock",	XkbIgnoreGroupLockMask	},
756f46a6179Smrg	{	"all",			XkbAllBooleanCtrlsMask	},
757f46a6179Smrg	{	"none",			0			},
758f46a6179Smrg	{	NULL,			0			}
759f46a6179Smrg};
760f46a6179Smrg
761f46a6179Smrgstatic Bool
762f46a6179SmrgHandleSetLockControls(	XkbDescPtr 	xkb,
763f46a6179Smrg			XkbAnyAction *	action,
764f46a6179Smrg			unsigned	field,
765f46a6179Smrg			ExprDef *	array_ndx,
766f46a6179Smrg			ExprDef *	value)
767f46a6179Smrg{
768f46a6179SmrgExprResult		rtrn;
769f46a6179SmrgXkbCtrlsAction *	act;
770f46a6179Smrg
771f46a6179Smrg    act= (XkbCtrlsAction *)action;
772f46a6179Smrg    if (field==F_Controls) {
773f46a6179Smrg	if (array_ndx!=NULL)
774f46a6179Smrg	    return ReportActionNotArray(action->type,field);
775f46a6179Smrg	if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)ctrlNames))
776f46a6179Smrg	    return ReportMismatch(action->type,field,"controls mask");
777f46a6179Smrg	XkbActionSetCtrls(act,rtrn.uval);
778f46a6179Smrg	return True;
779f46a6179Smrg    }
780f46a6179Smrg    return ReportIllegal(action->type,field);
781f46a6179Smrg}
782f46a6179Smrg
783f46a6179Smrgstatic LookupEntry evNames[]= {
784f46a6179Smrg	{	"press",	XkbSA_MessageOnPress	},
785f46a6179Smrg	{	"keypress",	XkbSA_MessageOnPress	},
786f46a6179Smrg	{	"release",	XkbSA_MessageOnRelease	},
787f46a6179Smrg	{	"keyrelease",	XkbSA_MessageOnRelease	},
788f46a6179Smrg	{	"all",		XkbSA_MessageOnPress|XkbSA_MessageOnRelease },
789f46a6179Smrg	{	"none",		0			},
790f46a6179Smrg	{	NULL,		0			}
791f46a6179Smrg};
792f46a6179Smrg
793f46a6179Smrgstatic Bool
794f46a6179SmrgHandleActionMessage(	XkbDescPtr 	xkb,
795f46a6179Smrg			XkbAnyAction *	action,
796f46a6179Smrg			unsigned	field,
797f46a6179Smrg			ExprDef *	array_ndx,
798f46a6179Smrg			ExprDef *	value)
799f46a6179Smrg{
800f46a6179SmrgExprResult		rtrn;
801f46a6179SmrgXkbMessageAction *	act;
802f46a6179Smrg
803f46a6179Smrg    act= (XkbMessageAction *)action;
804f46a6179Smrg    switch (field) {
805f46a6179Smrg	case F_Report:
806f46a6179Smrg	    if (array_ndx!=NULL)
807f46a6179Smrg		return ReportActionNotArray(action->type,field);
808f46a6179Smrg	    if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)evNames))
809f46a6179Smrg		return ReportMismatch(action->type,field,"key event mask");
810f46a6179Smrg	    act->flags&= ~(XkbSA_MessageOnPress|XkbSA_MessageOnRelease);
811f46a6179Smrg	    act->flags= rtrn.uval&(XkbSA_MessageOnPress|XkbSA_MessageOnRelease);
812f46a6179Smrg	    return True;
813f46a6179Smrg	case F_GenKeyEvent:
814f46a6179Smrg	    if (array_ndx!=NULL)
815f46a6179Smrg		return ReportActionNotArray(action->type,field);
816f46a6179Smrg	    if (!ExprResolveBoolean(value,&rtrn,NULL,NULL))
817f46a6179Smrg		return ReportMismatch(action->type,field,"boolean");
818f46a6179Smrg	    if (rtrn.uval)	act->flags|= XkbSA_MessageGenKeyEvent;
819f46a6179Smrg	    else		act->flags&= ~XkbSA_MessageGenKeyEvent;
820f46a6179Smrg	    return True;
821f46a6179Smrg	case F_Data:
822f46a6179Smrg	    if (array_ndx==NULL) {
823f46a6179Smrg		if (!ExprResolveString(value,&rtrn,NULL,NULL))
824f46a6179Smrg		    return ReportMismatch(action->type,field,"string");
825f46a6179Smrg		else {
826f46a6179Smrg		    int len= strlen(rtrn.str);
827f46a6179Smrg		    if ((len<1)||(len>6)) {
828f46a6179Smrg			WARN("An action message can hold only 6 bytes\n");
829f46a6179Smrg			ACTION1("Extra %d bytes ignored\n",len-6);
830f46a6179Smrg		    }
831f46a6179Smrg		    strncpy((char *)act->message,rtrn.str,6);
832f46a6179Smrg		}
833f46a6179Smrg		return True;
834f46a6179Smrg	    }
835f46a6179Smrg	    else {
836f46a6179Smrg		unsigned ndx;
837f46a6179Smrg		if (!ExprResolveInteger(array_ndx,&rtrn,NULL,NULL)) {
838f46a6179Smrg		    ERROR("Array subscript must be integer\n");
839f46a6179Smrg		    ACTION("Illegal subscript ignored\n");
840f46a6179Smrg		    return False;
841f46a6179Smrg		}
842f46a6179Smrg		ndx= rtrn.uval;
843f46a6179Smrg		if (ndx>5) {
844f46a6179Smrg		    ERROR("An action message is at most 6 bytes long\n");
845f46a6179Smrg		    ACTION1("Attempt to use data[%d] ignored\n",ndx);
846f46a6179Smrg		    return False;
847f46a6179Smrg		}
848f46a6179Smrg		if (!ExprResolveInteger(value,&rtrn,NULL,NULL))
849f46a6179Smrg		    return ReportMismatch(action->type,field,"integer");
850f46a6179Smrg		if ((rtrn.ival<0)||(rtrn.ival>255)) {
851f46a6179Smrg		    ERROR("Message data must be in the range 0..255\n");
852f46a6179Smrg		    ACTION1("Illegal datum %d ignored\n",rtrn.ival);
853f46a6179Smrg		    return False;
854f46a6179Smrg		}
855f46a6179Smrg		act->message[ndx]= rtrn.uval;
856f46a6179Smrg	    }
857f46a6179Smrg	    return True;
858f46a6179Smrg    }
859f46a6179Smrg    return ReportIllegal(action->type,field);
860f46a6179Smrg}
861f46a6179Smrg
862f46a6179Smrgstatic Bool
863f46a6179SmrgHandleRedirectKey(	XkbDescPtr 	xkb,
864f46a6179Smrg			XkbAnyAction *	action,
865f46a6179Smrg			unsigned	field,
866f46a6179Smrg			ExprDef *	array_ndx,
867f46a6179Smrg			ExprDef *	value)
868f46a6179Smrg{
869f46a6179SmrgExprResult		rtrn;
870f46a6179SmrgXkbRedirectKeyAction *	act;
871f46a6179Smrgunsigned		t1,t2,vmods,vmask;
872f46a6179Smrgunsigned long 		tmp;
873f46a6179Smrg
874f46a6179Smrg    if (array_ndx!=NULL)
875f46a6179Smrg	return ReportActionNotArray(action->type,field);
876f46a6179Smrg
877f46a6179Smrg    act= (XkbRedirectKeyAction *)action;
878f46a6179Smrg    switch (field) {
879f46a6179Smrg	case F_Keycode:
880f46a6179Smrg	    if (!ExprResolveKeyName(value,&rtrn,NULL,NULL))
881f46a6179Smrg		return ReportMismatch(action->type,field,"key name");
882f46a6179Smrg	    tmp= KeyNameToLong(rtrn.keyName.name);
883f46a6179Smrg	    if (!FindNamedKey(xkb,tmp,&t1,True,CreateKeyNames(xkb),0)) {
884f46a6179Smrg		return ReportNotFound(action->type,field,"Key",
885f46a6179Smrg				XkbKeyNameText(rtrn.keyName.name,XkbMessage));
886f46a6179Smrg	    }
887f46a6179Smrg	    act->new_key= t1;
888f46a6179Smrg	    return True;
889f46a6179Smrg	case F_ModsToClear:
890f46a6179Smrg	case F_Modifiers:
891f46a6179Smrg	    t1= 0;
892f46a6179Smrg	    if (CheckModifierField(xkb,action->type,value,&t1,&t2)) {
893f46a6179Smrg		act->mods_mask|= (t2&0xff);
894f46a6179Smrg		if (field==F_Modifiers)
895f46a6179Smrg		     act->mods|= (t2&0xff);
896f46a6179Smrg		else act->mods&= ~(t2&0xff);
897f46a6179Smrg
898f46a6179Smrg		t2= (t2>>8)&0xffff;
899f46a6179Smrg		vmods= XkbSARedirectVMods(act);
900f46a6179Smrg		vmask= XkbSARedirectVModsMask(act);
901f46a6179Smrg		vmask|= t2;
902f46a6179Smrg		if (field==F_Modifiers)
903f46a6179Smrg		     vmods|= t2;
904f46a6179Smrg		else vmods&= ~t2;
905f46a6179Smrg		XkbSARedirectSetVMods(act,vmods);
906f46a6179Smrg		XkbSARedirectSetVModsMask(act,vmask);
907f46a6179Smrg		return True;
908f46a6179Smrg	    }
909f46a6179Smrg	    return True;
910f46a6179Smrg    }
911f46a6179Smrg    return ReportIllegal(action->type,field);
912f46a6179Smrg}
913f46a6179Smrg
914f46a6179Smrgstatic Bool
915f46a6179SmrgHandleDeviceBtn(	XkbDescPtr 	xkb,
916f46a6179Smrg			XkbAnyAction *	action,
917f46a6179Smrg			unsigned	field,
918f46a6179Smrg			ExprDef *	array_ndx,
919f46a6179Smrg			ExprDef *	value)
920f46a6179Smrg{
921f46a6179SmrgExprResult		rtrn;
922f46a6179SmrgXkbDeviceBtnAction *	act;
923f46a6179Smrg
924f46a6179Smrg    act= (XkbDeviceBtnAction *)action;
925f46a6179Smrg    if (field==F_Button) {
926f46a6179Smrg	if (array_ndx!=NULL)
927f46a6179Smrg	    return ReportActionNotArray(action->type,field);
928f46a6179Smrg	if (!ExprResolveInteger(value,&rtrn,NULL,NULL))
929f46a6179Smrg	    return ReportMismatch(action->type,field,"integer (range 1..255)");
930f46a6179Smrg	if ((rtrn.ival<0)||(rtrn.ival>255)) {
931f46a6179Smrg	    ERROR("Button must specify default or be in the range 1..255\n");
932f46a6179Smrg	    ACTION1("Illegal button value %d ignored\n",rtrn.ival);
933f46a6179Smrg	    return False;
934f46a6179Smrg	}
935f46a6179Smrg	act->button= rtrn.ival;
936f46a6179Smrg	return True;
937f46a6179Smrg    }
938f46a6179Smrg    else if ((action->type==XkbSA_LockDeviceBtn)&&(field==F_Affect)) {
939f46a6179Smrg	if (array_ndx!=NULL)
940f46a6179Smrg	    return ReportActionNotArray(action->type,field);
941f46a6179Smrg	if (!ExprResolveEnum(value,&rtrn,lockWhich))
942f46a6179Smrg	    return ReportMismatch(action->type,field,"lock or unlock");
943f46a6179Smrg	act->flags&= ~(XkbSA_LockNoLock|XkbSA_LockNoUnlock);
944f46a6179Smrg	act->flags|= rtrn.ival;
945f46a6179Smrg	return True;
946f46a6179Smrg    }
947f46a6179Smrg    else if (field==F_Count) {
948f46a6179Smrg	if (array_ndx!=NULL)
949f46a6179Smrg	    return ReportActionNotArray(action->type,field);
950f46a6179Smrg	if (!ExprResolveInteger(value,&rtrn,SimpleLookup,(XPointer)btnNames))
951f46a6179Smrg	    return ReportMismatch(action->type,field,"integer");
952f46a6179Smrg	if ((rtrn.ival<0)||(rtrn.ival>255)) {
953f46a6179Smrg	    ERROR("The count field must have a value in the range 0..255\n");
954f46a6179Smrg	    ACTION1("Illegal count %d ignored\n",rtrn.ival);
955f46a6179Smrg	    return False;
956f46a6179Smrg	}
957f46a6179Smrg	act->count= rtrn.ival;
958f46a6179Smrg	return True;
959f46a6179Smrg    }
960f46a6179Smrg    else if (field==F_Device) {
961f46a6179Smrg	if (array_ndx!=NULL)
962f46a6179Smrg	    return ReportActionNotArray(action->type,field);
963f46a6179Smrg	if (!ExprResolveInteger(value,&rtrn,NULL,NULL))
964f46a6179Smrg	    return ReportMismatch(action->type,field,"integer (range 1..255)");
965f46a6179Smrg	if ((rtrn.ival<0)||(rtrn.ival>255)) {
966f46a6179Smrg	    ERROR("Device must specify default or be in the range 1..255\n");
967f46a6179Smrg	    ACTION1("Illegal device value %d ignored\n",rtrn.ival);
968f46a6179Smrg	    return False;
969f46a6179Smrg	}
970f46a6179Smrg	act->device= rtrn.ival;
971f46a6179Smrg	return True;
972f46a6179Smrg    }
973f46a6179Smrg    return ReportIllegal(action->type,field);
974f46a6179Smrg}
975f46a6179Smrg
976f46a6179Smrgstatic Bool
977f46a6179SmrgHandleDeviceValuator(	XkbDescPtr 	xkb,
978f46a6179Smrg			XkbAnyAction *	action,
979f46a6179Smrg			unsigned	field,
980f46a6179Smrg			ExprDef *	array_ndx,
981f46a6179Smrg			ExprDef *	value)
982f46a6179Smrg{
983f46a6179Smrg#if 0
984f46a6179SmrgExprResult			rtrn;
985f46a6179SmrgXkbDeviceValuatorAction *	act;
986f46a6179Smrg
987f46a6179Smrg    act= (XkbDeviceValuatorAction *)action;
988f46a6179Smrg    /*  XXX - Not yet implemented */
989f46a6179Smrg#endif
990f46a6179Smrg    return False;
991f46a6179Smrg}
992f46a6179Smrg
993f46a6179Smrgstatic Bool
994f46a6179SmrgHandlePrivate(	XkbDescPtr 	xkb,
995f46a6179Smrg		XkbAnyAction *	action,
996f46a6179Smrg		unsigned	field,
997f46a6179Smrg		ExprDef *	array_ndx,
998f46a6179Smrg		ExprDef *	value)
999f46a6179Smrg{
1000f46a6179SmrgExprResult	rtrn;
1001f46a6179Smrg
1002f46a6179Smrg    switch (field) {
1003f46a6179Smrg	case F_Type:
1004f46a6179Smrg	    if (!ExprResolveInteger(value,&rtrn,NULL,NULL))
1005f46a6179Smrg		return ReportMismatch(PrivateAction,field,"integer");
1006f46a6179Smrg	    if ((rtrn.ival<0)||(rtrn.ival>255)) {
1007f46a6179Smrg		ERROR("Private action type must be in the range 0..255\n");
1008f46a6179Smrg		ACTION1("Illegal type %d ignored\n",rtrn.ival);
1009f46a6179Smrg		return False;
1010f46a6179Smrg	    }
1011f46a6179Smrg	    action->type= rtrn.uval;
1012f46a6179Smrg	    return True;
1013f46a6179Smrg	case F_Data:
1014f46a6179Smrg	    if (array_ndx==NULL) {
1015f46a6179Smrg		if (!ExprResolveString(value,&rtrn,NULL,NULL))
1016f46a6179Smrg		    return ReportMismatch(action->type,field,"string");
1017f46a6179Smrg		else {
1018f46a6179Smrg		    int len= strlen(rtrn.str);
1019f46a6179Smrg		    if ((len<1)||(len>7)) {
1020f46a6179Smrg			WARN("A private action has 7 data bytes\n");
1021f46a6179Smrg			ACTION1("Extra %d bytes ignored\n",len-6);
1022f46a6179Smrg			return False;
1023f46a6179Smrg		    }
1024f46a6179Smrg		    strncpy((char *)action->data,rtrn.str,7);
1025f46a6179Smrg		}
1026f46a6179Smrg		return True;
1027f46a6179Smrg	    }
1028f46a6179Smrg	    else {
1029f46a6179Smrg		unsigned ndx;
1030f46a6179Smrg		if (!ExprResolveInteger(array_ndx,&rtrn,NULL,NULL)) {
1031f46a6179Smrg		    ERROR("Array subscript must be integer\n");
1032f46a6179Smrg		    ACTION("Illegal subscript ignored\n");
1033f46a6179Smrg		    return False;
1034f46a6179Smrg		}
1035f46a6179Smrg		ndx= rtrn.uval;
1036f46a6179Smrg		if (ndx>6) {
1037f46a6179Smrg		    ERROR("The data for a private action is 7 bytes long\n");
1038f46a6179Smrg		    ACTION1("Attempt to use data[%d] ignored\n",ndx);
1039f46a6179Smrg		    return False;
1040f46a6179Smrg		}
1041f46a6179Smrg		if (!ExprResolveInteger(value,&rtrn,NULL,NULL))
1042f46a6179Smrg		    return ReportMismatch(action->type,field,"integer");
1043f46a6179Smrg		if ((rtrn.ival<0)||(rtrn.ival>255)) {
1044f46a6179Smrg		    ERROR("All data for a private action must be 0..255\n");
1045f46a6179Smrg		    ACTION1("Illegal datum %d ignored\n",rtrn.ival);
1046f46a6179Smrg		    return False;
1047f46a6179Smrg		}
1048f46a6179Smrg		action->data[ndx]= rtrn.uval;
1049f46a6179Smrg		return True;
1050f46a6179Smrg	    }
1051f46a6179Smrg    }
1052f46a6179Smrg    return ReportIllegal(PrivateAction,field);
1053f46a6179Smrg}
1054f46a6179Smrg
1055f46a6179Smrgtypedef	Bool	(*actionHandler)(
1056f46a6179Smrg	XkbDescPtr 	/* xkb */,
1057f46a6179Smrg	XkbAnyAction *	/* action */,
1058f46a6179Smrg	unsigned	/* field */,
1059f46a6179Smrg	ExprDef *	/* array_ndx */,
1060f46a6179Smrg	ExprDef *	/* value */
1061f46a6179Smrg);
1062f46a6179Smrg
1063f46a6179Smrgstatic actionHandler	handleAction[XkbSA_NumActions+1] = {
1064f46a6179Smrg	HandleNoAction			/* NoAction	*/,
1065f46a6179Smrg	HandleSetLatchMods		/* SetMods	*/,
1066f46a6179Smrg	HandleSetLatchMods		/* LatchMods	*/,
1067f46a6179Smrg	HandleLockMods			/* LockMods	*/,
1068f46a6179Smrg	HandleSetLatchGroup		/* SetGroup	*/,
1069f46a6179Smrg	HandleSetLatchGroup		/* LatchGroup	*/,
1070f46a6179Smrg	HandleLockGroup			/* LockGroup	*/,
1071f46a6179Smrg	HandleMovePtr			/* MovePtr	*/,
1072f46a6179Smrg	HandlePtrBtn			/* PtrBtn	*/,
1073f46a6179Smrg	HandlePtrBtn			/* LockPtrBtn	*/,
1074f46a6179Smrg	HandleSetPtrDflt		/* SetPtrDflt	*/,
1075f46a6179Smrg	HandleISOLock			/* ISOLock	*/,
1076f46a6179Smrg	HandleNoAction			/* Terminate	*/,
1077f46a6179Smrg	HandleSwitchScreen		/* SwitchScreen	*/,
1078f46a6179Smrg	HandleSetLockControls		/* SetControls	*/,
1079f46a6179Smrg	HandleSetLockControls		/* LockControls	*/,
1080f46a6179Smrg	HandleActionMessage		/* ActionMessage*/,
1081f46a6179Smrg	HandleRedirectKey		/* RedirectKey	*/,
1082f46a6179Smrg	HandleDeviceBtn			/* DeviceBtn	*/,
1083f46a6179Smrg	HandleDeviceBtn			/* LockDeviceBtn*/,
1084f46a6179Smrg	HandleDeviceValuator		/* DeviceValuatr*/,
1085f46a6179Smrg	HandlePrivate			/* Private	*/
1086f46a6179Smrg};
1087f46a6179Smrg
1088f46a6179Smrg/***====================================================================***/
1089f46a6179Smrg
1090f46a6179Smrgstatic void
1091f46a6179SmrgApplyActionFactoryDefaults(XkbAction *action)
1092f46a6179Smrg{
1093f46a6179Smrg    if (action->type==XkbSA_SetPtrDflt) { /* increment default button */
1094f46a6179Smrg	action->dflt.affect= XkbSA_AffectDfltBtn;
1095f46a6179Smrg	action->dflt.flags= 0;
1096f46a6179Smrg	XkbSASetPtrDfltValue(&action->dflt,1);
1097f46a6179Smrg    }
1098f46a6179Smrg    else if (action->type==XkbSA_ISOLock) {
1099f46a6179Smrg	action->iso.real_mods=  LockMask;
1100f46a6179Smrg    }
1101f46a6179Smrg    return;
1102f46a6179Smrg}
1103f46a6179Smrg
1104f46a6179Smrg
1105f46a6179Smrgint
1106f46a6179SmrgHandleActionDef(	ExprDef *	def,
1107f46a6179Smrg			XkbDescPtr	xkb,
1108f46a6179Smrg			XkbAnyAction *	action,
1109f46a6179Smrg			unsigned	mergeMode,
1110f46a6179Smrg			ActionInfo *	info)
1111f46a6179Smrg{
1112f46a6179SmrgExprDef *		arg;
1113f46a6179Smrgregister char *		str;
1114f46a6179Smrgunsigned 		tmp,hndlrType;
1115f46a6179Smrg
1116f46a6179Smrg    if (!actionsInitialized)
1117f46a6179Smrg	ActionsInit();
1118f46a6179Smrg
1119f46a6179Smrg    if (def->op!=ExprActionDecl) {
1120f46a6179Smrg	ERROR1("Expected an action definition, found %s\n",exprOpText(def->op));
1121f46a6179Smrg	return False;
1122f46a6179Smrg    }
1123f46a6179Smrg    str= XkbAtomGetString(NULL,def->value.action.name);
1124f46a6179Smrg    if (!str) {
1125f46a6179Smrg	WSGO("Missing name in action definition!!\n");
1126f46a6179Smrg	return False;
1127f46a6179Smrg    }
1128f46a6179Smrg    if (!stringToAction(str,&tmp)) {
1129f46a6179Smrg	ERROR1("Unknown action %s\n",str);
1130f46a6179Smrg	return False;
1131f46a6179Smrg    }
1132f46a6179Smrg    action->type= hndlrType= tmp;
1133f46a6179Smrg    if (action->type!=XkbSA_NoAction) {
1134f46a6179Smrg	ApplyActionFactoryDefaults((XkbAction *)action);
1135f46a6179Smrg	while (info) {
1136f46a6179Smrg	    if ((info->action==XkbSA_NoAction)||(info->action==hndlrType)) {
1137f46a6179Smrg		if (!(*handleAction[hndlrType])(xkb,action,
1138f46a6179Smrg						info->field,info->array_ndx,
1139f46a6179Smrg						info->value)) {
1140f46a6179Smrg		    return False;
1141f46a6179Smrg		}
1142f46a6179Smrg	    }
1143f46a6179Smrg	    info= info->next;
1144f46a6179Smrg	}
1145f46a6179Smrg    }
1146f46a6179Smrg    for (arg=def->value.action.args;arg!=NULL;arg=(ExprDef*)arg->common.next) {
1147f46a6179Smrg	ExprDef *field,*value,*arrayRtrn;
1148f46a6179Smrg	ExprResult elemRtrn,fieldRtrn;
1149f46a6179Smrg	unsigned fieldNdx;
1150f46a6179Smrg
1151f46a6179Smrg	if (arg->op==OpAssign) {
1152f46a6179Smrg	    field= arg->value.binary.left;
1153f46a6179Smrg	    value= arg->value.binary.right;
1154f46a6179Smrg	}
1155f46a6179Smrg	else {
1156f46a6179Smrg	    if ((arg->op==OpNot)||(arg->op==OpInvert)) {
1157f46a6179Smrg		field= arg->value.child;
1158f46a6179Smrg		value= &constFalse;
1159f46a6179Smrg	    }
1160f46a6179Smrg	    else {
1161f46a6179Smrg		field= arg;
1162f46a6179Smrg		value= &constTrue;
1163f46a6179Smrg	    }
1164f46a6179Smrg	}
1165f46a6179Smrg	if (!ExprResolveLhs(field,&elemRtrn,&fieldRtrn,&arrayRtrn))
1166f46a6179Smrg	    return False;	/* internal error -- already reported */
1167f46a6179Smrg
1168f46a6179Smrg	if (elemRtrn.str!=NULL) {
1169f46a6179Smrg	    ERROR("Cannot change defaults in an action definition\n");
1170f46a6179Smrg	    ACTION2("Ignoring attempt to change %s.%s\n",elemRtrn.str,
1171f46a6179Smrg							 fieldRtrn.str);
1172f46a6179Smrg	    return False;
1173f46a6179Smrg	}
1174f46a6179Smrg	if (!stringToField(fieldRtrn.str,&fieldNdx)) {
1175f46a6179Smrg	    ERROR1("Unknown field name %s\n",uStringText(fieldRtrn.str));
1176f46a6179Smrg	    return False;
1177f46a6179Smrg	}
1178f46a6179Smrg	if (!(*handleAction[hndlrType])(xkb,action,fieldNdx,arrayRtrn,value)) {
1179f46a6179Smrg	    return False;
1180f46a6179Smrg	}
1181f46a6179Smrg    }
1182f46a6179Smrg    return True;
1183f46a6179Smrg}
1184f46a6179Smrg
1185f46a6179Smrg/***====================================================================***/
1186f46a6179Smrg
1187f46a6179Smrgint
1188f46a6179SmrgSetActionField(	XkbDescPtr	xkb,
1189f46a6179Smrg		char *		elem,
1190f46a6179Smrg		char *		field,
1191f46a6179Smrg		ExprDef *	array_ndx,
1192f46a6179Smrg		ExprDef *	value,
1193f46a6179Smrg		ActionInfo **	info_rtrn)
1194f46a6179Smrg{
1195f46a6179SmrgActionInfo *new,*old;
1196f46a6179Smrg
1197f46a6179Smrg    if (!actionsInitialized)
1198f46a6179Smrg	ActionsInit();
1199f46a6179Smrg
1200f46a6179Smrg    new= uTypedAlloc(ActionInfo);
1201f46a6179Smrg    if (new==NULL) {
1202f46a6179Smrg	WSGO("Couldn't allocate space for action default\n");
1203f46a6179Smrg	return False;
1204f46a6179Smrg    }
1205f46a6179Smrg    if (uStrCaseCmp(elem,"action")==0)
1206f46a6179Smrg	new->action= XkbSA_NoAction;
1207f46a6179Smrg    else {
1208f46a6179Smrg	if (!stringToAction(elem,&new->action))
1209f46a6179Smrg	    return False;
1210f46a6179Smrg	if (new->action==XkbSA_NoAction) {
1211f46a6179Smrg	    ERROR1("\"%s\" is not a valid field in a NoAction action\n",field);
1212f46a6179Smrg	    return False;
1213f46a6179Smrg	}
1214f46a6179Smrg    }
1215f46a6179Smrg    if (!stringToField(field,&new->field)) {
1216f46a6179Smrg	ERROR1("\"%s\" is not a legal field name\n",field);
1217f46a6179Smrg	return False;
1218f46a6179Smrg    }
1219f46a6179Smrg    new->array_ndx= array_ndx;
1220f46a6179Smrg    new->value= value;
1221f46a6179Smrg    new->next= NULL;
1222f46a6179Smrg    old= *info_rtrn;
1223f46a6179Smrg    while ((old)&&(old->next))
1224f46a6179Smrg	old= old->next;
1225f46a6179Smrg    if (old==NULL)	*info_rtrn= new;
1226f46a6179Smrg    else		old->next= new;
1227f46a6179Smrg    return True;
1228f46a6179Smrg}
1229f46a6179Smrg
1230f46a6179Smrg/***====================================================================***/
1231f46a6179Smrg
1232f46a6179Smrgvoid
1233f46a6179SmrgActionsInit(void)
1234f46a6179Smrg{
1235f46a6179Smrg    if (!actionsInitialized) {
1236f46a6179Smrg	bzero((char *)&constTrue,sizeof(constTrue));
1237f46a6179Smrg	bzero((char *)&constFalse,sizeof(constFalse));
1238f46a6179Smrg	constTrue.common.stmtType= StmtExpr;
1239f46a6179Smrg	constTrue.common.next= NULL;
1240f46a6179Smrg	constTrue.op= ExprIdent;
1241f46a6179Smrg	constTrue.type= TypeBoolean;
1242f46a6179Smrg	constTrue.value.str= XkbInternAtom(NULL,"true",False);
1243f46a6179Smrg	constFalse.common.stmtType= StmtExpr;
1244f46a6179Smrg	constFalse.common.next= NULL;
1245f46a6179Smrg	constFalse.op= ExprIdent;
1246f46a6179Smrg	constFalse.type= TypeBoolean;
1247f46a6179Smrg	constFalse.value.str= XkbInternAtom(NULL,"false",False);
1248f46a6179Smrg	actionsInitialized= 1;
1249f46a6179Smrg    }
1250f46a6179Smrg    return;
1251f46a6179Smrg}
1252f46a6179Smrg
1253