Applications do not communicate with the X server directly. Instead, they use one or more libraries that provide high-level interfaces to the X protocol. The three principal libraries available to a Motif application are Xlib, the X Toolkit Intrinsics (Xt), and the Motif toolkit.
X clients do not have to deal with the server at the level of the X protocol. X includes a C language client interface to the protocol, called Xlib. Among the Xlib facilities are the following:
The resource manager is the keystone of a fundamental tenet of X: that the user and application should control the appearance, interaction style, and other optional characteristics of a client. For example, the background and foreground colors and the fonts used by an application might be represented as resources. Typically, an application provides default values for such resources but allows the user to override the defaults.
A resource is a triple consisting of a name, a class, and a value. A class may include a set of resources with different names. Resources may be arranged hierarchically; a name and class may consist of components, each identifying the name or class of a particular level of the hierarchy. The fully qualified name or class of a resource is the list of names or classes at all levels, starting with the name or class of the application and ending with the name or class of the resource itself.
The resource manager permits a user or application to specify resource values in a file, on the command line while starting the application, or by calling an Xrm routine in the program. A resource specification must include either the name or the class of the resource, but it may be either partially or fully qualified according to name, class, or a mixture of name and class components. The resulting resource database may include a variety of general and specific resource specifications. When an application queries the database for a resource value, it supplies a fully qualified name and class. The resource manager uses a search algorithm that returns the value from the most specific specification that matches the requested name and class.
Although Xlib provides the fundamental means of interacting with the X server, developing a complex application using only Xlib would be a formidable task. Xlib essentially supplies the primitives for an X client. A complex application needs to combine these primitives into constructs that handle aspects of interaction with the server in a more general way.
X includes a library, the X Toolkit Intrinsics (abbreviated Xt), that supplies some of these higher-level interfaces. Three of the most important Xt contributions are the following:
At the heart of Xt is a set of data abstractions built on an object metaphor. Each of these objects, called a widget, is a combination of state and procedure. Each instance of a widget is a member of a class. A widget class holds a set of procedures and data structures that are common to all widgets of that class. A widget instance contains the procedures and data structures that are particular to that single widget. A widget instance also has a pointer to its class.
Each widget class typically provides the general behavior associated with a particular kind of interaction with the user. For example, Motif has a widget class designed to let the user enter and edit text. This class provides the general behavior to support text input and display, including editing, selection, cutting, and pasting of text. The class has data structures related not only to the content of the text but also to the appearance of the widget's on-screen representation. To use this class, an application creates an instance of this class of widget and provides some of its own data and procedures for the widget instance.
Xt supports single inheritance of widget classes. That is, a widget class may be a subclass of another class, its superclass. A subclass is often a specialized variant of a more general superclass. The subclass may inherit, override, or supplement the procedures and data structures of its superclass. Xt generally supplies widget classes designed to be superclasses for other classes. Motif supplies the subclasses of which the application constructs widget instances. Section 1.3 summarizes the Motif and Xt widget class hierarchy.
Widget instances form another, separate hierarchy. Every widget except the top-level widget (or widgets) in an application has a parent widget. Widgets of some classes, called composites, may have children. Other kinds of widgets, often called either primitives or gadgets, generally do not have children. An application constructs one or more trees of widget instances made up of composites, primitives, and gadgets. For example, a menu may consist of a composite parent representing the menu and a number of primitive children representing buttons. The menu and its children are one branch of the overall widget tree of the application.
Xt and Motif provide all the widget classes that most applications need. It is possible for an application to define new widget classes, but this requires knowledge of Xt and of Motif internals that is beyond the scope of this book. A typical application creates widget instances of the built-in classes, providing its own procedures and data for its widgets.
Xt uses an extension of the resource mechanism to represent the widget instance data that is available to an application. Each widget class defines a set of resources that apply to widgets of that class. A class may inherit or override the resources of its superclasses as well.
A widget class declares a name and a class for each of its resources. Xt and Motif give each widget class a name, and the application gives each widget instance a name. Finally, the application developer provides a name and a class for the application itself. For a given resource of a given widget, the fully qualified name is the list of names beginning with the application name, continuing with the name of the top-level widget and then with the names of descendant widgets down to the name of the given widget, and ending with the name of the resource. The fully qualified class is the list of classes beginning with the application class, continuing with the class of the top-level widget and then with the classes of descendant widgets down to the class of the given widget, and ending with the class of the resource.
The user, the application, and the widget class combine to provide values for resources and thus to control the appearance and other attributes of components of the application. Both the user and the application developer can provide either specific or general specifications for widget resources in several resource files and on the command line. They can also supply different resource specifications depending on the locale, the characteristics of the screen, or arbitrary customization criteria.
When the application starts up, Xt combines these specifications into an initial resource database. When the application creates a widget, Xt assigns initial values to the widget's resources using a specification from the database, from values supplied by the application at creation time, or from defaults supplied by the widget class. After creating a widget, the application can use the XtGetValues routine to retrieve the value of a widget resource and the XtSetValues routine to supply a new value for a resource.
Most widgets either have an associated window or occupy a defined rectangular area of their parent's window. Each widget has a height, width, and a position with respect to its parent, expressed as the x and y coordinates of the upper left corner of the widget. Specification of the dimensions of widgets and their positions with respect to each other constitutes the layout or geometry of the application.
Application geometry results from the interaction of several factors:
The process of accounting for all these factors and determining widget layout is known as geometry management. Xt provides the essential means of handling geometry management:
A child is managed when it and its parent are prepared to negotiate geometry. In general, widgets are eligible to appear on the screen only after they are managed.
See Chapter 14 for more information on geometry management and the specific management policies of Motif widgets.
Xt has an event-handling procedure that reads events from the server and dispatches them to appropriate widgets. Each widget that has an associated window may also have a translation table. This table maps descriptions of events to names of procedures, known as actions. When Xt reads an event associated with a widget, it looks up the event description in the translation table and dispatches the event to the associated action routine.
An application can provide its own action routine, but most such routines are supplied by the widget class. An action routine often takes some action on its own and then notifies the application by invoking an application procedure known as a callback. Many widgets have resources whose value is a list of callback procedures. The widget invokes the procedures on these lists at specified times, often when the widget receives certain kinds of events. Xt supplies other means for an application to receive and respond to events, but many applications need only add appropriate callback procedures. These callbacks do most of the "work" of the application in the course of interacting with the user.
The Xt event-handling mechanism leads naturally to an event-driven structure for an application program. Most applications have the same general form:
See Chapter 3 for more information about the structure of a Motif application.
Xt provides the substrate for creating a set of widgets responsible for specific aspects of a user interface. Motif uses the Xt substrate to build both base classes and specialized subclasses of widgets for a variety of purposes. Section 1.3 outlines the Motif widget set.
In addition to supplying widgets, Motif adds a number of features that are of general use to applications and users. The following sections summarize some of these features.
Motif widgets have a distinctive visual style. Many widgets have shadows with a three-dimensional look that makes the widget appear to be raised above or depressed below the background. A widget that has keyboard focus may have a rectangular highlight border. When the user presses the Btn1 mouse button and focus is in a button, the color of the button face changes to indicate that the user has selected or "pressed" the button.
Motif automatically generates default colors for widget foregrounds, shadows, highlights, and selections states. The user or application can supply its own colors or pixmaps as values for widget resources.
See Chapter 12 for more information on colors and pixmaps in Motif.
The X Window System establishes conventions for clients to follow in allowing the user to transfer data from one application to another. These transfers operate through selections of several kinds, including primary, secondary, and clipboard selections. A selection is a shared resource that can be owned by only one client at a time for a given display. When the user wants to transfer data from one application to another, the receiving client asks the selection owner to convert the data into a form the receiving client understands, and then the receiver inserts the data. This mechanism can also transfer data between one widget and another in the same application.
The Motif Text and TextField widgets support primary, secondary, and clipboard selections. Motif also has routines that handle the clipboard selection, allowing an application to copy data easily to and from the clipboard. Xt provides more general routines for transferring data by means of selections.
Motif has an extensive drag and drop mechanism for transferring data. The user begins a transfer by pressing the mouse button attached to the transfer function (usually Btn2) with the pointer over a data source. The user then drags an iconic representation of the data to a spot that can receive the data, called a drop site. When the user releases the mouse button the data is moved, copied, or linked to the drop site.
The Motif Text, TextField, List, and Label subclasses automatically support drag and drop transfer of textual and some pixmap data. Motif includes an extensive programming interface of objects and routines that allow an application to establish its own drag sources and drop sites, control negotiation between sender and receiver, customize the visual elements, and convert arbitrary kinds of data.
See Chapters 16 and 17 for more information about data transfer.
Motif provides two styles of transferring keyboard focus from widget to widget. In one style, the widget that contains the pointer has focus. In the other style, the user presses a key or Btn1 to move focus to another widget, and the pointer location does not otherwise affect the focus.
In the second style, Motif distinguishes between traversal to a composite or a widget with internal navigation, called a tab group, and navigation to a widget or element within a tab group. Motif has a number of resources and routines to control traversal using this style.
See Chapter 13 for more information on keyboard traversal and other input issues.
Motif represents much textual data using a data type called a compound string. (Also called XmString.) This is a stream of components representing text, a display direction, and rendition tags. These rendition tags specify how the text is to appear when rendered, including parameters such as the following:
A compound string can have multiple text segments, possibly with different directions and rendition tags. Motif uses compound strings to represent all text except that in the Text and TextField widgets.
For each widget that can contain text, Motif maintains information about fonts, color, tab stops, and other qualities of written text using a data type called a render table. A render table is a list of entries, each consisting of either a font or a font set and the rendition information. A font set is a construct representing a group of fonts needed to display text in the locale of the application.
When Motif displays the text of a compound string segment, it matches the segment's rendition tags with tags from the widget's render table. It then uses the associated font or font set to display the text of the segment. A special rendition tag (called _MOTIF_DEFAULT_LOCALE) indicates text to be parsed in the encoding of the locale and displayed using the fonts needed for that locale.
See Chapter 9 for more information on compound strings, fonts, renditions, and render tables. Chapter 11 contains information on using these tools to prepare an application for different language environments.
The Motif Window Manager (MWM) is a Motif client that is capable of managing windows of either Motif or non-Motif applications. MWM provides window decorations and functions for moving, resizing, raising, lowering, maximizing, and minimizing windows. The user can display icons either on the root window or in an icon box. MWM has many resources that permit the user to customize its appearance and behavior.
See Chapter 18 for more information on the application interfaces to MWM. See the mwm(1) reference page in the Motif Programmer's Reference for information on MWM resources and functions.
Motif has a specification language called the User Interface Language (UIL). The developer uses UIL to define widgets and data in a text file, and then compiles this file into a binary format. At run time the application, using Motif Resource Manager (MRM) routines, retrieves the widget descriptions and data definitions from the binary file, and MRM creates the widgets and data structures from these descriptions.
UIL and MRM work in conjunction with the Motif toolkit. The application defines callback procedures and interacts with the widgets as if it were using the Motif toolkit alone. By using UIL to define the program's widget hierarchies, the developer can separate the user interface specification from the application code. A developer can change the interface by editing and recompiling a text file without recompiling and relinking the application program. As with resource files, a developer can use separate UIL files to contain text, render tables, and other data specific to particular locales.
See Chapter 4 for information on using UIL and MRM in an application. See the UIL(5) reference page in the Motif Programmer's Reference for information on UIL syntax.
Xt is built atop Xlib, and Motif is built atop Xt. One goal of Xt is to give applications a set of high-level interfaces and objects that relieve the program of the need to deal with many primitive Xlib routines. A goal of Motif is to give applications still higher-level interfaces and, particularly, a versatile set of widgets to relieve the program of the need to define its own widgets for most tasks.
However, Xt does not strive to replace all Xlib interfaces, and Motif does not strive to replace all Xt interfaces. Even a simple Motif application must use basic Xt routines to initialize the toolkit, manage widgets, create windows for widgets, get and set resources, add callback routines, and enter the event-dispatching loop.
Many Motif applications do not need to call Xlib routines. However, Motif does not have its own graphics routines, color-space facilities, or support for application management of input methods. Programs that need these features must either use vendor-supplied tools or call Xlib routines directly.
As a general rule, an application should use the highest-level interfaces sufficient for the tasks at hand. Not only does this usually result in a concise program, but it also ensures that the program functions as intended when a higher-level procedure supersedes a lower-level procedure.
For example, Xlib, Xt, and Motif all have routines to set keyboard focus to a window or widget. Xt and Motif both maintain an internal state that keeps track of focus changes. If a Motif application uses the Xt or Xlib routine, it may cause Motif or Xt to become internally inconsistent.
By convention, the names of Xlib routines and data structures begin with "X"; the names of Xt routines and data structures begin with "Xt"; and the names of Motif routines and data structures begin with "Xm".
This book does not document Xlib or Xt interfaces. A Motif application developer must have a working knowledge of basic Xt application interfaces and should have at least general familiarity with Xlib. For more information on Xlib, see the X Consortium Standard Xlib--C Language X Interface. For more information on Xt, see the X Window System document X Toolkit Intrinsics--C Language Interface.