diff options
Diffstat (limited to 'platform/x11/os_x11.cpp')
-rw-r--r-- | platform/x11/os_x11.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index b089436a17..eb576b11f4 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -57,6 +57,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> +#include <dlfcn.h> //stupid linux.h #ifdef KEY_TAB @@ -117,6 +118,19 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi char * modifiers = XSetLocaleModifiers ("@im=none"); ERR_FAIL_COND( modifiers == NULL ); + const char* err; + xrr_get_monitors = NULL; + xrandr_handle = dlopen("libXrandr.so", RTLD_LAZY); + err = dlerror(); + if (!xrandr_handle) { + fprintf(stderr, "could not load libXrandr.so, dpi detection disabled. Error: %s\n", err); + } + else { + xrr_get_monitors = (xrr_get_monitors_t) dlsym(xrandr_handle, "XRRGetMonitors"); + if (!xrr_get_monitors) + fprintf(stderr, "could not find symbol XRRGetMonitors, dpi detection will only work on the first screen\nError: %s\n", err); + } + xim = XOpenIM (x11_display, NULL, NULL, NULL); @@ -480,6 +494,9 @@ void OS_X11::finalize() { physics_2d_server->finish(); memdelete(physics_2d_server); + if (xrandr_handle) + dlclose(xrandr_handle); + XUnmapWindow( x11_display, x11_window ); XDestroyWindow( x11_display, x11_window ); @@ -722,6 +739,47 @@ Size2 OS_X11::get_screen_size(int p_screen) const { return size; } +int OS_X11::get_screen_dpi(int p_screen) const { + + //invalid screen? + ERR_FAIL_INDEX_V(p_screen, get_screen_count(), 0); + + //Get physical monitor Dimensions through XRandR and calculate dpi + int event_base, error_base; + const Bool ext_okay = XRRQueryExtension(x11_display,&event_base, &error_base); + + Size2 sc = get_screen_size(p_screen); + if (ext_okay) { + int count = 0; + if (xrr_get_monitors) { + xrr_monitor_info *monitors = xrr_get_monitors(x11_display, x11_window, true, &count); + if (p_screen < count) { + double xdpi = sc.width / (double) monitors[p_screen].mwidth * 25.4; + double ydpi = sc.height / (double) monitors[p_screen].mheight * 25.4; + return (xdpi + ydpi) / 2; + } + } + else if (p_screen == 0) { + XRRScreenSize *sizes = XRRSizes(x11_display, 0, &count); + if (sizes) { + double xdpi = sc.width / (double) sizes[0].mwidth * 25.4; + double ydpi = sc.height / (double) sizes[0].mheight * 25.4; + return (xdpi + ydpi) / 2; + } + } + } + + int width_mm = DisplayWidthMM(x11_display, p_screen); + int height_mm = DisplayHeightMM(x11_display, p_screen); + double xdpi = (width_mm ? sc.width / (double) width_mm * 25.4 : 0); + double ydpi = (height_mm ? sc.height / (double) height_mm * 25.4 : 0); + if (xdpi || xdpi) + return (xdpi + ydpi)/(xdpi && ydpi ? 2 : 1); + + //could not get dpi + return 96; +} + Point2 OS_X11::get_window_position() const { int x,y; Window child; |