Changing gdm/lightdm user login settings programmatically

Recently, as part of the automated testing efforts in Linaro, I needed to programmatically change the default X session for a user. It used to be the case that editing ~/.dmrc was enough to achieve this. Display managers (DMs), such as gdm and lightdm, would read the contents of the ~/.dmrc at login time to decide which language and X session to use (among other settings). When a user changed a setting through the GUI, the DM would write the new settings to ~/.dmrc (only after successfully logging in, of course).

However, all of this changed with the introduction of AccountsService. As the name suggests, AccountsService provides a service for the management of user accounts, and among other things, some of the login settings that were previously configured in ~/.dmrc. It offers this functionality through the org.freedesktop.Accounts DBus service on the system bus.

Modern Display Managers use AccountsService to manipulate user  login settings, falling back to ~/.dmrc only when the service is unavailable (at least in the case of lightdm). What this means for the end-user is that editing ~/.dmrc manually has no effect. For example, you can try changing the Session field in ~/.dmrc all you want, but next time you log in you will end up in the same session and your ~/.dmrc changes will have been overwritten.

In order to actually change any settings we need to communicate with AccountsService through DBus. The first step is to find out the object that corresponds to the user we want to change the settings for. The path of this object is of the form /org/freedesktop/Accounts/. <USER> is usually of the form User<UID> but there is no guarantee of that.  Thankfully, the /org/freedesktop/Accounts object provides the org.freedesktop.Accounts.FindUserByName and org.freedesktop.Accounts.FindUserById methods, which we can use to get the object path for a user.

Having the user object path, we can use the org.freedesktop.Accounts.User.* methods on the user object to change the required settings.

We can use the dbus-send program to perform the operations mentioned above. For example:

$ USER_PATH=$(dbus-send --print-reply=literal --system --dest=org.freedesktop.Accounts /org/freedesktop/Accounts org.freedesktop.Accounts.FindUserById int64:1000)
$ dbus-send --print-reply --system --dest=org.freedesktop.Accounts $USER_PATH org.freedesktop.Accounts.User.SetXSession string:’xterm’

As I needed to get and set the X session for a user in a user-friendly manner,  I decided to create a small python program instead. You can find the program here:

You can use like:

$ ./ [--user-id <ID>|--user-name <NAME>] set <SESSION>
$ ./ [--user-id <ID>|--user-name <NAME>] get

where <SESSION> is one of the sessions available in /usr/share/xsessions/ . Note that you may need to run as root, depending on the account you want to change the settings for.

For example:

$ ./ --user-id 1000 set xterm

You can easily tweak the program to change another setting instead of the X session.

Update 2012-08-10: Fixed problem with wordpress converting -- (double-dash) to – (en-dash) in code snippets.


glmark2: more than a benchmark


Almost 1.5 year ago, we (at Linaro) set out on a mission to provide consolidation and optimization of GNU/Linux for ARM hardware. Soon after, the Linaro Graphics Working Group was formed to focus on the graphics and user interface parts of the stack. Like all other groups within Linaro, the Graphics WG strived (and still does, of course!) to provide palpable and measurable improvements. One of the tools we needed to ensure this goal, and we found was missing, was a Free Software OpenGL ES 2.0 benchmark.

Why did we even care about this when there surely are professional, proprietary alternatives used in the industry? The answer is simple: we couldn’t imagine doing this any other way.  Linaro, both as an organization and as individuals, strongly believe that Free Software is good for society. Even if we didn’t believe in the ethics of Free Software, using a proprietary solution would have been the wrong choice from a practical point of view. Many of our goals, which reach beyond plain benchmarking, would be very difficult to achieve with a proprietary solution. We wanted a tool that was freely (in every sense) available to all, so that it would provide a common reference point for all developers and users that didn’t have access to the proprietary tools.

