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(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(XkbcDescPtr xkb,
337 XkbAnyAction * 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, NULL, NULL))
357 return ReportMismatch(action, field, "boolean");
361 *flags_inout &= ~tmp;
366 CheckModifierField(XkbcDescPtr xkb,
369 unsigned *flags_inout, unsigned *mods_rtrn)
373 if (value->op == ExprIdent)
375 register char *valStr;
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 (!ExprResolveModMask(value, &rtrn, LookupVModMask, (char *) xkb))
387 return ReportMismatch(action, F_Modifiers, "modifier mask");
388 *mods_rtrn = rtrn.uval;
389 *flags_inout &= ~XkbSA_UseModMapMods;
394 HandleSetLatchMods(XkbcDescPtr xkb,
395 XkbAnyAction * action,
396 unsigned field, ExprDef * array_ndx, ExprDef * value)
402 act = (XkbcModAction *) 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(XkbcDescPtr xkb,
440 XkbAnyAction * action,
441 unsigned field, ExprDef * array_ndx, ExprDef * value)
446 act = (XkbcModAction *) 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(XkbcDescPtr xkb,
515 XkbAnyAction * action,
516 unsigned field, ExprDef * array_ndx, ExprDef * value)
523 act = (XkbGroupAction *) 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))
550 XkbSASetGroup(act, t2);
555 return ReportIllegal(action->type, field);
559 HandleLockGroup(XkbcDescPtr xkb,
560 XkbAnyAction * action,
561 unsigned field, ExprDef * array_ndx, ExprDef * value)
567 act = (XkbGroupAction *) 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))
576 XkbSASetGroup(act, t2);
581 return ReportIllegal(action->type, field);
585 HandleMovePtr(XkbcDescPtr xkb,
586 XkbAnyAction * action,
587 unsigned field, ExprDef * array_ndx, ExprDef * value)
593 act = (XkbPtrAction *) 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;
609 XkbSetPtrActionX(act, rtrn.ival);
614 act->flags |= XkbSA_MoveAbsoluteY;
615 XkbSetPtrActionY(act, rtrn.ival);
619 else if (field == F_Accel)
621 if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
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 btnNames[] = {
641 static LookupEntry lockWhich[] = {
643 {"lock", XkbSA_LockNoUnlock},
644 {"neither", (XkbSA_LockNoLock | XkbSA_LockNoUnlock)},
645 {"unlock", XkbSA_LockNoLock},
650 HandlePtrBtn(XkbcDescPtr xkb,
651 XkbAnyAction * action,
652 unsigned field, ExprDef * array_ndx, ExprDef * value)
655 XkbPtrBtnAction *act;
657 act = (XkbPtrBtnAction *) action;
658 if (field == F_Button)
660 if (array_ndx != NULL)
661 return ReportActionNotArray(action->type, field);
662 if (!ExprResolveInteger
663 (value, &rtrn, SimpleLookup, (char *) btnNames))
664 return ReportMismatch(action->type, field,
665 "integer (range 1..5)");
666 if ((rtrn.ival < 0) || (rtrn.ival > 5))
668 ERROR("Button must specify default or be in the range 1..5\n");
669 ACTION("Illegal button value %d ignored\n", rtrn.ival);
672 act->button = rtrn.ival;
675 else if ((action->type == XkbSA_LockPtrBtn) && (field == F_Affect))
677 if (array_ndx != NULL)
678 return ReportActionNotArray(action->type, field);
679 if (!ExprResolveEnum(value, &rtrn, lockWhich))
680 return ReportMismatch(action->type, field, "lock or unlock");
681 act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
682 act->flags |= rtrn.ival;
685 else if (field == F_Count)
687 if (array_ndx != NULL)
688 return ReportActionNotArray(action->type, field);
689 if (!ExprResolveInteger
690 (value, &rtrn, SimpleLookup, (char *) btnNames))
691 return ReportMismatch(action->type, field, "integer");
692 if ((rtrn.ival < 0) || (rtrn.ival > 255))
694 ERROR("The count field must have a value in the range 0..255\n");
695 ACTION("Illegal count %d ignored\n", rtrn.ival);
698 act->count = rtrn.ival;
701 return ReportIllegal(action->type, field);
704 static LookupEntry ptrDflts[] = {
705 {"dfltbtn", XkbSA_AffectDfltBtn},
706 {"defaultbutton", XkbSA_AffectDfltBtn},
707 {"button", XkbSA_AffectDfltBtn},
712 HandleSetPtrDflt(XkbcDescPtr xkb,
713 XkbAnyAction * action,
714 unsigned field, ExprDef * array_ndx, ExprDef * value)
717 XkbPtrDfltAction *act;
719 act = (XkbPtrDfltAction *) action;
720 if (field == F_Affect)
722 if (array_ndx != NULL)
723 return ReportActionNotArray(action->type, field);
724 if (!ExprResolveEnum(value, &rtrn, ptrDflts))
725 return ReportMismatch(action->type, field, "pointer component");
726 act->affect = rtrn.uval;
729 else if ((field == F_Button) || (field == F_Value))
732 if (array_ndx != NULL)
733 return ReportActionNotArray(action->type, field);
734 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
736 act->flags &= ~XkbSA_DfltBtnAbsolute;
737 btn = value->value.child;
741 act->flags |= XkbSA_DfltBtnAbsolute;
745 if (!ExprResolveInteger
746 (btn, &rtrn, SimpleLookup, (char *) btnNames))
747 return ReportMismatch(action->type, field,
748 "integer (range 1..5)");
749 if ((rtrn.ival < 0) || (rtrn.ival > 5))
751 ERROR("New default button value must be in the range 1..5\n");
752 ACTION("Illegal default button value %d ignored\n", rtrn.ival);
757 ERROR("Cannot set default pointer button to \"default\"\n");
758 ACTION("Illegal default button setting ignored\n");
761 if (value->op == OpNegate)
762 XkbSASetPtrDfltValue(act, -rtrn.ival);
764 XkbSASetPtrDfltValue(act, rtrn.ival);
767 return ReportIllegal(action->type, field);
770 static LookupEntry isoNames[] = {
771 {"mods", XkbSA_ISONoAffectMods},
772 {"modifiers", XkbSA_ISONoAffectMods},
773 {"group", XkbSA_ISONoAffectGroup},
774 {"groups", XkbSA_ISONoAffectGroup},
775 {"ptr", XkbSA_ISONoAffectPtr},
776 {"pointer", XkbSA_ISONoAffectPtr},
777 {"ctrls", XkbSA_ISONoAffectCtrls},
778 {"controls", XkbSA_ISONoAffectCtrls},
779 {"all", ~((unsigned) 0)},
785 HandleISOLock(XkbcDescPtr xkb,
786 XkbAnyAction * action,
787 unsigned field, ExprDef * array_ndx, ExprDef * value)
791 unsigned flags, mods;
794 act = (XkbcISOAction *) action;
798 if (array_ndx != NULL)
799 return ReportActionNotArray(action->type, field);
801 if (CheckModifierField(xkb, action->type, value, &flags, &mods))
803 act->flags = flags & (~XkbSA_ISODfltIsGroup);
804 act->real_mods = mods & 0xff;
805 act->vmods = (mods >> 8) & 0xff;
810 if (array_ndx != NULL)
811 return ReportActionNotArray(action->type, field);
813 if (CheckGroupField(action->type, value, &flags, &group))
815 act->flags = flags | XkbSA_ISODfltIsGroup;
821 if (array_ndx != NULL)
822 return ReportActionNotArray(action->type, field);
823 if (!ExprResolveMask(value, &rtrn, SimpleLookup, (char *) isoNames))
824 return ReportMismatch(action->type, field, "keyboard component");
825 act->affect = (~rtrn.uval) & XkbSA_ISOAffectMask;
828 return ReportIllegal(action->type, field);
832 HandleSwitchScreen(XkbcDescPtr xkb,
833 XkbAnyAction * action,
834 unsigned field, ExprDef * array_ndx, ExprDef * value)
837 XkbSwitchScreenAction *act;
839 act = (XkbSwitchScreenAction *) action;
840 if (field == F_Screen)
843 if (array_ndx != NULL)
844 return ReportActionNotArray(action->type, field);
845 if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
847 act->flags &= ~XkbSA_SwitchAbsolute;
848 scrn = value->value.child;
852 act->flags |= XkbSA_SwitchAbsolute;
856 if (!ExprResolveInteger(scrn, &rtrn, NULL, NULL))
857 return ReportMismatch(action->type, field, "integer (0..255)");
858 if ((rtrn.ival < 0) || (rtrn.ival > 255))
860 ERROR("Screen index must be in the range 1..255\n");
861 ACTION("Illegal screen value %d ignored\n", rtrn.ival);
864 if (value->op == OpNegate)
865 XkbSASetScreen(act, -rtrn.ival);
867 XkbSASetScreen(act, rtrn.ival);
870 else if (field == F_Same)
872 if (array_ndx != NULL)
873 return ReportActionNotArray(action->type, field);
874 if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
875 return ReportMismatch(action->type, field, "boolean");
877 act->flags &= ~XkbSA_SwitchApplication;
879 act->flags |= XkbSA_SwitchApplication;
882 return ReportIllegal(action->type, field);
885 LookupEntry ctrlNames[] = {
886 {"repeatkeys", XkbRepeatKeysMask}
888 {"repeat", XkbRepeatKeysMask}
890 {"autorepeat", XkbRepeatKeysMask}
892 {"slowkeys", XkbSlowKeysMask}
894 {"bouncekeys", XkbBounceKeysMask}
896 {"stickykeys", XkbStickyKeysMask}
898 {"mousekeys", XkbMouseKeysMask}
900 {"mousekeysaccel", XkbMouseKeysAccelMask}
902 {"accessxkeys", XkbAccessXKeysMask}
904 {"accessxtimeout", XkbAccessXTimeoutMask}
906 {"accessxfeedback", XkbAccessXFeedbackMask}
908 {"audiblebell", XkbAudibleBellMask}
910 {"overlay1", XkbOverlay1Mask}
912 {"overlay2", XkbOverlay2Mask}
914 {"ignoregrouplock", XkbIgnoreGroupLockMask}
916 {"all", XkbAllBooleanCtrlsMask}
924 HandleSetLockControls(XkbcDescPtr xkb,
925 XkbAnyAction * action,
926 unsigned field, ExprDef * array_ndx, ExprDef * value)
929 XkbcCtrlsAction *act;
931 act = (XkbcCtrlsAction *) action;
932 if (field == F_Controls)
934 if (array_ndx != NULL)
935 return ReportActionNotArray(action->type, field);
937 (value, &rtrn, SimpleLookup, (char *) ctrlNames))
938 return ReportMismatch(action->type, field, "controls mask");
939 act->ctrls = rtrn.uval;
942 return ReportIllegal(action->type, field);
945 static LookupEntry evNames[] = {
946 {"press", XkbSA_MessageOnPress},
947 {"keypress", XkbSA_MessageOnPress},
948 {"release", XkbSA_MessageOnRelease},
949 {"keyrelease", XkbSA_MessageOnRelease},
950 {"all", XkbSA_MessageOnPress | XkbSA_MessageOnRelease},
956 HandleActionMessage(XkbcDescPtr xkb,
957 XkbAnyAction * action,
958 unsigned field, ExprDef * array_ndx, ExprDef * value)
961 XkbMessageAction *act;
963 act = (XkbMessageAction *) action;
967 if (array_ndx != NULL)
968 return ReportActionNotArray(action->type, field);
969 if (!ExprResolveMask(value, &rtrn, SimpleLookup, (char *) evNames))
970 return ReportMismatch(action->type, field, "key event mask");
971 act->flags &= ~(XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
973 rtrn.uval & (XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
976 if (array_ndx != NULL)
977 return ReportActionNotArray(action->type, field);
978 if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
979 return ReportMismatch(action->type, field, "boolean");
981 act->flags |= XkbSA_MessageGenKeyEvent;
983 act->flags &= ~XkbSA_MessageGenKeyEvent;
986 if (array_ndx == NULL)
988 if (!ExprResolveString(value, &rtrn, NULL, NULL))
989 return ReportMismatch(action->type, field, "string");
992 int len = strlen(rtrn.str);
993 if ((len < 1) || (len > 6))
995 WARN("An action message can hold only 6 bytes\n");
996 ACTION("Extra %d bytes ignored\n", len - 6);
998 strncpy((char *) act->message, rtrn.str, 6);
1005 if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL))
1007 ERROR("Array subscript must be integer\n");
1008 ACTION("Illegal subscript ignored\n");
1014 ERROR("An action message is at most 6 bytes long\n");
1015 ACTION("Attempt to use data[%d] ignored\n", ndx);
1018 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1019 return ReportMismatch(action->type, field, "integer");
1020 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1022 ERROR("Message data must be in the range 0..255\n");
1023 ACTION("Illegal datum %d ignored\n", rtrn.ival);
1026 act->message[ndx] = rtrn.uval;
1030 return ReportIllegal(action->type, field);
1034 HandleRedirectKey(XkbcDescPtr xkb,
1035 XkbAnyAction * action,
1036 unsigned field, ExprDef * array_ndx, ExprDef * value)
1039 XkbRedirectKeyAction *act;
1043 if (array_ndx != NULL)
1044 return ReportActionNotArray(action->type, field);
1046 act = (XkbRedirectKeyAction *) action;
1050 if (!ExprResolveKeyName(value, &rtrn, NULL, NULL))
1051 return ReportMismatch(action->type, field, "key name");
1052 tmp = KeyNameToLong(rtrn.keyName.name);
1053 if (!FindNamedKey(xkb, tmp, &t1, True, CreateKeyNames(xkb), 0))
1055 return ReportNotFound(action->type, field, "Key",
1056 XkbcKeyNameText(rtrn.keyName.name));
1063 if (CheckModifierField(xkb, action->type, value, &t1, &t2))
1065 act->mods_mask |= (t2 & 0xff);
1066 if (field == F_Modifiers)
1067 act->mods |= (t2 & 0xff);
1069 act->mods &= ~(t2 & 0xff);
1071 t2 = (t2 >> 8) & 0xffff;
1072 XkbSARedirectSetVModsMask(act, XkbSARedirectVModsMask(act) | t2);
1073 if (field == F_Modifiers)
1074 XkbSARedirectSetVMods(act, XkbSARedirectVMods(act) | t2);
1076 XkbSARedirectSetVMods(act, XkbSARedirectVMods(act) & ~t2);
1081 return ReportIllegal(action->type, field);
1085 HandleDeviceBtn(XkbcDescPtr xkb,
1086 XkbAnyAction * action,
1087 unsigned field, ExprDef * array_ndx, ExprDef * value)
1090 XkbDeviceBtnAction *act;
1092 act = (XkbDeviceBtnAction *) action;
1093 if (field == F_Button)
1095 if (array_ndx != NULL)
1096 return ReportActionNotArray(action->type, field);
1097 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1098 return ReportMismatch(action->type, field,
1099 "integer (range 1..255)");
1100 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1102 ERROR("Button must specify default or be in the range 1..255\n");
1103 ACTION("Illegal button value %d ignored\n", rtrn.ival);
1106 act->button = rtrn.ival;
1109 else if ((action->type == XkbSA_LockDeviceBtn) && (field == F_Affect))
1111 if (array_ndx != NULL)
1112 return ReportActionNotArray(action->type, field);
1113 if (!ExprResolveEnum(value, &rtrn, lockWhich))
1114 return ReportMismatch(action->type, field, "lock or unlock");
1115 act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
1116 act->flags |= rtrn.ival;
1119 else if (field == F_Count)
1121 if (array_ndx != NULL)
1122 return ReportActionNotArray(action->type, field);
1123 if (!ExprResolveInteger
1124 (value, &rtrn, SimpleLookup, (char *) btnNames))
1125 return ReportMismatch(action->type, field, "integer");
1126 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1128 ERROR("The count field must have a value in the range 0..255\n");
1129 ACTION("Illegal count %d ignored\n", rtrn.ival);
1132 act->count = rtrn.ival;
1135 else if (field == F_Device)
1137 if (array_ndx != NULL)
1138 return ReportActionNotArray(action->type, field);
1139 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1140 return ReportMismatch(action->type, field,
1141 "integer (range 1..255)");
1142 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1144 ERROR("Device must specify default or be in the range 1..255\n");
1145 ACTION("Illegal device value %d ignored\n", rtrn.ival);
1148 act->device = rtrn.ival;
1151 return ReportIllegal(action->type, field);
1155 HandleDeviceValuator(XkbcDescPtr xkb,
1156 XkbAnyAction * action,
1157 unsigned field, ExprDef * array_ndx, ExprDef * value)
1161 XkbDeviceValuatorAction *act;
1163 act = (XkbDeviceValuatorAction *) action;
1164 /* XXX - Not yet implemented */
1170 HandlePrivate(XkbcDescPtr xkb,
1171 XkbAnyAction * action,
1172 unsigned field, ExprDef * array_ndx, ExprDef * value)
1179 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1180 return ReportMismatch(PrivateAction, field, "integer");
1181 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1183 ERROR("Private action type must be in the range 0..255\n");
1184 ACTION("Illegal type %d ignored\n", rtrn.ival);
1187 action->type = rtrn.uval;
1190 if (array_ndx == NULL)
1192 if (!ExprResolveString(value, &rtrn, NULL, NULL))
1193 return ReportMismatch(action->type, field, "string");
1196 int len = strlen(rtrn.str);
1197 if ((len < 1) || (len > 7))
1199 WARN("A private action has 7 data bytes\n");
1200 ACTION("Extra %d bytes ignored\n", len - 6);
1203 strncpy((char *) action->data, rtrn.str, 7);
1211 if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL))
1213 ERROR("Array subscript must be integer\n");
1214 ACTION("Illegal subscript ignored\n");
1220 ERROR("The data for a private action is 7 bytes long\n");
1221 ACTION("Attempt to use data[%d] ignored\n", ndx);
1224 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
1225 return ReportMismatch(action->type, field, "integer");
1226 if ((rtrn.ival < 0) || (rtrn.ival > 255))
1228 ERROR("All data for a private action must be 0..255\n");
1229 ACTION("Illegal datum %d ignored\n", rtrn.ival);
1232 action->data[ndx] = rtrn.uval;
1236 return ReportIllegal(PrivateAction, field);
1239 typedef Bool(*actionHandler) (XkbcDescPtr /* xkb */ ,
1240 XkbAnyAction * /* action */ ,
1241 unsigned /* field */ ,
1242 ExprDef * /* array_ndx */ ,
1243 ExprDef * /* value */
1246 static actionHandler handleAction[XkbSA_NumActions + 1] = {
1247 HandleNoAction /* NoAction */ ,
1248 HandleSetLatchMods /* SetMods */ ,
1249 HandleSetLatchMods /* LatchMods */ ,
1250 HandleLockMods /* LockMods */ ,
1251 HandleSetLatchGroup /* SetGroup */ ,
1252 HandleSetLatchGroup /* LatchGroup */ ,
1253 HandleLockGroup /* LockGroup */ ,
1254 HandleMovePtr /* MovePtr */ ,
1255 HandlePtrBtn /* PtrBtn */ ,
1256 HandlePtrBtn /* LockPtrBtn */ ,
1257 HandleSetPtrDflt /* SetPtrDflt */ ,
1258 HandleISOLock /* ISOLock */ ,
1259 HandleNoAction /* Terminate */ ,
1260 HandleSwitchScreen /* SwitchScreen */ ,
1261 HandleSetLockControls /* SetControls */ ,
1262 HandleSetLockControls /* LockControls */ ,
1263 HandleActionMessage /* ActionMessage */ ,
1264 HandleRedirectKey /* RedirectKey */ ,
1265 HandleDeviceBtn /* DeviceBtn */ ,
1266 HandleDeviceBtn /* LockDeviceBtn */ ,
1267 HandleDeviceValuator /* DeviceValuatr */ ,
1268 HandlePrivate /* Private */
1271 /***====================================================================***/
1274 ApplyActionFactoryDefaults(XkbcAction * action)
1276 if (action->type == XkbSA_SetPtrDflt)
1277 { /* increment default button */
1278 action->dflt.affect = XkbSA_AffectDfltBtn;
1279 action->dflt.flags = 0;
1280 action->dflt.value = 1;
1282 else if (action->type == XkbSA_ISOLock)
1284 action->iso.real_mods = LockMask;
1291 HandleActionDef(ExprDef * def,
1293 XkbAnyAction * action, unsigned mergeMode, ActionInfo * info)
1297 unsigned tmp, hndlrType;
1299 if (!actionsInitialized)
1302 if (def->op != ExprActionDecl)
1304 ERROR("Expected an action definition, found %s\n",
1305 exprOpText(def->op));
1308 str = XkbcAtomGetString(def->value.action.name);
1311 WSGO("Missing name in action definition!!\n");
1314 if (!stringToAction(str, &tmp))
1316 ERROR("Unknown action %s\n", str);
1319 action->type = hndlrType = tmp;
1320 if (action->type != XkbSA_NoAction)
1322 ApplyActionFactoryDefaults((XkbcAction *) action);
1325 if ((info->action == XkbSA_NoAction)
1326 || (info->action == hndlrType))
1328 if (!(*handleAction[hndlrType]) (xkb, action,
1339 for (arg = def->value.action.args; arg != NULL;
1340 arg = (ExprDef *) arg->common.next)
1342 ExprDef *field, *value, *arrayRtrn;
1343 ExprResult elemRtrn, fieldRtrn;
1346 if (arg->op == OpAssign)
1348 field = arg->value.binary.left;
1349 value = arg->value.binary.right;
1353 if ((arg->op == OpNot) || (arg->op == OpInvert))
1355 field = arg->value.child;
1356 value = &constFalse;
1364 if (!ExprResolveLhs(field, &elemRtrn, &fieldRtrn, &arrayRtrn))
1365 return False; /* internal error -- already reported */
1367 if (elemRtrn.str != NULL)
1369 ERROR("Cannot change defaults in an action definition\n");
1370 ACTION("Ignoring attempt to change %s.%s\n", elemRtrn.str,
1373 free(fieldRtrn.str);
1376 if (!stringToField(fieldRtrn.str, &fieldNdx))
1378 ERROR("Unknown field name %s\n", uStringText(fieldRtrn.str));
1380 free(fieldRtrn.str);
1384 free(fieldRtrn.str);
1385 if (!(*handleAction[hndlrType])
1386 (xkb, action, fieldNdx, arrayRtrn, value))
1394 /***====================================================================***/
1397 SetActionField(XkbcDescPtr xkb,
1400 ExprDef * array_ndx, ExprDef * value, ActionInfo ** info_rtrn)
1402 ActionInfo *new, *old;
1404 if (!actionsInitialized)
1407 new = uTypedAlloc(ActionInfo);
1410 WSGO("Couldn't allocate space for action default\n");
1413 if (uStrCaseCmp(elem, "action") == 0)
1414 new->action = XkbSA_NoAction;
1417 if (!stringToAction(elem, &new->action))
1422 if (new->action == XkbSA_NoAction)
1424 ERROR("\"%s\" is not a valid field in a NoAction action\n",
1430 if (!stringToField(field, &new->field))
1432 ERROR("\"%s\" is not a legal field name\n", field);
1436 new->array_ndx = array_ndx;
1440 while ((old) && (old->next))
1449 /***====================================================================***/
1454 if (!actionsInitialized)
1456 bzero((char *) &constTrue, sizeof(constTrue));
1457 bzero((char *) &constFalse, sizeof(constFalse));
1458 constTrue.common.stmtType = StmtExpr;
1459 constTrue.common.next = NULL;
1460 constTrue.op = ExprIdent;
1461 constTrue.type = TypeBoolean;
1462 constTrue.value.str = XkbcInternAtom("true", False);
1463 constFalse.common.stmtType = StmtExpr;
1464 constFalse.common.next = NULL;
1465 constFalse.op = ExprIdent;
1466 constFalse.type = TypeBoolean;
1467 constFalse.value.str = XkbcInternAtom("false", False);
1468 actionsInitialized = 1;