3 Copyright 1988, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
38 #ifdef HAVE_STRNCASECMP
42 static XModifierKeymap *map = NULL;
46 * The routines in this file manipulate a queue of intructions. Instead of
47 * executing each line as it is entered, we build up a list of actions to
48 * take and execute them all at the end. This allows us to find all errors
49 * at once, and to preserve the context in which we are looking up keysyms.
52 struct wq work_queue = {NULL, NULL};
56 * common utility routines
60 KeysymToKeycodes(Display *dpy, KeySym keysym, int *pnum_kcs)
66 for (i = min_keycode; i <= max_keycode; i++) {
67 for (j = 0; j < 8; j++) {
68 if (XKeycodeToKeysym(dpy, (KeyCode) i, j) == keysym) {
70 kcs = (KeyCode *)malloc(sizeof(KeyCode));
72 kcs = (KeyCode *)realloc((char *)kcs,
73 sizeof(KeyCode) * (*pnum_kcs + 1));
84 copy_to_scratch(const char *s, int len)
86 static char *buf = NULL;
87 static int buflen = 0;
94 buflen = (len < 40) ? 80 : (len * 2);
95 buf = (char *) malloc (buflen+1);
97 fprintf (stderr, "attempt to allocate %d byte scratch buffer\n", buflen + 1);
102 strncpy (buf, s, len);
111 fprintf (stderr, "%s: %s:%d: bad ", ProgramName, inputFilename, lineno+1);
115 #define badmsg0(what) { badheader(); fprintf (stderr, what); \
116 putc ('\n', stderr); }
118 #define badmsg(what,arg) { badheader(); fprintf (stderr, what, arg); \
119 putc ('\n', stderr); }
121 #define badmsgn(what,s,len) badmsg (what, copy_to_scratch (s, len))
124 initialize_map (void)
126 map = XGetModifierMapping (dpy);
130 static void do_keycode ( char *line, int len );
131 static void do_keysym ( char *line, int len );
132 static void finish_keycodes ( const char *line, int len, KeyCode *keycodes,
134 static void do_add ( char *line, int len );
135 static void do_remove ( char *line, int len );
136 static void do_clear ( char *line, int len );
137 static void do_pointer ( char *line, int len );
138 static int get_keysym_list ( const char *line, int len, int *np, KeySym **kslistp );
140 static void print_opcode(union op *op);
142 static int skip_word ( const char *s, int len );
143 static int skip_chars ( const char *s, int len );
144 static int skip_space ( const char *s, int len );
147 const char *command; /* name of input command */
148 int length; /* length of command */
149 void (*proc)(char *, int); /* handler */
150 } dispatch_table[] = {
151 { "keycode", 7, do_keycode },
152 { "keysym", 6, do_keysym },
153 { "add", 3, do_add },
154 { "remove", 6, do_remove },
155 { "clear", 5, do_clear },
156 { "pointer", 7, do_pointer },
160 * handle_line - this routine parses the input line (which has had all leading
161 * and trailing whitespace removed) and builds up the work queue.
165 handle_line(char *line, /* string to parse */
166 int len) /* length of line */
171 n = skip_chars (line, len);
173 badmsg ("input line '%s'", line);
177 for (dtp = dispatch_table; dtp->command != NULL; dtp++) {
178 if (n == dtp->length &&
179 strncmp (line, dtp->command, dtp->length) == 0) {
181 n += skip_space (line+n, len-n);
184 (*(dtp->proc)) (line, len);
189 fprintf (stderr, "%s: unknown command on line %s:%d\n",
190 ProgramName, inputFilename, lineno+1);
195 * the following routines are useful for parsing
199 skip_word (const char *s, int len)
203 n = skip_chars (s, len);
204 return (n + skip_space (s+n, len-n));
208 skip_chars(const char *s, int len)
212 if (len <= 0 || !s || *s == '\0') return (0);
214 for (i = 0; i < len; i++) {
215 if (isspace(s[i])) break;
221 skip_space(const char *s, int len)
225 if (len <= 0 || !s || *s == '\0') return (0);
227 for (i = 0; i < len; i++) {
228 if (!s[i] || !isspace(s[i])) break;
235 skip_until_char(const char *s, int len, char c)
239 for (i = 0; i < len; i++) {
240 if (s[i] == c) break;
247 * The action routines.
249 * This is where the real work gets done. Each routine is responsible for
250 * parsing its input (note that the command keyword has been stripped off)
251 * and adding to the work queue. They are also in charge of outputting
252 * error messages and returning non-zero if there is a problem.
254 * The following global variables are available:
255 * dpy the display descriptor
256 * work_queue linked list of opcodes
257 * inputFilename name of the file being processed
258 * lineno line number of current line in input file
261 add_to_work_queue(union op *p) /* this can become a macro someday */
263 if (work_queue.head == NULL) { /* nothing on the list */
264 work_queue.head = work_queue.tail = p; /* head, tail, no prev */
266 work_queue.tail->generic.next = p; /* head okay, prev */
267 work_queue.tail = p; /* tail */
269 p->generic.next = NULL;
278 parse_number(const char *str, unsigned long *val)
280 const char *fmt = "%ld";
284 while (isspace(*str))
291 if (*str == 'x' || *str == 'X') {
296 return (sscanf (str, fmt, val) == 1);
300 parse_keysym(const char *line, int n, char **name, KeySym *keysym)
302 *name = copy_to_scratch (line, n);
303 if (!strcmp(*name, "NoSymbol")) {
307 *keysym = XStringToKeysym (*name);
308 if (*keysym == NoSymbol && '0' <= **name && **name <= '9')
309 return parse_number(*name, keysym);
310 return (*keysym != NoSymbol);
314 * do_keycode - parse off lines of the form
316 * "keycode" number "=" [keysym ...]
319 * where number is in decimal, hex, or octal. Any number of keysyms may be
324 do_keycode(char *line, int len)
327 const char *fmt = "%d";
330 if (len < 3 || !line || *line == '\0') { /* 5=a minimum */
331 badmsg0 ("keycode input line");
336 * We need not bother to advance line/len past the
337 * number (or the string 'any') as finish_keycodes() will
338 * first advance past the '='.
340 if (!strncmp("any", line, 3)) {
343 if (*line == '0') line++, len--, fmt = "%o";
344 if (*line == 'x' || *line == 'X') line++, len--, fmt = "%x";
347 if (sscanf (line, fmt, &dummy) != 1 || dummy == 0) {
348 badmsg0 ("keycode value");
351 keycode = (KeyCode) dummy;
352 if ((int)keycode < min_keycode || (int)keycode > max_keycode) {
353 badmsg0 ("keycode value (out of range)");
358 finish_keycodes (line, len, &keycode, 1);
363 * do_keysym - parse off lines of the form
365 * "keysym" keysym "=" [keysym ...]
368 * The left keysyms has to be checked for validity and evaluated.
372 do_keysym(char *line, int len)
379 if (len < 3 || !line || *line == '\0') { /* a=b minimum */
380 badmsg0 ("keysym input line");
384 n = skip_chars (line, len);
386 badmsg0 ("target keysym name");
389 if (!parse_keysym(line, n, &tmpname, &keysym)) {
390 badmsg ("keysym target key symbol '%s'", tmpname);
394 keycodes = KeysymToKeycodes (dpy, keysym, &n);
396 badmsg ("keysym target keysym '%s', no corresponding keycodes",
402 printf ("! Keysym %s (0x%lx) corresponds to keycode(s)",
403 tmpname, (long) keysym);
404 for (i = 0; i < n; i++)
405 printf (" 0x%x", keycodes[i]);
409 finish_keycodes (line, len, keycodes, n);
413 finish_keycodes(const char *line, int len, KeyCode *keycodes, int count)
418 struct op_keycode *opk;
420 n = skip_until_char (line, len, '=');
423 if (len < 1 || *line != '=') { /* = minimum */
424 badmsg0 ("keycode command (missing keysym list),");
427 line++, len--; /* skip past the = */
429 n = skip_space (line, len);
432 /* allow empty list */
433 if (get_keysym_list (line, len, &n, &kslist) < 0)
436 while (--count >= 0) {
437 uop = AllocStruct (union op);
439 badmsg ("attempt to allocate a %ld byte keycode opcode",
440 (long) sizeof (struct op_keycode));
445 opk->type = doKeycode;
446 opk->target_keycode = keycodes[count];
448 opk->keysyms = kslist;
450 add_to_work_queue (uop);
454 /* make sure we handle any special keys */
455 check_special_keys (keycode, n, kslist);
461 * parse_modifier - convert a modifier string name to its index
464 struct modtab modifier_table[] = { /* keep in order so it can be index */
477 parse_modifier(char *line, int n)
482 /* lowercase for comparison against table */
483 for (i = 0; i < n; i++) {
484 if (isupper (line[i])) line[i] = tolower (line[i]);
487 for (mt = modifier_table; mt->name; mt++) {
488 if (n == mt->length && strncmp (line, mt->name, n) == 0)
496 * do_add - parse off lines of the form
498 * add MODIFIER = keysym ...
500 * where the MODIFIER is one of Shift, Lock, Control, Mod[1-5] where case
501 * is not important. There should also be an alias Ctrl for control.
505 do_add(char *line, int len)
511 struct op_addmodifier *opam;
513 if (len < 6 || !line || *line == '\0') { /* Lock=a minimum */
514 badmsg0 ("add modifier input line");
518 n = skip_chars (line, len);
520 badmsg ("add modifier name %s", line);
524 modifier = parse_modifier (line, n);
526 badmsgn ("add modifier name '%s', not allowed", line, n);
531 n = skip_until_char (line, len, '=');
533 badmsg0 ("add modifier = keysym");
538 n += skip_space (line+n, len-n);
541 if (get_keysym_list (line, len, &n, &kslist) < 0)
544 badmsg0 ("add modifier keysym list (empty)");
548 uop = AllocStruct (union op);
550 badmsg ("attempt to allocate %ld byte addmodifier opcode",
551 (long) sizeof (struct op_addmodifier));
554 opam = &uop->addmodifier;
556 opam->type = doAddModifier;
557 opam->modifier = modifier;
559 opam->keysyms = kslist;
561 add_to_work_queue (uop);
564 #ifdef AUTO_ADD_REMOVE
566 * make_add - stick a single add onto the queue
569 make_add(int modifier, KeySym keysym)
572 struct op_addmodifier *opam;
574 uop = AllocStruct (union op);
576 badmsg ("attempt to allocate %ld byte addmodifier opcode",
577 (long) sizeof (struct op_addmodifier));
580 opam = &uop->addmodifier;
582 opam->type = doAddModifier;
583 opam->modifier = modifier;
585 opam->keysyms = (KeySym *) malloc (sizeof (KeySym));
586 if (!opam->keysyms) {
587 badmsg ("attempt to allocate %ld byte KeySym", (long) sizeof (KeySym));
588 free ((char *) opam);
591 opam->keysyms[0] = keysym;
593 add_to_work_queue (uop);
596 #endif /* AUTO_ADD_REMOVE */
600 * do_remove - parse off lines of the form
602 * remove MODIFIER = oldkeysym ...
604 * where the MODIFIER is one of Shift, Lock, Control, Mod[1-5] where case
605 * is not important. There should also be an alias Ctrl for control.
609 do_remove(char *line, int len)
619 struct op_removemodifier *oprm;
621 if (len < 6 || !line || *line == '\0') { /* Lock=a minimum */
622 badmsg0 ("remove modifier input line");
626 n = skip_chars (line, len);
628 badmsg ("remove modifier name %s", line);
632 modifier = parse_modifier (line, n);
634 badmsgn ("remove modifier name '%s', not allowed", line, n);
639 n = skip_until_char (line, len, '=');
641 badmsg0 ("remove modifier = keysym");
646 n += skip_space (line+n, len-n);
649 if (get_keysym_list (line, len, &n, &kslist) < 0)
652 badmsg0 ("remove modifier keysym list (empty)");
657 * unlike the add command, we have to now evaluate the keysyms
660 kclist = (KeyCode *) malloc (n * sizeof (KeyCode));
662 badmsg ("attempt to allocate %ld byte keycode list",
663 (long) (n * sizeof (KeyCode)));
664 free ((char *) kslist);
670 for (i = 0; i < n; i++) {
673 kcs = KeysymToKeycodes (dpy, kslist[i], &num_kcs);
675 char *tmpname = XKeysymToString (kslist[i]);
676 badmsg ("keysym in remove modifier list '%s', no corresponding keycodes",
677 tmpname ? tmpname : "?");
682 char *tmpname = XKeysymToString (kslist[i]);
683 printf ("! Keysym %s (0x%lx) corresponds to keycode(s)",
684 tmpname ? tmpname : "?", (long) kslist[i]);
685 for (j = 0; j < num_kcs; j++)
686 printf(" 0x%x", kcs[j]);
689 if (nc + num_kcs > tot) {
691 kclist = (KeyCode *)realloc((char *)kclist, tot * sizeof(KeyCode));
693 badmsg ("attempt to allocate %ld byte keycode list",
694 (long) (tot * sizeof (KeyCode)));
695 free ((char *) kslist);
699 while (--num_kcs >= 0)
700 kclist[nc++] = *kcs++; /* okay, add it to list */
703 free ((char *) kslist); /* all done with it */
705 uop = AllocStruct (union op);
707 badmsg ("attempt to allocate %ld byte removemodifier opcode",
708 (long) sizeof (struct op_removemodifier));
711 oprm = &uop->removemodifier;
713 oprm->type = doRemoveModifier;
714 oprm->modifier = modifier;
716 oprm->keycodes = kclist;
718 add_to_work_queue (uop);
721 #ifdef AUTO_ADD_REMOVE
723 * make_remove - stick a single remove onto the queue
726 make_remove(int modifier, KeyCode keycode)
729 struct op_removemodifier *oprm;
731 uop = AllocStruct (union op);
733 badmsg ("attempt to allocate %ld byte removemodifier opcode",
734 (long) sizeof (struct op_removemodifier));
737 oprm = &uop->removemodifier;
739 oprm->type = doRemoveModifier;
740 oprm->modifier = modifier;
742 oprm->keycodes = (KeyCode *) malloc (sizeof (KeyCode));
743 if (!oprm->keycodes) {
744 badmsg ("attempt to allocate %ld byte KeyCode",
745 (long) sizeof (KeyCode));
746 free ((char *) oprm);
749 oprm->keycodes[0] = keycode;
751 add_to_work_queue (uop);
754 #endif /* AUTO_ADD_REMOVE */
758 * do_clear - parse off lines of the form
765 do_clear(char *line, int len)
770 struct op_clearmodifier *opcm;
772 if (len < 4 || !line || *line == '\0') { /* Lock minimum */
773 badmsg0 ("clear modifier input line");
777 n = skip_chars (line, len);
779 modifier = parse_modifier (line, n);
781 badmsgn ("clear modifier name '%s'", line, n);
784 n += skip_space (line+n, len-n);
786 badmsgn ("extra argument '%s' to clear modifier", line+n, len-n);
787 /* okay to continue */
790 uop = AllocStruct (union op);
792 badmsg ("attempt to allocate %ld byte clearmodifier opcode",
793 (long) sizeof (struct op_clearmodifier));
796 opcm = &uop->clearmodifier;
798 opcm->type = doClearModifier;
799 opcm->modifier = modifier;
801 add_to_work_queue (uop);
804 #ifndef HAVE_STRNCASECMP
806 strncasecmp(const char *a, const char *b, int n)
811 for (i = 0; i < n; i++, a++, b++) {
816 a1 = (isascii(*a) && isupper(*a)) ? tolower(*a) : *a;
817 b1 = (isascii(*b) && isupper(*b)) ? tolower(*b) : *b;
818 if (a1 != b1) return b1 - a1;
826 * do_pointer = get list of numbers of the form
828 * buttons = NUMBER ...
833 do_pointer(char *line, int len)
839 struct op_pointer *opp;
840 unsigned char buttons[MAXBUTTONCODES];
845 if (len < 2 || !line || *line == '\0') { /* =1 minimum */
846 badmsg0 ("buttons input line");
850 nbuttons = XGetPointerMapping (dpy, buttons, MAXBUTTONCODES);
852 n = skip_space (line, len);
855 if (line[0] != '=') {
856 badmsg0 ("buttons pointer code list, missing equal sign");
860 line++, len--; /* skip = */
861 n = skip_space (line, len);
865 if (len < 7 || strncasecmp (line, "default", 7) != 0) {
867 n = skip_space (line, len);
869 if (line[0] == '\0') break;
870 n = skip_word (line, len);
872 badmsg ("skip of word in buttons line: %s", line);
875 strval = copy_to_scratch(line, n);
876 ok = parse_number (strval, &val);
877 if (!ok || val >= MAXBUTTONCODES) {
878 badmsg ("value %s given for buttons list", strval);
881 buttons[i++] = (unsigned char) val;
886 if (i > 0 && i != nbuttons) {
887 fprintf (stderr, "Warning: Only changing the first %d of %d buttons.\n",
892 uop = AllocStruct (union op);
894 badmsg ("attempt to allocate a %ld byte pointer opcode",
895 (long) sizeof (struct op_pointer));
900 opp->type = doPointer;
902 for (i = 0; i < opp->count; i++) {
903 opp->button_codes[i] = buttons[i];
906 add_to_work_queue (uop);
911 * get_keysym_list - parses the rest of the line into a keysyms assumes
912 * that the = sign has been parsed off but there may be leading whitespace
917 * this involves getting the word containing the keysym, checking its range,
918 * and adding it to the list.
922 get_keysym_list(const char *line, int len, int *np, KeySym **kslistp)
924 int havesofar, maxcanhave;
930 if (len == 0) return (0); /* empty list */
933 maxcanhave = 4; /* most lists are small */
934 keysymlist = (KeySym *) malloc (maxcanhave * sizeof (KeySym));
936 badmsg ("attempt to allocate %ld byte initial keysymlist",
937 (long) (maxcanhave * sizeof (KeySym)));
947 n = skip_space (line, len);
950 n = skip_chars (line, len);
952 badmsg0 ("keysym name list");
957 ok = parse_keysym (line, n, &tmpname, &keysym);
960 badmsg ("keysym name '%s' in keysym list", tmpname);
961 /* do NOT return here, look for others */
966 * Do NOT test to see if the keysym translates to a keycode or you
967 * won't be able to assign new ones....
970 /* grow the list bigger if necessary */
971 if (havesofar >= maxcanhave) {
972 KeySym *origkeysymlist = keysymlist;
974 keysymlist = (KeySym *) realloc (keysymlist,
975 maxcanhave * sizeof (KeySym));
977 badmsg ("attempt to grow keysym list to %ld bytes",
978 (long) (maxcanhave * sizeof (KeySym)));
979 free(origkeysymlist);
984 /* and add it to the list */
985 keysymlist[havesofar++] = keysym;
988 *kslistp = keysymlist;
996 * check_special_keys - run through list of keysyms and generate "add" or
997 * "remove" commands for for any of the key syms that appear in the modifier
998 * list. this involves running down the modifier map which is an array of
999 * 8 by map->max_keypermod keycodes.
1003 check_special_keys(KeyCode keycode, int n, KeySym *kslist)
1005 int i; /* iterator variable */
1006 KeyCode *kcp; /* keycode pointer */
1009 * walk the modifiermap array. since its dimensions are not known at
1010 * compile time, we have to walk it by hand instead of indexing. this
1011 * is why it is initialized outside the loop, but incremented inside the
1015 kcp = map->modifiermap; /* start at beginning and iterate */
1016 for (i = 0; i < 8; i++) { /* there are 8 modifier keys */
1019 for (j = 0; j < map->max_keypermod; j++, kcp++) {
1023 if (!*kcp) continue; /* only non-zero entries significant */
1026 * check to see if the target keycode is already a modifier; if so,
1027 * then we have to remove it
1029 if (keycode == *kcp) {
1030 make_remove (i, keycode);
1034 * now, check to see if any of the keysyms map to keycodes
1035 * that are in the modifier list
1037 for (k = 0; k < n; k++) {
1040 kc = XKeysymToKeycode (dpy, kslist[k]);
1041 if (kc == *kcp) { /* yup, found one */
1043 * have to generate a remove of the CURRENT keycode
1044 * and then an add of the new KEYCODE
1046 make_remove (i, kc); /* modifier, keycode */
1047 make_add (i, kslist[k]); /* modifier, keysym */
1057 * print_work_queue - disassemble the work queue and print it on stdout
1061 print_work_queue(void)
1065 printf ("! dump of work queue\n");
1066 for (op = work_queue.head; op; op = op->generic.next) {
1073 print_opcode(union op *op)
1078 switch (op->generic.type) {
1080 if (op->keycode.target_keycode)
1081 printf ("keycode 0x%lx =", (long) op->keycode.target_keycode);
1083 printf ("keycode any =");
1084 for (i = 0; i < op->keycode.count; i++) {
1085 char *name = XKeysymToString (op->keycode.keysyms[i]);
1087 printf (" %s", name ? name : "BADKEYSYM");
1092 printf ("add %s =", modifier_table[op->addmodifier.modifier].name);
1093 for (i = 0; i < op->addmodifier.count; i++) {
1094 char *name = XKeysymToString (op->addmodifier.keysyms[i]);
1095 printf (" %s", name ? name : "BADKEYSYM");
1099 case doRemoveModifier:
1100 printf ("remove %s = ",
1101 modifier_table[op->removemodifier.modifier].name);
1102 for (i = 0; i < op->removemodifier.count; i++) {
1103 printf (" 0x%lx", (long) op->removemodifier.keycodes[i]);
1107 case doClearModifier:
1108 printf ("clear %s\n", modifier_table[op->clearmodifier.modifier].name);
1111 printf ("pointer = ");
1112 if (op->pointer.count == 0)
1114 else for (i=0; i < op->pointer.count; i++)
1115 printf(" %d", op->pointer.button_codes[i]);
1119 printf ("! unknown opcode %d\n", op->generic.type);
1126 * execute_work_queue - do the real meat and potatoes now that we know what
1127 * we need to do and that all of the input is correct.
1129 static int exec_keycode ( struct op_keycode *opk );
1130 static int exec_add ( struct op_addmodifier *opam );
1131 static int exec_remove ( struct op_removemodifier *oprm );
1132 static int exec_clear ( struct op_clearmodifier *opcm );
1133 static int exec_pointer ( struct op_pointer *opp );
1137 execute_work_queue (void)
1141 Bool update_map = False;
1146 printf ("! executing work queue\n");
1153 for (op = work_queue.head; op; op = op->generic.next) {
1154 if (verbose) print_opcode (op);
1156 /* check to see if we have to update the keyboard mapping */
1159 op->generic.type != doKeycode ||
1160 !op->keycode.target_keycode)) {
1162 while (XEventsQueued (dpy, QueuedAlready) > 0) {
1164 XNextEvent (dpy, &event);
1165 if (event.type == MappingNotify) {
1166 /* read all MappingNotify events */
1167 while (XCheckTypedEvent (dpy, MappingNotify, &event)) ;
1168 XRefreshKeyboardMapping (&event.xmapping);
1170 fprintf (stderr, "%s: unknown event %ld\n",
1171 ProgramName, (long) event.type);
1176 switch (op->generic.type) {
1178 if (exec_keycode (&op->keycode) < 0) errors++;
1179 if (op->keycode.target_keycode)
1185 if (exec_add (&op->addmodifier) < 0) errors++;
1186 else update_map = True;
1188 case doRemoveModifier:
1189 if (exec_remove (&op->removemodifier) < 0) errors++;
1190 else update_map = True;
1192 case doClearModifier:
1193 if (exec_clear (&op->clearmodifier) < 0) errors++;
1194 else update_map = True;
1197 if (exec_pointer (&op->pointer) < 0) errors++;
1200 fprintf (stderr, "%s: unknown opcode %d\n",
1201 ProgramName, op->generic.type);
1207 if (UpdateModifierMapping (map) < 0) errors++;
1210 return (errors > 0 ? -1 : 0);
1214 exec_keycode(struct op_keycode *opk)
1216 if (!opk->target_keycode) {
1222 for (i = min_keycode; i <= max_keycode; i++) {
1223 for (j = 0; j < opk->count; j++) {
1224 if (XKeycodeToKeysym(dpy, (KeyCode) i, j) != opk->keysyms[j])
1227 if (j >= opk->count)
1231 for (j = 0; j < 8; j++) {
1232 if (XKeycodeToKeysym(dpy, (KeyCode) i, j) != None)
1239 fprintf(stderr, "%s: no available keycode for assignment\n",
1243 XChangeKeyboardMapping (dpy, free, opk->count, opk->keysyms, 1);
1244 } else if (opk->count == 0) {
1245 KeySym dummy = NoSymbol;
1246 XChangeKeyboardMapping (dpy, opk->target_keycode, 1,
1249 XChangeKeyboardMapping (dpy, opk->target_keycode, opk->count,
1256 exec_add(struct op_addmodifier *opam)
1262 for (i = 0; i < opam->count; i++) {
1266 kcs = KeysymToKeycodes (dpy, opam->keysyms[i], &num_kcs);
1269 while (--num_kcs >= 0) {
1270 if (AddModifier (&map, *kcs++, opam->modifier) < 0)
1278 exec_remove(struct op_removemodifier *oprm)
1284 for (i = 0; i < oprm->count; i++) {
1285 if (RemoveModifier (&map, oprm->keycodes[i], oprm->modifier) < 0)
1292 exec_clear(struct op_clearmodifier *opcm)
1294 return (ClearModifier (&map, opcm->modifier));
1299 exec_pointer(struct op_pointer *opp)
1301 return (SetPointerMap (opp->button_codes, opp->count));
1305 print_modifier_map(void)
1307 PrintModifierMapping (map, stdout);
1312 print_key_table(Bool exprs)
1314 PrintKeyTable (exprs, stdout);
1319 print_pointer_map(void)
1321 PrintPointerMap (stdout);