Instead of starting completely from scratch, we leveraged an existing GPL licensed desktop GL benchmark, called glmark, and ported it to support OpenGL ES 2.0. We decided to call the new benchmark glmark2. Although OpenGL ES 2.0 was the primary goal for us (this API is prevalent in the ARM world), we continued to treat desktop OpenGL as a first class citizen. This mindset eventually led to what we call the “subset approach”: using only the common subset of desktop OpenGL 2.1 and OpenGL ES 2.0 APIs to produce a single, easily maintainable code base, working happily with both versions.


After the initial porting to OpenGL ES 2.0 was done, and as we continued to work on new features, a set of goals for glmark2 began to crystallize in our minds. These goals transcended the limits of plain benchmarking, and can be summarized as: flexible benchmarking, best practices, validation and educating new developers.

Flexible benchmarking

The primary function of glmark2 is, of course, to provide a comprehensive benchmarking suite. What differentiates glmark2 from other tools is the unique flexibility it delivers. Most existing benchmarking tools just provide the option to run benchmarks from a predefined fixed set. For glmark2, however, we decided that we didn’t want to force our own selections on users. In this spirit, glmark2 offers a suite of scenes that can be used to evaluate many aspects of OpenGL (ES) 2.0 performance. The way in which each scene is rendered is configurable through a set of scene-specific options, that range from the simple, like selecting the texturing mode for the texturing scene, to the complex, like specifying the convolution matrix for the GPU convolution scene. A benchmark is just a scene instantiated with specific options.

For the casual user, who just wants to get an overview of the graphics stack’s performance, glmark2 comes with a predefined set of default benchmarks. For users that need to explore a particular aspect in more depth, we have made it trivial to specify and execute a custom set of benchmarks.

Regarding the actual benchmark content, we draw inspiration from typical applications that use OpenGL, like games, modern user interfaces and our own experience about important features. We have given glmark2 a focus on fundamental techniques used in 3D and 2.5D graphics, so most scenes are relatively simple, but we don’t shy way from other kinds of benchmarks. We already have low-level benchmarks for specific shader features, and we are planning to add high-level benchmarks involving more complex and visually intriguing scenes in the future.

Best practices

The flexibility offered by our option-driven benchmarking approach lends itself naturally to another one of our goals: answering developer questions and providing best practices. “Should I use X or Y to get the best performance/quality/of both worlds on this class of hardware?” is a common form of question among developers. For example, we have implemented a benchmark to test how different methods of uploading data to the GPU (glBufferData vs glMapBuffer, interleaved buffers vs separate buffers etc) affect performance. We hope that the ease with which developers can use different options will make it painless to perform targeted tests and eventually provide best practices advice.


Besides measuring the graphics performance, we also care about output quality. That is, we want to validate the correctness of the graphics stack.  Of course, we don’t want to perform validation manually, by having someone looking at pictures. We want the process to be automatic, ideally as part of our continuous integration efforts.

To handle validation in glmark2 we added a special mode in which we just draw the first frame of each benchmark and fuzzily compare some pixel values against expected reference values. We rely on the 3D pipeline being deterministic, so, if a single pixel is correct, chances are that all pixels are correct. Is this a 100% robust validation solution? No, but it is more than enough for our needs; it’s not our aim to provide a conformance suite.

Educating new developers

The last (but not least) goal we have for glmark2 is a surprising but important one: educating new developers.  We found that one of the main issues developers have when trying to move to modern, programmable 3D APIs, and in particular OpenGL ES 2.0, is the lack of concrete information on how to work with the new APIs, like EGL, and, also, how to apply fundamental 3D techniques that were straightforward before, e.g., lighting. Due to our focus on benchmarks for fundamental techniques, we are actually providing clear examples of how to achieve useful results. We make a special effort to ensure that both the C++ and the shader code are understandable, including comments explaining why and how we are doing things. Developers can use the glmark2 code base as a  launchpad to explore the wonders of modern 3D graphics.

Our journey with glmark2 has been very exciting so far, and the future looks brighter than ever! We are constantly working on new features, and the recent addition of support for Android has made glmark2 one of the most versatile Free Software 3D benchmarking tools available. You can learn more about what we are planning by visiting our blueprints page.

What are you waiting for? Grab glmark2 and start exploring!