aboutsummaryrefslogtreecommitdiffstats
path: root/swaylock
diff options
context:
space:
mode:
Diffstat (limited to 'swaylock')
-rw-r--r--swaylock/main.c192
-rw-r--r--swaylock/pam.c2
-rw-r--r--swaylock/password.c96
-rw-r--r--swaylock/render.c28
-rw-r--r--swaylock/seat.c6
-rw-r--r--swaylock/shadow.c2
-rw-r--r--swaylock/swaylock.1.scd27
7 files changed, 240 insertions, 113 deletions
diff --git a/swaylock/main.c b/swaylock/main.c
index 9b74b671..0b167da1 100644
--- a/swaylock/main.c
+++ b/swaylock/main.c
@@ -1,10 +1,10 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#define _POSIX_C_SOURCE 200112L
3#include <assert.h> 2#include <assert.h>
4#include <ctype.h> 3#include <ctype.h>
5#include <errno.h> 4#include <errno.h>
6#include <fcntl.h> 5#include <fcntl.h>
7#include <getopt.h> 6#include <getopt.h>
7#include <poll.h>
8#include <stdbool.h> 8#include <stdbool.h>
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h> 10#include <stdlib.h>
@@ -23,7 +23,6 @@
23#include "cairo.h" 23#include "cairo.h"
24#include "log.h" 24#include "log.h"
25#include "loop.h" 25#include "loop.h"
26#include "readline.h"
27#include "stringop.h" 26#include "stringop.h"
28#include "util.h" 27#include "util.h"
29#include "wlr-input-inhibitor-unstable-v1-client-protocol.h" 28#include "wlr-input-inhibitor-unstable-v1-client-protocol.h"
@@ -397,28 +396,34 @@ static void set_default_colors(struct swaylock_colors *colors) {
397 colors->background = 0xFFFFFFFF; 396 colors->background = 0xFFFFFFFF;
398 colors->bs_highlight = 0xDB3300FF; 397 colors->bs_highlight = 0xDB3300FF;
399 colors->key_highlight = 0x33DB00FF; 398 colors->key_highlight = 0x33DB00FF;
399 colors->caps_lock_bs_highlight = 0xDB3300FF;
400 colors->caps_lock_key_highlight = 0x33DB00FF;
400 colors->separator = 0x000000FF; 401 colors->separator = 0x000000FF;
401 colors->inside = (struct swaylock_colorset){ 402 colors->inside = (struct swaylock_colorset){
402 .input = 0x000000C0, 403 .input = 0x000000C0,
403 .cleared = 0xE5A445C0, 404 .cleared = 0xE5A445C0,
405 .caps_lock = 0x000000C0,
404 .verifying = 0x0072FFC0, 406 .verifying = 0x0072FFC0,
405 .wrong = 0xFA0000C0, 407 .wrong = 0xFA0000C0,
406 }; 408 };
407 colors->line = (struct swaylock_colorset){ 409 colors->line = (struct swaylock_colorset){
408 .input = 0x000000FF, 410 .input = 0x000000FF,
409 .cleared = 0x000000FF, 411 .cleared = 0x000000FF,
412 .caps_lock = 0x000000FF,
410 .verifying = 0x000000FF, 413 .verifying = 0x000000FF,
411 .wrong = 0x000000FF, 414 .wrong = 0x000000FF,
412 }; 415 };
413 colors->ring = (struct swaylock_colorset){ 416 colors->ring = (struct swaylock_colorset){
414 .input = 0x337D00FF, 417 .input = 0x337D00FF,
415 .cleared = 0xE5A445FF, 418 .cleared = 0xE5A445FF,
419 .caps_lock = 0xE5A445FF,
416 .verifying = 0x3300FFFF, 420 .verifying = 0x3300FFFF,
417 .wrong = 0x7D3300FF, 421 .wrong = 0x7D3300FF,
418 }; 422 };
419 colors->text = (struct swaylock_colorset){ 423 colors->text = (struct swaylock_colorset){
420 .input = 0xE5A445FF, 424 .input = 0xE5A445FF,
421 .cleared = 0x000000FF, 425 .cleared = 0x000000FF,
426 .caps_lock = 0xE5A445FF,
422 .verifying = 0x000000FF, 427 .verifying = 0x000000FF,
423 .wrong = 0x000000FF, 428 .wrong = 0x000000FF,
424 }; 429 };
@@ -434,25 +439,31 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
434 enum line_mode *line_mode, char **config_path) { 439 enum line_mode *line_mode, char **config_path) {
435 enum long_option_codes { 440 enum long_option_codes {
436 LO_BS_HL_COLOR = 256, 441 LO_BS_HL_COLOR = 256,
442 LO_CAPS_LOCK_BS_HL_COLOR,
443 LO_CAPS_LOCK_KEY_HL_COLOR,
437 LO_FONT, 444 LO_FONT,
438 LO_IND_RADIUS, 445 LO_IND_RADIUS,
439 LO_IND_THICKNESS, 446 LO_IND_THICKNESS,
440 LO_INSIDE_COLOR, 447 LO_INSIDE_COLOR,
441 LO_INSIDE_CLEAR_COLOR, 448 LO_INSIDE_CLEAR_COLOR,
449 LO_INSIDE_CAPS_LOCK_COLOR,
442 LO_INSIDE_VER_COLOR, 450 LO_INSIDE_VER_COLOR,
443 LO_INSIDE_WRONG_COLOR, 451 LO_INSIDE_WRONG_COLOR,
444 LO_KEY_HL_COLOR, 452 LO_KEY_HL_COLOR,
445 LO_LINE_COLOR, 453 LO_LINE_COLOR,
446 LO_LINE_CLEAR_COLOR, 454 LO_LINE_CLEAR_COLOR,
455 LO_LINE_CAPS_LOCK_COLOR,
447 LO_LINE_VER_COLOR, 456 LO_LINE_VER_COLOR,
448 LO_LINE_WRONG_COLOR, 457 LO_LINE_WRONG_COLOR,
449 LO_RING_COLOR, 458 LO_RING_COLOR,
450 LO_RING_CLEAR_COLOR, 459 LO_RING_CLEAR_COLOR,
460 LO_RING_CAPS_LOCK_COLOR,
451 LO_RING_VER_COLOR, 461 LO_RING_VER_COLOR,
452 LO_RING_WRONG_COLOR, 462 LO_RING_WRONG_COLOR,
453 LO_SEP_COLOR, 463 LO_SEP_COLOR,
454 LO_TEXT_COLOR, 464 LO_TEXT_COLOR,
455 LO_TEXT_CLEAR_COLOR, 465 LO_TEXT_CLEAR_COLOR,
466 LO_TEXT_CAPS_LOCK_COLOR,
456 LO_TEXT_VER_COLOR, 467 LO_TEXT_VER_COLOR,
457 LO_TEXT_WRONG_COLOR, 468 LO_TEXT_WRONG_COLOR,
458 }; 469 };
@@ -464,6 +475,8 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
464 {"daemonize", no_argument, NULL, 'f'}, 475 {"daemonize", no_argument, NULL, 'f'},
465 {"help", no_argument, NULL, 'h'}, 476 {"help", no_argument, NULL, 'h'},
466 {"image", required_argument, NULL, 'i'}, 477 {"image", required_argument, NULL, 'i'},
478 {"disable-caps-lock-text", no_argument, NULL, 'L'},
479 {"indicator-caps-lock", no_argument, NULL, 'l'},
467 {"line-uses-inside", no_argument, NULL, 'n'}, 480 {"line-uses-inside", no_argument, NULL, 'n'},
468 {"socket", required_argument, NULL, 'p'}, 481 {"socket", required_argument, NULL, 'p'},
469 {"line-uses-ring", no_argument, NULL, 'r'}, 482 {"line-uses-ring", no_argument, NULL, 'r'},
@@ -472,25 +485,31 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
472 {"no-unlock-indicator", no_argument, NULL, 'u'}, 485 {"no-unlock-indicator", no_argument, NULL, 'u'},
473 {"version", no_argument, NULL, 'v'}, 486 {"version", no_argument, NULL, 'v'},
474 {"bs-hl-color", required_argument, NULL, LO_BS_HL_COLOR}, 487 {"bs-hl-color", required_argument, NULL, LO_BS_HL_COLOR},
488 {"caps-lock-bs-hl-color", required_argument, NULL, LO_CAPS_LOCK_BS_HL_COLOR},
489 {"caps-lock-key-hl-color", required_argument, NULL, LO_CAPS_LOCK_KEY_HL_COLOR},
475 {"font", required_argument, NULL, LO_FONT}, 490 {"font", required_argument, NULL, LO_FONT},
476 {"indicator-radius", required_argument, NULL, LO_IND_RADIUS}, 491 {"indicator-radius", required_argument, NULL, LO_IND_RADIUS},
477 {"indicator-thickness", required_argument, NULL, LO_IND_THICKNESS}, 492 {"indicator-thickness", required_argument, NULL, LO_IND_THICKNESS},
478 {"inside-color", required_argument, NULL, LO_INSIDE_COLOR}, 493 {"inside-color", required_argument, NULL, LO_INSIDE_COLOR},
479 {"inside-clear-color", required_argument, NULL, LO_INSIDE_CLEAR_COLOR}, 494 {"inside-clear-color", required_argument, NULL, LO_INSIDE_CLEAR_COLOR},
495 {"inside-caps-lock-color", required_argument, NULL, LO_INSIDE_CAPS_LOCK_COLOR},
480 {"inside-ver-color", required_argument, NULL, LO_INSIDE_VER_COLOR}, 496 {"inside-ver-color", required_argument, NULL, LO_INSIDE_VER_COLOR},
481 {"inside-wrong-color", required_argument, NULL, LO_INSIDE_WRONG_COLOR}, 497 {"inside-wrong-color", required_argument, NULL, LO_INSIDE_WRONG_COLOR},
482 {"key-hl-color", required_argument, NULL, LO_KEY_HL_COLOR}, 498 {"key-hl-color", required_argument, NULL, LO_KEY_HL_COLOR},
483 {"line-color", required_argument, NULL, LO_LINE_COLOR}, 499 {"line-color", required_argument, NULL, LO_LINE_COLOR},
484 {"line-clear-color", required_argument, NULL, LO_LINE_CLEAR_COLOR}, 500 {"line-clear-color", required_argument, NULL, LO_LINE_CLEAR_COLOR},
501 {"line-caps-lock-color", required_argument, NULL, LO_LINE_CAPS_LOCK_COLOR},
485 {"line-ver-color", required_argument, NULL, LO_LINE_VER_COLOR}, 502 {"line-ver-color", required_argument, NULL, LO_LINE_VER_COLOR},
486 {"line-wrong-color", required_argument, NULL, LO_LINE_WRONG_COLOR}, 503 {"line-wrong-color", required_argument, NULL, LO_LINE_WRONG_COLOR},
487 {"ring-color", required_argument, NULL, LO_RING_COLOR}, 504 {"ring-color", required_argument, NULL, LO_RING_COLOR},
488 {"ring-clear-color", required_argument, NULL, LO_RING_CLEAR_COLOR}, 505 {"ring-clear-color", required_argument, NULL, LO_RING_CLEAR_COLOR},
506 {"ring-caps-lock-color", required_argument, NULL, LO_RING_CAPS_LOCK_COLOR},
489 {"ring-ver-color", required_argument, NULL, LO_RING_VER_COLOR}, 507 {"ring-ver-color", required_argument, NULL, LO_RING_VER_COLOR},
490 {"ring-wrong-color", required_argument, NULL, LO_RING_WRONG_COLOR}, 508 {"ring-wrong-color", required_argument, NULL, LO_RING_WRONG_COLOR},
491 {"separator-color", required_argument, NULL, LO_SEP_COLOR}, 509 {"separator-color", required_argument, NULL, LO_SEP_COLOR},
492 {"text-color", required_argument, NULL, LO_TEXT_COLOR}, 510 {"text-color", required_argument, NULL, LO_TEXT_COLOR},
493 {"text-clear-color", required_argument, NULL, LO_TEXT_CLEAR_COLOR}, 511 {"text-clear-color", required_argument, NULL, LO_TEXT_CLEAR_COLOR},
512 {"text-caps-lock-color", required_argument, NULL, LO_TEXT_CAPS_LOCK_COLOR},
494 {"text-ver-color", required_argument, NULL, LO_TEXT_VER_COLOR}, 513 {"text-ver-color", required_argument, NULL, LO_TEXT_VER_COLOR},
495 {"text-wrong-color", required_argument, NULL, LO_TEXT_WRONG_COLOR}, 514 {"text-wrong-color", required_argument, NULL, LO_TEXT_WRONG_COLOR},
496 {0, 0, 0, 0} 515 {0, 0, 0, 0}
@@ -499,76 +518,97 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
499 const char usage[] = 518 const char usage[] =
500 "Usage: swaylock [options...]\n" 519 "Usage: swaylock [options...]\n"
501 "\n" 520 "\n"
502 " -C, --config <config_file> " 521 " -C, --config <config_file> "
503 "Path to the config file.\n" 522 "Path to the config file.\n"
504 " -c, --color <color> " 523 " -c, --color <color> "
505 "Turn the screen into the given color instead of white.\n" 524 "Turn the screen into the given color instead of white.\n"
506 " -e, --ignore-empty-password " 525 " -e, --ignore-empty-password "
507 "When an empty password is provided, do not validate it.\n" 526 "When an empty password is provided, do not validate it.\n"
508 " -f, --daemonize " 527 " -f, --daemonize "
509 "Detach from the controlling terminal after locking.\n" 528 "Detach from the controlling terminal after locking.\n"
510 " -h, --help " 529 " -h, --help "
511 "Show help message and quit.\n" 530 "Show help message and quit.\n"
512 " -i, --image [<output>:]<path> " 531 " -i, --image [<output>:]<path> "
513 "Display the given image.\n" 532 "Display the given image.\n"
514 " -s, --scaling <mode> " 533 " -L, --disable-caps-lock-text "
534 "Disable the Caps Lock text.\n"
535 " -l, --indicator-caps-lock "
536 "Show the current Caps Lock state also on the indicator.\n"
537 " -s, --scaling <mode> "
515 "Scaling mode: stretch, fill, fit, center, tile.\n" 538 "Scaling mode: stretch, fill, fit, center, tile.\n"
516 " -t, --tiling " 539 " -t, --tiling "
517 "Same as --scaling=tile.\n" 540 "Same as --scaling=tile.\n"
518 " -u, --no-unlock-indicator " 541 " -u, --no-unlock-indicator "
519 "Disable the unlock indicator.\n" 542 "Disable the unlock indicator.\n"
520 " -v, --version " 543 " -v, --version "
521 "Show the version number and quit.\n" 544 "Show the version number and quit.\n"
522 " --bs-hl-color <color> " 545 " --bs-hl-color <color> "
523 "Sets the color of backspace highlight segments.\n" 546 "Sets the color of backspace highlight segments.\n"
524 " --font <font> " 547 " --caps-lock-bs-hl-color <color> "
548 "Sets the color of backspace highlight segments when Caps Lock "
549 "is active.\n"
550 " --caps-lock-key-hl-color <color> "
551 "Sets the color of the key press highlight segments when "
552 "Caps Lock is active.\n"
553 " --font <font> "
525 "Sets the font of the text.\n" 554 "Sets the font of the text.\n"
526 " --indicator-radius <radius> " 555 " --indicator-radius <radius> "
527 "Sets the indicator radius.\n" 556 "Sets the indicator radius.\n"
528 " --indicator-thickness <thick> " 557 " --indicator-thickness <thick> "
529 "Sets the indicator thickness.\n" 558 "Sets the indicator thickness.\n"
530 " --inside-color <color> " 559 " --inside-color <color> "
531 "Sets the color of the inside of the indicator.\n" 560 "Sets the color of the inside of the indicator.\n"
532 " --inside-clear-color <color> " 561 " --inside-clear-color <color> "
533 "Sets the color of the inside of the indicator when cleared.\n" 562 "Sets the color of the inside of the indicator when cleared.\n"
534 " --inside-ver-color <color> " 563 " --inside-caps-lock-color <color> "
564 "Sets the color of the inside of the indicator when Caps Lock "
565 "is active.\n"
566 " --inside-ver-color <color> "
535 "Sets the color of the inside of the indicator when verifying.\n" 567 "Sets the color of the inside of the indicator when verifying.\n"
536 " --inside-wrong-color <color> " 568 " --inside-wrong-color <color> "
537 "Sets the color of the inside of the indicator when invalid.\n" 569 "Sets the color of the inside of the indicator when invalid.\n"
538 " --key-hl-color <color> " 570 " --key-hl-color <color> "
539 "Sets the color of the key press highlight segments.\n" 571 "Sets the color of the key press highlight segments.\n"
540 " --line-color <color> " 572 " --line-color <color> "
541 "Sets the color of the line between the inside and ring.\n" 573 "Sets the color of the line between the inside and ring.\n"
542 " --line-clear-color <color> " 574 " --line-clear-color <color> "
543 "Sets the color of the line between the inside and ring when " 575 "Sets the color of the line between the inside and ring when "
544 "cleared.\n" 576 "cleared.\n"
545 " --line-ver-color <color> " 577 " --line-caps-lock-color <color> "
578 "Sets the color of the line between the inside and ring when "
579 "Caps Lock is active.\n"
580 " --line-ver-color <color> "
546 "Sets the color of the line between the inside and ring when " 581 "Sets the color of the line between the inside and ring when "
547 "verifying.\n" 582 "verifying.\n"
548 " --line-wrong-color <color> " 583 " --line-wrong-color <color> "
549 "Sets the color of the line between the inside and ring when " 584 "Sets the color of the line between the inside and ring when "
550 "invalid.\n" 585 "invalid.\n"
551 " -n, --line-uses-inside " 586 " -n, --line-uses-inside "
552 "Use the inside color for the line between the inside and ring.\n" 587 "Use the inside color for the line between the inside and ring.\n"
553 " -r, --line-uses-ring " 588 " -r, --line-uses-ring "
554 "Use the ring color for the line between the inside and ring.\n" 589 "Use the ring color for the line between the inside and ring.\n"
555 " --ring-color <color> " 590 " --ring-color <color> "
556 "Sets the color of the ring of the indicator.\n" 591 "Sets the color of the ring of the indicator.\n"
557 " --ring-clear-color <color> " 592 " --ring-clear-color <color> "
558 "Sets the color of the ring of the indicator when cleared.\n" 593 "Sets the color of the ring of the indicator when cleared.\n"
559 " --ring-ver-color <color> " 594 " --ring-caps-lock-color <color> "
595 "Sets the color of the ring of the indicator when Caps Lock "
596 "is active.\n"
597 " --ring-ver-color <color> "
560 "Sets the color of the ring of the indicator when verifying.\n" 598 "Sets the color of the ring of the indicator when verifying.\n"
561 " --ring-wrong-color <color> " 599 " --ring-wrong-color <color> "
562 "Sets the color of the ring of the indicator when invalid.\n" 600 "Sets the color of the ring of the indicator when invalid.\n"
563 " --separator-color <color> " 601 " --separator-color <color> "
564 "Sets the color of the lines that separate highlight segments.\n" 602 "Sets the color of the lines that separate highlight segments.\n"
565 " --text-color <color> " 603 " --text-color <color> "
566 "Sets the color of the text.\n" 604 "Sets the color of the text.\n"
567 " --text-clear-color <color> " 605 " --text-clear-color <color> "
568 "Sets the color of the text when cleared.\n" 606 "Sets the color of the text when cleared.\n"
569 " --text-ver-color <color> " 607 " --text-caps-lock-color <color> "
608 "Sets the color of the text when Caps Lock is active.\n"
609 " --text-ver-color <color> "
570 "Sets the color of the text when verifying.\n" 610 "Sets the color of the text when verifying.\n"
571 " --text-wrong-color <color> " 611 " --text-wrong-color <color> "
572 "Sets the color of the text when invalid.\n" 612 "Sets the color of the text when invalid.\n"
573 "\n" 613 "\n"
574 "All <color> options are of the form <rrggbb[aa]>.\n"; 614 "All <color> options are of the form <rrggbb[aa]>.\n";
@@ -577,7 +617,7 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
577 optind = 1; 617 optind = 1;
578 while (1) { 618 while (1) {
579 int opt_idx = 0; 619 int opt_idx = 0;
580 c = getopt_long(argc, argv, "c:efhi:nrs:tuvC:", long_options, &opt_idx); 620 c = getopt_long(argc, argv, "c:efhi:Llnrs:tuvC:", long_options, &opt_idx);
581 if (c == -1) { 621 if (c == -1) {
582 break; 622 break;
583 } 623 }
@@ -608,6 +648,16 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
608 load_image(optarg, state); 648 load_image(optarg, state);
609 } 649 }
610 break; 650 break;
651 case 'L':
652 if (state) {
653 state->args.show_caps_lock_text = false;
654 }
655 break;
656 case 'l':
657 if (state) {
658 state->args.show_caps_lock_indicator = true;
659 }
660 break;
611 case 'n': 661 case 'n':
612 if (line_mode) { 662 if (line_mode) {
613 *line_mode = LM_INSIDE; 663 *line_mode = LM_INSIDE;
@@ -645,6 +695,16 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
645 state->args.colors.bs_highlight = parse_color(optarg); 695 state->args.colors.bs_highlight = parse_color(optarg);
646 } 696 }
647 break; 697 break;
698 case LO_CAPS_LOCK_BS_HL_COLOR:
699 if (state) {
700 state->args.colors.caps_lock_bs_highlight = parse_color(optarg);
701 }
702 break;
703 case LO_CAPS_LOCK_KEY_HL_COLOR:
704 if (state) {
705 state->args.colors.caps_lock_key_highlight = parse_color(optarg);
706 }
707 break;
648 case LO_FONT: 708 case LO_FONT:
649 if (state) { 709 if (state) {
650 free(state->args.font); 710 free(state->args.font);
@@ -671,6 +731,11 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
671 state->args.colors.inside.cleared = parse_color(optarg); 731 state->args.colors.inside.cleared = parse_color(optarg);
672 } 732 }
673 break; 733 break;
734 case LO_INSIDE_CAPS_LOCK_COLOR:
735 if (state) {
736 state->args.colors.inside.caps_lock = parse_color(optarg);
737 }
738 break;
674 case LO_INSIDE_VER_COLOR: 739 case LO_INSIDE_VER_COLOR:
675 if (state) { 740 if (state) {
676 state->args.colors.inside.verifying = parse_color(optarg); 741 state->args.colors.inside.verifying = parse_color(optarg);
@@ -696,6 +761,11 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
696 state->args.colors.line.cleared = parse_color(optarg); 761 state->args.colors.line.cleared = parse_color(optarg);
697 } 762 }
698 break; 763 break;
764 case LO_LINE_CAPS_LOCK_COLOR:
765 if (state) {
766 state->args.colors.line.caps_lock = parse_color(optarg);
767 }
768 break;
699 case LO_LINE_VER_COLOR: 769 case LO_LINE_VER_COLOR:
700 if (state) { 770 if (state) {
701 state->args.colors.line.verifying = parse_color(optarg); 771 state->args.colors.line.verifying = parse_color(optarg);
@@ -716,6 +786,11 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
716 state->args.colors.ring.cleared = parse_color(optarg); 786 state->args.colors.ring.cleared = parse_color(optarg);
717 } 787 }
718 break; 788 break;
789 case LO_RING_CAPS_LOCK_COLOR:
790 if (state) {
791 state->args.colors.ring.caps_lock = parse_color(optarg);
792 }
793 break;
719 case LO_RING_VER_COLOR: 794 case LO_RING_VER_COLOR:
720 if (state) { 795 if (state) {
721 state->args.colors.ring.verifying = parse_color(optarg); 796 state->args.colors.ring.verifying = parse_color(optarg);
@@ -741,6 +816,11 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
741 state->args.colors.text.cleared = parse_color(optarg); 816 state->args.colors.text.cleared = parse_color(optarg);
742 } 817 }
743 break; 818 break;
819 case LO_TEXT_CAPS_LOCK_COLOR:
820 if (state) {
821 state->args.colors.text.caps_lock = parse_color(optarg);
822 }
823 break;
744 case LO_TEXT_VER_COLOR: 824 case LO_TEXT_VER_COLOR:
745 if (state) { 825 if (state) {
746 state->args.colors.text.verifying = parse_color(optarg); 826 state->args.colors.text.verifying = parse_color(optarg);
@@ -808,36 +888,32 @@ static int load_config(char *path, struct swaylock_state *state,
808 wlr_log(WLR_ERROR, "Failed to read config. Running without it."); 888 wlr_log(WLR_ERROR, "Failed to read config. Running without it.");
809 return 0; 889 return 0;
810 } 890 }
811 char *line; 891 char *line = NULL;
892 size_t line_size = 0;
893 ssize_t nread;
812 int line_number = 0; 894 int line_number = 0;
813 while (!feof(config)) { 895 int result = 0;
814 line = read_line(config); 896 while ((nread = getline(&line, &line_size, config)) != -1) {
815 if (!line) {
816 continue;
817 }
818
819 line_number++; 897 line_number++;
820 if (line[0] == '#') { 898
821 free(line); 899 if (line[nread - 1] == '\n') {
822 continue; 900 line[--nread] = '\0';
823 } 901 }
824 if (strlen(line) == 0) { 902
825 free(line); 903 if (!*line || line[0] == '#') {
826 continue; 904 continue;
827 } 905 }
828 906
829 wlr_log(WLR_DEBUG, "Config Line #%d: %s", line_number, line); 907 wlr_log(WLR_DEBUG, "Config Line #%d: %s", line_number, line);
830 char flag[strlen(line) + 3]; 908 char flag[nread + 3];
831 sprintf(flag, "--%s", line); 909 sprintf(flag, "--%s", line);
832 char *argv[] = {"swaylock", flag}; 910 char *argv[] = {"swaylock", flag};
833 int result = parse_options(2, argv, state, line_mode, NULL); 911 result = parse_options(2, argv, state, line_mode, NULL);
834 if (result != 0) { 912 if (result != 0) {
835 free(line); 913 break;
836 fclose(config);
837 return result;
838 } 914 }
839 free(line);
840 } 915 }
916 free(line);
841 fclose(config); 917 fclose(config);
842 return 0; 918 return 0;
843} 919}
@@ -862,6 +938,8 @@ int main(int argc, char **argv) {
862 .thickness = 10, 938 .thickness = 10,
863 .ignore_empty = false, 939 .ignore_empty = false,
864 .show_indicator = true, 940 .show_indicator = true,
941 .show_caps_lock_indicator = false,
942 .show_caps_lock_text = true
865 }; 943 };
866 wl_list_init(&state.images); 944 wl_list_init(&state.images);
867 set_default_colors(&state.args.colors); 945 set_default_colors(&state.args.colors);
@@ -962,7 +1040,7 @@ int main(int argc, char **argv) {
962 } 1040 }
963 1041
964 state.eventloop = loop_create(); 1042 state.eventloop = loop_create();
965 loop_add_fd(state.eventloop, wl_display_get_fd(state.display), POLL_IN, 1043 loop_add_fd(state.eventloop, wl_display_get_fd(state.display), POLLIN,
966 display_in, NULL); 1044 display_in, NULL);
967 1045
968 state.run_display = true; 1046 state.run_display = true;
diff --git a/swaylock/pam.c b/swaylock/pam.c
index cac95a85..b90d9e87 100644
--- a/swaylock/pam.c
+++ b/swaylock/pam.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <pwd.h> 2#include <pwd.h>
3#include <security/pam_appl.h> 3#include <security/pam_appl.h>
4#include <stdbool.h> 4#include <stdbool.h>
diff --git a/swaylock/password.c b/swaylock/password.c
index 6138e1fe..3bd113ad 100644
--- a/swaylock/password.c
+++ b/swaylock/password.c
@@ -1,4 +1,3 @@
1#define _XOPEN_SOURCE 500
2#include <assert.h> 1#include <assert.h>
3#include <errno.h> 2#include <errno.h>
4#include <pwd.h> 3#include <pwd.h>
@@ -78,52 +77,56 @@ static void handle_preverify_timeout(void *data) {
78 state->verify_password_timer = NULL; 77 state->verify_password_timer = NULL;
79} 78}
80 79
81void swaylock_handle_key(struct swaylock_state *state, 80static void submit_password(struct swaylock_state *state) {
82 xkb_keysym_t keysym, uint32_t codepoint) { 81 if (state->args.ignore_empty && state->password.len == 0) {
83 switch (keysym) { 82 return;
84 case XKB_KEY_KP_Enter: /* fallthrough */ 83 }
85 case XKB_KEY_Return:
86 if (state->args.ignore_empty && state->password.len == 0) {
87 break;
88 }
89 84
90 state->auth_state = AUTH_STATE_VALIDATING; 85 state->auth_state = AUTH_STATE_VALIDATING;
91 damage_state(state); 86 damage_state(state);
92 87
93 // We generally want to wait until all surfaces are showing the 88 // We generally want to wait until all surfaces are showing the
94 // "verifying" state before we go and verify the password, because 89 // "verifying" state before we go and verify the password, because
95 // verifying it is a blocking operation. However, if the surface is on 90 // verifying it is a blocking operation. However, if the surface is on
96 // an output with DPMS off then it won't update, so we set a timer. 91 // an output with DPMS off then it won't update, so we set a timer.
97 state->verify_password_timer = loop_add_timer( 92 state->verify_password_timer = loop_add_timer(
98 state->eventloop, 50, handle_preverify_timeout, state); 93 state->eventloop, 50, handle_preverify_timeout, state);
99 94
100 while (state->run_display && state->verify_password_timer) { 95 while (state->run_display && state->verify_password_timer) {
101 errno = 0; 96 errno = 0;
102 if (wl_display_flush(state->display) == -1 && errno != EAGAIN) { 97 if (wl_display_flush(state->display) == -1 && errno != EAGAIN) {
103 break; 98 break;
104 } 99 }
105 loop_poll(state->eventloop); 100 loop_poll(state->eventloop);
106 101
107 bool ok = 1; 102 bool ok = 1;
108 struct swaylock_surface *surface; 103 struct swaylock_surface *surface;
109 wl_list_for_each(surface, &state->surfaces, link) { 104 wl_list_for_each(surface, &state->surfaces, link) {
110 if (surface->dirty) { 105 if (surface->dirty) {
111 ok = 0; 106 ok = 0;
112 }
113 }
114 if (ok) {
115 break;
116 } 107 }
117 } 108 }
118 wl_display_flush(state->display); 109 if (ok) {
119
120 if (attempt_password(&state->password)) {
121 state->run_display = false;
122 break; 110 break;
123 } 111 }
124 state->auth_state = AUTH_STATE_INVALID; 112 }
125 damage_state(state); 113 wl_display_flush(state->display);
126 schedule_indicator_clear(state); 114
115 if (attempt_password(&state->password)) {
116 state->run_display = false;
117 return;
118 }
119 state->auth_state = AUTH_STATE_INVALID;
120 damage_state(state);
121 schedule_indicator_clear(state);
122}
123
124void swaylock_handle_key(struct swaylock_state *state,
125 xkb_keysym_t keysym, uint32_t codepoint) {
126 switch (keysym) {
127 case XKB_KEY_KP_Enter: /* fallthrough */
128 case XKB_KEY_Return:
129 submit_password(state);
127 break; 130 break;
128 case XKB_KEY_Delete: 131 case XKB_KEY_Delete:
129 case XKB_KEY_BackSpace: 132 case XKB_KEY_BackSpace:
@@ -143,14 +146,6 @@ void swaylock_handle_key(struct swaylock_state *state,
143 schedule_indicator_clear(state); 146 schedule_indicator_clear(state);
144 break; 147 break;
145 case XKB_KEY_Caps_Lock: 148 case XKB_KEY_Caps_Lock:
146 /* The state is getting active after this
147 * so we need to manually toggle it */
148 state->xkb.caps_lock = !state->xkb.caps_lock;
149 state->auth_state = AUTH_STATE_INPUT_NOP;
150 damage_state(state);
151 schedule_indicator_clear(state);
152 schedule_password_clear(state);
153 break;
154 case XKB_KEY_Shift_L: 149 case XKB_KEY_Shift_L:
155 case XKB_KEY_Shift_R: 150 case XKB_KEY_Shift_R:
156 case XKB_KEY_Control_L: 151 case XKB_KEY_Control_L:
@@ -166,6 +161,13 @@ void swaylock_handle_key(struct swaylock_state *state,
166 schedule_indicator_clear(state); 161 schedule_indicator_clear(state);
167 schedule_password_clear(state); 162 schedule_password_clear(state);
168 break; 163 break;
164 case XKB_KEY_d:
165 if (state->xkb.control) {
166 submit_password(state);
167 break;
168 }
169 // fallthrough
170 case XKB_KEY_c: /* fallthrough */
169 case XKB_KEY_u: 171 case XKB_KEY_u:
170 if (state->xkb.control) { 172 if (state->xkb.control) {
171 clear_password_buffer(&state->password); 173 clear_password_buffer(&state->password);
diff --git a/swaylock/render.c b/swaylock/render.c
index fa8832bd..5aedaad5 100644
--- a/swaylock/render.c
+++ b/swaylock/render.c
@@ -1,4 +1,3 @@
1#define _POSIX_C_SOURCE 199506L
2#include <math.h> 1#include <math.h>
3#include <stdlib.h> 2#include <stdlib.h>
4#include <wayland-client.h> 3#include <wayland-client.h>
@@ -19,7 +18,17 @@ static void set_color_for_state(cairo_t *cairo, struct swaylock_state *state,
19 } else if (state->auth_state == AUTH_STATE_CLEAR) { 18 } else if (state->auth_state == AUTH_STATE_CLEAR) {
20 cairo_set_source_u32(cairo, colorset->cleared); 19 cairo_set_source_u32(cairo, colorset->cleared);
21 } else { 20 } else {
22 cairo_set_source_u32(cairo, colorset->input); 21 if (state->xkb.caps_lock && state->args.show_caps_lock_indicator) {
22 cairo_set_source_u32(cairo, colorset->caps_lock);
23 } else if (state->xkb.caps_lock && !state->args.show_caps_lock_indicator &&
24 state->args.show_caps_lock_text) {
25 uint32_t inputtextcolor = state->args.colors.text.input;
26 state->args.colors.text.input = state->args.colors.text.caps_lock;
27 cairo_set_source_u32(cairo, colorset->input);
28 state->args.colors.text.input = inputtextcolor;
29 } else {
30 cairo_set_source_u32(cairo, colorset->input);
31 }
23 } 32 }
24} 33}
25 34
@@ -93,7 +102,8 @@ void render_frame(struct swaylock_surface *surface) {
93 break; 102 break;
94 case AUTH_STATE_INPUT: 103 case AUTH_STATE_INPUT:
95 case AUTH_STATE_INPUT_NOP: 104 case AUTH_STATE_INPUT_NOP:
96 if (state->xkb.caps_lock) { 105 case AUTH_STATE_BACKSPACE:
106 if (state->xkb.caps_lock && state->args.show_caps_lock_text) {
97 text = "Caps Lock"; 107 text = "Caps Lock";
98 } 108 }
99 break; 109 break;
@@ -126,9 +136,17 @@ void render_frame(struct swaylock_surface *surface) {
126 arc_radius, highlight_start, 136 arc_radius, highlight_start,
127 highlight_start + TYPE_INDICATOR_RANGE); 137 highlight_start + TYPE_INDICATOR_RANGE);
128 if (state->auth_state == AUTH_STATE_INPUT) { 138 if (state->auth_state == AUTH_STATE_INPUT) {
129 cairo_set_source_u32(cairo, state->args.colors.key_highlight); 139 if (state->xkb.caps_lock && state->args.show_caps_lock_indicator) {
140 cairo_set_source_u32(cairo, state->args.colors.caps_lock_key_highlight);
141 } else {
142 cairo_set_source_u32(cairo, state->args.colors.key_highlight);
143 }
130 } else { 144 } else {
131 cairo_set_source_u32(cairo, state->args.colors.bs_highlight); 145 if (state->xkb.caps_lock && state->args.show_caps_lock_indicator) {
146 cairo_set_source_u32(cairo, state->args.colors.caps_lock_bs_highlight);
147 } else {
148 cairo_set_source_u32(cairo, state->args.colors.bs_highlight);
149 }
132 } 150 }
133 cairo_stroke(cairo); 151 cairo_stroke(cairo);
134 152
diff --git a/swaylock/seat.c b/swaylock/seat.c
index 7b72114f..f0b1385e 100644
--- a/swaylock/seat.c
+++ b/swaylock/seat.c
@@ -63,8 +63,12 @@ static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,
63 struct swaylock_state *state = data; 63 struct swaylock_state *state = data;
64 xkb_state_update_mask(state->xkb.state, 64 xkb_state_update_mask(state->xkb.state,
65 mods_depressed, mods_latched, mods_locked, 0, 0, group); 65 mods_depressed, mods_latched, mods_locked, 0, 0, group);
66 state->xkb.caps_lock = xkb_state_mod_name_is_active(state->xkb.state, 66 int caps_lock = xkb_state_mod_name_is_active(state->xkb.state,
67 XKB_MOD_NAME_CAPS, XKB_STATE_MODS_LOCKED); 67 XKB_MOD_NAME_CAPS, XKB_STATE_MODS_LOCKED);
68 if (caps_lock != state->xkb.caps_lock) {
69 state->xkb.caps_lock = caps_lock;
70 damage_state(state);
71 }
68 state->xkb.control = xkb_state_mod_name_is_active(state->xkb.state, 72 state->xkb.control = xkb_state_mod_name_is_active(state->xkb.state,
69 XKB_MOD_NAME_CTRL, 73 XKB_MOD_NAME_CTRL,
70 XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); 74 XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
diff --git a/swaylock/shadow.c b/swaylock/shadow.c
index f928eaa3..b7b10a67 100644
--- a/swaylock/shadow.c
+++ b/swaylock/shadow.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 1#define _XOPEN_SOURCE // for crypt
2#include <pwd.h> 2#include <pwd.h>
3#include <shadow.h> 3#include <shadow.h>
4#include <stdbool.h> 4#include <stdbool.h>
diff --git a/swaylock/swaylock.1.scd b/swaylock/swaylock.1.scd
index 8ddc7d3a..2c7979be 100644
--- a/swaylock/swaylock.1.scd
+++ b/swaylock/swaylock.1.scd
@@ -27,7 +27,7 @@ Locks your Wayland session.
27*-f, --daemonize* 27*-f, --daemonize*
28 Detach from the controlling terminal after locking. 28 Detach from the controlling terminal after locking.
29 29
30 Note: this is the default bahavior of i3lock. 30 Note: this is the default behavior of i3lock.
31 31
32*-h, --help* 32*-h, --help*
33 Show help message and quit. 33 Show help message and quit.
@@ -44,6 +44,12 @@ Locks your Wayland session.
44 Display the given image, optionally only on the given output. Use -c to set 44 Display the given image, optionally only on the given output. Use -c to set
45 a background color. 45 a background color.
46 46
47*-L, --disable-caps-lock-text*
48 Disable the Caps Lock Text.
49
50*-l, --indicator-caps-lock*
51 Show the current Caps Lock state also on the indicator.
52
47*-s, --scaling* 53*-s, --scaling*
48 Scaling mode for images: _stretch_, _fill_, _fit_, _center_, or _tile_. 54 Scaling mode for images: _stretch_, _fill_, _fit_, _center_, or _tile_.
49 55
@@ -58,6 +64,12 @@ Locks your Wayland session.
58*--bs-hl-color* <rrggbb[aa]> 64*--bs-hl-color* <rrggbb[aa]>
59 Sets the color of backspace highlight segments. 65 Sets the color of backspace highlight segments.
60 66
67*--caps-lock-bs-hl-color* <rrggbb[aa]>
68 Sets the color of backspace highlight segments when Caps Lock is active.
69
70*--caps-lock-bs-hl-color* <rrggbb[aa]>
71 Sets the color of the key press highlight segments when Caps Lock is active.
72
61*--font* <font> 73*--font* <font>
62 Sets the font of the text inside the indicator. 74 Sets the font of the text inside the indicator.
63 75
@@ -75,6 +87,9 @@ Locks your Wayland session.
75*--inside-clear-color* <rrggbb[aa]> 87*--inside-clear-color* <rrggbb[aa]>
76 Sets the color of the inside of the indicator when cleared. 88 Sets the color of the inside of the indicator when cleared.
77 89
90*--inside-caps-lock-color* <rrggbb[aa]>
91 Sets the color of the inside of the indicator when Caps Lock is active.
92
78*--inside-ver-color* <rrggbb[aa]> 93*--inside-ver-color* <rrggbb[aa]>
79 Sets the color of the inside of the indicator when verifying. 94 Sets the color of the inside of the indicator when verifying.
80 95
@@ -92,6 +107,10 @@ Locks your Wayland session.
92 Sets the color of the lines that separate the inside and outside of the 107 Sets the color of the lines that separate the inside and outside of the
93 indicator when cleared. 108 indicator when cleared.
94 109
110*--line-caps-lock-color* <rrggbb[aa]>
111 Sets the color of the line between the inside and ring when Caps Lock
112 is active.
113
95*--line-ver-color* <rrggbb[aa]> 114*--line-ver-color* <rrggbb[aa]>
96 Sets the color of the lines that separate the inside and outside of the 115 Sets the color of the lines that separate the inside and outside of the
97 indicator when verifying. 116 indicator when verifying.
@@ -114,6 +133,9 @@ Locks your Wayland session.
114*--ring-clear-color* <rrggbb[aa]> 133*--ring-clear-color* <rrggbb[aa]>
115 Sets the color of the outside of the indicator when cleared. 134 Sets the color of the outside of the indicator when cleared.
116 135
136*--ring-caps-lock-color* <rrggbb[aa]>
137 Sets the color of the ring of the indicator when Caps Lock is active.
138
117*--ring-ver-color* <rrggbb[aa]> 139*--ring-ver-color* <rrggbb[aa]>
118 Sets the color of the outside of the indicator when verifying. 140 Sets the color of the outside of the indicator when verifying.
119 141
@@ -129,6 +151,9 @@ Locks your Wayland session.
129*--text-clear-color* <rrggbb[aa]> 151*--text-clear-color* <rrggbb[aa]>
130 Sets the color of the text inside the indicator when cleared. 152 Sets the color of the text inside the indicator when cleared.
131 153
154*--text-caps-lock-color* <rrggbb[aa]>
155 Sets the color of the text when Caps Lock is active.
156
132*--text-ver-color* <rrggbb[aa]> 157*--text-ver-color* <rrggbb[aa]>
133 Sets the color of the text inside the indicator when verifying. 158 Sets the color of the text inside the indicator when verifying.
134 159