From: Nick Bowler Date: Mon, 28 Apr 2008 22:06:21 +0000 (-0400) Subject: Add a C tool to determine the physical aspect ratio of a display. X-Git-Url: https://git.draconx.ca/gitweb/fvwmconf.git/commitdiff_plain/383401a5e46855bc36fca8f9f2c98bb9f814f21a Add a C tool to determine the physical aspect ratio of a display. --- diff --git a/scripts/C/.gitignore b/scripts/C/.gitignore new file mode 100644 index 0000000..bb2bc77 --- /dev/null +++ b/scripts/C/.gitignore @@ -0,0 +1,2 @@ +*.o +xaspect diff --git a/scripts/C/Makefile b/scripts/C/Makefile new file mode 100644 index 0000000..5d61541 --- /dev/null +++ b/scripts/C/Makefile @@ -0,0 +1,13 @@ +CFLAGS = -O2 -Wall -Wextra -Wno-sign-compare +LDFLAGS = + +CC = c89 +LD = $(CC) + +all: xaspect + +.c.o: + $(CC) -c -o $@ $(CFLAGS) $< + +xaspect: xaspect.o + $(LD) -o xaspect $^ -lm -lxcb $(LDFLAGS) diff --git a/scripts/C/xaspect.c b/scripts/C/xaspect.c new file mode 100644 index 0000000..0dbc83d --- /dev/null +++ b/scripts/C/xaspect.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include + +#define MKASPECT(w, h) { (double)w/h, #w ":" #h } + +/* Table of common monitor aspect ratios. Add to this as necessary. */ +static struct aspect { + double ratio; + char *name; +} aspects[] = { + MKASPECT(16, 10), + MKASPECT(16, 9), + MKASPECT(8, 5), + MKASPECT(5, 4), + MKASPECT(4, 3) +}; + +/* + * Get the xcb screen structure for the specified screen, or NULL if it doesn't + * exist. + */ +static xcb_screen_t *getscreen(xcb_connection_t *c, int screen) +{ + xcb_screen_iterator_t iter; + + iter = xcb_setup_roots_iterator(xcb_get_setup(c)); + while (iter.rem) { + if (screen == 0) + return iter.data; + screen--; + xcb_screen_next(&iter); + } + + return NULL; +} + +char *testaspect(xcb_screen_t *screen) +{ + unsigned int w = screen->width_in_millimeters; + unsigned int h = screen->height_in_millimeters; + + double ratio = (double)w/h; + double diff = 0; + char *best = NULL; + int i; + + for (i = 0; i < (sizeof aspects / sizeof aspects[0]); i++) { + if (!best || fabs(aspects[i].ratio - ratio) < diff) { + best = aspects[i].name; + diff = fabs(aspects[i].ratio - ratio); + } + } + + return best; +} + +int main(int argc, char **argv) +{ + xcb_connection_t *display; + xcb_screen_t *screen; + char *dpynam = NULL; + int screen_num; + + if (argc > 2 && strcmp(argv[1], "-display") == 0) + dpynam = argv[2]; + + display = xcb_connect(dpynam, &screen_num); + if (xcb_connection_has_error(display)) { + fprintf(stderr, "Failed to open display.\n"); + xcb_disconnect(display); + return EXIT_FAILURE; + } + + screen = getscreen(display, screen_num); + if (!screen) { + fprintf(stderr, "Invalid screen number.\n"); + xcb_disconnect(display); + return EXIT_FAILURE; + } + + printf("%s\n", testaspect(screen)); + + xcb_disconnect(display); + return EXIT_SUCCESS; +}