Obtaining Display Information on Mobile Internet Devices

Submit New Article

August 16, 2009 9:00 PM PDT


Introduction


With the advent of Mobile Internet Devices (MIDs) based on Intel® Architecture, the porting of desktop and laptop applications to mobile hand-held devices has become significantly easier. However, one area of continued challenge is the adapting of screen layout and user-interface navigation to this small form factor. These devices have a screen size that ranges from 4.5" to 7" and a resolution of at least 800 x 480 pixels. Device characteristics of increased pixel density, combined with the ability to rotate between landscape and portrait orientations, and the strict display brightness constraints necessary to preserve battery power, make it essential for compelling software to be aware of the device's display attributes. Ideally an application will obtain this information at runtime in order to dynamically adapt.

Since MID devices run Moblin-based, Linux operating system, this paper will describe several mechanisms for obtaining display information in a Linux compliant manner. Unfortunately, all display information isn't available from one easily accessible source, so this document will cover the various sources of screen information. The X Window extension X Resize and Rotation (XRandR) is a good source for resolution and screen orientation. Physical screen dimensions are also available through the XRandR API but accuracy of this particular information is dependent upon screen drivers providing accurate EDID values. Another source of information is the Hardware Access Layer (HAL). This component exposes a wide range of system information; the properties of interest in this context are screen brightness and the levels of brightness. These pieces of information, as well as other platform and context information, can also be retrieved using the Platform Awareness Service, available from Intel® on Moblin based platforms.

Getting Display Information from XWindows

The X11 library is designed to provide a connection to the X Server. It allows access to size and rotation information about the root window of the screen and also provides the ability to set these values.

In order to get to the resolution information, several preliminary calls need to be made to connect to the X Server and get to the desired data structure. First, a call to XOpenDisplay() connects to the X Server and returns a Display pointer. The X11 architecture allows for multiple Windows, with the root window being the one that holds the information we want. A call to RootWindow() will return this window. Once the display is opened and the Root Window is obtained the third call can be made to XRRGetScreenInfo() which returns an XRRScreenConfiguration structure.
#include 

Display *dpy;
Window root;
XRRScreenConfiguration *sc;

