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);
466 CheckGroupField(unsigned action,
467 ExprDef * value, unsigned *flags_inout, int *grp_rtrn)
472 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
474 *flags_inout &= ~XkbSA_GroupAbsolute;
475 spec = value->value.child;
479 *flags_inout |= XkbSA_GroupAbsolute;
483 if (!ExprResolveGroup(spec, &rtrn))
484 return ReportMismatch(action, F_Group, "integer (range 1..8)");
485 if (value->op == OpNegate)
486 *grp_rtrn = -rtrn.ival;
487 else if (value->op == OpUnaryPlus)
488 *grp_rtrn = rtrn.ival;
490 *grp_rtrn = rtrn.ival - 1;
495 HandleSetLatchGroup(struct xkb_desc * xkb,
496 struct xkb_any_action * action,
497 unsigned field, ExprDef * array_ndx, ExprDef * value)
499 struct xkb_group_action *act;
504 act = (struct xkb_group_action *) action;
505 if (array_ndx != NULL)
512 return ReportActionNotArray(action->type, field);
520 if (CheckLatchLockFlags(action->type, field, value, &rtrn))
528 if (CheckGroupField(action->type, value, &t1, &t2))
536 return ReportIllegal(action->type, field);
540 HandleLockGroup(struct xkb_desc * xkb,
541 struct xkb_any_action * action,
542 unsigned field, ExprDef * array_ndx, ExprDef * value)
544 struct xkb_group_action *act;
548 act = (struct xkb_group_action *) action;
549 if ((array_ndx != NULL) && (field == F_Group))
550 return ReportActionNotArray(action->type, field);
551 if (field == F_Group)
554 if (CheckGroupField(action->type, value, &t1, &t2))
562 return ReportIllegal(action->type, field);
566 HandleMovePtr(struct xkb_desc * xkb,
567 struct xkb_any_action * action,
568 unsigned field, ExprDef * array_ndx, ExprDef * value)
571 struct xkb_pointer_action *act;
574 act = (struct xkb_pointer_action *) action;
575 if ((array_ndx != NULL) && ((field == F_X) || (field == F_Y)))
576 return ReportActionNotArray(action->type, field);
578 if ((field == F_X) || (field == F_Y))
580 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
584 if (!ExprResolveInteger(value, &rtrn))
585 return ReportMismatch(action->type, field, "integer");
589 act->flags |= XkbSA_MoveAbsoluteX;
595 act->flags |= XkbSA_MoveAbsoluteY;
600 else if (field == F_Accel)
602 if (!ExprResolveBoolean(value, &rtrn))
603 return ReportMismatch(action->type, field, "boolean");
605 act->flags &= ~XkbSA_NoAcceleration;
607 act->flags |= XkbSA_NoAcceleration;
609 return ReportIllegal(action->type, field);
612 static LookupEntry lockWhich[] = {
614 {"lock", XkbSA_LockNoUnlock},
615 {"neither", (XkbSA_LockNoLock | XkbSA_LockNoUnlock)},
616 {"unlock", XkbSA_LockNoLock},
621 HandlePtrBtn(struct xkb_desc * xkb,
622 struct xkb_any_action * action,
623 unsigned field, ExprDef * array_ndx, ExprDef * value)
626 struct xkb_pointer_button_action *act;
628 act = (struct xkb_pointer_button_action *) action;
629 if (field == F_Button)
631 if (array_ndx != NULL)
632 return ReportActionNotArray(action->type, field);
633 if (!ExprResolveButton(value, &rtrn))
634 return ReportMismatch(action->type, field,
635 "integer (range 1..5)");
636 if ((rtrn.ival < 0) || (rtrn.ival > 5))
638 ERROR("Button must specify default or be in the range 1..5\n");
639 ACTION("Illegal button value %d ignored\n", rtrn.ival);
642 act->button = rtrn.ival;
645 else if ((action->type == XkbSA_LockPtrBtn) && (field == F_Affect))
647 if (array_ndx != NULL)
648 return ReportActionNotArray(action->type, field);
649 if (!ExprResolveEnum(value, &rtrn, lockWhich))
650 return ReportMismatch(action->type, field, "lock or unlock");
651 act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
652 act->flags |= rtrn.ival;
655 else if (field == F_Count)
657 if (array_ndx != NULL)
658 return ReportActionNotArray(action->type, field);
659 if (!ExprResolveButton(value, &rtrn))
660 return ReportMismatch(action->type, field, "integer");
661 if ((rtrn.ival < 0) || (rtrn.ival > 255))
663 ERROR("The count field must have a value in the range 0..255\n");
664 ACTION("Illegal count %d ignored\n", rtrn.ival);
667 act->count = rtrn.ival;
670 return ReportIllegal(action->type, field);
673 static LookupEntry ptrDflts[] = {
674 {"dfltbtn", XkbSA_AffectDfltBtn},
675 {"defaultbutton", XkbSA_AffectDfltBtn},
676 {"button", XkbSA_AffectDfltBtn},
681 HandleSetPtrDflt(struct xkb_desc * xkb,
682 struct xkb_any_action * action,
683 unsigned field, ExprDef * array_ndx, ExprDef * value)
686 struct xkb_pointer_default_action *act;
688 act = (struct xkb_pointer_default_action *) action;
689 if (field == F_Affect)
691 if (array_ndx != NULL)
692 return ReportActionNotArray(action->type, field);
693 if (!ExprResolveEnum(value, &rtrn, ptrDflts))
694 return ReportMismatch(action->type, field, "pointer component");
695 act->affect = rtrn.uval;
698 else if ((field == F_Button) || (field == F_Value))
701 if (array_ndx != NULL)
702 return ReportActionNotArray(action->type, field);
703 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
705 act->flags &= ~XkbSA_DfltBtnAbsolute;
706 btn = value->value.child;
710 act->flags |= XkbSA_DfltBtnAbsolute;
714 if (!ExprResolveButton(btn, &rtrn))
715 return ReportMismatch(action->type, field,
716 "integer (range 1..5)");
717 if ((rtrn.ival < 0) || (rtrn.ival > 5))
719 ERROR("New default button value must be in the range 1..5\n");
720 ACTION("Illegal default button value %d ignored\n", rtrn.ival);
725 ERROR("Cannot set default pointer button to \"default\"\n");
726 ACTION("Illegal default button setting ignored\n");
729 if (value->op == OpNegate)
730 act->value = -rtrn.ival;
732 act->value = rtrn.ival;
735 return ReportIllegal(action->type, field);
738 static LookupEntry isoNames[] = {
739 {"mods", XkbSA_ISONoAffectMods},
740 {"modifiers", XkbSA_ISONoAffectMods},
741 {"group", XkbSA_ISONoAffectGroup},
742 {"groups", XkbSA_ISONoAffectGroup},
743 {"ptr", XkbSA_ISONoAffectPtr},
744 {"pointer", XkbSA_ISONoAffectPtr},
745 {"ctrls", XkbSA_ISONoAffectCtrls},
746 {"controls", XkbSA_ISONoAffectCtrls},
747 {"all", ~((unsigned) 0)},
753 HandleISOLock(struct xkb_desc * xkb,
754 struct xkb_any_action * action,
755 unsigned field, ExprDef * array_ndx, ExprDef * value)
758 struct xkb_iso_action *act;
759 unsigned flags, mods;
762 act = (struct xkb_iso_action *) action;
766 if (array_ndx != NULL)
767 return ReportActionNotArray(action->type, field);
769 if (CheckModifierField(xkb, action->type, value, &flags, &mods))
771 act->flags = flags & (~XkbSA_ISODfltIsGroup);
772 act->real_mods = mods & 0xff;
773 act->vmods = (mods >> 8) & 0xff;
778 if (array_ndx != NULL)
779 return ReportActionNotArray(action->type, field);
781 if (CheckGroupField(action->type, value, &flags, &group))
783 act->flags = flags | XkbSA_ISODfltIsGroup;
789 if (array_ndx != NULL)
790 return ReportActionNotArray(action->type, field);
791 if (!ExprResolveMask(value, &rtrn, isoNames))
792 return ReportMismatch(action->type, field, "keyboard component");
793 act->affect = (~rtrn.uval) & XkbSA_ISOAffectMask;
796 return ReportIllegal(action->type, field);
800 HandleSwitchScreen(struct xkb_desc * xkb,
801 struct xkb_any_action * action,
802 unsigned field, ExprDef * array_ndx, ExprDef * value)
805 struct xkb_switch_screen_action *act;
807 act = (struct xkb_switch_screen_action *) action;
808 if (field == F_Screen)
811 if (array_ndx != NULL)
812 return ReportActionNotArray(action->type, field);
813 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
815 act->flags &= ~XkbSA_SwitchAbsolute;
816 scrn = value->value.child;
820 act->flags |= XkbSA_SwitchAbsolute;
824 if (!ExprResolveInteger(scrn, &rtrn))
825 return ReportMismatch(action->type, field, "integer (0..255)");
826 if ((rtrn.ival < 0) || (rtrn.ival > 255))
828 ERROR("Screen index must be in the range 1..255\n");
829 ACTION("Illegal screen value %d ignored\n", rtrn.ival);
832 if (value->op == OpNegate)
833 act->screen = -rtrn.ival;
835 act->screen = rtrn.ival;
838 else if (field == F_Same)
840 if (array_ndx != NULL)
841 return ReportActionNotArray(action->type, field);
842 if (!ExprResolveBoolean(value, &rtrn))
843 return ReportMismatch(action->type, field, "boolean");
845 act->flags &= ~XkbSA_SwitchApplication;
847 act->flags |= XkbSA_SwitchApplication;
850 return ReportIllegal(action->type, field);
853 LookupEntry ctrlNames[] = {
854 {"repeatkeys", XkbRepeatKeysMask}
856 {"repeat", XkbRepeatKeysMask}
858 {"autorepeat", XkbRepeatKeysMask}
860 {"slowkeys", XkbSlowKeysMask}
862 {"bouncekeys", XkbBounceKeysMask}
864 {"stickykeys", XkbStickyKeysMask}
866 {"mousekeys", XkbMouseKeysMask}
868 {"mousekeysaccel", XkbMouseKeysAccelMask}
870 {"accessxkeys", XkbAccessXKeysMask}
872 {"accessxtimeout", XkbAccessXTimeoutMask}
874 {"accessxfeedback", XkbAccessXFeedbackMask}
876 {"audiblebell", XkbAudibleBellMask}
878 {"overlay1", XkbOverlay1Mask}
880 {"overlay2", XkbOverlay2Mask}
882 {"ignoregrouplock", XkbIgnoreGroupLockMask}
884 {"all", XkbAllBooleanCtrlsMask}
892 HandleSetLockControls(struct xkb_desc * xkb,
893 struct xkb_any_action * action,
894 unsigned field, ExprDef * array_ndx, ExprDef * value)
897 struct xkb_controls_action *act;
899 act = (struct xkb_controls_action *) action;
900 if (field == F_Controls)
902 if (array_ndx != NULL)
903 return ReportActionNotArray(action->type, field);
904 if (!ExprResolveMask(value, &rtrn, ctrlNames))
905 return ReportMismatch(action->type, field, "controls mask");
906 act->ctrls = rtrn.uval;
909 return ReportIllegal(action->type, field);
912 static LookupEntry evNames[] = {
913 {"press", XkbSA_MessageOnPress},
914 {"keypress", XkbSA_MessageOnPress},
915 {"release", XkbSA_MessageOnRelease},
916 {"keyrelease", XkbSA_MessageOnRelease},
917 {"all", XkbSA_MessageOnPress | XkbSA_MessageOnRelease},
923 HandleActionMessage(struct xkb_desc * xkb,
924 struct xkb_any_action * action,
925 unsigned field, ExprDef * array_ndx, ExprDef * value)
928 struct xkb_message_action *act;
930 act = (struct xkb_message_action *) action;
934 if (array_ndx != NULL)
935 return ReportActionNotArray(action->type, field);
936 if (!ExprResolveMask(value, &rtrn, evNames))
937 return ReportMismatch(action->type, field, "key event mask");
938 act->flags &= ~(XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
940 rtrn.uval & (XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
943 if (array_ndx != NULL)
944 return ReportActionNotArray(action->type, field);
945 if (!ExprResolveBoolean(value, &rtrn))
946 return ReportMismatch(action->type, field, "boolean");
948 act->flags |= XkbSA_MessageGenKeyEvent;
950 act->flags &= ~XkbSA_MessageGenKeyEvent;
953 if (array_ndx == NULL)
955 if (!ExprResolveString(value, &rtrn))
956 return ReportMismatch(action->type, field, "string");
959 int len = strlen(rtrn.str);
960 if ((len < 1) || (len > 6))
962 WARN("An action message can hold only 6 bytes\n");
963 ACTION("Extra %d bytes ignored\n", len - 6);
965 strncpy((char *) act->message, rtrn.str, 6);
972 if (!ExprResolveInteger(array_ndx, &rtrn))
974 ERROR("Array subscript must be integer\n");
975 ACTION("Illegal subscript ignored\n");
981 ERROR("An action message is at most 6 bytes long\n");
982 ACTION("Attempt to use data[%d] ignored\n", ndx);
985 if (!ExprResolveInteger(value, &rtrn))
986 return ReportMismatch(action->type, field, "integer");
987 if ((rtrn.ival < 0) || (rtrn.ival > 255))
989 ERROR("Message data must be in the range 0..255\n");
990 ACTION("Illegal datum %d ignored\n", rtrn.ival);
993 act->message[ndx] = rtrn.uval;
997 return ReportIllegal(action->type, field);
1001 HandleRedirectKey(struct xkb_desc * xkb,
1002 struct xkb_any_action * action,
1003 unsigned field, ExprDef * array_ndx, ExprDef * value)
1006 struct xkb_redirect_key_action *act;
1011 if (array_ndx != NULL)
1012 return ReportActionNotArray(action->type, field);
1014 act = (struct xkb_redirect_key_action *) action;
1018 if (!ExprResolveKeyName(value, &rtrn))
1019 return ReportMismatch(action->type, field, "key name");
1020 tmp = KeyNameToLong(rtrn.keyName.name);
1021 if (!FindNamedKey(xkb, tmp, &kc, True, CreateKeyNames(xkb), 0))
1023 return ReportNotFound(action->type, field, "Key",
1024 XkbcKeyNameText(rtrn.keyName.name));
1031 if (CheckModifierField(xkb, action->type, value, &t1, &t2))
1033 act->mods_mask |= (t2 & 0xff);
1034 if (field == F_Modifiers)
1035 act->mods |= (t2 & 0xff);
1037 act->mods &= ~(t2 & 0xff);
1039 t2 = (t2 >> 8) & 0xffff;
1040 act->vmods_mask |= t2;
1041 if (field == F_Modifiers)
1049 return ReportIllegal(action->type, field);
1053 HandleDeviceBtn(struct xkb_desc * xkb,
1054 struct xkb_any_action * action,
1055 unsigned field, ExprDef * array_ndx, ExprDef * value)
1058 struct xkb_device_button_action *act;
1060 act = (struct xkb_device_button_action *) action;
1061 if (field == F_Button)
1063 if (array_ndx != NULL)
1064 return ReportActionNotArray(action->type, field);
1065 if (!ExprResolveInteger(value, &rtrn))
1066 return ReportMismatch(action->type, field,
1067 "integer (range 1..255)");
1068 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1070 ERROR("Button must specify default or be in the range 1..255\n");
1071 ACTION("Illegal button value %d ignored\n", rtrn.ival);
1074 act->button = rtrn.ival;
1077 else if ((action->type == XkbSA_LockDeviceBtn) && (field == F_Affect))
1079 if (array_ndx != NULL)
1080 return ReportActionNotArray(action->type, field);
1081 if (!ExprResolveEnum(value, &rtrn, lockWhich))
1082 return ReportMismatch(action->type, field, "lock or unlock");
1083 act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
1084 act->flags |= rtrn.ival;
1087 else if (field == F_Count)
1089 if (array_ndx != NULL)
1090 return ReportActionNotArray(action->type, field);
1091 if (!ExprResolveButton(value, &rtrn))
1092 return ReportMismatch(action->type, field, "integer");
1093 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1095 ERROR("The count field must have a value in the range 0..255\n");
1096 ACTION("Illegal count %d ignored\n", rtrn.ival);
1099 act->count = rtrn.ival;
1102 else if (field == F_Device)
1104 if (array_ndx != NULL)
1105 return ReportActionNotArray(action->type, field);
1106 if (!ExprResolveInteger(value, &rtrn))
1107 return ReportMismatch(action->type, field,
1108 "integer (range 1..255)");
1109 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1111 ERROR("Device must specify default or be in the range 1..255\n");
1112 ACTION("Illegal device value %d ignored\n", rtrn.ival);
1115 act->device = rtrn.ival;
1118 return ReportIllegal(action->type, field);
1122 HandleDeviceValuator(struct xkb_desc * xkb,
1123 struct xkb_any_action * action,
1124 unsigned field, ExprDef * array_ndx, ExprDef * value)
1128 struct xkb_device_valuator_action *act;
1130 act = (struct xkb_device_valuator_action *) action;
1131 /* XXX - Not yet implemented */
1137 HandlePrivate(struct xkb_desc * xkb,
1138 struct xkb_any_action * action,
1139 unsigned field, ExprDef * array_ndx, ExprDef * value)
1146 if (!ExprResolveInteger(value, &rtrn))
1147 return ReportMismatch(PrivateAction, field, "integer");
1148 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1150 ERROR("Private action type must be in the range 0..255\n");
1151 ACTION("Illegal type %d ignored\n", rtrn.ival);
1154 action->type = rtrn.uval;
1157 if (array_ndx == NULL)
1159 if (!ExprResolveString(value, &rtrn))
1160 return ReportMismatch(action->type, field, "string");
1163 int len = strlen(rtrn.str);
1164 if ((len < 1) || (len > 7))
1166 WARN("A private action has 7 data bytes\n");
1167 ACTION("Extra %d bytes ignored\n", len - 6);
1170 strncpy((char *) action->data, rtrn.str, sizeof action->data);
1178 if (!ExprResolveInteger(array_ndx, &rtrn))
1180 ERROR("Array subscript must be integer\n");
1181 ACTION("Illegal subscript ignored\n");
1185 if (ndx >= sizeof action->data)
1187 ERROR("The data for a private action is 18 bytes long\n");
1188 ACTION("Attempt to use data[%d] ignored\n", ndx);
1191 if (!ExprResolveInteger(value, &rtrn))
1192 return ReportMismatch(action->type, field, "integer");
1193 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1195 ERROR("All data for a private action must be 0..255\n");
1196 ACTION("Illegal datum %d ignored\n", rtrn.ival);
1199 action->data[ndx] = rtrn.uval;
1203 return ReportIllegal(PrivateAction, field);
1206 typedef Bool(*actionHandler) (struct xkb_desc * /* xkb */ ,
1207 struct xkb_any_action * /* action */ ,
1208 unsigned /* field */ ,
1209 ExprDef * /* array_ndx */ ,
1210 ExprDef * /* value */
1213 static actionHandler handleAction[XkbSA_NumActions + 1] = {
1214 HandleNoAction /* NoAction */ ,
1215 HandleSetLatchMods /* SetMods */ ,
1216 HandleSetLatchMods /* LatchMods */ ,
1217 HandleLockMods /* LockMods */ ,
1218 HandleSetLatchGroup /* SetGroup */ ,
1219 HandleSetLatchGroup /* LatchGroup */ ,
1220 HandleLockGroup /* LockGroup */ ,
1221 HandleMovePtr /* MovePtr */ ,
1222 HandlePtrBtn /* PtrBtn */ ,
1223 HandlePtrBtn /* LockPtrBtn */ ,
1224 HandleSetPtrDflt /* SetPtrDflt */ ,
1225 HandleISOLock /* ISOLock */ ,
1226 HandleNoAction /* Terminate */ ,
1227 HandleSwitchScreen /* SwitchScreen */ ,
1228 HandleSetLockControls /* SetControls */ ,
1229 HandleSetLockControls /* LockControls */ ,
1230 HandleActionMessage /* ActionMessage */ ,
1231 HandleRedirectKey /* RedirectKey */ ,
1232 HandleDeviceBtn /* DeviceBtn */ ,
1233 HandleDeviceBtn /* LockDeviceBtn */ ,
1234 HandleDeviceValuator /* DeviceValuatr */ ,
1235 HandlePrivate /* Private */
1238 /***====================================================================***/
1241 ApplyActionFactoryDefaults(union xkb_action * action)
1243 if (action->type == XkbSA_SetPtrDflt)
1244 { /* increment default button */
1245 action->dflt.affect = XkbSA_AffectDfltBtn;
1246 action->dflt.flags = 0;
1247 action->dflt.value = 1;
1249 else if (action->type == XkbSA_ISOLock)
1251 action->iso.real_mods = LockMask;
1260 HandleActionDef(ExprDef * def,
1261 struct xkb_desc * xkb,
1262 struct xkb_any_action * action, unsigned mergeMode, ActionInfo * info)
1266 unsigned tmp, hndlrType;
1268 if (!actionsInitialized)
1271 if (def->op != ExprActionDecl)
1273 ERROR("Expected an action definition, found %s\n",
1274 exprOpText(def->op));
1277 str = XkbcAtomText(def->value.action.name);
1280 WSGO("Missing name in action definition!!\n");
1283 if (!stringToAction(str, &tmp))
1285 ERROR("Unknown action %s\n", str);
1288 action->type = hndlrType = tmp;
1289 if (action->type != XkbSA_NoAction)
1291 ApplyActionFactoryDefaults((union xkb_action *) action);
1294 if ((info->action == XkbSA_NoAction)
1295 || (info->action == hndlrType))
1297 if (!(*handleAction[hndlrType]) (xkb, action,
1308 for (arg = def->value.action.args; arg != NULL;
1309 arg = (ExprDef *) arg->common.next)
1311 ExprDef *field, *value, *arrayRtrn;
1312 ExprResult elemRtrn, fieldRtrn;
1315 if (arg->op == OpAssign)
1317 field = arg->value.binary.left;
1318 value = arg->value.binary.right;
1322 if ((arg->op == OpNot) || (arg->op == OpInvert))
1324 field = arg->value.child;
1325 value = &constFalse;
1333 if (!ExprResolveLhs(field, &elemRtrn, &fieldRtrn, &arrayRtrn))
1334 return False; /* internal error -- already reported */
1336 if (elemRtrn.str != NULL)
1338 ERROR("Cannot change defaults in an action definition\n");
1339 ACTION("Ignoring attempt to change %s.%s\n", elemRtrn.str,
1342 free(fieldRtrn.str);
1345 if (!stringToField(fieldRtrn.str, &fieldNdx))
1347 ERROR("Unknown field name %s\n", uStringText(fieldRtrn.str));
1349 free(fieldRtrn.str);
1353 free(fieldRtrn.str);
1354 if (!(*handleAction[hndlrType])
1355 (xkb, action, fieldNdx, arrayRtrn, value))
1363 /***====================================================================***/
1366 SetActionField(struct xkb_desc * xkb,
1369 ExprDef * array_ndx, ExprDef * value, ActionInfo ** info_rtrn)
1371 ActionInfo *new, *old;
1373 if (!actionsInitialized)
1376 new = uTypedAlloc(ActionInfo);
1379 WSGO("Couldn't allocate space for action default\n");
1382 if (uStrCaseCmp(elem, "action") == 0)
1383 new->action = XkbSA_NoAction;
1386 if (!stringToAction(elem, &new->action))
1391 if (new->action == XkbSA_NoAction)
1393 ERROR("\"%s\" is not a valid field in a NoAction action\n",
1399 if (!stringToField(field, &new->field))
1401 ERROR("\"%s\" is not a legal field name\n", field);
1405 new->array_ndx = array_ndx;
1409 while ((old) && (old->next))
1418 /***====================================================================***/
1423 if (!actionsInitialized)
1425 bzero((char *) &constTrue, sizeof(constTrue));
1426 bzero((char *) &constFalse, sizeof(constFalse));
1427 constTrue.common.stmtType = StmtExpr;
1428 constTrue.common.next = NULL;
1429 constTrue.op = ExprIdent;
1430 constTrue.type = TypeBoolean;
1431 constTrue.value.str = xkb_intern_atom("true");
1432 constFalse.common.stmtType = StmtExpr;
1433 constFalse.common.next = NULL;
1434 constFalse.op = ExprIdent;
1435 constFalse.type = TypeBoolean;
1436 constFalse.value.str = xkb_intern_atom("false");
1437 actionsInitialized = 1;