1 /************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
37 static Bool actionsInitialized;
38 static ExprDef constTrue;
39 static ExprDef constFalse;
41 /***====================================================================***/
44 stringToAction(const char *str, unsigned *type_rtrn)
49 if (uStrCaseCmp(str, "noaction") == 0)
50 *type_rtrn = XkbSA_NoAction;
51 else if (uStrCaseCmp(str, "setmods") == 0)
52 *type_rtrn = XkbSA_SetMods;
53 else if (uStrCaseCmp(str, "latchmods") == 0)
54 *type_rtrn = XkbSA_LatchMods;
55 else if (uStrCaseCmp(str, "lockmods") == 0)
56 *type_rtrn = XkbSA_LockMods;
57 else if (uStrCaseCmp(str, "setgroup") == 0)
58 *type_rtrn = XkbSA_SetGroup;
59 else if (uStrCaseCmp(str, "latchgroup") == 0)
60 *type_rtrn = XkbSA_LatchGroup;
61 else if (uStrCaseCmp(str, "lockgroup") == 0)
62 *type_rtrn = XkbSA_LockGroup;
63 else if (uStrCaseCmp(str, "moveptr") == 0)
64 *type_rtrn = XkbSA_MovePtr;
65 else if (uStrCaseCmp(str, "movepointer") == 0)
66 *type_rtrn = XkbSA_MovePtr;
67 else if (uStrCaseCmp(str, "ptrbtn") == 0)
68 *type_rtrn = XkbSA_PtrBtn;
69 else if (uStrCaseCmp(str, "pointerbutton") == 0)
70 *type_rtrn = XkbSA_PtrBtn;
71 else if (uStrCaseCmp(str, "lockptrbtn") == 0)
72 *type_rtrn = XkbSA_LockPtrBtn;
73 else if (uStrCaseCmp(str, "lockpointerbutton") == 0)
74 *type_rtrn = XkbSA_LockPtrBtn;
75 else if (uStrCaseCmp(str, "lockptrbutton") == 0)
76 *type_rtrn = XkbSA_LockPtrBtn;
77 else if (uStrCaseCmp(str, "lockpointerbtn") == 0)
78 *type_rtrn = XkbSA_LockPtrBtn;
79 else if (uStrCaseCmp(str, "setptrdflt") == 0)
80 *type_rtrn = XkbSA_SetPtrDflt;
81 else if (uStrCaseCmp(str, "setpointerdefault") == 0)
82 *type_rtrn = XkbSA_SetPtrDflt;
83 else if (uStrCaseCmp(str, "isolock") == 0)
84 *type_rtrn = XkbSA_ISOLock;
85 else if (uStrCaseCmp(str, "terminate") == 0)
86 *type_rtrn = XkbSA_Terminate;
87 else if (uStrCaseCmp(str, "terminateserver") == 0)
88 *type_rtrn = XkbSA_Terminate;
89 else if (uStrCaseCmp(str, "switchscreen") == 0)
90 *type_rtrn = XkbSA_SwitchScreen;
91 else if (uStrCaseCmp(str, "setcontrols") == 0)
92 *type_rtrn = XkbSA_SetControls;
93 else if (uStrCaseCmp(str, "lockcontrols") == 0)
94 *type_rtrn = XkbSA_LockControls;
95 else if (uStrCaseCmp(str, "actionmessage") == 0)
96 *type_rtrn = XkbSA_ActionMessage;
97 else if (uStrCaseCmp(str, "messageaction") == 0)
98 *type_rtrn = XkbSA_ActionMessage;
99 else if (uStrCaseCmp(str, "message") == 0)
100 *type_rtrn = XkbSA_ActionMessage;
101 else if (uStrCaseCmp(str, "redirect") == 0)
102 *type_rtrn = XkbSA_RedirectKey;
103 else if (uStrCaseCmp(str, "redirectkey") == 0)
104 *type_rtrn = XkbSA_RedirectKey;
105 else if (uStrCaseCmp(str, "devbtn") == 0)
106 *type_rtrn = XkbSA_DeviceBtn;
107 else if (uStrCaseCmp(str, "devicebtn") == 0)
108 *type_rtrn = XkbSA_DeviceBtn;
109 else if (uStrCaseCmp(str, "devbutton") == 0)
110 *type_rtrn = XkbSA_DeviceBtn;
111 else if (uStrCaseCmp(str, "devicebutton") == 0)
112 *type_rtrn = XkbSA_DeviceBtn;
113 else if (uStrCaseCmp(str, "lockdevbtn") == 0)
114 *type_rtrn = XkbSA_DeviceBtn;
115 else if (uStrCaseCmp(str, "lockdevicebtn") == 0)
116 *type_rtrn = XkbSA_LockDeviceBtn;
117 else if (uStrCaseCmp(str, "lockdevbutton") == 0)
118 *type_rtrn = XkbSA_LockDeviceBtn;
119 else if (uStrCaseCmp(str, "lockdevicebutton") == 0)
120 *type_rtrn = XkbSA_LockDeviceBtn;
121 else if (uStrCaseCmp(str, "devval") == 0)
122 *type_rtrn = XkbSA_DeviceValuator;
123 else if (uStrCaseCmp(str, "deviceval") == 0)
124 *type_rtrn = XkbSA_DeviceValuator;
125 else if (uStrCaseCmp(str, "devvaluator") == 0)
126 *type_rtrn = XkbSA_DeviceValuator;
127 else if (uStrCaseCmp(str, "devicevaluator") == 0)
128 *type_rtrn = XkbSA_DeviceValuator;
129 else if (uStrCaseCmp(str, "private") == 0)
130 *type_rtrn = PrivateAction;
137 stringToField(char *str, unsigned *field_rtrn)
143 if (uStrCaseCmp(str, "clearlocks") == 0)
144 *field_rtrn = F_ClearLocks;
145 else if (uStrCaseCmp(str, "latchtolock") == 0)
146 *field_rtrn = F_LatchToLock;
147 else if (uStrCaseCmp(str, "genkeyevent") == 0)
148 *field_rtrn = F_GenKeyEvent;
149 else if (uStrCaseCmp(str, "generatekeyevent") == 0)
150 *field_rtrn = F_GenKeyEvent;
151 else if (uStrCaseCmp(str, "report") == 0)
152 *field_rtrn = F_Report;
153 else if (uStrCaseCmp(str, "default") == 0)
154 *field_rtrn = F_Default;
155 else if (uStrCaseCmp(str, "affect") == 0)
156 *field_rtrn = F_Affect;
157 else if (uStrCaseCmp(str, "increment") == 0)
158 *field_rtrn = F_Increment;
159 else if (uStrCaseCmp(str, "mods") == 0)
160 *field_rtrn = F_Modifiers;
161 else if (uStrCaseCmp(str, "modifiers") == 0)
162 *field_rtrn = F_Modifiers;
163 else if (uStrCaseCmp(str, "group") == 0)
164 *field_rtrn = F_Group;
165 else if (uStrCaseCmp(str, "x") == 0)
167 else if (uStrCaseCmp(str, "y") == 0)
169 else if (uStrCaseCmp(str, "accel") == 0)
170 *field_rtrn = F_Accel;
171 else if (uStrCaseCmp(str, "accelerate") == 0)
172 *field_rtrn = F_Accel;
173 else if (uStrCaseCmp(str, "repeat") == 0)
174 *field_rtrn = F_Accel;
175 else if (uStrCaseCmp(str, "button") == 0)
176 *field_rtrn = F_Button;
177 else if (uStrCaseCmp(str, "value") == 0)
178 *field_rtrn = F_Value;
179 else if (uStrCaseCmp(str, "controls") == 0)
180 *field_rtrn = F_Controls;
181 else if (uStrCaseCmp(str, "ctrls") == 0)
182 *field_rtrn = F_Controls;
183 else if (uStrCaseCmp(str, "type") == 0)
184 *field_rtrn = F_Type;
185 else if (uStrCaseCmp(str, "count") == 0)
186 *field_rtrn = F_Count;
187 else if (uStrCaseCmp(str, "screen") == 0)
188 *field_rtrn = F_Screen;
189 else if (uStrCaseCmp(str, "same") == 0)
190 *field_rtrn = F_Same;
191 else if (uStrCaseCmp(str, "sameserver") == 0)
192 *field_rtrn = F_Same;
193 else if (uStrCaseCmp(str, "data") == 0)
194 *field_rtrn = F_Data;
195 else if (uStrCaseCmp(str, "device") == 0)
196 *field_rtrn = F_Device;
197 else if (uStrCaseCmp(str, "dev") == 0)
198 *field_rtrn = F_Device;
199 else if (uStrCaseCmp(str, "key") == 0)
200 *field_rtrn = F_Keycode;
201 else if (uStrCaseCmp(str, "keycode") == 0)
202 *field_rtrn = F_Keycode;
203 else if (uStrCaseCmp(str, "kc") == 0)
204 *field_rtrn = F_Keycode;
205 else if (uStrCaseCmp(str, "clearmods") == 0)
206 *field_rtrn = F_ModsToClear;
207 else if (uStrCaseCmp(str, "clearmodifiers") == 0)
208 *field_rtrn = F_ModsToClear;
215 fieldText(unsigned field)
222 strcpy(buf, "clearLocks");
225 strcpy(buf, "latchToLock");
228 strcpy(buf, "genKeyEvent");
231 strcpy(buf, "report");
234 strcpy(buf, "default");
237 strcpy(buf, "affect");
240 strcpy(buf, "increment");
243 strcpy(buf, "modifiers");
246 strcpy(buf, "group");
255 strcpy(buf, "accel");
258 strcpy(buf, "button");
261 strcpy(buf, "value");
264 strcpy(buf, "controls");
270 strcpy(buf, "count");
273 strcpy(buf, "screen");
276 strcpy(buf, "sameServer");
282 strcpy(buf, "device");
285 strcpy(buf, "keycode");
288 strcpy(buf, "clearmods");
291 strcpy(buf, "unknown");
297 /***====================================================================***/
300 ReportMismatch(unsigned action, unsigned field, const char *type)
302 ERROR("Value of %s field must be of type %s\n", fieldText(field), type);
303 ACTION("Action %s definition ignored\n", XkbcActionTypeText(action));
308 ReportIllegal(unsigned action, unsigned field)
310 ERROR("Field %s is not defined for an action of type %s\n",
311 fieldText(field), XkbcActionTypeText(action));
312 ACTION("Action definition ignored\n");
317 ReportActionNotArray(unsigned action, unsigned field)
319 ERROR("The %s field in the %s action is not an array\n",
320 fieldText(field), XkbcActionTypeText(action));
321 ACTION("Action definition ignored\n");
326 ReportNotFound(unsigned action, unsigned field, const char *what, char *bad)
328 ERROR("%s named %s not found\n", what, bad);
329 ACTION("Ignoring the %s field of an %s action\n", fieldText(field),
330 XkbcActionTypeText(action));
335 HandleNoAction(struct xkb_desc * xkb,
336 struct xkb_any_action * action,
337 unsigned field, ExprDef * array_ndx, ExprDef * value)
339 return ReportIllegal(action->type, field);
343 CheckLatchLockFlags(unsigned action,
344 unsigned field, ExprDef * value, unsigned *flags_inout)
349 if (field == F_ClearLocks)
350 tmp = XkbSA_ClearLocks;
351 else if (field == F_LatchToLock)
352 tmp = XkbSA_LatchToLock;
354 return False; /* WSGO! */
355 if (!ExprResolveBoolean(value, &result))
356 return ReportMismatch(action, field, "boolean");
360 *flags_inout &= ~tmp;
365 CheckModifierField(struct xkb_desc * xkb,
368 unsigned *flags_inout, unsigned *mods_rtrn)
372 if (value->op == ExprIdent)
375 valStr = XkbcAtomText(value->value.str);
376 if (valStr && ((uStrCaseCmp(valStr, "usemodmapmods") == 0) ||
377 (uStrCaseCmp(valStr, "modmapmods") == 0)))
381 *flags_inout |= XkbSA_UseModMapMods;
385 if (!ExprResolveVModMask(value, &rtrn, xkb))
386 return ReportMismatch(action, F_Modifiers, "modifier mask");
387 *mods_rtrn = rtrn.uval;
388 *flags_inout &= ~XkbSA_UseModMapMods;
393 HandleSetLatchMods(struct xkb_desc * xkb,
394 struct xkb_any_action * action,
395 unsigned field, ExprDef * array_ndx, ExprDef * value)
397 struct xkb_mod_action *act;
401 act = (struct xkb_mod_action *) action;
402 if (array_ndx != NULL)
409 return ReportActionNotArray(action->type, field);
417 if (CheckLatchLockFlags(action->type, field, value, &rtrn))
425 if (CheckModifierField(xkb, action->type, value, &t1, &t2))
428 act->real_mods = act->mask = (t2 & 0xff);
429 act->vmods = (t2 >> 8) & 0xffff;
434 return ReportIllegal(action->type, field);
438 HandleLockMods(struct xkb_desc * xkb,
439 struct xkb_any_action * action,
440 unsigned field, ExprDef * array_ndx, ExprDef * value)
442 struct xkb_mod_action *act;
445 act = (struct xkb_mod_action *) action;
446 if ((array_ndx != NULL) && (field == F_Modifiers))
447 return ReportActionNotArray(action->type, field);
452 if (CheckModifierField(xkb, action->type, value, &t1, &t2))
455 act->real_mods = act->mask = (t2 & 0xff);
456 act->vmods = (t2 >> 8) & 0xffff;
461 return ReportIllegal(action->type, field);
465 CheckGroupField(unsigned action,
466 ExprDef * value, unsigned *flags_inout, int *grp_rtrn)
471 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
473 *flags_inout &= ~XkbSA_GroupAbsolute;
474 spec = value->value.child;
478 *flags_inout |= XkbSA_GroupAbsolute;
482 if (!ExprResolveGroup(spec, &rtrn))
483 return ReportMismatch(action, F_Group, "integer (range 1..8)");
484 if (value->op == OpNegate)
485 *grp_rtrn = -rtrn.ival;
486 else if (value->op == OpUnaryPlus)
487 *grp_rtrn = rtrn.ival;
489 *grp_rtrn = rtrn.ival - 1;
494 HandleSetLatchGroup(struct xkb_desc * xkb,
495 struct xkb_any_action * action,
496 unsigned field, ExprDef * array_ndx, ExprDef * value)
498 struct xkb_group_action *act;
503 act = (struct xkb_group_action *) action;
504 if (array_ndx != NULL)
511 return ReportActionNotArray(action->type, field);
519 if (CheckLatchLockFlags(action->type, field, value, &rtrn))
527 if (CheckGroupField(action->type, value, &t1, &t2))
535 return ReportIllegal(action->type, field);
539 HandleLockGroup(struct xkb_desc * xkb,
540 struct xkb_any_action * action,
541 unsigned field, ExprDef * array_ndx, ExprDef * value)
543 struct xkb_group_action *act;
547 act = (struct xkb_group_action *) action;
548 if ((array_ndx != NULL) && (field == F_Group))
549 return ReportActionNotArray(action->type, field);
550 if (field == F_Group)
553 if (CheckGroupField(action->type, value, &t1, &t2))
561 return ReportIllegal(action->type, field);
565 HandleMovePtr(struct xkb_desc * xkb,
566 struct xkb_any_action * action,
567 unsigned field, ExprDef * array_ndx, ExprDef * value)
570 struct xkb_pointer_action *act;
573 act = (struct xkb_pointer_action *) action;
574 if ((array_ndx != NULL) && ((field == F_X) || (field == F_Y)))
575 return ReportActionNotArray(action->type, field);
577 if ((field == F_X) || (field == F_Y))
579 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
583 if (!ExprResolveInteger(value, &rtrn))
584 return ReportMismatch(action->type, field, "integer");
588 act->flags |= XkbSA_MoveAbsoluteX;
594 act->flags |= XkbSA_MoveAbsoluteY;
599 else if (field == F_Accel)
601 if (!ExprResolveBoolean(value, &rtrn))
602 return ReportMismatch(action->type, field, "boolean");
604 act->flags &= ~XkbSA_NoAcceleration;
606 act->flags |= XkbSA_NoAcceleration;
608 return ReportIllegal(action->type, field);
611 static LookupEntry lockWhich[] = {
613 {"lock", XkbSA_LockNoUnlock},
614 {"neither", (XkbSA_LockNoLock | XkbSA_LockNoUnlock)},
615 {"unlock", XkbSA_LockNoLock},
620 HandlePtrBtn(struct xkb_desc * xkb,
621 struct xkb_any_action * action,
622 unsigned field, ExprDef * array_ndx, ExprDef * value)
625 struct xkb_pointer_button_action *act;
627 act = (struct xkb_pointer_button_action *) action;
628 if (field == F_Button)
630 if (array_ndx != NULL)
631 return ReportActionNotArray(action->type, field);
632 if (!ExprResolveButton(value, &rtrn))
633 return ReportMismatch(action->type, field,
634 "integer (range 1..5)");
635 if ((rtrn.ival < 0) || (rtrn.ival > 5))
637 ERROR("Button must specify default or be in the range 1..5\n");
638 ACTION("Illegal button value %d ignored\n", rtrn.ival);
641 act->button = rtrn.ival;
644 else if ((action->type == XkbSA_LockPtrBtn) && (field == F_Affect))
646 if (array_ndx != NULL)
647 return ReportActionNotArray(action->type, field);
648 if (!ExprResolveEnum(value, &rtrn, lockWhich))
649 return ReportMismatch(action->type, field, "lock or unlock");
650 act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
651 act->flags |= rtrn.ival;
654 else if (field == F_Count)
656 if (array_ndx != NULL)
657 return ReportActionNotArray(action->type, field);
658 if (!ExprResolveButton(value, &rtrn))
659 return ReportMismatch(action->type, field, "integer");
660 if ((rtrn.ival < 0) || (rtrn.ival > 255))
662 ERROR("The count field must have a value in the range 0..255\n");
663 ACTION("Illegal count %d ignored\n", rtrn.ival);
666 act->count = rtrn.ival;
669 return ReportIllegal(action->type, field);
672 static LookupEntry ptrDflts[] = {
673 {"dfltbtn", XkbSA_AffectDfltBtn},
674 {"defaultbutton", XkbSA_AffectDfltBtn},
675 {"button", XkbSA_AffectDfltBtn},
680 HandleSetPtrDflt(struct xkb_desc * xkb,
681 struct xkb_any_action * action,
682 unsigned field, ExprDef * array_ndx, ExprDef * value)
685 struct xkb_pointer_default_action *act;
687 act = (struct xkb_pointer_default_action *) action;
688 if (field == F_Affect)
690 if (array_ndx != NULL)
691 return ReportActionNotArray(action->type, field);
692 if (!ExprResolveEnum(value, &rtrn, ptrDflts))
693 return ReportMismatch(action->type, field, "pointer component");
694 act->affect = rtrn.uval;
697 else if ((field == F_Button) || (field == F_Value))
700 if (array_ndx != NULL)
701 return ReportActionNotArray(action->type, field);
702 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
704 act->flags &= ~XkbSA_DfltBtnAbsolute;
705 btn = value->value.child;
709 act->flags |= XkbSA_DfltBtnAbsolute;
713 if (!ExprResolveButton(btn, &rtrn))
714 return ReportMismatch(action->type, field,
715 "integer (range 1..5)");
716 if ((rtrn.ival < 0) || (rtrn.ival > 5))
718 ERROR("New default button value must be in the range 1..5\n");
719 ACTION("Illegal default button value %d ignored\n", rtrn.ival);
724 ERROR("Cannot set default pointer button to \"default\"\n");
725 ACTION("Illegal default button setting ignored\n");
728 if (value->op == OpNegate)
729 act->value = -rtrn.ival;
731 act->value = rtrn.ival;
734 return ReportIllegal(action->type, field);
737 static LookupEntry isoNames[] = {
738 {"mods", XkbSA_ISONoAffectMods},
739 {"modifiers", XkbSA_ISONoAffectMods},
740 {"group", XkbSA_ISONoAffectGroup},
741 {"groups", XkbSA_ISONoAffectGroup},
742 {"ptr", XkbSA_ISONoAffectPtr},
743 {"pointer", XkbSA_ISONoAffectPtr},
744 {"ctrls", XkbSA_ISONoAffectCtrls},
745 {"controls", XkbSA_ISONoAffectCtrls},
746 {"all", ~((unsigned) 0)},
752 HandleISOLock(struct xkb_desc * xkb,
753 struct xkb_any_action * action,
754 unsigned field, ExprDef * array_ndx, ExprDef * value)
757 struct xkb_iso_action *act;
758 unsigned flags, mods;
761 act = (struct xkb_iso_action *) action;
765 if (array_ndx != NULL)
766 return ReportActionNotArray(action->type, field);
768 if (CheckModifierField(xkb, action->type, value, &flags, &mods))
770 act->flags = flags & (~XkbSA_ISODfltIsGroup);
771 act->real_mods = mods & 0xff;
772 act->vmods = (mods >> 8) & 0xff;
777 if (array_ndx != NULL)
778 return ReportActionNotArray(action->type, field);
780 if (CheckGroupField(action->type, value, &flags, &group))
782 act->flags = flags | XkbSA_ISODfltIsGroup;
788 if (array_ndx != NULL)
789 return ReportActionNotArray(action->type, field);
790 if (!ExprResolveMask(value, &rtrn, isoNames))
791 return ReportMismatch(action->type, field, "keyboard component");
792 act->affect = (~rtrn.uval) & XkbSA_ISOAffectMask;
795 return ReportIllegal(action->type, field);
799 HandleSwitchScreen(struct xkb_desc * xkb,
800 struct xkb_any_action * action,
801 unsigned field, ExprDef * array_ndx, ExprDef * value)
804 struct xkb_switch_screen_action *act;
806 act = (struct xkb_switch_screen_action *) action;
807 if (field == F_Screen)
810 if (array_ndx != NULL)
811 return ReportActionNotArray(action->type, field);
812 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
814 act->flags &= ~XkbSA_SwitchAbsolute;
815 scrn = value->value.child;
819 act->flags |= XkbSA_SwitchAbsolute;
823 if (!ExprResolveInteger(scrn, &rtrn))
824 return ReportMismatch(action->type, field, "integer (0..255)");
825 if ((rtrn.ival < 0) || (rtrn.ival > 255))
827 ERROR("Screen index must be in the range 1..255\n");
828 ACTION("Illegal screen value %d ignored\n", rtrn.ival);
831 if (value->op == OpNegate)
832 act->screen = -rtrn.ival;
834 act->screen = rtrn.ival;
837 else if (field == F_Same)
839 if (array_ndx != NULL)
840 return ReportActionNotArray(action->type, field);
841 if (!ExprResolveBoolean(value, &rtrn))
842 return ReportMismatch(action->type, field, "boolean");
844 act->flags &= ~XkbSA_SwitchApplication;
846 act->flags |= XkbSA_SwitchApplication;
849 return ReportIllegal(action->type, field);
852 LookupEntry ctrlNames[] = {
853 {"repeatkeys", XkbRepeatKeysMask}
855 {"repeat", XkbRepeatKeysMask}
857 {"autorepeat", XkbRepeatKeysMask}
859 {"slowkeys", XkbSlowKeysMask}
861 {"bouncekeys", XkbBounceKeysMask}
863 {"stickykeys", XkbStickyKeysMask}
865 {"mousekeys", XkbMouseKeysMask}
867 {"mousekeysaccel", XkbMouseKeysAccelMask}
869 {"accessxkeys", XkbAccessXKeysMask}
871 {"accessxtimeout", XkbAccessXTimeoutMask}
873 {"accessxfeedback", XkbAccessXFeedbackMask}
875 {"audiblebell", XkbAudibleBellMask}
877 {"overlay1", XkbOverlay1Mask}
879 {"overlay2", XkbOverlay2Mask}
881 {"ignoregrouplock", XkbIgnoreGroupLockMask}
883 {"all", XkbAllBooleanCtrlsMask}
891 HandleSetLockControls(struct xkb_desc * xkb,
892 struct xkb_any_action * action,
893 unsigned field, ExprDef * array_ndx, ExprDef * value)
896 struct xkb_controls_action *act;
898 act = (struct xkb_controls_action *) action;
899 if (field == F_Controls)
901 if (array_ndx != NULL)
902 return ReportActionNotArray(action->type, field);
903 if (!ExprResolveMask(value, &rtrn, ctrlNames))
904 return ReportMismatch(action->type, field, "controls mask");
905 act->ctrls = rtrn.uval;
908 return ReportIllegal(action->type, field);
911 static LookupEntry evNames[] = {
912 {"press", XkbSA_MessageOnPress},
913 {"keypress", XkbSA_MessageOnPress},
914 {"release", XkbSA_MessageOnRelease},
915 {"keyrelease", XkbSA_MessageOnRelease},
916 {"all", XkbSA_MessageOnPress | XkbSA_MessageOnRelease},
922 HandleActionMessage(struct xkb_desc * xkb,
923 struct xkb_any_action * action,
924 unsigned field, ExprDef * array_ndx, ExprDef * value)
927 struct xkb_message_action *act;
929 act = (struct xkb_message_action *) action;
933 if (array_ndx != NULL)
934 return ReportActionNotArray(action->type, field);
935 if (!ExprResolveMask(value, &rtrn, evNames))
936 return ReportMismatch(action->type, field, "key event mask");
937 act->flags &= ~(XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
939 rtrn.uval & (XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
942 if (array_ndx != NULL)
943 return ReportActionNotArray(action->type, field);
944 if (!ExprResolveBoolean(value, &rtrn))
945 return ReportMismatch(action->type, field, "boolean");
947 act->flags |= XkbSA_MessageGenKeyEvent;
949 act->flags &= ~XkbSA_MessageGenKeyEvent;
952 if (array_ndx == NULL)
954 if (!ExprResolveString(value, &rtrn))
955 return ReportMismatch(action->type, field, "string");
958 int len = strlen(rtrn.str);
959 if ((len < 1) || (len > 6))
961 WARN("An action message can hold only 6 bytes\n");
962 ACTION("Extra %d bytes ignored\n", len - 6);
964 strncpy((char *) act->message, rtrn.str, 6);
971 if (!ExprResolveInteger(array_ndx, &rtrn))
973 ERROR("Array subscript must be integer\n");
974 ACTION("Illegal subscript ignored\n");
980 ERROR("An action message is at most 6 bytes long\n");
981 ACTION("Attempt to use data[%d] ignored\n", ndx);
984 if (!ExprResolveInteger(value, &rtrn))
985 return ReportMismatch(action->type, field, "integer");
986 if ((rtrn.ival < 0) || (rtrn.ival > 255))
988 ERROR("Message data must be in the range 0..255\n");
989 ACTION("Illegal datum %d ignored\n", rtrn.ival);
992 act->message[ndx] = rtrn.uval;
996 return ReportIllegal(action->type, field);
1000 HandleRedirectKey(struct xkb_desc * xkb,
1001 struct xkb_any_action * action,
1002 unsigned field, ExprDef * array_ndx, ExprDef * value)
1005 struct xkb_redirect_key_action *act;
1010 if (array_ndx != NULL)
1011 return ReportActionNotArray(action->type, field);
1013 act = (struct xkb_redirect_key_action *) action;
1017 if (!ExprResolveKeyName(value, &rtrn))
1018 return ReportMismatch(action->type, field, "key name");
1019 tmp = KeyNameToLong(rtrn.keyName.name);
1020 if (!FindNamedKey(xkb, tmp, &kc, True, CreateKeyNames(xkb), 0))
1022 return ReportNotFound(action->type, field, "Key",
1023 XkbcKeyNameText(rtrn.keyName.name));
1030 if (CheckModifierField(xkb, action->type, value, &t1, &t2))
1032 act->mods_mask |= (t2 & 0xff);
1033 if (field == F_Modifiers)
1034 act->mods |= (t2 & 0xff);
1036 act->mods &= ~(t2 & 0xff);
1038 t2 = (t2 >> 8) & 0xffff;
1039 act->vmods_mask |= t2;
1040 if (field == F_Modifiers)
1048 return ReportIllegal(action->type, field);
1052 HandleDeviceBtn(struct xkb_desc * xkb,
1053 struct xkb_any_action * action,
1054 unsigned field, ExprDef * array_ndx, ExprDef * value)
1057 struct xkb_device_button_action *act;
1059 act = (struct xkb_device_button_action *) action;
1060 if (field == F_Button)
1062 if (array_ndx != NULL)
1063 return ReportActionNotArray(action->type, field);
1064 if (!ExprResolveInteger(value, &rtrn))
1065 return ReportMismatch(action->type, field,
1066 "integer (range 1..255)");
1067 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1069 ERROR("Button must specify default or be in the range 1..255\n");
1070 ACTION("Illegal button value %d ignored\n", rtrn.ival);
1073 act->button = rtrn.ival;
1076 else if ((action->type == XkbSA_LockDeviceBtn) && (field == F_Affect))
1078 if (array_ndx != NULL)
1079 return ReportActionNotArray(action->type, field);
1080 if (!ExprResolveEnum(value, &rtrn, lockWhich))
1081 return ReportMismatch(action->type, field, "lock or unlock");
1082 act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
1083 act->flags |= rtrn.ival;
1086 else if (field == F_Count)
1088 if (array_ndx != NULL)
1089 return ReportActionNotArray(action->type, field);
1090 if (!ExprResolveButton(value, &rtrn))
1091 return ReportMismatch(action->type, field, "integer");
1092 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1094 ERROR("The count field must have a value in the range 0..255\n");
1095 ACTION("Illegal count %d ignored\n", rtrn.ival);
1098 act->count = rtrn.ival;
1101 else if (field == F_Device)
1103 if (array_ndx != NULL)
1104 return ReportActionNotArray(action->type, field);
1105 if (!ExprResolveInteger(value, &rtrn))
1106 return ReportMismatch(action->type, field,
1107 "integer (range 1..255)");
1108 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1110 ERROR("Device must specify default or be in the range 1..255\n");
1111 ACTION("Illegal device value %d ignored\n", rtrn.ival);
1114 act->device = rtrn.ival;
1117 return ReportIllegal(action->type, field);
1121 HandleDeviceValuator(struct xkb_desc * xkb,
1122 struct xkb_any_action * action,
1123 unsigned field, ExprDef * array_ndx, ExprDef * value)
1127 struct xkb_device_valuator_action *act;
1129 act = (struct xkb_device_valuator_action *) action;
1130 /* XXX - Not yet implemented */
1136 HandlePrivate(struct xkb_desc * xkb,
1137 struct xkb_any_action * action,
1138 unsigned field, ExprDef * array_ndx, ExprDef * value)
1145 if (!ExprResolveInteger(value, &rtrn))
1146 return ReportMismatch(PrivateAction, field, "integer");
1147 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1149 ERROR("Private action type must be in the range 0..255\n");
1150 ACTION("Illegal type %d ignored\n", rtrn.ival);
1153 action->type = rtrn.uval;
1156 if (array_ndx == NULL)
1158 if (!ExprResolveString(value, &rtrn))
1159 return ReportMismatch(action->type, field, "string");
1162 int len = strlen(rtrn.str);
1163 if ((len < 1) || (len > 7))
1165 WARN("A private action has 7 data bytes\n");
1166 ACTION("Extra %d bytes ignored\n", len - 6);
1169 strncpy((char *) action->data, rtrn.str, sizeof action->data);
1177 if (!ExprResolveInteger(array_ndx, &rtrn))
1179 ERROR("Array subscript must be integer\n");
1180 ACTION("Illegal subscript ignored\n");
1184 if (ndx >= sizeof action->data)
1186 ERROR("The data for a private action is 18 bytes long\n");
1187 ACTION("Attempt to use data[%d] ignored\n", ndx);
1190 if (!ExprResolveInteger(value, &rtrn))
1191 return ReportMismatch(action->type, field, "integer");
1192 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1194 ERROR("All data for a private action must be 0..255\n");
1195 ACTION("Illegal datum %d ignored\n", rtrn.ival);
1198 action->data[ndx] = rtrn.uval;
1202 return ReportIllegal(PrivateAction, field);
1205 typedef Bool(*actionHandler) (struct xkb_desc * /* xkb */ ,
1206 struct xkb_any_action * /* action */ ,
1207 unsigned /* field */ ,
1208 ExprDef * /* array_ndx */ ,
1209 ExprDef * /* value */
1212 static actionHandler handleAction[XkbSA_NumActions + 1] = {
1213 HandleNoAction /* NoAction */ ,
1214 HandleSetLatchMods /* SetMods */ ,
1215 HandleSetLatchMods /* LatchMods */ ,
1216 HandleLockMods /* LockMods */ ,
1217 HandleSetLatchGroup /* SetGroup */ ,
1218 HandleSetLatchGroup /* LatchGroup */ ,
1219 HandleLockGroup /* LockGroup */ ,
1220 HandleMovePtr /* MovePtr */ ,
1221 HandlePtrBtn /* PtrBtn */ ,
1222 HandlePtrBtn /* LockPtrBtn */ ,
1223 HandleSetPtrDflt /* SetPtrDflt */ ,
1224 HandleISOLock /* ISOLock */ ,
1225 HandleNoAction /* Terminate */ ,
1226 HandleSwitchScreen /* SwitchScreen */ ,
1227 HandleSetLockControls /* SetControls */ ,
1228 HandleSetLockControls /* LockControls */ ,
1229 HandleActionMessage /* ActionMessage */ ,
1230 HandleRedirectKey /* RedirectKey */ ,
1231 HandleDeviceBtn /* DeviceBtn */ ,
1232 HandleDeviceBtn /* LockDeviceBtn */ ,
1233 HandleDeviceValuator /* DeviceValuatr */ ,
1234 HandlePrivate /* Private */
1237 /***====================================================================***/
1240 ApplyActionFactoryDefaults(union xkb_action * action)
1242 if (action->type == XkbSA_SetPtrDflt)
1243 { /* increment default button */
1244 action->dflt.affect = XkbSA_AffectDfltBtn;
1245 action->dflt.flags = 0;
1246 action->dflt.value = 1;
1248 else if (action->type == XkbSA_ISOLock)
1250 action->iso.real_mods = LockMask;
1259 HandleActionDef(ExprDef * def,
1260 struct xkb_desc * xkb,
1261 struct xkb_any_action * action, unsigned mergeMode, ActionInfo * info)
1265 unsigned tmp, hndlrType;
1267 if (!actionsInitialized)
1270 if (def->op != ExprActionDecl)
1272 ERROR("Expected an action definition, found %s\n",
1273 exprOpText(def->op));
1276 str = XkbcAtomText(def->value.action.name);
1279 WSGO("Missing name in action definition!!\n");
1282 if (!stringToAction(str, &tmp))
1284 ERROR("Unknown action %s\n", str);
1287 action->type = hndlrType = tmp;
1288 if (action->type != XkbSA_NoAction)
1290 ApplyActionFactoryDefaults((union xkb_action *) action);
1293 if ((info->action == XkbSA_NoAction)
1294 || (info->action == hndlrType))
1296 if (!(*handleAction[hndlrType]) (xkb, action,
1307 for (arg = def->value.action.args; arg != NULL;
1308 arg = (ExprDef *) arg->common.next)
1310 ExprDef *field, *value, *arrayRtrn;
1311 ExprResult elemRtrn, fieldRtrn;
1314 if (arg->op == OpAssign)
1316 field = arg->value.binary.left;
1317 value = arg->value.binary.right;
1321 if ((arg->op == OpNot) || (arg->op == OpInvert))
1323 field = arg->value.child;
1324 value = &constFalse;
1332 if (!ExprResolveLhs(field, &elemRtrn, &fieldRtrn, &arrayRtrn))
1333 return False; /* internal error -- already reported */
1335 if (elemRtrn.str != NULL)
1337 ERROR("Cannot change defaults in an action definition\n");
1338 ACTION("Ignoring attempt to change %s.%s\n", elemRtrn.str,
1341 free(fieldRtrn.str);
1344 if (!stringToField(fieldRtrn.str, &fieldNdx))
1346 ERROR("Unknown field name %s\n", uStringText(fieldRtrn.str));
1348 free(fieldRtrn.str);
1352 free(fieldRtrn.str);
1353 if (!(*handleAction[hndlrType])
1354 (xkb, action, fieldNdx, arrayRtrn, value))
1362 /***====================================================================***/
1365 SetActionField(struct xkb_desc * xkb,
1368 ExprDef * array_ndx, ExprDef * value, ActionInfo ** info_rtrn)
1370 ActionInfo *new, *old;
1372 if (!actionsInitialized)
1375 new = uTypedAlloc(ActionInfo);
1378 WSGO("Couldn't allocate space for action default\n");
1381 if (uStrCaseCmp(elem, "action") == 0)
1382 new->action = XkbSA_NoAction;
1385 if (!stringToAction(elem, &new->action))
1390 if (new->action == XkbSA_NoAction)
1392 ERROR("\"%s\" is not a valid field in a NoAction action\n",
1398 if (!stringToField(field, &new->field))
1400 ERROR("\"%s\" is not a legal field name\n", field);
1404 new->array_ndx = array_ndx;
1408 while ((old) && (old->next))
1417 /***====================================================================***/
1422 if (!actionsInitialized)
1424 bzero((char *) &constTrue, sizeof(constTrue));
1425 bzero((char *) &constFalse, sizeof(constFalse));
1426 constTrue.common.stmtType = StmtExpr;
1427 constTrue.common.next = NULL;
1428 constTrue.op = ExprIdent;
1429 constTrue.type = TypeBoolean;
1430 constTrue.value.str = xkb_intern_atom("true");
1431 constFalse.common.stmtType = StmtExpr;
1432 constFalse.common.next = NULL;
1433 constFalse.op = ExprIdent;
1434 constFalse.type = TypeBoolean;
1435 constFalse.value.str = xkb_intern_atom("false");
1436 actionsInitialized = 1;