]> git.draconx.ca Git - fvwmconf.git/blob - scripts/C/xaspect.c
xaspect: remove redundant 8:5 aspect and add 8:3 instead.
[fvwmconf.git] / scripts / C / xaspect.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include <xcb/xcb.h>
6
7 #define MKASPECT(w, h) { (double)w/h, #w ":" #h }
8
9 /* Table of common monitor aspect ratios.  Add to this as necessary. */
10 static struct aspect {
11         double ratio;
12         char *name;
13 } aspects[] = {
14         MKASPECT(16, 10),
15         MKASPECT(16, 9),
16         MKASPECT(8, 3),
17         MKASPECT(5, 4),
18         MKASPECT(4, 3)
19 };
20
21 /*
22  * Get the xcb screen structure for the specified screen, or NULL if it doesn't
23  * exist.
24  */
25 static xcb_screen_t *getscreen(xcb_connection_t *c, int screen)
26 {
27         xcb_screen_iterator_t iter;
28
29         iter = xcb_setup_roots_iterator(xcb_get_setup(c));
30         while (iter.rem) {
31                 if (screen == 0)
32                         return iter.data;
33                 screen--;
34                 xcb_screen_next(&iter);
35         }
36
37         return NULL;
38 }
39
40 char *testaspect(xcb_screen_t *screen)
41 {
42         unsigned int w = screen->width_in_millimeters;
43         unsigned int h = screen->height_in_millimeters;
44
45         double ratio = (double)w/h;
46         double diff = 0;
47         char *best = NULL;
48         int i;
49
50         for (i = 0; i < (sizeof aspects / sizeof aspects[0]); i++) {
51                 if (!best || fabs(aspects[i].ratio - ratio) < diff) {
52                         best = aspects[i].name;
53                         diff = fabs(aspects[i].ratio - ratio);
54                 }
55         }
56
57         return best;
58 }
59
60 int main(int argc, char **argv)
61 {
62         xcb_connection_t *display;
63         xcb_screen_t     *screen;
64         char *dpynam = NULL;
65         int screen_num;
66
67         if (argc > 2 && strcmp(argv[1], "-display") == 0)
68                 dpynam = argv[2];
69         
70         display = xcb_connect(dpynam, &screen_num);
71         if (xcb_connection_has_error(display)) {
72                 fprintf(stderr, "Failed to open display.\n");
73                 xcb_disconnect(display);
74                 return EXIT_FAILURE;
75         }
76
77         screen = getscreen(display, screen_num);
78         if (!screen) {
79                 fprintf(stderr, "Invalid screen number.\n");
80                 xcb_disconnect(display);
81                 return EXIT_FAILURE;
82         }
83
84         printf("%s\n", testaspect(screen));
85
86         xcb_disconnect(display);
87         return EXIT_SUCCESS;
88 }