Using and Specifying X Resources Jim Fulton MIT X Consortium Copyright 1988 X Consortium Permission to use, copy, modify, and distribute this documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the X Consortium not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. * * * * The Xlib Resource Manager provides a set of tools for specifying and manipulating user preferences (e.g. geometry, colors, fonts). Simple programming interfaces to it are provided by the X Toolkit and by the Xlib routine XGetDefault. Resources, also refered to as "defaults" in older versions of X, are simply pairs that are frequently used to control the appearence or function of particular program or subsystem. They provide a convenient way to tailor whole collections of applications with a minimal amount of work. In previous versions of X, defaults were stored in a .Xdefaults file in each user's home directory, on every machine. In addition to requiring duplicate copies of the defaults, it did not lend itself to conditional specifications (particularly if the user used both monochrome and color displays). In X11, these problems are solved by using the window property mechanism in the X protocol to store resources in the server, where they are available to all clients. As a result, defaults may now be dynamically specified based on the particular display being used. This is particularly useful in setting up different defaults for monochrome and color displays. Furthermore, a new convention for specifying resources from the command line has been established (and is supported by all clients of the X Toolkit). Resources are usually as "program.name.subname.etc: value", one per line in resource files, or one per -xrm argument. Names are hierarchies, usually corresponding to major structures within an application (where structures are often objects like windows, panels, menus, scrollbars, etc.). The various subnames are called components and are specified left to right from most general to least general. If we take the "xmh" application as an example, we can see that its display is made up of sections called "panes", some of which in turn contain command buttons. The "include" button (used to retreive new mail) in the "toc" (table of contents) pane could be named as follows: program pane object group subobject name name name name xmh toc buttons include An object's fully specified name (such as "xmh.toc.buttons.include" in the example above) is called the "instance" name for that object. In addition, each component belongs to a collection of similar components (such as the set of all panes, the set of all buttons, etc.) that can be specified using a "class" name. In the above example, if we assume that the xmh program is one of possibly several "Xmh" types of programs (just as "gnuemacs" and "microemacs" might be thought of as instances of the class of "Emacs" programs), we could build the following class name: application top level second level third level type area type object type object type Xmh VPaned Box Command ... By convention, instance name components begin with lowercase letters and class name components begin with uppercase letters. Components that are made up of more than one word have the succeeding words capitalized and concatentated without any spaces. Thus, an instance of an icon pixmap might be called "iconPixmap" whereas the class of icon pixmaps would be called "IconPixmap". The capitalization is important because resource names may contain both instance and class name components within the same specification (for example, "gnuemacs.VPaned.cursorColor: blue"). Class names allow default values to be specified for all versions of given object. Instance names allow a value for a particular version to be given that overrides the class value, and can be used to specify exceptions to the rules outlined by the class names. For example, we could specify that that all command buttons in button boxes in vertical panes should have a background color of blue, except for "include", which should be red: with *VPaned.Box.Command.Background: blue xmh.toc.buttons.include.background: red Furthermore, resource name hierarchies do not have to be fully specified. In the preceeding example, we listed each of the individual components; however, this can be quite cumbersome. Instead of having to give a full specification for each set of objects (there might be slider bars, or edit windows, or any number of other types), we can just "wildcard", or omit, the intervening components by using the "*" separator in place of the "." separator. In general, it is a good idea to use the "*" instead of "." in case you've forgotten any intervening components or in case new levels are inserted into the middle of the hierarchy. Xmh*VPaned*Background: blue xmh*toc.buttons.include.background: red The distiction between classes and instances is important. For example, many text applications have some notion of background, foreground, border, pointer, and cursor or marker color. Usually the background is set to one color, and all of the other attributes are set to another so that they may be seen on a monochrome display. To allow users of color displays to set any or all of them, the colors may be organized into classes as follows: instance name class name background Background foreground Foreground borderColor Foreground pointerColor Foreground cursorColor Foreground Then, to configure the application to run in "monochrome" mode, but using two colors, you would only have to use two specifications: obj*Background: blue obj*Foreground: red Then, if you decided that you wanted the cursor to be yellow, but the pointer and the border to remain the same as the foreground, you would only need one new resource specification: obj*cursorColor: yellow Because class and instance names are distinguishable by case, both types of names may be given in a single resource specification. Section 10.11 of the Xlib manual gives the following additional examples (note, the "xmh" program may use other names, these are for example only): xmh*background: red *command.font: 8x13 *command.background: blue *Command.Foreground: green xmh*toc*Command.activeForeground: black The resource hierarchy "xmh.toc*Command.activeForeground" specifies a particular color resource (in this case, the active foreground color) of all components of class Command that are contained within the "toc" in the xmh application. Although this is very powerful, figuring out that this can be specified at all, let alone how, is currently a problem with the documentation for many of the more complex clients of the Resource Manager. Eventually, widgets should be documented just as commands are today: there should be descriptions of the instance names, class names, and allowable values for each of the widget's resources. Application documentation would then only need to describe how widgets are combined. Until then, the best places to look for information on which resources may be specified are: 1. the manual pages for the application 2. any documentation for the widgets used by the application 3. any application resource files in /usr/lib/X11/app-defaults/ 4. any XtResource tables in the the application or the widget sources Under X11, you have a lot of flexibility as to where defaults are defined. The Resource Manager obtains resource specifications from the following places: 1. from any application-specific resource files, usually stored in /usr/lib/X11/app-defaults/. 2. from any application-specific resources files in the directory named by the environment variable XAPPLRESDIR (default value is $HOME) for programs written using the X Toolkit. 3. from the RESOURCE_MANAGER property on the root window of screen 0; these are stored using the xrdb program. If this property is not defined, then $HOME/.Xdefaults will be read to provide compatibility with X10 (although the resource specification format has changed somewhat). 4. from any user-specific defaults stored in a file whose name is set in the environment variable XENVIRONMENT. 5. from the -xrm command line option (for programs written with the X Toolkit). Resources are usually loaded from a file into the RESOURCE_MANAGER property using the "xrdb" program from whatever script you use to start up X. Sites that use the xdm Display Manager will most likely provide for loading in user-specified resources automatically. See your system manager for details. I have a script called "xsetup" on every machine that I use that starts up the appropriate programs for that machine (terminal emulators, a mailbox on my home machine, clocks, load average monitors, etc.). For example, I use the following on my desktop workstation to get my base environment going: #!/bin/sh xrdb -load $HOME/.Xresources stty erase '^?' xmodmap -p $HOME/.xmodmap xset b 100 400 c 50 s 1800 uwm & xclock -geometry 48x48-1+1 & xload -geometry 48x48-1+100 & The xrdb program reads my global defaults from $HOME/.Xresources. This is where I define resources that I want to have used by clients on every machine: bitmap*Dashed: off XTerm*multiScroll: on XTerm*jumpScroll: on XTerm*reverseWrap: on XTerm*curses: on XTerm*font: 6x10 emacs*Geometry: 80x65-0-0 emacs*Background: #5b7686 emacs*Foreground: white emacs*Cursor: white emacs*BorderColor: white emacs*Font: 6x10 I put machine-specific defaults (usually colors so that I can easily distinguish windows on various machines) in a file called ~/.Xenv and set the XENVIRONMENT variable in my .login to point to that file. For example, I use the following defaults on my desktop workstation: XTerm*Background: black XTerm*Foreground: green XTerm*BorderColor: white xclock*analog: on xclock*borderWidth: 0 xclock*padding: 2 xclock*Background: black xclock*Foreground: red xload*Background: black xload*Foreground: cyan For consistency, I create an xsetup script and a .Xenv file (if I want any machine specific defaults) on each of the machines that I commonly use. This allows me to just login, type "xsetup", and get right to work. Continuing the example started above, here is the xsetup file that I use on my server: #!/bin/sh xterm -geometry 80x55+0+0 & xterm -geometry 80x65+488+1 & xterm -geometry 80x20+0-0 & xload =48x48-1+150 & xbiff -rv =48x48-1+50 & and the corresponding .Xenv file: XTerm*Foreground: white XTerm*Background: #c00 XTerm*BorderColor: white tinyxterm*Font: 3x5 tinyxterm*Geometry: 80x24 bigxterm*Font: 9x15 bigxterm*Geometry: 80x55 xload*Background: black xload*Foreground: red xbiff*borderWidth: 0 xbiff*Background: white xbiff*Foreground: blue xbiff*reverseVideo: on Note the use of the alternative instance names "tinyxterm" and "bigxterm". This allows me to quickly get a different "flavor" of xterm by simply invoking "xterm -name tinyxterm" or "xterm -name bigxterm". The xrdb program uses the C preprocessor to provide conditionals based on the configuration of the server being used. This is very useful if you commonly use different types of servers (such as monochrome and color) from the same account. See the xrdb(1) manual page for more details. Summary X11 gives you many choices as to how to organize your screen, specify your defaults, and start up various programs. I frequently have 5 xterms, 1 clock, 2 load average monitors, 1 mailbox, an emacs, and uwm all running at once. The scheme outlined above is somewhat of a brute force approach, but works well for me. The highlights are: 1. Use the Display Manager xdm. It is very flexible and can be tailored to provide any sort of default environment. 2. Create X startup scripts that run the appropriate programs to set up your environment (start your window manager, load defaults, etc.). I call these scripts "xsetup" on each machine. 3. Put global resources in one file that you run xrdb on from your X startup script. I call this file ~/.Xresources. In general, you should use "*" instead of "." to separate components. 4. Put machine-specific resources in another file and set the XENVINRONMENT variable to point to it. I call this file ~/.Xenv. Use "*" instead of "." to separate components. Where to look for more information: X(1), xrdb(1), Section 10.11 of the Xlib manual, XGetDefault(3X), Section 4.2 of the X Toolkit manual, application manual pages