Getting the Most Out of X Resources
Do you ever wonder how some peoples' xclocks and xterms always start up with different colors than boring old black and white? Do you wish those Athena 3-D widgets (discussed in Linux Journal, issue 15) looked a bit more like the Motif ones they are supposed to emulate? Through the magic of something called X Resources, you can make all this happen—and a lot more.
Resources may look confusing and complex at first glance, like something only a programmer with a mean streak would foist upon the unwitting user. It's true that resources are very closely tied to X programming, which is why they can appear so arcane. However, with a little practice, you can customize applications to suit your own personal preferences, and kiss “vanilla X” goodbye forever.
Color has already been mentioned, but to dismiss resources as a simple color control mechanism would be a mistake. Don't like an application's choice of fonts? Change them. Want to change the way the cursor appears? You can do that too.
Resources can even be used to modify the entire behaviour of an application, from the appearance and labels of buttons and pull-down menus, to the actual functions that these items call in the program. For instance, if you think that the “Quit” label on a button is too bland, you can easily substitute “Kill”, or something even more imaginative.
X Resources are stored in several locations. Applications often have a default set of resources that are stored in a file in the /usr/lib/X11/app-defaults directory. For example, you will find resource files for both xterm and xload in that directory. Notice the files usually have the first two letters capitalized, i.e. XTerm, and XLoad. While this is only a de-facto standard, it is related to the applications class name, which we'll get to later.
Besides these application-specific files, there are two other files in which you can store resources. If you have a file in your home directory called .Xdefaults, it will be loaded when your X session starts (either through xdm or startx), replacing any system-wide resources that might have been defined (stored in /usr/lib/X11/Xdefaults). A second file, .Xresources, doesn't replace the system defaults but instead is merged with them. For that reason, you probably want to use this file for your own resources instead of .Xdefaults.
Resources are specified in one of the following formats:
name*variable: valuename.variable.variable: value
Resources are case sensitive, and you should be sure that there is at least a space or a tab after the colon, before the value specified. The first format listed, which utilizes the * separator (called loose binding), is used to indicate that all resources of a program with name name and variable variable are to acquire value value. For instance, the resource
will cause xedit to use a 7x14 fixed font for everything, including the main window and the menus. (We will see how to find resource names later in the article—take them on faith for now.) But what if you only want to change the font in a particular area of a program? In that case, the . notation (called tight binding) would be used. This notation allows you to be more specific than loose binding allows:
will make two labels in xedit use the fixed font. However, the default font (7x14, as set by the first resource) will be used everywhere else. Note that although the first resource applies to every font resource in the Xedit program, including those two labels, the second resource is the one used for those labels because it is more specific. More specific resources are always used in preference to less specific resources.
Resources, and the widgets they modify, have a hierarchical nature. “What's a widget?” you ask. Widgets are the basic building blocks, or objects, of X programs. Some example widgets with which everyone is familiar: scrollbars, text-entry fields, buttons, and checkboxes. In the above resource, the Label widget is a “child” of the Paned widget, which is a “child” of Xedit. This will become more clear when the editres program is introduced below.
One other note before we continue: a distinction must be made between classes and instances of a particular class. In the above resource, Label specifies any instance of the widget class Label. There are two that match the specification, whose names are bc_label and labelWindow. All classes begin with a capital letter by definition; Label is the class, and bc_label and labelWindow, which start with lower case letters, are the instances of that class.
You can specify instances as well as classes, so that only one particular widget is affected; you can add the following resource:
which will set the font for one of the two Label widgets back to 7x14—it is more specific than the previous resource.
It is usually more convenient to set the resources for an entire class of widgets than for an individual instance, as you typically want to make the entire application look consistent.