]> git.draconx.ca Git - fvwmconf.git/blobdiff - scripts/C/xaspect.c
Improve wallpaper menu generation.
[fvwmconf.git] / scripts / C / xaspect.c
index 16d151fe62ba4d6b60424a7e8dce323f8889a890..0009424f24f3263d5c8fd56b31d7d87717ca59bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2007 Nick Bowler
+ * Copyright © 2008, 2017 Nick Bowler
  *
  * License WTFPL2: Do What The Fuck You Want To Public License, version 2.
  * This is free software: you are free to do what the fuck you want to.
 #include <inttypes.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;
+static const struct aspect {
+       unsigned num, denom;
 } aspects[] = {
-       MKASPECT(16, 10),
-       MKASPECT(16, 9),
-       MKASPECT(8, 3),
-       MKASPECT(5, 4),
-       MKASPECT(4, 3)
+       { 16, 10 },
+       { 16, 9 },
+       { 8, 3 },
+       { 5, 4 },
+       { 4, 3 }
 };
 
 /*
@@ -46,24 +43,32 @@ static xcb_screen_t *getscreen(xcb_connection_t *c, int screen)
        return NULL;
 }
 
-char *testaspect(xcb_screen_t *screen)
+void find_nearest_aspect(xcb_screen_t *screen, struct aspect *out)
 {
        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;
+       double r = (double)w/h;
+       double d = HUGE_VAL;
        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);
+               double t = (double) aspects[i].num / aspects[i].denom;
+               double cmp;
+
+               cmp = fabs(r - t);
+               if (cmp < d) {
+                       *out = aspects[i];
+                       d = cmp;
                }
-       }
 
-       return best;
+               cmp = fabs(r - 1/t);
+               if (cmp < d) {
+                       out->num = aspects[i].denom;
+                       out->denom = aspects[i].num;
+                       d = cmp;
+               }
+       }
 }
 
 struct options {
@@ -91,6 +96,7 @@ struct options {
 
 int main(int argc, char **argv)
 {
+       struct aspect screenaspect;
        xcb_connection_t *display;
        xcb_screen_t     *screen;
        int screen_num;
@@ -115,7 +121,9 @@ int main(int argc, char **argv)
                printf("%" PRIu16 "x%" PRIu16 "-",
                       screen->width_in_pixels, screen->height_in_pixels);
        }
-       printf("%s\n", testaspect(screen));
+
+       find_nearest_aspect(screen, &screenaspect);
+       printf("%u:%u\n", screenaspect.num, screenaspect.denom);
 
        xcb_disconnect(display);
        return EXIT_SUCCESS;