/* pairs a binding to a function */ #include "nawm.h" #include "bindings.h" BindInfo bind_list; unsigned bind_cnt; int current_mode = DEFAULT_MODE; Window current_window = (Window)0; Window focus_window = (Window)0; init_bindings() { bind_list = (BindInfo)malloc(0); bind_cnt = 0; } BindInfo realloc_binding() { static BindInfo tmp; tmp = (BindInfo)realloc((char *) bind_list, (unsigned) ++bind_cnt * sizeof(BindInfo_S)); if(!tmp) { die("Out of memory"); } bind_list = tmp; return &bind_list[bind_cnt-1]; } grab_things() { unsigned int i; BindInfo bi; for(i = 0, bi = bind_list; i < bind_cnt; bi++, i++) if(bi->whatmode == ANY_MODE || bi->whatmode == current_mode) { /* break, but continue loop. this allows multiple bindings to the same event */ switch(bi->type) { case ButtonPress: XGrabButton(dpy, bi->button, bi->modifiers, root, False, ButtonReleaseMask | PointerMotionMask, GrabModeAsync,GrabModeAsync,None, None); break; case KeyPress: XGrabKey(dpy, bi->keycode, bi->modifiers, root, False, GrabModeAsync,GrabModeAsync); break; } } } ungrab_things() { unsigned int i; BindInfo bi; for(i = 0, bi = bind_list; i < bind_cnt; bi++, i++) if (bi->whatmode == ANY_MODE || bi->whatmode == current_mode) { /* break, but continue loop. this allows multiple bindings to the same event */ switch(bi->type) { case ButtonPress: XUngrabButton(dpy, bi->button, bi->modifiers, root); break; case KeyPress: XUngrabKey(dpy, bi->keycode, bi->modifiers, root); break; } } } add_motion_binding(modifiers, bi) unsigned int modifiers; BindInfo bi; { bi->type = MotionNotify; bi->modifiers = modifiers; } add_key_binding(keycode, modifiers, bi) KeyCode keycode; unsigned int modifiers; BindInfo bi; { bi->type = KeyPress; bi->keycode = keycode; bi->modifiers = modifiers; } add_button_binding(button, modifiers, bi) unsigned int button; unsigned int modifiers; BindInfo bi; { bi->type = ButtonPress; bi->button = button; bi->modifiers = modifiers; } set_mode (n) int n; { if (current_mode == n) return; ungrab_things(); current_mode = n; grab_things(); } wait_for_binding() { XEvent ev; unsigned int i; BindInfo bi; int mode; #ifdef USE_CACHE if (use_cache) start_cache(); #endif grab_things(); for(;;) { XNextEvent(dpy, &ev); #ifdef USE_CACHE update_cache(&ev); #endif switch(ev.type) { case MotionNotify: inform_user(10, "MotionNotify event"); current_window = ev.xmotion.subwindow; break; case ButtonPress: inform_user(10, "ButtonPress event"); current_window = ev.xbutton.subwindow; break; case KeyPress: current_window = ev.xkey.subwindow; break; } focus_window = current_window; mode = current_mode; for(i = 0, bi = bind_list; i < bind_cnt; bi++, i++) { if(bi->type == ev.type && (bi->whatmode == ANY_MODE || bi->whatmode == mode)) { /* break, but continue loop. this allows multiple bindings to the same event */ switch(ev.type) { case MotionNotify: do_binding(bi, &ev); break; case ButtonPress: if(bi->button == ev.xbutton.button && (bi->modifiers |AnyButton) == (ev.xbutton.state |AnyButton)) do_binding(bi, &ev); break; case KeyPress: if(bi->keycode == ev.xkey.keycode && bi->modifiers == ev.xkey.state) do_binding(bi, &ev); break; } } } icon_dispatch(&ev); } }