diff --git a/i3lock.c b/i3lock.c index d5918631..130452de 100644 --- a/i3lock.c +++ b/i3lock.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,7 @@ typedef void (*ev_callback_t)(EV_P_ ev_timer *w, int revents); static void input_done(void); +static void update_arguments(int argc, char *argv[]); char color[9] = "a3a3a3ff"; @@ -267,6 +269,12 @@ pthread_t draw_thread; // allow you to disable. handy if you use bar with lots of crap. bool redraw_thread = false; +// for the api thread +pthread_t api_thread; +// this enables api access to update i3lock +bool api_enabled = false; +char *api_fifo_path = "/tmp/i3lock-api"; + // experimental bar stuff #define BAR_VERT 0 #define BAR_FLAT 1 @@ -643,6 +651,50 @@ static void redraw_timeout(EV_P_ ev_timer *w, int revents) { STOP_TIMER(w); } +static void *listen_api() { + mkfifo(api_fifo_path, S_IRWXU); + + FILE *fifo; + char c; + int i; + int times = 0; + char *text = (char *) malloc(50); + wordexp_t data; + + while(1) { + i = 0; + fifo = fopen(api_fifo_path, "rb"); + while ((c = fgetc(fifo)) != EOF) { + if (sizeof(text) <= i) { + text = (char *) realloc(text, i * 2); + } + if (c == '\n') { + text[i] = ' '; + } else { + text[i] = c; + } + i++; + } + fclose(fifo); + + char copy[] = "command "; + strcat(copy, text); + text = copy; + + wordfree(&data); + wordexp(text, &data, 0); + DEBUG("API message received - %d\n", times); + times++; + + update_arguments(data.we_wordc, data.we_wordv); + init_colors_once(); + + text = (char *) malloc(50); + redraw_screen(); + } + return NULL; +} + static bool skip_without_validation(void) { if (input_position != 0) return false; @@ -1437,19 +1489,10 @@ static void load_slideshow_images(const char *path, char *image_raw_format) { closedir(d); } -int main(int argc, char *argv[]) { - struct passwd *pw; - char *username; - char *image_path = NULL; - char *image_raw_format = NULL; -#ifndef __OpenBSD__ - int ret; - struct pam_conv conv = {conv_callback, NULL}; -#endif - int curs_choice = CURS_NONE; - int o; - int longoptind = 0; - struct option longopts[] = { +int curs_choice = CURS_NONE; + +static void update_arguments(int argc, char *argv[]) { + static struct option longopts[] = { {"version", no_argument, NULL, 'v'}, {"nofork", no_argument, NULL, 'n'}, {"beep", no_argument, NULL, 'b'}, @@ -1592,6 +1635,7 @@ int main(int argc, char *argv[]) { {"refresh-rate", required_argument, NULL, 901}, {"composite", no_argument, NULL, 902}, {"no-verify", no_argument, NULL, 905}, + {"enable-api", no_argument, NULL, 906}, // slideshow options {"slideshow-interval", required_argument, NULL, 903}, @@ -1599,16 +1643,15 @@ int main(int argc, char *argv[]) { {NULL, no_argument, NULL, 0}}; - if ((pw = getpwuid(getuid())) == NULL) - err(EXIT_FAILURE, "getpwuid() failed"); - if ((username = pw->pw_name) == NULL) - errx(EXIT_FAILURE, "pw->pw_name is NULL."); - if (getenv("WAYLAND_DISPLAY") != NULL) - errx(EXIT_FAILURE, "i3lock is a program for X11 and does not work on Wayland. Try https://github.com/swaywm/swaylock instead"); - + int o; + int longoptind = 0; + int opt = 0; char *optstring = "hvnbdc:p:ui:tCFLMeI:frsS:kB:m"; + + char *image_path; + char *image_raw_format; + char *arg = NULL; - int opt = 0; char padded[9] = "ffffffff"; \ #define parse_color(acolor)\ @@ -1631,7 +1674,10 @@ int main(int argc, char *argv[]) { awidth = 0;\ } + optind = 0; + while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) { + DEBUG("OPTLONG: %d - %s\n", o, optarg); switch (o) { case 'v': errx(EXIT_SUCCESS, "version " I3LOCK_VERSION " © 2010 Michael Stapelberg, © 2015 Cassandra Fox, © 2021 Raymond Li"); @@ -2232,6 +2278,9 @@ int main(int argc, char *argv[]) { case 905: no_verify = true; break; + case 906: + api_enabled = true; + break; case 998: image_raw_format = strdup(optarg); break; @@ -2244,6 +2293,26 @@ int main(int argc, char *argv[]) { "Please see the manpage for a full list of arguments."); } } +} + +int main(int argc, char *argv[]) { + struct passwd *pw; + char *username; + char *image_path = NULL; + char *image_raw_format = NULL; +#ifndef __OpenBSD__ + int ret; + struct pam_conv conv = {conv_callback, NULL}; +#endif + + if ((pw = getpwuid(getuid())) == NULL) + err(EXIT_FAILURE, "getpwuid() failed"); + if ((username = pw->pw_name) == NULL) + errx(EXIT_FAILURE, "pw->pw_name is NULL."); + if (getenv("WAYLAND_DISPLAY") != NULL) + errx(EXIT_FAILURE, "i3lock is a program for X11 and does not work on Wayland. Try https://github.com/swaywm/swaylock instead"); + + update_arguments(argc, argv); /* We need (relatively) random numbers for highlighting a random part of * the unlock indicator upon keypresses. */ @@ -2475,6 +2544,11 @@ int main(int argc, char *argv[]) { start_time_redraw_tick(main_loop); } } + + if (api_enabled) { + (void) pthread_create(&api_thread, NULL, listen_api, NULL); + } + ev_loop(main_loop, 0); #ifndef __OpenBSD__