dpy = XOpenDisplay (NULL); //open the current display
if (dpy)
{
root = RootWindow (dpy, 0);
sc = XRRGetScreenInfo (dpy, root);


After the XRRScreenConfiguration structure is obtained it can be used to make the call that actually returns the resolution information. X11 allows for the possibility of an array of sizes of which the first represents the current display. A call to XRRConfigSizes(), passing in the XRRScreenConfiguration, will return this array. Each element of the array contains a width and height value.

XRRScreenSize *sizes;
unsigned int nsize;
unsigned int xres, yres;

sizes = XRRConfigSizes (sc, &nsize);

if (0 >= nsize)
{
xres = sizes[0].width;
yres = sizes[0].height;

}


The physical dimension of the screen can be obtained directly from the XRRScreenConfiguration structure via the screen member. It should be noted however that the accuracy of this information is dependent on the screen driver providing correct values from the display device's Extended Display Identification Data (EDID) block[1]. At the time or this writing the display devices on a number of publicly available MIDs do not provide correct information.

// Physical dimensions

int mwidth, mheight;

mwidth = sc->screen->mwidth;
mheight = sc->screen->mheight;


The other interesting display attribute that can be obtained from X11 is the screen orientation. According X11 there are four settings of rotation; 0%, 90%, 180% and 270%. X will also tell you which of the rotations are supported on the current device. A call to XRRRotations(), passing in the previously obtained Display pointer will return this info as a bit array. The X11 header file defines values that can be used to mask out the supported rotations.

// Screen Rotation – What rotations are supported

Rotation rotations_supported, cur_rotation;
bool bRotate_0, bRotate_90, bRotate_180, bRotate_270;

rotations_supported = XRRRotations (dpy, 0, &cur_rotation);

if (1 >= rotations_supported)
return; // Screen rotation not supported
else
{
if ( 0 != ( rotations_supported & RR_Rotate_0))
bRotate_0 = true;
if ( 0 != (rotations & RR_Rotate_90))
bRotate_90 = true;
if ( 0 != (rotations & RR_Rotate_180))
bRotate_180 = true;
if ( 0 != (rotations & RR_Rotate_270))
bRotate_270 = true;
}


The cur_rotation variable that was passed to XRRRotations() specifies the current rotation. Again the X11 header file defines values used to interpret the current rotation value.

switch (cur_rotation) 
{
case RR_Rotate_0:
...
break;
case RR_Rotate_90:
...
break;
case RR_Rotate_180:
...
break;
case RR_Rotate_270:
...
break;
default:
return false;
}


Finally, cleanup needs to be done to free the XRRScreenConfiguration struct and close the display.

XRRFreeScreenConfigInfo (sc);
XCloseDisplay(dpy);


Getting Screen Brightness information from the HAL


Screen brightness information is not inherently necessary for MID screen layout and navigation. However, since battery power savings is one of the most critical aspects of MID design, screen brightness management becomes an important factor of overall efficient power usage, and an application may wish to modify its behavior or appearance based on screen brightness settings.

The HAL is a software layer that provides access to various pieces of hardware on a system. Metadata is available describing the hardware, its state and notifications of change. A Device Object with accompanying properties is used to represent each piece of hardware. Namespaces are also defined to group the properties into logical categories. Finally, D-Bus Interfaces are defined as the access mechanism to the properties and notifications within a namespace. For background information on the D-BUS architecture and usage refer to these locations:

To make a D-BUS connection to the HAL, several steps are necessary. First, a pointer to the System Bus is obtained by calling dbus_g_bus_get()[2]. With the system bus pointer, an interface can be obtained to the HAL Manager by calling dbus_g_proxy_new_for_name(). This manager will allow a search for all objects on the system with the "laptop_panel" capability. The object that provides "laptop_panel" capability is where screen brightness information is found.

DBusGConnection *systemBus;
GError *error
DBusGProxy *managerProxy;
char **deviceList;
int len;

// Initialize the System DBus connection
systemBus = dbus_g_bus_get(DBUS_BUS_SYSTEM, error);

if (systemBus == NULL)
return FALSE;

managerProxy = dbus_g_proxy_new_for_name( systemBus,
"org.freedesktop.Hal",
"/org/freedesktop/Hal/Manager",
"org.freedesktop.Hal.Manager" );

dbus_g_proxy_call(managerProxy, "FindDeviceByCapability", &error,
G_TYPE_STRING, "laptop_panel", G_TYPE_INVALID,
G_TYPE_STRV, &deviceList, G_TYPE_INVALID);
len = g_strv_length(deviceList);

if (len = 0)
return false;


Now that we have a pointer to the list of laptop_panel objects we can get the interface that directly provides the screen brightness properties (note the following code assumes there is only one screen attached to the system). This is done with the same call used to obtain the HAL Manager but specifies the Device.LaptopPanel interface as the fourth parameter.

char **devices_ptr;
DBusGProxy *deviceProxy;

devices_ptr = deviceList;

deviceProxy = dbus_g_proxy_new_for_name( systemBus,
"org.freedesktop.Hal",
*devices_ptr,
"org.freedesktop.Hal.Device.LaptopPanel" );



To get the current brightness setting, we need to call a method of the LaptopPanel interface called GetBrightness. This is done again with dbus_g_proxy_call function but takes no parameters and returns the brightness as an integer.

uint brightness;

dbus_g_proxy_call(deviceProxy, "GetBrightness", &error,
G_TYPE_INVALID,
G_TYPE_UINT, &brightness, G_TYPE_INVALID);



Conclusion


By obtaining a few basic pieces of screen display information (resolution, orientation, physical dimensions and screen brightness) an application is poised to adapt efficiently and dynamically to the various MID form factors and their changing display characteristics. With this information in hand, the real work of creating MID optimized UI designs and navigation can begin!

References


[1] For more information see http://www.vesa.org/vesa-standards/ or http://en.wikipedia.org/wiki/Extended_display_identification_data

[2] This is actually a glib wrapper to the D-Bus function that retrieves the bus. The glib wrapper is used in this discussion because it is less complex than using D-Bus directly.