/* * 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. * There is NO WARRANTY, to the extent permitted by law. */ #include #include #include #include #include #include /* Table of common monitor aspect ratios. Add to this as necessary. */ static const struct aspect { unsigned num, denom; } aspects[] = { { 16, 10 }, { 16, 9 }, { 8, 3 }, { 5, 4 }, { 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; } 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 r = (double)w/h; double d = HUGE_VAL; int i; for (i = 0; i < (sizeof aspects / sizeof aspects[0]); i++) { double t = (double) aspects[i].num / aspects[i].denom; double cmp; cmp = fabs(r - t); if (cmp < d) { *out = aspects[i]; d = cmp; } cmp = fabs(r - 1/t); if (cmp < d) { out->num = aspects[i].denom; out->denom = aspects[i].num; d = cmp; } } } struct options { char *displayname; int showdimensions; } *parseoptions(int argc, char **argv) { static struct options opts = { 0 }; int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-display") == 0) { if (++i < argc) { opts.displayname = argv[i]; continue; } fprintf(stderr, "-display requires an argument\n"); } else if (strcmp(argv[i], "-dimensions") == 0) { opts.showdimensions = 1; } } return &opts; } int main(int argc, char **argv) { struct aspect screenaspect; xcb_connection_t *display; xcb_screen_t *screen; int screen_num; struct options *opts = parseoptions(argc, argv); display = xcb_connect(opts->displayname, &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; } if (opts->showdimensions) { printf("%" PRIu16 "x%" PRIu16 "-", screen->width_in_pixels, screen->height_in_pixels); } find_nearest_aspect(screen, &screenaspect); printf("%u:%u\n", screenaspect.num, screenaspect.denom); xcb_disconnect(display); return EXIT_SUCCESS; }