/* * (C)opyright 2007-2009 Robert Manea * See LICENSE file for license details. * */ #include "dzen.h" #include "action.h" #include #include #include struct event_lookup ev_lookup_table[] = { { "onstart", onstart}, { "onexit", onexit}, { "onnewinput", onnewinput}, { "button1", button1}, { "button2", button2}, { "button3", button3}, { "button4", button4}, { "button5", button5}, { "button6", button6}, { "button7", button7}, { "entertitle", entertitle}, { "leavetitle", leavetitle}, { "enterslave", enterslave}, { "leaveslave", leaveslave}, { "sigusr1", sigusr1}, { "sigusr2", sigusr2}, { "keymarker", keymarker}, { 0, 0 } }; struct action_lookup ac_lookup_table[] = { { "print", a_print }, { "exec", a_exec}, { "exit", a_exit}, { "collapse", a_collapse}, { "uncollapse", a_uncollapse}, { "togglecollapse", a_togglecollapse}, { "stick", a_stick}, { "unstick", a_unstick}, { "togglestick", a_togglestick}, { "hide", a_hide}, { "unhide", a_unhide}, { "togglehide", a_togglehide}, { "scrollup", a_scrollup}, { "scrolldown", a_scrolldown}, { "menuprint", a_menuprint}, { "menuprint_noparse", a_menuprint_noparse}, { "menuexec", a_menuexec}, { "raise", a_raise}, { "lower", a_lower}, { "scrollhome", a_scrollhome}, { "scrollend", a_scrollend}, { "grabkeys", a_grabkeys}, { "ungrabkeys", a_ungrabkeys}, { "grabmouse", a_grabmouse}, { "ungrabmouse", a_ungrabmouse}, { 0, 0 } }; ev_list *head = NULL; static int new_event(long evid) { ev_list *item, *newitem; if(!head) { head = emalloc(sizeof (ev_list)); head->id = evid; head->next = NULL; } else { item = head; /* check if we already handle this event */ while(item) { if(item->id == evid) return 0; item = item->next; } item = head; while(item->next) item = item->next; newitem = emalloc(sizeof (ev_list)); newitem->id = evid; item->next = newitem; newitem->next = NULL; } return 0; } static void add_handler(long evid, int hpos, handlerf* hcb) { ev_list *item; item = head; while(item) { if(item->id == evid) { if(hpos < MAXACTIONS) { item->action[hpos] = emalloc(sizeof(As)); item->action[hpos]->handler = hcb; } break; } item = item->next; } } static void add_option(long evid, int hpos, int opos, char* opt) { ev_list *item; item = head; while(item) { if(item->id == evid) { if(opos < MAXOPTIONS) { item->action[hpos]->options[opos] = estrdup(opt); item->action[hpos]->options[opos+1] = NULL; } break; } item = item->next; } } int find_event(long evid) { ev_list *item; item = head; while(item) { if(item->id == evid) return item->id; item = item->next; } return -1; } void do_action(long evid) { int i; ev_list *item; item = head; while(item) { if(item->id == evid) break; item = item->next; } if(item) { for(i=0; item->action[i]->handler; i++) { item->action[i]->handler(item->action[i]->options); } } } int get_ev_id(const char *evname) { int i; KeySym ks; /* check for keyboard event */ if((!strncmp(evname, "key_", 4)) && ((ks = XStringToKeysym(evname+4)) != NoSymbol)) { return ks+keymarker; } /* own events */ for(i=0; ev_lookup_table[i].name; i++) { if(strncmp(ev_lookup_table[i].name, evname, strlen(ev_lookup_table[i].name)) == 0) return ev_lookup_table[i].id; } return -1; } handlerf * get_action_handler(const char *acname) { int i; for(i=0; ac_lookup_table[i].name; i++) { if(strcmp(ac_lookup_table[i].name, acname) == 0) return ac_lookup_table[i].handler; } return NULL; } void free_event_list(void) { int i; ev_list *item; item = head; while(item) { for(i=0; item->action[i]->handler; i++) free(item->action[i]); item = item->next; } } void fill_ev_table(char *input) { char *str1, *str2, *str3, *str4, *token, *subtoken, *kommatoken, *dptoken; char *saveptr1=NULL, *saveptr2=NULL, *saveptr3=NULL, *saveptr4=NULL; int j, i=0, k=0; long eid=0; handlerf *ah=0; for (j = 1, str1 = input; ; j++, str1 = NULL) { token = strtok_r(str1, ";", &saveptr1); if (token == NULL) break; for (str2 = token; ; str2 = NULL) { subtoken = strtok_r(str2, "=", &saveptr2); if (subtoken == NULL) break; if( (str2 == token) && ((eid = get_ev_id(subtoken)) != -1)) ; else if(eid == -1) break; for (str3 = subtoken; ; str3 = NULL) { kommatoken = strtok_r(str3, ",", &saveptr3); if (kommatoken == NULL) break; for (str4 = kommatoken; ; str4 = NULL) { dptoken = strtok_r(str4, ":", &saveptr4); if (dptoken == NULL) { break; } if(str4 == kommatoken && str4 != token && eid != -1) { if((ah = get_action_handler(dptoken)) != NULL) { new_event(eid); add_handler(eid, i, ah); i++; } } else if(str4 != token && eid != -1 && ah) { add_option(eid, i-1, k, dptoken); k++; } else if(!ah) break; } k=0; } new_event(eid); add_handler(eid, i, NULL); i=0; } } } /* actions */ int a_exit(char * opt[]) { if(opt[0]) dzen.ret_val = atoi(opt[0]); dzen.running = False; return 0; } int a_collapse(char * opt[]){ (void)opt; if(!dzen.slave_win.ishmenu && dzen.slave_win.max_lines && !dzen.slave_win.issticky) { XUnmapWindow(dzen.dpy, dzen.slave_win.win); } return 0; } int a_uncollapse(char * opt[]){ int i; (void)opt; if(!dzen.slave_win.ishmenu && dzen.slave_win.max_lines && !dzen.slave_win.issticky) { XMapRaised(dzen.dpy, dzen.slave_win.win); for(i=0; i < dzen.slave_win.max_lines; i++) XMapWindow(dzen.dpy, dzen.slave_win.line[i]); } return 0; } int a_togglecollapse(char * opt[]){ XWindowAttributes wa; (void)opt; if(dzen.slave_win.max_lines && (XGetWindowAttributes(dzen.dpy, dzen.slave_win.win, &wa), wa.map_state == IsUnmapped)) a_uncollapse(NULL); else a_collapse(NULL); return 0; } int a_stick(char * opt[]) { (void)opt; if(!dzen.slave_win.ishmenu && dzen.slave_win.max_lines) dzen.slave_win.issticky = True; return 0; } int a_unstick(char * opt[]) { (void)opt; if(!dzen.slave_win.ishmenu && dzen.slave_win.max_lines) dzen.slave_win.issticky = False; return 0; } int a_togglestick(char * opt[]) { (void)opt; if(!dzen.slave_win.ishmenu && dzen.slave_win.max_lines) dzen.slave_win.issticky = dzen.slave_win.issticky ? False : True; return 0; } static void scroll(int n) { if(dzen.slave_win.tcnt <= dzen.slave_win.max_lines) return; if(dzen.slave_win.first_line_vis + n < 0) { dzen.slave_win.first_line_vis = 0; dzen.slave_win.last_line_vis = dzen.slave_win.max_lines; } else if(dzen.slave_win.last_line_vis + n > dzen.slave_win.tcnt) { dzen.slave_win.first_line_vis = dzen.slave_win.tcnt - dzen.slave_win.max_lines; dzen.slave_win.last_line_vis = dzen.slave_win.tcnt; } else { dzen.slave_win.first_line_vis += n; dzen.slave_win.last_line_vis += n; } x_draw_body(); } int a_scrollup(char * opt[]) { int n=1; if(opt[0]) n = atoi(opt[0]); if(dzen.slave_win.max_lines) scroll(-1*n); return 0; } int a_scrolldown(char * opt[]) { int n=1; if(opt[0]) n = atoi(opt[0]); if(dzen.slave_win.max_lines) scroll(n); return 0; } int a_hide(char * opt[]) { int n=1; printf("n:%d\n", n); if(!dzen.title_win.ishidden) { if(!dzen.slave_win.ishmenu) XResizeWindow(dzen.dpy, dzen.title_win.win, dzen.title_win.width, 1); else XResizeWindow(dzen.dpy, dzen.slave_win.win, dzen.title_win.width, 1); dzen.title_win.ishidden = True; } return 0; } int a_unhide(char * opt[]) { (void)opt; if(dzen.title_win.ishidden) { if(!dzen.slave_win.ishmenu) XResizeWindow(dzen.dpy, dzen.title_win.win, dzen.title_win.width, dzen.line_height); else XResizeWindow(dzen.dpy, dzen.slave_win.win, dzen.title_win.width, dzen.line_height); dzen.title_win.ishidden = False; } return 0; } int a_togglehide(char * opt[]) { dzen.title_win.ishidden ? a_unhide(NULL) : a_hide(opt); return 0; } int a_exec(char * opt[]) { int i; if(opt) for(i=0; opt[i]; i++) if(opt[i]) spawn(opt[i]); return 0; } int a_print(char * opt[]) { int i; if(opt) for(i=0; opt[i]; i++) puts(opt[i]); return 0; } int a_menuprint(char * opt[]) { char *text; int i; if(dzen.slave_win.ismenu && dzen.slave_win.sel_line != -1 && (dzen.slave_win.sel_line + dzen.slave_win.first_line_vis) < dzen.slave_win.tcnt) { text = parse_line(NULL, dzen.slave_win.sel_line, 0, 0, 1); printf("%s", text); if(opt) for(i=0; opt[i]; ++i) printf("%s", opt[i]); puts(""); fflush(stdout); dzen.slave_win.sel_line = -1; free(text); } return 0; } int a_menuprint_noparse(char * opt[]) { int i; if(dzen.slave_win.ismenu && dzen.slave_win.sel_line != -1 && (dzen.slave_win.sel_line + dzen.slave_win.first_line_vis) < dzen.slave_win.tcnt) { printf("%s", dzen.slave_win.tbuf[dzen.slave_win.sel_line]); if(opt) for(i=0; opt[i]; ++i) printf("%s", opt[i]); puts(""); fflush(stdout); dzen.slave_win.sel_line = -1; } return 0; } int a_menuexec(char * opt[]) { char *text; (void)opt; if(dzen.slave_win.ismenu && dzen.slave_win.sel_line != -1 && (dzen.slave_win.sel_line + dzen.slave_win.first_line_vis) < dzen.slave_win.tcnt) { text = parse_line(NULL, dzen.slave_win.sel_line, 0, 0, 1); spawn(text); dzen.slave_win.sel_line = -1; free(text); } return 0; } int a_raise(char * opt[]) { (void)opt; XRaiseWindow(dzen.dpy, dzen.title_win.win); if(dzen.slave_win.max_lines) XRaiseWindow(dzen.dpy, dzen.slave_win.win); return 0; } int a_lower(char * opt[]) { (void)opt; XLowerWindow(dzen.dpy, dzen.title_win.win); if(dzen.slave_win.max_lines) XLowerWindow(dzen.dpy, dzen.slave_win.win); return 0; } int a_scrollhome(char * opt[]) { (void)opt; if(dzen.slave_win.max_lines) { dzen.slave_win.first_line_vis = 0; dzen.slave_win.last_line_vis = dzen.slave_win.max_lines; x_draw_body(); } return 0; } int a_scrollend(char * opt[]) { (void)opt; if(dzen.slave_win.max_lines) { dzen.slave_win.first_line_vis = dzen.slave_win.tcnt - dzen.slave_win.max_lines ; dzen.slave_win.last_line_vis = dzen.slave_win.tcnt; x_draw_body(); } return 0; } int a_grabkeys(char * opt[]) { (void)opt; XGrabKeyboard(dzen.dpy, RootWindow(dzen.dpy, dzen.screen), True, GrabModeAsync, GrabModeAsync, CurrentTime); return 0; } int a_ungrabkeys(char * opt[]) { (void)opt; XUngrabKeyboard(dzen.dpy, CurrentTime); return 0; } int a_grabmouse(char * opt[]) { (void)opt; XGrabPointer(dzen.dpy, RootWindow(dzen.dpy, dzen.screen), True, ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); return 0; } int a_ungrabmouse(char * opt[]) { (void)opt; XUngrabPointer(dzen.dpy, CurrentTime); return 0; }