aboutsummaryrefslogtreecommitdiffstats
path: root/swaylock/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaylock/main.c')
-rw-r--r--swaylock/main.c180
1 files changed, 145 insertions, 35 deletions
diff --git a/swaylock/main.c b/swaylock/main.c
index f004a8d5..49b24a3a 100644
--- a/swaylock/main.c
+++ b/swaylock/main.c
@@ -18,9 +18,11 @@
18#include "swaylock/swaylock.h" 18#include "swaylock/swaylock.h"
19#include "ipc-client.h" 19#include "ipc-client.h"
20#include "log.h" 20#include "log.h"
21#include "util.h"
21 22
22struct registry *registry; 23struct registry *registry;
23struct render_data render_data; 24struct render_data render_data;
25struct lock_config *config;
24bool show_indicator = true; 26bool show_indicator = true;
25 27
26void wl_dispatch_events() { 28void wl_dispatch_events() {
@@ -35,7 +37,7 @@ void sigalarm_handler(int sig) {
35 signal(SIGALRM, SIG_IGN); 37 signal(SIGALRM, SIG_IGN);
36 // Hide typing indicator 38 // Hide typing indicator
37 render_data.auth_state = AUTH_STATE_IDLE; 39 render_data.auth_state = AUTH_STATE_IDLE;
38 render(&render_data); 40 render(&render_data, config);
39 wl_display_flush(registry->display); 41 wl_display_flush(registry->display);
40 signal(SIGALRM, sigalarm_handler); 42 signal(SIGALRM, sigalarm_handler);
41} 43}
@@ -55,6 +57,36 @@ void sway_terminate(int exit_code) {
55 57
56char *password; 58char *password;
57int password_size; 59int password_size;
60enum line_source line_source = LINE_SOURCE_DEFAULT;
61
62struct lock_config *init_config() {
63 struct lock_config *config = calloc(1, sizeof(struct lock_config));
64
65 config->font = strdup("sans-serif");
66 config->colors.text = 0x000000FF;
67
68 config->colors.line = 0x000000FF;
69 config->colors.separator = 0x000000FF;
70
71 config->colors.input_cursor = 0x33DB00FF;
72 config->colors.backspace_cursor = 0xDB3300FF;
73
74 config->colors.normal.inner_ring = 0x000000BF;
75 config->colors.normal.outer_ring = 0x337D00FF;
76
77 config->colors.validating.inner_ring = 0x0072FFBF;
78 config->colors.validating.outer_ring = 0x3300FAFF;
79
80 config->colors.invalid.inner_ring = 0xFA0000BF;
81 config->colors.invalid.outer_ring = 0x7D3300FF;
82
83 return config;
84}
85
86void free_config(struct lock_config *config) {
87 free(config->font);
88 free(config);
89}
58 90
59int function_conversation(int num_msg, const struct pam_message **msg, 91int function_conversation(int num_msg, const struct pam_message **msg,
60 struct pam_response **resp, void *appdata_ptr) { 92 struct pam_response **resp, void *appdata_ptr) {
@@ -123,7 +155,7 @@ void notify_key(enum wl_keyboard_key_state state, xkb_keysym_t sym, uint32_t cod
123 case XKB_KEY_Return: 155 case XKB_KEY_Return:
124 render_data.auth_state = AUTH_STATE_VALIDATING; 156 render_data.auth_state = AUTH_STATE_VALIDATING;
125 157
126 render(&render_data); 158 render(&render_data, config);
127 // Make sure our render call will actually be displayed on the screen 159 // Make sure our render call will actually be displayed on the screen
128 wl_dispatch_events(); 160 wl_dispatch_events();
129 161
@@ -207,7 +239,7 @@ void notify_key(enum wl_keyboard_key_state state, xkb_keysym_t sym, uint32_t cod
207 } 239 }
208 } 240 }
209 if (redraw_screen) { 241 if (redraw_screen) {
210 render(&render_data); 242 render(&render_data, config);
211 wl_dispatch_events(); 243 wl_dispatch_events();
212 // Hide the indicator after a couple of seconds 244 // Hide the indicator after a couple of seconds
213 alarm(5); 245 alarm(5);
@@ -315,6 +347,7 @@ int main(int argc, char **argv) {
315 const char *scaling_mode_str = "fit", *socket_path = NULL; 347 const char *scaling_mode_str = "fit", *socket_path = NULL;
316 int i; 348 int i;
317 void *images = NULL; 349 void *images = NULL;
350 config = init_config();
318 351
319 render_data.num_images = 0; 352 render_data.num_images = 0;
320 render_data.color_set = 0; 353 render_data.color_set = 0;
@@ -329,12 +362,26 @@ int main(int argc, char **argv) {
329 {"help", no_argument, NULL, 'h'}, 362 {"help", no_argument, NULL, 'h'},
330 {"color", required_argument, NULL, 'c'}, 363 {"color", required_argument, NULL, 'c'},
331 {"image", required_argument, NULL, 'i'}, 364 {"image", required_argument, NULL, 'i'},
332 {"scaling", required_argument, NULL, 's'}, 365 {"scaling", required_argument, NULL, 0},
333 {"tiling", no_argument, NULL, 't'}, 366 {"tiling", no_argument, NULL, 't'},
334 {"version", no_argument, NULL, 'v'}, 367 {"version", no_argument, NULL, 'v'},
335 {"socket", required_argument, NULL, 'p'}, 368 {"socket", required_argument, NULL, 'p'},
336 {"no-unlock-indicator", no_argument, NULL, 'u'}, 369 {"no-unlock-indicator", no_argument, NULL, 'u'},
337 {"daemonize", no_argument, NULL, 'f'}, 370 {"daemonize", no_argument, NULL, 'f'},
371 {"font", required_argument, NULL, 0},
372 {"line-uses-ring", no_argument, NULL, 'r'},
373 {"line-uses-inside", no_argument, NULL, 's'},
374 {"textcolor", required_argument, NULL, 0},
375 {"insidevercolor", required_argument, NULL, 0},
376 {"insidewrongcolor", required_argument, NULL, 0},
377 {"insidecolor", required_argument, NULL, 0},
378 {"ringvercolor", required_argument, NULL, 0},
379 {"ringwrongcolor", required_argument, NULL, 0},
380 {"ringcolor", required_argument, NULL, 0},
381 {"linecolor", required_argument, NULL, 0},
382 {"separatorcolor", required_argument, NULL, 0},
383 {"keyhlcolor", required_argument, NULL, 0},
384 {"bshlcolor", required_argument, NULL, 0},
338 {0, 0, 0, 0} 385 {0, 0, 0, 0}
339 }; 386 };
340 387
@@ -343,13 +390,14 @@ int main(int argc, char **argv) {
343 "\n" 390 "\n"
344 " -h, --help Show help message and quit.\n" 391 " -h, --help Show help message and quit.\n"
345 " -c, --color <rrggbb[aa]> Turn the screen into the given color instead of white.\n" 392 " -c, --color <rrggbb[aa]> Turn the screen into the given color instead of white.\n"
346 " -s, --scaling Scaling mode: stretch, fill, fit, center, tile.\n" 393 " --scaling Scaling mode: stretch, fill, fit, center, tile.\n"
347 " -t, --tiling Same as --scaling=tile.\n" 394 " -t, --tiling Same as --scaling=tile.\n"
348 " -v, --version Show the version number and quit.\n" 395 " -v, --version Show the version number and quit.\n"
349 " -i, --image [<output>:]<path> Display the given image.\n" 396 " -i, --image [<output>:]<path> Display the given image.\n"
350 " -u, --no-unlock-indicator Disable the unlock indicator.\n" 397 " -u, --no-unlock-indicator Disable the unlock indicator.\n"
351 " -f, --daemonize Detach from the controlling terminal.\n" 398 " -f, --daemonize Detach from the controlling terminal.\n"
352 " --socket <socket> Use the specified socket.\n"; 399 " --socket <socket> Use the specified socket.\n"
400 " For more information see `man swaylock`\n";
353 401
354 402
355 registry = registry_poll(); 403 registry = registry_poll();
@@ -357,25 +405,15 @@ int main(int argc, char **argv) {
357 int c; 405 int c;
358 while (1) { 406 while (1) {
359 int option_index = 0; 407 int option_index = 0;
360 c = getopt_long(argc, argv, "hc:i:s:tvuf", long_options, &option_index); 408 c = getopt_long(argc, argv, "hc:i:srtvuf", long_options, &option_index);
361 if (c == -1) { 409 if (c == -1) {
362 break; 410 break;
363 } 411 }
364 switch (c) { 412 switch (c) {
365 case 'c': 413 case 'c':
366 { 414 {
367 int colorlen = strlen(optarg); 415 render_data.color = parse_color(optarg);
368 if (colorlen < 6 || colorlen == 7 || colorlen > 8) {
369 sway_log(L_ERROR, "color must be specified in 3 or 4 byte format, i.e. rrggbb or rrggbbaa");
370 exit(EXIT_FAILURE);
371 }
372 render_data.color = strtol(optarg, NULL, 16);
373 render_data.color_set = 1; 416 render_data.color_set = 1;
374
375 if (colorlen == 6) {
376 render_data.color <<= 8;
377 render_data.color |= 0xFF;
378 }
379 break; 417 break;
380 } 418 }
381 case 'i': 419 case 'i':
@@ -405,9 +443,6 @@ int main(int argc, char **argv) {
405 } 443 }
406 break; 444 break;
407 } 445 }
408 case 's':
409 scaling_mode_str = optarg;
410 break;
411 case 't': 446 case 't':
412 scaling_mode_str = "tile"; 447 scaling_mode_str = "tile";
413 break; 448 break;
@@ -431,6 +466,50 @@ int main(int argc, char **argv) {
431 exit(EXIT_FAILURE); 466 exit(EXIT_FAILURE);
432 } 467 }
433 break; 468 break;
469 case 'r':
470 if (line_source != LINE_SOURCE_DEFAULT) {
471 sway_log(L_ERROR, "line source options conflict");
472 exit(EXIT_FAILURE);
473 }
474 line_source = LINE_SOURCE_RING;
475 break;
476 case 's':
477 if (line_source != LINE_SOURCE_DEFAULT) {
478 sway_log(L_ERROR, "line source options conflict");
479 exit(EXIT_FAILURE);
480 }
481 line_source = LINE_SOURCE_INSIDE;
482 break;
483 case 0:
484 if (strcmp(long_options[option_index].name, "font") == 0) {
485 free(config->font);
486 config->font = strdup(optarg);
487 } else if (strcmp(long_options[option_index].name, "scaling") == 0) {
488 scaling_mode_str = optarg;
489 } else if (strcmp(long_options[option_index].name, "textcolor") == 0) {
490 config->colors.text = parse_color(optarg);
491 } else if (strcmp(long_options[option_index].name, "insidevercolor") == 0) {
492 config->colors.validating.inner_ring = parse_color(optarg);
493 } else if (strcmp(long_options[option_index].name, "insidewrongcolor") == 0) {
494 config->colors.invalid.inner_ring = parse_color(optarg);
495 } else if (strcmp(long_options[option_index].name, "insidecolor") == 0) {
496 config->colors.normal.inner_ring = parse_color(optarg);
497 } else if (strcmp(long_options[option_index].name, "ringvercolor") == 0) {
498 config->colors.validating.outer_ring = parse_color(optarg);
499 } else if (strcmp(long_options[option_index].name, "ringwrongcolor") == 0) {
500 config->colors.invalid.outer_ring = parse_color(optarg);
501 } else if (strcmp(long_options[option_index].name, "ringcolor") == 0) {
502 config->colors.normal.outer_ring = parse_color(optarg);
503 } else if (strcmp(long_options[option_index].name, "linecolor") == 0) {
504 config->colors.line = parse_color(optarg);
505 } else if (strcmp(long_options[option_index].name, "separatorcolor") == 0) {
506 config->colors.separator = parse_color(optarg);
507 } else if (strcmp(long_options[option_index].name, "keyhlcolor") == 0) {
508 config->colors.input_cursor = parse_color(optarg);
509 } else if (strcmp(long_options[option_index].name, "bshlcolor") == 0) {
510 config->colors.backspace_cursor = parse_color(optarg);
511 }
512 break;
434 default: 513 default:
435 fprintf(stderr, "%s", usage); 514 fprintf(stderr, "%s", usage);
436 exit(EXIT_FAILURE); 515 exit(EXIT_FAILURE);
@@ -524,7 +603,7 @@ int main(int argc, char **argv) {
524 free(displays_paths); 603 free(displays_paths);
525 } 604 }
526 605
527 render(&render_data); 606 render(&render_data, config);
528 bool locked = false; 607 bool locked = false;
529 while (wl_display_dispatch(registry->display) != -1) { 608 while (wl_display_dispatch(registry->display) != -1) {
530 if (!locked) { 609 if (!locked) {
@@ -556,10 +635,12 @@ int main(int argc, char **argv) {
556 list_free(render_data.surfaces); 635 list_free(render_data.surfaces);
557 registry_teardown(registry); 636 registry_teardown(registry);
558 637
638 free_config(config);
639
559 return 0; 640 return 0;
560} 641}
561 642
562void render(struct render_data *render_data) { 643void render(struct render_data *render_data, struct lock_config *config) {
563 int i; 644 int i;
564 for (i = 0; i < render_data->surfaces->length; ++i) { 645 for (i = 0; i < render_data->surfaces->length; ++i) {
565 sway_log(L_DEBUG, "Render surface %d of %d", i, render_data->surfaces->length); 646 sway_log(L_DEBUG, "Render surface %d of %d", i, render_data->surfaces->length);
@@ -609,21 +690,21 @@ void render(struct render_data *render_data) {
609 switch (render_data->auth_state) { 690 switch (render_data->auth_state) {
610 case AUTH_STATE_INPUT: 691 case AUTH_STATE_INPUT:
611 case AUTH_STATE_BACKSPACE: { 692 case AUTH_STATE_BACKSPACE: {
612 cairo_set_source_rgba(window->cairo, 0, 0, 0, 0.75); 693 cairo_set_source_u32(window->cairo, config->colors.normal.inner_ring);
613 cairo_fill_preserve(window->cairo); 694 cairo_fill_preserve(window->cairo);
614 cairo_set_source_rgb(window->cairo, 51.0 / 255, 125.0 / 255, 0); 695 cairo_set_source_u32(window->cairo, config->colors.normal.outer_ring);
615 cairo_stroke(window->cairo); 696 cairo_stroke(window->cairo);
616 } break; 697 } break;
617 case AUTH_STATE_VALIDATING: { 698 case AUTH_STATE_VALIDATING: {
618 cairo_set_source_rgba(window->cairo, 0, 114.0 / 255, 255.0 / 255, 0.75); 699 cairo_set_source_u32(window->cairo, config->colors.validating.inner_ring);
619 cairo_fill_preserve(window->cairo); 700 cairo_fill_preserve(window->cairo);
620 cairo_set_source_rgb(window->cairo, 51.0 / 255, 0, 250.0 / 255); 701 cairo_set_source_u32(window->cairo, config->colors.validating.outer_ring);
621 cairo_stroke(window->cairo); 702 cairo_stroke(window->cairo);
622 } break; 703 } break;
623 case AUTH_STATE_INVALID: { 704 case AUTH_STATE_INVALID: {
624 cairo_set_source_rgba(window->cairo, 250.0 / 255, 0, 0, 0.75); 705 cairo_set_source_u32(window->cairo, config->colors.invalid.inner_ring);
625 cairo_fill_preserve(window->cairo); 706 cairo_fill_preserve(window->cairo);
626 cairo_set_source_rgb(window->cairo, 125.0 / 255, 51.0 / 255, 0); 707 cairo_set_source_u32(window->cairo, config->colors.invalid.outer_ring);
627 cairo_stroke(window->cairo); 708 cairo_stroke(window->cairo);
628 } break; 709 } break;
629 default: break; 710 default: break;
@@ -631,8 +712,8 @@ void render(struct render_data *render_data) {
631 712
632 // Draw a message 713 // Draw a message
633 char *text = NULL; 714 char *text = NULL;
634 cairo_set_source_rgb(window->cairo, 0, 0, 0); 715 cairo_set_source_u32(window->cairo, config->colors.text);
635 cairo_select_font_face(window->cairo, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); 716 cairo_select_font_face(window->cairo, config->font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
636 cairo_set_font_size(window->cairo, ARC_RADIUS/3.0f); 717 cairo_set_font_size(window->cairo, ARC_RADIUS/3.0f);
637 switch (render_data->auth_state) { 718 switch (render_data->auth_state) {
638 case AUTH_STATE_VALIDATING: 719 case AUTH_STATE_VALIDATING:
@@ -664,14 +745,14 @@ void render(struct render_data *render_data) {
664 highlight_start += (rand() % (int)(M_PI * 100)) / 100.0 + M_PI * 0.5; 745 highlight_start += (rand() % (int)(M_PI * 100)) / 100.0 + M_PI * 0.5;
665 cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_RANGE); 746 cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_RANGE);
666 if (render_data->auth_state == AUTH_STATE_INPUT) { 747 if (render_data->auth_state == AUTH_STATE_INPUT) {
667 cairo_set_source_rgb(window->cairo, 51.0 / 255, 219.0 / 255, 0); 748 cairo_set_source_u32(window->cairo, config->colors.input_cursor);
668 } else { 749 } else {
669 cairo_set_source_rgb(window->cairo, 219.0 / 255, 51.0 / 255, 0); 750 cairo_set_source_u32(window->cairo, config->colors.backspace_cursor);
670 } 751 }
671 cairo_stroke(window->cairo); 752 cairo_stroke(window->cairo);
672 753
673 // Draw borders 754 // Draw borders
674 cairo_set_source_rgb(window->cairo, 0, 0, 0); 755 cairo_set_source_u32(window->cairo, config->colors.separator);
675 cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_BORDER_THICKNESS); 756 cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_BORDER_THICKNESS);
676 cairo_stroke(window->cairo); 757 cairo_stroke(window->cairo);
677 758
@@ -679,8 +760,37 @@ void render(struct render_data *render_data) {
679 cairo_stroke(window->cairo); 760 cairo_stroke(window->cairo);
680 } 761 }
681 762
763 switch(line_source) {
764 case LINE_SOURCE_RING:
765 switch(render_data->auth_state) {
766 case AUTH_STATE_VALIDATING:
767 cairo_set_source_u32(window->cairo, config->colors.validating.outer_ring);
768 break;
769 case AUTH_STATE_INVALID:
770 cairo_set_source_u32(window->cairo, config->colors.invalid.outer_ring);
771 break;
772 default:
773 cairo_set_source_u32(window->cairo, config->colors.normal.outer_ring);
774 }
775 break;
776 case LINE_SOURCE_INSIDE:
777 switch(render_data->auth_state) {
778 case AUTH_STATE_VALIDATING:
779 cairo_set_source_u32(window->cairo, config->colors.validating.inner_ring);
780 break;
781 case AUTH_STATE_INVALID:
782 cairo_set_source_u32(window->cairo, config->colors.invalid.inner_ring);
783 break;
784 default:
785 cairo_set_source_u32(window->cairo, config->colors.normal.inner_ring);
786 break;
787 }
788 break;
789 default:
790 cairo_set_source_u32(window->cairo, config->colors.line);
791 break;
792 }
682 // Draw inner + outer border of the circle 793 // Draw inner + outer border of the circle
683 cairo_set_source_rgb(window->cairo, 0, 0, 0);
684 cairo_set_line_width(window->cairo, 2.0); 794 cairo_set_line_width(window->cairo, 2.0);
685 cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS - ARC_THICKNESS/2, 0, 2*M_PI); 795 cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS - ARC_THICKNESS/2, 0, 2*M_PI);
686 cairo_stroke(window->cairo); 796 cairo_stroke(window->cairo);