X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=i3bar%2Fsrc%2Fmain.c;h=910e952482f0d788b46747ac0b9bab396242f7c5;hb=607e97e65190d1997048b510d72d30ebff1ca129;hp=d3107bfb071b5c47f198d3acf63a1d6ece4d8195;hpb=8d09ed7bf53ebf39c8139146465c520e2edc0837;p=i3%2Fi3 diff --git a/i3bar/src/main.c b/i3bar/src/main.c index d3107bfb..910e9524 100644 --- a/i3bar/src/main.c +++ b/i3bar/src/main.c @@ -1,11 +1,12 @@ /* - * i3bar - an xcb-based status- and ws-bar for i3 - * - * © 2010-2011 Axel Wagner and contributors + * vim:ts=4:sw=4:expandtab * - * See file LICNSE for license information + * i3bar - an xcb-based status- and ws-bar for i3 + * © 2010 Axel Wagner and contributors (see also: LICENSE) * */ +#include "common.h" + #include #include #include @@ -16,7 +17,28 @@ #include #include -#include "common.h" +/* + * Having verboselog(), errorlog() and debuglog() is necessary when using libi3. + * + */ +void verboselog(char *fmt, ...) { + va_list args; + + va_start(args, fmt); + vfprintf(stdout, fmt, args); + va_end(args); +} + +void errorlog(char *fmt, ...) { + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); +} + +void debuglog(char *fmt, ...) { +} /* * Glob path, i.e. expand ~ @@ -28,75 +50,28 @@ char *expand_path(char *path) { ELOG("glob() failed\n"); exit(EXIT_FAILURE); } - char *result = strdup(globbuf.gl_pathc > 0 ? globbuf.gl_pathv[0] : path); - if (result == NULL) { - ELOG("malloc() failed: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } + char *result = sstrdup(globbuf.gl_pathc > 0 ? globbuf.gl_pathv[0] : path); globfree(&globbuf); return result; } -static void read_color(char **color) { - int len = strlen(optarg); - if (len == 6 || (len == 7 && optarg[0] == '#')) { - int offset = len - 6; - int good = 1, i; - for (i = offset; good && i < 6 + offset; ++i) { - char c = optarg[i]; - if (!(c >= 'a' && c <= 'f') - && !(c >= 'A' && c <= 'F') - && !(c >= '0' && c <= '9')) { - good = 0; - break; - } - } - if (good) { - *color = strdup(optarg + offset); - return; - } - } - - fprintf(stderr, "Bad color value \"%s\"\n", optarg); - exit(EXIT_FAILURE); -} - -static void free_colors(struct xcb_color_strings_t *colors) { -#define FREE_COLOR(x) \ - do { \ - if (colors->x) \ - free(colors->x); \ - } while (0) - FREE_COLOR(bar_fg); - FREE_COLOR(bar_bg); - FREE_COLOR(active_ws_fg); - FREE_COLOR(active_ws_bg); - FREE_COLOR(inactive_ws_fg); - FREE_COLOR(inactive_ws_bg); - FREE_COLOR(urgent_ws_fg); - FREE_COLOR(urgent_ws_bg); - FREE_COLOR(focus_ws_fg); - FREE_COLOR(focus_ws_bg); -#undef FREE_COLOR -} - void print_usage(char *elf_name) { - printf("Usage: %s [-s sock_path] [-c command] [-m|-d[pos]] [-f font] [-V] [-h]\n", elf_name); - printf("-s \tConnect to i3 via \n"); - printf("-c \tExecute to get stdin\n"); - printf("-m\t\tHide the bars, when mod4 is not pressed.\n"); - printf("-d[]\tEnable dockmode. is \"top\" or \"bottom\". Default is bottom\n"); - printf("\t\tIf -c is specified, the childprocess is sent a SIGSTOP on hiding,\n"); - printf("\t\tand a SIGCONT on unhiding of the bars\n"); - printf("-f \tUse X-Core-Font for display\n"); - printf("-w\t\tDisable workspace-buttons\n"); - printf("-V\t\tBe (very) verbose with the debug-output\n"); - printf("-h\t\tDisplay this help-message and exit\n"); + printf("Usage: %s -b bar_id [-s sock_path] [-h] [-v]\n", elf_name); + printf("\n"); + printf("-b, --bar_id \tBar ID for which to get the configuration\n"); + printf("-s, --socket \tConnect to i3 via \n"); + printf("-h, --help Display this help message and exit\n"); + printf("-v, --version Display version number and exit\n"); + printf("\n"); + printf(" PLEASE NOTE that i3bar will be automatically started by i3\n" + " as soon as there is a 'bar' configuration block in your\n" + " config file. You should never need to start it manually.\n"); + printf("\n"); } /* * We watch various signals, that are there to make our application stop. - * If we get one of those, we ev_unloop() and invoke the cleanup-routines + * If we get one of those, we ev_unloop() and invoke the cleanup routines * in main() with that * */ @@ -118,107 +93,32 @@ int main(int argc, char **argv) { int opt; int option_index = 0; char *socket_path = getenv("I3SOCK"); - char *command = NULL; - char *fontname = NULL; + if (socket_path != NULL) { + socket_path = sstrdup(socket_path); + } char *i3_default_sock_path = "/tmp/i3-ipc.sock"; - struct xcb_color_strings_t colors = { NULL, }; - /* Definition of the standard-config */ - config.hide_on_modifier = 0; - config.dockpos = DOCKPOS_NONE; - config.disable_ws = 0; + /* Initialize the standard config to use 0 as default */ + memset(&config, '\0', sizeof(config_t)); static struct option long_opt[] = { - { "socket", required_argument, 0, 's' }, - { "command", required_argument, 0, 'c' }, - { "hide", no_argument, 0, 'm' }, - { "dock", optional_argument, 0, 'd' }, - { "font", required_argument, 0, 'f' }, - { "nows", no_argument, 0, 'w' }, - { "help", no_argument, 0, 'h' }, - { "version", no_argument, 0, 'v' }, - { "verbose", no_argument, 0, 'V' }, - { "color-bar-fg", required_argument, 0, 'A' }, - { "color-bar-bg", required_argument, 0, 'B' }, - { "color-active-ws-fg", required_argument, 0, 'C' }, - { "color-active-ws-bg", required_argument, 0, 'D' }, - { "color-inactive-ws-fg", required_argument, 0, 'E' }, - { "color-inactive-ws-bg", required_argument, 0, 'F' }, - { "color-urgent-ws-bg", required_argument, 0, 'G' }, - { "color-urgent-ws-fg", required_argument, 0, 'H' }, - { "color-focus-ws-bg", required_argument, 0, 'I' }, - { "color-focus-ws-fg", required_argument, 0, 'J' }, - { NULL, 0, 0, 0} - }; + {"socket", required_argument, 0, 's'}, + {"bar_id", required_argument, 0, 'b'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'v'}, + {NULL, 0, 0, 0}}; - while ((opt = getopt_long(argc, argv, "s:c:d::mf:whvVA:B:C:D:E:F:G:H:I:J:", long_opt, &option_index)) != -1) { + while ((opt = getopt_long(argc, argv, "b:s:hv", long_opt, &option_index)) != -1) { switch (opt) { case 's': socket_path = expand_path(optarg); break; - case 'c': - command = strdup(optarg); - break; - case 'm': - config.hide_on_modifier = 1; - break; - case 'd': - config.hide_on_modifier = 0; - if (optarg == NULL) { - config.dockpos = DOCKPOS_BOT; - break; - } - if (!strcmp(optarg, "top")) { - config.dockpos = DOCKPOS_TOP; - } else if (!strcmp(optarg, "bottom")) { - config.dockpos = DOCKPOS_BOT; - } else { - print_usage(argv[0]); - exit(EXIT_FAILURE); - } - break; - case 'f': - fontname = strdup(optarg); - break; - case 'w': - config.disable_ws = 1; - break; case 'v': - printf("i3bar version " I3BAR_VERSION " © 2010-2011 Axel Wagner and contributors\n"); + printf("i3bar version " I3_VERSION " © 2010 Axel Wagner and contributors\n"); exit(EXIT_SUCCESS); break; - case 'V': - config.verbose = 1; - break; - case 'A': - read_color(&colors.bar_fg); - break; - case 'B': - read_color(&colors.bar_bg); - break; - case 'C': - read_color(&colors.active_ws_fg); - break; - case 'D': - read_color(&colors.active_ws_bg); - break; - case 'E': - read_color(&colors.inactive_ws_fg); - break; - case 'F': - read_color(&colors.inactive_ws_bg); - break; - case 'G': - read_color(&colors.urgent_ws_bg); - break; - case 'H': - read_color(&colors.urgent_ws_fg); - break; - case 'I': - read_color(&colors.focus_ws_bg); - break; - case 'J': - read_color(&colors.focus_ws_fg); + case 'b': + config.bar_id = sstrdup(optarg); break; default: print_usage(argv[0]); @@ -227,68 +127,43 @@ int main(int argc, char **argv) { } } - if (fontname == NULL) { - /* This is a very restrictive default. More sensefull would be something like - * "-misc-*-*-*-*--*-*-*-*-*-*-*-*". But since that produces very ugly results - * on my machine, let's stick with this until we have a configfile */ - fontname = "-misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso10646-1"; - } - - if (config.dockpos != DOCKPOS_NONE) { - if (config.hide_on_modifier) { - ELOG("--dock and --hide are mutually exclusive!\n"); - exit(EXIT_FAILURE); - } - } else { - config.hide_on_modifier = 1; + if (!config.bar_id) { + /* TODO: maybe we want -f which will automatically ask i3 for the first + * configured bar (and error out if there are too many)? */ + ELOG("No bar_id passed. Please let i3 start i3bar or specify --bar_id\n"); + exit(EXIT_FAILURE); } main_loop = ev_default_loop(0); - init_colors(&colors); - char *atom_sock_path = init_xcb(fontname); + char *atom_sock_path = init_xcb_early(); if (socket_path == NULL) { socket_path = atom_sock_path; + } else { + free(atom_sock_path); } if (socket_path == NULL) { - ELOG("No Socket Path Specified, default to %s\n", i3_default_sock_path); + ELOG("No socket path specified, default to %s\n", i3_default_sock_path); socket_path = expand_path(i3_default_sock_path); } - free_colors(&colors); + init_dpi(); init_outputs(); - init_connection(socket_path); - - /* We subscribe to the i3-events we need */ - subscribe_events(); - - /* We initiate the main-function by requesting infos about the outputs and - * workspaces. Everything else (creating the bars, showing the right workspace- - * buttons and more) is taken care of by the event-driveniness of the code */ - i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL); - if (!config.disable_ws) { - i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL); + if (init_connection(socket_path)) { + /* Request the bar configuration. When it arrives, we fill the config array. */ + i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG, config.bar_id); } + free(socket_path); - /* The name of this function is actually misleading. Even if no -c is specified, - * this function initiates the watchers to listen on stdin and react accordingly */ - start_child(command); - FREE(command); - - /* We listen to SIGTERM/QUIT/INT and try to exit cleanly, by stopping the main-loop. + /* We listen to SIGTERM/QUIT/INT and try to exit cleanly, by stopping the main loop. * We only need those watchers on the stack, so putting them on the stack saves us * some calls to free() */ - ev_signal *sig_term = malloc(sizeof(ev_signal)); - ev_signal *sig_int = malloc(sizeof(ev_signal)); - ev_signal *sig_hup = malloc(sizeof(ev_signal)); - - if (sig_term == NULL || sig_int == NULL || sig_hup == NULL) { - ELOG("malloc() failed: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } + ev_signal *sig_term = smalloc(sizeof(ev_signal)); + ev_signal *sig_int = smalloc(sizeof(ev_signal)); + ev_signal *sig_hup = smalloc(sizeof(ev_signal)); ev_signal_init(sig_term, &sig_cb, SIGTERM); ev_signal_init(sig_int, &sig_cb, SIGINT); @@ -299,13 +174,11 @@ int main(int argc, char **argv) { ev_signal_start(main_loop, sig_hup); /* From here on everything should run smooth for itself, just start listening for - * events. We stop simply stop the event-loop, when we are finished */ + * events. We stop simply stop the event loop, when we are finished */ ev_loop(main_loop, 0); kill_child(); - FREE(statusline_buffer); - clean_xcb(); ev_default_destroy();