diff --git a/calmwm.h b/calmwm.h index b925c2c..16901b3 100644 --- a/calmwm.h +++ b/calmwm.h @@ -439,7 +439,7 @@ void conf_grab(struct conf *, struct keybinding *); void conf_grab_mouse(struct client_ctx *); void conf_init(struct conf *); void conf_ignore(struct conf *, char *); -void conf_mousebind(struct conf *, char *, char *); +int conf_mousebind(struct conf *, char *, char *); void conf_screen(struct screen_ctx *); void conf_ungrab(struct conf *, struct keybinding *); diff --git a/conf.c b/conf.c index 984e4cc..0afc11d 100644 --- a/conf.c +++ b/conf.c @@ -577,11 +577,14 @@ static struct { { "menu_cmd", mousefunc_menu_cmd, MOUSEBIND_CTX_ROOT }, }; -void +static unsigned int mouse_btns[] = { Button1, Button2, Button3 }; + +int conf_mousebind(struct conf *c, char *name, char *binding) { struct mousebinding *current_binding; char *substring, *tmp; + u_int button; const char *errstr; u_int i; @@ -600,16 +603,27 @@ conf_mousebind(struct conf *c, char *name, char *binding) } else substring = name; - current_binding->button = strtonum(substring, 1, 3, &errstr); + button = strtonum(substring, 1, 3, &errstr); if (errstr) - warnx("number of buttons is %s: %s", errstr, substring); + warnx("button number is %s: %s", errstr, substring); + + for (i = 0; i < nitems(mouse_btns); i++) { + if (button == mouse_btns[i]) { + current_binding->button = button; + break; + } + } + if (!current_binding->button || errstr) { + free(current_binding); + return (0); + } /* We now have the correct binding, remove duplicates. */ conf_mouseunbind(c, current_binding); if (strcmp("unmap", binding) == 0) { free(current_binding); - return; + return (1); } for (i = 0; i < nitems(name_to_mousefunc); i++) { @@ -619,8 +633,10 @@ conf_mousebind(struct conf *c, char *name, char *binding) current_binding->context = name_to_mousefunc[i].context; current_binding->callback = name_to_mousefunc[i].handler; TAILQ_INSERT_TAIL(&c->mousebindingq, current_binding, entry); - return; + return (1); } + + return (0); } static void @@ -646,26 +662,10 @@ void conf_grab_mouse(struct client_ctx *cc) { struct mousebinding *mb; - u_int button; TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) { if (mb->context != MOUSEBIND_CTX_WIN) continue; - - switch(mb->button) { - case 1: - button = Button1; - break; - case 2: - button = Button2; - break; - case 3: - button = Button3; - break; - default: - warnx("strange button in mousebinding\n"); - continue; - } - xu_btn_grab(cc->win, mb->modmask, button); + xu_btn_grab(cc->win, mb->modmask, mb->button); } } diff --git a/parse.y b/parse.y index 111be2e..0e67ba1 100644 --- a/parse.y +++ b/parse.y @@ -171,7 +171,12 @@ main : FONTNAME STRING { conf->gap.right = $5; } | MOUSEBIND STRING string { - conf_mousebind(conf, $2, $3); + if (!conf_mousebind(conf, $2, $3)) { + yyerror("invalid mousebind: %s %s", $2, $3); + free($2); + free($3); + YYERROR; + } free($2); free($3); }