allow to execute uicb function via awesome control fifo

This commit is contained in:
Julien Danjou 2007-10-12 17:10:36 +02:00
parent 7ca3bd32bb
commit a6781157b6
9 changed files with 218 additions and 90 deletions

View File

@ -3,7 +3,7 @@
include config.mk 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} OBJ = ${SRC:.c=.o} ${LAYOUTS:.c=.o}
all: options awesome all: options awesome

View File

@ -42,6 +42,7 @@
#include "screen.h" #include "screen.h"
#include "util.h" #include "util.h"
#include "statusbar.h" #include "statusbar.h"
#include "uicb.h"
#define CONTROL_FIFO_PATH ".awesome_ctl" #define CONTROL_FIFO_PATH ".awesome_ctl"
@ -258,7 +259,7 @@ typedef void event_handler (XEvent *, awesome_config *);
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char *p, *fifopath; char *fifopath, buf[1024];
const char *confpath = NULL, *homedir; const char *confpath = NULL, *homedir;
int r, cfd, xfd, e_dummy; int r, cfd, xfd, e_dummy;
fd_set rd; fd_set rd;
@ -390,13 +391,13 @@ main(int argc, char *argv[])
p_delete(&fifopath); 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 */ /* main event loop, also reads status text from stdin */
while(running) 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(select(MAX(xfd, cfd) + 1, &rd, NULL, NULL, NULL) == -1)
{ {
if(errno == EINTR) if(errno == EINTR)
@ -405,7 +406,7 @@ main(int argc, char *argv[])
} }
if(cfd >= 0 && FD_ISSET(cfd, &rd)) 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: case -1:
perror("awesome: error reading fifo"); perror("awesome: error reading fifo");
@ -417,12 +418,7 @@ main(int argc, char *argv[])
case 0: case 0:
break; break;
default: default:
for(awesomeconf[0].statustext[r] = '\0', p = awesomeconf[0].statustext + a_strlen(awesomeconf[0].statustext) - 1; parse_control(buf, awesomeconf);
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));
} }
drawstatusbar(dpy, &awesomeconf[0]); drawstatusbar(dpy, &awesomeconf[0]);
} }

126
config.c
View File

@ -27,29 +27,19 @@
#include <confuse.h> #include <confuse.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include "awesome.h"
#include "layout.h"
#include "tag.h"
#include "draw.h"
#include "util.h" #include "util.h"
#include "statusbar.h" #include "uicb.h"
#include "screen.h" #include "screen.h"
#include "draw.h"
#include "layouts/tile.h" #include "layouts/tile.h"
#include "layouts/max.h"
#include "layouts/floating.h" #include "layouts/floating.h"
#include "layouts/max.h"
#define AWESOME_CONFIG_FILE ".awesomerc" #define AWESOME_CONFIG_FILE ".awesomerc"
static XColor initxcolor(Display *, int, const char *); static XColor initxcolor(Display *, int, const char *);
static unsigned int get_numlockmask(Display *); 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 */ /** Link a name to a key symbol */
typedef struct typedef struct
{ {
@ -57,6 +47,51 @@ typedef struct
KeySym keysym; KeySym keysym;
} KeyMod; } 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 */ /** List of keyname and corresponding X11 mask codes */
static const KeyMod KeyModList[] = static const KeyMod KeyModList[] =
{ {
@ -81,50 +116,6 @@ static const NameFuncLink LayoutsList[] =
{NULL, NULL} {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 /** Lookup for a key mask from its name
* \param keyname Key name * \param keyname Key name
* \return Key mask or 0 if not found * \return Key mask or 0 if not found
@ -142,25 +133,6 @@ key_mask_lookup(const char *keyname)
return 0; 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 /** Parse configuration file and initialize some stuff
* \param disp Display ref * \param disp Display ref
* \param scr Screen number * \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++) for(j = 0; j < cfg_size(cfgsectmp, "modkey"); j++)
awesomeconf->keys[i].mod |= key_mask_lookup(cfg_getnstr(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].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")); awesomeconf->keys[i].arg = a_strdup(cfg_getstr(cfgsectmp, "arg"));
} }

View File

@ -248,3 +248,13 @@ uicb_togglebar(awesome_config *awesomeconf,
arrange(awesomeconf->display, 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);
}

View File

@ -29,5 +29,6 @@ void drawstatusbar(Display *, awesome_config *);
void updatebarpos(Display *, Statusbar); void updatebarpos(Display *, Statusbar);
UICB_PROTO(uicb_togglebar); UICB_PROTO(uicb_togglebar);
UICB_PROTO(uicb_setstatustext);
#endif #endif

85
uicb.c Normal file
View File

@ -0,0 +1,85 @@
/*
* uicb.c - user interface callbacks management
*
* Copyright © 2007 Julien Danjou <julien@danjou.info>
*
* 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 <string.h>
#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;
}

36
uicb.h Normal file
View File

@ -0,0 +1,36 @@
/*
* uicb.h - user interface callbacks management header
*
* Copyright © 2007 Julien Danjou <julien@danjou.info>
*
* 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

20
util.c
View File

@ -155,6 +155,26 @@ compute_new_value_from_arg(const char *arg, double current_value)
return 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. /** \brief safe limited strcpy.
* *
* Copies at most min(<tt>n-1</tt>, \c l) characters from \c src into \c dst, * Copies at most min(<tt>n-1</tt>, \c l) characters from \c src into \c dst,

8
util.h
View File

@ -27,6 +27,13 @@
#include <stdlib.h> #include <stdlib.h>
#include "common.h" #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 */ /** \brief replace \c NULL strings with emtpy strings */
#define NONULL(x) (x ? x : "") #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))); void eprint(const char *, ...) __attribute__ ((noreturn)) __attribute__ ((format(printf, 1, 2)));
Bool xgettextprop(Display *, Window, Atom, char *, ssize_t); Bool xgettextprop(Display *, Window, Atom, char *, ssize_t);
double compute_new_value_from_arg(const char *, double); double compute_new_value_from_arg(const char *, double);
void *name_func_lookup(const char *, const NameFuncLink *);
UICB_PROTO(uicb_spawn); UICB_PROTO(uicb_spawn);
UICB_PROTO(uicb_exec); UICB_PROTO(uicb_exec);