|
| 1 | +#define WOB_DEFAULT_WIDTH 400 |
| 2 | +#define WOB_DEFAULT_HEIGHT 50 |
| 3 | +#define WOB_DEFAULT_BORDER_OFFSET 4 |
| 4 | +#define WOB_DEFAULT_BORDER_SIZE 4 |
| 5 | +#define WOB_DEFAULT_BAR_PADDING 4 |
| 6 | +#define WOB_DEFAULT_ANCHOR 0 |
| 7 | +#define WOB_DEFAULT_MARGIN 0 |
| 8 | +#define WOB_DEFAULT_MAXIMUM 100 |
| 9 | +#define WOB_DEFAULT_TIMEOUT 1000 |
| 10 | +#define WOB_DEFAULT_BAR_COLOR 0xFFFFFFFF |
| 11 | +#define WOB_DEFAULT_BACKGROUND_COLOR 0xFF000000 |
| 12 | +#define WOB_DEFAULT_BORDER_COLOR 0xFFFFFFFF |
| 13 | + |
| 14 | +#define MIN_PERCENTAGE_BAR_WIDTH 1 |
| 15 | +#define MIN_PERCENTAGE_BAR_HEIGHT 1 |
| 16 | + |
| 17 | +#define STR(x) #x |
| 18 | + |
1 | 19 | // sizeof already includes NULL byte
|
2 | 20 | #define INPUT_BUFFER_LENGTH (3 * sizeof(unsigned long) + sizeof(" #FF000000 #FFFFFFFF #FFFFFFFF\n"))
|
3 | 21 |
|
4 | 22 | #define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
5 | 23 |
|
6 | 24 | #define _POSIX_C_SOURCE 200809L
|
7 | 25 | #include <errno.h>
|
| 26 | +#include <getopt.h> |
| 27 | +#include <limits.h> |
8 | 28 | #include <poll.h>
|
9 | 29 | #include <stdbool.h>
|
10 | 30 | #include <stdio.h>
|
|
13 | 33 | #include <unistd.h>
|
14 | 34 |
|
15 | 35 | #include "buffer.h"
|
16 |
| -#include "options.h" |
17 | 36 | #include "parse.h"
|
18 | 37 | #include "pledge.h"
|
19 | 38 | #include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
@@ -437,51 +456,205 @@ wob_draw_percentage(const struct wob_geom *geom, uint32_t *argb, uint32_t bar_co
|
437 | 456 | int
|
438 | 457 | main(int argc, char **argv)
|
439 | 458 | {
|
440 |
| - struct wob_options options; |
441 |
| - if (!wob_getopt(argc, argv, &options)) { |
442 |
| - return EXIT_FAILURE; |
443 |
| - } |
| 459 | + const char *usage = |
| 460 | + "Usage: wob [options]\n" |
| 461 | + "\n" |
| 462 | + " -h, --help Show help message and quit.\n" |
| 463 | + " -v, --version Show the version number and quit.\n" |
| 464 | + " -t, --timeout <ms> Hide wob after <ms> milliseconds, defaults to " STR(WOB_DEFAULT_TIMEOUT) ".\n" |
| 465 | + " -m, --max <%> Define the maximum percentage, defaults to " STR(WOB_DEFAULT_MAXIMUM) ". \n" |
| 466 | + " -W, --width <px> Define bar width in pixels, defaults to " STR(WOB_DEFAULT_WIDTH) ". \n" |
| 467 | + " -H, --height <px> Define bar height in pixels, defaults to " STR(WOB_DEFAULT_HEIGHT) ". \n" |
| 468 | + " -o, --offset <px> Define border offset in pixels, defaults to " STR(WOB_DEFAULT_BORDER_OFFSET) ". \n" |
| 469 | + " -b, --border <px> Define border size in pixels, defaults to " STR(WOB_DEFAULT_BORDER_SIZE) ". \n" |
| 470 | + " -p, --padding <px> Define bar padding in pixels, defaults to " STR(WOB_DEFAULT_BAR_PADDING) ". \n" |
| 471 | + " -a, --anchor <s> Define anchor point; one of 'top', 'left', 'right', 'bottom', 'center' (default). \n" |
| 472 | + " May be specified multiple times. \n" |
| 473 | + " -M, --margin <px> Define anchor margin in pixels, defaults to " STR(WOB_DEFAULT_MARGIN) ". \n" |
| 474 | + " -O, --output <name> Define output to show bar on or '*' for all. If ommited, focused output is chosen.\n" |
| 475 | + " May be specified multiple times.\n" |
| 476 | + " --border-color <#argb> Define border color\n" |
| 477 | + " --background-color <#argb> Define background color\n" |
| 478 | + " --bar-color <#argb> Define bar color\n" |
| 479 | + "\n"; |
444 | 480 |
|
445 | 481 | struct wob app = {0};
|
446 | 482 | wl_list_init(&(app.output_configs));
|
447 | 483 |
|
448 |
| - unsigned long maximum = options.maximum; |
449 |
| - unsigned long timeout_msec = options.timeout_msec; |
| 484 | + unsigned long maximum = WOB_DEFAULT_MAXIMUM; |
| 485 | + unsigned long timeout_msec = WOB_DEFAULT_TIMEOUT; |
450 | 486 | struct wob_geom geom = {
|
451 |
| - .width = options.bar_width, |
452 |
| - .height = options.bar_height, |
453 |
| - .border_offset = options.border_offset, |
454 |
| - .border_size = options.border_size, |
455 |
| - .bar_padding = options.bar_padding, |
456 |
| - .anchor = options.bar_anchor, |
457 |
| - .margin = options.bar_margin, |
| 487 | + .width = WOB_DEFAULT_WIDTH, |
| 488 | + .height = WOB_DEFAULT_HEIGHT, |
| 489 | + .border_offset = WOB_DEFAULT_BORDER_OFFSET, |
| 490 | + .border_size = WOB_DEFAULT_BORDER_SIZE, |
| 491 | + .bar_padding = WOB_DEFAULT_BAR_PADDING, |
| 492 | + .anchor = WOB_DEFAULT_ANCHOR, |
| 493 | + .margin = WOB_DEFAULT_MARGIN, |
458 | 494 | };
|
459 | 495 | struct wob_colors colors = {
|
460 |
| - .background = options.background_color, |
461 |
| - .bar = options.bar_color, |
462 |
| - .border = options.border_color, |
| 496 | + .background = WOB_DEFAULT_BACKGROUND_COLOR, |
| 497 | + .bar = WOB_DEFAULT_BAR_COLOR, |
| 498 | + .border = WOB_DEFAULT_BORDER_COLOR, |
463 | 499 | };
|
464 |
| - bool pledge = options.pledge; |
| 500 | + bool pledge = true; |
| 501 | + |
| 502 | + char *disable_pledge_env = getenv("WOB_DISABLE_PLEDGE"); |
| 503 | + if (disable_pledge_env != NULL && strcmp(disable_pledge_env, "0") != 0) { |
| 504 | + pledge = false; |
| 505 | + } |
465 | 506 |
|
466 |
| - struct wob_output_name *output_name, *output_name_tmp; |
467 | 507 | struct wob_output_config *output_config;
|
468 |
| - wl_list_for_each_safe (output_name, output_name_tmp, &options.outputs, link) { |
469 |
| - output_config = calloc(1, sizeof(struct wob_output_config)); |
470 |
| - if (output_config == NULL) { |
471 |
| - fprintf(stderr, "calloc failed\n"); |
472 |
| - return EXIT_FAILURE; |
473 |
| - } |
| 508 | + int option_index = 0; |
| 509 | + int c; |
| 510 | + char *strtoul_end; |
| 511 | + static struct option long_options[] = { |
| 512 | + {"help", no_argument, NULL, 'h'}, |
| 513 | + {"version", no_argument, NULL, 'v'}, |
| 514 | + {"timeout", required_argument, NULL, 't'}, |
| 515 | + {"max", required_argument, NULL, 'm'}, |
| 516 | + {"width", required_argument, NULL, 'W'}, |
| 517 | + {"height", required_argument, NULL, 'H'}, |
| 518 | + {"offset", required_argument, NULL, 'o'}, |
| 519 | + {"border", required_argument, NULL, 'b'}, |
| 520 | + {"padding", required_argument, NULL, 'p'}, |
| 521 | + {"anchor", required_argument, NULL, 'a'}, |
| 522 | + {"margin", required_argument, NULL, 'M'}, |
| 523 | + {"output", required_argument, NULL, 'O'}, |
| 524 | + {"border-color", required_argument, NULL, 1}, |
| 525 | + {"background-color", required_argument, NULL, 2}, |
| 526 | + {"bar-color", required_argument, NULL, 3}, |
| 527 | + }; |
| 528 | + while ((c = getopt_long(argc, argv, "t:m:W:H:o:b:p:a:M:O:vh", long_options, &option_index)) != -1) { |
| 529 | + switch (c) { |
| 530 | + case 1: |
| 531 | + if (!wob_parse_color(optarg, &strtoul_end, &(colors.border))) { |
| 532 | + fprintf(stderr, "Border color must be a value between #00000000 and #FFFFFFFF.\n"); |
| 533 | + return EXIT_FAILURE; |
| 534 | + } |
| 535 | + break; |
| 536 | + case 2: |
| 537 | + if (!wob_parse_color(optarg, &strtoul_end, &(colors.background))) { |
| 538 | + fprintf(stderr, "Background color must be a value between #00000000 and #FFFFFFFF.\n"); |
| 539 | + return EXIT_FAILURE; |
| 540 | + } |
| 541 | + break; |
| 542 | + case 3: |
| 543 | + if (!wob_parse_color(optarg, &strtoul_end, &(colors.bar))) { |
| 544 | + fprintf(stderr, "Bar color must be a value between #00000000 and #FFFFFFFF.\n"); |
| 545 | + return EXIT_FAILURE; |
| 546 | + } |
| 547 | + break; |
| 548 | + case 't': |
| 549 | + timeout_msec = strtoul(optarg, &strtoul_end, 10); |
| 550 | + if (*strtoul_end != '\0' || errno == ERANGE || timeout_msec == 0) { |
| 551 | + fprintf(stderr, "Timeout must be a value between 1 and %lu.\n", ULONG_MAX); |
| 552 | + return EXIT_FAILURE; |
| 553 | + } |
| 554 | + break; |
| 555 | + case 'm': |
| 556 | + maximum = strtoul(optarg, &strtoul_end, 10); |
| 557 | + if (*strtoul_end != '\0' || errno == ERANGE || maximum == 0) { |
| 558 | + fprintf(stderr, "Maximum must be a value between 1 and %lu.\n", ULONG_MAX); |
| 559 | + return EXIT_FAILURE; |
| 560 | + } |
| 561 | + break; |
| 562 | + case 'W': |
| 563 | + geom.width = strtoul(optarg, &strtoul_end, 10); |
| 564 | + if (*strtoul_end != '\0' || errno == ERANGE) { |
| 565 | + fprintf(stderr, "Width must be a positive value."); |
| 566 | + return EXIT_FAILURE; |
| 567 | + } |
| 568 | + break; |
| 569 | + case 'H': |
| 570 | + geom.height = strtoul(optarg, &strtoul_end, 10); |
| 571 | + if (*strtoul_end != '\0' || errno == ERANGE) { |
| 572 | + fprintf(stderr, "Height must be a positive value."); |
| 573 | + return EXIT_FAILURE; |
| 574 | + } |
| 575 | + break; |
| 576 | + case 'o': |
| 577 | + geom.border_offset = strtoul(optarg, &strtoul_end, 10); |
| 578 | + if (*strtoul_end != '\0' || errno == ERANGE) { |
| 579 | + fprintf(stderr, "Border offset must be a positive value."); |
| 580 | + return EXIT_FAILURE; |
| 581 | + } |
| 582 | + break; |
| 583 | + case 'b': |
| 584 | + geom.border_size = strtoul(optarg, &strtoul_end, 10); |
| 585 | + if (*strtoul_end != '\0' || errno == ERANGE) { |
| 586 | + fprintf(stderr, "Border size must be a positive value."); |
| 587 | + return EXIT_FAILURE; |
| 588 | + } |
| 589 | + break; |
| 590 | + case 'p': |
| 591 | + geom.bar_padding = strtoul(optarg, &strtoul_end, 10); |
| 592 | + if (*strtoul_end != '\0' || errno == ERANGE) { |
| 593 | + fprintf(stderr, "Bar padding must be a positive value."); |
| 594 | + return EXIT_FAILURE; |
| 595 | + } |
| 596 | + break; |
| 597 | + case 'a': |
| 598 | + if (strcmp(optarg, "left") == 0) { |
| 599 | + geom.anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; |
| 600 | + } |
| 601 | + else if (strcmp(optarg, "right") == 0) { |
| 602 | + geom.anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; |
| 603 | + } |
| 604 | + else if (strcmp(optarg, "top") == 0) { |
| 605 | + geom.anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; |
| 606 | + } |
| 607 | + else if (strcmp(optarg, "bottom") == 0) { |
| 608 | + geom.anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; |
| 609 | + } |
| 610 | + else if (strcmp(optarg, "center") != 0) { |
| 611 | + fprintf(stderr, "Anchor must be one of 'top', 'bottom', 'left', 'right', 'center'."); |
| 612 | + return EXIT_FAILURE; |
| 613 | + } |
| 614 | + break; |
| 615 | + case 'M': |
| 616 | + geom.margin = strtoul(optarg, &strtoul_end, 10); |
| 617 | + if (*strtoul_end != '\0' || errno == ERANGE) { |
| 618 | + fprintf(stderr, "Anchor margin must be a positive value."); |
| 619 | + return EXIT_FAILURE; |
| 620 | + } |
| 621 | + break; |
| 622 | + case 'O': |
| 623 | + output_config = calloc(1, sizeof(struct wob_output_config)); |
| 624 | + if (output_config == NULL) { |
| 625 | + fprintf(stderr, "calloc failed\n"); |
| 626 | + return EXIT_FAILURE; |
| 627 | + } |
474 | 628 |
|
475 |
| - output_config->name = strdup(output_name->name); |
476 |
| - if (output_config->name == NULL) { |
477 |
| - fprintf(stderr, "strdup failed\n"); |
478 |
| - return EXIT_FAILURE; |
| 629 | + output_config->name = strdup(optarg); |
| 630 | + if (output_config->name == NULL) { |
| 631 | + fprintf(stderr, "strdup failed\n"); |
| 632 | + return EXIT_FAILURE; |
| 633 | + } |
| 634 | + |
| 635 | + wl_list_insert(&(app.output_configs), &(output_config->link)); |
| 636 | + break; |
| 637 | + case 'v': |
| 638 | + fprintf(stdout, "wob version: " WOB_VERSION "\n"); |
| 639 | + return EXIT_SUCCESS; |
| 640 | + case 'h': |
| 641 | + fprintf(stdout, "%s", usage); |
| 642 | + return EXIT_SUCCESS; |
| 643 | + default: |
| 644 | + fprintf(stderr, "%s", usage); |
| 645 | + return EXIT_FAILURE; |
479 | 646 | }
|
| 647 | + } |
480 | 648 |
|
481 |
| - wl_list_insert(&(app.output_configs), &(output_config->link)); |
| 649 | + if (geom.width < MIN_PERCENTAGE_BAR_WIDTH + 2 * (geom.border_offset + geom.border_size + geom.bar_padding)) { |
| 650 | + fprintf(stderr, "Invalid geometry: width is too small for given parameters\n"); |
| 651 | + return EXIT_FAILURE; |
482 | 652 | }
|
483 | 653 |
|
484 |
| - wob_options_destroy(&options); |
| 654 | + if (geom.height < MIN_PERCENTAGE_BAR_HEIGHT + 2 * (geom.border_offset + geom.border_size + geom.bar_padding)) { |
| 655 | + fprintf(stderr, "Invalid geometry: height is too small for given parameters\n"); |
| 656 | + return EXIT_FAILURE; |
| 657 | + } |
485 | 658 |
|
486 | 659 | geom.stride = geom.width * 4;
|
487 | 660 | geom.size = geom.stride * geom.height;
|
|
0 commit comments