Add auto-detect dpi method
If Xft.dpi value is not available, auto-detect value based on monitor using randr provided sizes. Disable Xinerama and enable randr by default. Also update dpi everytime the monitor changes.
This commit is contained in:
parent
cc3a08c1db
commit
4dd628ccf4
12
config.mk
12
config.mk
@ -9,8 +9,12 @@ VERSION := $(shell git describe --tags)
|
||||
endif
|
||||
|
||||
# Xinerama, comment if you don't want it
|
||||
XINERAMALIBS = -lXinerama
|
||||
XINERAMAFLAGS = -DXINERAMA
|
||||
#XINERAMALIBS = -lXinerama
|
||||
#XINERAMAFLAGS = -DXINERAMA
|
||||
|
||||
# RANDR, comment if you don't want it
|
||||
XRANDRLIBS = -lXrandr
|
||||
XRANDRFLAGS = -DXRANDR
|
||||
|
||||
# uncomment to disable parsing of dunstrc
|
||||
# or use "CFLAGS=-DSTATIC_CONFIG make" to build
|
||||
@ -22,7 +26,7 @@ ifeq (${PKG_CONFIG}, ${EMPTY})
|
||||
endif
|
||||
|
||||
# flags
|
||||
CPPFLAGS += -D_DEFAULT_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} ${INIFLAGS}
|
||||
CPPFLAGS += -D_DEFAULT_SOURCE -DVERSION=\"${VERSION}\" ${XRANDRFLAGS} ${XINERAMAFLAGS} ${INIFLAGS}
|
||||
CFLAGS += -g --std=gnu99 -pedantic -Wall -Wno-overlength-strings -Os ${STATIC} ${CPPFLAGS} ${EXTRACFLAGS}
|
||||
|
||||
pkg_config_packs := dbus-1 x11 xscrnsaver \
|
||||
@ -37,7 +41,7 @@ endif
|
||||
# includes and libs
|
||||
INCS := $(shell ${PKG_CONFIG} --cflags ${pkg_config_packs})
|
||||
CFLAGS += ${INCS}
|
||||
LDFLAGS += -lm -L${X11LIB} -lXss ${XINERAMALIBS} $(shell ${PKG_CONFIG} --libs ${pkg_config_packs})
|
||||
LDFLAGS += -lm -L${X11LIB} -lXss ${XRANDRLIBS} ${XINERAMALIBS} $(shell ${PKG_CONFIG} --libs ${pkg_config_packs})
|
||||
|
||||
# only make this an fatal error when where not cleaning
|
||||
ifneq (clean, $(MAKECMDGOALS))
|
||||
|
134
src/x.c
134
src/x.c
@ -7,7 +7,10 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xresource.h>
|
||||
#ifdef XINERAMA
|
||||
#ifdef XRANDR
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <assert.h>
|
||||
#elif XINERAMA
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#include <assert.h>
|
||||
#endif
|
||||
@ -137,28 +140,6 @@ static color_t x_get_separator_color(colored_layout *cl, colored_layout *cl_next
|
||||
}
|
||||
}
|
||||
|
||||
static void set_dpi_value()
|
||||
{
|
||||
double dpi = 0.0;
|
||||
XrmInitialize();
|
||||
char * xRMS = XResourceManagerString(xctx.dpy);
|
||||
|
||||
if ( xRMS != NULL ) {
|
||||
XrmDatabase xDB = XrmGetStringDatabase(xRMS);
|
||||
char * xrmType;
|
||||
XrmValue xrmValue;
|
||||
|
||||
if ( XrmGetResource(xDB, "Xft.dpi", NULL, &xrmType, &xrmValue))
|
||||
dpi = strtod(xrmValue.addr, NULL);
|
||||
|
||||
}
|
||||
|
||||
if (dpi > 0.0) {
|
||||
PangoFontMap *font_map = pango_cairo_font_map_get_default();
|
||||
pango_cairo_font_map_set_resolution((PangoCairoFontMap *) font_map, dpi);
|
||||
}
|
||||
}
|
||||
|
||||
static void x_cairo_setup(void)
|
||||
{
|
||||
cairo_ctx.surface = cairo_xlib_surface_create(xctx.dpy,
|
||||
@ -166,8 +147,6 @@ static void x_cairo_setup(void)
|
||||
|
||||
cairo_ctx.context = cairo_create(cairo_ctx.surface);
|
||||
|
||||
set_dpi_value();
|
||||
|
||||
cairo_ctx.desc = pango_font_description_from_string(settings.font);
|
||||
}
|
||||
|
||||
@ -949,12 +928,80 @@ static Window get_focused_window(void)
|
||||
return focused;
|
||||
}
|
||||
|
||||
#ifdef XINERAMA
|
||||
static double get_xft_dpi_value()
|
||||
{
|
||||
double dpi = 0.0;
|
||||
XrmInitialize();
|
||||
char * xRMS = XResourceManagerString(xctx.dpy);
|
||||
|
||||
if ( xRMS != NULL ) {
|
||||
XrmDatabase xDB = XrmGetStringDatabase(xRMS);
|
||||
char * xrmType;
|
||||
XrmValue xrmValue;
|
||||
|
||||
if ( XrmGetResource(xDB, "Xft.dpi", NULL, &xrmType, &xrmValue))
|
||||
dpi = strtod(xrmValue.addr, NULL);
|
||||
|
||||
}
|
||||
|
||||
return dpi;
|
||||
}
|
||||
static void set_dpi_value(screen_info * scr, double dpi)
|
||||
{
|
||||
if (dpi > 0.0) {
|
||||
PangoFontMap *font_map = pango_cairo_font_map_get_default();
|
||||
pango_cairo_font_map_set_resolution((PangoCairoFontMap *) font_map, dpi);
|
||||
}
|
||||
#ifdef XRANDR
|
||||
//fallback to auto-detect method
|
||||
else {
|
||||
dpi = (double)scr->dim.h * 25.4 / (double)scr->dim.mmh;
|
||||
PangoFontMap *font_map = pango_cairo_font_map_get_default();
|
||||
pango_cairo_font_map_set_resolution((PangoCairoFontMap *) font_map, dpi);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef XRANDR
|
||||
static int lookup_active_screen(XRRMonitorInfo *info, int n, int x, int y)
|
||||
{
|
||||
int ret = -1;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (INRECT(x, y, info[i].x, info[i].y,
|
||||
info[i].width, info[i].height)) {
|
||||
ret = i;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
#elif XINERAMA
|
||||
static int lookup_active_screen(XineramaScreenInfo * info, int n, int x, int y)
|
||||
{
|
||||
int ret = -1;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (INRECT(x, y, info[i].x_org, info[i].y_org,
|
||||
info[i].width, info[i].height)) {
|
||||
ret = i;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XRANDR
|
||||
/*
|
||||
* Select the screen on which the Window
|
||||
* should be displayed.
|
||||
*/
|
||||
static int select_screen(XRRMonitorInfo *info, int n)
|
||||
#elif XINERAMA
|
||||
static int select_screen(XineramaScreenInfo * info, int info_len)
|
||||
#endif
|
||||
#if defined(XRANDR) || defined(XINERAMA)
|
||||
{
|
||||
int ret = 0;
|
||||
x_follow_setup_error_handler();
|
||||
@ -996,14 +1043,10 @@ static int select_screen(XineramaScreenInfo * info, int info_len)
|
||||
0, 0, &x, &y, &child_return);
|
||||
}
|
||||
|
||||
for (int i = 0; i < info_len; i++) {
|
||||
if (INRECT(x, y, info[i].x_org,
|
||||
info[i].y_org,
|
||||
info[i].width, info[i].height)) {
|
||||
ret = i;
|
||||
ret = lookup_active_screen(info, n, x, y);
|
||||
|
||||
if (ret > 0)
|
||||
goto sc_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* something seems to be wrong. Fallback to default */
|
||||
ret = settings.monitor >=
|
||||
@ -1022,7 +1065,24 @@ sc_cleanup:
|
||||
*/
|
||||
static void x_screen_info(screen_info * scr)
|
||||
{
|
||||
#ifdef XINERAMA
|
||||
#ifdef XRANDR
|
||||
int n;
|
||||
XRRMonitorInfo *m;
|
||||
|
||||
m = XRRGetMonitors(xctx.dpy, RootWindow(xctx.dpy, DefaultScreen(xctx.dpy)), true, &n);
|
||||
int screen = select_screen(m, n);
|
||||
if (screen >= n) {
|
||||
/* invalid monitor, fallback to default */
|
||||
screen = 0;
|
||||
}
|
||||
|
||||
scr->dim.x = m[screen].x;
|
||||
scr->dim.y = m[screen].y;
|
||||
scr->dim.w = m[screen].width;
|
||||
scr->dim.h = m[screen].height;
|
||||
scr->dim.mmh = m[screen].mheight;
|
||||
XRRFreeMonitors(m);
|
||||
#elif XINERAMA
|
||||
int n;
|
||||
XineramaScreenInfo *info;
|
||||
if ((info = XineramaQueryScreens(xctx.dpy, &n))) {
|
||||
@ -1051,6 +1111,12 @@ static void x_screen_info(screen_info * scr)
|
||||
scr->dim.w = DisplayWidth(xctx.dpy, screen);
|
||||
scr->dim.h = DisplayHeight(xctx.dpy, screen);
|
||||
}
|
||||
|
||||
//Update dpi
|
||||
double dpi = 0.0;
|
||||
|
||||
dpi = get_xft_dpi_value();
|
||||
set_dpi_value(scr, dpi);
|
||||
}
|
||||
|
||||
void x_free(void)
|
||||
|
Loading…
x
Reference in New Issue
Block a user