diff options
author | 2018-07-18 09:32:03 +1000 | |
---|---|---|
committer | 2018-07-18 09:32:03 +1000 | |
commit | 8ce7e3b44eea0a270ecc35a9da2ae801aaf6bce1 (patch) | |
tree | 6badffb0c6ee33b4e23e914c4c9f9b39a625b5f3 /swaylock/main.c | |
parent | Destroy empty workspace when destroying its output (diff) | |
parent | Merge pull request #2281 from pvsr/X11_click (diff) | |
download | sway-8ce7e3b44eea0a270ecc35a9da2ae801aaf6bce1.tar.gz sway-8ce7e3b44eea0a270ecc35a9da2ae801aaf6bce1.tar.zst sway-8ce7e3b44eea0a270ecc35a9da2ae801aaf6bce1.zip |
Merge branch 'master' into destroy-output-destroy-empty-workspaces
Diffstat (limited to 'swaylock/main.c')
-rw-r--r-- | swaylock/main.c | 462 |
1 files changed, 415 insertions, 47 deletions
diff --git a/swaylock/main.c b/swaylock/main.c index 73c2b5d6..ae5b86b9 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,7 +35,7 @@ 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) { |
@@ -58,7 +59,7 @@ static void daemonize() { | |||
58 | close(fds[1]); | 59 | close(fds[1]); |
59 | uint8_t success; | 60 | uint8_t success; |
60 | if (read(fds[0], &success, 1) != 1 || !success) { | 61 | if (read(fds[0], &success, 1) != 1 || !success) { |
61 | wlr_log(L_ERROR, "Failed to daemonize"); | 62 | wlr_log(WLR_ERROR, "Failed to daemonize"); |
62 | exit(1); | 63 | exit(1); |
63 | } | 64 | } |
64 | close(fds[0]); | 65 | close(fds[0]); |
@@ -89,7 +90,7 @@ static bool surface_is_opaque(struct swaylock_surface *surface) { | |||
89 | if (surface->image) { | 90 | if (surface->image) { |
90 | return cairo_surface_get_content(surface->image) == CAIRO_CONTENT_COLOR; | 91 | return cairo_surface_get_content(surface->image) == CAIRO_CONTENT_COLOR; |
91 | } | 92 | } |
92 | return (surface->state->args.color & 0xff) == 0xff; | 93 | return (surface->state->args.colors.background & 0xff) == 0xff; |
93 | } | 94 | } |
94 | 95 | ||
95 | static void create_layer_surface(struct swaylock_surface *surface) { | 96 | static void create_layer_surface(struct swaylock_surface *surface) { |
@@ -238,7 +239,7 @@ static void handle_xdg_output_logical_position(void *data, | |||
238 | 239 | ||
239 | 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, |
240 | const char *name) { | 241 | const char *name) { |
241 | wlr_log(L_DEBUG, "output name is %s", name); | 242 | wlr_log(WLR_DEBUG, "output name is %s", name); |
242 | struct swaylock_surface *surface = data; | 243 | struct swaylock_surface *surface = data; |
243 | surface->xdg_output = output; | 244 | surface->xdg_output = output; |
244 | surface->output_name = strdup(name); | 245 | surface->output_name = strdup(name); |
@@ -354,10 +355,10 @@ static void load_image(char *arg, struct swaylock_state *state) { | |||
354 | } | 355 | } |
355 | if (exists) { | 356 | if (exists) { |
356 | if (image->output_name) { | 357 | if (image->output_name) { |
357 | wlr_log(L_ERROR, "Multiple images defined for output %s", | 358 | wlr_log(WLR_ERROR, "Multiple images defined for output %s", |
358 | image->output_name); | 359 | image->output_name); |
359 | } else { | 360 | } else { |
360 | wlr_log(L_ERROR, "Multiple default images defined"); | 361 | wlr_log(WLR_ERROR, "Multiple default images defined"); |
361 | } | 362 | } |
362 | } | 363 | } |
363 | 364 | ||
@@ -377,71 +378,232 @@ static void load_image(char *arg, struct swaylock_state *state) { | |||
377 | } | 378 | } |
378 | wl_list_insert(&state->images, &image->link); | 379 | wl_list_insert(&state->images, &image->link); |
379 | state->args.mode = BACKGROUND_MODE_FILL; | 380 | state->args.mode = BACKGROUND_MODE_FILL; |
380 | wlr_log(L_DEBUG, "Loaded image %s for output %s", | 381 | wlr_log(WLR_DEBUG, "Loaded image %s for output %s", |
381 | image->path, image->output_name ? image->output_name : "*"); | 382 | image->path, image->output_name ? image->output_name : "*"); |
382 | } | 383 | } |
383 | 384 | ||
384 | static struct swaylock_state state; | 385 | static void set_default_colors(struct swaylock_colors *colors) { |
386 | colors->background = 0xFFFFFFFF; | ||
387 | colors->bs_highlight = 0xDB3300FF; | ||
388 | colors->key_highlight = 0x33DB00FF; | ||
389 | colors->separator = 0x000000FF; | ||
390 | colors->inside = (struct swaylock_colorset){ | ||
391 | .input = 0x000000C0, | ||
392 | .cleared = 0xE5A445C0, | ||
393 | .verifying = 0x0072FFC0, | ||
394 | .wrong = 0xFA0000C0, | ||
395 | }; | ||
396 | colors->line = (struct swaylock_colorset){ | ||
397 | .input = 0x000000FF, | ||
398 | .cleared = 0x000000FF, | ||
399 | .verifying = 0x000000FF, | ||
400 | .wrong = 0x000000FF, | ||
401 | }; | ||
402 | colors->ring = (struct swaylock_colorset){ | ||
403 | .input = 0x337D00FF, | ||
404 | .cleared = 0xE5A445FF, | ||
405 | .verifying = 0x3300FFFF, | ||
406 | .wrong = 0x7D3300FF, | ||
407 | }; | ||
408 | colors->text = (struct swaylock_colorset){ | ||
409 | .input = 0xE5A445FF, | ||
410 | .cleared = 0x000000FF, | ||
411 | .verifying = 0x000000FF, | ||
412 | .wrong = 0x000000FF, | ||
413 | }; | ||
414 | } | ||
415 | |||
416 | enum line_mode { | ||
417 | LM_LINE, | ||
418 | LM_INSIDE, | ||
419 | LM_RING, | ||
420 | }; | ||
421 | |||
422 | static int parse_options(int argc, char **argv, struct swaylock_state *state, | ||
423 | enum line_mode *line_mode) { | ||
424 | enum long_option_codes { | ||
425 | LO_BS_HL_COLOR = 256, | ||
426 | LO_FONT, | ||
427 | LO_IND_RADIUS, | ||
428 | LO_IND_THICKNESS, | ||
429 | LO_INSIDE_COLOR, | ||
430 | LO_INSIDE_CLEAR_COLOR, | ||
431 | LO_INSIDE_VER_COLOR, | ||
432 | LO_INSIDE_WRONG_COLOR, | ||
433 | LO_KEY_HL_COLOR, | ||
434 | LO_LINE_COLOR, | ||
435 | LO_LINE_CLEAR_COLOR, | ||
436 | LO_LINE_VER_COLOR, | ||
437 | LO_LINE_WRONG_COLOR, | ||
438 | LO_RING_COLOR, | ||
439 | LO_RING_CLEAR_COLOR, | ||
440 | LO_RING_VER_COLOR, | ||
441 | LO_RING_WRONG_COLOR, | ||
442 | LO_SEP_COLOR, | ||
443 | LO_TEXT_COLOR, | ||
444 | LO_TEXT_CLEAR_COLOR, | ||
445 | LO_TEXT_VER_COLOR, | ||
446 | LO_TEXT_WRONG_COLOR, | ||
447 | }; | ||
385 | 448 | ||
386 | int main(int argc, char **argv) { | ||
387 | static struct option long_options[] = { | 449 | static struct option long_options[] = { |
388 | {"help", no_argument, NULL, 'h'}, | 450 | {"config", required_argument, NULL, 'C'}, |
389 | {"color", required_argument, NULL, 'c'}, | 451 | {"color", required_argument, NULL, 'c'}, |
452 | {"ignore-empty-password", no_argument, NULL, 'e'}, | ||
453 | {"daemonize", no_argument, NULL, 'f'}, | ||
454 | {"help", no_argument, NULL, 'h'}, | ||
390 | {"image", required_argument, NULL, 'i'}, | 455 | {"image", required_argument, NULL, 'i'}, |
456 | {"line-uses-inside", no_argument, NULL, 'n'}, | ||
457 | {"socket", required_argument, NULL, 'p'}, | ||
458 | {"line-uses-ring", no_argument, NULL, 'r'}, | ||
391 | {"scaling", required_argument, NULL, 's'}, | 459 | {"scaling", required_argument, NULL, 's'}, |
392 | {"tiling", no_argument, NULL, 't'}, | 460 | {"tiling", no_argument, NULL, 't'}, |
393 | {"version", no_argument, NULL, 'v'}, | ||
394 | {"socket", required_argument, NULL, 'p'}, | ||
395 | {"no-unlock-indicator", no_argument, NULL, 'u'}, | 461 | {"no-unlock-indicator", no_argument, NULL, 'u'}, |
396 | {"daemonize", no_argument, NULL, 'f'}, | 462 | {"version", no_argument, NULL, 'v'}, |
463 | {"bs-hl-color", required_argument, NULL, LO_BS_HL_COLOR}, | ||
464 | {"font", required_argument, NULL, LO_FONT}, | ||
465 | {"indicator-radius", required_argument, NULL, LO_IND_RADIUS}, | ||
466 | {"indicator-thickness", required_argument, NULL, LO_IND_THICKNESS}, | ||
467 | {"inside-color", required_argument, NULL, LO_INSIDE_COLOR}, | ||
468 | {"inside-clear-color", required_argument, NULL, LO_INSIDE_CLEAR_COLOR}, | ||
469 | {"inside-ver-color", required_argument, NULL, LO_INSIDE_VER_COLOR}, | ||
470 | {"inside-wrong-color", required_argument, NULL, LO_INSIDE_WRONG_COLOR}, | ||
471 | {"key-hl-color", required_argument, NULL, LO_KEY_HL_COLOR}, | ||
472 | {"line-color", required_argument, NULL, LO_LINE_COLOR}, | ||
473 | {"line-clear-color", required_argument, NULL, LO_LINE_CLEAR_COLOR}, | ||
474 | {"line-ver-color", required_argument, NULL, LO_LINE_VER_COLOR}, | ||
475 | {"line-wrong-color", required_argument, NULL, LO_LINE_WRONG_COLOR}, | ||
476 | {"ring-color", required_argument, NULL, LO_RING_COLOR}, | ||
477 | {"ring-clear-color", required_argument, NULL, LO_RING_CLEAR_COLOR}, | ||
478 | {"ring-ver-color", required_argument, NULL, LO_RING_VER_COLOR}, | ||
479 | {"ring-wrong-color", required_argument, NULL, LO_RING_WRONG_COLOR}, | ||
480 | {"separator-color", required_argument, NULL, LO_SEP_COLOR}, | ||
481 | {"text-color", required_argument, NULL, LO_TEXT_COLOR}, | ||
482 | {"text-clear-color", required_argument, NULL, LO_TEXT_CLEAR_COLOR}, | ||
483 | {"text-ver-color", required_argument, NULL, LO_TEXT_VER_COLOR}, | ||
484 | {"text-wrong-color", required_argument, NULL, LO_TEXT_WRONG_COLOR}, | ||
397 | {0, 0, 0, 0} | 485 | {0, 0, 0, 0} |
398 | }; | 486 | }; |
399 | 487 | ||
400 | const char usage[] = | 488 | const char usage[] = |
401 | "Usage: swaylock [options...]\n" | 489 | "Usage: swaylock [options...]\n" |
402 | "\n" | 490 | "\n" |
403 | " -h, --help Show help message and quit.\n" | 491 | " -C, --config <config_file> " |
404 | " -c, --color <rrggbb[aa]> Turn the screen into the given color instead of white.\n" | 492 | "Path to the config file.\n" |
405 | " -s, --scaling Scaling mode: stretch, fill, fit, center, tile.\n" | 493 | " -c, --color <color> " |
406 | " -t, --tiling Same as --scaling=tile.\n" | 494 | "Turn the screen into the given color instead of white.\n" |
407 | " -v, --version Show the version number and quit.\n" | 495 | " -e, --ignore-empty-password " |
408 | " -i, --image [<output>:]<path> Display the given image.\n" | 496 | "When an empty password is provided, do not validate it.\n" |
409 | " -u, --no-unlock-indicator Disable the unlock indicator.\n" | 497 | " -f, --daemonize " |
410 | " -f, --daemonize Detach from the controlling terminal after locking.\n"; | 498 | "Detach from the controlling terminal after locking.\n" |
411 | 499 | " -h, --help " | |
412 | state.args = (struct swaylock_args){ | 500 | "Show help message and quit.\n" |
413 | .mode = BACKGROUND_MODE_SOLID_COLOR, | 501 | " -i, --image [<output>:]<path> " |
414 | .color = 0xFFFFFFFF, | 502 | "Display the given image.\n" |
415 | .show_indicator = true, | 503 | " -s, --scaling <mode> " |
416 | }; | 504 | "Scaling mode: stretch, fill, fit, center, tile.\n" |
417 | wl_list_init(&state.images); | 505 | " -t, --tiling " |
418 | 506 | "Same as --scaling=tile.\n" | |
419 | wlr_log_init(L_DEBUG, NULL); | 507 | " -u, --no-unlock-indicator " |
508 | "Disable the unlock indicator.\n" | ||
509 | " -v, --version " | ||
510 | "Show the version number and quit.\n" | ||
511 | " --bs-hl-color <color> " | ||
512 | "Sets the color of backspace highlight segments.\n" | ||
513 | " --font <font> " | ||
514 | "Sets the font of the text.\n" | ||
515 | " --indicator-radius <radius> " | ||
516 | "Sets the indicator radius.\n" | ||
517 | " --indicator-thickness <thick> " | ||
518 | "Sets the indicator thickness.\n" | ||
519 | " --inside-color <color> " | ||
520 | "Sets the color of the inside of the indicator.\n" | ||
521 | " --inside-clear-color <color> " | ||
522 | "Sets the color of the inside of the indicator when cleared.\n" | ||
523 | " --inside-ver-color <color> " | ||
524 | "Sets the color of the inside of the indicator when verifying.\n" | ||
525 | " --inside-wrong-color <color> " | ||
526 | "Sets the color of the inside of the indicator when invalid.\n" | ||
527 | " --key-hl-color <color> " | ||
528 | "Sets the color of the key press highlight segments.\n" | ||
529 | " --line-color <color> " | ||
530 | "Sets the color of the line between the inside and ring.\n" | ||
531 | " --line-clear-color <color> " | ||
532 | "Sets the color of the line between the inside and ring when " | ||
533 | "cleared.\n" | ||
534 | " --line-ver-color <color> " | ||
535 | "Sets the color of the line between the inside and ring when " | ||
536 | "verifying.\n" | ||
537 | " --line-wrong-color <color> " | ||
538 | "Sets the color of the line between the inside and ring when " | ||
539 | "invalid.\n" | ||
540 | " -n, --line-uses-inside " | ||
541 | "Use the inside color for the line between the inside and ring.\n" | ||
542 | " -r, --line-uses-ring " | ||
543 | "Use the ring color for the line between the inside and ring.\n" | ||
544 | " --ring-color <color> " | ||
545 | "Sets the color of the ring of the indicator.\n" | ||
546 | " --ring-clear-color <color> " | ||
547 | "Sets the color of the ring of the indicator when cleared.\n" | ||
548 | " --ring-ver-color <color> " | ||
549 | "Sets the color of the ring of the indicator when verifying.\n" | ||
550 | " --ring-wrong-color <color> " | ||
551 | "Sets the color of the ring of the indicator when invalid.\n" | ||
552 | " --separator-color <color> " | ||
553 | "Sets the color of the lines that separate highlight segments.\n" | ||
554 | " --text-color <color> " | ||
555 | "Sets the color of the text.\n" | ||
556 | " --text-clear-color <color> " | ||
557 | "Sets the color of the text when cleared.\n" | ||
558 | " --text-ver-color <color> " | ||
559 | "Sets the color of the text when verifying.\n" | ||
560 | " --text-wrong-color <color> " | ||
561 | "Sets the color of the text when invalid.\n" | ||
562 | "\n" | ||
563 | "All <color> options are of the form <rrggbb[aa]>.\n"; | ||
420 | 564 | ||
421 | int c; | 565 | int c; |
566 | optind = 1; | ||
422 | while (1) { | 567 | while (1) { |
423 | int option_index = 0; | 568 | int opt_idx = 0; |
424 | c = getopt_long(argc, argv, "hc:i:s:tvuf", long_options, &option_index); | 569 | c = getopt_long(argc, argv, "c:efhi:nrs:tuvC:", long_options, &opt_idx); |
425 | if (c == -1) { | 570 | if (c == -1) { |
426 | break; | 571 | break; |
427 | } | 572 | } |
428 | switch (c) { | 573 | switch (c) { |
429 | case 'c': { | 574 | case 'C': |
430 | state.args.color = parse_color(optarg); | 575 | // Config file. This will have already been handled so just ignore. |
431 | state.args.mode = BACKGROUND_MODE_SOLID_COLOR; | 576 | break; |
577 | case 'c': | ||
578 | state->args.colors.background = parse_color(optarg); | ||
579 | state->args.mode = BACKGROUND_MODE_SOLID_COLOR; | ||
580 | break; | ||
581 | case 'e': | ||
582 | state->args.ignore_empty = true; | ||
583 | break; | ||
584 | case 'f': | ||
585 | state->args.daemonize = true; | ||
432 | break; | 586 | break; |
433 | } | ||
434 | case 'i': | 587 | case 'i': |
435 | load_image(optarg, &state); | 588 | load_image(optarg, state); |
589 | break; | ||
590 | case 'n': | ||
591 | *line_mode = LM_INSIDE; | ||
592 | break; | ||
593 | case 'r': | ||
594 | *line_mode = LM_RING; | ||
436 | break; | 595 | break; |
437 | case 's': | 596 | case 's': |
438 | state.args.mode = parse_background_mode(optarg); | 597 | state->args.mode = parse_background_mode(optarg); |
439 | if (state.args.mode == BACKGROUND_MODE_INVALID) { | 598 | if (state->args.mode == BACKGROUND_MODE_INVALID) { |
440 | return 1; | 599 | return 1; |
441 | } | 600 | } |
442 | break; | 601 | break; |
443 | case 't': | 602 | case 't': |
444 | state.args.mode = BACKGROUND_MODE_TILE; | 603 | state->args.mode = BACKGROUND_MODE_TILE; |
604 | break; | ||
605 | case 'u': | ||
606 | state->args.show_indicator = false; | ||
445 | break; | 607 | break; |
446 | case 'v': | 608 | case 'v': |
447 | #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE | 609 | #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE |
@@ -451,11 +613,72 @@ int main(int argc, char **argv) { | |||
451 | fprintf(stdout, "version unknown\n"); | 613 | fprintf(stdout, "version unknown\n"); |
452 | #endif | 614 | #endif |
453 | return 0; | 615 | return 0; |
454 | case 'u': | 616 | case LO_BS_HL_COLOR: |
455 | state.args.show_indicator = false; | 617 | state->args.colors.bs_highlight = parse_color(optarg); |
456 | break; | 618 | break; |
457 | case 'f': | 619 | case LO_FONT: |
458 | state.args.daemonize = true; | 620 | free(state->args.font); |
621 | state->args.font = strdup(optarg); | ||
622 | break; | ||
623 | case LO_IND_RADIUS: | ||
624 | state->args.radius = strtol(optarg, NULL, 0); | ||
625 | break; | ||
626 | case LO_IND_THICKNESS: | ||
627 | state->args.thickness = strtol(optarg, NULL, 0); | ||
628 | break; | ||
629 | case LO_INSIDE_COLOR: | ||
630 | state->args.colors.inside.input = parse_color(optarg); | ||
631 | break; | ||
632 | case LO_INSIDE_CLEAR_COLOR: | ||
633 | state->args.colors.inside.cleared = parse_color(optarg); | ||
634 | break; | ||
635 | case LO_INSIDE_VER_COLOR: | ||
636 | state->args.colors.inside.verifying = parse_color(optarg); | ||
637 | break; | ||
638 | case LO_INSIDE_WRONG_COLOR: | ||
639 | state->args.colors.inside.wrong = parse_color(optarg); | ||
640 | break; | ||
641 | case LO_KEY_HL_COLOR: | ||
642 | state->args.colors.key_highlight = parse_color(optarg); | ||
643 | break; | ||
644 | case LO_LINE_COLOR: | ||
645 | state->args.colors.line.input = parse_color(optarg); | ||
646 | break; | ||
647 | case LO_LINE_CLEAR_COLOR: | ||
648 | state->args.colors.line.cleared = parse_color(optarg); | ||
649 | break; | ||
650 | case LO_LINE_VER_COLOR: | ||
651 | state->args.colors.line.verifying = parse_color(optarg); | ||
652 | break; | ||
653 | case LO_LINE_WRONG_COLOR: | ||
654 | state->args.colors.line.wrong = parse_color(optarg); | ||
655 | break; | ||
656 | case LO_RING_COLOR: | ||
657 | state->args.colors.ring.input = parse_color(optarg); | ||
658 | break; | ||
659 | case LO_RING_CLEAR_COLOR: | ||
660 | state->args.colors.ring.cleared = parse_color(optarg); | ||
661 | break; | ||
662 | case LO_RING_VER_COLOR: | ||
663 | state->args.colors.ring.verifying = parse_color(optarg); | ||
664 | break; | ||
665 | case LO_RING_WRONG_COLOR: | ||
666 | state->args.colors.ring.wrong = parse_color(optarg); | ||
667 | break; | ||
668 | case LO_SEP_COLOR: | ||
669 | state->args.colors.separator = parse_color(optarg); | ||
670 | break; | ||
671 | case LO_TEXT_COLOR: | ||
672 | state->args.colors.text.input = parse_color(optarg); | ||
673 | break; | ||
674 | case LO_TEXT_CLEAR_COLOR: | ||
675 | state->args.colors.text.cleared = parse_color(optarg); | ||
676 | break; | ||
677 | case LO_TEXT_VER_COLOR: | ||
678 | state->args.colors.text.verifying = parse_color(optarg); | ||
679 | break; | ||
680 | case LO_TEXT_WRONG_COLOR: | ||
681 | state->args.colors.text.wrong = parse_color(optarg); | ||
459 | break; | 682 | break; |
460 | default: | 683 | default: |
461 | fprintf(stderr, "%s", usage); | 684 | fprintf(stderr, "%s", usage); |
@@ -463,6 +686,149 @@ int main(int argc, char **argv) { | |||
463 | } | 686 | } |
464 | } | 687 | } |
465 | 688 | ||
689 | return 0; | ||
690 | } | ||
691 | |||
692 | static bool file_exists(const char *path) { | ||
693 | return path && access(path, R_OK) != -1; | ||
694 | } | ||
695 | |||
696 | static char *get_config_path(void) { | ||
697 | static const char *config_paths[] = { | ||
698 | "$HOME/.swaylock/config", | ||
699 | "$XDG_CONFIG_HOME/swaylock/config", | ||
700 | SYSCONFDIR "/swaylock/config", | ||
701 | }; | ||
702 | |||
703 | if (!getenv("XDG_CONFIG_HOME")) { | ||
704 | char *home = getenv("HOME"); | ||
705 | char *config_home = malloc(strlen(home) + strlen("/.config") + 1); | ||
706 | if (!config_home) { | ||
707 | wlr_log(WLR_ERROR, "Unable to allocate $HOME/.config"); | ||
708 | } else { | ||
709 | strcpy(config_home, home); | ||
710 | strcat(config_home, "/.config"); | ||
711 | setenv("XDG_CONFIG_HOME", config_home, 1); | ||
712 | wlr_log(WLR_DEBUG, "Set XDG_CONFIG_HOME to %s", config_home); | ||
713 | free(config_home); | ||
714 | } | ||
715 | } | ||
716 | |||
717 | wordexp_t p; | ||
718 | char *path; | ||
719 | for (size_t i = 0; i < sizeof(config_paths) / sizeof(char *); ++i) { | ||
720 | if (wordexp(config_paths[i], &p, 0) == 0) { | ||
721 | path = strdup(p.we_wordv[0]); | ||
722 | wordfree(&p); | ||
723 | if (file_exists(path)) { | ||
724 | return path; | ||
725 | } | ||
726 | free(path); | ||
727 | } | ||
728 | } | ||
729 | |||
730 | return NULL; | ||
731 | } | ||
732 | |||
733 | static int load_config(char *path, struct swaylock_state *state, | ||
734 | enum line_mode *line_mode) { | ||
735 | FILE *config = fopen(path, "r"); | ||
736 | if (!config) { | ||
737 | wlr_log(WLR_ERROR, "Failed to read config. Running without it."); | ||
738 | return 0; | ||
739 | } | ||
740 | char *line; | ||
741 | int line_number = 0; | ||
742 | while (!feof(config)) { | ||
743 | line = read_line(config); | ||
744 | if (!line) { | ||
745 | continue; | ||
746 | } | ||
747 | |||
748 | line_number++; | ||
749 | if (line[0] == '#') { | ||
750 | free(line); | ||
751 | continue; | ||
752 | } | ||
753 | if (strlen(line) == 0) { | ||
754 | free(line); | ||
755 | continue; | ||
756 | } | ||
757 | |||
758 | wlr_log(WLR_DEBUG, "Config Line #%d: %s", line_number, line); | ||
759 | char flag[strlen(line) + 3]; | ||
760 | sprintf(flag, "--%s", line); | ||
761 | char *argv[] = {"swaylock", flag}; | ||
762 | int result = parse_options(2, argv, state, line_mode); | ||
763 | if (result != 0) { | ||
764 | free(line); | ||
765 | fclose(config); | ||
766 | return result; | ||
767 | } | ||
768 | free(line); | ||
769 | } | ||
770 | fclose(config); | ||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | static struct swaylock_state state; | ||
775 | |||
776 | int main(int argc, char **argv) { | ||
777 | enum line_mode line_mode = LM_LINE; | ||
778 | state.args = (struct swaylock_args){ | ||
779 | .mode = BACKGROUND_MODE_SOLID_COLOR, | ||
780 | .font = strdup("sans-serif"), | ||
781 | .radius = 50, | ||
782 | .thickness = 10, | ||
783 | .ignore_empty = false, | ||
784 | .show_indicator = true, | ||
785 | }; | ||
786 | wl_list_init(&state.images); | ||
787 | set_default_colors(&state.args.colors); | ||
788 | |||
789 | wlr_log_init(WLR_DEBUG, NULL); | ||
790 | |||
791 | char *config_path = NULL; | ||
792 | static struct option long_options[] = { | ||
793 | {"config", required_argument, NULL, 'C'}, | ||
794 | {0, 0, 0, 0}, | ||
795 | }; | ||
796 | while (1) { | ||
797 | int c = getopt_long(argc, argv, "C:", long_options, NULL); | ||
798 | if (c == -1) { | ||
799 | break; | ||
800 | } else if (c == 'C') { | ||
801 | config_path = strdup(optarg); | ||
802 | break; | ||
803 | } | ||
804 | } | ||
805 | if (!config_path) { | ||
806 | config_path = get_config_path(); | ||
807 | } | ||
808 | |||
809 | if (config_path) { | ||
810 | wlr_log(WLR_DEBUG, "Found config at %s", config_path); | ||
811 | int config_status = load_config(config_path, &state, &line_mode); | ||
812 | free(config_path); | ||
813 | if (config_status != 0) { | ||
814 | return config_status; | ||
815 | } | ||
816 | } | ||
817 | |||
818 | if (argc > 1) { | ||
819 | wlr_log(WLR_DEBUG, "Parsing CLI Args"); | ||
820 | int result = parse_options(argc, argv, &state, &line_mode); | ||
821 | if (result != 0) { | ||
822 | return result; | ||
823 | } | ||
824 | } | ||
825 | |||
826 | if (line_mode == LM_INSIDE) { | ||
827 | state.args.colors.line = state.args.colors.inside; | ||
828 | } else if (line_mode == LM_RING) { | ||
829 | state.args.colors.line = state.args.colors.ring; | ||
830 | } | ||
831 | |||
466 | #ifdef __linux__ | 832 | #ifdef __linux__ |
467 | // Most non-linux platforms require root to mlock() | 833 | // Most non-linux platforms require root to mlock() |
468 | if (mlock(state.password.buffer, sizeof(state.password.buffer)) != 0) { | 834 | if (mlock(state.password.buffer, sizeof(state.password.buffer)) != 0) { |
@@ -480,13 +846,13 @@ int main(int argc, char **argv) { | |||
480 | wl_display_roundtrip(state.display); | 846 | wl_display_roundtrip(state.display); |
481 | assert(state.compositor && state.layer_shell && state.shm); | 847 | assert(state.compositor && state.layer_shell && state.shm); |
482 | if (!state.input_inhibit_manager) { | 848 | if (!state.input_inhibit_manager) { |
483 | wlr_log(L_ERROR, "Compositor does not support the input inhibitor " | 849 | wlr_log(WLR_ERROR, "Compositor does not support the input inhibitor " |
484 | "protocol, refusing to run insecurely"); | 850 | "protocol, refusing to run insecurely"); |
485 | return 1; | 851 | return 1; |
486 | } | 852 | } |
487 | 853 | ||
488 | if (wl_list_empty(&state.surfaces)) { | 854 | if (wl_list_empty(&state.surfaces)) { |
489 | wlr_log(L_DEBUG, "Exiting - no outputs to show on."); | 855 | wlr_log(WLR_DEBUG, "Exiting - no outputs to show on."); |
490 | return 0; | 856 | return 0; |
491 | } | 857 | } |
492 | 858 | ||
@@ -502,7 +868,7 @@ int main(int argc, char **argv) { | |||
502 | } | 868 | } |
503 | wl_display_roundtrip(state.display); | 869 | wl_display_roundtrip(state.display); |
504 | } else { | 870 | } else { |
505 | wlr_log(L_INFO, "Compositor does not support zxdg output manager, " | 871 | wlr_log(WLR_INFO, "Compositor does not support zxdg output manager, " |
506 | "images assigned to named outputs will not work"); | 872 | "images assigned to named outputs will not work"); |
507 | } | 873 | } |
508 | 874 | ||
@@ -520,5 +886,7 @@ int main(int argc, char **argv) { | |||
520 | while (wl_display_dispatch(state.display) != -1 && state.run_display) { | 886 | while (wl_display_dispatch(state.display) != -1 && state.run_display) { |
521 | // This space intentionally left blank | 887 | // This space intentionally left blank |
522 | } | 888 | } |
889 | |||
890 | free(state.args.font); | ||
523 | return 0; | 891 | return 0; |
524 | } | 892 | } |