1
/* $Xorg: handle.c,v 1.6 2001/02/09 02:05:56 xorgcvs Exp $ */
4
Copyright 1988, 1998 The Open Group
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
12
The above copyright notice and this permission notice shall be included
13
in all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
19
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
OTHER DEALINGS IN THE SOFTWARE.
23
Except as contained in this notice, the name of The Open Group shall
24
not be used in advertising or otherwise to promote the sale, use or
25
other dealings in this Software without prior written authorization
29
/* $XFree86: xc/programs/xmodmap/handle.c,v 3.6 2001/07/25 15:05:27 dawes Exp $ */
40
static XModifierKeymap *map = NULL;
44
* The routines in this file manipulate a queue of intructions. Instead of
45
* executing each line as it is entered, we build up a list of actions to
46
* take and execute them all at the end. This allows us to find all errors
47
* at once, and to preserve the context in which we are looking up keysyms.
50
struct wq work_queue = {NULL, NULL};
54
* common utility routines
58
KeysymToKeycodes(Display *dpy, KeySym keysym, int *pnum_kcs)
64
for (i = min_keycode; i <= max_keycode; i++) {
65
for (j = 0; j < 8; j++) {
66
if (XKeycodeToKeysym(dpy, (KeyCode) i, j) == keysym) {
68
kcs = (KeyCode *)malloc(sizeof(KeyCode));
70
kcs = (KeyCode *)realloc((char *)kcs,
71
sizeof(KeyCode) * (*pnum_kcs + 1));
82
copy_to_scratch(const char *s, int len)
84
static char *buf = NULL;
85
static int buflen = 0;
89
buflen = (len < 40) ? 80 : (len * 2);
90
buf = (char *) malloc (buflen+1);
93
strncpy (buf, s, len);
104
fprintf (stderr, "%s: %s:%d: bad ", ProgramName, inputFilename, lineno+1);
108
#define badmsg0(what) { badheader(); fprintf (stderr, what); \
109
putc ('\n', stderr); }
111
#define badmsg(what,arg) { badheader(); fprintf (stderr, what, arg); \
112
putc ('\n', stderr); }
114
#define badmsgn(what,s,len) badmsg (what, copy_to_scratch (s, len))
117
initialize_map (void)
119
map = XGetModifierMapping (dpy);
123
static void do_keycode ( char *line, int len );
124
static void do_keysym ( char *line, int len );
125
static void finish_keycodes ( const char *line, int len, KeyCode *keycodes,
127
static void do_add ( char *line, int len );
128
static void do_remove ( char *line, int len );
129
static void do_clear ( char *line, int len );
130
static void do_pointer ( char *line, int len );
131
static int get_keysym_list ( const char *line, int len, int *np, KeySym **kslistp );
133
static void print_opcode(union op *op);
135
static int skip_word ( const char *s, int len );
136
static int skip_chars ( const char *s, int len );
137
static int skip_space ( const char *s, int len );
140
char *command; /* name of input command */
141
int length; /* length of command */
142
void (*proc)(char *, int); /* handler */
143
} dispatch_table[] = {
144
{ "keycode", 7, do_keycode },
145
{ "keysym", 6, do_keysym },
146
{ "add", 3, do_add },
147
{ "remove", 6, do_remove },
148
{ "clear", 5, do_clear },
149
{ "pointer", 7, do_pointer },
153
* handle_line - this routine parses the input line (which has had all leading
154
* and trailing whitespace removed) and builds up the work queue.
158
handle_line(char *line, /* string to parse */
159
int len) /* length of line */
164
n = skip_chars (line, len);
166
badmsg ("input line '%s'", line);
170
for (dtp = dispatch_table; dtp->command != NULL; dtp++) {
171
if (n == dtp->length &&
172
strncmp (line, dtp->command, dtp->length) == 0) {
174
n += skip_space (line+n, len-n);
177
(*(dtp->proc)) (line, len);
182
fprintf (stderr, "%s: unknown command on line %s:%d\n",
183
ProgramName, inputFilename, lineno+1);
188
* the following routines are useful for parsing
192
skip_word (const char *s, int len)
196
n = skip_chars (s, len);
197
return (n + skip_space (s+n, len-n));
201
skip_chars(const char *s, int len)
205
if (len <= 0 || !s || *s == '\0') return (0);
207
for (i = 0; i < len; i++) {
208
if (isspace(s[i])) break;
214
skip_space(const char *s, int len)
218
if (len <= 0 || !s || *s == '\0') return (0);
220
for (i = 0; i < len; i++) {
221
if (!s[i] || !isspace(s[i])) break;
228
skip_until_char(const char *s, int len, char c)
232
for (i = 0; i < len; i++) {
233
if (s[i] == c) break;
240
* The action routines.
242
* This is where the real work gets done. Each routine is responsible for
243
* parsing its input (note that the command keyword has been stripped off)
244
* and adding to the work queue. They are also in charge of outputting
245
* error messages and returning non-zero if there is a problem.
247
* The following global variables are available:
248
* dpy the display descriptor
249
* work_queue linked list of opcodes
250
* inputFilename name of the file being processed
251
* lineno line number of current line in input file
254
add_to_work_queue(union op *p) /* this can become a macro someday */
256
if (work_queue.head == NULL) { /* nothing on the list */
257
work_queue.head = work_queue.tail = p; /* head, tail, no prev */
259
work_queue.tail->generic.next = p; /* head okay, prev */
260
work_queue.tail = p; /* tail */
262
p->generic.next = NULL;
271
parse_number(const char *str, unsigned long *val)
282
if (*str == 'x' || *str == 'X') {
287
return (sscanf (str, fmt, val) == 1);
291
parse_keysym(const char *line, int n, char **name, KeySym *keysym)
293
*name = copy_to_scratch (line, n);
294
if (!strcmp(*name, "NoSymbol")) {
298
*keysym = XStringToKeysym (*name);
299
if (*keysym == NoSymbol && '0' <= **name && **name <= '9')
300
return parse_number(*name, keysym);
301
return (*keysym != NoSymbol);
305
* do_keycode - parse off lines of the form
307
* "keycode" number "=" [keysym ...]
310
* where number is in decimal, hex, or octal. Any number of keysyms may be
315
do_keycode(char *line, int len)
321
if (len < 3 || !line || *line == '\0') { /* 5=a minimum */
322
badmsg0 ("keycode input line");
327
* We need not bother to advance line/len past the
328
* number (or the string 'any') as finish_keycodes() will
329
* first advance past the '='.
331
if (!strncmp("any", line, 3)) {
334
if (*line == '0') line++, len--, fmt = "%o";
335
if (*line == 'x' || *line == 'X') line++, len--, fmt = "%x";
338
if (sscanf (line, fmt, &dummy) != 1 || dummy == 0) {
339
badmsg0 ("keycode value");
342
keycode = (KeyCode) dummy;
343
if ((int)keycode < min_keycode || (int)keycode > max_keycode) {
344
badmsg0 ("keycode value (out of range)");
349
finish_keycodes (line, len, &keycode, 1);
354
* do_keysym - parse off lines of the form
356
* "keysym" keysym "=" [keysym ...]
359
* The left keysyms has to be checked for validity and evaluated.
363
do_keysym(char *line, int len)
370
if (len < 3 || !line || *line == '\0') { /* a=b minimum */
371
badmsg0 ("keysym input line");
375
n = skip_chars (line, len);
377
badmsg0 ("target keysym name");
380
if (!parse_keysym(line, n, &tmpname, &keysym)) {
381
badmsg ("keysym target key symbol '%s'", tmpname);
385
keycodes = KeysymToKeycodes (dpy, keysym, &n);
387
badmsg ("keysym target keysym '%s', no corresponding keycodes",
393
printf ("! Keysym %s (0x%lx) corresponds to keycode(s)",
394
tmpname, (long) keysym);
395
for (i = 0; i < n; i++)
396
printf (" 0x%x", keycodes[i]);
400
finish_keycodes (line, len, keycodes, n);
404
finish_keycodes(const char *line, int len, KeyCode *keycodes, int count)
409
struct op_keycode *opk;
411
n = skip_until_char (line, len, '=');
414
if (len < 1 || *line != '=') { /* = minimum */
415
badmsg0 ("keycode command (missing keysym list),");
418
line++, len--; /* skip past the = */
420
n = skip_space (line, len);
423
/* allow empty list */
424
if (get_keysym_list (line, len, &n, &kslist) < 0)
427
while (--count >= 0) {
428
uop = AllocStruct (union op);
430
badmsg ("attempt to allocate a %ld byte keycode opcode",
431
(long) sizeof (struct op_keycode));
436
opk->type = doKeycode;
437
opk->target_keycode = keycodes[count];
439
opk->keysyms = kslist;
441
add_to_work_queue (uop);
445
/* make sure we handle any special keys */
446
check_special_keys (keycode, n, kslist);
452
* parse_modifier - convert a modifier string name to its index
455
struct modtab modifier_table[] = { /* keep in order so it can be index */
468
parse_modifier(char *line, int n)
473
/* lowercase for comparison against table */
474
for (i = 0; i < n; i++) {
475
if (isupper (line[i])) line[i] = tolower (line[i]);
478
for (mt = modifier_table; mt->name; mt++) {
479
if (n == mt->length && strncmp (line, mt->name, n) == 0)
487
* do_add - parse off lines of the form
489
* add MODIFIER = keysym ...
491
* where the MODIFIER is one of Shift, Lock, Control, Mod[1-5] where case
492
* is not important. There should also be an alias Ctrl for control.
496
do_add(char *line, int len)
502
struct op_addmodifier *opam;
504
if (len < 6 || !line || *line == '\0') { /* Lock=a minimum */
505
badmsg0 ("add modifier input line");
509
n = skip_chars (line, len);
511
badmsg ("add modifier name %s", line);
515
modifier = parse_modifier (line, n);
517
badmsgn ("add modifier name '%s', not allowed", line, n);
522
n = skip_until_char (line, len, '=');
524
badmsg0 ("add modifier = keysym");
529
n += skip_space (line+n, len-n);
532
if (get_keysym_list (line, len, &n, &kslist) < 0)
535
badmsg0 ("add modifier keysym list (empty)");
539
uop = AllocStruct (union op);
541
badmsg ("attempt to allocate %ld byte addmodifier opcode",
542
(long) sizeof (struct op_addmodifier));
545
opam = &uop->addmodifier;
547
opam->type = doAddModifier;
548
opam->modifier = modifier;
550
opam->keysyms = kslist;
552
add_to_work_queue (uop);
555
#ifdef AUTO_ADD_REMOVE
557
* make_add - stick a single add onto the queue
560
make_add(int modifier, KeySym keysym)
563
struct op_addmodifier *opam;
565
uop = AllocStruct (union op);
567
badmsg ("attempt to allocate %ld byte addmodifier opcode",
568
(long) sizeof (struct op_addmodifier));
571
opam = &uop->addmodifier;
573
opam->type = doAddModifier;
574
opam->modifier = modifier;
576
opam->keysyms = (KeySym *) malloc (sizeof (KeySym));
577
if (!opam->keysyms) {
578
badmsg ("attempt to allocate %ld byte KeySym", (long) sizeof (KeySym));
579
free ((char *) opam);
582
opam->keysyms[0] = keysym;
584
add_to_work_queue (uop);
587
#endif /* AUTO_ADD_REMOVE */
591
* do_remove - parse off lines of the form
593
* remove MODIFIER = oldkeysym ...
595
* where the MODIFIER is one of Shift, Lock, Control, Mod[1-5] where case
596
* is not important. There should also be an alias Ctrl for control.
600
do_remove(char *line, int len)
610
struct op_removemodifier *oprm;
612
if (len < 6 || !line || *line == '\0') { /* Lock=a minimum */
613
badmsg0 ("remove modifier input line");
617
n = skip_chars (line, len);
619
badmsg ("remove modifier name %s", line);
623
modifier = parse_modifier (line, n);
625
badmsgn ("remove modifier name '%s', not allowed", line, n);
630
n = skip_until_char (line, len, '=');
632
badmsg0 ("remove modifier = keysym");
637
n += skip_space (line+n, len-n);
640
if (get_keysym_list (line, len, &n, &kslist) < 0)
643
badmsg0 ("remove modifier keysym list (empty)");
648
* unlike the add command, we have to now evaluate the keysyms
651
kclist = (KeyCode *) malloc (n * sizeof (KeyCode));
653
badmsg ("attempt to allocate %ld byte keycode list",
654
(long) (n * sizeof (KeyCode)));
655
free ((char *) kslist);
661
for (i = 0; i < n; i++) {
664
kcs = KeysymToKeycodes (dpy, kslist[i], &num_kcs);
666
char *tmpname = XKeysymToString (kslist[i]);
667
badmsg ("keysym in remove modifier list '%s', no corresponding keycodes",
668
tmpname ? tmpname : "?");
673
char *tmpname = XKeysymToString (kslist[i]);
674
printf ("! Keysym %s (0x%lx) corresponds to keycode(s)",
675
tmpname ? tmpname : "?", (long) kslist[i]);
676
for (j = 0; j < num_kcs; j++)
677
printf(" 0x%x", kcs[j]);
680
if (nc + num_kcs > tot) {
682
kclist = (KeyCode *)realloc((char *)kclist, tot * sizeof(KeyCode));
684
badmsg ("attempt to allocate %ld byte keycode list",
685
(long) (tot * sizeof (KeyCode)));
686
free ((char *) kslist);
690
while (--num_kcs >= 0)
691
kclist[nc++] = *kcs++; /* okay, add it to list */
694
free ((char *) kslist); /* all done with it */
696
uop = AllocStruct (union op);
698
badmsg ("attempt to allocate %ld byte removemodifier opcode",
699
(long) sizeof (struct op_removemodifier));
702
oprm = &uop->removemodifier;
704
oprm->type = doRemoveModifier;
705
oprm->modifier = modifier;
707
oprm->keycodes = kclist;
709
add_to_work_queue (uop);
712
#ifdef AUTO_ADD_REMOVE
714
* make_remove - stick a single remove onto the queue
717
make_remove(int modifier, KeyCode keycode)
720
struct op_removemodifier *oprm;
722
uop = AllocStruct (union op);
724
badmsg ("attempt to allocate %ld byte removemodifier opcode",
725
(long) sizeof (struct op_removemodifier));
728
oprm = &uop->removemodifier;
730
oprm->type = doRemoveModifier;
731
oprm->modifier = modifier;
733
oprm->keycodes = (KeyCode *) malloc (sizeof (KeyCode));
734
if (!oprm->keycodes) {
735
badmsg ("attempt to allocate %ld byte KeyCode",
736
(long) sizeof (KeyCode));
737
free ((char *) oprm);
740
oprm->keycodes[0] = keycode;
742
add_to_work_queue (uop);
745
#endif /* AUTO_ADD_REMOVE */
749
* do_clear - parse off lines of the form
756
do_clear(char *line, int len)
761
struct op_clearmodifier *opcm;
763
if (len < 4 || !line || *line == '\0') { /* Lock minimum */
764
badmsg0 ("clear modifier input line");
768
n = skip_chars (line, len);
770
modifier = parse_modifier (line, n);
772
badmsgn ("clear modifier name '%s'", line, n);
775
n += skip_space (line+n, len-n);
777
badmsgn ("extra argument '%s' to clear modifier", line+n, len-n);
778
/* okay to continue */
781
uop = AllocStruct (union op);
783
badmsg ("attempt to allocate %ld byte clearmodifier opcode",
784
(long) sizeof (struct op_clearmodifier));
787
opcm = &uop->clearmodifier;
789
opcm->type = doClearModifier;
790
opcm->modifier = modifier;
792
add_to_work_queue (uop);
795
#ifndef HAVE_STRNCASECMP
797
strncasecmp(const char *a, const char *b, int n)
802
for (i = 0; i < n; i++, a++, b++) {
807
a1 = (isascii(*a) && isupper(*a)) ? tolower(*a) : *a;
808
b1 = (isascii(*b) && isupper(*b)) ? tolower(*b) : *b;
809
if (a1 != b1) return b1 - a1;
817
* do_pointer = get list of numbers of the form
819
* buttons = NUMBER ...
824
do_pointer(char *line, int len)
830
struct op_pointer *opp;
831
unsigned char buttons[MAXBUTTONCODES];
836
if (len < 2 || !line || *line == '\0') { /* =1 minimum */
837
badmsg0 ("buttons input line");
841
nbuttons = XGetPointerMapping (dpy, buttons, MAXBUTTONCODES);
843
n = skip_space (line, len);
846
if (line[0] != '=') {
847
badmsg0 ("buttons pointer code list, missing equal sign");
851
line++, len--; /* skip = */
852
n = skip_space (line, len);
856
if (len < 7 || strncasecmp (line, "default", 7) != 0) {
858
n = skip_space (line, len);
860
if (line[0] == '\0') break;
861
n = skip_word (line, len);
863
badmsg ("skip of word in buttons line: %s", line);
866
strval = copy_to_scratch(line, n);
867
ok = parse_number (strval, &val);
868
if (!ok || val >= MAXBUTTONCODES) {
869
badmsg ("value %s given for buttons list", strval);
872
buttons[i++] = (unsigned char) val;
877
if (i > 0 && i != nbuttons) {
878
fprintf (stderr, "Warning: Only changing the first %d of %d buttons.\n",
883
uop = AllocStruct (union op);
885
badmsg ("attempt to allocate a %ld byte pointer opcode",
886
(long) sizeof (struct op_pointer));
891
opp->type = doPointer;
893
for (i = 0; i < opp->count; i++) {
894
opp->button_codes[i] = buttons[i];
897
add_to_work_queue (uop);
902
* get_keysym_list - parses the rest of the line into a keysyms assumes
903
* that the = sign has been parsed off but there may be leading whitespace
908
* this involves getting the word containing the keysym, checking its range,
909
* and adding it to the list.
913
get_keysym_list(const char *line, int len, int *np, KeySym **kslistp)
915
int havesofar, maxcanhave;
921
if (len == 0) return (0); /* empty list */
924
maxcanhave = 4; /* most lists are small */
925
keysymlist = (KeySym *) malloc (maxcanhave * sizeof (KeySym));
927
badmsg ("attempt to allocate %ld byte initial keysymlist",
928
(long) (maxcanhave * sizeof (KeySym)));
938
n = skip_space (line, len);
941
n = skip_chars (line, len);
943
badmsg0 ("keysym name list");
948
ok = parse_keysym (line, n, &tmpname, &keysym);
951
badmsg ("keysym name '%s' in keysym list", tmpname);
952
/* do NOT return here, look for others */
957
* Do NOT test to see if the keysym translates to a keycode or you
958
* won't be able to assign new ones....
961
/* grow the list bigger if necessary */
962
if (havesofar >= maxcanhave) {
963
KeySym *origkeysymlist = keysymlist;
965
keysymlist = (KeySym *) realloc (keysymlist,
966
maxcanhave * sizeof (KeySym));
968
badmsg ("attempt to grow keysym list to %ld bytes",
969
(long) (maxcanhave * sizeof (KeySym)));
970
free(origkeysymlist);
975
/* and add it to the list */
976
keysymlist[havesofar++] = keysym;
979
*kslistp = keysymlist;
987
* check_special_keys - run through list of keysyms and generate "add" or
988
* "remove" commands for for any of the key syms that appear in the modifier
989
* list. this involves running down the modifier map which is an array of
990
* 8 by map->max_keypermod keycodes.
994
check_special_keys(KeyCode keycode, int n, KeySym *kslist)
996
int i; /* iterator variable */
997
KeyCode *kcp; /* keycode pointer */
1000
* walk the modifiermap array. since its dimensions are not known at
1001
* compile time, we have to walk it by hand instead of indexing. this
1002
* is why it is initialized outside the loop, but incremented inside the
1006
kcp = map->modifiermap; /* start at beginning and iterate */
1007
for (i = 0; i < 8; i++) { /* there are 8 modifier keys */
1010
for (j = 0; j < map->max_keypermod; j++, kcp++) {
1014
if (!*kcp) continue; /* only non-zero entries significant */
1017
* check to see if the target keycode is already a modifier; if so,
1018
* then we have to remove it
1020
if (keycode == *kcp) {
1021
make_remove (i, keycode);
1025
* now, check to see if any of the keysyms map to keycodes
1026
* that are in the modifier list
1028
for (k = 0; k < n; k++) {
1031
kc = XKeysymToKeycode (dpy, kslist[k]);
1032
if (kc == *kcp) { /* yup, found one */
1034
* have to generate a remove of the CURRENT keycode
1035
* and then an add of the new KEYCODE
1037
make_remove (i, kc); /* modifier, keycode */
1038
make_add (i, kslist[k]); /* modifier, keysym */
1048
* print_work_queue - disassemble the work queue and print it on stdout
1052
print_work_queue(void)
1056
printf ("! dump of work queue\n");
1057
for (op = work_queue.head; op; op = op->generic.next) {
1064
print_opcode(union op *op)
1069
switch (op->generic.type) {
1071
if (op->keycode.target_keycode)
1072
printf ("keycode 0x%lx =", (long) op->keycode.target_keycode);
1074
printf ("keycode any =");
1075
for (i = 0; i < op->keycode.count; i++) {
1076
char *name = XKeysymToString (op->keycode.keysyms[i]);
1078
printf (" %s", name ? name : "BADKEYSYM");
1083
printf ("add %s =", modifier_table[op->addmodifier.modifier].name);
1084
for (i = 0; i < op->addmodifier.count; i++) {
1085
char *name = XKeysymToString (op->addmodifier.keysyms[i]);
1086
printf (" %s", name ? name : "BADKEYSYM");
1090
case doRemoveModifier:
1091
printf ("remove %s = ",
1092
modifier_table[op->removemodifier.modifier].name);
1093
for (i = 0; i < op->removemodifier.count; i++) {
1094
printf (" 0x%lx", (long) op->removemodifier.keycodes[i]);
1098
case doClearModifier:
1099
printf ("clear %s\n", modifier_table[op->clearmodifier.modifier].name);
1102
printf ("pointer = ");
1103
if (op->pointer.count == 0)
1105
else for (i=0; i < op->pointer.count; i++)
1106
printf(" %d", op->pointer.button_codes[i]);
1110
printf ("! unknown opcode %d\n", op->generic.type);
1117
* execute_work_queue - do the real meat and potatoes now that we know what
1118
* we need to do and that all of the input is correct.
1120
static int exec_keycode ( struct op_keycode *opk );
1121
static int exec_add ( struct op_addmodifier *opam );
1122
static int exec_remove ( struct op_removemodifier *oprm );
1123
static int exec_clear ( struct op_clearmodifier *opcm );
1124
static int exec_pointer ( struct op_pointer *opp );
1128
execute_work_queue (void)
1132
Bool update_map = False;
1137
printf ("! executing work queue\n");
1144
for (op = work_queue.head; op; op = op->generic.next) {
1145
if (verbose) print_opcode (op);
1147
/* check to see if we have to update the keyboard mapping */
1150
op->generic.type != doKeycode ||
1151
!op->keycode.target_keycode)) {
1153
while (XEventsQueued (dpy, QueuedAlready) > 0) {
1155
XNextEvent (dpy, &event);
1156
if (event.type == MappingNotify) {
1157
/* read all MappingNotify events */
1158
while (XCheckTypedEvent (dpy, MappingNotify, &event)) ;
1159
XRefreshKeyboardMapping (&event.xmapping);
1161
fprintf (stderr, "%s: unknown event %ld\n",
1162
ProgramName, (long) event.type);
1167
switch (op->generic.type) {
1169
if (exec_keycode (&op->keycode) < 0) errors++;
1170
if (op->keycode.target_keycode)
1176
if (exec_add (&op->addmodifier) < 0) errors++;
1177
else update_map = True;
1179
case doRemoveModifier:
1180
if (exec_remove (&op->removemodifier) < 0) errors++;
1181
else update_map = True;
1183
case doClearModifier:
1184
if (exec_clear (&op->clearmodifier) < 0) errors++;
1185
else update_map = True;
1188
if (exec_pointer (&op->pointer) < 0) errors++;
1191
fprintf (stderr, "%s: unknown opcode %d\n",
1192
ProgramName, op->generic.type);
1198
if (UpdateModifierMapping (map) < 0) errors++;
1201
return (errors > 0 ? -1 : 0);
1205
exec_keycode(struct op_keycode *opk)
1207
if (!opk->target_keycode) {
1213
for (i = min_keycode; i <= max_keycode; i++) {
1214
for (j = 0; j < opk->count; j++) {
1215
if (XKeycodeToKeysym(dpy, (KeyCode) i, j) != opk->keysyms[j])
1218
if (j >= opk->count)
1222
for (j = 0; j < 8; j++) {
1223
if (XKeycodeToKeysym(dpy, (KeyCode) i, j) != None)
1230
fprintf(stderr, "%s: no available keycode for assignment\n",
1234
XChangeKeyboardMapping (dpy, free, opk->count, opk->keysyms, 1);
1235
} else if (opk->count == 0) {
1236
KeySym dummy = NoSymbol;
1237
XChangeKeyboardMapping (dpy, opk->target_keycode, 1,
1240
XChangeKeyboardMapping (dpy, opk->target_keycode, opk->count,
1247
exec_add(struct op_addmodifier *opam)
1253
for (i = 0; i < opam->count; i++) {
1257
kcs = KeysymToKeycodes (dpy, opam->keysyms[i], &num_kcs);
1260
while (--num_kcs >= 0) {
1261
if (AddModifier (&map, *kcs++, opam->modifier) < 0)
1269
exec_remove(struct op_removemodifier *oprm)
1275
for (i = 0; i < oprm->count; i++) {
1276
if (RemoveModifier (&map, oprm->keycodes[i], oprm->modifier) < 0)
1283
exec_clear(struct op_clearmodifier *opcm)
1285
return (ClearModifier (&map, opcm->modifier));
1290
exec_pointer(struct op_pointer *opp)
1292
return (SetPointerMap (opp->button_codes, opp->count));
1296
print_modifier_map(void)
1298
PrintModifierMapping (map, stdout);
1303
print_key_table(Bool exprs)
1305
PrintKeyTable (exprs, stdout);
1310
print_pointer_map(void)
1312
PrintPointerMap (stdout);