From 383401a5e46855bc36fca8f9f2c98bb9f814f21a Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 28 Apr 2008 18:06:21 -0400 Subject: [PATCH] Add a C tool to determine the physical aspect ratio of a display. --- scripts/C/.gitignore | 2 + scripts/C/Makefile | 13 +++++++ scripts/C/xaspect.c | 88 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 scripts/C/.gitignore create mode 100644 scripts/C/Makefile create mode 100644 scripts/C/xaspect.c 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; +} -- 2.43.0