1f46a6179Smrg/************************************************************ 2f46a6179Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 3f46a6179Smrg 4f46a6179Smrg Permission to use, copy, modify, and distribute this 5f46a6179Smrg software and its documentation for any purpose and without 6f46a6179Smrg fee is hereby granted, provided that the above copyright 7f46a6179Smrg notice appear in all copies and that both that copyright 8f46a6179Smrg notice and this permission notice appear in supporting 9bfe6082cSmrg documentation, and that the name of Silicon Graphics not be 10bfe6082cSmrg used in advertising or publicity pertaining to distribution 11f46a6179Smrg of the software without specific prior written permission. 12bfe6082cSmrg Silicon Graphics makes no representation about the suitability 13f46a6179Smrg of this software for any purpose. It is provided "as is" 14f46a6179Smrg without any express or implied warranty. 15bfe6082cSmrg 16bfe6082cSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17bfe6082cSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19bfe6082cSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20bfe6082cSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21bfe6082cSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22f46a6179Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23f46a6179Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 24f46a6179Smrg 25f46a6179Smrg ********************************************************/ 26f46a6179Smrg 27f46a6179Smrg#include "xkbcomp.h" 28f46a6179Smrg#include "tokens.h" 29f46a6179Smrg#include "expr.h" 30f46a6179Smrg 31f46a6179Smrg#include "keycodes.h" 32f46a6179Smrg#include "vmod.h" 33f46a6179Smrg#include "misc.h" 34f46a6179Smrg#include "action.h" 35f46a6179Smrg#include "misc.h" 36f46a6179Smrg 3734345a63Smrgstatic Bool actionsInitialized; 3834345a63Smrgstatic ExprDef constTrue; 3934345a63Smrgstatic ExprDef constFalse; 40f46a6179Smrg 416930ead5Smrgstatic void ActionsInit(void); 426930ead5Smrg 43f46a6179Smrg/***====================================================================***/ 44f46a6179Smrg 45f46a6179Smrgstatic Bool 46c82dfdfbSmrgstringToAction(const char *str, unsigned *type_rtrn) 47f46a6179Smrg{ 4834345a63Smrg if (str == NULL) 4934345a63Smrg return False; 5034345a63Smrg 5134345a63Smrg if (uStrCaseCmp(str, "noaction") == 0) 5234345a63Smrg *type_rtrn = XkbSA_NoAction; 5334345a63Smrg else if (uStrCaseCmp(str, "setmods") == 0) 5434345a63Smrg *type_rtrn = XkbSA_SetMods; 5534345a63Smrg else if (uStrCaseCmp(str, "latchmods") == 0) 5634345a63Smrg *type_rtrn = XkbSA_LatchMods; 5734345a63Smrg else if (uStrCaseCmp(str, "lockmods") == 0) 5834345a63Smrg *type_rtrn = XkbSA_LockMods; 5934345a63Smrg else if (uStrCaseCmp(str, "setgroup") == 0) 6034345a63Smrg *type_rtrn = XkbSA_SetGroup; 6134345a63Smrg else if (uStrCaseCmp(str, "latchgroup") == 0) 6234345a63Smrg *type_rtrn = XkbSA_LatchGroup; 6334345a63Smrg else if (uStrCaseCmp(str, "lockgroup") == 0) 6434345a63Smrg *type_rtrn = XkbSA_LockGroup; 6534345a63Smrg else if (uStrCaseCmp(str, "moveptr") == 0) 6634345a63Smrg *type_rtrn = XkbSA_MovePtr; 6734345a63Smrg else if (uStrCaseCmp(str, "movepointer") == 0) 6834345a63Smrg *type_rtrn = XkbSA_MovePtr; 6934345a63Smrg else if (uStrCaseCmp(str, "ptrbtn") == 0) 7034345a63Smrg *type_rtrn = XkbSA_PtrBtn; 7134345a63Smrg else if (uStrCaseCmp(str, "pointerbutton") == 0) 7234345a63Smrg *type_rtrn = XkbSA_PtrBtn; 7334345a63Smrg else if (uStrCaseCmp(str, "lockptrbtn") == 0) 7434345a63Smrg *type_rtrn = XkbSA_LockPtrBtn; 7534345a63Smrg else if (uStrCaseCmp(str, "lockpointerbutton") == 0) 7634345a63Smrg *type_rtrn = XkbSA_LockPtrBtn; 7734345a63Smrg else if (uStrCaseCmp(str, "lockptrbutton") == 0) 7834345a63Smrg *type_rtrn = XkbSA_LockPtrBtn; 7934345a63Smrg else if (uStrCaseCmp(str, "lockpointerbtn") == 0) 8034345a63Smrg *type_rtrn = XkbSA_LockPtrBtn; 8134345a63Smrg else if (uStrCaseCmp(str, "setptrdflt") == 0) 8234345a63Smrg *type_rtrn = XkbSA_SetPtrDflt; 8334345a63Smrg else if (uStrCaseCmp(str, "setpointerdefault") == 0) 8434345a63Smrg *type_rtrn = XkbSA_SetPtrDflt; 8534345a63Smrg else if (uStrCaseCmp(str, "isolock") == 0) 8634345a63Smrg *type_rtrn = XkbSA_ISOLock; 8734345a63Smrg else if (uStrCaseCmp(str, "terminate") == 0) 8834345a63Smrg *type_rtrn = XkbSA_Terminate; 8934345a63Smrg else if (uStrCaseCmp(str, "terminateserver") == 0) 9034345a63Smrg *type_rtrn = XkbSA_Terminate; 9134345a63Smrg else if (uStrCaseCmp(str, "switchscreen") == 0) 9234345a63Smrg *type_rtrn = XkbSA_SwitchScreen; 9334345a63Smrg else if (uStrCaseCmp(str, "setcontrols") == 0) 9434345a63Smrg *type_rtrn = XkbSA_SetControls; 9534345a63Smrg else if (uStrCaseCmp(str, "lockcontrols") == 0) 9634345a63Smrg *type_rtrn = XkbSA_LockControls; 9734345a63Smrg else if (uStrCaseCmp(str, "actionmessage") == 0) 9834345a63Smrg *type_rtrn = XkbSA_ActionMessage; 9934345a63Smrg else if (uStrCaseCmp(str, "messageaction") == 0) 10034345a63Smrg *type_rtrn = XkbSA_ActionMessage; 10134345a63Smrg else if (uStrCaseCmp(str, "message") == 0) 10234345a63Smrg *type_rtrn = XkbSA_ActionMessage; 10334345a63Smrg else if (uStrCaseCmp(str, "redirect") == 0) 10434345a63Smrg *type_rtrn = XkbSA_RedirectKey; 10534345a63Smrg else if (uStrCaseCmp(str, "redirectkey") == 0) 10634345a63Smrg *type_rtrn = XkbSA_RedirectKey; 10734345a63Smrg else if (uStrCaseCmp(str, "devbtn") == 0) 10834345a63Smrg *type_rtrn = XkbSA_DeviceBtn; 10934345a63Smrg else if (uStrCaseCmp(str, "devicebtn") == 0) 11034345a63Smrg *type_rtrn = XkbSA_DeviceBtn; 11134345a63Smrg else if (uStrCaseCmp(str, "devbutton") == 0) 11234345a63Smrg *type_rtrn = XkbSA_DeviceBtn; 11334345a63Smrg else if (uStrCaseCmp(str, "devicebutton") == 0) 11434345a63Smrg *type_rtrn = XkbSA_DeviceBtn; 11534345a63Smrg else if (uStrCaseCmp(str, "lockdevbtn") == 0) 116bfe6082cSmrg *type_rtrn = XkbSA_LockDeviceBtn; 11734345a63Smrg else if (uStrCaseCmp(str, "lockdevicebtn") == 0) 11834345a63Smrg *type_rtrn = XkbSA_LockDeviceBtn; 11934345a63Smrg else if (uStrCaseCmp(str, "lockdevbutton") == 0) 12034345a63Smrg *type_rtrn = XkbSA_LockDeviceBtn; 12134345a63Smrg else if (uStrCaseCmp(str, "lockdevicebutton") == 0) 12234345a63Smrg *type_rtrn = XkbSA_LockDeviceBtn; 12334345a63Smrg else if (uStrCaseCmp(str, "devval") == 0) 12434345a63Smrg *type_rtrn = XkbSA_DeviceValuator; 12534345a63Smrg else if (uStrCaseCmp(str, "deviceval") == 0) 12634345a63Smrg *type_rtrn = XkbSA_DeviceValuator; 12734345a63Smrg else if (uStrCaseCmp(str, "devvaluator") == 0) 12834345a63Smrg *type_rtrn = XkbSA_DeviceValuator; 12934345a63Smrg else if (uStrCaseCmp(str, "devicevaluator") == 0) 13034345a63Smrg *type_rtrn = XkbSA_DeviceValuator; 13134345a63Smrg else if (uStrCaseCmp(str, "private") == 0) 13234345a63Smrg *type_rtrn = PrivateAction; 13334345a63Smrg else 13434345a63Smrg return False; 135f46a6179Smrg return True; 136f46a6179Smrg} 137f46a6179Smrg 138f46a6179Smrgstatic Bool 139c82dfdfbSmrgstringToField(const char *str, unsigned *field_rtrn) 140f46a6179Smrg{ 141f46a6179Smrg 14234345a63Smrg if (str == NULL) 14334345a63Smrg return False; 14434345a63Smrg 14534345a63Smrg if (uStrCaseCmp(str, "clearlocks") == 0) 14634345a63Smrg *field_rtrn = F_ClearLocks; 14734345a63Smrg else if (uStrCaseCmp(str, "latchtolock") == 0) 14834345a63Smrg *field_rtrn = F_LatchToLock; 14934345a63Smrg else if (uStrCaseCmp(str, "genkeyevent") == 0) 15034345a63Smrg *field_rtrn = F_GenKeyEvent; 15134345a63Smrg else if (uStrCaseCmp(str, "generatekeyevent") == 0) 15234345a63Smrg *field_rtrn = F_GenKeyEvent; 15334345a63Smrg else if (uStrCaseCmp(str, "report") == 0) 15434345a63Smrg *field_rtrn = F_Report; 15534345a63Smrg else if (uStrCaseCmp(str, "default") == 0) 15634345a63Smrg *field_rtrn = F_Default; 15734345a63Smrg else if (uStrCaseCmp(str, "affect") == 0) 15834345a63Smrg *field_rtrn = F_Affect; 15934345a63Smrg else if (uStrCaseCmp(str, "increment") == 0) 16034345a63Smrg *field_rtrn = F_Increment; 16134345a63Smrg else if (uStrCaseCmp(str, "mods") == 0) 16234345a63Smrg *field_rtrn = F_Modifiers; 16334345a63Smrg else if (uStrCaseCmp(str, "modifiers") == 0) 16434345a63Smrg *field_rtrn = F_Modifiers; 16534345a63Smrg else if (uStrCaseCmp(str, "group") == 0) 16634345a63Smrg *field_rtrn = F_Group; 16734345a63Smrg else if (uStrCaseCmp(str, "x") == 0) 16834345a63Smrg *field_rtrn = F_X; 16934345a63Smrg else if (uStrCaseCmp(str, "y") == 0) 17034345a63Smrg *field_rtrn = F_Y; 17134345a63Smrg else if (uStrCaseCmp(str, "accel") == 0) 17234345a63Smrg *field_rtrn = F_Accel; 17334345a63Smrg else if (uStrCaseCmp(str, "accelerate") == 0) 17434345a63Smrg *field_rtrn = F_Accel; 17534345a63Smrg else if (uStrCaseCmp(str, "repeat") == 0) 17634345a63Smrg *field_rtrn = F_Accel; 17734345a63Smrg else if (uStrCaseCmp(str, "button") == 0) 17834345a63Smrg *field_rtrn = F_Button; 17934345a63Smrg else if (uStrCaseCmp(str, "value") == 0) 18034345a63Smrg *field_rtrn = F_Value; 18134345a63Smrg else if (uStrCaseCmp(str, "controls") == 0) 18234345a63Smrg *field_rtrn = F_Controls; 18334345a63Smrg else if (uStrCaseCmp(str, "ctrls") == 0) 18434345a63Smrg *field_rtrn = F_Controls; 18534345a63Smrg else if (uStrCaseCmp(str, "type") == 0) 18634345a63Smrg *field_rtrn = F_Type; 18734345a63Smrg else if (uStrCaseCmp(str, "count") == 0) 18834345a63Smrg *field_rtrn = F_Count; 18934345a63Smrg else if (uStrCaseCmp(str, "screen") == 0) 19034345a63Smrg *field_rtrn = F_Screen; 19134345a63Smrg else if (uStrCaseCmp(str, "same") == 0) 19234345a63Smrg *field_rtrn = F_Same; 19334345a63Smrg else if (uStrCaseCmp(str, "sameserver") == 0) 19434345a63Smrg *field_rtrn = F_Same; 19534345a63Smrg else if (uStrCaseCmp(str, "data") == 0) 19634345a63Smrg *field_rtrn = F_Data; 19734345a63Smrg else if (uStrCaseCmp(str, "device") == 0) 19834345a63Smrg *field_rtrn = F_Device; 19934345a63Smrg else if (uStrCaseCmp(str, "dev") == 0) 20034345a63Smrg *field_rtrn = F_Device; 20134345a63Smrg else if (uStrCaseCmp(str, "key") == 0) 20234345a63Smrg *field_rtrn = F_Keycode; 20334345a63Smrg else if (uStrCaseCmp(str, "keycode") == 0) 20434345a63Smrg *field_rtrn = F_Keycode; 20534345a63Smrg else if (uStrCaseCmp(str, "kc") == 0) 20634345a63Smrg *field_rtrn = F_Keycode; 20734345a63Smrg else if (uStrCaseCmp(str, "clearmods") == 0) 20834345a63Smrg *field_rtrn = F_ModsToClear; 20934345a63Smrg else if (uStrCaseCmp(str, "clearmodifiers") == 0) 21034345a63Smrg *field_rtrn = F_ModsToClear; 21134345a63Smrg else 21234345a63Smrg return False; 213f46a6179Smrg return True; 214f46a6179Smrg} 215f46a6179Smrg 216f46a6179Smrgstatic char * 217f46a6179SmrgfieldText(unsigned field) 218f46a6179Smrg{ 21934345a63Smrg static char buf[32]; 22034345a63Smrg 22134345a63Smrg switch (field) 22234345a63Smrg { 22334345a63Smrg case F_ClearLocks: 22434345a63Smrg strcpy(buf, "clearLocks"); 22534345a63Smrg break; 22634345a63Smrg case F_LatchToLock: 22734345a63Smrg strcpy(buf, "latchToLock"); 22834345a63Smrg break; 22934345a63Smrg case F_GenKeyEvent: 23034345a63Smrg strcpy(buf, "genKeyEvent"); 23134345a63Smrg break; 23234345a63Smrg case F_Report: 23334345a63Smrg strcpy(buf, "report"); 23434345a63Smrg break; 23534345a63Smrg case F_Default: 23634345a63Smrg strcpy(buf, "default"); 23734345a63Smrg break; 23834345a63Smrg case F_Affect: 23934345a63Smrg strcpy(buf, "affect"); 24034345a63Smrg break; 24134345a63Smrg case F_Increment: 24234345a63Smrg strcpy(buf, "increment"); 24334345a63Smrg break; 24434345a63Smrg case F_Modifiers: 24534345a63Smrg strcpy(buf, "modifiers"); 24634345a63Smrg break; 24734345a63Smrg case F_Group: 24834345a63Smrg strcpy(buf, "group"); 24934345a63Smrg break; 25034345a63Smrg case F_X: 25134345a63Smrg strcpy(buf, "x"); 25234345a63Smrg break; 25334345a63Smrg case F_Y: 25434345a63Smrg strcpy(buf, "y"); 25534345a63Smrg break; 25634345a63Smrg case F_Accel: 25734345a63Smrg strcpy(buf, "accel"); 25834345a63Smrg break; 25934345a63Smrg case F_Button: 26034345a63Smrg strcpy(buf, "button"); 26134345a63Smrg break; 26234345a63Smrg case F_Value: 26334345a63Smrg strcpy(buf, "value"); 26434345a63Smrg break; 26534345a63Smrg case F_Controls: 26634345a63Smrg strcpy(buf, "controls"); 26734345a63Smrg break; 26834345a63Smrg case F_Type: 26934345a63Smrg strcpy(buf, "type"); 27034345a63Smrg break; 27134345a63Smrg case F_Count: 27234345a63Smrg strcpy(buf, "count"); 27334345a63Smrg break; 27434345a63Smrg case F_Screen: 27534345a63Smrg strcpy(buf, "screen"); 27634345a63Smrg break; 27734345a63Smrg case F_Same: 27834345a63Smrg strcpy(buf, "sameServer"); 27934345a63Smrg break; 28034345a63Smrg case F_Data: 28134345a63Smrg strcpy(buf, "data"); 28234345a63Smrg break; 28334345a63Smrg case F_Device: 28434345a63Smrg strcpy(buf, "device"); 28534345a63Smrg break; 28634345a63Smrg case F_Keycode: 28734345a63Smrg strcpy(buf, "keycode"); 28834345a63Smrg break; 28934345a63Smrg case F_ModsToClear: 29034345a63Smrg strcpy(buf, "clearmods"); 29134345a63Smrg break; 29234345a63Smrg default: 29334345a63Smrg strcpy(buf, "unknown"); 29434345a63Smrg break; 295f46a6179Smrg } 296f46a6179Smrg return buf; 297f46a6179Smrg} 298f46a6179Smrg 299f46a6179Smrg/***====================================================================***/ 300f46a6179Smrg 301f46a6179Smrgstatic Bool 302f46a6179SmrgReportMismatch(unsigned action, unsigned field, const char *type) 303f46a6179Smrg{ 304bfe6082cSmrg ERROR("Value of %s field must be of type %s\n", fieldText(field), type); 305bfe6082cSmrg ACTION("Action %s definition ignored\n", 30634345a63Smrg XkbActionTypeText(action, XkbMessage)); 307f46a6179Smrg return False; 308f46a6179Smrg} 309f46a6179Smrg 310f46a6179Smrgstatic Bool 31134345a63SmrgReportIllegal(unsigned action, unsigned field) 312f46a6179Smrg{ 313bfe6082cSmrg ERROR("Field %s is not defined for an action of type %s\n", 31434345a63Smrg fieldText(field), XkbActionTypeText(action, XkbMessage)); 315f46a6179Smrg ACTION("Action definition ignored\n"); 316f46a6179Smrg return False; 317f46a6179Smrg} 318f46a6179Smrg 319f46a6179Smrgstatic Bool 32034345a63SmrgReportActionNotArray(unsigned action, unsigned field) 321f46a6179Smrg{ 322bfe6082cSmrg ERROR("The %s field in the %s action is not an array\n", 32334345a63Smrg fieldText(field), XkbActionTypeText(action, XkbMessage)); 324f46a6179Smrg ACTION("Action definition ignored\n"); 325f46a6179Smrg return False; 326f46a6179Smrg} 327f46a6179Smrg 328f46a6179Smrgstatic Bool 329f46a6179SmrgReportNotFound(unsigned action, unsigned field, const char *what, char *bad) 330f46a6179Smrg{ 331bfe6082cSmrg ERROR("%s named %s not found\n", what, bad); 332bfe6082cSmrg ACTION("Ignoring the %s field of an %s action\n", fieldText(field), 33334345a63Smrg XkbActionTypeText(action, XkbMessage)); 334f46a6179Smrg return False; 335f46a6179Smrg} 336f46a6179Smrg 337f46a6179Smrgstatic Bool 3386930ead5SmrgHandleNoAction(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 3396930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 340f46a6179Smrg{ 34134345a63Smrg return ReportIllegal(action->type, field); 342f46a6179Smrg} 343f46a6179Smrg 344f46a6179Smrgstatic Bool 3456930ead5SmrgCheckLatchLockFlags(unsigned action, unsigned field, 3466930ead5Smrg const ExprDef *value, unsigned *flags_inout) 347f46a6179Smrg{ 34834345a63Smrg unsigned tmp; 34934345a63Smrg ExprResult result; 35034345a63Smrg 35134345a63Smrg if (field == F_ClearLocks) 35234345a63Smrg tmp = XkbSA_ClearLocks; 35334345a63Smrg else if (field == F_LatchToLock) 35434345a63Smrg tmp = XkbSA_LatchToLock; 35534345a63Smrg else 35634345a63Smrg return False; /* WSGO! */ 35734345a63Smrg if (!ExprResolveBoolean(value, &result, NULL, NULL)) 35834345a63Smrg return ReportMismatch(action, field, "boolean"); 35934345a63Smrg if (result.uval) 36034345a63Smrg *flags_inout |= tmp; 36134345a63Smrg else 36234345a63Smrg *flags_inout &= ~tmp; 363f46a6179Smrg return True; 364f46a6179Smrg} 365f46a6179Smrg 366f46a6179Smrgstatic Bool 3676930ead5SmrgCheckModifierField(XkbDescPtr xkb, unsigned action, const ExprDef *value, 36834345a63Smrg unsigned *flags_inout, unsigned *mods_rtrn) 369f46a6179Smrg{ 37034345a63Smrg ExprResult rtrn; 37134345a63Smrg 37234345a63Smrg if (value->op == ExprIdent) 37334345a63Smrg { 3746930ead5Smrg char *valStr; 37534345a63Smrg valStr = XkbAtomGetString(NULL, value->value.str); 37634345a63Smrg if (valStr && ((uStrCaseCmp(valStr, "usemodmapmods") == 0) || 37734345a63Smrg (uStrCaseCmp(valStr, "modmapmods") == 0))) 37834345a63Smrg { 37934345a63Smrg 38034345a63Smrg *mods_rtrn = 0; 38134345a63Smrg *flags_inout |= XkbSA_UseModMapMods; 38234345a63Smrg return True; 38334345a63Smrg } 384f46a6179Smrg } 38534345a63Smrg if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb)) 38634345a63Smrg return ReportMismatch(action, F_Modifiers, "modifier mask"); 38734345a63Smrg *mods_rtrn = rtrn.uval; 38834345a63Smrg *flags_inout &= ~XkbSA_UseModMapMods; 389f46a6179Smrg return True; 390f46a6179Smrg} 391f46a6179Smrg 392f46a6179Smrgstatic Bool 3936930ead5SmrgHandleSetLatchMods(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 3946930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 395f46a6179Smrg{ 39634345a63Smrg XkbModAction *act; 39734345a63Smrg 39834345a63Smrg act = (XkbModAction *) action; 39934345a63Smrg if (array_ndx != NULL) 40034345a63Smrg { 40134345a63Smrg switch (field) 40234345a63Smrg { 40334345a63Smrg case F_ClearLocks: 40434345a63Smrg case F_LatchToLock: 40534345a63Smrg case F_Modifiers: 40634345a63Smrg return ReportActionNotArray(action->type, field); 40734345a63Smrg } 408f46a6179Smrg } 40934345a63Smrg switch (field) 41034345a63Smrg { 41134345a63Smrg case F_ClearLocks: 41234345a63Smrg case F_LatchToLock: 4136930ead5Smrg { 4146930ead5Smrg unsigned rtrn = act->flags; 41534345a63Smrg if (CheckLatchLockFlags(action->type, field, value, &rtrn)) 41634345a63Smrg { 41734345a63Smrg act->flags = rtrn; 41834345a63Smrg return True; 41934345a63Smrg } 42034345a63Smrg return False; 4216930ead5Smrg } 42234345a63Smrg case F_Modifiers: 4236930ead5Smrg { 4246930ead5Smrg unsigned t1 = act->flags, t2; 42534345a63Smrg if (CheckModifierField(xkb, action->type, value, &t1, &t2)) 42634345a63Smrg { 42734345a63Smrg act->flags = t1; 42834345a63Smrg act->real_mods = act->mask = (t2 & 0xff); 42934345a63Smrg t2 = (t2 >> 8) & 0xffff; 43034345a63Smrg XkbSetModActionVMods(act, t2); 43134345a63Smrg return True; 43234345a63Smrg } 43334345a63Smrg return False; 434f46a6179Smrg } 4356930ead5Smrg } 43634345a63Smrg return ReportIllegal(action->type, field); 437f46a6179Smrg} 438f46a6179Smrg 439bfe6082cSmrgstatic LookupEntry lockWhich[] = { 440bfe6082cSmrg {"both", 0}, 441bfe6082cSmrg {"lock", XkbSA_LockNoUnlock}, 442bfe6082cSmrg {"neither", (XkbSA_LockNoLock | XkbSA_LockNoUnlock)}, 443bfe6082cSmrg {"unlock", XkbSA_LockNoLock}, 444bfe6082cSmrg {NULL, 0} 445bfe6082cSmrg}; 446bfe6082cSmrg 447f46a6179Smrgstatic Bool 4486930ead5SmrgHandleLockMods(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 4496930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 450f46a6179Smrg{ 45134345a63Smrg XkbModAction *act; 45234345a63Smrg 45334345a63Smrg act = (XkbModAction *) action; 454bfe6082cSmrg if ((array_ndx != NULL) && (field == F_Modifiers || field == F_Affect)) 45534345a63Smrg return ReportActionNotArray(action->type, field); 45634345a63Smrg switch (field) 45734345a63Smrg { 458bfe6082cSmrg case F_Affect: 4596930ead5Smrg { 4606930ead5Smrg ExprResult rtrn; 461bfe6082cSmrg if (!ExprResolveEnum(value, &rtrn, lockWhich)) 462bfe6082cSmrg return ReportMismatch(action->type, field, "lock or unlock"); 463bfe6082cSmrg act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock); 464bfe6082cSmrg act->flags |= rtrn.uval; 465bfe6082cSmrg return True; 4666930ead5Smrg } 46734345a63Smrg case F_Modifiers: 4686930ead5Smrg { 4696930ead5Smrg unsigned t1 = act->flags, t2; 47034345a63Smrg if (CheckModifierField(xkb, action->type, value, &t1, &t2)) 47134345a63Smrg { 47234345a63Smrg act->flags = t1; 47334345a63Smrg act->real_mods = act->mask = (t2 & 0xff); 47434345a63Smrg t2 = (t2 >> 8) & 0xffff; 47534345a63Smrg XkbSetModActionVMods(act, t2); 47634345a63Smrg return True; 47734345a63Smrg } 47834345a63Smrg return False; 479f46a6179Smrg } 4806930ead5Smrg } 48134345a63Smrg return ReportIllegal(action->type, field); 482f46a6179Smrg} 483f46a6179Smrg 484f46a6179Smrgstatic LookupEntry groupNames[] = { 48534345a63Smrg {"group1", 1}, 48634345a63Smrg {"group2", 2}, 48734345a63Smrg {"group3", 3}, 48834345a63Smrg {"group4", 4}, 48934345a63Smrg {"group5", 5}, 49034345a63Smrg {"group6", 6}, 49134345a63Smrg {"group7", 7}, 49234345a63Smrg {"group8", 8}, 49334345a63Smrg {NULL, 0}, 494f46a6179Smrg}; 495f46a6179Smrg 496f46a6179Smrgstatic Bool 4976930ead5SmrgCheckGroupField(unsigned action, const ExprDef *value, 4986930ead5Smrg unsigned *flags_inout, int *grp_rtrn) 499f46a6179Smrg{ 5006930ead5Smrg const ExprDef *spec; 50134345a63Smrg ExprResult rtrn; 502f46a6179Smrg 50334345a63Smrg if ((value->op == OpNegate) || (value->op == OpUnaryPlus)) 50434345a63Smrg { 50534345a63Smrg *flags_inout &= ~XkbSA_GroupAbsolute; 50634345a63Smrg spec = value->value.child; 507f46a6179Smrg } 50834345a63Smrg else 50934345a63Smrg { 51034345a63Smrg *flags_inout |= XkbSA_GroupAbsolute; 51134345a63Smrg spec = value; 512f46a6179Smrg } 513f46a6179Smrg 51434345a63Smrg if (!ExprResolveInteger(spec, &rtrn, SimpleLookup, (XPointer) groupNames)) 51534345a63Smrg return ReportMismatch(action, F_Group, "integer (range 1..8)"); 51634345a63Smrg if ((rtrn.ival < 1) || (rtrn.ival > XkbNumKbdGroups)) 51734345a63Smrg { 518bfe6082cSmrg ERROR("Illegal group %d (must be in the range 1..%d)\n", rtrn.ival, 51934345a63Smrg XkbNumKbdGroups); 520bfe6082cSmrg ACTION("Action %s definition ignored\n", 52134345a63Smrg XkbActionTypeText(action, XkbMessage)); 52234345a63Smrg return False; 523f46a6179Smrg } 52434345a63Smrg if (value->op == OpNegate) 52534345a63Smrg *grp_rtrn = -rtrn.ival; 52634345a63Smrg else if (value->op == OpUnaryPlus) 52734345a63Smrg *grp_rtrn = rtrn.ival; 52834345a63Smrg else 52934345a63Smrg *grp_rtrn = rtrn.ival - 1; 530f46a6179Smrg return True; 531f46a6179Smrg} 532f46a6179Smrg 533f46a6179Smrgstatic Bool 5346930ead5SmrgHandleSetLatchGroup(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 5356930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 536f46a6179Smrg{ 53734345a63Smrg XkbGroupAction *act; 53834345a63Smrg 53934345a63Smrg act = (XkbGroupAction *) action; 54034345a63Smrg if (array_ndx != NULL) 54134345a63Smrg { 54234345a63Smrg switch (field) 54334345a63Smrg { 54434345a63Smrg case F_ClearLocks: 54534345a63Smrg case F_LatchToLock: 54634345a63Smrg case F_Group: 54734345a63Smrg return ReportActionNotArray(action->type, field); 54834345a63Smrg } 549f46a6179Smrg } 55034345a63Smrg switch (field) 55134345a63Smrg { 55234345a63Smrg case F_ClearLocks: 55334345a63Smrg case F_LatchToLock: 5546930ead5Smrg { 5556930ead5Smrg unsigned rtrn = act->flags; 55634345a63Smrg if (CheckLatchLockFlags(action->type, field, value, &rtrn)) 55734345a63Smrg { 55834345a63Smrg act->flags = rtrn; 55934345a63Smrg return True; 56034345a63Smrg } 56134345a63Smrg return False; 5626930ead5Smrg } 56334345a63Smrg case F_Group: 5646930ead5Smrg { 5656930ead5Smrg unsigned t1 = act->flags; 5666930ead5Smrg int t2; 56734345a63Smrg if (CheckGroupField(action->type, value, &t1, &t2)) 56834345a63Smrg { 56934345a63Smrg act->flags = t1; 57034345a63Smrg XkbSASetGroup(act, t2); 57134345a63Smrg return True; 57234345a63Smrg } 57334345a63Smrg return False; 574f46a6179Smrg } 5756930ead5Smrg } 57634345a63Smrg return ReportIllegal(action->type, field); 577f46a6179Smrg} 578f46a6179Smrg 579f46a6179Smrgstatic Bool 5806930ead5SmrgHandleLockGroup(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 5816930ead5Smrg const ExprDef * array_ndx, const ExprDef *value) 582f46a6179Smrg{ 58334345a63Smrg XkbGroupAction *act; 58434345a63Smrg 58534345a63Smrg act = (XkbGroupAction *) action; 58634345a63Smrg if ((array_ndx != NULL) && (field == F_Group)) 58734345a63Smrg return ReportActionNotArray(action->type, field); 58834345a63Smrg if (field == F_Group) 58934345a63Smrg { 5906930ead5Smrg unsigned t1 = act->flags; 5916930ead5Smrg int t2; 59234345a63Smrg if (CheckGroupField(action->type, value, &t1, &t2)) 59334345a63Smrg { 59434345a63Smrg act->flags = t1; 59534345a63Smrg XkbSASetGroup(act, t2); 59634345a63Smrg return True; 59734345a63Smrg } 59834345a63Smrg return False; 599f46a6179Smrg } 60034345a63Smrg return ReportIllegal(action->type, field); 601f46a6179Smrg} 602f46a6179Smrg 603f46a6179Smrgstatic Bool 6046930ead5SmrgHandleMovePtr(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 6056930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 606f46a6179Smrg{ 60734345a63Smrg ExprResult rtrn; 60834345a63Smrg XkbPtrAction *act; 60934345a63Smrg 61034345a63Smrg act = (XkbPtrAction *) action; 61134345a63Smrg if ((array_ndx != NULL) && ((field == F_X) || (field == F_Y))) 61234345a63Smrg return ReportActionNotArray(action->type, field); 61334345a63Smrg 61434345a63Smrg if ((field == F_X) || (field == F_Y)) 61534345a63Smrg { 6166930ead5Smrg Bool absolute; 6176930ead5Smrg 61834345a63Smrg if ((value->op == OpNegate) || (value->op == OpUnaryPlus)) 61934345a63Smrg absolute = False; 62034345a63Smrg else 62134345a63Smrg absolute = True; 62234345a63Smrg if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) 62334345a63Smrg return ReportMismatch(action->type, field, "integer"); 62434345a63Smrg if (field == F_X) 62534345a63Smrg { 62634345a63Smrg if (absolute) 62734345a63Smrg act->flags |= XkbSA_MoveAbsoluteX; 62834345a63Smrg XkbSetPtrActionX(act, rtrn.ival); 62934345a63Smrg } 63034345a63Smrg else 63134345a63Smrg { 63234345a63Smrg if (absolute) 63334345a63Smrg act->flags |= XkbSA_MoveAbsoluteY; 63434345a63Smrg XkbSetPtrActionY(act, rtrn.ival); 63534345a63Smrg } 63634345a63Smrg return True; 637f46a6179Smrg } 63834345a63Smrg else if (field == F_Accel) 63934345a63Smrg { 64034345a63Smrg if (!ExprResolveBoolean(value, &rtrn, NULL, NULL)) 64134345a63Smrg return ReportMismatch(action->type, field, "boolean"); 64234345a63Smrg if (rtrn.uval) 64334345a63Smrg act->flags &= ~XkbSA_NoAcceleration; 64434345a63Smrg else 64534345a63Smrg act->flags |= XkbSA_NoAcceleration; 646bfe6082cSmrg return True; 647f46a6179Smrg } 64834345a63Smrg return ReportIllegal(action->type, field); 649f46a6179Smrg} 650f46a6179Smrg 651f46a6179Smrgstatic LookupEntry btnNames[] = { 65234345a63Smrg {"button1", 1}, 65334345a63Smrg {"button2", 2}, 65434345a63Smrg {"button3", 3}, 65534345a63Smrg {"button4", 4}, 65634345a63Smrg {"button5", 5}, 65734345a63Smrg {"default", 0}, 65834345a63Smrg {NULL, 0} 659f46a6179Smrg}; 660f46a6179Smrg 661f46a6179Smrgstatic Bool 6626930ead5SmrgHandlePtrBtn(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 6636930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 664f46a6179Smrg{ 66534345a63Smrg ExprResult rtrn; 66634345a63Smrg XkbPtrBtnAction *act; 66734345a63Smrg 66834345a63Smrg act = (XkbPtrBtnAction *) action; 66934345a63Smrg if (field == F_Button) 67034345a63Smrg { 67134345a63Smrg if (array_ndx != NULL) 67234345a63Smrg return ReportActionNotArray(action->type, field); 67334345a63Smrg if (!ExprResolveInteger 67434345a63Smrg (value, &rtrn, SimpleLookup, (XPointer) btnNames)) 67534345a63Smrg return ReportMismatch(action->type, field, 67634345a63Smrg "integer (range 1..5)"); 67734345a63Smrg if ((rtrn.ival < 0) || (rtrn.ival > 5)) 67834345a63Smrg { 67934345a63Smrg ERROR("Button must specify default or be in the range 1..5\n"); 680bfe6082cSmrg ACTION("Illegal button value %d ignored\n", rtrn.ival); 68134345a63Smrg return False; 68234345a63Smrg } 68334345a63Smrg act->button = rtrn.ival; 68434345a63Smrg return True; 685f46a6179Smrg } 68634345a63Smrg else if ((action->type == XkbSA_LockPtrBtn) && (field == F_Affect)) 68734345a63Smrg { 68834345a63Smrg if (array_ndx != NULL) 68934345a63Smrg return ReportActionNotArray(action->type, field); 69034345a63Smrg if (!ExprResolveEnum(value, &rtrn, lockWhich)) 69134345a63Smrg return ReportMismatch(action->type, field, "lock or unlock"); 69234345a63Smrg act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock); 693bfe6082cSmrg act->flags |= rtrn.uval; 69434345a63Smrg return True; 695f46a6179Smrg } 69634345a63Smrg else if (field == F_Count) 69734345a63Smrg { 69834345a63Smrg if (array_ndx != NULL) 69934345a63Smrg return ReportActionNotArray(action->type, field); 70034345a63Smrg if (!ExprResolveInteger 70134345a63Smrg (value, &rtrn, SimpleLookup, (XPointer) btnNames)) 70234345a63Smrg return ReportMismatch(action->type, field, "integer"); 70334345a63Smrg if ((rtrn.ival < 0) || (rtrn.ival > 255)) 70434345a63Smrg { 70534345a63Smrg ERROR("The count field must have a value in the range 0..255\n"); 706bfe6082cSmrg ACTION("Illegal count %d ignored\n", rtrn.ival); 70734345a63Smrg return False; 70834345a63Smrg } 70934345a63Smrg act->count = rtrn.ival; 71034345a63Smrg return True; 711f46a6179Smrg } 71234345a63Smrg return ReportIllegal(action->type, field); 713f46a6179Smrg} 714f46a6179Smrg 715f46a6179Smrgstatic LookupEntry ptrDflts[] = { 71634345a63Smrg {"dfltbtn", XkbSA_AffectDfltBtn}, 71734345a63Smrg {"defaultbutton", XkbSA_AffectDfltBtn}, 71834345a63Smrg {"button", XkbSA_AffectDfltBtn}, 71934345a63Smrg {NULL, 0} 720f46a6179Smrg}; 721f46a6179Smrg 722f46a6179Smrgstatic Bool 7236930ead5SmrgHandleSetPtrDflt(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 7246930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 725f46a6179Smrg{ 72634345a63Smrg ExprResult rtrn; 72734345a63Smrg XkbPtrDfltAction *act; 72834345a63Smrg 72934345a63Smrg act = (XkbPtrDfltAction *) action; 73034345a63Smrg if (field == F_Affect) 73134345a63Smrg { 73234345a63Smrg if (array_ndx != NULL) 73334345a63Smrg return ReportActionNotArray(action->type, field); 73434345a63Smrg if (!ExprResolveEnum(value, &rtrn, ptrDflts)) 73534345a63Smrg return ReportMismatch(action->type, field, "pointer component"); 73634345a63Smrg act->affect = rtrn.uval; 73734345a63Smrg return True; 738f46a6179Smrg } 73934345a63Smrg else if ((field == F_Button) || (field == F_Value)) 74034345a63Smrg { 7416930ead5Smrg const ExprDef *btn; 74234345a63Smrg if (array_ndx != NULL) 74334345a63Smrg return ReportActionNotArray(action->type, field); 74434345a63Smrg if ((value->op == OpNegate) || (value->op == OpUnaryPlus)) 74534345a63Smrg { 74634345a63Smrg act->flags &= ~XkbSA_DfltBtnAbsolute; 74734345a63Smrg btn = value->value.child; 74834345a63Smrg } 74934345a63Smrg else 75034345a63Smrg { 75134345a63Smrg act->flags |= XkbSA_DfltBtnAbsolute; 75234345a63Smrg btn = value; 75334345a63Smrg } 75434345a63Smrg 75534345a63Smrg if (!ExprResolveInteger 75634345a63Smrg (btn, &rtrn, SimpleLookup, (XPointer) btnNames)) 75734345a63Smrg return ReportMismatch(action->type, field, 75834345a63Smrg "integer (range 1..5)"); 75934345a63Smrg if ((rtrn.ival < 0) || (rtrn.ival > 5)) 76034345a63Smrg { 76134345a63Smrg ERROR("New default button value must be in the range 1..5\n"); 762bfe6082cSmrg ACTION("Illegal default button value %d ignored\n", rtrn.ival); 76334345a63Smrg return False; 76434345a63Smrg } 76534345a63Smrg if (rtrn.ival == 0) 76634345a63Smrg { 76734345a63Smrg ERROR("Cannot set default pointer button to \"default\"\n"); 76834345a63Smrg ACTION("Illegal default button setting ignored\n"); 76934345a63Smrg return False; 77034345a63Smrg } 77134345a63Smrg if (value->op == OpNegate) 77234345a63Smrg XkbSASetPtrDfltValue(act, -rtrn.ival); 77334345a63Smrg else 77434345a63Smrg XkbSASetPtrDfltValue(act, rtrn.ival); 77534345a63Smrg return True; 776f46a6179Smrg } 77734345a63Smrg return ReportIllegal(action->type, field); 778f46a6179Smrg} 779f46a6179Smrg 78034345a63Smrgstatic LookupEntry isoNames[] = { 78134345a63Smrg {"mods", XkbSA_ISONoAffectMods}, 78234345a63Smrg {"modifiers", XkbSA_ISONoAffectMods}, 78334345a63Smrg {"group", XkbSA_ISONoAffectGroup}, 78434345a63Smrg {"groups", XkbSA_ISONoAffectGroup}, 78534345a63Smrg {"ptr", XkbSA_ISONoAffectPtr}, 78634345a63Smrg {"pointer", XkbSA_ISONoAffectPtr}, 78734345a63Smrg {"ctrls", XkbSA_ISONoAffectCtrls}, 78834345a63Smrg {"controls", XkbSA_ISONoAffectCtrls}, 789bfe6082cSmrg {"all", XkbSA_ISOAffectMask}, 79034345a63Smrg {"none", 0}, 791bfe6082cSmrg {"both", 0}, 792bfe6082cSmrg {"lock", XkbSA_LockNoUnlock}, 793bfe6082cSmrg {"neither", (XkbSA_LockNoLock | XkbSA_LockNoUnlock)}, 794bfe6082cSmrg {"unlock", XkbSA_LockNoLock}, 79534345a63Smrg {NULL, 0}, 796f46a6179Smrg}; 797f46a6179Smrg 798f46a6179Smrgstatic Bool 7996930ead5SmrgHandleISOLock(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 8006930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 801f46a6179Smrg{ 80234345a63Smrg ExprResult rtrn; 80334345a63Smrg XkbISOAction *act; 8046930ead5Smrg unsigned flags; 80534345a63Smrg 80634345a63Smrg act = (XkbISOAction *) action; 80734345a63Smrg switch (field) 80834345a63Smrg { 80934345a63Smrg case F_Modifiers: 8106930ead5Smrg { 8116930ead5Smrg unsigned mods; 81234345a63Smrg if (array_ndx != NULL) 81334345a63Smrg return ReportActionNotArray(action->type, field); 81434345a63Smrg flags = act->flags; 81534345a63Smrg if (CheckModifierField(xkb, action->type, value, &flags, &mods)) 81634345a63Smrg { 81734345a63Smrg act->flags = flags & (~XkbSA_ISODfltIsGroup); 818bfe6082cSmrg act->real_mods = act->mask = (mods & 0xff); 819bfe6082cSmrg mods = (mods >> 8) & 0xffff; 82034345a63Smrg XkbSetModActionVMods(act, mods); 82134345a63Smrg return True; 82234345a63Smrg } 82334345a63Smrg return False; 8246930ead5Smrg } 82534345a63Smrg case F_Group: 8266930ead5Smrg { 8276930ead5Smrg int group; 82834345a63Smrg if (array_ndx != NULL) 82934345a63Smrg return ReportActionNotArray(action->type, field); 83034345a63Smrg flags = act->flags; 83134345a63Smrg if (CheckGroupField(action->type, value, &flags, &group)) 83234345a63Smrg { 83334345a63Smrg act->flags = flags | XkbSA_ISODfltIsGroup; 83434345a63Smrg XkbSASetGroup(act, group); 83534345a63Smrg return True; 83634345a63Smrg } 83734345a63Smrg return False; 8386930ead5Smrg } 83934345a63Smrg case F_Affect: 84034345a63Smrg if (array_ndx != NULL) 84134345a63Smrg return ReportActionNotArray(action->type, field); 84234345a63Smrg if (!ExprResolveMask(value, &rtrn, SimpleLookup, (XPointer) isoNames)) 84334345a63Smrg return ReportMismatch(action->type, field, "keyboard component"); 84434345a63Smrg act->affect = (~rtrn.uval) & XkbSA_ISOAffectMask; 845bfe6082cSmrg act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock); 846bfe6082cSmrg act->flags |= rtrn.uval & (XkbSA_LockNoLock | XkbSA_LockNoUnlock); 84734345a63Smrg return True; 848f46a6179Smrg } 84934345a63Smrg return ReportIllegal(action->type, field); 850f46a6179Smrg} 851f46a6179Smrg 852f46a6179Smrgstatic Bool 8536930ead5SmrgHandleSwitchScreen(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 8546930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 855f46a6179Smrg{ 85634345a63Smrg ExprResult rtrn; 85734345a63Smrg XkbSwitchScreenAction *act; 85834345a63Smrg 85934345a63Smrg act = (XkbSwitchScreenAction *) action; 86034345a63Smrg if (field == F_Screen) 86134345a63Smrg { 8626930ead5Smrg const ExprDef *scrn; 86334345a63Smrg if (array_ndx != NULL) 86434345a63Smrg return ReportActionNotArray(action->type, field); 86534345a63Smrg if ((value->op == OpNegate) || (value->op == OpUnaryPlus)) 86634345a63Smrg { 86734345a63Smrg act->flags &= ~XkbSA_SwitchAbsolute; 86834345a63Smrg scrn = value->value.child; 86934345a63Smrg } 87034345a63Smrg else 87134345a63Smrg { 87234345a63Smrg act->flags |= XkbSA_SwitchAbsolute; 87334345a63Smrg scrn = value; 87434345a63Smrg } 87534345a63Smrg 87634345a63Smrg if (!ExprResolveInteger(scrn, &rtrn, NULL, NULL)) 87734345a63Smrg return ReportMismatch(action->type, field, "integer (0..255)"); 87834345a63Smrg if ((rtrn.ival < 0) || (rtrn.ival > 255)) 87934345a63Smrg { 88034345a63Smrg ERROR("Screen index must be in the range 1..255\n"); 881bfe6082cSmrg ACTION("Illegal screen value %d ignored\n", rtrn.ival); 88234345a63Smrg return False; 88334345a63Smrg } 88434345a63Smrg if (value->op == OpNegate) 88534345a63Smrg XkbSASetScreen(act, -rtrn.ival); 88634345a63Smrg else 88734345a63Smrg XkbSASetScreen(act, rtrn.ival); 88834345a63Smrg return True; 889f46a6179Smrg } 89034345a63Smrg else if (field == F_Same) 89134345a63Smrg { 89234345a63Smrg if (array_ndx != NULL) 89334345a63Smrg return ReportActionNotArray(action->type, field); 89434345a63Smrg if (!ExprResolveBoolean(value, &rtrn, NULL, NULL)) 89534345a63Smrg return ReportMismatch(action->type, field, "boolean"); 89634345a63Smrg if (rtrn.uval) 89734345a63Smrg act->flags &= ~XkbSA_SwitchApplication; 89834345a63Smrg else 89934345a63Smrg act->flags |= XkbSA_SwitchApplication; 90034345a63Smrg return True; 901f46a6179Smrg } 90234345a63Smrg return ReportIllegal(action->type, field); 903f46a6179Smrg} 904f46a6179Smrg 90534345a63SmrgLookupEntry ctrlNames[] = { 90634345a63Smrg {"repeatkeys", XkbRepeatKeysMask} 90734345a63Smrg , 90834345a63Smrg {"repeat", XkbRepeatKeysMask} 90934345a63Smrg , 91034345a63Smrg {"autorepeat", XkbRepeatKeysMask} 91134345a63Smrg , 91234345a63Smrg {"slowkeys", XkbSlowKeysMask} 91334345a63Smrg , 91434345a63Smrg {"bouncekeys", XkbBounceKeysMask} 91534345a63Smrg , 91634345a63Smrg {"stickykeys", XkbStickyKeysMask} 91734345a63Smrg , 91834345a63Smrg {"mousekeys", XkbMouseKeysMask} 91934345a63Smrg , 92034345a63Smrg {"mousekeysaccel", XkbMouseKeysAccelMask} 92134345a63Smrg , 92234345a63Smrg {"accessxkeys", XkbAccessXKeysMask} 92334345a63Smrg , 92434345a63Smrg {"accessxtimeout", XkbAccessXTimeoutMask} 92534345a63Smrg , 92634345a63Smrg {"accessxfeedback", XkbAccessXFeedbackMask} 92734345a63Smrg , 92834345a63Smrg {"audiblebell", XkbAudibleBellMask} 92934345a63Smrg , 93034345a63Smrg {"overlay1", XkbOverlay1Mask} 93134345a63Smrg , 93234345a63Smrg {"overlay2", XkbOverlay2Mask} 93334345a63Smrg , 93434345a63Smrg {"ignoregrouplock", XkbIgnoreGroupLockMask} 93534345a63Smrg , 93634345a63Smrg {"all", XkbAllBooleanCtrlsMask} 93734345a63Smrg , 93834345a63Smrg {"none", 0} 93934345a63Smrg , 94034345a63Smrg {NULL, 0} 941f46a6179Smrg}; 942f46a6179Smrg 943f46a6179Smrgstatic Bool 9446930ead5SmrgHandleSetLockControls(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 9456930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 946f46a6179Smrg{ 94734345a63Smrg ExprResult rtrn; 94834345a63Smrg XkbCtrlsAction *act; 94934345a63Smrg 95034345a63Smrg act = (XkbCtrlsAction *) action; 95134345a63Smrg if (field == F_Controls) 95234345a63Smrg { 95334345a63Smrg if (array_ndx != NULL) 95434345a63Smrg return ReportActionNotArray(action->type, field); 95534345a63Smrg if (!ExprResolveMask 95634345a63Smrg (value, &rtrn, SimpleLookup, (XPointer) ctrlNames)) 95734345a63Smrg return ReportMismatch(action->type, field, "controls mask"); 95834345a63Smrg XkbActionSetCtrls(act, rtrn.uval); 95934345a63Smrg return True; 960f46a6179Smrg } 961bfe6082cSmrg else if (field == F_Affect && action->type == XkbSA_LockControls) { 962bfe6082cSmrg if (array_ndx != NULL) 963bfe6082cSmrg return ReportActionNotArray(action->type, field); 964bfe6082cSmrg if (!ExprResolveEnum(value, &rtrn, lockWhich)) 965bfe6082cSmrg return ReportMismatch(action->type, field, "lock or unlock"); 966bfe6082cSmrg act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock); 967bfe6082cSmrg act->flags |= rtrn.uval; 968bfe6082cSmrg return True; 969bfe6082cSmrg } 97034345a63Smrg return ReportIllegal(action->type, field); 971f46a6179Smrg} 972f46a6179Smrg 97334345a63Smrgstatic LookupEntry evNames[] = { 97434345a63Smrg {"press", XkbSA_MessageOnPress}, 97534345a63Smrg {"keypress", XkbSA_MessageOnPress}, 97634345a63Smrg {"release", XkbSA_MessageOnRelease}, 97734345a63Smrg {"keyrelease", XkbSA_MessageOnRelease}, 97834345a63Smrg {"all", XkbSA_MessageOnPress | XkbSA_MessageOnRelease}, 97934345a63Smrg {"none", 0}, 98034345a63Smrg {NULL, 0} 981f46a6179Smrg}; 982f46a6179Smrg 983f46a6179Smrgstatic Bool 9846930ead5SmrgHandleActionMessage(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 9856930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 986f46a6179Smrg{ 98734345a63Smrg ExprResult rtrn; 98834345a63Smrg XkbMessageAction *act; 98934345a63Smrg 99034345a63Smrg act = (XkbMessageAction *) action; 99134345a63Smrg switch (field) 99234345a63Smrg { 99334345a63Smrg case F_Report: 99434345a63Smrg if (array_ndx != NULL) 99534345a63Smrg return ReportActionNotArray(action->type, field); 99634345a63Smrg if (!ExprResolveMask(value, &rtrn, SimpleLookup, (XPointer) evNames)) 99734345a63Smrg return ReportMismatch(action->type, field, "key event mask"); 99834345a63Smrg act->flags &= ~(XkbSA_MessageOnPress | XkbSA_MessageOnRelease); 99934345a63Smrg act->flags = 100034345a63Smrg rtrn.uval & (XkbSA_MessageOnPress | XkbSA_MessageOnRelease); 100134345a63Smrg return True; 100234345a63Smrg case F_GenKeyEvent: 100334345a63Smrg if (array_ndx != NULL) 100434345a63Smrg return ReportActionNotArray(action->type, field); 100534345a63Smrg if (!ExprResolveBoolean(value, &rtrn, NULL, NULL)) 100634345a63Smrg return ReportMismatch(action->type, field, "boolean"); 100734345a63Smrg if (rtrn.uval) 100834345a63Smrg act->flags |= XkbSA_MessageGenKeyEvent; 100934345a63Smrg else 101034345a63Smrg act->flags &= ~XkbSA_MessageGenKeyEvent; 101134345a63Smrg return True; 101234345a63Smrg case F_Data: 101334345a63Smrg if (array_ndx == NULL) 101434345a63Smrg { 101534345a63Smrg if (!ExprResolveString(value, &rtrn, NULL, NULL)) 101634345a63Smrg return ReportMismatch(action->type, field, "string"); 101734345a63Smrg else 101834345a63Smrg { 101934345a63Smrg int len = strlen(rtrn.str); 102034345a63Smrg if ((len < 1) || (len > 6)) 102134345a63Smrg { 102234345a63Smrg WARN("An action message can hold only 6 bytes\n"); 1023bfe6082cSmrg ACTION("Extra %d bytes ignored\n", len - 6); 102434345a63Smrg } 102534345a63Smrg strncpy((char *) act->message, rtrn.str, 6); 102634345a63Smrg } 102734345a63Smrg return True; 102834345a63Smrg } 102934345a63Smrg else 103034345a63Smrg { 103134345a63Smrg unsigned ndx; 103234345a63Smrg if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL)) 103334345a63Smrg { 103434345a63Smrg ERROR("Array subscript must be integer\n"); 103534345a63Smrg ACTION("Illegal subscript ignored\n"); 103634345a63Smrg return False; 103734345a63Smrg } 103834345a63Smrg ndx = rtrn.uval; 103934345a63Smrg if (ndx > 5) 104034345a63Smrg { 104134345a63Smrg ERROR("An action message is at most 6 bytes long\n"); 1042bfe6082cSmrg ACTION("Attempt to use data[%d] ignored\n", ndx); 104334345a63Smrg return False; 104434345a63Smrg } 104534345a63Smrg if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) 104634345a63Smrg return ReportMismatch(action->type, field, "integer"); 104734345a63Smrg if ((rtrn.ival < 0) || (rtrn.ival > 255)) 104834345a63Smrg { 104934345a63Smrg ERROR("Message data must be in the range 0..255\n"); 1050bfe6082cSmrg ACTION("Illegal datum %d ignored\n", rtrn.ival); 105134345a63Smrg return False; 105234345a63Smrg } 105334345a63Smrg act->message[ndx] = rtrn.uval; 105434345a63Smrg } 105534345a63Smrg return True; 1056f46a6179Smrg } 105734345a63Smrg return ReportIllegal(action->type, field); 1058f46a6179Smrg} 1059f46a6179Smrg 1060f46a6179Smrgstatic Bool 10616930ead5SmrgHandleRedirectKey(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 10626930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 1063f46a6179Smrg{ 106434345a63Smrg ExprResult rtrn; 106534345a63Smrg XkbRedirectKeyAction *act; 106634345a63Smrg 106734345a63Smrg if (array_ndx != NULL) 106834345a63Smrg return ReportActionNotArray(action->type, field); 106934345a63Smrg 107034345a63Smrg act = (XkbRedirectKeyAction *) action; 107134345a63Smrg switch (field) 107234345a63Smrg { 107334345a63Smrg case F_Keycode: 10746930ead5Smrg { 10756930ead5Smrg unsigned int t1; 10766930ead5Smrg unsigned long tmp; 10776930ead5Smrg 107834345a63Smrg if (!ExprResolveKeyName(value, &rtrn, NULL, NULL)) 107934345a63Smrg return ReportMismatch(action->type, field, "key name"); 108034345a63Smrg tmp = KeyNameToLong(rtrn.keyName.name); 108134345a63Smrg if (!FindNamedKey(xkb, tmp, &t1, True, CreateKeyNames(xkb), 0)) 108234345a63Smrg { 108334345a63Smrg return ReportNotFound(action->type, field, "Key", 108434345a63Smrg XkbKeyNameText(rtrn.keyName.name, 108534345a63Smrg XkbMessage)); 108634345a63Smrg } 108734345a63Smrg act->new_key = t1; 108834345a63Smrg return True; 10896930ead5Smrg } 109034345a63Smrg case F_ModsToClear: 109134345a63Smrg case F_Modifiers: 10926930ead5Smrg { 10936930ead5Smrg unsigned t1 = 0, t2; 10946930ead5Smrg 109534345a63Smrg if (CheckModifierField(xkb, action->type, value, &t1, &t2)) 109634345a63Smrg { 10976930ead5Smrg unsigned vmods, vmask; 10986930ead5Smrg 109934345a63Smrg act->mods_mask |= (t2 & 0xff); 110034345a63Smrg if (field == F_Modifiers) 110134345a63Smrg act->mods |= (t2 & 0xff); 110234345a63Smrg else 110334345a63Smrg act->mods &= ~(t2 & 0xff); 110434345a63Smrg 110534345a63Smrg t2 = (t2 >> 8) & 0xffff; 110634345a63Smrg vmods = XkbSARedirectVMods(act); 110734345a63Smrg vmask = XkbSARedirectVModsMask(act); 110834345a63Smrg vmask |= t2; 110934345a63Smrg if (field == F_Modifiers) 111034345a63Smrg vmods |= t2; 111134345a63Smrg else 111234345a63Smrg vmods &= ~t2; 111334345a63Smrg XkbSARedirectSetVMods(act, vmods); 111434345a63Smrg XkbSARedirectSetVModsMask(act, vmask); 111534345a63Smrg return True; 111634345a63Smrg } 111734345a63Smrg return True; 1118f46a6179Smrg } 11196930ead5Smrg } 112034345a63Smrg return ReportIllegal(action->type, field); 1121f46a6179Smrg} 1122f46a6179Smrg 1123f46a6179Smrgstatic Bool 11246930ead5SmrgHandleDeviceBtn(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 11256930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 1126f46a6179Smrg{ 112734345a63Smrg ExprResult rtrn; 112834345a63Smrg XkbDeviceBtnAction *act; 112934345a63Smrg 113034345a63Smrg act = (XkbDeviceBtnAction *) action; 113134345a63Smrg if (field == F_Button) 113234345a63Smrg { 113334345a63Smrg if (array_ndx != NULL) 113434345a63Smrg return ReportActionNotArray(action->type, field); 113534345a63Smrg if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) 113634345a63Smrg return ReportMismatch(action->type, field, 113734345a63Smrg "integer (range 1..255)"); 113834345a63Smrg if ((rtrn.ival < 0) || (rtrn.ival > 255)) 113934345a63Smrg { 114034345a63Smrg ERROR("Button must specify default or be in the range 1..255\n"); 1141bfe6082cSmrg ACTION("Illegal button value %d ignored\n", rtrn.ival); 114234345a63Smrg return False; 114334345a63Smrg } 114434345a63Smrg act->button = rtrn.ival; 114534345a63Smrg return True; 1146f46a6179Smrg } 114734345a63Smrg else if ((action->type == XkbSA_LockDeviceBtn) && (field == F_Affect)) 114834345a63Smrg { 114934345a63Smrg if (array_ndx != NULL) 115034345a63Smrg return ReportActionNotArray(action->type, field); 115134345a63Smrg if (!ExprResolveEnum(value, &rtrn, lockWhich)) 115234345a63Smrg return ReportMismatch(action->type, field, "lock or unlock"); 115334345a63Smrg act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock); 1154bfe6082cSmrg act->flags |= rtrn.uval; 115534345a63Smrg return True; 1156f46a6179Smrg } 115734345a63Smrg else if (field == F_Count) 115834345a63Smrg { 115934345a63Smrg if (array_ndx != NULL) 116034345a63Smrg return ReportActionNotArray(action->type, field); 116134345a63Smrg if (!ExprResolveInteger 116234345a63Smrg (value, &rtrn, SimpleLookup, (XPointer) btnNames)) 116334345a63Smrg return ReportMismatch(action->type, field, "integer"); 116434345a63Smrg if ((rtrn.ival < 0) || (rtrn.ival > 255)) 116534345a63Smrg { 116634345a63Smrg ERROR("The count field must have a value in the range 0..255\n"); 1167bfe6082cSmrg ACTION("Illegal count %d ignored\n", rtrn.ival); 116834345a63Smrg return False; 116934345a63Smrg } 117034345a63Smrg act->count = rtrn.ival; 117134345a63Smrg return True; 1172f46a6179Smrg } 117334345a63Smrg else if (field == F_Device) 117434345a63Smrg { 117534345a63Smrg if (array_ndx != NULL) 117634345a63Smrg return ReportActionNotArray(action->type, field); 117734345a63Smrg if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) 117834345a63Smrg return ReportMismatch(action->type, field, 117934345a63Smrg "integer (range 1..255)"); 118034345a63Smrg if ((rtrn.ival < 0) || (rtrn.ival > 255)) 118134345a63Smrg { 118234345a63Smrg ERROR("Device must specify default or be in the range 1..255\n"); 1183bfe6082cSmrg ACTION("Illegal device value %d ignored\n", rtrn.ival); 118434345a63Smrg return False; 118534345a63Smrg } 118634345a63Smrg act->device = rtrn.ival; 118734345a63Smrg return True; 1188f46a6179Smrg } 118934345a63Smrg return ReportIllegal(action->type, field); 1190f46a6179Smrg} 1191f46a6179Smrg 1192f46a6179Smrgstatic Bool 11936930ead5SmrgHandleDeviceValuator(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 11946930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 1195f46a6179Smrg{ 1196f46a6179Smrg#if 0 119734345a63Smrg ExprResult rtrn; 119834345a63Smrg XkbDeviceValuatorAction *act; 1199f46a6179Smrg 120034345a63Smrg act = (XkbDeviceValuatorAction *) action; 1201f46a6179Smrg /* XXX - Not yet implemented */ 1202f46a6179Smrg#endif 1203f46a6179Smrg return False; 1204f46a6179Smrg} 1205f46a6179Smrg 1206f46a6179Smrgstatic Bool 12076930ead5SmrgHandlePrivate(XkbDescPtr xkb, XkbAnyAction *action, unsigned field, 12086930ead5Smrg const ExprDef *array_ndx, const ExprDef *value) 1209f46a6179Smrg{ 121034345a63Smrg ExprResult rtrn; 121134345a63Smrg 121234345a63Smrg switch (field) 121334345a63Smrg { 121434345a63Smrg case F_Type: 121534345a63Smrg if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) 121634345a63Smrg return ReportMismatch(PrivateAction, field, "integer"); 121734345a63Smrg if ((rtrn.ival < 0) || (rtrn.ival > 255)) 121834345a63Smrg { 121934345a63Smrg ERROR("Private action type must be in the range 0..255\n"); 1220bfe6082cSmrg ACTION("Illegal type %d ignored\n", rtrn.ival); 122134345a63Smrg return False; 122234345a63Smrg } 122334345a63Smrg action->type = rtrn.uval; 122434345a63Smrg return True; 122534345a63Smrg case F_Data: 122634345a63Smrg if (array_ndx == NULL) 122734345a63Smrg { 122834345a63Smrg if (!ExprResolveString(value, &rtrn, NULL, NULL)) 122934345a63Smrg return ReportMismatch(action->type, field, "string"); 123034345a63Smrg else 123134345a63Smrg { 123234345a63Smrg int len = strlen(rtrn.str); 123334345a63Smrg if ((len < 1) || (len > 7)) 123434345a63Smrg { 123534345a63Smrg WARN("A private action has 7 data bytes\n"); 1236bfe6082cSmrg ACTION("Extra %d bytes ignored\n", len - 6); 123734345a63Smrg return False; 123834345a63Smrg } 123934345a63Smrg strncpy((char *) action->data, rtrn.str, 7); 124034345a63Smrg } 124134345a63Smrg return True; 124234345a63Smrg } 124334345a63Smrg else 124434345a63Smrg { 124534345a63Smrg unsigned ndx; 124634345a63Smrg if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL)) 124734345a63Smrg { 124834345a63Smrg ERROR("Array subscript must be integer\n"); 124934345a63Smrg ACTION("Illegal subscript ignored\n"); 125034345a63Smrg return False; 125134345a63Smrg } 125234345a63Smrg ndx = rtrn.uval; 125334345a63Smrg if (ndx > 6) 125434345a63Smrg { 125534345a63Smrg ERROR("The data for a private action is 7 bytes long\n"); 1256bfe6082cSmrg ACTION("Attempt to use data[%d] ignored\n", ndx); 125734345a63Smrg return False; 125834345a63Smrg } 125934345a63Smrg if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) 126034345a63Smrg return ReportMismatch(action->type, field, "integer"); 126134345a63Smrg if ((rtrn.ival < 0) || (rtrn.ival > 255)) 126234345a63Smrg { 126334345a63Smrg ERROR("All data for a private action must be 0..255\n"); 1264bfe6082cSmrg ACTION("Illegal datum %d ignored\n", rtrn.ival); 126534345a63Smrg return False; 126634345a63Smrg } 126734345a63Smrg action->data[ndx] = rtrn.uval; 126834345a63Smrg return True; 126934345a63Smrg } 1270f46a6179Smrg } 127134345a63Smrg return ReportIllegal(PrivateAction, field); 1272f46a6179Smrg} 1273f46a6179Smrg 127434345a63Smrgtypedef Bool(*actionHandler) (XkbDescPtr /* xkb */ , 127534345a63Smrg XkbAnyAction * /* action */ , 127634345a63Smrg unsigned /* field */ , 12776930ead5Smrg const ExprDef * /* array_ndx */ , 12786930ead5Smrg const ExprDef * /* value */ 127934345a63Smrg ); 128034345a63Smrg 128134345a63Smrgstatic actionHandler handleAction[XkbSA_NumActions + 1] = { 128234345a63Smrg HandleNoAction /* NoAction */ , 128334345a63Smrg HandleSetLatchMods /* SetMods */ , 128434345a63Smrg HandleSetLatchMods /* LatchMods */ , 128534345a63Smrg HandleLockMods /* LockMods */ , 128634345a63Smrg HandleSetLatchGroup /* SetGroup */ , 128734345a63Smrg HandleSetLatchGroup /* LatchGroup */ , 128834345a63Smrg HandleLockGroup /* LockGroup */ , 128934345a63Smrg HandleMovePtr /* MovePtr */ , 129034345a63Smrg HandlePtrBtn /* PtrBtn */ , 129134345a63Smrg HandlePtrBtn /* LockPtrBtn */ , 129234345a63Smrg HandleSetPtrDflt /* SetPtrDflt */ , 129334345a63Smrg HandleISOLock /* ISOLock */ , 129434345a63Smrg HandleNoAction /* Terminate */ , 129534345a63Smrg HandleSwitchScreen /* SwitchScreen */ , 129634345a63Smrg HandleSetLockControls /* SetControls */ , 129734345a63Smrg HandleSetLockControls /* LockControls */ , 129834345a63Smrg HandleActionMessage /* ActionMessage */ , 129934345a63Smrg HandleRedirectKey /* RedirectKey */ , 130034345a63Smrg HandleDeviceBtn /* DeviceBtn */ , 130134345a63Smrg HandleDeviceBtn /* LockDeviceBtn */ , 130234345a63Smrg HandleDeviceValuator /* DeviceValuatr */ , 130334345a63Smrg HandlePrivate /* Private */ 1304f46a6179Smrg}; 1305f46a6179Smrg 1306f46a6179Smrg/***====================================================================***/ 1307f46a6179Smrg 1308f46a6179Smrgstatic void 130934345a63SmrgApplyActionFactoryDefaults(XkbAction * action) 1310f46a6179Smrg{ 131134345a63Smrg if (action->type == XkbSA_SetPtrDflt) 131234345a63Smrg { /* increment default button */ 131334345a63Smrg action->dflt.affect = XkbSA_AffectDfltBtn; 131434345a63Smrg action->dflt.flags = 0; 131534345a63Smrg XkbSASetPtrDfltValue(&action->dflt, 1); 1316f46a6179Smrg } 131734345a63Smrg else if (action->type == XkbSA_ISOLock) 131834345a63Smrg { 1319bfe6082cSmrg action->iso.real_mods = action->iso.mask = LockMask; 1320f46a6179Smrg } 1321f46a6179Smrg return; 1322f46a6179Smrg} 1323f46a6179Smrg 1324f46a6179Smrg 132534345a63Smrgint 13266930ead5SmrgHandleActionDef(const ExprDef *def, XkbDescPtr xkb, XkbAnyAction *action, 13276930ead5Smrg unsigned mergeMode, const ActionInfo *info) 1328f46a6179Smrg{ 132934345a63Smrg ExprDef *arg; 13306930ead5Smrg const char *str; 133134345a63Smrg unsigned tmp, hndlrType; 1332f46a6179Smrg 1333f46a6179Smrg if (!actionsInitialized) 133434345a63Smrg ActionsInit(); 1335f46a6179Smrg 133634345a63Smrg if (def->op != ExprActionDecl) 133734345a63Smrg { 1338bfe6082cSmrg ERROR("Expected an action definition, found %s\n", 133934345a63Smrg exprOpText(def->op)); 134034345a63Smrg return False; 1341f46a6179Smrg } 134234345a63Smrg str = XkbAtomGetString(NULL, def->value.action.name); 134334345a63Smrg if (!str) 134434345a63Smrg { 134534345a63Smrg WSGO("Missing name in action definition!!\n"); 134634345a63Smrg return False; 1347f46a6179Smrg } 134834345a63Smrg if (!stringToAction(str, &tmp)) 134934345a63Smrg { 1350bfe6082cSmrg ERROR("Unknown action %s\n", str); 135134345a63Smrg return False; 1352f46a6179Smrg } 135334345a63Smrg action->type = hndlrType = tmp; 135434345a63Smrg if (action->type != XkbSA_NoAction) 135534345a63Smrg { 135634345a63Smrg ApplyActionFactoryDefaults((XkbAction *) action); 135734345a63Smrg while (info) 135834345a63Smrg { 135934345a63Smrg if ((info->action == XkbSA_NoAction) 136034345a63Smrg || (info->action == hndlrType)) 136134345a63Smrg { 136234345a63Smrg if (!(*handleAction[hndlrType]) (xkb, action, 136334345a63Smrg info->field, 136434345a63Smrg info->array_ndx, 136534345a63Smrg info->value)) 136634345a63Smrg { 136734345a63Smrg return False; 136834345a63Smrg } 136934345a63Smrg } 137034345a63Smrg info = info->next; 137134345a63Smrg } 1372f46a6179Smrg } 137334345a63Smrg for (arg = def->value.action.args; arg != NULL; 137434345a63Smrg arg = (ExprDef *) arg->common.next) 137534345a63Smrg { 137634345a63Smrg ExprDef *field, *value, *arrayRtrn; 137734345a63Smrg ExprResult elemRtrn, fieldRtrn; 137834345a63Smrg unsigned fieldNdx; 137934345a63Smrg 138034345a63Smrg if (arg->op == OpAssign) 138134345a63Smrg { 138234345a63Smrg field = arg->value.binary.left; 138334345a63Smrg value = arg->value.binary.right; 138434345a63Smrg } 138534345a63Smrg else 138634345a63Smrg { 138734345a63Smrg if ((arg->op == OpNot) || (arg->op == OpInvert)) 138834345a63Smrg { 138934345a63Smrg field = arg->value.child; 139034345a63Smrg value = &constFalse; 139134345a63Smrg } 139234345a63Smrg else 139334345a63Smrg { 139434345a63Smrg field = arg; 139534345a63Smrg value = &constTrue; 139634345a63Smrg } 139734345a63Smrg } 139834345a63Smrg if (!ExprResolveLhs(field, &elemRtrn, &fieldRtrn, &arrayRtrn)) 139934345a63Smrg return False; /* internal error -- already reported */ 140034345a63Smrg 140134345a63Smrg if (elemRtrn.str != NULL) 140234345a63Smrg { 140334345a63Smrg ERROR("Cannot change defaults in an action definition\n"); 1404bfe6082cSmrg ACTION("Ignoring attempt to change %s.%s\n", elemRtrn.str, 140534345a63Smrg fieldRtrn.str); 140634345a63Smrg return False; 140734345a63Smrg } 140834345a63Smrg if (!stringToField(fieldRtrn.str, &fieldNdx)) 140934345a63Smrg { 1410bfe6082cSmrg ERROR("Unknown field name %s\n", uStringText(fieldRtrn.str)); 141134345a63Smrg return False; 141234345a63Smrg } 141334345a63Smrg if (!(*handleAction[hndlrType]) 141434345a63Smrg (xkb, action, fieldNdx, arrayRtrn, value)) 141534345a63Smrg { 141634345a63Smrg return False; 141734345a63Smrg } 1418f46a6179Smrg } 1419f46a6179Smrg return True; 1420f46a6179Smrg} 1421f46a6179Smrg 1422f46a6179Smrg/***====================================================================***/ 1423f46a6179Smrg 142434345a63Smrgint 14256930ead5SmrgSetActionField(XkbDescPtr xkb, const char *elem, const char *field, 14266930ead5Smrg ExprDef *array_ndx, ExprDef *value, ActionInfo **info_rtrn) 1427f46a6179Smrg{ 142834345a63Smrg ActionInfo *new, *old; 1429f46a6179Smrg 1430f46a6179Smrg if (!actionsInitialized) 143134345a63Smrg ActionsInit(); 1432f46a6179Smrg 14336930ead5Smrg new = malloc(sizeof(ActionInfo)); 143434345a63Smrg if (new == NULL) 143534345a63Smrg { 143634345a63Smrg WSGO("Couldn't allocate space for action default\n"); 143734345a63Smrg return False; 1438f46a6179Smrg } 143934345a63Smrg if (uStrCaseCmp(elem, "action") == 0) 144034345a63Smrg new->action = XkbSA_NoAction; 144134345a63Smrg else 144234345a63Smrg { 144334345a63Smrg if (!stringToAction(elem, &new->action)) 144434345a63Smrg return False; 144534345a63Smrg if (new->action == XkbSA_NoAction) 144634345a63Smrg { 1447bfe6082cSmrg ERROR("\"%s\" is not a valid field in a NoAction action\n", 144834345a63Smrg field); 144934345a63Smrg return False; 145034345a63Smrg } 1451f46a6179Smrg } 145234345a63Smrg if (!stringToField(field, &new->field)) 145334345a63Smrg { 1454bfe6082cSmrg ERROR("\"%s\" is not a legal field name\n", field); 145534345a63Smrg return False; 1456f46a6179Smrg } 145734345a63Smrg new->array_ndx = array_ndx; 145834345a63Smrg new->value = value; 145934345a63Smrg new->next = NULL; 146034345a63Smrg old = *info_rtrn; 146134345a63Smrg while ((old) && (old->next)) 146234345a63Smrg old = old->next; 146334345a63Smrg if (old == NULL) 146434345a63Smrg *info_rtrn = new; 146534345a63Smrg else 146634345a63Smrg old->next = new; 1467f46a6179Smrg return True; 1468f46a6179Smrg} 1469f46a6179Smrg 1470f46a6179Smrg/***====================================================================***/ 1471f46a6179Smrg 14726930ead5Smrgstatic void 1473f46a6179SmrgActionsInit(void) 1474f46a6179Smrg{ 147534345a63Smrg if (!actionsInitialized) 147634345a63Smrg { 14776930ead5Smrg bzero(&constTrue, sizeof(constTrue)); 14786930ead5Smrg constTrue = (ExprDef) { 14796930ead5Smrg .common.stmtType = StmtExpr, 14806930ead5Smrg .common.next = NULL, 14816930ead5Smrg .op = ExprIdent, 14826930ead5Smrg .type = TypeBoolean, 14836930ead5Smrg .value.str = XkbInternAtom(NULL, "true", False) 14846930ead5Smrg }; 14856930ead5Smrg bzero(&constFalse, sizeof(constFalse)); 14866930ead5Smrg constFalse = (ExprDef) { 14876930ead5Smrg .common.stmtType = StmtExpr, 14886930ead5Smrg .common.next = NULL, 14896930ead5Smrg .op = ExprIdent, 14906930ead5Smrg .type = TypeBoolean, 14916930ead5Smrg .value.str = XkbInternAtom(NULL, "false", False) 14926930ead5Smrg }; 149334345a63Smrg actionsInitialized = 1; 1494f46a6179Smrg } 1495f46a6179Smrg return; 1496f46a6179Smrg} 1497