diff --git a/python/tag_func.c b/python/tag_func.c index d24e458..cec5814 100644 --- a/python/tag_func.c +++ b/python/tag_func.c @@ -1,4 +1,4 @@ -/* +3* * tag_func.c * Copyright © 2008 Martin Duquesnoy * All rights reserved. diff --git a/shell/wmfs-shell.c b/shell/wmfs-shell.c new file mode 100644 index 0000000..6440d56 --- /dev/null +++ b/shell/wmfs-shell.c @@ -0,0 +1,178 @@ +#include "wmfs-shell.h" + +void +send_client_message(char* atom_name, long data_l[5]) +{ + XEvent ev; + int i; + + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.message_type = ATOM(atom_name); + ev.xclient.window = ROOT; + ev.xclient.format = 32; + + for(i = 0; i < 6; ++i) + ev.xclient.data.l[i] = data_l[i]; + + XSendEvent(dpy, ROOT, False, SubstructureRedirectMask|SubstructureNotifyMask, &ev); + XSync(dpy, False); + + return; +} + +void +spawn(char* arg) +{ + char *sh; + + if(!(sh = getenv("SHELL"))) + sh = "/bin/sh"; + if(!strlen(arg)) + return; + + if(fork() == 0) + { + if(fork() == 0) + { + setsid(); + execl(sh, sh, "-c", arg, (char*)NULL); + } + exit(EXIT_SUCCESS); + } + + return; +} + + +void +exec_uicb_function(char *func, char *cmd) +{ + long data[5]; + + data[4] = True; + + XChangeProperty(dpy, ROOT, ATOM("_WMFS_FUNCTION"), ATOM("UTF8_STRING"), + 8, PropModeReplace, (unsigned char*)func, strlen(func)); + + if(cmd == NULL) + cmd = ""; + XChangeProperty(dpy, ROOT, ATOM("_WMFS_CMD"), ATOM("UTF8_STRING"), + 8, PropModeReplace, (unsigned char*)cmd, strlen(cmd)); + + send_client_message("_WMFS_FUNCTION", data); + + return; +} + +void +manage_input(char *input) +{ + char *p = input; + char *q1, *q2, *tmp, *aargs = NULL, *func = input; + char **args; + int i, v = 0; + + + if(!strcmp(input, "clear")) + printf(CLEAR); + else if(!strcmp(input, "exit") + || !strcmp(input, "quit")) + exit(EXIT_FAILURE); + else if(!strcmp(input, "help") + || !strcmp(input, "list")) + printf(HELPSTR); + else if(!strcmp(input, "uicb_list") + || !strcmp(input, "uicb_function_list")) + printf(UICBLIST); + + /* If there is a function ( func() ) */ + else if((q1 = strchr(p, '(')) + && (q2 = strchr(p, ')')) + && p[0] != '(') + { + /* Set FUNCTION Name AND ARGS in **args + * {{{ */ + + /* Get function name */ + for(i = 0; i < strlen(p) - ((strlen(p) - strlen(q1))); ++i) + func[ (strlen(p) - strlen(q1)) + i ] = 0; + + *q1 = *q2 = '\0'; + aargs = q1 + 1; + + /* Count how many ',' there is in aargs */ + for(i = 0; i < strlen(aargs) + 1; ++i) + if(aargs[i] == ',') + ++v; + + args = malloc(sizeof(char*) * v + 1); + tmp = strtok(aargs, ","); + + for(i = 0; tmp != NULL; ++i) + { + args[i] = tmp; + tmp = strtok(NULL, ","); + } + /* + * }}} */ + + /* Manage function */ + + if(!strcmp(func, "exec")) + { + if(v > 1 || !args[0]) + printf("Exec: exec(, ).\n"); + else + { + if(!args[1]) + args[1] = NULL; + exec_uicb_function(args[0], args[1]); + } + } + else if(!strcmp(func, "spawn")) + { + if(v > 0 || !args[0]) + printf("Spawn: spawn(), Execute a system command.\n"); + else + spawn(args[0]); + } + + free(args); + } + + + return; +} + +int +main(void) +{ + char *input, *p, c; + + if(!(dpy = XOpenDisplay(NULL))) + fprintf(stderr, "wmfs-shell: Wmfs is probably not running: cannot open X server. \n"); + + for(;;) + { + printf(PROMPT); + + input = malloc(sizeof(char) * SIZE); + + fgets(input, SIZE, stdin); + + if((p = strrchr(input, '\n')) != NULL) + *p = '\0'; + else + while((c = fgetc(stdin)) != '\n' && c != EOF); + + manage_input(input); + + free(input); + } + + + + return 0; +} diff --git a/shell/wmfs-shell.h b/shell/wmfs-shell.h new file mode 100644 index 0000000..b10bd70 --- /dev/null +++ b/shell/wmfs-shell.h @@ -0,0 +1,61 @@ +#include +#include +#include +#include + +#include +#include +#include + +#define SIZE 512 + +#define PROMPT "wmfs-shell >> " +#define CLEAR "\033[H\033[2J" + +#define HELPSTR \ +"\n help, list Print this message.\n\ + clear Clear the terminal.\n\ + exit, quit Quit wmfs-shell.\n\ + uicb_list Print all uicb wmfs function.\n\ + exec(, ) Execute a Wmfs uicb function.\n\ + spawn() Execute a system command.\n\n" +#define UICBLIST \ + "Here is a list of all wmfs's uicb functions that are usable with the exec function: \n\ + spawn Exec a system command. \n\ + client_kill Kill the selected client. \n\ + client_prev Select the previous client. \n\ + client_next Select the next client. \n\ + toggle_max Toggle the selected client max/. \n\ + layout_next Set the next layout. \n\ + layout_prev Set the previous layout. \n\ + tag Manipul tag (1, 3, +2 ..). \n\ + tag_next Select the next tag. \n\ + tag_prev Select the previous tag. \n\ + tag_transfert Transfert the selected client to the tag. \n\ + set_mwfact Set the mwfact (+0.10, -0.43, ...). \n\ + set_nmaster Set the nmaster (+1 ..). \n\ + quit Quit WMFS. \n\ + toggle_infobar_position Toggle the infobar position (top/bottom). \n\ + mouse_move Select the selected client with the mouse and move it. \n\ + mouse_resize Select the selected client with the mouse and resize it. \n\ + client_raise Raise the selected client. \n\ + tile_switch Switch the master client in the tile grid. \n\ + toggle_free Toggle the selected client to free. \n\ + screen_select Select the screen. \n\ + screen_next Select the next screen. \n\ + screen_prev Select the previous screen. \n\ + reload Reload the WMFS configuration. \n\n" + + +/* Xlib util macro */ +#define ROOT RootWindow(dpy, SCREEN) +#define ATOM(a) XInternAtom(dpy, a, False) +#define SCREEN DefaultScreen(dpy) + +/* Protos */ +void send_client_message(char* atom_name, long data_l[5]); +void exec_uicb_function(char *func, char *cmd); +void manage_input(char *input); + +/* Variables */ +Display *dpy; diff --git a/src/event.c b/src/event.c index 1dcea95..1ec91b2 100644 --- a/src/event.c +++ b/src/event.c @@ -183,7 +183,8 @@ clientmessageevent(XClientMessageEvent *ev) void (*func)(uicb_t) = name_to_func((char*)ret_func, func_list); - func((uicb_t)ret_cmd); + if(func) + func((uicb_t)ret_cmd); if(ret_cmd) XFree(ret_cmd); diff --git a/src/mouse.c b/src/mouse.c index 34f3347..46ff317 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -142,7 +142,7 @@ mouse_grabbuttons(Client *c, Bool focused) XUngrabButton(dpy, AnyButton, AnyModifier, c->win); if(focused) - for(i = 0; i < (sizeof but / sizeof but[0]); ++i) + for(i = 0; i < LEN(but); ++i) { XGrabButton(dpy, but[i], conf.client.mod, c->win, False, ButtonMask, GrabModeAsync,GrabModeSync, None, None); diff --git a/src/structs.h b/src/structs.h index 3744775..3737926 100644 --- a/src/structs.h +++ b/src/structs.h @@ -40,7 +40,7 @@ #define NUM_OF_LAYOUT 7 /* Typedef */ -typedef const char* uicb_t; +typedef const char* uicb_t; typedef unsigned int uint; typedef unsigned long ulong; typedef unsigned short ushort; diff --git a/src/util.c b/src/util.c index 31fc213..ffe99bb 100644 --- a/src/util.c +++ b/src/util.c @@ -75,7 +75,6 @@ color_enlight(ulong col) return col + 0x333333; else return col; - } /** Round function diff --git a/src/wmfs.c b/src/wmfs.c index fdb254e..1a58bf2 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -314,7 +314,6 @@ main(int argc, char **argv) XSetErrorHandler(errorhandler); /* Let's Go ! */ - ewmh_init_hints(); init_conf(); init();