From 8b23a6c7e1aee255004dd19098d4c2462b61b849 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 3 Mar 2009 19:30:32 -0800 Subject: auto import from //depot/cupcake/@135843 --- android/utils/display.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 android/utils/display.c (limited to 'android/utils/display.c') diff --git a/android/utils/display.c b/android/utils/display.c new file mode 100644 index 0000000..e1ba507 --- /dev/null +++ b/android/utils/display.c @@ -0,0 +1,245 @@ +/* Copyright (C) 2007-2008 The Android Open Source Project +** +** This software is licensed under the terms of the GNU General Public +** License version 2, as published by the Free Software Foundation, and +** may be copied, distributed, and modified under those terms. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +*/ + +#include "android/utils/display.h" +#include "android/utils/debug.h" + +#define D(...) VERBOSE_PRINT(init,__VA_ARGS__) + +/** HOST RESOLUTION SETTINGS + ** + ** return the main monitor's DPI resolution according to the host device + ** beware: this is not always reliable or even obtainable. + ** + ** returns 0 on success, or -1 in case of error (e.g. the system returns funky values) + **/ + +/** NOTE: the following code assumes that we exclusively use X11 on Linux, and Quartz on OS X + **/ + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN +#include +#include + +int +get_monitor_resolution( int *px_dpi, int *py_dpi ) +{ + HDC displayDC = CreateDC( "DISPLAY", NULL, NULL, NULL ); + int xdpi, ydpi; + + if (displayDC == NULL) { + D( "%s: could not get display DC\n", __FUNCTION__ ); + return -1; + } + xdpi = GetDeviceCaps( displayDC, LOGPIXELSX ); + ydpi = GetDeviceCaps( displayDC, LOGPIXELSY ); + + /* sanity checks */ + if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) { + D( "%s: bad resolution: xpi=%d ydpi=%d", __FUNCTION__, + xdpi, ydpi ); + return -1; + } + + *px_dpi = xdpi; + *py_dpi = ydpi; + return 0; +} + +int +get_nearest_monitor_rect( int *x, int *y, int *width, int *height ) +{ + SDL_SysWMinfo info; + HMONITOR monitor; + MONITORINFO monitorInfo; + + SDL_VERSION(&info.version); + + if ( !SDL_GetWMInfo(&info) ) { + D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError()); + return -1; + } + + monitor = MonitorFromWindow( info.window, MONITOR_DEFAULTTONEAREST ); + monitorInfo.cbSize = sizeof(monitorInfo); + GetMonitorInfo( monitor, &monitorInfo ); + + *x = monitorInfo.rcMonitor.left; + *y = monitorInfo.rcMonitor.top; + *width = monitorInfo.rcMonitor.right - *x; + *height = monitorInfo.rcMonitor.bottom - *y; + + D("%s: found (x,y,w,h)=(%d,%d,%d,%d)", __FUNCTION__, + *x, *y, *width, *height); + + return 0; +} + + +#elif defined __APPLE__ + +/* the real implementation is in display-quartz.m, but + * unfortunately, the Android build system doesn't know + * how to build Objective-C sources, so provide stubs + * here instead. + * + * CONFIG_NO_COCOA is set by Makefile.android + */ + +#ifdef CONFIG_NO_COCOA +int +get_monitor_resolution( int *px_dpi, int *py_dpi ) +{ + return -1; +} + +int +get_nearest_monitor_rect( int *x, int *y, int *width, int *height ) +{ + return -1; +} +#endif /* CONFIG_NO_COCOA */ + +#else /* Linux and others */ +#include +#include +#include +#include +#define MM_PER_INCH 25.4 + +#define DYNLINK_FUNCTIONS \ + DYNLINK_FUNC(int,XDefaultScreen,(Display*)) \ + DYNLINK_FUNC(int,XDisplayWidth,(Display*,int)) \ + DYNLINK_FUNC(int,XDisplayWidthMM,(Display*,int)) \ + DYNLINK_FUNC(int,XDisplayHeight,(Display*,int)) \ + DYNLINK_FUNC(int,XDisplayHeightMM,(Display*,int)) \ + +#define DYNLINK_FUNCTIONS_INIT \ + x11_dynlink_init + +#include "dynlink.h" + +static int x11_lib_inited; +static void* x11_lib; + +int +x11_lib_init( void ) +{ + if (!x11_lib_inited) { + x11_lib_inited = 1; + + x11_lib = dlopen( "libX11.so", RTLD_NOW ); + + if (x11_lib == NULL) { + x11_lib = dlopen( "libX11.so.6", RTLD_NOW ); + } + if (x11_lib == NULL) { + D("%s: Could not find libX11.so on this machine", + __FUNCTION__); + return -1; + } + + if (x11_dynlink_init(x11_lib) < 0) { + D("%s: didn't find necessary symbols in libX11.so", + __FUNCTION__); + dlclose(x11_lib); + x11_lib = NULL; + } + } + return x11_lib ? 0 : -1; +} + + +int +get_monitor_resolution( int *px_dpi, int *py_dpi ) +{ + SDL_SysWMinfo info; + Display* display; + int screen; + int width, width_mm, height, height_mm, xdpi, ydpi; + + SDL_VERSION(&info.version); + + if ( !SDL_GetWMInfo(&info) ) { + D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError()); + return -1; + } + + if (x11_lib_init() < 0) + return -1; + + display = info.info.x11.display; + screen = FF(XDefaultScreen)(display); + + width = FF(XDisplayWidth)(display, screen); + width_mm = FF(XDisplayWidthMM)(display, screen); + height = FF(XDisplayHeight)(display, screen); + height_mm = FF(XDisplayHeightMM)(display, screen); + + if (width_mm <= 0 || height_mm <= 0) { + D( "%s: bad screen dimensions: width_mm = %d, height_mm = %d", + __FUNCTION__, width_mm, height_mm); + return -1; + } + + D( "%s: found screen width=%d height=%d width_mm=%d height_mm=%d", + __FUNCTION__, width, height, width_mm, height_mm ); + + xdpi = width * MM_PER_INCH / width_mm; + ydpi = height * MM_PER_INCH / height_mm; + + if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) { + D( "%s: bad resolution: xpi=%d ydpi=%d", __FUNCTION__, + xdpi, ydpi ); + return -1; + } + + *px_dpi = xdpi; + *py_dpi = ydpi; + + return 0; +} + +int +get_nearest_monitor_rect( int *x, int *y, int *width, int *height ) +{ + SDL_SysWMinfo info; + Display* display; + int screen; + + SDL_VERSION(&info.version); + + if ( !SDL_GetWMInfo(&info) ) { + D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError()); + return -1; + } + + if (x11_lib_init() < 0) + return -1; + + display = info.info.x11.display; + screen = FF(XDefaultScreen)(display); + + *x = 0; + *y = 0; + *width = FF(XDisplayWidth)(display, screen); + *height = FF(XDisplayHeight)(display, screen); + + D("%s: found (x,y,w,h)=(%d,%d,%d,%d)", __FUNCTION__, + *x, *y, *width, *height); + + return 0; +} + +#endif -- cgit v1.1