]> git.draconx.ca Git - fvwmconf.git/commitdiff
Add a C tool to determine the physical aspect ratio of a display.
authorNick Bowler <draconx@gmail.com>
Mon, 28 Apr 2008 22:06:21 +0000 (18:06 -0400)
committerNick Bowler <draconx@gmail.com>
Mon, 28 Apr 2008 22:06:21 +0000 (18:06 -0400)
scripts/C/.gitignore [new file with mode: 0644]
scripts/C/Makefile [new file with mode: 0644]
scripts/C/xaspect.c [new file with mode: 0644]

diff --git a/scripts/C/.gitignore b/scripts/C/.gitignore
new file mode 100644 (file)
index 0000000..bb2bc77
--- /dev/null
@@ -0,0 +1,2 @@
+*.o
+xaspect
diff --git a/scripts/C/Makefile b/scripts/C/Makefile
new file mode 100644 (file)
index 0000000..5d61541
--- /dev/null
@@ -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 (file)
index 0000000..0dbc83d
--- /dev/null
@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <xcb/xcb.h>
+
+#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;
+}