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 ((rtrn.ival < 1) || (rtrn.ival > XkbNumKbdGroups))
487 ERROR("Illegal group %d (must be in the range 1..%d)\n", rtrn.ival,
489 ACTION("Action %s definition ignored\n", XkbcActionTypeText(action));
492 if (value->op == OpNegate)
493 *grp_rtrn = -rtrn.ival;
494 else if (value->op == OpUnaryPlus)
495 *grp_rtrn = rtrn.ival;
497 *grp_rtrn = rtrn.ival - 1;
502 HandleSetLatchGroup(struct xkb_desc * xkb,
503 struct xkb_any_action * action,
504 unsigned field, ExprDef * array_ndx, ExprDef * value)
506 struct xkb_group_action *act;
511 act = (struct xkb_group_action *) action;
512 if (array_ndx != NULL)
519 return ReportActionNotArray(action->type, field);
527 if (CheckLatchLockFlags(action->type, field, value, &rtrn))
535 if (CheckGroupField(action->type, value, &t1, &t2))
543 return ReportIllegal(action->type, field);
547 HandleLockGroup(struct xkb_desc * xkb,
548 struct xkb_any_action * action,
549 unsigned field, ExprDef * array_ndx, ExprDef * value)
551 struct xkb_group_action *act;
555 act = (struct xkb_group_action *) action;
556 if ((array_ndx != NULL) && (field == F_Group))
557 return ReportActionNotArray(action->type, field);
558 if (field == F_Group)
561 if (CheckGroupField(action->type, value, &t1, &t2))
569 return ReportIllegal(action->type, field);
573 HandleMovePtr(struct xkb_desc * xkb,
574 struct xkb_any_action * action,
575 unsigned field, ExprDef * array_ndx, ExprDef * value)
578 struct xkb_pointer_action *act;
581 act = (struct xkb_pointer_action *) action;
582 if ((array_ndx != NULL) && ((field == F_X) || (field == F_Y)))
583 return ReportActionNotArray(action->type, field);
585 if ((field == F_X) || (field == F_Y))
587 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
591 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
592 return ReportMismatch(action->type, field, "integer");
596 act->flags |= XkbSA_MoveAbsoluteX;
602 act->flags |= XkbSA_MoveAbsoluteY;
607 else if (field == F_Accel)
609 if (!ExprResolveBoolean(value, &rtrn))
610 return ReportMismatch(action->type, field, "boolean");
612 act->flags &= ~XkbSA_NoAcceleration;
614 act->flags |= XkbSA_NoAcceleration;
616 return ReportIllegal(action->type, field);
619 static LookupEntry lockWhich[] = {
621 {"lock", XkbSA_LockNoUnlock},
622 {"neither", (XkbSA_LockNoLock | XkbSA_LockNoUnlock)},
623 {"unlock", XkbSA_LockNoLock},
628 HandlePtrBtn(struct xkb_desc * xkb,
629 struct xkb_any_action * action,
630 unsigned field, ExprDef * array_ndx, ExprDef * value)
633 struct xkb_pointer_button_action *act;
635 act = (struct xkb_pointer_button_action *) action;
636 if (field == F_Button)
638 if (array_ndx != NULL)
639 return ReportActionNotArray(action->type, field);
640 if (!ExprResolveButton(value, &rtrn))
641 return ReportMismatch(action->type, field,
642 "integer (range 1..5)");
643 if ((rtrn.ival < 0) || (rtrn.ival > 5))
645 ERROR("Button must specify default or be in the range 1..5\n");
646 ACTION("Illegal button value %d ignored\n", rtrn.ival);
649 act->button = rtrn.ival;
652 else if ((action->type == XkbSA_LockPtrBtn) && (field == F_Affect))
654 if (array_ndx != NULL)
655 return ReportActionNotArray(action->type, field);
656 if (!ExprResolveEnum(value, &rtrn, lockWhich))
657 return ReportMismatch(action->type, field, "lock or unlock");
658 act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
659 act->flags |= rtrn.ival;
662 else if (field == F_Count)
664 if (array_ndx != NULL)
665 return ReportActionNotArray(action->type, field);
666 if (!ExprResolveButton(value, &rtrn))
667 return ReportMismatch(action->type, field, "integer");
668 if ((rtrn.ival < 0) || (rtrn.ival > 255))
670 ERROR("The count field must have a value in the range 0..255\n");
671 ACTION("Illegal count %d ignored\n", rtrn.ival);
674 act->count = rtrn.ival;
677 return ReportIllegal(action->type, field);
680 static LookupEntry ptrDflts[] = {
681 {"dfltbtn", XkbSA_AffectDfltBtn},
682 {"defaultbutton", XkbSA_AffectDfltBtn},
683 {"button", XkbSA_AffectDfltBtn},
688 HandleSetPtrDflt(struct xkb_desc * xkb,
689 struct xkb_any_action * action,
690 unsigned field, ExprDef * array_ndx, ExprDef * value)
693 struct xkb_pointer_default_action *act;
695 act = (struct xkb_pointer_default_action *) action;
696 if (field == F_Affect)
698 if (array_ndx != NULL)
699 return ReportActionNotArray(action->type, field);
700 if (!ExprResolveEnum(value, &rtrn, ptrDflts))
701 return ReportMismatch(action->type, field, "pointer component");
702 act->affect = rtrn.uval;
705 else if ((field == F_Button) || (field == F_Value))
708 if (array_ndx != NULL)
709 return ReportActionNotArray(action->type, field);
710 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
712 act->flags &= ~XkbSA_DfltBtnAbsolute;
713 btn = value->value.child;
717 act->flags |= XkbSA_DfltBtnAbsolute;
721 if (!ExprResolveButton(btn, &rtrn))
722 return ReportMismatch(action->type, field,
723 "integer (range 1..5)");
724 if ((rtrn.ival < 0) || (rtrn.ival > 5))
726 ERROR("New default button value must be in the range 1..5\n");
727 ACTION("Illegal default button value %d ignored\n", rtrn.ival);
732 ERROR("Cannot set default pointer button to \"default\"\n");
733 ACTION("Illegal default button setting ignored\n");
736 if (value->op == OpNegate)
737 act->value = -rtrn.ival;
739 act->value = rtrn.ival;
742 return ReportIllegal(action->type, field);
745 static LookupEntry isoNames[] = {
746 {"mods", XkbSA_ISONoAffectMods},
747 {"modifiers", XkbSA_ISONoAffectMods},
748 {"group", XkbSA_ISONoAffectGroup},
749 {"groups", XkbSA_ISONoAffectGroup},
750 {"ptr", XkbSA_ISONoAffectPtr},
751 {"pointer", XkbSA_ISONoAffectPtr},
752 {"ctrls", XkbSA_ISONoAffectCtrls},
753 {"controls", XkbSA_ISONoAffectCtrls},
754 {"all", ~((unsigned) 0)},
760 HandleISOLock(struct xkb_desc * xkb,
761 struct xkb_any_action * action,
762 unsigned field, ExprDef * array_ndx, ExprDef * value)
765 struct xkb_iso_action *act;
766 unsigned flags, mods;
769 act = (struct xkb_iso_action *) action;
773 if (array_ndx != NULL)
774 return ReportActionNotArray(action->type, field);
776 if (CheckModifierField(xkb, action->type, value, &flags, &mods))
778 act->flags = flags & (~XkbSA_ISODfltIsGroup);
779 act->real_mods = mods & 0xff;
780 act->vmods = (mods >> 8) & 0xff;
785 if (array_ndx != NULL)
786 return ReportActionNotArray(action->type, field);
788 if (CheckGroupField(action->type, value, &flags, &group))
790 act->flags = flags | XkbSA_ISODfltIsGroup;
796 if (array_ndx != NULL)
797 return ReportActionNotArray(action->type, field);
798 if (!ExprResolveMask(value, &rtrn, SimpleLookup, (char *) isoNames))
799 return ReportMismatch(action->type, field, "keyboard component");
800 act->affect = (~rtrn.uval) & XkbSA_ISOAffectMask;
803 return ReportIllegal(action->type, field);
807 HandleSwitchScreen(struct xkb_desc * xkb,
808 struct xkb_any_action * action,
809 unsigned field, ExprDef * array_ndx, ExprDef * value)
812 struct xkb_switch_screen_action *act;
814 act = (struct xkb_switch_screen_action *) action;
815 if (field == F_Screen)
818 if (array_ndx != NULL)
819 return ReportActionNotArray(action->type, field);
820 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
822 act->flags &= ~XkbSA_SwitchAbsolute;
823 scrn = value->value.child;
827 act->flags |= XkbSA_SwitchAbsolute;
831 if (!ExprResolveInteger(scrn, &rtrn, NULL, NULL))
832 return ReportMismatch(action->type, field, "integer (0..255)");
833 if ((rtrn.ival < 0) || (rtrn.ival > 255))
835 ERROR("Screen index must be in the range 1..255\n");
836 ACTION("Illegal screen value %d ignored\n", rtrn.ival);
839 if (value->op == OpNegate)
840 act->screen = -rtrn.ival;
842 act->screen = rtrn.ival;
845 else if (field == F_Same)
847 if (array_ndx != NULL)
848 return ReportActionNotArray(action->type, field);
849 if (!ExprResolveBoolean(value, &rtrn))
850 return ReportMismatch(action->type, field, "boolean");
852 act->flags &= ~XkbSA_SwitchApplication;
854 act->flags |= XkbSA_SwitchApplication;
857 return ReportIllegal(action->type, field);
860 LookupEntry ctrlNames[] = {
861 {"repeatkeys", XkbRepeatKeysMask}
863 {"repeat", XkbRepeatKeysMask}
865 {"autorepeat", XkbRepeatKeysMask}
867 {"slowkeys", XkbSlowKeysMask}
869 {"bouncekeys", XkbBounceKeysMask}
871 {"stickykeys", XkbStickyKeysMask}
873 {"mousekeys", XkbMouseKeysMask}
875 {"mousekeysaccel", XkbMouseKeysAccelMask}
877 {"accessxkeys", XkbAccessXKeysMask}
879 {"accessxtimeout", XkbAccessXTimeoutMask}
881 {"accessxfeedback", XkbAccessXFeedbackMask}
883 {"audiblebell", XkbAudibleBellMask}
885 {"overlay1", XkbOverlay1Mask}
887 {"overlay2", XkbOverlay2Mask}
889 {"ignoregrouplock", XkbIgnoreGroupLockMask}
891 {"all", XkbAllBooleanCtrlsMask}
899 HandleSetLockControls(struct xkb_desc * xkb,
900 struct xkb_any_action * action,
901 unsigned field, ExprDef * array_ndx, ExprDef * value)
904 struct xkb_controls_action *act;
906 act = (struct xkb_controls_action *) action;
907 if (field == F_Controls)
909 if (array_ndx != NULL)
910 return ReportActionNotArray(action->type, field);
912 (value, &rtrn, SimpleLookup, (char *) ctrlNames))
913 return ReportMismatch(action->type, field, "controls mask");
914 act->ctrls = rtrn.uval;
917 return ReportIllegal(action->type, field);
920 static LookupEntry evNames[] = {
921 {"press", XkbSA_MessageOnPress},
922 {"keypress", XkbSA_MessageOnPress},
923 {"release", XkbSA_MessageOnRelease},
924 {"keyrelease", XkbSA_MessageOnRelease},
925 {"all", XkbSA_MessageOnPress | XkbSA_MessageOnRelease},
931 HandleActionMessage(struct xkb_desc * xkb,
932 struct xkb_any_action * action,
933 unsigned field, ExprDef * array_ndx, ExprDef * value)
936 struct xkb_message_action *act;
938 act = (struct xkb_message_action *) action;
942 if (array_ndx != NULL)
943 return ReportActionNotArray(action->type, field);
944 if (!ExprResolveMask(value, &rtrn, SimpleLookup, (char *) evNames))
945 return ReportMismatch(action->type, field, "key event mask");
946 act->flags &= ~(XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
948 rtrn.uval & (XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
951 if (array_ndx != NULL)
952 return ReportActionNotArray(action->type, field);
953 if (!ExprResolveBoolean(value, &rtrn))
954 return ReportMismatch(action->type, field, "boolean");
956 act->flags |= XkbSA_MessageGenKeyEvent;
958 act->flags &= ~XkbSA_MessageGenKeyEvent;
961 if (array_ndx == NULL)
963 if (!ExprResolveString(value, &rtrn))
964 return ReportMismatch(action->type, field, "string");
967 int len = strlen(rtrn.str);
968 if ((len < 1) || (len > 6))
970 WARN("An action message can hold only 6 bytes\n");
971 ACTION("Extra %d bytes ignored\n", len - 6);
973 strncpy((char *) act->message, rtrn.str, 6);
980 if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL))
982 ERROR("Array subscript must be integer\n");
983 ACTION("Illegal subscript ignored\n");
989 ERROR("An action message is at most 6 bytes long\n");
990 ACTION("Attempt to use data[%d] ignored\n", ndx);
993 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
994 return ReportMismatch(action->type, field, "integer");
995 if ((rtrn.ival < 0) || (rtrn.ival > 255))
997 ERROR("Message data must be in the range 0..255\n");
998 ACTION("Illegal datum %d ignored\n", rtrn.ival);
1001 act->message[ndx] = rtrn.uval;
1005 return ReportIllegal(action->type, field);
1009 HandleRedirectKey(struct xkb_desc * xkb,
1010 struct xkb_any_action * action,
1011 unsigned field, ExprDef * array_ndx, ExprDef * value)
1014 struct xkb_redirect_key_action *act;
1019 if (array_ndx != NULL)
1020 return ReportActionNotArray(action->type, field);
1022 act = (struct xkb_redirect_key_action *) action;
1026 if (!ExprResolveKeyName(value, &rtrn))
1027 return ReportMismatch(action->type, field, "key name");
1028 tmp = KeyNameToLong(rtrn.keyName.name);
1029 if (!FindNamedKey(xkb, tmp, &kc, True, CreateKeyNames(xkb), 0))
1031 return ReportNotFound(action->type, field, "Key",
1032 XkbcKeyNameText(rtrn.keyName.name));
1039 if (CheckModifierField(xkb, action->type, value, &t1, &t2))
1041 act->mods_mask |= (t2 & 0xff);
1042 if (field == F_Modifiers)
1043 act->mods |= (t2 & 0xff);
1045 act->mods &= ~(t2 & 0xff);
1047 t2 = (t2 >> 8) & 0xffff;
1048 act->vmods_mask |= t2;
1049 if (field == F_Modifiers)
1057 return ReportIllegal(action->type, field);
1061 HandleDeviceBtn(struct xkb_desc * xkb,
1062 struct xkb_any_action * action,
1063 unsigned field, ExprDef * array_ndx, ExprDef * value)
1066 struct xkb_device_button_action *act;
1068 act = (struct xkb_device_button_action *) action;
1069 if (field == F_Button)
1071 if (array_ndx != NULL)
1072 return ReportActionNotArray(action->type, field);
1073 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1074 return ReportMismatch(action->type, field,
1075 "integer (range 1..255)");
1076 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1078 ERROR("Button must specify default or be in the range 1..255\n");
1079 ACTION("Illegal button value %d ignored\n", rtrn.ival);
1082 act->button = rtrn.ival;
1085 else if ((action->type == XkbSA_LockDeviceBtn) && (field == F_Affect))
1087 if (array_ndx != NULL)
1088 return ReportActionNotArray(action->type, field);
1089 if (!ExprResolveEnum(value, &rtrn, lockWhich))
1090 return ReportMismatch(action->type, field, "lock or unlock");
1091 act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
1092 act->flags |= rtrn.ival;
1095 else if (field == F_Count)
1097 if (array_ndx != NULL)
1098 return ReportActionNotArray(action->type, field);
1099 if (!ExprResolveButton(value, &rtrn))
1100 return ReportMismatch(action->type, field, "integer");
1101 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1103 ERROR("The count field must have a value in the range 0..255\n");
1104 ACTION("Illegal count %d ignored\n", rtrn.ival);
1107 act->count = rtrn.ival;
1110 else if (field == F_Device)
1112 if (array_ndx != NULL)
1113 return ReportActionNotArray(action->type, field);
1114 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1115 return ReportMismatch(action->type, field,
1116 "integer (range 1..255)");
1117 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1119 ERROR("Device must specify default or be in the range 1..255\n");
1120 ACTION("Illegal device value %d ignored\n", rtrn.ival);
1123 act->device = rtrn.ival;
1126 return ReportIllegal(action->type, field);
1130 HandleDeviceValuator(struct xkb_desc * xkb,
1131 struct xkb_any_action * action,
1132 unsigned field, ExprDef * array_ndx, ExprDef * value)
1136 struct xkb_device_valuator_action *act;
1138 act = (struct xkb_device_valuator_action *) action;
1139 /* XXX - Not yet implemented */
1145 HandlePrivate(struct xkb_desc * xkb,
1146 struct xkb_any_action * action,
1147 unsigned field, ExprDef * array_ndx, ExprDef * value)
1154 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1155 return ReportMismatch(PrivateAction, field, "integer");
1156 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1158 ERROR("Private action type must be in the range 0..255\n");
1159 ACTION("Illegal type %d ignored\n", rtrn.ival);
1162 action->type = rtrn.uval;
1165 if (array_ndx == NULL)
1167 if (!ExprResolveString(value, &rtrn))
1168 return ReportMismatch(action->type, field, "string");
1171 int len = strlen(rtrn.str);
1172 if ((len < 1) || (len > 7))
1174 WARN("A private action has 7 data bytes\n");
1175 ACTION("Extra %d bytes ignored\n", len - 6);
1178 strncpy((char *) action->data, rtrn.str, sizeof action->data);
1186 if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL))
1188 ERROR("Array subscript must be integer\n");
1189 ACTION("Illegal subscript ignored\n");
1193 if (ndx >= sizeof action->data)
1195 ERROR("The data for a private action is 18 bytes long\n");
1196 ACTION("Attempt to use data[%d] ignored\n", ndx);
1199 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1200 return ReportMismatch(action->type, field, "integer");
1201 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1203 ERROR("All data for a private action must be 0..255\n");
1204 ACTION("Illegal datum %d ignored\n", rtrn.ival);
1207 action->data[ndx] = rtrn.uval;
1211 return ReportIllegal(PrivateAction, field);
1214 typedef Bool(*actionHandler) (struct xkb_desc * /* xkb */ ,
1215 struct xkb_any_action * /* action */ ,
1216 unsigned /* field */ ,
1217 ExprDef * /* array_ndx */ ,
1218 ExprDef * /* value */
1221 static actionHandler handleAction[XkbSA_NumActions + 1] = {
1222 HandleNoAction /* NoAction */ ,
1223 HandleSetLatchMods /* SetMods */ ,
1224 HandleSetLatchMods /* LatchMods */ ,
1225 HandleLockMods /* LockMods */ ,
1226 HandleSetLatchGroup /* SetGroup */ ,
1227 HandleSetLatchGroup /* LatchGroup */ ,
1228 HandleLockGroup /* LockGroup */ ,
1229 HandleMovePtr /* MovePtr */ ,
1230 HandlePtrBtn /* PtrBtn */ ,
1231 HandlePtrBtn /* LockPtrBtn */ ,
1232 HandleSetPtrDflt /* SetPtrDflt */ ,
1233 HandleISOLock /* ISOLock */ ,
1234 HandleNoAction /* Terminate */ ,
1235 HandleSwitchScreen /* SwitchScreen */ ,
1236 HandleSetLockControls /* SetControls */ ,
1237 HandleSetLockControls /* LockControls */ ,
1238 HandleActionMessage /* ActionMessage */ ,
1239 HandleRedirectKey /* RedirectKey */ ,
1240 HandleDeviceBtn /* DeviceBtn */ ,
1241 HandleDeviceBtn /* LockDeviceBtn */ ,
1242 HandleDeviceValuator /* DeviceValuatr */ ,
1243 HandlePrivate /* Private */
1246 /***====================================================================***/
1249 ApplyActionFactoryDefaults(union xkb_action * action)
1251 if (action->type == XkbSA_SetPtrDflt)
1252 { /* increment default button */
1253 action->dflt.affect = XkbSA_AffectDfltBtn;
1254 action->dflt.flags = 0;
1255 action->dflt.value = 1;
1257 else if (action->type == XkbSA_ISOLock)
1259 action->iso.real_mods = LockMask;
1268 HandleActionDef(ExprDef * def,
1269 struct xkb_desc * xkb,
1270 struct xkb_any_action * action, unsigned mergeMode, ActionInfo * info)
1274 unsigned tmp, hndlrType;
1276 if (!actionsInitialized)
1279 if (def->op != ExprActionDecl)
1281 ERROR("Expected an action definition, found %s\n",
1282 exprOpText(def->op));
1285 str = XkbcAtomText(def->value.action.name);
1288 WSGO("Missing name in action definition!!\n");
1291 if (!stringToAction(str, &tmp))
1293 ERROR("Unknown action %s\n", str);
1296 action->type = hndlrType = tmp;
1297 if (action->type != XkbSA_NoAction)
1299 ApplyActionFactoryDefaults((union xkb_action *) action);
1302 if ((info->action == XkbSA_NoAction)
1303 || (info->action == hndlrType))
1305 if (!(*handleAction[hndlrType]) (xkb, action,
1316 for (arg = def->value.action.args; arg != NULL;
1317 arg = (ExprDef *) arg->common.next)
1319 ExprDef *field, *value, *arrayRtrn;
1320 ExprResult elemRtrn, fieldRtrn;
1323 if (arg->op == OpAssign)
1325 field = arg->value.binary.left;
1326 value = arg->value.binary.right;
1330 if ((arg->op == OpNot) || (arg->op == OpInvert))
1332 field = arg->value.child;
1333 value = &constFalse;
1341 if (!ExprResolveLhs(field, &elemRtrn, &fieldRtrn, &arrayRtrn))
1342 return False; /* internal error -- already reported */
1344 if (elemRtrn.str != NULL)
1346 ERROR("Cannot change defaults in an action definition\n");
1347 ACTION("Ignoring attempt to change %s.%s\n", elemRtrn.str,
1350 free(fieldRtrn.str);
1353 if (!stringToField(fieldRtrn.str, &fieldNdx))
1355 ERROR("Unknown field name %s\n", uStringText(fieldRtrn.str));
1357 free(fieldRtrn.str);
1361 free(fieldRtrn.str);
1362 if (!(*handleAction[hndlrType])
1363 (xkb, action, fieldNdx, arrayRtrn, value))
1371 /***====================================================================***/
1374 SetActionField(struct xkb_desc * xkb,
1377 ExprDef * array_ndx, ExprDef * value, ActionInfo ** info_rtrn)
1379 ActionInfo *new, *old;
1381 if (!actionsInitialized)
1384 new = uTypedAlloc(ActionInfo);
1387 WSGO("Couldn't allocate space for action default\n");
1390 if (uStrCaseCmp(elem, "action") == 0)
1391 new->action = XkbSA_NoAction;
1394 if (!stringToAction(elem, &new->action))
1399 if (new->action == XkbSA_NoAction)
1401 ERROR("\"%s\" is not a valid field in a NoAction action\n",
1407 if (!stringToField(field, &new->field))
1409 ERROR("\"%s\" is not a legal field name\n", field);
1413 new->array_ndx = array_ndx;
1417 while ((old) && (old->next))
1426 /***====================================================================***/
1431 if (!actionsInitialized)
1433 bzero((char *) &constTrue, sizeof(constTrue));
1434 bzero((char *) &constFalse, sizeof(constFalse));
1435 constTrue.common.stmtType = StmtExpr;
1436 constTrue.common.next = NULL;
1437 constTrue.op = ExprIdent;
1438 constTrue.type = TypeBoolean;
1439 constTrue.value.str = xkb_intern_atom("true");
1440 constFalse.common.stmtType = StmtExpr;
1441 constFalse.common.next = NULL;
1442 constFalse.op = ExprIdent;
1443 constFalse.type = TypeBoolean;
1444 constFalse.value.str = xkb_intern_atom("false");
1445 actionsInitialized = 1;