/* Hacked version of osd_cat to allow display of percentage and slider bars Modifed by Phil Gees (philgees@hotmail.com) Original code by: Andre Renaud Tim Wright Modified without permission. */ #include #include #include #include #include #include #include #include #include #include static struct option long_options[] = { {"help", 0, NULL, 'h'}, {"font", 1, NULL, 'f'}, {"color", 1, NULL, 'c'}, {"colour", 1, NULL, 'c'}, {"indent", 1, NULL, 'i'}, {"delay", 1, NULL, 'd'}, {"offset", 1, NULL, 'o'}, {"pos", 1, NULL, 'p'}, {"xscreen", 1, NULL, 'n'}, {"align", 1, NULL, 'A'}, {"shadow", 1, NULL, 's'}, {"shadowcolour", 1, NULL, 'S'}, {"age", 2, NULL, 'a'}, {"lines", 1, NULL, 'l'}, {"wait", 0, NULL, 'w'}, {"outline", 1, NULL, 'O'}, {"outlinecolour", 1, NULL, 'u'}, {"bbox", 1, NULL, 'x'}, {"bboxcolour", 1, NULL, 'X'}, {"barmode", 1, NULL, 'b'}, {"percentage", 1, NULL, 'P'}, {"text", 1, NULL, 'T'}, {NULL, 0, NULL, 0} }; FILE *fp; xosd *osd; char buffer[1024]; char *font = NULL; char *colour = "red"; char *text = NULL; enum { bar_none=0, bar_percentage, bar_slider } barmode = bar_none; int percentage = 50; int outline_offset = 0; int bbox_offset = 0; char *outline_colour = NULL; char *bbox_colour = NULL; char *shadow_colour = NULL; int delay = 5; int forcewait = 0; xosd_pos pos = XOSD_top; int voffset = 0; int hoffset = 0; int shadow = 0; int xscreen = -1; int scroll_age = 0; struct timeval old_age, new_age; int screen_line = 0; int lines = 5; xosd_align align = XOSD_left; int main(int argc, char *argv[]) { if (setlocale(LC_ALL, "") == NULL || !XSupportsLocale()) fprintf(stderr, "Locale not available, expect problems with fonts.\n"); while (1) { int option_index = 0; int c = getopt_long(argc, argv, "l:A:a::f:c:d:o:i:s:p:n:O:x:S:u:X:b:P:T:hw", long_options, &option_index); if (c == -1) break; switch (c) { case 'a': scroll_age = optarg ? atoi(optarg) : delay; break; case 'w': forcewait = 1; break; case 'A': if (strcasecmp(optarg, "left") == 0) { align = XOSD_left; } else if (strcasecmp(optarg, "right") == 0) { align = XOSD_right; } else if (strcasecmp(optarg, "center") == 0) { align = XOSD_center; } else if (strcasecmp(optarg, "centre") == 0) { align = XOSD_center; } else { fprintf(stderr, "Unknown alignment: %s\n", optarg); return EXIT_FAILURE; } break; case 'p': if (strcasecmp(optarg, "top") == 0) { pos = XOSD_top; } else if (strcasecmp(optarg, "middle") == 0) { pos = XOSD_middle; } else if (strcasecmp(optarg, "bottom") == 0) { pos = XOSD_bottom; } else { fprintf(stderr, "Unknown alignment: %s\n", optarg); return EXIT_FAILURE; } break; case 'f': font = optarg; break; case 'c': colour = optarg; break; case 'd': delay = atoi(optarg); break; case 'n': xscreen = atoi(optarg); break; case 'o': voffset = atoi(optarg); break; case 'O': outline_offset = atoi(optarg); break; case 'x': bbox_offset = atoi(optarg); break; case 'S': shadow_colour = optarg; break; case 'u': outline_colour = optarg; break; case 'X': bbox_colour = optarg; break; case 'i': hoffset = atoi(optarg); break; case 's': shadow = atoi(optarg); break; case 'l': lines = atoi(optarg); if (lines <= 0) { fprintf(stderr, "Illegal number of lines: %d\n", lines); return EXIT_FAILURE; } break; case 'b': if (strcasecmp(optarg, "percentage") == 0) { barmode = bar_percentage; } else if (strcasecmp(optarg, "slider") == 0) { barmode = bar_slider; } else { fprintf(stderr, "Unknown barmode: %s.\n", optarg); return EXIT_FAILURE; } break; case 'P': percentage = atoi(optarg); break; case 'T': text = optarg; break; case '?': case 'h': default: fprintf(stderr, "Usage: %s [OPTION] [FILE]...\n", argv[0]); fprintf(stderr, "Version: %s\n", XOSD_VERSION); fprintf(stderr, "Display FILE, or standard input, on top of display.\n" "\n" " -h, --help Show this help\n" " -p, --pos=(top|middle|bottom)\n" " Display at top/middle/bottom of screen. Top is default\n" " -o, --offset=OFFSET Vertical Offset\n" " -A, --align=(left|right|center)\n" " Display at left/right/center of screen. Left is default\n" " -n, --xscreen=SCREEN\n" " Xinerama screen to be used. Default -1 for all screens\n" " -i, --indent=OFFSET Horizontal Offset\n" " -f, --font=FONT Use font (default: %s)\n", osd_default_font); fprintf(stderr, " -c, --colour=COLOUR Use colour\n" " -s, --shadow=OFFSET Offset of shadow, default is 0 which is no shadow\n" " -S, --shadowcolour=COLOUR\n" " Colour of shadow, default is black\n" " -O, --outline=WIDTH\n" " Offset of outline, default is 0 which is no outline\n" " -u, --outlinecolour=COLOUR\n" " Colour of outline, default is black\n" " -x, --bbox=WIDTH\n" " Width of the bounding box, default is 0 (none)\n" " -X, --bboxcolour=COLOUR\n" " Colour of bounding box, default is black\n" " -a, --age[=TIME] Time in seconds before old scroll lines are discarded\n" " If no time is given, the current DELAY is used.\n" " -l, --lines=N Scroll using n lines. Default is 5.\n" " -d, --delay=TIME Show for specified time\n" " -w, --wait Delay display even when new lines are ready\n" "\n" " -b, --barmode=(percentage|slider)\n" " Lets you display a percentage or slider bar instead of just text.\n" " Options may be 'percentage' or 'slider'.\n" " Disregards any text or files when used.\n" " When this option is used, the following options are also valid.\n" " -P, --percentage=PERCENTAGE\n" " The length of the percentage bar / slider position (0 to 100).\n" " -T, --text=TEXT The text to get displayed above the percentage bar.\n" "\n\n" "With no FILE, or when FILE is -, read standard input.\n"); return EXIT_SUCCESS; } } if (barmode) { osd = xosd_create_xinerama( (text && *text) ? 2 : 1, xscreen); } else { if ((optind < argc) && strncmp(argv[optind], "-", 2)) { if ((fp = fopen(argv[optind], "r")) == NULL) { fprintf(stderr, "Unable to open: %s\n", argv[optind]); return EXIT_FAILURE; } } else fp = stdin; osd = xosd_create_xinerama(lines, xscreen); } if (!osd) { fprintf(stderr, "Error initializing osd: %s\n", xosd_error); return EXIT_FAILURE; } xosd_set_shadow_offset(osd, shadow); if (shadow_colour) xosd_set_shadow_colour(osd, shadow_colour); xosd_set_outline_offset(osd, outline_offset); if (outline_colour) xosd_set_outline_colour(osd, outline_colour); xosd_set_bbox_offset(osd, bbox_offset); if (bbox_colour) xosd_set_bbox_colour(osd, bbox_colour); if (colour) xosd_set_colour(osd, colour); xosd_set_timeout(osd, delay); xosd_set_pos(osd, pos); xosd_set_vertical_offset(osd, voffset); xosd_set_horizontal_offset(osd, hoffset); xosd_set_align(osd, align); if (font && xosd_set_font(osd, font)) { /* This is critical, because fontset=NULL, will segfault later! */ fprintf(stderr, "ABORT: %s\n", xosd_error); return EXIT_FAILURE; } switch (barmode) { case bar_percentage: if (text) xosd_display(osd, 0, XOSD_string, text); xosd_display(osd, text ? 1 : 0, XOSD_percentage, percentage); break; case bar_slider: if (text) xosd_display(osd, 0, XOSD_string, text); xosd_display(osd, text ? 1 : 0, XOSD_slider, percentage); break; case bar_none: /* Not really needed, but at least we aren't throwing around an unknown value */ old_age.tv_sec = 0; if (scroll_age) gettimeofday(&old_age, 0); while (!feof(fp)) { if (fgets(buffer, sizeof(buffer) - 1, fp)) { char *newline = strchr(buffer, '\n'); if (newline) newline[0] = '\0'; /* Enforce delay even when new lines are available */ if (forcewait && xosd_is_onscreen(osd)) xosd_wait_until_no_display(osd); /* If more than scroll_age time passes after the last time somethings * was displayed, clear the full display by scolling off all lines at * once. */ if (scroll_age) { gettimeofday(&new_age, 0); if ((new_age.tv_sec - old_age.tv_sec) > scroll_age) { if (lines > 1) xosd_scroll(osd, lines); screen_line = 0; } } /* else scroll of the first line if the display is full. */ if (screen_line >= lines) { if (lines > 1) xosd_scroll(osd, 1); screen_line = lines - 1; } xosd_display(osd, screen_line++, XOSD_string, buffer); old_age.tv_sec = new_age.tv_sec; } else if (!feof(fp)) { fprintf(stderr, "Error occured reading input file: %s\n", strerror(errno)); exit(1); } } fclose(fp); break; } if (xosd_is_onscreen(osd)) xosd_wait_until_no_display(osd); xosd_destroy(osd); return EXIT_SUCCESS; }