#include #include #include "nawm.h" #include "bindings.h" #include "cmd.h" KeySym *keyboard_mapping = NULL; int keysyms_per_keycode; int whatmode = DEFAULT_MODE; /* * string_to_keycode --- look up keysym (in string form) in Xlation * table, return keycode and modifiers. returns 1 if found. Keysyms * can also be in the form #nnn, where nnn is a keycode. */ int string_to_keycode (sym_name, code, modifier) char *sym_name; /* KeySym name */ KeyCode *code; /* Return */ int *modifier; /* Return */ { KeySym sym; KeyCode n; int m, q = -1; extern int min_keycode, max_keycode; if ((sym = XStringToKeysym(sym_name)) == NoSymbol) if (*sym_name == '#' && isdigit(sym_name[1])) sym = (KeySym) atoi(sym_name+1); else return 0; for (n = min_keycode; n <= max_keycode; n++) for (m = 0; m < keysyms_per_keycode; m++) if (keyboard_mapping[++q] == sym) { *code = n; *modifier = m; return 1; } return 0; } KeySym keycode_to_keysym (keycode) int keycode; { return (keyboard_mapping[(keycode - min_keycode) * keysyms_per_keycode]); } skip_ws(cp) char **cp; { while (isspace(**cp)) (*cp)++; } char *get_id(cp) char **cp; { char *ret; skip_ws(cp); ret = *cp; if (**cp == '"') { ret++; do (*cp)++; while (**cp && (**cp != '"')); } else { while (**cp && !isspace(**cp)) (*cp)++; } /* invariant here: (**cp) is WS or NUL or '"' */ /* if it's non-NUL terminate the string and move on, otherwise leave the pointer on the NUL */ if (**cp) *(*cp)++ = 0; return ret; } int get_int (cp) char **cp; { char *ptr; ptr = get_id(cp); /* [gsstark:19951115.1905EST] handle "-screenwidth", "- screenwidth", etc*/ /* [gsstark:19960127.0752EST] it would be nice if this also handled things like -x -x_mark etc. */ if (*ptr=='-') if (*++ptr) return(-get_int(&ptr)); else return(-get_int(cp)); else if(!strcasecmp(ptr, "screenwidth")) return DisplayWidth(dpy, 0); else if(!strcasecmp(ptr, "screenheight")) return DisplayHeight(dpy, 0); else if(!strcasecmp(ptr, "xctr")) return DisplayWidth(dpy, 0)/2; else if(!strcasecmp(ptr, "yctr")) return DisplayHeight(dpy, 0)/2; else if(!strcasecmp(ptr, "x")) return USE_X; else if(!strcasecmp(ptr, "y")) return USE_Y; else if(!strcasecmp(ptr, "x_mark")) return USE_MARKERX; else if(!strcasecmp(ptr, "y_mark")) return USE_MARKERY; else if(!strcasecmp(ptr, "dx_mark")) return USE_DXMARKER; else if(!strcasecmp(ptr, "dy_mark")) return USE_DYMARKER; else return atoi(ptr); } read_config_file(f) FILE *f; { #define BUFCHUNK 100 int bufmax=BUFCHUNK; char *buf=malloc(bufmax+1), *c, *cmd; if (!keyboard_mapping) keyboard_mapping = XGetKeyboardMapping(dpy, min_keycode, max_keycode - min_keycode + 1, &keysyms_per_keycode); while(fgets(buf,bufmax+1,f)) { while (!(c=strchr(buf,'\n')) || (*(c-1)=='\\' && ((*(c-1)) = (*c = ' ')))) { buf = (char *)realloc(buf,(bufmax+=BUFCHUNK)+1); if (! fgets(strchr(buf,'\0'),BUFCHUNK+1,f)) break; } if (c = strchr(buf, '#')) *c = 0; c = buf; cmd = get_id(&c); if (*cmd) if (!strcmp(cmd, "mode")) whatmode = get_int(&c); else if (!strcmp(cmd, "anymode")) whatmode = ANY_MODE; else if (!strcmp(cmd, "endmode")) whatmode = DEFAULT_MODE; else if (!strcmp(cmd, "key")) parse_key_command (c); else if (!strcmp(cmd, "button")) parse_mouse_command(c); else if (!strcmp(cmd, "motion")) parse_motion_command(c); else if (!strcmp(cmd, "init")) do_init_command(c); else { fputs (cmd, stdout); puts (" not understood"); exit(1); } } free(buf); fclose(f); } read_nawmrc() { char buf[300]; FILE *f; strcpy (buf, getenv("HOME")); strcat (buf, "/.nawmrc"); if (!(f = fopen(buf, "r"))) { perror(buf); exit(1); } read_config_file(f); } BindInfo parse_bind_info (cp, bstorage) char **cp; BindInfo bstorage; /* NULL to use main binding list */ { BindInfo b; char *cmd = get_id(cp); char *name; char *word; int state; if (!*cmd) return NULL; b = bstorage ? bstorage : (BindInfo) realloc_binding(); b->whatmode = whatmode; if (!strcmp(cmd, "warptowindow")) { b->func = warp_to_window_cmd; } else if (!strcmp(cmd, "iconify")) { b->func = iconify_cmd; } else if (!strcmp(cmd, "deiconify")) { b->func = deiconify_cmd; } else if (!strcmp(cmd, "map")) { b->func = map_cmd; } else if (!strcmp(cmd, "unmap")) { b->func = unmap_cmd; } else if (!strcmp(cmd, "find")) { b->func = find_cmd; name = get_id(cp); malloc_strcpy(b->data.find.win_name, name); } else if (!strcmp(cmd, "warp")) { b->func = warp_cmd; b->data.warp.dx = get_int(cp); b->data.warp.dy = get_int(cp); } else if (!strcmp(cmd, "warpto")) { b->func = warp_to_cmd; b->data.warpto.x = get_int(cp); b->data.warpto.y = get_int(cp); } else if (!strcmp(cmd, "move")) { b->func = move_cmd; b->data.move.dx = get_int(cp); b->data.move.dy = get_int(cp); } else if (!strcmp(cmd, "moveto")) { b->func = move_to_cmd; b->data.moveto.x = get_int(cp); b->data.moveto.y = get_int(cp); } else if (!strcmp(cmd, "screen")) { b->func = screen_cmd; b->data.screen.dx = get_int(cp); b->data.screen.dy = get_int(cp); } else if (!strcmp(cmd, "screento")) { b->func = screen_to_cmd; b->data.screento.x = get_int(cp); b->data.screento.y = get_int(cp); } else if (!strcmp(cmd, "screen_except")) { b->func = screen_except_cmd; name = get_id(cp); b->data.screen_except.except_list = malloc(strlen(name)+4); sprintf(b->data.screen_except.except_list,",%s,",name); b->data.screen_except.dx = get_int(cp); b->data.screen_except.dy = get_int(cp); } else if (!strcmp(cmd, "screento_except")) { b->func = screen_to_except_cmd; name = get_id(cp); b->data.screento_except.except_list = malloc(strlen(name)+4); sprintf(b->data.screento_except.except_list,",%s,",name); b->data.screento_except.x = get_int(cp); b->data.screento_except.y = get_int(cp); } else if (!strcmp(cmd, "carry")) { b->func = carry_cmd; b->data.carry.dx = get_int(cp); b->data.carry.dy = get_int(cp); } else if (!strcmp(cmd, "carryto")) { b->func = carry_to_cmd; b->data.carryto.x = get_int(cp); b->data.carryto.y = get_int(cp); } else if (!strcmp(cmd, "size")) { b->func = size_cmd; b->data.size.dx = get_int(cp); b->data.size.dy = get_int(cp); } else if (!strcmp(cmd, "sizeto")) { b->func = size_to_cmd; b->data.sizeto.x = get_int(cp); b->data.sizeto.y = get_int(cp); } else if (!strcmp(cmd, "lower")) { b->func = lower_cmd; } else if (!strcmp(cmd, "raise")) { b->func = raise_cmd; } else if (!strcmp(cmd, "prev")) { b->func = prev_cmd; } else if (!strcmp(cmd, "next")) { b->func = next_cmd; } else if (!strcmp(cmd, "bell")) { b->func = bell_cmd; } else if (!strcmp(cmd, "kill")) { b->func = kill_cmd; } else if (!strcmp(cmd, "bind")) { b->func = bind_cmd; } else if (!strcmp(cmd, "unbind")) { b->func = unbind_cmd; } else if (!strcmp(cmd, "grab")) { b->func = grab_pointer_cmd; } else if (!strcmp(cmd, "ungrab")) { b->func = ungrab_pointer_cmd; } else if (!strcmp(cmd, "setmarker")) { b->func = set_marker_cmd; } else if (!strcmp(cmd, "exchmark")) { b->func = exch_mark_cmd; } else if (!strcmp(cmd, "setx")) { b->func = set_x_cmd; b->data.setx.x = get_int(cp); } else if (!strcmp(cmd, "sety")) { b->func = set_y_cmd; b->data.sety.y = get_int(cp); } else if (!strcmp(cmd, "setmode")) { b->func = set_mode_cmd; b->data.setmode.mode = get_int(cp); } else if (!strcmp(cmd, "endmode")) { b->func = set_mode_cmd; b->data.setmode.mode = DEFAULT_MODE; } else if (!strcmp(cmd, "mouseclick")) { b->func = mouseclick_cmd; parse_modifiers(cp, &word, &state); b->data.mouseclick.modifiers = state; b->data.mouseclick.button = get_int(&word); b->data.mouseclick.x = get_int(cp); if ((b->data.mouseclick.x < 0) && (b->data.mouseclick.x >= -DisplayWidth(dpy, 0))) b->data.mouseclick.x += DisplayWidth(dpy, 0); b->data.mouseclick.y = get_int(cp); if ((b->data.mouseclick.y < 0) && (b->data.mouseclick.x >= -DisplayHeight(dpy, 0))) b->data.mouseclick.y += DisplayHeight(dpy, 0); } else if (!strcmp(cmd, "break")) { b->func = break_cmd; } else if (!strcmp(cmd, "system")) { b->func = system_cmd; name = get_id(cp); malloc_strcpy(b->data.system.cmd, name); } else if (!strcmp(cmd, "exit")) { b->func = exit_cmd; } else { fputs (cmd, stderr); fputs (": command for binding unknown\n", stderr); exit(1); } return b; } parse_modifiers (cp, nextword, state) char **cp; char **nextword; /* return */ unsigned int *state; /* return */ { char *word; *state = 0; do { word = get_id(cp); if (!strcasecmp(word, "shift")) *state |= ShiftMask; else if (!strcasecmp(word, "control")) *state |= ControlMask; else if (!strcasecmp(word, "meta")) *state |= Mod1Mask; else if (!strcasecmp(word, "mod2")) *state |= Mod2Mask; else if (!strcasecmp(word, "mod3")) *state |= Mod3Mask; else if (!strcasecmp(word, "mod4")) *state |= Mod4Mask; else if (!strcasecmp(word, "mod5")) *state |= Mod5Mask; else if (!strcasecmp(word, "any")) *state = AnyModifier; else break; } while (1); *nextword = word; } parse_key_command (c) char *c; { KeyCode code; unsigned int state; int entryno; char *word; BindInfo b; parse_modifiers (&c, &word, &state); if (!(string_to_keycode(word, &code, &entryno))) { fputs (word, stderr); fputs (": key name (keysym) unknown\n", stderr); exit(1); } while (b = parse_bind_info(&c, NULL)) add_key_binding (code, state, b); } parse_mouse_command (c) char *c; { BindInfo b; unsigned int state; unsigned int button = 0; char *word; parse_modifiers (&c, &word, &state); if (!strcasecmp(word, "left")) button = Button1; else if (!strcasecmp(word, "middle")) button = Button2; else if (!strcasecmp(word, "right")) button = Button3; else if (word[0] == '#') button = atoi(word[1]); else { fputs (word, stderr); fputs (": mouse button unknown\n", stderr); exit(1); } while (b = parse_bind_info(&c, NULL)) add_button_binding (button, state, b); } parse_motion_command(c) char* c; { BindInfo b; while (b = parse_bind_info(&c, NULL)) add_motion_binding(AnyModifier, b); } do_init_command(c) char *c; { BindInfo_S bind; while (parse_bind_info(&c, &bind)) do_binding(&bind, NULL); }