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 ********************************************************/
38 static Bool actionsInitialized;
39 static ExprDef constTrue;
40 static ExprDef constFalse;
42 /***====================================================================***/
45 stringToAction(const char *str, unsigned *type_rtrn)
50 if (uStrCaseCmp(str, "noaction") == 0)
51 *type_rtrn = XkbSA_NoAction;
52 else if (uStrCaseCmp(str, "setmods") == 0)
53 *type_rtrn = XkbSA_SetMods;
54 else if (uStrCaseCmp(str, "latchmods") == 0)
55 *type_rtrn = XkbSA_LatchMods;
56 else if (uStrCaseCmp(str, "lockmods") == 0)
57 *type_rtrn = XkbSA_LockMods;
58 else if (uStrCaseCmp(str, "setgroup") == 0)
59 *type_rtrn = XkbSA_SetGroup;
60 else if (uStrCaseCmp(str, "latchgroup") == 0)
61 *type_rtrn = XkbSA_LatchGroup;
62 else if (uStrCaseCmp(str, "lockgroup") == 0)
63 *type_rtrn = XkbSA_LockGroup;
64 else if (uStrCaseCmp(str, "moveptr") == 0)
65 *type_rtrn = XkbSA_MovePtr;
66 else if (uStrCaseCmp(str, "movepointer") == 0)
67 *type_rtrn = XkbSA_MovePtr;
68 else if (uStrCaseCmp(str, "ptrbtn") == 0)
69 *type_rtrn = XkbSA_PtrBtn;
70 else if (uStrCaseCmp(str, "pointerbutton") == 0)
71 *type_rtrn = XkbSA_PtrBtn;
72 else if (uStrCaseCmp(str, "lockptrbtn") == 0)
73 *type_rtrn = XkbSA_LockPtrBtn;
74 else if (uStrCaseCmp(str, "lockpointerbutton") == 0)
75 *type_rtrn = XkbSA_LockPtrBtn;
76 else if (uStrCaseCmp(str, "lockptrbutton") == 0)
77 *type_rtrn = XkbSA_LockPtrBtn;
78 else if (uStrCaseCmp(str, "lockpointerbtn") == 0)
79 *type_rtrn = XkbSA_LockPtrBtn;
80 else if (uStrCaseCmp(str, "setptrdflt") == 0)
81 *type_rtrn = XkbSA_SetPtrDflt;
82 else if (uStrCaseCmp(str, "setpointerdefault") == 0)
83 *type_rtrn = XkbSA_SetPtrDflt;
84 else if (uStrCaseCmp(str, "isolock") == 0)
85 *type_rtrn = XkbSA_ISOLock;
86 else if (uStrCaseCmp(str, "terminate") == 0)
87 *type_rtrn = XkbSA_Terminate;
88 else if (uStrCaseCmp(str, "terminateserver") == 0)
89 *type_rtrn = XkbSA_Terminate;
90 else if (uStrCaseCmp(str, "switchscreen") == 0)
91 *type_rtrn = XkbSA_SwitchScreen;
92 else if (uStrCaseCmp(str, "setcontrols") == 0)
93 *type_rtrn = XkbSA_SetControls;
94 else if (uStrCaseCmp(str, "lockcontrols") == 0)
95 *type_rtrn = XkbSA_LockControls;
96 else if (uStrCaseCmp(str, "actionmessage") == 0)
97 *type_rtrn = XkbSA_ActionMessage;
98 else if (uStrCaseCmp(str, "messageaction") == 0)
99 *type_rtrn = XkbSA_ActionMessage;
100 else if (uStrCaseCmp(str, "message") == 0)
101 *type_rtrn = XkbSA_ActionMessage;
102 else if (uStrCaseCmp(str, "redirect") == 0)
103 *type_rtrn = XkbSA_RedirectKey;
104 else if (uStrCaseCmp(str, "redirectkey") == 0)
105 *type_rtrn = XkbSA_RedirectKey;
106 else if (uStrCaseCmp(str, "devbtn") == 0)
107 *type_rtrn = XkbSA_DeviceBtn;
108 else if (uStrCaseCmp(str, "devicebtn") == 0)
109 *type_rtrn = XkbSA_DeviceBtn;
110 else if (uStrCaseCmp(str, "devbutton") == 0)
111 *type_rtrn = XkbSA_DeviceBtn;
112 else if (uStrCaseCmp(str, "devicebutton") == 0)
113 *type_rtrn = XkbSA_DeviceBtn;
114 else if (uStrCaseCmp(str, "lockdevbtn") == 0)
115 *type_rtrn = XkbSA_DeviceBtn;
116 else if (uStrCaseCmp(str, "lockdevicebtn") == 0)
117 *type_rtrn = XkbSA_LockDeviceBtn;
118 else if (uStrCaseCmp(str, "lockdevbutton") == 0)
119 *type_rtrn = XkbSA_LockDeviceBtn;
120 else if (uStrCaseCmp(str, "lockdevicebutton") == 0)
121 *type_rtrn = XkbSA_LockDeviceBtn;
122 else if (uStrCaseCmp(str, "devval") == 0)
123 *type_rtrn = XkbSA_DeviceValuator;
124 else if (uStrCaseCmp(str, "deviceval") == 0)
125 *type_rtrn = XkbSA_DeviceValuator;
126 else if (uStrCaseCmp(str, "devvaluator") == 0)
127 *type_rtrn = XkbSA_DeviceValuator;
128 else if (uStrCaseCmp(str, "devicevaluator") == 0)
129 *type_rtrn = XkbSA_DeviceValuator;
130 else if (uStrCaseCmp(str, "private") == 0)
131 *type_rtrn = PrivateAction;
138 stringToField(char *str, unsigned *field_rtrn)
144 if (uStrCaseCmp(str, "clearlocks") == 0)
145 *field_rtrn = F_ClearLocks;
146 else if (uStrCaseCmp(str, "latchtolock") == 0)
147 *field_rtrn = F_LatchToLock;
148 else if (uStrCaseCmp(str, "genkeyevent") == 0)
149 *field_rtrn = F_GenKeyEvent;
150 else if (uStrCaseCmp(str, "generatekeyevent") == 0)
151 *field_rtrn = F_GenKeyEvent;
152 else if (uStrCaseCmp(str, "report") == 0)
153 *field_rtrn = F_Report;
154 else if (uStrCaseCmp(str, "default") == 0)
155 *field_rtrn = F_Default;
156 else if (uStrCaseCmp(str, "affect") == 0)
157 *field_rtrn = F_Affect;
158 else if (uStrCaseCmp(str, "increment") == 0)
159 *field_rtrn = F_Increment;
160 else if (uStrCaseCmp(str, "mods") == 0)
161 *field_rtrn = F_Modifiers;
162 else if (uStrCaseCmp(str, "modifiers") == 0)
163 *field_rtrn = F_Modifiers;
164 else if (uStrCaseCmp(str, "group") == 0)
165 *field_rtrn = F_Group;
166 else if (uStrCaseCmp(str, "x") == 0)
168 else if (uStrCaseCmp(str, "y") == 0)
170 else if (uStrCaseCmp(str, "accel") == 0)
171 *field_rtrn = F_Accel;
172 else if (uStrCaseCmp(str, "accelerate") == 0)
173 *field_rtrn = F_Accel;
174 else if (uStrCaseCmp(str, "repeat") == 0)
175 *field_rtrn = F_Accel;
176 else if (uStrCaseCmp(str, "button") == 0)
177 *field_rtrn = F_Button;
178 else if (uStrCaseCmp(str, "value") == 0)
179 *field_rtrn = F_Value;
180 else if (uStrCaseCmp(str, "controls") == 0)
181 *field_rtrn = F_Controls;
182 else if (uStrCaseCmp(str, "ctrls") == 0)
183 *field_rtrn = F_Controls;
184 else if (uStrCaseCmp(str, "type") == 0)
185 *field_rtrn = F_Type;
186 else if (uStrCaseCmp(str, "count") == 0)
187 *field_rtrn = F_Count;
188 else if (uStrCaseCmp(str, "screen") == 0)
189 *field_rtrn = F_Screen;
190 else if (uStrCaseCmp(str, "same") == 0)
191 *field_rtrn = F_Same;
192 else if (uStrCaseCmp(str, "sameserver") == 0)
193 *field_rtrn = F_Same;
194 else if (uStrCaseCmp(str, "data") == 0)
195 *field_rtrn = F_Data;
196 else if (uStrCaseCmp(str, "device") == 0)
197 *field_rtrn = F_Device;
198 else if (uStrCaseCmp(str, "dev") == 0)
199 *field_rtrn = F_Device;
200 else if (uStrCaseCmp(str, "key") == 0)
201 *field_rtrn = F_Keycode;
202 else if (uStrCaseCmp(str, "keycode") == 0)
203 *field_rtrn = F_Keycode;
204 else if (uStrCaseCmp(str, "kc") == 0)
205 *field_rtrn = F_Keycode;
206 else if (uStrCaseCmp(str, "clearmods") == 0)
207 *field_rtrn = F_ModsToClear;
208 else if (uStrCaseCmp(str, "clearmodifiers") == 0)
209 *field_rtrn = F_ModsToClear;
216 fieldText(unsigned field)
223 strcpy(buf, "clearLocks");
226 strcpy(buf, "latchToLock");
229 strcpy(buf, "genKeyEvent");
232 strcpy(buf, "report");
235 strcpy(buf, "default");
238 strcpy(buf, "affect");
241 strcpy(buf, "increment");
244 strcpy(buf, "modifiers");
247 strcpy(buf, "group");
256 strcpy(buf, "accel");
259 strcpy(buf, "button");
262 strcpy(buf, "value");
265 strcpy(buf, "controls");
271 strcpy(buf, "count");
274 strcpy(buf, "screen");
277 strcpy(buf, "sameServer");
283 strcpy(buf, "device");
286 strcpy(buf, "keycode");
289 strcpy(buf, "clearmods");
292 strcpy(buf, "unknown");
298 /***====================================================================***/
301 ReportMismatch(unsigned action, unsigned field, const char *type)
303 ERROR("Value of %s field must be of type %s\n", fieldText(field), type);
304 ACTION("Action %s definition ignored\n", XkbcActionTypeText(action));
309 ReportIllegal(unsigned action, unsigned field)
311 ERROR("Field %s is not defined for an action of type %s\n",
312 fieldText(field), XkbcActionTypeText(action));
313 ACTION("Action definition ignored\n");
318 ReportActionNotArray(unsigned action, unsigned field)
320 ERROR("The %s field in the %s action is not an array\n",
321 fieldText(field), XkbcActionTypeText(action));
322 ACTION("Action definition ignored\n");
327 ReportNotFound(unsigned action, unsigned field, const char *what, char *bad)
329 ERROR("%s named %s not found\n", what, bad);
330 ACTION("Ignoring the %s field of an %s action\n", fieldText(field),
331 XkbcActionTypeText(action));
336 HandleNoAction(struct xkb_desc * xkb,
337 struct xkb_any_action * action,
338 unsigned field, ExprDef * array_ndx, ExprDef * value)
340 return ReportIllegal(action->type, field);
344 CheckLatchLockFlags(unsigned action,
345 unsigned field, ExprDef * value, unsigned *flags_inout)
350 if (field == F_ClearLocks)
351 tmp = XkbSA_ClearLocks;
352 else if (field == F_LatchToLock)
353 tmp = XkbSA_LatchToLock;
355 return False; /* WSGO! */
356 if (!ExprResolveBoolean(value, &result))
357 return ReportMismatch(action, field, "boolean");
361 *flags_inout &= ~tmp;
366 CheckModifierField(struct xkb_desc * xkb,
369 unsigned *flags_inout, unsigned *mods_rtrn)
373 if (value->op == ExprIdent)
376 valStr = XkbcAtomText(value->value.str);
377 if (valStr && ((uStrCaseCmp(valStr, "usemodmapmods") == 0) ||
378 (uStrCaseCmp(valStr, "modmapmods") == 0)))
382 *flags_inout |= XkbSA_UseModMapMods;
386 if (!ExprResolveVModMask(value, &rtrn, xkb))
387 return ReportMismatch(action, F_Modifiers, "modifier mask");
388 *mods_rtrn = rtrn.uval;
389 *flags_inout &= ~XkbSA_UseModMapMods;
394 HandleSetLatchMods(struct xkb_desc * xkb,
395 struct xkb_any_action * action,
396 unsigned field, ExprDef * array_ndx, ExprDef * value)
398 struct xkb_mod_action *act;
402 act = (struct xkb_mod_action *) action;
403 if (array_ndx != NULL)
410 return ReportActionNotArray(action->type, field);
418 if (CheckLatchLockFlags(action->type, field, value, &rtrn))
426 if (CheckModifierField(xkb, action->type, value, &t1, &t2))
429 act->real_mods = act->mask = (t2 & 0xff);
430 act->vmods = (t2 >> 8) & 0xffff;
435 return ReportIllegal(action->type, field);
439 HandleLockMods(struct xkb_desc * xkb,
440 struct xkb_any_action * action,
441 unsigned field, ExprDef * array_ndx, ExprDef * value)
443 struct xkb_mod_action *act;
446 act = (struct xkb_mod_action *) action;
447 if ((array_ndx != NULL) && (field == F_Modifiers))
448 return ReportActionNotArray(action->type, field);
453 if (CheckModifierField(xkb, action->type, value, &t1, &t2))
456 act->real_mods = act->mask = (t2 & 0xff);
457 act->vmods = (t2 >> 8) & 0xffff;
462 return ReportIllegal(action->type, field);
465 static LookupEntry groupNames[] = {
478 CheckGroupField(unsigned action,
479 ExprDef * value, unsigned *flags_inout, int *grp_rtrn)
484 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
486 *flags_inout &= ~XkbSA_GroupAbsolute;
487 spec = value->value.child;
491 *flags_inout |= XkbSA_GroupAbsolute;
495 if (!ExprResolveInteger(spec, &rtrn, SimpleLookup, (char *) groupNames))
496 return ReportMismatch(action, F_Group, "integer (range 1..8)");
497 if ((rtrn.ival < 1) || (rtrn.ival > XkbNumKbdGroups))
499 ERROR("Illegal group %d (must be in the range 1..%d)\n", rtrn.ival,
501 ACTION("Action %s definition ignored\n", XkbcActionTypeText(action));
504 if (value->op == OpNegate)
505 *grp_rtrn = -rtrn.ival;
506 else if (value->op == OpUnaryPlus)
507 *grp_rtrn = rtrn.ival;
509 *grp_rtrn = rtrn.ival - 1;
514 HandleSetLatchGroup(struct xkb_desc * xkb,
515 struct xkb_any_action * action,
516 unsigned field, ExprDef * array_ndx, ExprDef * value)
518 struct xkb_group_action *act;
523 act = (struct xkb_group_action *) action;
524 if (array_ndx != NULL)
531 return ReportActionNotArray(action->type, field);
539 if (CheckLatchLockFlags(action->type, field, value, &rtrn))
547 if (CheckGroupField(action->type, value, &t1, &t2))
555 return ReportIllegal(action->type, field);
559 HandleLockGroup(struct xkb_desc * xkb,
560 struct xkb_any_action * action,
561 unsigned field, ExprDef * array_ndx, ExprDef * value)
563 struct xkb_group_action *act;
567 act = (struct xkb_group_action *) action;
568 if ((array_ndx != NULL) && (field == F_Group))
569 return ReportActionNotArray(action->type, field);
570 if (field == F_Group)
573 if (CheckGroupField(action->type, value, &t1, &t2))
581 return ReportIllegal(action->type, field);
585 HandleMovePtr(struct xkb_desc * xkb,
586 struct xkb_any_action * action,
587 unsigned field, ExprDef * array_ndx, ExprDef * value)
590 struct xkb_pointer_action *act;
593 act = (struct xkb_pointer_action *) action;
594 if ((array_ndx != NULL) && ((field == F_X) || (field == F_Y)))
595 return ReportActionNotArray(action->type, field);
597 if ((field == F_X) || (field == F_Y))
599 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
603 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
604 return ReportMismatch(action->type, field, "integer");
608 act->flags |= XkbSA_MoveAbsoluteX;
614 act->flags |= XkbSA_MoveAbsoluteY;
619 else if (field == F_Accel)
621 if (!ExprResolveBoolean(value, &rtrn))
622 return ReportMismatch(action->type, field, "boolean");
624 act->flags &= ~XkbSA_NoAcceleration;
626 act->flags |= XkbSA_NoAcceleration;
628 return ReportIllegal(action->type, field);
631 static LookupEntry lockWhich[] = {
633 {"lock", XkbSA_LockNoUnlock},
634 {"neither", (XkbSA_LockNoLock | XkbSA_LockNoUnlock)},
635 {"unlock", XkbSA_LockNoLock},
640 HandlePtrBtn(struct xkb_desc * xkb,
641 struct xkb_any_action * action,
642 unsigned field, ExprDef * array_ndx, ExprDef * value)
645 struct xkb_pointer_button_action *act;
647 act = (struct xkb_pointer_button_action *) action;
648 if (field == F_Button)
650 if (array_ndx != NULL)
651 return ReportActionNotArray(action->type, field);
652 if (!ExprResolveButton(value, &rtrn))
653 return ReportMismatch(action->type, field,
654 "integer (range 1..5)");
655 if ((rtrn.ival < 0) || (rtrn.ival > 5))
657 ERROR("Button must specify default or be in the range 1..5\n");
658 ACTION("Illegal button value %d ignored\n", rtrn.ival);
661 act->button = rtrn.ival;
664 else if ((action->type == XkbSA_LockPtrBtn) && (field == F_Affect))
666 if (array_ndx != NULL)
667 return ReportActionNotArray(action->type, field);
668 if (!ExprResolveEnum(value, &rtrn, lockWhich))
669 return ReportMismatch(action->type, field, "lock or unlock");
670 act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
671 act->flags |= rtrn.ival;
674 else if (field == F_Count)
676 if (array_ndx != NULL)
677 return ReportActionNotArray(action->type, field);
678 if (!ExprResolveButton(value, &rtrn))
679 return ReportMismatch(action->type, field, "integer");
680 if ((rtrn.ival < 0) || (rtrn.ival > 255))
682 ERROR("The count field must have a value in the range 0..255\n");
683 ACTION("Illegal count %d ignored\n", rtrn.ival);
686 act->count = rtrn.ival;
689 return ReportIllegal(action->type, field);
692 static LookupEntry ptrDflts[] = {
693 {"dfltbtn", XkbSA_AffectDfltBtn},
694 {"defaultbutton", XkbSA_AffectDfltBtn},
695 {"button", XkbSA_AffectDfltBtn},
700 HandleSetPtrDflt(struct xkb_desc * xkb,
701 struct xkb_any_action * action,
702 unsigned field, ExprDef * array_ndx, ExprDef * value)
705 struct xkb_pointer_default_action *act;
707 act = (struct xkb_pointer_default_action *) action;
708 if (field == F_Affect)
710 if (array_ndx != NULL)
711 return ReportActionNotArray(action->type, field);
712 if (!ExprResolveEnum(value, &rtrn, ptrDflts))
713 return ReportMismatch(action->type, field, "pointer component");
714 act->affect = rtrn.uval;
717 else if ((field == F_Button) || (field == F_Value))
720 if (array_ndx != NULL)
721 return ReportActionNotArray(action->type, field);
722 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
724 act->flags &= ~XkbSA_DfltBtnAbsolute;
725 btn = value->value.child;
729 act->flags |= XkbSA_DfltBtnAbsolute;
733 if (!ExprResolveButton(btn, &rtrn))
734 return ReportMismatch(action->type, field,
735 "integer (range 1..5)");
736 if ((rtrn.ival < 0) || (rtrn.ival > 5))
738 ERROR("New default button value must be in the range 1..5\n");
739 ACTION("Illegal default button value %d ignored\n", rtrn.ival);
744 ERROR("Cannot set default pointer button to \"default\"\n");
745 ACTION("Illegal default button setting ignored\n");
748 if (value->op == OpNegate)
749 act->value = -rtrn.ival;
751 act->value = rtrn.ival;
754 return ReportIllegal(action->type, field);
757 static LookupEntry isoNames[] = {
758 {"mods", XkbSA_ISONoAffectMods},
759 {"modifiers", XkbSA_ISONoAffectMods},
760 {"group", XkbSA_ISONoAffectGroup},
761 {"groups", XkbSA_ISONoAffectGroup},
762 {"ptr", XkbSA_ISONoAffectPtr},
763 {"pointer", XkbSA_ISONoAffectPtr},
764 {"ctrls", XkbSA_ISONoAffectCtrls},
765 {"controls", XkbSA_ISONoAffectCtrls},
766 {"all", ~((unsigned) 0)},
772 HandleISOLock(struct xkb_desc * xkb,
773 struct xkb_any_action * action,
774 unsigned field, ExprDef * array_ndx, ExprDef * value)
777 struct xkb_iso_action *act;
778 unsigned flags, mods;
781 act = (struct xkb_iso_action *) action;
785 if (array_ndx != NULL)
786 return ReportActionNotArray(action->type, field);
788 if (CheckModifierField(xkb, action->type, value, &flags, &mods))
790 act->flags = flags & (~XkbSA_ISODfltIsGroup);
791 act->real_mods = mods & 0xff;
792 act->vmods = (mods >> 8) & 0xff;
797 if (array_ndx != NULL)
798 return ReportActionNotArray(action->type, field);
800 if (CheckGroupField(action->type, value, &flags, &group))
802 act->flags = flags | XkbSA_ISODfltIsGroup;
808 if (array_ndx != NULL)
809 return ReportActionNotArray(action->type, field);
810 if (!ExprResolveMask(value, &rtrn, SimpleLookup, (char *) isoNames))
811 return ReportMismatch(action->type, field, "keyboard component");
812 act->affect = (~rtrn.uval) & XkbSA_ISOAffectMask;
815 return ReportIllegal(action->type, field);
819 HandleSwitchScreen(struct xkb_desc * xkb,
820 struct xkb_any_action * action,
821 unsigned field, ExprDef * array_ndx, ExprDef * value)
824 struct xkb_switch_screen_action *act;
826 act = (struct xkb_switch_screen_action *) action;
827 if (field == F_Screen)
830 if (array_ndx != NULL)
831 return ReportActionNotArray(action->type, field);
832 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
834 act->flags &= ~XkbSA_SwitchAbsolute;
835 scrn = value->value.child;
839 act->flags |= XkbSA_SwitchAbsolute;
843 if (!ExprResolveInteger(scrn, &rtrn, NULL, NULL))
844 return ReportMismatch(action->type, field, "integer (0..255)");
845 if ((rtrn.ival < 0) || (rtrn.ival > 255))
847 ERROR("Screen index must be in the range 1..255\n");
848 ACTION("Illegal screen value %d ignored\n", rtrn.ival);
851 if (value->op == OpNegate)
852 act->screen = -rtrn.ival;
854 act->screen = rtrn.ival;
857 else if (field == F_Same)
859 if (array_ndx != NULL)
860 return ReportActionNotArray(action->type, field);
861 if (!ExprResolveBoolean(value, &rtrn))
862 return ReportMismatch(action->type, field, "boolean");
864 act->flags &= ~XkbSA_SwitchApplication;
866 act->flags |= XkbSA_SwitchApplication;
869 return ReportIllegal(action->type, field);
872 LookupEntry ctrlNames[] = {
873 {"repeatkeys", XkbRepeatKeysMask}
875 {"repeat", XkbRepeatKeysMask}
877 {"autorepeat", XkbRepeatKeysMask}
879 {"slowkeys", XkbSlowKeysMask}
881 {"bouncekeys", XkbBounceKeysMask}
883 {"stickykeys", XkbStickyKeysMask}
885 {"mousekeys", XkbMouseKeysMask}
887 {"mousekeysaccel", XkbMouseKeysAccelMask}
889 {"accessxkeys", XkbAccessXKeysMask}
891 {"accessxtimeout", XkbAccessXTimeoutMask}
893 {"accessxfeedback", XkbAccessXFeedbackMask}
895 {"audiblebell", XkbAudibleBellMask}
897 {"overlay1", XkbOverlay1Mask}
899 {"overlay2", XkbOverlay2Mask}
901 {"ignoregrouplock", XkbIgnoreGroupLockMask}
903 {"all", XkbAllBooleanCtrlsMask}
911 HandleSetLockControls(struct xkb_desc * xkb,
912 struct xkb_any_action * action,
913 unsigned field, ExprDef * array_ndx, ExprDef * value)
916 struct xkb_controls_action *act;
918 act = (struct xkb_controls_action *) action;
919 if (field == F_Controls)
921 if (array_ndx != NULL)
922 return ReportActionNotArray(action->type, field);
924 (value, &rtrn, SimpleLookup, (char *) ctrlNames))
925 return ReportMismatch(action->type, field, "controls mask");
926 act->ctrls = rtrn.uval;
929 return ReportIllegal(action->type, field);
932 static LookupEntry evNames[] = {
933 {"press", XkbSA_MessageOnPress},
934 {"keypress", XkbSA_MessageOnPress},
935 {"release", XkbSA_MessageOnRelease},
936 {"keyrelease", XkbSA_MessageOnRelease},
937 {"all", XkbSA_MessageOnPress | XkbSA_MessageOnRelease},
943 HandleActionMessage(struct xkb_desc * xkb,
944 struct xkb_any_action * action,
945 unsigned field, ExprDef * array_ndx, ExprDef * value)
948 struct xkb_message_action *act;
950 act = (struct xkb_message_action *) action;
954 if (array_ndx != NULL)
955 return ReportActionNotArray(action->type, field);
956 if (!ExprResolveMask(value, &rtrn, SimpleLookup, (char *) evNames))
957 return ReportMismatch(action->type, field, "key event mask");
958 act->flags &= ~(XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
960 rtrn.uval & (XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
963 if (array_ndx != NULL)
964 return ReportActionNotArray(action->type, field);
965 if (!ExprResolveBoolean(value, &rtrn))
966 return ReportMismatch(action->type, field, "boolean");
968 act->flags |= XkbSA_MessageGenKeyEvent;
970 act->flags &= ~XkbSA_MessageGenKeyEvent;
973 if (array_ndx == NULL)
975 if (!ExprResolveString(value, &rtrn))
976 return ReportMismatch(action->type, field, "string");
979 int len = strlen(rtrn.str);
980 if ((len < 1) || (len > 6))
982 WARN("An action message can hold only 6 bytes\n");
983 ACTION("Extra %d bytes ignored\n", len - 6);
985 strncpy((char *) act->message, rtrn.str, 6);
992 if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL))
994 ERROR("Array subscript must be integer\n");
995 ACTION("Illegal subscript ignored\n");
1001 ERROR("An action message is at most 6 bytes long\n");
1002 ACTION("Attempt to use data[%d] ignored\n", ndx);
1005 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1006 return ReportMismatch(action->type, field, "integer");
1007 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1009 ERROR("Message data must be in the range 0..255\n");
1010 ACTION("Illegal datum %d ignored\n", rtrn.ival);
1013 act->message[ndx] = rtrn.uval;
1017 return ReportIllegal(action->type, field);
1021 HandleRedirectKey(struct xkb_desc * xkb,
1022 struct xkb_any_action * action,
1023 unsigned field, ExprDef * array_ndx, ExprDef * value)
1026 struct xkb_redirect_key_action *act;
1031 if (array_ndx != NULL)
1032 return ReportActionNotArray(action->type, field);
1034 act = (struct xkb_redirect_key_action *) action;
1038 if (!ExprResolveKeyName(value, &rtrn))
1039 return ReportMismatch(action->type, field, "key name");
1040 tmp = KeyNameToLong(rtrn.keyName.name);
1041 if (!FindNamedKey(xkb, tmp, &kc, True, CreateKeyNames(xkb), 0))
1043 return ReportNotFound(action->type, field, "Key",
1044 XkbcKeyNameText(rtrn.keyName.name));
1051 if (CheckModifierField(xkb, action->type, value, &t1, &t2))
1053 act->mods_mask |= (t2 & 0xff);
1054 if (field == F_Modifiers)
1055 act->mods |= (t2 & 0xff);
1057 act->mods &= ~(t2 & 0xff);
1059 t2 = (t2 >> 8) & 0xffff;
1060 act->vmods_mask |= t2;
1061 if (field == F_Modifiers)
1069 return ReportIllegal(action->type, field);
1073 HandleDeviceBtn(struct xkb_desc * xkb,
1074 struct xkb_any_action * action,
1075 unsigned field, ExprDef * array_ndx, ExprDef * value)
1078 struct xkb_device_button_action *act;
1080 act = (struct xkb_device_button_action *) action;
1081 if (field == F_Button)
1083 if (array_ndx != NULL)
1084 return ReportActionNotArray(action->type, field);
1085 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1086 return ReportMismatch(action->type, field,
1087 "integer (range 1..255)");
1088 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1090 ERROR("Button must specify default or be in the range 1..255\n");
1091 ACTION("Illegal button value %d ignored\n", rtrn.ival);
1094 act->button = rtrn.ival;
1097 else if ((action->type == XkbSA_LockDeviceBtn) && (field == F_Affect))
1099 if (array_ndx != NULL)
1100 return ReportActionNotArray(action->type, field);
1101 if (!ExprResolveEnum(value, &rtrn, lockWhich))
1102 return ReportMismatch(action->type, field, "lock or unlock");
1103 act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
1104 act->flags |= rtrn.ival;
1107 else if (field == F_Count)
1109 if (array_ndx != NULL)
1110 return ReportActionNotArray(action->type, field);
1111 if (!ExprResolveButton(value, &rtrn))
1112 return ReportMismatch(action->type, field, "integer");
1113 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1115 ERROR("The count field must have a value in the range 0..255\n");
1116 ACTION("Illegal count %d ignored\n", rtrn.ival);
1119 act->count = rtrn.ival;
1122 else if (field == F_Device)
1124 if (array_ndx != NULL)
1125 return ReportActionNotArray(action->type, field);
1126 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1127 return ReportMismatch(action->type, field,
1128 "integer (range 1..255)");
1129 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1131 ERROR("Device must specify default or be in the range 1..255\n");
1132 ACTION("Illegal device value %d ignored\n", rtrn.ival);
1135 act->device = rtrn.ival;
1138 return ReportIllegal(action->type, field);
1142 HandleDeviceValuator(struct xkb_desc * xkb,
1143 struct xkb_any_action * action,
1144 unsigned field, ExprDef * array_ndx, ExprDef * value)
1148 struct xkb_device_valuator_action *act;
1150 act = (struct xkb_device_valuator_action *) action;
1151 /* XXX - Not yet implemented */
1157 HandlePrivate(struct xkb_desc * xkb,
1158 struct xkb_any_action * action,
1159 unsigned field, ExprDef * array_ndx, ExprDef * value)
1166 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1167 return ReportMismatch(PrivateAction, field, "integer");
1168 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1170 ERROR("Private action type must be in the range 0..255\n");
1171 ACTION("Illegal type %d ignored\n", rtrn.ival);
1174 action->type = rtrn.uval;
1177 if (array_ndx == NULL)
1179 if (!ExprResolveString(value, &rtrn))
1180 return ReportMismatch(action->type, field, "string");
1183 int len = strlen(rtrn.str);
1184 if ((len < 1) || (len > 7))
1186 WARN("A private action has 7 data bytes\n");
1187 ACTION("Extra %d bytes ignored\n", len - 6);
1190 strncpy((char *) action->data, rtrn.str, sizeof action->data);
1198 if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL))
1200 ERROR("Array subscript must be integer\n");
1201 ACTION("Illegal subscript ignored\n");
1205 if (ndx >= sizeof action->data)
1207 ERROR("The data for a private action is 18 bytes long\n");
1208 ACTION("Attempt to use data[%d] ignored\n", ndx);
1211 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1212 return ReportMismatch(action->type, field, "integer");
1213 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1215 ERROR("All data for a private action must be 0..255\n");
1216 ACTION("Illegal datum %d ignored\n", rtrn.ival);
1219 action->data[ndx] = rtrn.uval;
1223 return ReportIllegal(PrivateAction, field);
1226 typedef Bool(*actionHandler) (struct xkb_desc * /* xkb */ ,
1227 struct xkb_any_action * /* action */ ,
1228 unsigned /* field */ ,
1229 ExprDef * /* array_ndx */ ,
1230 ExprDef * /* value */
1233 static actionHandler handleAction[XkbSA_NumActions + 1] = {
1234 HandleNoAction /* NoAction */ ,
1235 HandleSetLatchMods /* SetMods */ ,
1236 HandleSetLatchMods /* LatchMods */ ,
1237 HandleLockMods /* LockMods */ ,
1238 HandleSetLatchGroup /* SetGroup */ ,
1239 HandleSetLatchGroup /* LatchGroup */ ,
1240 HandleLockGroup /* LockGroup */ ,
1241 HandleMovePtr /* MovePtr */ ,
1242 HandlePtrBtn /* PtrBtn */ ,
1243 HandlePtrBtn /* LockPtrBtn */ ,
1244 HandleSetPtrDflt /* SetPtrDflt */ ,
1245 HandleISOLock /* ISOLock */ ,
1246 HandleNoAction /* Terminate */ ,
1247 HandleSwitchScreen /* SwitchScreen */ ,
1248 HandleSetLockControls /* SetControls */ ,
1249 HandleSetLockControls /* LockControls */ ,
1250 HandleActionMessage /* ActionMessage */ ,
1251 HandleRedirectKey /* RedirectKey */ ,
1252 HandleDeviceBtn /* DeviceBtn */ ,
1253 HandleDeviceBtn /* LockDeviceBtn */ ,
1254 HandleDeviceValuator /* DeviceValuatr */ ,
1255 HandlePrivate /* Private */
1258 /***====================================================================***/
1261 ApplyActionFactoryDefaults(union xkb_action * action)
1263 if (action->type == XkbSA_SetPtrDflt)
1264 { /* increment default button */
1265 action->dflt.affect = XkbSA_AffectDfltBtn;
1266 action->dflt.flags = 0;
1267 action->dflt.value = 1;
1269 else if (action->type == XkbSA_ISOLock)
1271 action->iso.real_mods = LockMask;
1280 HandleActionDef(ExprDef * def,
1281 struct xkb_desc * xkb,
1282 struct xkb_any_action * action, unsigned mergeMode, ActionInfo * info)
1286 unsigned tmp, hndlrType;
1288 if (!actionsInitialized)
1291 if (def->op != ExprActionDecl)
1293 ERROR("Expected an action definition, found %s\n",
1294 exprOpText(def->op));
1297 str = XkbcAtomText(def->value.action.name);
1300 WSGO("Missing name in action definition!!\n");
1303 if (!stringToAction(str, &tmp))
1305 ERROR("Unknown action %s\n", str);
1308 action->type = hndlrType = tmp;
1309 if (action->type != XkbSA_NoAction)
1311 ApplyActionFactoryDefaults((union xkb_action *) action);
1314 if ((info->action == XkbSA_NoAction)
1315 || (info->action == hndlrType))
1317 if (!(*handleAction[hndlrType]) (xkb, action,
1328 for (arg = def->value.action.args; arg != NULL;
1329 arg = (ExprDef *) arg->common.next)
1331 ExprDef *field, *value, *arrayRtrn;
1332 ExprResult elemRtrn, fieldRtrn;
1335 if (arg->op == OpAssign)
1337 field = arg->value.binary.left;
1338 value = arg->value.binary.right;
1342 if ((arg->op == OpNot) || (arg->op == OpInvert))
1344 field = arg->value.child;
1345 value = &constFalse;
1353 if (!ExprResolveLhs(field, &elemRtrn, &fieldRtrn, &arrayRtrn))
1354 return False; /* internal error -- already reported */
1356 if (elemRtrn.str != NULL)
1358 ERROR("Cannot change defaults in an action definition\n");
1359 ACTION("Ignoring attempt to change %s.%s\n", elemRtrn.str,
1362 free(fieldRtrn.str);
1365 if (!stringToField(fieldRtrn.str, &fieldNdx))
1367 ERROR("Unknown field name %s\n", uStringText(fieldRtrn.str));
1369 free(fieldRtrn.str);
1373 free(fieldRtrn.str);
1374 if (!(*handleAction[hndlrType])
1375 (xkb, action, fieldNdx, arrayRtrn, value))
1383 /***====================================================================***/
1386 SetActionField(struct xkb_desc * xkb,
1389 ExprDef * array_ndx, ExprDef * value, ActionInfo ** info_rtrn)
1391 ActionInfo *new, *old;
1393 if (!actionsInitialized)
1396 new = uTypedAlloc(ActionInfo);
1399 WSGO("Couldn't allocate space for action default\n");
1402 if (uStrCaseCmp(elem, "action") == 0)
1403 new->action = XkbSA_NoAction;
1406 if (!stringToAction(elem, &new->action))
1411 if (new->action == XkbSA_NoAction)
1413 ERROR("\"%s\" is not a valid field in a NoAction action\n",
1419 if (!stringToField(field, &new->field))
1421 ERROR("\"%s\" is not a legal field name\n", field);
1425 new->array_ndx = array_ndx;
1429 while ((old) && (old->next))
1438 /***====================================================================***/
1443 if (!actionsInitialized)
1445 bzero((char *) &constTrue, sizeof(constTrue));
1446 bzero((char *) &constFalse, sizeof(constFalse));
1447 constTrue.common.stmtType = StmtExpr;
1448 constTrue.common.next = NULL;
1449 constTrue.op = ExprIdent;
1450 constTrue.type = TypeBoolean;
1451 constTrue.value.str = xkb_intern_atom("true");
1452 constFalse.common.stmtType = StmtExpr;
1453 constFalse.common.next = NULL;
1454 constFalse.op = ExprIdent;
1455 constFalse.type = TypeBoolean;
1456 constFalse.value.str = xkb_intern_atom("false");
1457 actionsInitialized = 1;