From a6781157b64e27aa9bee2af0fc976b264dccbe4d Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Fri, 12 Oct 2007 17:10:36 +0200 Subject: [PATCH] allow to execute uicb function via awesome control fifo --- Makefile | 2 +- awesome.c | 20 ++++----- config.c | 126 ++++++++++++++++++++-------------------------------- statusbar.c | 10 +++++ statusbar.h | 1 + uicb.c | 85 +++++++++++++++++++++++++++++++++++ uicb.h | 36 +++++++++++++++ util.c | 20 +++++++++ util.h | 8 ++++ 9 files changed, 218 insertions(+), 90 deletions(-) create mode 100644 uicb.c create mode 100644 uicb.h diff --git a/Makefile b/Makefile index a491e285..7350d9ef 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = client.c draw.c event.c layout.c awesome.c tag.c util.c config.c screen.c statusbar.c +SRC = client.c draw.c event.c layout.c awesome.c tag.c util.c config.c screen.c statusbar.c uicb.c OBJ = ${SRC:.c=.o} ${LAYOUTS:.c=.o} all: options awesome diff --git a/awesome.c b/awesome.c index a0e33cf2..77074929 100644 --- a/awesome.c +++ b/awesome.c @@ -42,6 +42,7 @@ #include "screen.h" #include "util.h" #include "statusbar.h" +#include "uicb.h" #define CONTROL_FIFO_PATH ".awesome_ctl" @@ -258,7 +259,7 @@ typedef void event_handler (XEvent *, awesome_config *); int main(int argc, char *argv[]) { - char *p, *fifopath; + char *fifopath, buf[1024]; const char *confpath = NULL, *homedir; int r, cfd, xfd, e_dummy; fd_set rd; @@ -390,13 +391,13 @@ main(int argc, char *argv[]) p_delete(&fifopath); + FD_ZERO(&rd); + if(cfd > 0) + FD_SET(cfd, &rd); + FD_SET(xfd, &rd); /* main event loop, also reads status text from stdin */ while(running) { - FD_ZERO(&rd); - if(cfd > 0) - FD_SET(cfd, &rd); - FD_SET(xfd, &rd); if(select(MAX(xfd, cfd) + 1, &rd, NULL, NULL, NULL) == -1) { if(errno == EINTR) @@ -405,7 +406,7 @@ main(int argc, char *argv[]) } if(cfd >= 0 && FD_ISSET(cfd, &rd)) { - switch (r = read(cfd, awesomeconf[0].statustext, sizeof(awesomeconf[0].statustext) - 1)) + switch (r = read(cfd, buf, sizeof(buf))) { case -1: perror("awesome: error reading fifo"); @@ -417,12 +418,7 @@ main(int argc, char *argv[]) case 0: break; default: - for(awesomeconf[0].statustext[r] = '\0', p = awesomeconf[0].statustext + a_strlen(awesomeconf[0].statustext) - 1; - p >= awesomeconf[0].statustext && *p == '\n'; *p-- = '\0'); - for(; p >= awesomeconf[0].statustext && *p != '\n'; --p); - if(p > awesomeconf[0].statustext) - a_strncpy(awesomeconf[0].statustext, sizeof(awesomeconf[0].statustext), - p + 1, sizeof(awesomeconf[0].statustext)); + parse_control(buf, awesomeconf); } drawstatusbar(dpy, &awesomeconf[0]); } diff --git a/config.c b/config.c index 885bbaaa..4e3c1287 100644 --- a/config.c +++ b/config.c @@ -27,29 +27,19 @@ #include #include -#include "awesome.h" -#include "layout.h" -#include "tag.h" -#include "draw.h" #include "util.h" -#include "statusbar.h" +#include "uicb.h" #include "screen.h" +#include "draw.h" #include "layouts/tile.h" -#include "layouts/max.h" #include "layouts/floating.h" +#include "layouts/max.h" #define AWESOME_CONFIG_FILE ".awesomerc" static XColor initxcolor(Display *, int, const char *); static unsigned int get_numlockmask(Display *); -/** Link a name to a function */ -typedef struct -{ - const char *name; - void *func; -} NameFuncLink; - /** Link a name to a key symbol */ typedef struct { @@ -57,6 +47,51 @@ typedef struct KeySym keysym; } KeyMod; +/** List of available UI bindable callbacks and functions */ +const NameFuncLink UicbList[] = { + /* util.c */ + {"spawn", uicb_spawn}, + {"exec", uicb_exec}, + /* client.c */ + {"killclient", uicb_killclient}, + {"moveresize", uicb_moveresize}, + {"settrans", uicb_settrans}, + {"setborder", uicb_setborder}, + {"swapnext", uicb_swapnext}, + {"swapprev", uicb_swapprev}, + /* tag.c */ + {"tag", uicb_tag}, + {"togglefloating", uicb_togglefloating}, + {"toggleview", uicb_toggleview}, + {"toggletag", uicb_toggletag}, + {"view", uicb_view}, + {"view_tag_prev_selected", uicb_tag_prev_selected}, + {"view_tag_previous", uicb_tag_viewprev}, + {"view_tag_next", uicb_tag_viewnext}, + /* layout.c */ + {"setlayout", uicb_setlayout}, + {"focusnext", uicb_focusnext}, + {"focusprev", uicb_focusprev}, + {"togglemax", uicb_togglemax}, + {"toggleverticalmax", uicb_toggleverticalmax}, + {"togglehorizontalmax", uicb_togglehorizontalmax}, + {"zoom", uicb_zoom}, + /* layouts/tile.c */ + {"setmwfact", uicb_setmwfact}, + {"setnmaster", uicb_setnmaster}, + {"setncol", uicb_setncol}, + /* screen.c */ + {"focusnextscreen", uicb_focusnextscreen}, + {"focusprevscreen", uicb_focusprevscreen}, + {"movetoscreen", uicb_movetoscreen}, + /* awesome.c */ + {"quit", uicb_quit}, + /* statusbar.c */ + {"togglebar", uicb_togglebar}, + {"setstatustext", uicb_setstatustext}, + {NULL, NULL} +}; + /** List of keyname and corresponding X11 mask codes */ static const KeyMod KeyModList[] = { @@ -81,50 +116,6 @@ static const NameFuncLink LayoutsList[] = {NULL, NULL} }; -/** List of available UI bindable callbacks and functions */ -static const NameFuncLink KeyfuncList[] = { - /* util.c */ - {"spawn", uicb_spawn}, - {"exec", uicb_exec}, - /* client.c */ - {"killclient", uicb_killclient}, - {"moveresize", uicb_moveresize}, - {"settrans", uicb_settrans}, - {"setborder", uicb_setborder}, - {"swapnext", uicb_swapnext}, - {"swapprev", uicb_swapprev}, - /* tag.c */ - {"tag", uicb_tag}, - {"togglefloating", uicb_togglefloating}, - {"toggleview", uicb_toggleview}, - {"toggletag", uicb_toggletag}, - {"view", uicb_view}, - {"view_tag_prev_selected", uicb_tag_prev_selected}, - {"view_tag_previous", uicb_tag_viewprev}, - {"view_tag_next", uicb_tag_viewnext}, - /* layout.c */ - {"setlayout", uicb_setlayout}, - {"focusnext", uicb_focusnext}, - {"focusprev", uicb_focusprev}, - {"togglemax", uicb_togglemax}, - {"toggleverticalmax", uicb_toggleverticalmax}, - {"togglehorizontalmax", uicb_togglehorizontalmax}, - {"zoom", uicb_zoom}, - /* layouts/tile.c */ - {"setmwfact", uicb_setmwfact}, - {"setnmaster", uicb_setnmaster}, - {"setncol", uicb_setncol}, - /* screen.c */ - {"focusnextscreen", uicb_focusnextscreen}, - {"focusprevscreen", uicb_focusprevscreen}, - {"movetoscreen", uicb_movetoscreen}, - /* awesome.c */ - {"quit", uicb_quit}, - /* statusbar.c */ - {"togglebar", uicb_togglebar}, - {NULL, NULL} -}; - /** Lookup for a key mask from its name * \param keyname Key name * \return Key mask or 0 if not found @@ -142,25 +133,6 @@ key_mask_lookup(const char *keyname) return 0; } -/** Lookup for a function pointer from its name - * in the given NameFuncLink list - * \param funcname Function name - * \param list Function and name link list - * \return function pointer - */ -static void * -name_func_lookup(const char *funcname, const NameFuncLink * list) -{ - int i; - - if(funcname && list) - for(i = 0; list[i].name; i++) - if(!a_strcmp(funcname, list[i].name)) - return list[i].func; - - return NULL; -} - /** Parse configuration file and initialize some stuff * \param disp Display ref * \param scr Screen number @@ -410,7 +382,7 @@ parse_config(Display * disp, int scr,const char *confpatharg, awesome_config *aw for(j = 0; j < cfg_size(cfgsectmp, "modkey"); j++) awesomeconf->keys[i].mod |= key_mask_lookup(cfg_getnstr(cfgsectmp, "modkey", j)); awesomeconf->keys[i].keysym = XStringToKeysym(cfg_getstr(cfgsectmp, "key")); - awesomeconf->keys[i].func = name_func_lookup(cfg_getstr(cfgsectmp, "command"), KeyfuncList); + awesomeconf->keys[i].func = name_func_lookup(cfg_getstr(cfgsectmp, "command"), UicbList); awesomeconf->keys[i].arg = a_strdup(cfg_getstr(cfgsectmp, "arg")); } diff --git a/statusbar.c b/statusbar.c index 0cd10c1e..c6f53c26 100644 --- a/statusbar.c +++ b/statusbar.c @@ -248,3 +248,13 @@ uicb_togglebar(awesome_config *awesomeconf, arrange(awesomeconf->display, awesomeconf); } + +void +uicb_setstatustext(awesome_config *awesomeconf, const char *arg) +{ + if(!arg) + return; + a_strncpy(awesomeconf->statustext, sizeof(awesomeconf->statustext), arg, a_strlen(arg)); + + drawstatusbar(awesomeconf->display, awesomeconf); +} diff --git a/statusbar.h b/statusbar.h index d972572a..69b35186 100644 --- a/statusbar.h +++ b/statusbar.h @@ -29,5 +29,6 @@ void drawstatusbar(Display *, awesome_config *); void updatebarpos(Display *, Statusbar); UICB_PROTO(uicb_togglebar); +UICB_PROTO(uicb_setstatustext); #endif diff --git a/uicb.c b/uicb.c new file mode 100644 index 00000000..fdc49f21 --- /dev/null +++ b/uicb.c @@ -0,0 +1,85 @@ +/* + * uicb.c - user interface callbacks management + * + * Copyright © 2007 Julien Danjou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include + +#include "util.h" +#include "uicb.h" + +extern const NameFuncLink UicbList[]; + +int +parse_control(char *cmd, awesome_config *awesomeconf) +{ + char *p, *curcmd = cmd; + + if(!a_strlen(cmd)) + return -1; + + while((p = strchr(curcmd, '\n'))) + { + *p = '\0'; + run_uicb(curcmd, awesomeconf); + curcmd = p + 1; + } + + return 0; +} + +int +run_uicb(char *cmd, awesome_config *awesomeconf) +{ + char *p, *uicb_name, *arg; + int screen; + void (*uicb) (awesome_config *, char *); + + if(!a_strlen(cmd)) + return -1; + + if(!(p = strchr(cmd, ' '))) + return -1; + + *p++ = '\0'; + + if((screen = atoi(cmd)) >= get_screen_count(awesomeconf->display)) + return -1; + + uicb_name = p; + + if(!(p = strchr(p, ' '))) + return -1; + + *p++ = '\0'; + + arg = p; + + if((p = strchr(arg, '\n'))) + *p = '\0'; + + uicb = name_func_lookup(uicb_name, UicbList); + + if(uicb) + uicb(&awesomeconf[screen], arg); + else + return -1; + + return 0; +} diff --git a/uicb.h b/uicb.h new file mode 100644 index 00000000..df6bf85b --- /dev/null +++ b/uicb.h @@ -0,0 +1,36 @@ +/* + * uicb.h - user interface callbacks management header + * + * Copyright © 2007 Julien Danjou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef AWESOME_UICB_H +#define AWESOME_UICB_H + +#include "config.h" +#include "screen.h" +#include "tag.h" +#include "layout.h" +#include "awesome.h" +#include "statusbar.h" +#include "layouts/tile.h" + +int parse_control(char *, awesome_config *); +int run_uicb(char *, awesome_config *); + +#endif diff --git a/util.c b/util.c index 0e1a5cbb..9c504a83 100644 --- a/util.c +++ b/util.c @@ -155,6 +155,26 @@ compute_new_value_from_arg(const char *arg, double current_value) return current_value; } + +/** Lookup for a function pointer from its name + * in the given NameFuncLink list + * \param funcname Function name + * \param list Function and name link list + * \return function pointer + */ +void * +name_func_lookup(const char *funcname, const NameFuncLink * list) +{ + int i; + + if(funcname && list) + for(i = 0; list[i].name; i++) + if(!a_strcmp(funcname, list[i].name)) + return list[i].func; + + return NULL; +} + /** \brief safe limited strcpy. * * Copies at most min(n-1, \c l) characters from \c src into \c dst, diff --git a/util.h b/util.h index b75849e9..cadb8ab8 100644 --- a/util.h +++ b/util.h @@ -27,6 +27,13 @@ #include #include "common.h" +/** Link a name to a function */ +typedef struct +{ + const char *name; + void *func; +} NameFuncLink; + /** \brief replace \c NULL strings with emtpy strings */ #define NONULL(x) (x ? x : "") @@ -195,6 +202,7 @@ void die(const char *, ...) __attribute__ ((noreturn)) __attribute__ ((format(pr void eprint(const char *, ...) __attribute__ ((noreturn)) __attribute__ ((format(printf, 1, 2))); Bool xgettextprop(Display *, Window, Atom, char *, ssize_t); double compute_new_value_from_arg(const char *, double); +void *name_func_lookup(const char *, const NameFuncLink *); UICB_PROTO(uicb_spawn); UICB_PROTO(uicb_exec);