libxosd-xft/src/osd-demo.c

500 lines
13 KiB
C

/*
Copyright 2021 Dakshinamurthy Karra (dakshinamurthy.karra@jaliansystems.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xosd-xft.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <locale.h>
#include <X11/Xlib.h>
#include <sys/time.h>
#ifdef HAVE_LIBXINERAMA
int use_xinerama = True;
#endif
#ifdef HAVE_LIBXRANDR
int use_xrandr = True;
#endif
typedef enum
{
DEMO_none = 0,
DEMO_color = (1<<0),
DEMO_alpha = (1<<1),
DEMO_size = (1<<2),
DEMO_position = (1<<3),
DEMO_padding = (1<<4),
DEMO_align = (1<<5),
DEMO_text_align = (1<<6)
} osd_demo;
int all_demo = False;
static struct option long_options[] = {
#ifdef DEBUG
{"debug", 1, NULL, 'D'},
#endif
{"alpha", 0, NULL, 'a'},
{"align", 0, NULL, 'A'},
{"color", 0, NULL, 'c'},
{"font", 1, NULL, 'f'},
{"position", 0, NULL, 'p'},
{"padding", 0, NULL, 'P'},
{"size", 0, NULL, 's'},
{"text-align", 0, NULL, 't'},
{"all", 0, &all_demo, True },
{"help", 0, NULL, 'h'},
/* Multihead support */
#ifdef HAVE_LIBXINERAMA
{"no-xinerama", 0, &use_xinerama, False},
#endif
#ifdef HAVE_LIBXRANDR
{"no-xrandr", 0, &use_xrandr, False},
#endif
{NULL, 0, NULL, 0}};
xosd_xft *osd;
/* Default Values */
char* font = "mixed:size=36";
char* text_color = "red";
int text_alpha = 100;
char* bg_color = "black";
int bg_alpha = 100;
char* padding = "0";
int delay_millis = 1000;
#if defined(HAVE_LIBXINERAMA) || defined(HAVE_LIBXRANDR)
int monitor = -1;
#endif
char* geometry = "800x80+0+0*middle/center";
char* text_align = "center/middle";
#ifdef DEBUG
char* debug_level = NULL;
#endif
char* message = "~~~ Linux Rocks ~~~";
osd_demo demo = DEMO_none;
static void demo_color(xosd_xft* osd, char **argv);
static void demo_alpha(xosd_xft* osd, char **argv);
static void demo_size(xosd_xft* osd, char **argv);
static void demo_align(xosd_xft* osd, char **argv);
static void demo_text_align(xosd_xft* osd, char **argv);
static void demo_position(xosd_xft* osd, char **argv);
static void demo_padding(xosd_xft* osd, char **argv);
static void help(char **argv, char *error);
void
pause_demo()
{
char b[200];
printf("Press ENTER to continue...");
fflush(stdout);
fgets(b, 200, stdin);
}
void
reset_osd(xosd_xft* osd, char** argv)
{
osd_geometry g, *parsed = &g;
if(osd_parse_geometry(geometry, text_align, parsed) == NULL) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
osd_set_geometry(osd, parsed);
osd_set_font(osd, font);
osd_set_monitor(osd, monitor);
osd_set_padding(osd, padding);
osd_set_textcolor(osd, text_color, text_alpha);
osd_set_bgcolor(osd, bg_color, bg_alpha);
}
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, "D:f:caApPsth?",
long_options,
&option_index);
if (c == -1)
break;
switch (c)
{
case 0:
break;
case 'f':
font = optarg;
break;
case 'a':
demo |= DEMO_alpha;
break;
case 'A':
demo |= DEMO_align;
break;
case 'c':
demo |= DEMO_color;
break;
#ifdef DEBUG
case 'D':
debug_level = optarg;
break;
#endif
case 'p':
demo |= DEMO_position;
break;
case 'P':
demo |= DEMO_padding;
break;
case 's':
demo |= DEMO_size;
break;
case 't':
demo |= DEMO_text_align;
break;
case '?':
case 'h':
default:
help(argv, NULL);
return EXIT_SUCCESS;
}
}
if(all_demo) demo = -1;
if(demo == DEMO_none) {
help(argv, "No demo option provided");
return EXIT_FAILURE;
}
xosd_xft *osd = osd_create();
reset_osd(osd, argv);
osd_set_xinerama(osd, use_xinerama);
osd_set_xrandr(osd, use_xrandr);
#ifdef DEBUG
osd_set_debug_level(debug_level);
#endif
if(demo & DEMO_color) {
reset_osd(osd, argv);
demo_color(osd, argv);
}
if(demo & DEMO_alpha) {
reset_osd(osd, argv);
demo_alpha(osd, argv);
}
if(demo & DEMO_size) {
reset_osd(osd, argv);
demo_size(osd, argv);
}
if(demo & DEMO_align) {
reset_osd(osd, argv);
demo_align(osd, argv);
}
if(demo & DEMO_text_align) {
reset_osd(osd, argv);
demo_text_align(osd, argv);
}
if(demo & DEMO_position) {
reset_osd(osd, argv);
demo_position(osd, argv);
}
if(demo & DEMO_padding) {
reset_osd(osd, argv);
demo_padding(osd, argv);
}
osd_destroy(osd);
return EXIT_SUCCESS;
}
static void
demo_color(xosd_xft* osd, char **argv)
{
char *colors[] = { "#f96167", "#f9de42" };
char *bg_colors[] = { "#fce77d", "#292826" };
if(osd_display(osd, message, strlen(message)) == -1) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
for(int i = 0; i < sizeof(colors)/sizeof(char*); i++) {
printf("Colors { bg: %s, fg: %s }\n", bg_colors[i], colors[i]);
osd_set_textcolor(osd, colors[i], text_alpha);
osd_set_bgcolor(osd, bg_colors[i], bg_alpha);
pause_demo();
}
}
static void
demo_alpha(xosd_xft* osd, char **argv)
{
if(osd_display(osd, message, strlen(message)) == -1) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
for(int alpha = bg_alpha; alpha >= 0; alpha-=10) {
printf("Setting alpha to: %d\n", alpha);
osd_set_bgcolor(osd, bg_color, alpha);
pause_demo();
}
}
static void
tryout_widths(xosd_xft* osd, osd_geometry *g, int per, int chars, int* widths, int len)
{
g->width_per = per;
g->width_chars = chars;
for(int i = 0; i < len; i++) {
printf("Setting width to %d\n", widths[i]);
g->width = widths[i];
osd_set_geometry(osd, g);
pause_demo();
}
}
static void
tryout_heights(xosd_xft* osd, osd_geometry *g, int per, int lines, int* heights, int len)
{
g->height_per = per;
g->height_lines = lines;
for(int i = 0; i < len; i++) {
printf("Setting height to %d\n", heights[i]);
g->height = heights[i];
osd_set_geometry(osd, g);
pause_demo();
}
}
static void
demo_size(xosd_xft* osd, char **argv)
{
char *geometry = "100%x80+0+0";
osd_geometry to_parse, *g = &to_parse;
g = osd_parse_geometry(geometry, text_align, g);
if(g == NULL) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
osd_set_geometry(osd, g);
if(osd_display(osd, message, strlen(message)) == -1) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
printf("***** WIDTH as percentage of screen size *****\n");
{
int widths[] = { 40, 60, 80, 100 };
tryout_widths(osd, g, 1, 0, widths, sizeof(widths)/sizeof(int));
}
printf("***** WIDTH as number of characters *****\n");
{
int widths[] = { 40, 60, 80, 100 };
tryout_widths(osd, g, 0, 1, widths, sizeof(widths)/sizeof(int));
}
printf("***** WIDTH as number of pixels *****\n");
{
int widths[] = { 400, 600, 800, 1000 };
tryout_widths(osd, g, 0, 0, widths, sizeof(widths)/sizeof(int));
}
printf("***** HEIGHT as percentage of screen size *****\n");
{
int heights[] = { 40, 60, 80, 100 };
tryout_heights(osd, g, 1, 0, heights, sizeof(heights)/sizeof(int));
}
printf("***** HEIGHT as number of lines *****\n");
{
int heights[] = { 4, 6, 8, 10 };
tryout_heights(osd, g, 0, 1, heights, sizeof(heights)/sizeof(int));
}
printf("***** HEIGHT as number of pixels *****\n");
{
int heights[] = { 400, 600, 800, 1000 };
tryout_heights(osd, g, 0, 0, heights, sizeof(heights)/sizeof(int));
}
}
static char *osd_valign_names[] = {"top", "bottom", "middle", "none"};
static char *osd_halign_names[] = {"left", "center", "right", "none"};
static void
demo_align(xosd_xft* osd, char **argv)
{
char* geometry = "100%x80+0+0";
osd_geometry to_parse, *g = &to_parse;
g = osd_parse_geometry(geometry, text_align, g);
if(g == NULL) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
osd_set_geometry(osd, g);
if(osd_display(osd, message, strlen(message)) == -1) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
printf("***** Vertical Align *****\n");
for(int i = 0; i < 3; i++) {
printf("Setting valign to %s\n", osd_valign_names[i]);
g->valign = i ;
osd_set_geometry(osd, g);
pause_demo();
}
printf("***** Horizontal Align *****\n");
geometry = "60%x80+0+0";
g = &to_parse;
g = osd_parse_geometry(geometry, text_align, g);
if(g == NULL) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
osd_set_geometry(osd, g);
for(int i = 0; i < 3; i++) {
printf("Setting halign to %s\n", osd_halign_names[i]);
g->halign = i ;
osd_set_geometry(osd, g);
pause_demo();
}
}
static void
demo_text_align(xosd_xft* osd, char **argv)
{
char *geometry = "100%x180+0+0";
osd_geometry to_parse, *g = &to_parse;
g = osd_parse_geometry(geometry, text_align, g);
if(g == NULL) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
osd_set_geometry(osd, g);
if(osd_display(osd, message, strlen(message)) == -1) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
printf("***** Text Vertical Align *****\n");
for(int i = 0; i < 3; i++) {
printf("Setting text valign to %s\n", osd_valign_names[i]);
g->text_valign = i ;
osd_set_geometry(osd, g);
pause_demo();
}
printf("***** Text Horizontal Align *****\n");
for(int i = 0; i < 3; i++) {
printf("Setting text halign to %s\n", osd_halign_names[i]);
g->text_halign = i ;
osd_set_geometry(osd, g);
pause_demo();
}
}
static void
demo_position(xosd_xft* osd, char **argv)
{
char* geometry = "400x80+0+0";
osd_geometry to_parse, *g = &to_parse;
g = osd_parse_geometry(geometry, text_align, g);
if(g == NULL) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
osd_set_geometry(osd, g);
if(osd_display(osd, message, strlen(message)) == -1) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
printf("***** Position (Offsets) *****\n");
for(int xneg = 0; xneg < 2; xneg++) {
for(int yneg = 0; yneg < 2; yneg++) {
for(int offset = 0; offset < 31; offset += 30) {
g->xneg = xneg;
g->yneg = yneg ;
g->xoffset = g->yoffset = offset ;
printf("Setting geometry to %dx%d%s%d%s%d\n",
g->width, g->height, g->xneg ? "-" : "+", g->xoffset, g->yneg ? "-" : "+", g->yoffset);
osd_set_geometry(osd, g);
pause_demo();
}
}
}
}
static void
demo_padding(xosd_xft* osd, char **argv)
{
char* paddings[] = { "0", "30", "30 20", "30 20 15", "30 20 15 10" };
char* geometry = "600x180+0+0*middle/center";
char* text_align = "left/top";
osd_geometry to_parse, *g = &to_parse ;
g = osd_parse_geometry(geometry, text_align, g);
if(g == NULL) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
osd_set_geometry(osd, g);
if(osd_display(osd, message, strlen(message)) == -1) {
help(argv, osd_error);
exit(EXIT_FAILURE);
}
printf("***** Padding *****\n");
for(int i = 0; i < 5; i++) {
printf("Setting padding to %s\n", paddings[i]);
osd_set_padding(osd, paddings[i]);
pause_demo();
}
}
static void
help(char **argv, char* error)
{
FILE *out = error ? stderr : stdout ;
if(error) {
fprintf(stderr, "Error: %s\n", error);
}
fprintf(out, "Usage: %s [OPTION] message...\n", argv[0]);
fprintf(out, "Version: %s\n", XOSD_XFT_VERSION);
fprintf(out,
"Display a given message on top of the display\n"
"\n"
" -h, --help Show this help\n"
" -f, --font=<font> Font for display (default: %s)\n"
" <font> is Xft font name\n"
" -c, --color Demoing color options\n"
" -a, --alpha Demoing background alpha\n"
" -A, --align Demoing various alignment options for OSD window\n"
" -p, --position Demoing various position options\n"
" -P, --padding Demoing various padding options\n"
" -s, --size Demoing various options for specifying size\n"
" -t, --text-align Demoing various text alignment options\n"
#ifdef DEBUG
" -D, --debug=<level> The debug levels to be enabled\n"
" <level>: CSV of none function,locking,select,trace,value,update,all\n"
#endif
"\n\n", font );
}
/* vim: foldmethod=marker tabstop=2 shiftwidth=2 expandtab
*/