Use Xlib to read resources (#142)
This commit is contained in:
parent
3b040aabc7
commit
49cde08ed6
2
build.sh
2
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"
|
||||
|
|
|
@ -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()
|
||||
|
|
35
src/main.c
35
src/main.c
|
@ -7,7 +7,10 @@
|
|||
#include <windows.h>
|
||||
#elif __linux__
|
||||
#include <unistd.h>
|
||||
#include "xrdb_parse.h"
|
||||
#include <SDL_syswm.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xresource.h>
|
||||
#elif __APPLE__
|
||||
#include <mach-o/dyld.h>
|
||||
#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
|
||||
|
|
|
@ -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,
|
||||
|
|
139
src/xrdb_parse.c
139
src/xrdb_parse.c
|
@ -1,139 +0,0 @@
|
|||
#ifdef __unix__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#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
|
|
@ -1,6 +0,0 @@
|
|||
#ifndef XRDB_PARSE_H
|
||||
#define XRDB_PARSE_H
|
||||
|
||||
extern int xrdb_find_dpi();
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue