diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-07-23 20:27:56 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2018-07-23 20:31:11 -0400 |
commit | f4b882475eee7a81c206c7825616cc4656b2f60b (patch) | |
tree | 38e6ebf81b235424f105dcbcbb194e5e9eac70c0 /swaylock | |
parent | Implement pid->workspace tracking (diff) | |
parent | Merge pull request #2342 from RyanDwyer/update-cursor (diff) | |
download | sway-f4b882475eee7a81c206c7825616cc4656b2f60b.tar.gz sway-f4b882475eee7a81c206c7825616cc4656b2f60b.tar.zst sway-f4b882475eee7a81c206c7825616cc4656b2f60b.zip |
Merge branch 'master' into pid-workspaces
Diffstat (limited to 'swaylock')
-rw-r--r-- | swaylock/main.c | 568 | ||||
-rw-r--r-- | swaylock/password.c | 25 | ||||
-rw-r--r-- | swaylock/render.c | 77 | ||||
-rw-r--r-- | swaylock/seat.c | 4 | ||||
-rw-r--r-- | swaylock/swaylock.1.scd | 92 |
5 files changed, 632 insertions, 134 deletions
diff --git a/swaylock/main.c b/swaylock/main.c index 591df7b4..668a8742 100644 --- a/swaylock/main.c +++ b/swaylock/main.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "pool-buffer.h" | 21 | #include "pool-buffer.h" |
22 | #include "cairo.h" | 22 | #include "cairo.h" |
23 | #include "log.h" | 23 | #include "log.h" |
24 | #include "readline.h" | ||
24 | #include "stringop.h" | 25 | #include "stringop.h" |
25 | #include "util.h" | 26 | #include "util.h" |
26 | #include "wlr-input-inhibitor-unstable-v1-client-protocol.h" | 27 | #include "wlr-input-inhibitor-unstable-v1-client-protocol.h" |
@@ -34,14 +35,16 @@ void sway_terminate(int exit_code) { | |||
34 | static void daemonize() { | 35 | static void daemonize() { |
35 | int fds[2]; | 36 | int fds[2]; |
36 | if (pipe(fds) != 0) { | 37 | if (pipe(fds) != 0) { |
37 | wlr_log(L_ERROR, "Failed to pipe"); | 38 | wlr_log(WLR_ERROR, "Failed to pipe"); |
38 | exit(1); | 39 | exit(1); |
39 | } | 40 | } |
40 | if (fork() == 0) { | 41 | if (fork() == 0) { |
42 | setsid(); | ||
41 | close(fds[0]); | 43 | close(fds[0]); |
42 | int devnull = open("/dev/null", O_RDWR); | 44 | int devnull = open("/dev/null", O_RDWR); |
43 | dup2(STDOUT_FILENO, devnull); | 45 | dup2(STDOUT_FILENO, devnull); |
44 | dup2(STDERR_FILENO, devnull); | 46 | dup2(STDERR_FILENO, devnull); |
47 | close(devnull); | ||
45 | uint8_t success = 0; | 48 | uint8_t success = 0; |
46 | if (chdir("/") != 0) { | 49 | if (chdir("/") != 0) { |
47 | write(fds[1], &success, 1); | 50 | write(fds[1], &success, 1); |
@@ -56,7 +59,7 @@ static void daemonize() { | |||
56 | close(fds[1]); | 59 | close(fds[1]); |
57 | uint8_t success; | 60 | uint8_t success; |
58 | if (read(fds[0], &success, 1) != 1 || !success) { | 61 | if (read(fds[0], &success, 1) != 1 || !success) { |
59 | wlr_log(L_ERROR, "Failed to daemonize"); | 62 | wlr_log(WLR_ERROR, "Failed to daemonize"); |
60 | exit(1); | 63 | exit(1); |
61 | } | 64 | } |
62 | close(fds[0]); | 65 | close(fds[0]); |
@@ -83,6 +86,13 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener; | |||
83 | static cairo_surface_t *select_image(struct swaylock_state *state, | 86 | static cairo_surface_t *select_image(struct swaylock_state *state, |
84 | struct swaylock_surface *surface); | 87 | struct swaylock_surface *surface); |
85 | 88 | ||
89 | static bool surface_is_opaque(struct swaylock_surface *surface) { | ||
90 | if (surface->image) { | ||
91 | return cairo_surface_get_content(surface->image) == CAIRO_CONTENT_COLOR; | ||
92 | } | ||
93 | return (surface->state->args.colors.background & 0xff) == 0xff; | ||
94 | } | ||
95 | |||
86 | static void create_layer_surface(struct swaylock_surface *surface) { | 96 | static void create_layer_surface(struct swaylock_surface *surface) { |
87 | struct swaylock_state *state = surface->state; | 97 | struct swaylock_state *state = surface->state; |
88 | 98 | ||
@@ -107,6 +117,17 @@ static void create_layer_surface(struct swaylock_surface *surface) { | |||
107 | surface->layer_surface, true); | 117 | surface->layer_surface, true); |
108 | zwlr_layer_surface_v1_add_listener(surface->layer_surface, | 118 | zwlr_layer_surface_v1_add_listener(surface->layer_surface, |
109 | &layer_surface_listener, surface); | 119 | &layer_surface_listener, surface); |
120 | |||
121 | if (surface_is_opaque(surface) && | ||
122 | surface->state->args.mode != BACKGROUND_MODE_CENTER && | ||
123 | surface->state->args.mode != BACKGROUND_MODE_FIT) { | ||
124 | struct wl_region *region = | ||
125 | wl_compositor_create_region(surface->state->compositor); | ||
126 | wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX); | ||
127 | wl_surface_set_opaque_region(surface->surface, region); | ||
128 | wl_region_destroy(region); | ||
129 | } | ||
130 | |||
110 | wl_surface_commit(surface->surface); | 131 | wl_surface_commit(surface->surface); |
111 | } | 132 | } |
112 | 133 | ||
@@ -218,7 +239,7 @@ static void handle_xdg_output_logical_position(void *data, | |||
218 | 239 | ||
219 | static void handle_xdg_output_name(void *data, struct zxdg_output_v1 *output, | 240 | static void handle_xdg_output_name(void *data, struct zxdg_output_v1 *output, |
220 | const char *name) { | 241 | const char *name) { |
221 | wlr_log(L_DEBUG, "output name is %s", name); | 242 | wlr_log(WLR_DEBUG, "output name is %s", name); |
222 | struct swaylock_surface *surface = data; | 243 | struct swaylock_surface *surface = data; |
223 | surface->xdg_output = output; | 244 | surface->xdg_output = output; |
224 | surface->output_name = strdup(name); | 245 | surface->output_name = strdup(name); |
@@ -324,22 +345,25 @@ static void load_image(char *arg, struct swaylock_state *state) { | |||
324 | image->path = strdup(arg); | 345 | image->path = strdup(arg); |
325 | } | 346 | } |
326 | 347 | ||
327 | bool exists = false; | 348 | struct swaylock_image *iter_image, *temp; |
328 | struct swaylock_image *iter_image; | 349 | wl_list_for_each_safe(iter_image, temp, &state->images, link) { |
329 | wl_list_for_each(iter_image, &state->images, link) { | ||
330 | if (lenient_strcmp(iter_image->output_name, image->output_name) == 0) { | 350 | if (lenient_strcmp(iter_image->output_name, image->output_name) == 0) { |
331 | exists = true; | 351 | if (image->output_name) { |
352 | wlr_log(WLR_DEBUG, | ||
353 | "Replacing image defined for output %s with %s", | ||
354 | image->output_name, image->path); | ||
355 | } else { | ||
356 | wlr_log(WLR_DEBUG, "Replacing default image with %s", | ||
357 | image->path); | ||
358 | } | ||
359 | wl_list_remove(&iter_image->link); | ||
360 | free(iter_image->cairo_surface); | ||
361 | free(iter_image->output_name); | ||
362 | free(iter_image->path); | ||
363 | free(iter_image); | ||
332 | break; | 364 | break; |
333 | } | 365 | } |
334 | } | 366 | } |
335 | if (exists) { | ||
336 | if (image->output_name) { | ||
337 | wlr_log(L_ERROR, "Multiple images defined for output %s", | ||
338 | image->output_name); | ||
339 | } else { | ||
340 | wlr_log(L_ERROR, "Multiple default images defined"); | ||
341 | } | ||
342 | } | ||
343 | 367 | ||
344 | // Bash doesn't replace the ~ with $HOME if the output name is supplied | 368 | // Bash doesn't replace the ~ with $HOME if the output name is supplied |
345 | wordexp_t p; | 369 | wordexp_t p; |
@@ -357,71 +381,252 @@ static void load_image(char *arg, struct swaylock_state *state) { | |||
357 | } | 381 | } |
358 | wl_list_insert(&state->images, &image->link); | 382 | wl_list_insert(&state->images, &image->link); |
359 | state->args.mode = BACKGROUND_MODE_FILL; | 383 | state->args.mode = BACKGROUND_MODE_FILL; |
360 | wlr_log(L_DEBUG, "Loaded image %s for output %s", | 384 | wlr_log(WLR_DEBUG, "Loaded image %s for output %s", |
361 | image->path, image->output_name ? image->output_name : "*"); | 385 | image->path, image->output_name ? image->output_name : "*"); |
362 | } | 386 | } |
363 | 387 | ||
364 | static struct swaylock_state state; | 388 | static void set_default_colors(struct swaylock_colors *colors) { |
389 | colors->background = 0xFFFFFFFF; | ||
390 | colors->bs_highlight = 0xDB3300FF; | ||
391 | colors->key_highlight = 0x33DB00FF; | ||
392 | colors->separator = 0x000000FF; | ||
393 | colors->inside = (struct swaylock_colorset){ | ||
394 | .input = 0x000000C0, | ||
395 | .cleared = 0xE5A445C0, | ||
396 | .verifying = 0x0072FFC0, | ||
397 | .wrong = 0xFA0000C0, | ||
398 | }; | ||
399 | colors->line = (struct swaylock_colorset){ | ||
400 | .input = 0x000000FF, | ||
401 | .cleared = 0x000000FF, | ||
402 | .verifying = 0x000000FF, | ||
403 | .wrong = 0x000000FF, | ||
404 | }; | ||
405 | colors->ring = (struct swaylock_colorset){ | ||
406 | .input = 0x337D00FF, | ||
407 | .cleared = 0xE5A445FF, | ||
408 | .verifying = 0x3300FFFF, | ||
409 | .wrong = 0x7D3300FF, | ||
410 | }; | ||
411 | colors->text = (struct swaylock_colorset){ | ||
412 | .input = 0xE5A445FF, | ||
413 | .cleared = 0x000000FF, | ||
414 | .verifying = 0x000000FF, | ||
415 | .wrong = 0x000000FF, | ||
416 | }; | ||
417 | } | ||
418 | |||
419 | enum line_mode { | ||
420 | LM_LINE, | ||
421 | LM_INSIDE, | ||
422 | LM_RING, | ||
423 | }; | ||
424 | |||
425 | static int parse_options(int argc, char **argv, struct swaylock_state *state, | ||
426 | enum line_mode *line_mode, char **config_path) { | ||
427 | enum long_option_codes { | ||
428 | LO_BS_HL_COLOR = 256, | ||
429 | LO_FONT, | ||
430 | LO_IND_RADIUS, | ||
431 | LO_IND_THICKNESS, | ||
432 | LO_INSIDE_COLOR, | ||
433 | LO_INSIDE_CLEAR_COLOR, | ||
434 | LO_INSIDE_VER_COLOR, | ||
435 | LO_INSIDE_WRONG_COLOR, | ||
436 | LO_KEY_HL_COLOR, | ||
437 | LO_LINE_COLOR, | ||
438 | LO_LINE_CLEAR_COLOR, | ||
439 | LO_LINE_VER_COLOR, | ||
440 | LO_LINE_WRONG_COLOR, | ||
441 | LO_RING_COLOR, | ||
442 | LO_RING_CLEAR_COLOR, | ||
443 | LO_RING_VER_COLOR, | ||
444 | LO_RING_WRONG_COLOR, | ||
445 | LO_SEP_COLOR, | ||
446 | LO_TEXT_COLOR, | ||
447 | LO_TEXT_CLEAR_COLOR, | ||
448 | LO_TEXT_VER_COLOR, | ||
449 | LO_TEXT_WRONG_COLOR, | ||
450 | }; | ||
365 | 451 | ||
366 | int main(int argc, char **argv) { | ||
367 | static struct option long_options[] = { | 452 | static struct option long_options[] = { |
368 | {"help", no_argument, NULL, 'h'}, | 453 | {"config", required_argument, NULL, 'C'}, |
369 | {"color", required_argument, NULL, 'c'}, | 454 | {"color", required_argument, NULL, 'c'}, |
455 | {"ignore-empty-password", no_argument, NULL, 'e'}, | ||
456 | {"daemonize", no_argument, NULL, 'f'}, | ||
457 | {"help", no_argument, NULL, 'h'}, | ||
370 | {"image", required_argument, NULL, 'i'}, | 458 | {"image", required_argument, NULL, 'i'}, |
459 | {"line-uses-inside", no_argument, NULL, 'n'}, | ||
460 | {"socket", required_argument, NULL, 'p'}, | ||
461 | {"line-uses-ring", no_argument, NULL, 'r'}, | ||
371 | {"scaling", required_argument, NULL, 's'}, | 462 | {"scaling", required_argument, NULL, 's'}, |
372 | {"tiling", no_argument, NULL, 't'}, | 463 | {"tiling", no_argument, NULL, 't'}, |
373 | {"version", no_argument, NULL, 'v'}, | ||
374 | {"socket", required_argument, NULL, 'p'}, | ||
375 | {"no-unlock-indicator", no_argument, NULL, 'u'}, | 464 | {"no-unlock-indicator", no_argument, NULL, 'u'}, |
376 | {"daemonize", no_argument, NULL, 'f'}, | 465 | {"version", no_argument, NULL, 'v'}, |
466 | {"bs-hl-color", required_argument, NULL, LO_BS_HL_COLOR}, | ||
467 | {"font", required_argument, NULL, LO_FONT}, | ||
468 | {"indicator-radius", required_argument, NULL, LO_IND_RADIUS}, | ||
469 | {"indicator-thickness", required_argument, NULL, LO_IND_THICKNESS}, | ||
470 | {"inside-color", required_argument, NULL, LO_INSIDE_COLOR}, | ||
471 | {"inside-clear-color", required_argument, NULL, LO_INSIDE_CLEAR_COLOR}, | ||
472 | {"inside-ver-color", required_argument, NULL, LO_INSIDE_VER_COLOR}, | ||
473 | {"inside-wrong-color", required_argument, NULL, LO_INSIDE_WRONG_COLOR}, | ||
474 | {"key-hl-color", required_argument, NULL, LO_KEY_HL_COLOR}, | ||
475 | {"line-color", required_argument, NULL, LO_LINE_COLOR}, | ||
476 | {"line-clear-color", required_argument, NULL, LO_LINE_CLEAR_COLOR}, | ||
477 | {"line-ver-color", required_argument, NULL, LO_LINE_VER_COLOR}, | ||
478 | {"line-wrong-color", required_argument, NULL, LO_LINE_WRONG_COLOR}, | ||
479 | {"ring-color", required_argument, NULL, LO_RING_COLOR}, | ||
480 | {"ring-clear-color", required_argument, NULL, LO_RING_CLEAR_COLOR}, | ||
481 | {"ring-ver-color", required_argument, NULL, LO_RING_VER_COLOR}, | ||
482 | {"ring-wrong-color", required_argument, NULL, LO_RING_WRONG_COLOR}, | ||
483 | {"separator-color", required_argument, NULL, LO_SEP_COLOR}, | ||
484 | {"text-color", required_argument, NULL, LO_TEXT_COLOR}, | ||
485 | {"text-clear-color", required_argument, NULL, LO_TEXT_CLEAR_COLOR}, | ||
486 | {"text-ver-color", required_argument, NULL, LO_TEXT_VER_COLOR}, | ||
487 | {"text-wrong-color", required_argument, NULL, LO_TEXT_WRONG_COLOR}, | ||
377 | {0, 0, 0, 0} | 488 | {0, 0, 0, 0} |
378 | }; | 489 | }; |
379 | 490 | ||
380 | const char usage[] = | 491 | const char usage[] = |
381 | "Usage: swaylock [options...]\n" | 492 | "Usage: swaylock [options...]\n" |
382 | "\n" | 493 | "\n" |
383 | " -h, --help Show help message and quit.\n" | 494 | " -C, --config <config_file> " |
384 | " -c, --color <rrggbb[aa]> Turn the screen into the given color instead of white.\n" | 495 | "Path to the config file.\n" |
385 | " -s, --scaling Scaling mode: stretch, fill, fit, center, tile.\n" | 496 | " -c, --color <color> " |
386 | " -t, --tiling Same as --scaling=tile.\n" | 497 | "Turn the screen into the given color instead of white.\n" |
387 | " -v, --version Show the version number and quit.\n" | 498 | " -e, --ignore-empty-password " |
388 | " -i, --image [<output>:]<path> Display the given image.\n" | 499 | "When an empty password is provided, do not validate it.\n" |
389 | " -u, --no-unlock-indicator Disable the unlock indicator.\n" | 500 | " -f, --daemonize " |
390 | " -f, --daemonize Detach from the controlling terminal.\n"; | 501 | "Detach from the controlling terminal after locking.\n" |
391 | 502 | " -h, --help " | |
392 | state.args = (struct swaylock_args){ | 503 | "Show help message and quit.\n" |
393 | .mode = BACKGROUND_MODE_SOLID_COLOR, | 504 | " -i, --image [<output>:]<path> " |
394 | .color = 0xFFFFFFFF, | 505 | "Display the given image.\n" |
395 | .show_indicator = true, | 506 | " -s, --scaling <mode> " |
396 | }; | 507 | "Scaling mode: stretch, fill, fit, center, tile.\n" |
397 | wl_list_init(&state.images); | 508 | " -t, --tiling " |
398 | 509 | "Same as --scaling=tile.\n" | |
399 | wlr_log_init(L_DEBUG, NULL); | 510 | " -u, --no-unlock-indicator " |
511 | "Disable the unlock indicator.\n" | ||
512 | " -v, --version " | ||
513 | "Show the version number and quit.\n" | ||
514 | " --bs-hl-color <color> " | ||
515 | "Sets the color of backspace highlight segments.\n" | ||
516 | " --font <font> " | ||
517 | "Sets the font of the text.\n" | ||
518 | " --indicator-radius <radius> " | ||
519 | "Sets the indicator radius.\n" | ||
520 | " --indicator-thickness <thick> " | ||
521 | "Sets the indicator thickness.\n" | ||
522 | " --inside-color <color> " | ||
523 | "Sets the color of the inside of the indicator.\n" | ||
524 | " --inside-clear-color <color> " | ||
525 | "Sets the color of the inside of the indicator when cleared.\n" | ||
526 | " --inside-ver-color <color> " | ||
527 | "Sets the color of the inside of the indicator when verifying.\n" | ||
528 | " --inside-wrong-color <color> " | ||
529 | "Sets the color of the inside of the indicator when invalid.\n" | ||
530 | " --key-hl-color <color> " | ||
531 | "Sets the color of the key press highlight segments.\n" | ||
532 | " --line-color <color> " | ||
533 | "Sets the color of the line between the inside and ring.\n" | ||
534 | " --line-clear-color <color> " | ||
535 | "Sets the color of the line between the inside and ring when " | ||
536 | "cleared.\n" | ||
537 | " --line-ver-color <color> " | ||
538 | "Sets the color of the line between the inside and ring when " | ||
539 | "verifying.\n" | ||
540 | " --line-wrong-color <color> " | ||
541 | "Sets the color of the line between the inside and ring when " | ||
542 | "invalid.\n" | ||
543 | " -n, --line-uses-inside " | ||
544 | "Use the inside color for the line between the inside and ring.\n" | ||
545 | " -r, --line-uses-ring " | ||
546 | "Use the ring color for the line between the inside and ring.\n" | ||
547 | " --ring-color <color> " | ||
548 | "Sets the color of the ring of the indicator.\n" | ||
549 | " --ring-clear-color <color> " | ||
550 | "Sets the color of the ring of the indicator when cleared.\n" | ||
551 | " --ring-ver-color <color> " | ||
552 | "Sets the color of the ring of the indicator when verifying.\n" | ||
553 | " --ring-wrong-color <color> " | ||
554 | "Sets the color of the ring of the indicator when invalid.\n" | ||
555 | " --separator-color <color> " | ||
556 | "Sets the color of the lines that separate highlight segments.\n" | ||
557 | " --text-color <color> " | ||
558 | "Sets the color of the text.\n" | ||
559 | " --text-clear-color <color> " | ||
560 | "Sets the color of the text when cleared.\n" | ||
561 | " --text-ver-color <color> " | ||
562 | "Sets the color of the text when verifying.\n" | ||
563 | " --text-wrong-color <color> " | ||
564 | "Sets the color of the text when invalid.\n" | ||
565 | "\n" | ||
566 | "All <color> options are of the form <rrggbb[aa]>.\n"; | ||
400 | 567 | ||
401 | int c; | 568 | int c; |
569 | optind = 1; | ||
402 | while (1) { | 570 | while (1) { |
403 | int option_index = 0; | 571 | int opt_idx = 0; |
404 | c = getopt_long(argc, argv, "hc:i:s:tvuf", long_options, &option_index); | 572 | c = getopt_long(argc, argv, "c:efhi:nrs:tuvC:", long_options, &opt_idx); |
405 | if (c == -1) { | 573 | if (c == -1) { |
406 | break; | 574 | break; |
407 | } | 575 | } |
408 | switch (c) { | 576 | switch (c) { |
409 | case 'c': { | 577 | case 'C': |
410 | state.args.color = parse_color(optarg); | 578 | if (config_path) { |
411 | state.args.mode = BACKGROUND_MODE_SOLID_COLOR; | 579 | *config_path = strdup(optarg); |
580 | } | ||
581 | break; | ||
582 | case 'c': | ||
583 | if (state) { | ||
584 | state->args.colors.background = parse_color(optarg); | ||
585 | state->args.mode = BACKGROUND_MODE_SOLID_COLOR; | ||
586 | } | ||
587 | break; | ||
588 | case 'e': | ||
589 | if (state) { | ||
590 | state->args.ignore_empty = true; | ||
591 | } | ||
592 | break; | ||
593 | case 'f': | ||
594 | if (state) { | ||
595 | state->args.daemonize = true; | ||
596 | } | ||
412 | break; | 597 | break; |
413 | } | ||
414 | case 'i': | 598 | case 'i': |
415 | load_image(optarg, &state); | 599 | if (state) { |
600 | load_image(optarg, state); | ||
601 | } | ||
602 | break; | ||
603 | case 'n': | ||
604 | if (line_mode) { | ||
605 | *line_mode = LM_INSIDE; | ||
606 | } | ||
607 | break; | ||
608 | case 'r': | ||
609 | if (line_mode) { | ||
610 | *line_mode = LM_RING; | ||
611 | } | ||
416 | break; | 612 | break; |
417 | case 's': | 613 | case 's': |
418 | state.args.mode = parse_background_mode(optarg); | 614 | if (state) { |
419 | if (state.args.mode == BACKGROUND_MODE_INVALID) { | 615 | state->args.mode = parse_background_mode(optarg); |
420 | return 1; | 616 | if (state->args.mode == BACKGROUND_MODE_INVALID) { |
617 | return 1; | ||
618 | } | ||
421 | } | 619 | } |
422 | break; | 620 | break; |
423 | case 't': | 621 | case 't': |
424 | state.args.mode = BACKGROUND_MODE_TILE; | 622 | if (state) { |
623 | state->args.mode = BACKGROUND_MODE_TILE; | ||
624 | } | ||
625 | break; | ||
626 | case 'u': | ||
627 | if (state) { | ||
628 | state->args.show_indicator = false; | ||
629 | } | ||
425 | break; | 630 | break; |
426 | case 'v': | 631 | case 'v': |
427 | #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE | 632 | #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE |
@@ -430,12 +635,117 @@ int main(int argc, char **argv) { | |||
430 | #else | 635 | #else |
431 | fprintf(stdout, "version unknown\n"); | 636 | fprintf(stdout, "version unknown\n"); |
432 | #endif | 637 | #endif |
433 | return 0; | 638 | return 1; |
434 | case 'u': | 639 | case LO_BS_HL_COLOR: |
435 | state.args.show_indicator = false; | 640 | if (state) { |
641 | state->args.colors.bs_highlight = parse_color(optarg); | ||
642 | } | ||
436 | break; | 643 | break; |
437 | case 'f': | 644 | case LO_FONT: |
438 | daemonize(); | 645 | if (state) { |
646 | free(state->args.font); | ||
647 | state->args.font = strdup(optarg); | ||
648 | } | ||
649 | break; | ||
650 | case LO_IND_RADIUS: | ||
651 | if (state) { | ||
652 | state->args.radius = strtol(optarg, NULL, 0); | ||
653 | } | ||
654 | break; | ||
655 | case LO_IND_THICKNESS: | ||
656 | if (state) { | ||
657 | state->args.thickness = strtol(optarg, NULL, 0); | ||
658 | } | ||
659 | break; | ||
660 | case LO_INSIDE_COLOR: | ||
661 | if (state) { | ||
662 | state->args.colors.inside.input = parse_color(optarg); | ||
663 | } | ||
664 | break; | ||
665 | case LO_INSIDE_CLEAR_COLOR: | ||
666 | if (state) { | ||
667 | state->args.colors.inside.cleared = parse_color(optarg); | ||
668 | } | ||
669 | break; | ||
670 | case LO_INSIDE_VER_COLOR: | ||
671 | if (state) { | ||
672 | state->args.colors.inside.verifying = parse_color(optarg); | ||
673 | } | ||
674 | break; | ||
675 | case LO_INSIDE_WRONG_COLOR: | ||
676 | if (state) { | ||
677 | state->args.colors.inside.wrong = parse_color(optarg); | ||
678 | } | ||
679 | break; | ||
680 | case LO_KEY_HL_COLOR: | ||
681 | if (state) { | ||
682 | state->args.colors.key_highlight = parse_color(optarg); | ||
683 | } | ||
684 | break; | ||
685 | case LO_LINE_COLOR: | ||
686 | if (state) { | ||
687 | state->args.colors.line.input = parse_color(optarg); | ||
688 | } | ||
689 | break; | ||
690 | case LO_LINE_CLEAR_COLOR: | ||
691 | if (state) { | ||
692 | state->args.colors.line.cleared = parse_color(optarg); | ||
693 | } | ||
694 | break; | ||
695 | case LO_LINE_VER_COLOR: | ||
696 | if (state) { | ||
697 | state->args.colors.line.verifying = parse_color(optarg); | ||
698 | } | ||
699 | break; | ||
700 | case LO_LINE_WRONG_COLOR: | ||
701 | if (state) { | ||
702 | state->args.colors.line.wrong = parse_color(optarg); | ||
703 | } | ||
704 | break; | ||
705 | case LO_RING_COLOR: | ||
706 | if (state) { | ||
707 | state->args.colors.ring.input = parse_color(optarg); | ||
708 | } | ||
709 | break; | ||
710 | case LO_RING_CLEAR_COLOR: | ||
711 | if (state) { | ||
712 | state->args.colors.ring.cleared = parse_color(optarg); | ||
713 | } | ||
714 | break; | ||
715 | case LO_RING_VER_COLOR: | ||
716 | if (state) { | ||
717 | state->args.colors.ring.verifying = parse_color(optarg); | ||
718 | } | ||
719 | break; | ||
720 | case LO_RING_WRONG_COLOR: | ||
721 | if (state) { | ||
722 | state->args.colors.ring.wrong = parse_color(optarg); | ||
723 | } | ||
724 | break; | ||
725 | case LO_SEP_COLOR: | ||
726 | if (state) { | ||
727 | state->args.colors.separator = parse_color(optarg); | ||
728 | } | ||
729 | break; | ||
730 | case LO_TEXT_COLOR: | ||
731 | if (state) { | ||
732 | state->args.colors.text.input = parse_color(optarg); | ||
733 | } | ||
734 | break; | ||
735 | case LO_TEXT_CLEAR_COLOR: | ||
736 | if (state) { | ||
737 | state->args.colors.text.cleared = parse_color(optarg); | ||
738 | } | ||
739 | break; | ||
740 | case LO_TEXT_VER_COLOR: | ||
741 | if (state) { | ||
742 | state->args.colors.text.verifying = parse_color(optarg); | ||
743 | } | ||
744 | break; | ||
745 | case LO_TEXT_WRONG_COLOR: | ||
746 | if (state) { | ||
747 | state->args.colors.text.wrong = parse_color(optarg); | ||
748 | } | ||
439 | break; | 749 | break; |
440 | default: | 750 | default: |
441 | fprintf(stderr, "%s", usage); | 751 | fprintf(stderr, "%s", usage); |
@@ -443,6 +753,141 @@ int main(int argc, char **argv) { | |||
443 | } | 753 | } |
444 | } | 754 | } |
445 | 755 | ||
756 | return 0; | ||
757 | } | ||
758 | |||
759 | static bool file_exists(const char *path) { | ||
760 | return path && access(path, R_OK) != -1; | ||
761 | } | ||
762 | |||
763 | static char *get_config_path(void) { | ||
764 | static const char *config_paths[] = { | ||
765 | "$HOME/.swaylock/config", | ||
766 | "$XDG_CONFIG_HOME/swaylock/config", | ||
767 | SYSCONFDIR "/swaylock/config", | ||
768 | }; | ||
769 | |||
770 | if (!getenv("XDG_CONFIG_HOME")) { | ||
771 | char *home = getenv("HOME"); | ||
772 | char *config_home = malloc(strlen(home) + strlen("/.config") + 1); | ||
773 | if (!config_home) { | ||
774 | wlr_log(WLR_ERROR, "Unable to allocate $HOME/.config"); | ||
775 | } else { | ||
776 | strcpy(config_home, home); | ||
777 | strcat(config_home, "/.config"); | ||
778 | setenv("XDG_CONFIG_HOME", config_home, 1); | ||
779 | wlr_log(WLR_DEBUG, "Set XDG_CONFIG_HOME to %s", config_home); | ||
780 | free(config_home); | ||
781 | } | ||
782 | } | ||
783 | |||
784 | wordexp_t p; | ||
785 | char *path; | ||
786 | for (size_t i = 0; i < sizeof(config_paths) / sizeof(char *); ++i) { | ||
787 | if (wordexp(config_paths[i], &p, 0) == 0) { | ||
788 | path = strdup(p.we_wordv[0]); | ||
789 | wordfree(&p); | ||
790 | if (file_exists(path)) { | ||
791 | return path; | ||
792 | } | ||
793 | free(path); | ||
794 | } | ||
795 | } | ||
796 | |||
797 | return NULL; | ||
798 | } | ||
799 | |||
800 | static int load_config(char *path, struct swaylock_state *state, | ||
801 | enum line_mode *line_mode) { | ||
802 | FILE *config = fopen(path, "r"); | ||
803 | if (!config) { | ||
804 | wlr_log(WLR_ERROR, "Failed to read config. Running without it."); | ||
805 | return 0; | ||
806 | } | ||
807 | char *line; | ||
808 | int line_number = 0; | ||
809 | while (!feof(config)) { | ||
810 | line = read_line(config); | ||
811 | if (!line) { | ||
812 | continue; | ||
813 | } | ||
814 | |||
815 | line_number++; | ||
816 | if (line[0] == '#') { | ||
817 | free(line); | ||
818 | continue; | ||
819 | } | ||
820 | if (strlen(line) == 0) { | ||
821 | free(line); | ||
822 | continue; | ||
823 | } | ||
824 | |||
825 | wlr_log(WLR_DEBUG, "Config Line #%d: %s", line_number, line); | ||
826 | char flag[strlen(line) + 3]; | ||
827 | sprintf(flag, "--%s", line); | ||
828 | char *argv[] = {"swaylock", flag}; | ||
829 | int result = parse_options(2, argv, state, line_mode, NULL); | ||
830 | if (result != 0) { | ||
831 | free(line); | ||
832 | fclose(config); | ||
833 | return result; | ||
834 | } | ||
835 | free(line); | ||
836 | } | ||
837 | fclose(config); | ||
838 | return 0; | ||
839 | } | ||
840 | |||
841 | static struct swaylock_state state; | ||
842 | |||
843 | int main(int argc, char **argv) { | ||
844 | enum line_mode line_mode = LM_LINE; | ||
845 | state.args = (struct swaylock_args){ | ||
846 | .mode = BACKGROUND_MODE_SOLID_COLOR, | ||
847 | .font = strdup("sans-serif"), | ||
848 | .radius = 50, | ||
849 | .thickness = 10, | ||
850 | .ignore_empty = false, | ||
851 | .show_indicator = true, | ||
852 | }; | ||
853 | wl_list_init(&state.images); | ||
854 | set_default_colors(&state.args.colors); | ||
855 | |||
856 | wlr_log_init(WLR_DEBUG, NULL); | ||
857 | |||
858 | char *config_path = NULL; | ||
859 | int result = parse_options(argc, argv, NULL, NULL, &config_path); | ||
860 | if (result != 0) { | ||
861 | free(config_path); | ||
862 | return result; | ||
863 | } | ||
864 | if (!config_path) { | ||
865 | config_path = get_config_path(); | ||
866 | } | ||
867 | |||
868 | if (config_path) { | ||
869 | wlr_log(WLR_DEBUG, "Found config at %s", config_path); | ||
870 | int config_status = load_config(config_path, &state, &line_mode); | ||
871 | free(config_path); | ||
872 | if (config_status != 0) { | ||
873 | return config_status; | ||
874 | } | ||
875 | } | ||
876 | |||
877 | if (argc > 1) { | ||
878 | wlr_log(WLR_DEBUG, "Parsing CLI Args"); | ||
879 | int result = parse_options(argc, argv, &state, &line_mode, NULL); | ||
880 | if (result != 0) { | ||
881 | return result; | ||
882 | } | ||
883 | } | ||
884 | |||
885 | if (line_mode == LM_INSIDE) { | ||
886 | state.args.colors.line = state.args.colors.inside; | ||
887 | } else if (line_mode == LM_RING) { | ||
888 | state.args.colors.line = state.args.colors.ring; | ||
889 | } | ||
890 | |||
446 | #ifdef __linux__ | 891 | #ifdef __linux__ |
447 | // Most non-linux platforms require root to mlock() | 892 | // Most non-linux platforms require root to mlock() |
448 | if (mlock(state.password.buffer, sizeof(state.password.buffer)) != 0) { | 893 | if (mlock(state.password.buffer, sizeof(state.password.buffer)) != 0) { |
@@ -460,13 +905,13 @@ int main(int argc, char **argv) { | |||
460 | wl_display_roundtrip(state.display); | 905 | wl_display_roundtrip(state.display); |
461 | assert(state.compositor && state.layer_shell && state.shm); | 906 | assert(state.compositor && state.layer_shell && state.shm); |
462 | if (!state.input_inhibit_manager) { | 907 | if (!state.input_inhibit_manager) { |
463 | wlr_log(L_ERROR, "Compositor does not support the input inhibitor " | 908 | wlr_log(WLR_ERROR, "Compositor does not support the input inhibitor " |
464 | "protocol, refusing to run insecurely"); | 909 | "protocol, refusing to run insecurely"); |
465 | return 1; | 910 | return 1; |
466 | } | 911 | } |
467 | 912 | ||
468 | if (wl_list_empty(&state.surfaces)) { | 913 | if (wl_list_empty(&state.surfaces)) { |
469 | wlr_log(L_DEBUG, "Exiting - no outputs to show on."); | 914 | wlr_log(WLR_DEBUG, "Exiting - no outputs to show on."); |
470 | return 0; | 915 | return 0; |
471 | } | 916 | } |
472 | 917 | ||
@@ -482,7 +927,7 @@ int main(int argc, char **argv) { | |||
482 | } | 927 | } |
483 | wl_display_roundtrip(state.display); | 928 | wl_display_roundtrip(state.display); |
484 | } else { | 929 | } else { |
485 | wlr_log(L_INFO, "Compositor does not support zxdg output manager, " | 930 | wlr_log(WLR_INFO, "Compositor does not support zxdg output manager, " |
486 | "images assigned to named outputs will not work"); | 931 | "images assigned to named outputs will not work"); |
487 | } | 932 | } |
488 | 933 | ||
@@ -491,9 +936,16 @@ int main(int argc, char **argv) { | |||
491 | create_layer_surface(surface); | 936 | create_layer_surface(surface); |
492 | } | 937 | } |
493 | 938 | ||
939 | if (state.args.daemonize) { | ||
940 | wl_display_roundtrip(state.display); | ||
941 | daemonize(); | ||
942 | } | ||
943 | |||
494 | state.run_display = true; | 944 | state.run_display = true; |
495 | while (wl_display_dispatch(state.display) != -1 && state.run_display) { | 945 | while (wl_display_dispatch(state.display) != -1 && state.run_display) { |
496 | // This space intentionally left blank | 946 | // This space intentionally left blank |
497 | } | 947 | } |
948 | |||
949 | free(state.args.font); | ||
498 | return 0; | 950 | return 0; |
499 | } | 951 | } |
diff --git a/swaylock/password.c b/swaylock/password.c index bb32286e..7c686b34 100644 --- a/swaylock/password.c +++ b/swaylock/password.c | |||
@@ -53,15 +53,15 @@ static bool attempt_password(struct swaylock_password *pw) { | |||
53 | // TODO: only call pam_start once. keep the same handle the whole time | 53 | // TODO: only call pam_start once. keep the same handle the whole time |
54 | if ((pam_err = pam_start("swaylock", username, | 54 | if ((pam_err = pam_start("swaylock", username, |
55 | &local_conversation, &local_auth_handle)) != PAM_SUCCESS) { | 55 | &local_conversation, &local_auth_handle)) != PAM_SUCCESS) { |
56 | wlr_log(L_ERROR, "PAM returned error %d", pam_err); | 56 | wlr_log(WLR_ERROR, "PAM returned error %d", pam_err); |
57 | } | 57 | } |
58 | if ((pam_err = pam_authenticate(local_auth_handle, 0)) != PAM_SUCCESS) { | 58 | if ((pam_err = pam_authenticate(local_auth_handle, 0)) != PAM_SUCCESS) { |
59 | wlr_log(L_ERROR, "pam_authenticate failed"); | 59 | wlr_log(WLR_ERROR, "pam_authenticate failed"); |
60 | goto fail; | 60 | goto fail; |
61 | } | 61 | } |
62 | // TODO: only call pam_end once we succeed at authing. refresh tokens beforehand | 62 | // TODO: only call pam_end once we succeed at authing. refresh tokens beforehand |
63 | if ((pam_err = pam_end(local_auth_handle, pam_err)) != PAM_SUCCESS) { | 63 | if ((pam_err = pam_end(local_auth_handle, pam_err)) != PAM_SUCCESS) { |
64 | wlr_log(L_ERROR, "pam_end failed"); | 64 | wlr_log(WLR_ERROR, "pam_end failed"); |
65 | goto fail; | 65 | goto fail; |
66 | } | 66 | } |
67 | clear_password_buffer(pw); | 67 | clear_password_buffer(pw); |
@@ -95,9 +95,26 @@ void swaylock_handle_key(struct swaylock_state *state, | |||
95 | switch (keysym) { | 95 | switch (keysym) { |
96 | case XKB_KEY_KP_Enter: /* fallthrough */ | 96 | case XKB_KEY_KP_Enter: /* fallthrough */ |
97 | case XKB_KEY_Return: | 97 | case XKB_KEY_Return: |
98 | if (state->args.ignore_empty && state->password.len == 0) { | ||
99 | break; | ||
100 | } | ||
101 | |||
98 | state->auth_state = AUTH_STATE_VALIDATING; | 102 | state->auth_state = AUTH_STATE_VALIDATING; |
99 | damage_state(state); | 103 | damage_state(state); |
100 | wl_display_roundtrip(state->display); | 104 | while (wl_display_dispatch(state->display) != -1 && state->run_display) { |
105 | bool ok = 1; | ||
106 | struct swaylock_surface *surface; | ||
107 | wl_list_for_each(surface, &state->surfaces, link) { | ||
108 | if (surface->dirty) { | ||
109 | ok = 0; | ||
110 | } | ||
111 | } | ||
112 | if (ok) { | ||
113 | break; | ||
114 | } | ||
115 | } | ||
116 | wl_display_flush(state->display); | ||
117 | |||
101 | if (attempt_password(&state->password)) { | 118 | if (attempt_password(&state->password)) { |
102 | state->run_display = false; | 119 | state->run_display = false; |
103 | break; | 120 | break; |
diff --git a/swaylock/render.c b/swaylock/render.c index 2032ddcf..66c55965 100644 --- a/swaylock/render.c +++ b/swaylock/render.c | |||
@@ -7,11 +7,22 @@ | |||
7 | #include "swaylock/swaylock.h" | 7 | #include "swaylock/swaylock.h" |
8 | 8 | ||
9 | #define M_PI 3.14159265358979323846 | 9 | #define M_PI 3.14159265358979323846 |
10 | const int ARC_RADIUS = 50; | ||
11 | const int ARC_THICKNESS = 10; | ||
12 | const float TYPE_INDICATOR_RANGE = M_PI / 3.0f; | 10 | const float TYPE_INDICATOR_RANGE = M_PI / 3.0f; |
13 | const float TYPE_INDICATOR_BORDER_THICKNESS = M_PI / 128.0f; | 11 | const float TYPE_INDICATOR_BORDER_THICKNESS = M_PI / 128.0f; |
14 | 12 | ||
13 | static void set_color_for_state(cairo_t *cairo, struct swaylock_state *state, | ||
14 | struct swaylock_colorset *colorset) { | ||
15 | if (state->auth_state == AUTH_STATE_VALIDATING) { | ||
16 | cairo_set_source_u32(cairo, colorset->verifying); | ||
17 | } else if (state->auth_state == AUTH_STATE_INVALID) { | ||
18 | cairo_set_source_u32(cairo, colorset->wrong); | ||
19 | } else if (state->auth_state == AUTH_STATE_CLEAR) { | ||
20 | cairo_set_source_u32(cairo, colorset->cleared); | ||
21 | } else { | ||
22 | cairo_set_source_u32(cairo, colorset->input); | ||
23 | } | ||
24 | } | ||
25 | |||
15 | void render_frame(struct swaylock_surface *surface) { | 26 | void render_frame(struct swaylock_surface *surface) { |
16 | struct swaylock_state *state = surface->state; | 27 | struct swaylock_state *state = surface->state; |
17 | 28 | ||
@@ -30,58 +41,37 @@ void render_frame(struct swaylock_surface *surface) { | |||
30 | cairo_t *cairo = surface->current_buffer->cairo; | 41 | cairo_t *cairo = surface->current_buffer->cairo; |
31 | cairo_identity_matrix(cairo); | 42 | cairo_identity_matrix(cairo); |
32 | 43 | ||
44 | cairo_save(cairo); | ||
45 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
33 | if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR || !surface->image) { | 46 | if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR || !surface->image) { |
34 | cairo_set_source_u32(cairo, state->args.color); | 47 | cairo_set_source_u32(cairo, state->args.colors.background); |
35 | cairo_paint(cairo); | 48 | cairo_paint(cairo); |
36 | } else { | 49 | } else { |
37 | render_background_image(cairo, surface->image, | 50 | render_background_image(cairo, surface->image, |
38 | state->args.mode, buffer_width, buffer_height); | 51 | state->args.mode, buffer_width, buffer_height); |
39 | } | 52 | } |
53 | cairo_restore(cairo); | ||
40 | cairo_identity_matrix(cairo); | 54 | cairo_identity_matrix(cairo); |
41 | 55 | ||
42 | int arc_radius = ARC_RADIUS * surface->scale; | 56 | int arc_radius = state->args.radius * surface->scale; |
43 | int arc_thickness = ARC_THICKNESS * surface->scale; | 57 | int arc_thickness = state->args.thickness * surface->scale; |
44 | float type_indicator_border_thickness = | 58 | float type_indicator_border_thickness = |
45 | TYPE_INDICATOR_BORDER_THICKNESS * surface->scale; | 59 | TYPE_INDICATOR_BORDER_THICKNESS * surface->scale; |
46 | 60 | ||
47 | if (state->args.show_indicator && state->auth_state != AUTH_STATE_IDLE) { | 61 | if (state->args.show_indicator && state->auth_state != AUTH_STATE_IDLE) { |
48 | // Draw circle | 62 | // Draw circle |
49 | cairo_set_line_width(cairo, arc_thickness); | 63 | cairo_set_line_width(cairo, arc_thickness); |
50 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, arc_radius, 0, 2 * M_PI); | 64 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, arc_radius, |
51 | switch (state->auth_state) { | 65 | 0, 2 * M_PI); |
52 | case AUTH_STATE_INPUT: | 66 | set_color_for_state(cairo, state, &state->args.colors.inside); |
53 | case AUTH_STATE_INPUT_NOP: | 67 | cairo_fill_preserve(cairo); |
54 | case AUTH_STATE_BACKSPACE: { | 68 | set_color_for_state(cairo, state, &state->args.colors.ring); |
55 | cairo_set_source_rgba(cairo, 0, 0, 0, 0.75); | 69 | cairo_stroke(cairo); |
56 | cairo_fill_preserve(cairo); | ||
57 | cairo_set_source_rgb(cairo, 51.0 / 255, 125.0 / 255, 0); | ||
58 | cairo_stroke(cairo); | ||
59 | } break; | ||
60 | case AUTH_STATE_VALIDATING: { | ||
61 | cairo_set_source_rgba(cairo, 0, 114.0 / 255, 255.0 / 255, 0.75); | ||
62 | cairo_fill_preserve(cairo); | ||
63 | cairo_set_source_rgb(cairo, 51.0 / 255, 0, 250.0 / 255); | ||
64 | cairo_stroke(cairo); | ||
65 | } break; | ||
66 | case AUTH_STATE_INVALID: { | ||
67 | cairo_set_source_rgba(cairo, 250.0 / 255, 0, 0, 0.75); | ||
68 | cairo_fill_preserve(cairo); | ||
69 | cairo_set_source_rgb(cairo, 125.0 / 255, 51.0 / 255, 0); | ||
70 | cairo_stroke(cairo); | ||
71 | } break; | ||
72 | case AUTH_STATE_CLEAR: { | ||
73 | cairo_set_source_rgba(cairo, 229.0/255, 164.0/255, 69.0/255, 0.75); | ||
74 | cairo_fill_preserve(cairo); | ||
75 | cairo_set_source_rgb(cairo, 229.0/255, 164.0/255, 69.0/255); | ||
76 | cairo_stroke(cairo); | ||
77 | } break; | ||
78 | default: break; | ||
79 | } | ||
80 | 70 | ||
81 | // Draw a message | 71 | // Draw a message |
82 | char *text = NULL; | 72 | char *text = NULL; |
83 | cairo_set_source_rgb(cairo, 0, 0, 0); | 73 | set_color_for_state(cairo, state, &state->args.colors.text); |
84 | cairo_select_font_face(cairo, "sans-serif", | 74 | cairo_select_font_face(cairo, state->args.font, |
85 | CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); | 75 | CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); |
86 | cairo_set_font_size(cairo, arc_radius / 3.0f); | 76 | cairo_set_font_size(cairo, arc_radius / 3.0f); |
87 | switch (state->auth_state) { | 77 | switch (state->auth_state) { |
@@ -98,9 +88,10 @@ void render_frame(struct swaylock_surface *surface) { | |||
98 | case AUTH_STATE_INPUT_NOP: | 88 | case AUTH_STATE_INPUT_NOP: |
99 | if (state->xkb.caps_lock) { | 89 | if (state->xkb.caps_lock) { |
100 | text = "Caps Lock"; | 90 | text = "Caps Lock"; |
101 | cairo_set_source_rgb(cairo, 229.0/255, 164.0/255, 69.0/255); | ||
102 | } | 91 | } |
103 | default: break; | 92 | break; |
93 | default: | ||
94 | break; | ||
104 | } | 95 | } |
105 | 96 | ||
106 | if (text) { | 97 | if (text) { |
@@ -128,14 +119,14 @@ void render_frame(struct swaylock_surface *surface) { | |||
128 | arc_radius, highlight_start, | 119 | arc_radius, highlight_start, |
129 | highlight_start + TYPE_INDICATOR_RANGE); | 120 | highlight_start + TYPE_INDICATOR_RANGE); |
130 | if (state->auth_state == AUTH_STATE_INPUT) { | 121 | if (state->auth_state == AUTH_STATE_INPUT) { |
131 | cairo_set_source_rgb(cairo, 51.0 / 255, 219.0 / 255, 0); | 122 | cairo_set_source_u32(cairo, state->args.colors.key_highlight); |
132 | } else { | 123 | } else { |
133 | cairo_set_source_rgb(cairo, 219.0 / 255, 51.0 / 255, 0); | 124 | cairo_set_source_u32(cairo, state->args.colors.bs_highlight); |
134 | } | 125 | } |
135 | cairo_stroke(cairo); | 126 | cairo_stroke(cairo); |
136 | 127 | ||
137 | // Draw borders | 128 | // Draw borders |
138 | cairo_set_source_rgb(cairo, 0, 0, 0); | 129 | cairo_set_source_u32(cairo, state->args.colors.separator); |
139 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, | 130 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, |
140 | arc_radius, highlight_start, | 131 | arc_radius, highlight_start, |
141 | highlight_start + type_indicator_border_thickness); | 132 | highlight_start + type_indicator_border_thickness); |
@@ -149,7 +140,7 @@ void render_frame(struct swaylock_surface *surface) { | |||
149 | } | 140 | } |
150 | 141 | ||
151 | // Draw inner + outer border of the circle | 142 | // Draw inner + outer border of the circle |
152 | cairo_set_source_rgb(cairo, 0, 0, 0); | 143 | set_color_for_state(cairo, state, &state->args.colors.line); |
153 | cairo_set_line_width(cairo, 2.0 * surface->scale); | 144 | cairo_set_line_width(cairo, 2.0 * surface->scale); |
154 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, | 145 | cairo_arc(cairo, buffer_width / 2, buffer_height / 2, |
155 | arc_radius - arc_thickness / 2, 0, 2 * M_PI); | 146 | arc_radius - arc_thickness / 2, 0, 2 * M_PI); |
diff --git a/swaylock/seat.c b/swaylock/seat.c index 6c66d220..c2630d87 100644 --- a/swaylock/seat.c +++ b/swaylock/seat.c | |||
@@ -12,13 +12,13 @@ static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, | |||
12 | struct swaylock_state *state = data; | 12 | struct swaylock_state *state = data; |
13 | if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { | 13 | if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { |
14 | close(fd); | 14 | close(fd); |
15 | wlr_log(L_ERROR, "Unknown keymap format %d, aborting", format); | 15 | wlr_log(WLR_ERROR, "Unknown keymap format %d, aborting", format); |
16 | exit(1); | 16 | exit(1); |
17 | } | 17 | } |
18 | char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); | 18 | char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); |
19 | if (map_shm == MAP_FAILED) { | 19 | if (map_shm == MAP_FAILED) { |
20 | close(fd); | 20 | close(fd); |
21 | wlr_log(L_ERROR, "Unable to initialize keymap shm, aborting"); | 21 | wlr_log(WLR_ERROR, "Unable to initialize keymap shm, aborting"); |
22 | exit(1); | 22 | exit(1); |
23 | } | 23 | } |
24 | struct xkb_keymap *keymap = xkb_keymap_new_from_string( | 24 | struct xkb_keymap *keymap = xkb_keymap_new_from_string( |
diff --git a/swaylock/swaylock.1.scd b/swaylock/swaylock.1.scd index 35d6444c..3107124f 100644 --- a/swaylock/swaylock.1.scd +++ b/swaylock/swaylock.1.scd | |||
@@ -12,23 +12,34 @@ Locks your Wayland session. | |||
12 | 12 | ||
13 | # OPTIONS | 13 | # OPTIONS |
14 | 14 | ||
15 | *-h, --help* | 15 | *-C, --config* <path> |
16 | Show help message and quit. | 16 | The config file to use. By default, the following paths are checked: |
17 | _$HOME/.swaylock/config_, _$XDG\_CONFIG\_HOME/swaylock/config_, and | ||
18 | _SYSCONFDIR/swaylock/config_. All flags aside from this one are valid | ||
19 | options in the configuration file using the format _long-option=value_. | ||
20 | For options such as _ignore-empty-password_, just supply the _long-option_. | ||
21 | All leading dashes should be omitted and the equals sign is required for | ||
22 | flags that take an argument. | ||
17 | 23 | ||
18 | *-c, --color* <rrggbb[aa]> | 24 | *-c, --color* <rrggbb[aa]> |
19 | Turn the screen into the given color. If -i is used, this sets the | 25 | Turn the screen into the given color. If -i is used, this sets the |
20 | background of the image to the given color. Defaults to white (FFFFFF), or | 26 | background of the image to the given color. Defaults to white (FFFFFF), or |
21 | transparent (00000000) if an image is in use. | 27 | transparent (00000000) if an image is in use. |
22 | 28 | ||
29 | *-e, --ignore-empty-password* | ||
30 | When an empty password is provided by the user, do not validate it. | ||
31 | |||
23 | *-f, --daemonize* | 32 | *-f, --daemonize* |
24 | Fork into the background after spawning. Note: this is the default behavior | 33 | Detach from the controlling terminal after locking. |
25 | of i3lock. | 34 | |
35 | *-h, --help* | ||
36 | Show help message and quit. | ||
26 | 37 | ||
27 | *-i, --image* [<output>:]<path> | 38 | *-i, --image* [<output>:]<path> |
28 | Display the given image, optionally only on the given output. Use -c to set | 39 | Display the given image, optionally only on the given output. Use -c to set |
29 | a background color. | 40 | a background color. |
30 | 41 | ||
31 | *--scaling* | 42 | *-s, --scaling* |
32 | Scaling mode for images: _stretch_, _fill_, _fit_, _center_, or _tile_. | 43 | Scaling mode for images: _stretch_, _fill_, _fit_, _center_, or _tile_. |
33 | 44 | ||
34 | *-t, --tiling* | 45 | *-t, --tiling* |
@@ -42,29 +53,52 @@ Locks your Wayland session. | |||
42 | 53 | ||
43 | # APPEARANCE | 54 | # APPEARANCE |
44 | 55 | ||
45 | *--bshlcolor* <rrggbb[aa]> | 56 | *--bs-hl-color* <rrggbb[aa]> |
46 | Sets the color of backspace highlight segments. | 57 | Sets the color of backspace highlight segments. |
47 | 58 | ||
48 | *--font* <font> | 59 | *--font* <font> |
49 | Sets the font of the text inside the indicator. | 60 | Sets the font of the text inside the indicator. |
50 | 61 | ||
51 | *--insidecolor* <rrggbb[aa]> | 62 | *--indicator-radius* <radius> |
63 | Sets the radius of the indicator to _radius_ pixels. The default value is | ||
64 | 50. | ||
65 | |||
66 | *--indicator-thickness* <thickness> | ||
67 | Sets the thickness of the indicator to _thickness_ pixels. The default value | ||
68 | is 10. | ||
69 | |||
70 | *--inside-color* <rrggbb[aa]> | ||
52 | Sets the color of the inside of the indicator when typing or idle. | 71 | Sets the color of the inside of the indicator when typing or idle. |
53 | 72 | ||
54 | *--insidevercolor* <rrggbb[aa]> | 73 | *--inside-clear-color* <rrggbb[aa]> |
74 | Sets the color of the inside of the indicator when cleared. | ||
75 | |||
76 | *--inside-ver-color* <rrggbb[aa]> | ||
55 | Sets the color of the inside of the indicator when verifying. | 77 | Sets the color of the inside of the indicator when verifying. |
56 | 78 | ||
57 | *--insidewrongcolor* <rrggbb[aa]> | 79 | *--inside-wrong-color* <rrggbb[aa]> |
58 | Sets the color of the inside of the indicator when invalid. | 80 | Sets the color of the inside of the indicator when invalid. |
59 | 81 | ||
60 | *--keyhlcolor* <rrggbb[aa]> | 82 | *--key-hl-color* <rrggbb[aa]> |
61 | Sets the color of keypress highlight segments. | 83 | Sets the color of key press highlight segments. |
62 | 84 | ||
63 | *--linecolor* <rrggbb[aa]> | 85 | *--line-color* <rrggbb[aa]> |
64 | Sets the color of the lines that separate the inside and outside of the | 86 | Sets the color of the lines that separate the inside and outside of the |
65 | indicator. | 87 | indicator when typing or idle. |
66 | 88 | ||
67 | *-s, --line-uses-inside* | 89 | *--line-clear-color* <rrggbb[aa]> |
90 | Sets the color of the lines that separate the inside and outside of the | ||
91 | indicator when cleared. | ||
92 | |||
93 | *--line-ver-color* <rrggbb[aa]> | ||
94 | Sets the color of the lines that separate the inside and outside of the | ||
95 | indicator when verifying. | ||
96 | |||
97 | *--line-wrong-color* <rrggbb[aa]> | ||
98 | Sets the color of the lines that separate the inside and outside of the | ||
99 | indicator when invalid. | ||
100 | |||
101 | *-n, --line-uses-inside* | ||
68 | Use the color of the inside of the indicator for the line separating the | 102 | Use the color of the inside of the indicator for the line separating the |
69 | inside and outside of the indicator. | 103 | inside and outside of the indicator. |
70 | 104 | ||
@@ -72,28 +106,32 @@ Locks your Wayland session. | |||
72 | Use the outer ring's color for the line separating the inside and outside of | 106 | Use the outer ring's color for the line separating the inside and outside of |
73 | the indicator. | 107 | the indicator. |
74 | 108 | ||
75 | *--ringcolor* <rrggbb[aa]> | 109 | *--ring-color* <rrggbb[aa]> |
76 | Sets the color of the outside of the indicator when typing or idle. | 110 | Sets the color of the outside of the indicator when typing or idle. |
77 | 111 | ||
78 | *--ringvercolor* <rrggbb[aa]> | 112 | *--ring-clear-color* <rrggbb[aa]> |
113 | Sets the color of the outside of the indicator when cleared. | ||
114 | |||
115 | *--ring-ver-color* <rrggbb[aa]> | ||
79 | Sets the color of the outside of the indicator when verifying. | 116 | Sets the color of the outside of the indicator when verifying. |
80 | 117 | ||
81 | *--ringwrongcolor* <rrggbb[aa]> | 118 | *--ring-wrong-color* <rrggbb[aa]> |
82 | Sets the color of the outside of the indicator when invalid. | 119 | Sets the color of the outside of the indicator when invalid. |
83 | 120 | ||
84 | *--separatorcolor* <rrggbb[aa]> | 121 | *--separator-color* <rrggbb[aa]> |
85 | Sets the color of the lines that seperate highlight segments. | 122 | Sets the color of the lines that separate highlight segments. |
86 | 123 | ||
87 | *--textcolor* <rrggbb[aa]> | 124 | *--text-color* <rrggbb[aa]> |
88 | Sets the color of the text inside the indicator. | 125 | Sets the color of the text inside the indicator when typing or idle. |
89 | 126 | ||
90 | *--indicator-radius* <radius> | 127 | *--text-clear-color* <rrggbb[aa]> |
91 | Sets the radius of the indicator to _radius_ pixels. The default value is | 128 | Sets the color of the text inside the indicator when cleared. |
92 | 50. | ||
93 | 129 | ||
94 | *--indicator-thickness* <thickness> | 130 | *--text-ver-color* <rrggbb[aa]> |
95 | Sets the thickness of the indicator to _thickness_ pixels. The default value | 131 | Sets the color of the text inside the indicator when verifying. |
96 | is 10. | 132 | |
133 | *--text-wrong-color* <rrggbb[aa]> | ||
134 | Sets the color of the text inside the indicator when invalid. | ||
97 | 135 | ||
98 | # AUTHORS | 136 | # AUTHORS |
99 | 137 | ||