From 2d1afba2e3c20ac7cf49758ebc26235bf6595e2f Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Wed, 22 Apr 2009 02:32:55 +0200 Subject: [PATCH] Wmfs: Remove shell, add -c and -s options, see -h. --- CMakeLists.txt | 8 +- shell/.gitignore | 3 - shell/wmfs-shell.c | 341 --------------------------------------------- shell/wmfs-shell.h | 96 ------------- src/wmfs.c | 134 +++++++++++++++++- src/wmfs.h | 3 + 6 files changed, 133 insertions(+), 452 deletions(-) delete mode 100644 shell/.gitignore delete mode 100644 shell/wmfs-shell.c delete mode 100644 shell/wmfs-shell.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f4d4b5f..e2aff09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,12 +46,9 @@ set(wmfs_src src/tag.c src/util.c src/wmfs.c) -set(wmfs-shell_src - shell/wmfs-shell.c) # Set the executable from the wmfs_src add_executable(wmfs ${wmfs_src}) -add_executable(wmfs-shell ${wmfs-shell_src}) # Set the version - NOT USED AT THE MOMENT set(VERSION "0.1rc4 (On The Run)") @@ -88,11 +85,8 @@ set(LIBRARIES_TO_LINK confuse Xft Xinerama) -set(SHELL_LINK_LIBS - ${X11_LIBRARIES}) target_link_libraries(wmfs ${LIBRARIES_TO_LINK}) -target_link_libraries(wmfs-shell ${SHELL_LINK_LIBS}) # Messages message("Project version: ${VERSION}") @@ -298,7 +292,7 @@ set(PROJECT_CHANGELOG ${SOURCE_DIR}/CHANGELOG) set(PROJECT_DEFAULT_CONF ${SOURCE_DIR}/wmfsrc) # installs -install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME_SHELL} RUNTIME DESTINATION bin) +install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) if(WITH_LOGOS) set(PROJECT_LOGOS ${PROJECT_DATA_PATH}/logos) set(PROJECT_LOGOS_DIR ${SOURCE_DIR}/logos) diff --git a/shell/.gitignore b/shell/.gitignore deleted file mode 100644 index 3976386..0000000 --- a/shell/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*~ -*# -a.out diff --git a/shell/wmfs-shell.c b/shell/wmfs-shell.c deleted file mode 100644 index 58c027c..0000000 --- a/shell/wmfs-shell.c +++ /dev/null @@ -1,341 +0,0 @@ -/* -* wmfs-shell.c -* Copyright © 2008 Martin Duquesnoy -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following disclaimer -* in the documentation and/or other materials provided with the -* distribution. -* * Neither the name of the nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "wmfs-shell.h" - -void -init(void) -{ - Atom rt; - int rf; - unsigned long ir, il; - unsigned char *ret; - - /* Init display */ - if(!(dpy = XOpenDisplay(NULL))) - { - fprintf(stderr, "wmfs-shell: Wmfs is probably not running: cannot open X server. \n"); - exit(EXIT_SUCCESS); - } - - /* Check if wmfs is running */ - XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_RUNNING"), 0L, 4096, - False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret); - - if(!ret) - { - XFree(ret); - fprintf(stderr, "Wmfs is not running. ( _WMFS_RUNNING not present)\n"); - exit(EXIT_FAILURE); - } - - return; -} - -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 -statustext(char *text) -{ - long data[5]; - - data[4] = True; - - XChangeProperty(dpy, ROOT, ATOM("_WMFS_STATUSTEXT"), ATOM("UTF8_STRING"), - 8, PropModeReplace, (unsigned char*)text, strlen(text)); - - send_client_message("_WMFS_STATUSTEXT", data); - - 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 -tag_get_current(char **name, int *num) -{ - Atom rt; - int rf; - unsigned long ir, il; - unsigned char *ret; - - if(name && XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_CURRENT_TAG"), 0L, 4096, - False, ATOM("UTF8_STRING"), &rt, &rf, &ir, &il, &ret) == Success) - *name = (char*)ret; - - if(XGetWindowProperty(dpy, ROOT, ATOM("_NET_CURRENT_DESKTOP"), 0L, 4096, - False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success) - *num = *(int*)ret; - - if(ret) - XFree(ret); - - return; -} - -void -tag_set(int tag) -{ - long data[5]; - int t; - char *n; - - if(tag >= 0) - data[0] = tag; - - send_client_message("_NET_CURRENT_DESKTOP", data); - - usleep(100000); /* For tag_get_current */ - - tag_get_current(&n, &t); - printf("Your now on '%s' (tag %d).\n", n, t); - - return; -} - -void -manage_input(char *input) -{ - char *p = input, *func = input; - char *q1, *q2, *tmp, *aargs = NULL; - char **args; - int i, v = 0; - - if(!strcmp(input, "clear")) - printf(CLEAR); - else if(!strcmp(input, "exit") - || !strcmp(input, "quit")) - exit(EXIT_SUCCESS); - 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, "tag_set")) - { - if(v > 0 || !args[0]) - printf("Tag_set: tag_set(), Set the current tag.\n"); - else - tag_set(atoi(args[0])); - } - else if(!strcmp(func, "statustext")) - { - if(v > 0 || !args[0]) - printf("Statustext: statustext(), Print text in the wmfs bar.\n"); - else - statustext(args[0]); - } - else if(!strcmp(func, "spawn")) - { - if(v > 0 || !args[0]) - printf("Spawn: spawn(), Execute a system command.\n"); - else - spawn(args[0]); - } - - free(args); - } - else - printf("Unknow command '%s', try 'help'.\n", input); - - return; -} - -int -main(int argc, char *argv[]) -{ - char *input, *p; - int c; - char opt; - - static struct option shell_opts[] = - { - {"help", 0, NULL, 'h'}, - {"cmd", 1, NULL, 'c'}, - {0} - }; - - /* Initialisation */ - init(); - - /* get args from argv */ - while(EOF != (opt = (char)getopt_long(argc, argv, "hc", shell_opts, NULL))) - { - - /* Just print help */ - if( (opt == 'h') || (opt == '?')) - { - printf("Usage : wmfs-shell [-c|--cmd cmd]\n"); - exit(0); - } - - else if(opt == 'c') - { - /* Run a single command */ - if((argc >= 2)&&(argv[2] != '\0')) - manage_input(argv[2]); - else - printf("Run 'wmfs-shell --help' for help\n"); - exit(0); - } - - } - - 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); - - if(*input != '\0') - manage_input(input); - - free(input); - } - - return 0; -} diff --git a/shell/wmfs-shell.h b/shell/wmfs-shell.h deleted file mode 100644 index 566e26d..0000000 --- a/shell/wmfs-shell.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -* wmfs-shell.h -* Copyright © 2008 Martin Duquesnoy -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following disclaimer -* in the documentation and/or other materials provided with the -* distribution. -* * Neither the name of the nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#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\ - tag_set() Change the current tag\n\ - statustext(text) Print text in the wmfs bar.\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/wmfs.c b/src/wmfs.c index 10c19d2..c5805c1 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -260,6 +260,111 @@ uicb_reload(uicb_t cmd) return; } +/** Check if wmfs is running (for function that will be + execute when wmfs will be already running). + \return False if wmfs is not running +*/ +Bool +check_wmfs_running(void) +{ + Atom rt; + int rf; + ulong ir, il; + uchar *ret; + + XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_RUNNING"), 0L, 4096, + False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret); + + if(!ret) + { + XFree(ret); + + fprintf(stderr, "Wmfs is not running. ( _WMFS_RUNNING not present)\n"); + + return False; + } + + XFree(ret); + + return True; +} + +/** Execute an uicb function + *\param func Function name + *\param cmd Function's command + *\return 0 if there is an error +*/ +void +exec_uicb_function(char *func, char *cmd) +{ + XEvent ev; + int i; + long data[5]; + + /* Check if wmfs is running (this function is executed when wmfs + is already running normally...) */ + if(!check_wmfs_running()) + return; + + data[4] = True; + + XChangeProperty(dpy, ROOT, ATOM("_WMFS_FUNCTION"), ATOM("UTF8_STRING"), + 8, PropModeReplace, (uchar*)func, strlen(func)); + + if(cmd == NULL) + cmd = ""; + + XChangeProperty(dpy, ROOT, ATOM("_WMFS_CMD"), ATOM("UTF8_STRING"), + 8, PropModeReplace, (uchar*)cmd, strlen(cmd)); + + + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.message_type = ATOM("_WMFS_FUNCTION"); + ev.xclient.window = ROOT; + ev.xclient.format = 32; + + for(i = 0; i < 6; ++i) + ev.xclient.data.l[i] = data[i]; + + XSendEvent(dpy, ROOT, False, SubstructureRedirectMask | SubstructureNotifyMask, &ev); + XSync(dpy, False); + + return; +} + +/** Set statustext + *\param str Statustext string +*/ +void +set_statustext(char *str) +{ + XEvent ev; + int i; + long data[5]; + + data[4] = True; + + XChangeProperty(dpy, ROOT, ATOM("_WMFS_STATUSTEXT"), ATOM("UTF8_STRING"), + 8, PropModeReplace, (unsigned char*)str, strlen(str)); + + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.message_type = ATOM("_WMFS_STATUSTEXT"); + ev.xclient.window = ROOT; + ev.xclient.format = 32; + + for(i = 0; i < 6; ++i) + ev.xclient.data.l[i] = data[i]; + + XSendEvent(dpy, ROOT, False, SubstructureRedirectMask | SubstructureNotifyMask, &ev); + XSync(dpy, False); + + return; +} + /** Signal handle function * \param signum Signal number */ @@ -286,16 +391,25 @@ main(int argc, char **argv) int i; struct sigaction sig; - while ((i = getopt(argc, argv, "hvi")) != -1) + while ((i = getopt(argc, argv, "hvic:s:")) != -1) { + if(i == 'c' || i == 's') + if(!(dpy = XOpenDisplay(NULL))) + { + fprintf(stderr, "WMFS: cannot open X server.\n"); + exit(EXIT_FAILURE); + } + switch (i) { case 'h': default: - printf("usage: %s [-ihv]\n" - " -h show this page\n" - " -i show informations\n" - " -v show WMFS version\n", argv[0]); + printf("usage: %s [-ihv] [-c ] [-s ]\n" + " -c Execute an uicb function to control WMFS\n" + " -s Set the bar(s) statustext\n" + " -h Show this page\n" + " -i Show informations\n" + " -v Show WMFS version\n", argv[0]); exit(EXIT_SUCCESS); break; case 'i': @@ -310,6 +424,16 @@ main(int argc, char **argv) " - On "WMFS_COMPILE_MACHINE" by "WMFS_COMPILE_BY".\n"); exit(EXIT_SUCCESS); break; + case 'c': + exec_uicb_function(argv[2], ((argv[3]) ? argv[3] : NULL)); + XCloseDisplay(dpy); + exit(EXIT_SUCCESS); + break; + case 's': + set_statustext(optarg); + XCloseDisplay(dpy); + exit(EXIT_SUCCESS); + break; } } diff --git a/src/wmfs.h b/src/wmfs.h index 9d7cf48..9daa018 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -297,6 +297,9 @@ int errorhandlerdummy(Display *d, XErrorEvent *event); void quit(void); void mainloop(void); void scan(void); +Bool check_wmfs_running(void); +void exec_uicb_function(char *func, char *cmd); +void set_statustext(char *str); void handle_signal(int signum); void uicb_quit(uicb_t); void uicb_reload(uicb_t);