From cb1fcfed6a918eba985530a262916b1b6a17f9b2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ingo=20B=C3=BCrk?= Date: Fri, 23 Sep 2016 15:09:49 +0200 Subject: [PATCH] Use Xft.dpi for DPI if available. fixes #2465 --- i3-config-wizard/i3-config-wizard.mk | 4 +- i3-input/i3-input.mk | 4 +- i3-nagbar/i3-nagbar.mk | 4 +- i3bar/i3bar.mk | 4 +- include/libi3.h | 7 ++++ libi3/dpi.c | 57 +++++++++++++++++++++++++++- libi3/libi3.mk | 2 +- src/main.c | 7 ++-- 8 files changed, 75 insertions(+), 14 deletions(-) diff --git a/i3-config-wizard/i3-config-wizard.mk b/i3-config-wizard/i3-config-wizard.mk index 2a761433..9c01cdb6 100644 --- a/i3-config-wizard/i3-config-wizard.mk +++ b/i3-config-wizard/i3-config-wizard.mk @@ -4,8 +4,8 @@ CLEAN_TARGETS += clean-i3-config-wizard i3_config_wizard_SOURCES := $(wildcard i3-config-wizard/*.c) i3_config_wizard_HEADERS := $(wildcard i3-config-wizard/*.h) -i3_config_wizard_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(PANGO_CFLAGS) $(XKB_COMMON_CFLAGS) $(XKB_COMMON_X11_CFLAGS) -i3_config_wizard_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS) $(XKB_COMMON_LIBS) $(XKB_COMMON_X11_LIBS) +i3_config_wizard_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(PANGO_CFLAGS) $(XCB_XRM_CFLAGS) $(XKB_COMMON_CFLAGS) $(XKB_COMMON_X11_CFLAGS) +i3_config_wizard_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS) $(XCB_XRM_LIBS) $(XKB_COMMON_LIBS) $(XKB_COMMON_X11_LIBS) i3_config_wizard_OBJECTS := $(i3_config_wizard_SOURCES:.c=.o) diff --git a/i3-input/i3-input.mk b/i3-input/i3-input.mk index 2b1f451e..ce36f932 100644 --- a/i3-input/i3-input.mk +++ b/i3-input/i3-input.mk @@ -4,8 +4,8 @@ CLEAN_TARGETS += clean-i3-input i3_input_SOURCES := $(wildcard i3-input/*.c) i3_input_HEADERS := $(wildcard i3-input/*.h) -i3_input_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(PANGO_CFLAGS) -i3_input_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS) +i3_input_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(PANGO_CFLAGS) $(XCB_XRM_CFLAGS) +i3_input_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS) $(XCB_XRM_LIBS) i3_input_OBJECTS := $(i3_input_SOURCES:.c=.o) diff --git a/i3-nagbar/i3-nagbar.mk b/i3-nagbar/i3-nagbar.mk index 564a7bc2..c6c7a2ef 100644 --- a/i3-nagbar/i3-nagbar.mk +++ b/i3-nagbar/i3-nagbar.mk @@ -4,8 +4,8 @@ CLEAN_TARGETS += clean-i3-nagbar i3_nagbar_SOURCES := $(wildcard i3-nagbar/*.c) i3_nagbar_HEADERS := $(wildcard i3-nagbar/*.h) -i3_nagbar_CFLAGS = $(XCB_CFLAGS) $(XCB_CURSOR_CFLAGS) $(XCB_WM_CFLAGS) $(PANGO_CFLAGS) -i3_nagbar_LIBS = $(XCB_LIBS) $(XCB_CURSOR_LIBS) $(XCB_WM_LIBS) $(PANGO_LIBS) +i3_nagbar_CFLAGS = $(XCB_CFLAGS) $(XCB_CURSOR_CFLAGS) $(XCB_WM_CFLAGS) $(PANGO_CFLAGS) $(XCB_XRM_CFLAGS) +i3_nagbar_LIBS = $(XCB_LIBS) $(XCB_CURSOR_LIBS) $(XCB_WM_LIBS) $(PANGO_LIBS) $(XCB_XRM_LIBS) i3_nagbar_OBJECTS := $(i3_nagbar_SOURCES:.c=.o) diff --git a/i3bar/i3bar.mk b/i3bar/i3bar.mk index 114e9314..03c607dd 100644 --- a/i3bar/i3bar.mk +++ b/i3bar/i3bar.mk @@ -4,8 +4,8 @@ CLEAN_TARGETS += clean-i3bar i3bar_SOURCES := $(wildcard i3bar/src/*.c) i3bar_HEADERS := $(wildcard i3bar/include/*.h) -i3bar_CFLAGS = $(XCB_CFLAGS) $(XCB_CURSOR_CFLAGS) $(PANGO_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS) -i3bar_LIBS = $(XCB_LIBS) $(XCB_CURSOR_LIBS) $(PANGO_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS) $(XCB_XKB_LIBS) +i3bar_CFLAGS = $(XCB_CFLAGS) $(XCB_CURSOR_CFLAGS) $(PANGO_CFLAGS) $(XCB_XRM_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS) +i3bar_LIBS = $(XCB_LIBS) $(XCB_CURSOR_LIBS) $(PANGO_LIBS) $(XCB_XRM_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS) $(XCB_XKB_LIBS) i3bar_OBJECTS := $(i3bar_SOURCES:.c=.o) diff --git a/include/libi3.h b/include/libi3.h index da5ad891..c1fe770b 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -470,6 +470,13 @@ char *get_process_filename(const char *prefix); */ char *get_exe_path(const char *argv0); +/** + * Initialize the DPI setting. + * This will use the 'Xft.dpi' X resource if available and fall back to + * guessing the correct value otherwise. + */ +void init_dpi(void); + /** * Convert a logical amount of pixels (e.g. 2 pixels on a “standard” 96 DPI * screen) to a corresponding amount of physical pixels on a standard or retina diff --git a/libi3/dpi.c b/libi3/dpi.c index 897e6e40..f105ef9a 100644 --- a/libi3/dpi.c +++ b/libi3/dpi.c @@ -7,6 +7,61 @@ */ #include "libi3.h" #include +#include +#include + +static long dpi; + +static long init_dpi_fallback(void) { + return (double)root_screen->height_in_pixels * 25.4 / (double)root_screen->height_in_millimeters; +} + +/* + * Initialize the DPI setting. + * This will use the 'Xft.dpi' X resource if available and fall back to + * guessing the correct value otherwise. + */ +void init_dpi(void) { + xcb_xrm_database_t *database = NULL; + + if (conn == NULL) { + goto init_dpi_end; + } + + database = xcb_xrm_database_from_default(conn); + if (database == NULL) { + ELOG("Failed to open the resource database.\n"); + goto init_dpi_end; + } + + char *resource; + xcb_xrm_resource_get_string(database, "Xft.dpi", NULL, &resource); + if (resource == NULL) { + DLOG("Resource Xft.dpi not specified, skipping.\n"); + goto init_dpi_end; + } + + char *endptr; + dpi = strtol(resource, &endptr, 10); + if (dpi == LONG_MAX || dpi == LONG_MIN || dpi < 0 || *endptr != '\0' || endptr == resource) { + ELOG("Xft.dpi = %s is an invalid number and couldn't be parsed.\n", resource); + dpi = 0; + goto init_dpi_end; + } + + DLOG("Found Xft.dpi = %ld.\n", dpi); + +init_dpi_end: + if (database != NULL) { + xcb_xrm_database_free(database); + } + + if (dpi == 0) { + DLOG("Using fallback for calculating DPI.\n"); + dpi = init_dpi_fallback(); + DLOG("Using dpi = %ld\n", dpi); + } +} /* * Convert a logical amount of pixels (e.g. 2 pixels on a “standard” 96 DPI @@ -21,8 +76,6 @@ int logical_px(const int logical) { return logical; } - const int dpi = (double)root_screen->height_in_pixels * 25.4 / - (double)root_screen->height_in_millimeters; /* There are many misconfigurations out there, i.e. systems with screens * whose dpi is in fact higher than 96 dpi, but not significantly higher, * so software was never adapted. We could tell people to reconfigure their diff --git a/libi3/libi3.mk b/libi3/libi3.mk index d313a44e..16e1f149 100644 --- a/libi3/libi3.mk +++ b/libi3/libi3.mk @@ -2,7 +2,7 @@ CLEAN_TARGETS += clean-libi3 libi3_SOURCES := $(wildcard libi3/*.c) libi3_HEADERS := $(wildcard libi3/*.h) -libi3_CFLAGS = $(PANGO_CFLAGS) +libi3_CFLAGS = $(PANGO_CFLAGS) $(XCB_XRM_CFLAGS) libi3_LIBS = libi3_OBJECTS := $(libi3_SOURCES:.c=.o) diff --git a/src/main.c b/src/main.c index 5362d077..96eab671 100644 --- a/src/main.c +++ b/src/main.c @@ -503,10 +503,11 @@ int main(int argc, char *argv[]) { visual_type = get_visualtype(root_screen); } + init_dpi(); + DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_type->visual_id); - DLOG("root_screen->height_in_pixels = %d, root_screen->height_in_millimeters = %d, dpi = %d\n", - root_screen->height_in_pixels, root_screen->height_in_millimeters, - (int)((double)root_screen->height_in_pixels * 25.4 / (double)root_screen->height_in_millimeters)); + DLOG("root_screen->height_in_pixels = %d, root_screen->height_in_millimeters = %d\n", + root_screen->height_in_pixels, root_screen->height_in_millimeters); DLOG("One logical pixel corresponds to %d physical pixels on this display.\n", logical_px(1)); xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(conn, root); -- 2.39.5