diff --git a/build.sh b/build.sh index d66fa422..bfb679b0 100755 --- a/build.sh +++ b/build.sh @@ -3,7 +3,7 @@ cflags+="-Wall -O3 -g -std=gnu11 -fno-strict-aliasing -Isrc -Ilib/font_renderer" cflags+=" $(pkg-config --cflags lua5.2) $(sdl2-config --cflags)" lflags="-static-libgcc -static-libstdc++" -for package in libagg freetype2 lua5.2; do +for package in libagg freetype2 lua5.2 x11; do lflags+=" $(pkg-config --libs $package)" done lflags+=" $(sdl2-config --libs) -lm" diff --git a/meson.build b/meson.build index 4da88afa..c1a996d4 100644 --- a/meson.build +++ b/meson.build @@ -3,6 +3,7 @@ project('lite', 'c', 'cpp', default_options : ['c_std=gnu11', 'cpp_std=c++03']) cc = meson.get_compiler('c') libm = cc.find_library('m', required : false) libdl = cc.find_library('dl', required : false) +libx11 = dependency('x11', required : false) lua_dep = dependency('lua5.2', required : false) if not lua_dep.found() diff --git a/src/main.c b/src/main.c index 0024a717..9533d4a4 100644 --- a/src/main.c +++ b/src/main.c @@ -7,7 +7,10 @@ #include #elif __linux__ #include - #include "xrdb_parse.h" + #include + #include + #include + #include #elif __APPLE__ #include #endif @@ -16,16 +19,32 @@ SDL_Window *window; static double get_scale(void) { -#if _WIN32 +#ifdef _WIN32 float dpi; SDL_GetDisplayDPI(0, NULL, &dpi, NULL); return dpi / 96.0; -#elif __unix__ - int xft_dpi = xrdb_find_dpi(); - if (xft_dpi > 0) { - return xft_dpi / 96.0; - } - return 1.0; +#elif __linux__ + SDL_SysWMinfo info; + XrmDatabase db; + XrmValue value; + char *type = NULL; + + SDL_VERSION(&info.version); + if (!SDL_GetWindowWMInfo(window, &info) + || info.subsystem != SDL_SYSWM_X11) + return 1.0; + + char *resource = XResourceManagerString(info.info.x11.display); + if (resource == NULL) + return 1.0; + + XrmInitialize(); + db = XrmGetStringDatabase(resource); + if (XrmGetResource(db, "Xft.dpi", "String", &type, &value) == False + || value.addr == NULL) + return 1.0; + + return atof(value.addr) / 96.0; #else return 1.0; #endif diff --git a/src/meson.build b/src/meson.build index d760b165..6a56bae6 100644 --- a/src/meson.build +++ b/src/meson.build @@ -6,14 +6,13 @@ lite_sources = [ 'api/system.c', 'renderer.c', 'rencache.c', - 'xrdb_parse.c', 'main.c', ] executable('lite', lite_sources + lite_rc, include_directories: [lite_include, font_renderer_include], - dependencies: [lua_dep, sdl_dep, libm, libdl], + dependencies: [lua_dep, sdl_dep, libm, libdl, libx11], c_args: lite_cargs, link_with: libfontrenderer, link_args: lite_link_args, diff --git a/src/xrdb_parse.c b/src/xrdb_parse.c deleted file mode 100644 index 47018106..00000000 --- a/src/xrdb_parse.c +++ /dev/null @@ -1,139 +0,0 @@ -#ifdef __unix__ - -#include -#include -#include -#include -#include -#include "xrdb_parse.h" - -extern char **environ; - -static int join_path(char buf[], int buf_size, const char *path, const char *name) { - const char *path_delim = strchr(path, ':'); - if (!path_delim) { - path_delim = path + strlen(path); - } - const int path_len = path_delim - path, name_len = strlen(name); - if (buf_size < path_len + 1 + name_len + 1) return -1; - memcpy(buf, path, path_len); - buf[path_len] = '/'; - memcpy(buf + path_len + 1, name, name_len + 1); - return 0; -} - - -static int xrdb_popen (int *pid_ptr) { - int fd[2]; - - if (pipe(fd) != 0) return -1; - int read_fd = fd[0]; - int write_fd = fd[1]; - - int pid = fork(); - if (pid == 0) { - close(read_fd); - dup2(write_fd, STDOUT_FILENO); - close(write_fd); - char *path = getenv("PATH"); - char xrdb_filename[256]; - while (path) { - char *xrgb_argv[3] = {"xrdb", "-query", NULL}; - if (join_path(xrdb_filename, 256, path, "xrdb") == 0) { - execve(xrdb_filename, xrgb_argv, environ); - } - path = strchr(path, ':'); - if (path) { - path++; - } - } - } else { - *pid_ptr = pid; - close(write_fd); - return read_fd; - } - return -1; -} - - -static int xrdb_try_dpi_match(const char *line, int len) { - if (len >= 8 && strncmp(line, "Xft.dpi:", 8) == 0) { - for (line += 8; *line && (*line == '\t' || *line == ' '); line++) { } - int dpi = 0; - for ( ; *line >= '0' && *line <= '9'; line++) { - dpi = dpi * 10 + ((int) (*line) - (int) '0'); - } - return dpi; - } - return -1; -} - -static void xrdb_complete_reading(int read_fd, char *buf, size_t buf_size) { - while (1) { - int nr = read(read_fd, buf, buf_size); - if (nr <= 0) return; - } -} - -#define XRDB_READ_BUF_SIZE 256 -static int xrdb_parse_for_dpi(int read_fd) { - char buf[XRDB_READ_BUF_SIZE]; - char buf_remaining = 0; - while (1) { - int nr = read(read_fd, buf + buf_remaining, XRDB_READ_BUF_SIZE - buf_remaining); - if (nr > 0) { - const char * const buf_limit = buf + nr + buf_remaining; - char *line_start = buf; - while (line_start < buf_limit) { - char *nlptr = line_start; - while (nlptr < buf_limit && *nlptr != '\n') { - nlptr++; - } - if (nlptr < buf_limit) { - int dpi_read = xrdb_try_dpi_match(line_start, nlptr - line_start); - if (dpi_read > 0) { - xrdb_complete_reading(read_fd, buf, XRDB_READ_BUF_SIZE); - return dpi_read; - } - /* doesn't match: position after newline to search again */ - line_start = nlptr + 1; - } else { - /* No newline found: copy the remaining part at the beginning of buf - and read again from file descriptor. */ - buf_remaining = buf_limit - line_start; - if (buf_remaining >= XRDB_READ_BUF_SIZE) { - /* Line is too long for the buffer: skip. */ - buf_remaining = 0; - } else { - memmove(buf, line_start, buf_remaining); - } - break; - } - } - } else { - if (nr == 0 && buf_remaining > 0) { - int dpi_read = xrdb_try_dpi_match(buf, buf_remaining); - if (dpi_read > 0) { - return dpi_read; - } - } - break; - } - } - return -1; -} - -int xrdb_find_dpi() { - int xrdb_pid; - int read_fd = xrdb_popen(&xrdb_pid); - if (read_fd >= 0) { - int dpi_read = xrdb_parse_for_dpi(read_fd); - int child_status; - waitpid(xrdb_pid, &child_status, 0); - close(read_fd); - return dpi_read; - } - return -1; -} - -#endif diff --git a/src/xrdb_parse.h b/src/xrdb_parse.h deleted file mode 100644 index e7ef8396..00000000 --- a/src/xrdb_parse.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef XRDB_PARSE_H -#define XRDB_PARSE_H - -extern int xrdb_find_dpi(); - -#endif