Figure 46.10 shows a visual representation of the geometry. For example,
xterm -geometry -50+50 & places the xterm on the top-right corner, 50 pixels from the right edge of the screen and 50 pixels from the top of the screen.
The following parameters specify the edges of the screen:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
It's important to bring up this point about the keyboard and its special keys under X. Keyboards come in different flavors, and the most important key for using keystrokes in X can be radically different from one keyboard to another. On the PC-based
keyboards it is usually the Alt key, on Macintoshes it is the fan-shaped key, on Suns it's Left, Right, Alternate; on other keyboards it's completely different.
In short, when this chapter refers to the Meta key, it means your special key for your special keyboard. For a PC-based keyboard, this would be the Alt key. So do not look for a key called Meta on your keyboard. Where the chapter says Meta, use Alt,
fan, or whatever your keyboard uses.
Now you can invoke any item on this Window menu one of two ways:
Note that some of these functions may not be available for a menu shown for an icon. You will not be able to size or minimize an icon. You will, however, be allowed to move, maximize, or close it.
Click Button3 while the cursor is in the root window. You will see a menu pop up on top of all the windows. This is known as the root menu. Keep in mind that this menu is very customizable and may look radically different on your machine. You will learn
all about creating your own menu later in this chapter in the section "Customizing mwm."
A typical root menu would list the following items:
"Root Menu" New Window Shuffle Up Shuffle Down Refresh Utils > Restart Exit
While holding Button1 down, move the cursor down the list to the item you want to select. When you get to the menu item you want, release the button. If you do not want to select any items, move the cursor off the menu and release the button.
In the root menu list, the functionality could be as follows:
Most programmers find the X Windows system libraries too basic to work with, so they use the next building block, called Toolkits. The most common interface toolkit is called the XtIntrinsics toolkit from MIT. This is called Xt. On top of Xt, you can
have other toolkits such as Motif or the OPEN LOOK Interface Toolkit (OLIT). When you are working with Motif, you are working with a Motif toolkit. In Motif you are working with Motif widgets.
Widgets help users program consistent user interfaces in Motif. By using widgets, users can quickly put together interfaces that have the same look and feel of all Motif applications.
Some widgets display information. Some widgets collect user input (mouse or keyboard) information. Some widgets react to user input by changing their appearance or by performing some programmed function. Some widgets are simply containers for other
widgets. All widgets can be customized in one form or another, whether it is appearance, font size or style, colors, or whatever other parameter is required.
All widgets of the same type have two data structures with information that describes their attributes: instance and class. The instance data structure contains information for a specific widget on the screen. The class information contains information
required for all widgets of the class.
Widgets are grouped into several classes. Each class depends on the type of functionality offered by the widget. Normally the internal functions of a widget are hidden from the applications programmer (encapsulation). A widget class shares a set of
functions and data structures for all widgets in that class. A new widget class can be derived from an existing widget class.
The newly derived class can inherit all the parent class' data structures and functions. A widget is created and destroyed during a Motif program execution.
This should sound familiar to C++ programmers. True polymorphism is somewhat harder to find in widgets. This is all done in C. For C++ programmers, the class data structure is to the class of an object as the instance data structure is to the instance
of an object.
A widget is really a pointer to a data structure when viewed in a debugger. This data structure is allocated on the creation of a widget and is destroyed when a widget is destroyed.
Let's look at a typical application screen to see some widgets in action. You will work with a demo application called xmdialogs, shown in Figure 46.11. The widgets shown here are described later in this chapter. The xmdialogs application can be found
in the /usr/bin/X11 directory. If you do not have this application, you can still learn about working with widgets by applying these concepts to different applications.
Figure 46.11. The xmdialogs demo application.
Figure 46.11 shows a menu bar, a file selection list with scroll bars, an option button, some radio and toggle buttons, some push buttons, labels, and a text display dialog.
The Actions and Help items are shown on a menu bar. By moving the pointer to either of these items and pressing Button1, you will be presented with a menu of options very similar in operation to the window and root menu.
Under this menu bar is a list of items in a scrollable list. This widget is of the type XmList. The XmList lets you keep a selection of items in a visible list. It has scroll bars to allow the user to scroll the list if the entire list is not visible. A
programmer can set the number of items that are visible at one time. If you resize the window and if the list box sizes itself proportionately with the window, the number of visible items in the list may change.
To select an item, move the pointer to the item of your choice and press Button1 once. The item is highlighted in a darker color. Some lists allow you to select more than one item, some just one item. In this application you select only one type of
dialog box. Figure 46.11 shows that the bulletin board item is the selected item.
The scroll bars on the side of the list widget are of the class XmScrollbar. A scroll bar is either a horizontal or vertical rectangle. There is a raised box in the rectangle, called the slider box. This slider moves within the larger rectangle. The
moveable space for the slider bar is called the scroll region. The size of the slider bar to the scroll region is proportional to the size of the work area to the total area being viewed.
The XmScrollBar rectangle has an arrow at each end. The arrows point out from the rectangle and in opposite directions. You can use the arrow keys to move the slider bar within the scroll region.
You can also move the slider bar by dragging with the mouse:
Now move your cursor to the selection item of the resize policy button. When you click this button, you are presented with a pop-up menu containing the types of resize policies for the dialog box you want to create. When you press the button, a menu
pops out and presents a list of options. You make the selection with your pointer by moving the pointer to that button and releasing it. The menu disappears and your selection is displayed in the box. In Figure 46.11 the resize policy is set to any. This
is known as an Option Button.
Note the diamond-shaped buttons and selections below this current menu. This is a list of one of four possible selections for the dialog box. One of the items is shown in a lighter gray color. This is known as being grayed out, and the option is a not a
valid option at the time. The option for the work area is disabled. You can select one of the other three options. These items are grouped together with a rectangular frame drawn around them. Usually buttons are grouped together in Motif this way when
their functionality falls in the same group of actions. The actions are similar to the buttons on an old radio: Push one button and the rest in the row of buttons all come up. This is why these are referred to as radio buttons.
Look at the two buttons called auto manage and default position. These are toggle buttons for this application. When you select one button, the other is not influenced at all. The functionality provided by each button is completely independent of that
of the other. Do you see the difference between radio buttons and toggle buttons?
Sometimes the scroll bar is used on either side of a drawing area. This is called a scrolled window and belongs to the XmScrolledWindow class. This widget can hold graphics instead of a list of items. The XmScrolledWindow is used primarily to view large
graphics items in a small window, whereas XmList is used to show a list of items from which the user can select.
Under the toggle buttons, you will see four push buttons. When a push button is pressed, the colors on the border of the button reverse. Furthermore, the color of the pressed rec-tangle changes to show the user action. Push buttons are used to invoke
some sort of action. When you select the file selection dialog from the list and press the push button to manage it, the display shown in Figure 46.12 appears. This is the standard file selection box under Motif, and you will see it for most applications.
Figure 46.12. A typical File Selection dialog box.
The Motif toolkit also supplies the widgets described in the following sections.
This is a subclass of TransientShell. Instances of this class are used from modal or modeless dialog boxes. Modality refers to whether the user may interact with other windows while the dialog box is being displayed. A modal dialog box prevents you from
moving on until you are finished with the dialog box. A modeless dialog box lets you work with other boxes. A File Selection dialog box is a modeless dialog box.
Instances of this class are used to create menu panes for pop-up and pull-down menus. This is derived from the OverrideShell.
This is a subclass of WMShell. It provides the interface to a window manager. These are provided by specific systems vendors, hence the name.
These display widgets are used to provide user interaction tools via buttons, arrows, scroll bars, etc. This list is by no means complete since vendors and end users can create their own versions of widgets or brand new widgets. Some examples of
commercially available widgets include spreadsheet widgets, bar chart widgets, gauges, and so forth. These widgets provide a consistent interface and are therefore easy to include in Motif applications. Some of the standard widgets are listed here.
This is a directional arrow with a border around it. A programmer can modify the direction of the arrow, as well as the thickness and color of the border, by setting the widget's parameters. If you look at the ends of a scroll bar, you will see two
examples of such a widget.
A DrawnButton provides a rectangular area with a border for the programmer. The programmer can size, redraw, or reposition text or graphics within this window. This widget provides hooks to set parameters for its border appearance, as well as to attach
functions for accepting user inputs.
This is a rectangular box consisting of either text or graphics. It is instantiated but is also used as a base class for all button widgets. A label's text can be multiline, multifont, or even multidirectional. In the xmdialogs example, this would be
the labels Active Dialog and the Motif Dialog widgets.
Many features of labels can be modified such as fonts, foreground and background colors, and alignment (left, center, or right justification). In fact, this can even store a pixmap graphic image.
This is a text label or pixmap with a border around it. This widget accepts keystrokes or mouse button presses. In the xmdialogs example these are the create, destroy, manage, and unmanage buttons. When a button has focus, it has a heavy border.
Press the Enter key or a pointer button when the button has focus. Move the cursor to the button. Press a key or button and hold it down. You have armed the button. The color on the button changes and the border colors reverse. This gives the impression
that the button has been pressed inward. When you release the button, the button reverts to its original state.
When a mouse button is pressed in this widget, the foreground and background colors of the widget usually invert. This simulates the pressing of a button.
This is used to create a line between functional sections of a screen. There is really not much users can do with this widget except position it on the screen.
This is used to create a fully functional multiline text editor on a screen. The user can select text by dragging the mouse from one location to another while Button1 is pressed. Users can also click anywhere on the widget to mark the insertion point.
If the text widget is enabled for user input, the user can type at the insertion point and insert the text into the text widget.
These are rectangular areas in the window that allow users to select from a group of items. The items are generally laid out in push buttons. You can select a push button either by moving the mouse to that selection or by pressing Alt+K, where K is the
letter in the menu button that is underlined. In the xmdialogs function, the Meta+F key selects the file item, and Meta+H selects the Help item.
The Motif root window menu is a good example of a pop-up menu. When you press the mouse button, a menu is displayed. You can select the items in the menu by moving the cursor onto the item and pressing Button1.
The Xmscale widget is used to display the value of a data item between two extremes. It can also be used to accept user input. A scale widget has a scroll region very similar to the scroll bar. However, it does not have the arrow buttons at either end.
This is a combination of a horizontal scroll bar, vertical scroll bar, and a drawing area. If the size of the drawing area fits within the window, you will not see the scroll bars. If the size of the drawing area is greater than the visible area of the
scrolled window, then you will see either the horizontal scroll bar, the vertical scroll bar, or both. You can then use the scroll bars to move the visible portion on top of the drawing area. This is known as panning the window.
This is a simple widget used to put a consistent border around one single widget. A frame can only hold one widget at a time.
This is a general-purpose widget organizer. The widget can lay out its widget collection in a variety of ways, including the following:
|
Row major |
This is where all widgets on the row column widget are stored until one row fills up, and a new row is created when another widget is added that will not fit on this row. The creation of a new row is sometimes called wrap around. |
|
Column major |
This is the same as a row major, but it wraps around in a columnar fashion. |
You can specify the width of each column to be that of the widest widget, the number of fixed columns, the packing (whether all widgets should be packed as closely as possible), or determined individually by each widget.
As mentioned earlier, there are several other widgets available in the Motif widget set. You can see the complete listing and their options in The Programmers' Reference Manual from the Open Software Foundation (OSF).
Motif widgets create a window in X Windows. A complex Motif application can create several X Windows very quickly. Each window uses X resources in the server and having many windows can slow your overall system performance.
Gadgets are windowless versions of widgets. Most gadgets have the same names as widgets but have the string gadget appended to their names. So XmLabel has an XmLabelGadget counterpart.
Gadgets do not have all the features of widgets. For example, gadgets share the foreground and background colors of their parents. Also, some gadgets actually turn out to be slower than the widgets they are trying to replace. Given the troubles you can
get into by using gadgets, you would be better off not using them.
Now that you are familiar with widgets, you need to know the parameters that affect them: resources.
As you saw in the previous sections, you can customize some aspects of an application from the command line prompt. X allows you to modify the aspects of an existing application every time a client runs that application. X does this by setting control
variables for that client. These control variables are called resources and have a value associated with them.
For example, take the case of an xterm. An xterm's resources are its font size, its pointer shape, the foreground color for all displayed text, its background color, and so on. These are only a few of the resources for an xterm. Most of these resources
exist as predefined defaults for all the common clients in a system.
You can specify resources on an application-specific basis or for all applications on your system. These resources are normally stored in an ASCII file called .Xresources in your home directory.
This file affects only those applications that you run. This file normally contains only those options that you would customize over those in the systemwide files.
You can always override these defaults specified in the systemwide file with defaults in your .Xresources file. In turn, your command line options for a single client override those in the .Xresources file. Keep in mind that the command line default
applies only to a specific client; the .Xresources default setting becomes the default for all your clients.
Also remember that the command line operations override any default resources set in a file. Normally you set how you want your application to look under normal circumstances, then override the changes via command line options.
To make your resource specifications available to all clients, use the X resource database manager program, or xrdb. This stores the resources directly on the server and makes the resource available to all clients on the system. This step takes some
care since your change will affect all your clients, regardless of what platform they are running on.
A resource definition file is basically a line-by-line list of all the resources in the file. Each line consists of two entries: one for the resource type and the other for the value for the resource. The two entries are separated by a colon.
The syntax for a resource definition is
client*variable: value
where client is the name of the client. The variable for that client is set to value. Note that the colon follows the variable without any spaces.
Now look at the resource declaration for an xterm client.
XTerm*foreground: white XTerm*background: blue XTerm*font: 10x20 ... aixterm*foreground: white aixterm*background: blue aixterm*font: 10x20
On your system, you may see declarations for cterm, or in the case of IBM's AIX machine, aixterm, instead of xterm. These are simply names for xterm in other versions. When in doubt, search for the word XTerm, xterm, or term in your .Xresources file. If
you do not already have an .Xresources file, you can create one yourself with an ASCII editor.
The values can be Boolean, numeric, or string values. They can be specified for widgets in an application, as well. For example, if you want to set the background color for all push buttons in an application called myWorld, you would set the following
resource:
myWorld*PushButton.background: red myWorld*background: blue
Note that the asterisk is used to represent the widgets between the actual myWorld application and all push buttons in that application. Had we specified
myWorld.mainForm.PushButton: blue
then only the buttons on the widget, mainForm, which in turn had to exist on myWorld, would be affected. This would be tight binding. Using the asterisk is loose binding since it allows for multiple levels of widget hierarchy between the objects on
either side of the asterisk. If you had an application with a hierarchy of
myWorld.mainForm.subForm.PushButton
then the first two of the following declarations would affect the push buttons on the subForm, but the last one would not:
myWorld*PushButton.background: red myWorld*background: blue myWorld.mainForm.PushButton: blue
Another example would be the settings for an xterm. If you attempt to set the scroll bars using
XTerm.scrollbar: true
it will most likely not work. There will probably be a widget hierarchy between the top-level application and the scroll bar widgets. In this case, it will work if you use this:
XTerm*scrollbar: true
After you have modified the .Xresources file, you will probably expect to see the changes occur immediately. Not so. You now have to inform the server of your defaults by using the xrdb command. Use the command
xrdb -load .Xresources
This will reflect the changes for all subsequent executions of your client. These changes will remain in effect until they are overridden or until your session terminates. If you saved your .Xresources file in your login directory, these changes will be
loaded whenever you start X in the future if you run this:
xrdb -load .Xresources
This command is useful when creating .Xresources for the first time in a session. That is why in most cases this command is run when the windowing system is first created. If you want to keep the previous settings, use the -merge command option instead
of -load, as in
xrdb -merge .myOwnResources
Also, you can use the exclamation point as the comment character at any point in the input line before any text begins. Therefore, the following lines are comments:
! This is a comment ! another one ! commented*labelString: This resource is not used.
You can also use the cpp preprocessor's directives #if, #ifdef, #else, and #endif. This is running through xrdb only. cpp is not run when the .Xresources file is parsed. You can override the run through cpp by using the -nocpp parameter on the command
line. No other parameters are required. If you want to remove a resource, use the -remove operation:
xrdb -remove myOldResources
There are two types of resource files: user and class.
User files apply to each instance of all applications. These are the resources you would set in the .Xresources file.
Class files pertain to all the instances of a particular class. These will exist in files usually in your home directory or in your path. The name of the class file is the name of the class. The class name is the name of the application class with the
first letter capitalized.
For example, all xterms belong to the class XTerm. Note that the class name is the name of a type of an application, with the first letter capitalized. XTerm is an exception in this regard since it has XT capitalized instead of only X.
Now look at setting the resources for a particular class of an application. The command line
*labelString: Hello World
will set the labelString resource for all widgets in every application in your session to Hello World. This may not be exactly what you want. The command line
Xapp*labelString: Hello World
will set the labelString resource for all widgets in every Xapp application in your session to Hello World. This will not affect widgets within other applications. This effect would be desirable if you were trying to set only one type of application
resource.
You can also specify your own class for setting resources. This would be via setting the -name option on a client. For example, you could define all the resources for an xterm with 10 x 20 font to be of class hugeterm. Then whenever you run
xterm -name hugeterm &
it will use the resources in the class hugeterm. So now you can set the foreground color to whatever you want for terminals, with a name of hugeterm.
Note that the name of a resource cannot contain the * or . characters. These values will cause your resource setting to be ignored. mwm simply ignores bad syntax rather than informing the user to make corrections.
Customizing mwm is very similar to customizing the X resources. However, mwm offers a far greater set of features and allows the user to customize just about every item on the screen. The resources here can be set to maintain a consistent set of
interfaces for all applications, without changing a line of code. For example, it's easy to change the background color of all the forms in your applications by simply editing the resources file rather than editing each source file individually. Here are
some more methods for setting resources:
You can set resources by hard coding the values in your application source code. See Chapter 47.
Hard coding resource settings is justifiable in the following situations:
You saw an example of this earlier when the chapter talked about customizing X applications and listed some of the resources that can be set from the command line. Motif applications usually list their options in man pages.
Use the -xrm command line option to set or override a particular resource. The syntax for this option is
xclient -xrm "resource*variable: value"
Note that you can concatenate several resource settings using the \ operator.
xclient -xrm "resource*variable: value" \
-xrm "resource*variable: value" \
-xrm "resource*variable: value"
So, how do you know which resources to set? Look in the OSF/Motif Programmers' Reference Manual for the description of a widget's resources.
Looking at the Label widget, you will see resources grouped by the class and all its inherited resources. Some of the resources would be declared under the class Core, some under Manager, and so on. Now look at some of the resources for an XmPushButton
widget. You will see these listed with the letters XmN in front of them. These letters signify that it is a Motif resource.
XmNinputCallback XcCallback XtCallBackList NULL C XmNarmColor XmCarmColor Pixel Dynamic CSG XmNarmPixmap XmCArmPixmap Pixmap XmUNSPECIFIED_PIXMAP CSG XmNdefaultButtonThickness XmCdefaultButtonShadowThickness Dimension 0 CSG ....
Note the letters CSG for the access description. The C signifies creation. This tells that the resource can be set upon creation. The S signifies that this value can be set at runtime. The G signifies that it can be read (get) at runtime.
In the case of the push button widget, the XmNinputCallback class can be set only at the time when it is created (that is, once at runtime). This is usually done in the code section where an address to a pointer is set for this widget.
The other values can be set at runtime. For example, the XmNarmColor can be set from a resource file since it does have the S set for it. Likewise, when programming widgets, this resource can be read from an application since the G value is specified
for this resource.
Motif uses several environment variables to hold its pointers to locations for resource files.
The XENVIRONMENT environment variable can hold the complete path to a file that holds the resource file. This must be the complete path of the application. If this variable is not set, then the Xt toolkit will look in .Xresources-HostName in the
application's home directory.
The XUSERFILESEARCHPATH is a pointer to the locations of application resource files. This is a colon-delimited string. Each field is expanded into meaningful names at runtime. Some of the most common fields are these:
The RESOURCE_MANAGER variable is set by xrd. This xrd is executed at runtime. This usually happens at start-up.
The XFILESEARCH environment variable holds a colon-delimited list of directories for the app-defaults file. Usually these defaults are in the /usr/lib/X11/app-defaults directory. The files in this directory are interesting to see. See Listing 46.1.
Bitmap Bitmap-color Chooser Clock-color Doc Editres Editres-color Fileview Ghostview Mwm Neko Periodic Viewres X3270* XCalc XCalc-color XClipboard XClock XConsole XDbx XFontSel XGas XLess XLoad XLock XLogo XLogo-color XMdemos XMem XMtravel XTerm Xditview Xditview-chrtr Xedit Xfd Xgc Xmag Xman Xmh Xtetris Xtetris.bw Xtetris.c
Note that some of the classes listed here have the first two letters of their names capitalized instead of just one (XTerm, XDbx, XMdemos). So if your class resource settings do not work as expected, look in this directory for some hints on what the
resource class name might look like. Again, the contents of this directory depend on your installation of Motif and X.
The search for the missing .Xresources occurs in the following order:
Keep this advice in mind: In all but the most unavoidable cases you should not rely on environments to set your application resources.
The methods are too complicated to learn, especially for the end user. However, they can be a very powerful customization tool. Editing resource files is hard enough on the programmer, but it's even worse on the user. However, in order to be a good
Motif user, you should know about the environment variables that affect applications that come from other vendors.
There are two Motif applications that can assist you in determining an application's resources: appres and editres.
The appres program's syntax is this:
appress Class application
This will list all the resources in a given class for the named application.
The second command is a menu-driven GUI program, editres, that allows you to edit the given resources for an application. This is available for X11R5 and later. The program displays a tree-like representation of all the widget classes in a program and
allows the user to move through the tree node by node. Search your release for this file. If you do not have this file, do not despair, contact your local hardware vendor for a complete X installation.
Create this file from the system.mwmrc file by copying it into your $HOME directory as .mwmrc, and then edit it. (Look in the /usr/bin/X11 directory and search for the file system.mwmrc using the find command.)
Listing 46.1 on the CD-ROM shows a sample .mwmrc file. As stated earlier, when working with .Xresources, you start a comment with a ! character.
!!
!! $HOME/.mwmrc
!! Modified system.mwmrc for personal changes. kh.
!!
!!
!! Root Menu Description
!!
Menu DefaultRootMenu
{
"Root Menu" f.title
"New Window" f.exec "xterm &"
"Shuffle Up" f.circle_up
"Shuffle Down" f.circle_down
"Refresh" f.refresh
"Pack Icons" f.pack_icons
! "Toggle Behavior..." f.set_behavior
no-label f.separator
"Restart..." f.restart
! "Quit..." f.quit_mwm
}
Menu RootMenu_1.1
{
"Root Menu" f.title
"New Window" f.exec "xterm &"
"Shuffle Up" f.circle_up
"Shuffle Down" f.circle_down
"Refresh" f.refresh
! "Pack Icons" f.pack_icons
! "Toggle Behavior" f.set_behavior
no-label f.separator
"Restart..." f.restart
}
!!
!! Default Window Menu Description
!!
Menu DefaultWindowMenu
{
Restore _R Alt<Key>F5 f.restore
Move _M Alt<Key>F7 f.move
Size _S Alt<Key>F8 f.resize
Minimize _n Alt<Key>F9 f.minimize
Maximize _x Alt<Key>F10 f.maximize
Lower _L Alt<Key>F3 f.lower
no-label f.separator
Close _C Alt<Key>F4 f.kill
}
!!
!! Key Binding Description
!!
Keys DefaultKeyBindings
{
Shift<Key>Escape window|icon f.post_wmenu
Alt<Key>space window|icon f.post_wmenu
Alt<Key>Tab root|icon|window f.next_key
Alt Shift<Key>Tab root|icon|window f.prev_key
Alt<Key>Escape root|icon|window f.circle_down
Alt Shift<Key>Escape root|icon|window f.circle_up
Alt Shift Ctrl<Key>exclam root|icon|window f.set_behavior
Alt<Key>F6 window f.next_key transient
Alt Shift<Key>F6 window f.prev_key transient
Shift<Key>F10 icon f.post_wmenu
! Alt Shift<Key>Delete root|icon|window f.restart
}
!!
!! Button Binding Description(s)
!!
Buttons DefaultButtonBindings
{
<Btn1Down> icon|frame f.raise
<Btn3Down> icon|frame f.post_wmenu
<Btn3Down> root f.menu DefaultRootMenu
}
Buttons ExplicitButtonBindings
{
<Btn1Down> frame|icon f.raise
<Btn3Down> frame|icon f.post_wmenu
<Btn3Down> root f.menu DefaultRootMenu
! <Btn1Up> icon f.restore
Alt<Btn1Down> window|icon f.lower
! Alt<Btn2Down> window|icon f.resize
! Alt<Btn3Down> window|icon f.move
}
Buttons PointerButtonBindings
{
<Btn1Down> frame|icon f.raise
<Btn3Down> frame|icon f.post_wmenu
<Btn3Down> root f.menu DefaultRootMenu
<Btn1Down> window f.raise
! <Btn1Up> icon f.restore
Alt<Btn1Down> window|icon f.lower
! Alt<Btn2Down> window|icon f.resize
! Alt<Btn3Down> window|icon f.move
}
!!
!! END OF mwm RESOURCE DESCRIPTION FILE
!!
There are several key features here: key bindings, button bindings, and menu items.
A binding is a mapping between a user action and a function. The key bindings map keystrokes to actions, and the button bindings map button presses and releases to actions. Menus display the menu items and let you organize action items into sections.
The format for the all items is
Section_type Section_Title
{
.. definitions..
.. definitions..
}
where Section_type could be Menu, Keys, or Buttons. The Section_Title is a string defining the variable name. It's a name that can be used to refer to this section in other portions of the file.
The functions shown in the sample file begin with an f. keyword. Some actions are fairly obvious: f.move, f.resize, f.maximize, f.minimize, f.title, f.lower, and so on. Some actions are not: f.separator (displays a line on the menu item), f.circle_up
(shuffles the window stacking order up), f.circle_down (shuffles the window stacking order down). Remember how windows are like sheets of paper stacked on a canvas. (See section "Stacking Order.")
See Table 46.1 for all the features available.
Function |
Description |
|
f.menu mm |
Associates mm with a menu. |
|
f.minimize |
Changes the window to an icon. |
|
f.move |
Enables the interactive movement of a window. |
|
f.nop |
No operationit's a filler only. |
|
f.normalize |
Restores a window to its original size. |
|
f.pack_icons |
Rearranges the icons on a desktop. |
|
f.pass_keys |
Toggles enabling and disabling key bindings. |
|
f.quit_mwm |
Terminates mwm. |
|
f.raise |
Raises a window to the top of the stack. |
|
f.refresh |
Redraws all windows. |
|
f.resize |
Enables the interactive sizing of a window. |
|
f.restart |
Restarts mwm. |
|
f.separator |
Draws a line. |
|
f.title nn |
Names the menu. |
Now you're ready to define your own menu items. Here are some examples of menu item names:
Menu MyGames
{
"Kamran Games" f.title
no-label f.separator
"Tetris" f.exec "xtetris &"
"Mahhjong" f.exec "xmahjong &"
"Chess" f.exec "xchess &"
}
The f.title action specifies a heading for the submenu. The f.separator action draws a line under the title. The f.exec action fires up the command shown in double quotes.
Now you can add this new menu to the root menu by adding the line
"Utils" f.menu MyGames
in your DefaultRootMenu definitions.
The key and button bindings work in the same way as menus. The first obvious difference is the extra column with the words icon, frame, window, and root in it. These words force the bindings on the context. The root applies to any location of the
pointer on the root window, the frame or window keywords apply binding only when the pointer is in a window or its frame, and the icon bindings apply to icons.
In your .Xresource or .Xresources file, you will refer to these key bindings for the class mwm as follows:
Mwm*keyBindings: DefaultKeyBindings
Here are some of the descriptions in the key bindings:
|
|
|
|
|
|
|
|
|
The syntax for a keystroke binding is
modifier<Key>key
where modifier is Alt, Control, or Shift. The key can be a keystroke or function key. The first two declarations describe the same actionShow the window menubut use different keystrokes. The third key, binding, shows a method for displaying
the root menu.
The button bindings are the bindings for your buttons. These are the three important bindings to remember:
Buttons DefaultButtonBindings Buttons ExplicitButtonBindings Buttons PointerButtonBindings
In your .Xresource or .Xresources file, you will refer to one of these button bindings for the class mwm in one of the following ways:
You can customize your desktop using some of the client software that comes with your X11R5 distribution. This chapter covers the following applications:
There are several more utilities in the /usr/bin/X11 directory for you to play with: bitmap, xmag, xcalc. Check each one out to customize your desktop. This chapter describes the ones that are not intuitively obvious.
This client customizes the root window characteristics. Some of the options available are the following:
Look in the /usr/lib/X11 directory for the file called rgb.txt for a list of files and look at the section called "Colors" in this chapter for more information.
See the man pages for additional features for xsetroot.
The xset command sets up some of the basic options on your environment. Some of these options may not work on your particular system. It's worth it to check these out.
You can set the bell volume:
xset b volume frequency durationInMilliseconds.
For example, the command line
xset b 70 4000 60
sets the keyboard bell to about 70 percent of the maximum, with a frequency of 4,000 Hz, lasting 60 milliseconds.
To turn on the speaker, use xset b on. To turn it off, type xset off. Use xset c volume to set the keyclick volume in percentages. A volume setting of 0 turns it off. Any other number (1100) turns it on at that percentage. Of course, for this
command to work, you have to have your speaker turned on.
To set the mouse speed, type xset m acceleration threshold at the prompt.
The acceleration is the number of times faster to travel per mouse movement that is greater than the threshold. If your movement is below the threshold, the mouse will not accelerate. If the movement is greater than the threshold, each pointer movement
on the screen will be greater than the physical movement by this accelerated factor. This way you can zip across the screen with a twitch. Use care in setting this feature unless you are very adroit.
Use xset s seconds to enable the screen saver. You can turn off the screen saver with the off option. The default option reverts to system default time for blanking the screen.
For more options type in xset q.
To load your own fonts, use
xset fp /user/home/myfont,/usr/lib/X11/fontsdir xset fp rehash
The rehash command forces the server to reread its system files for your command to take effect.
To restore to normal, use
xset fp default xset fp rehash
See the section called "Fonts" later in this chapter.
The xdpyinfo utility gives you more information about your X server. It is used to list the capabilities of your server and all predefined parameters for it. Some of these capabilities include the following:
The list is too exhaustive to include here and will be different for your installation. Pipe its output to a file and review it for information about the server.
If you are a left-handed user, it might a bit uncomfortable to use the left mouse button with your third or second finger. The X designers kept you in mind. If you want to swap the functionality of the pointers on your mouse, or pointer, use the
xmodmap command. First, display the current mappings with
xmodmap -pp
You will see the following display:
|
|
|
|
|
|
|
|
|
|
This shows you that Button Code 1 is mapped to Physical Button 1, Button Code 2 is mapped to Physical Button 2, and Button Code 3 is mapped to Physical Button 3.
Now issue the command
xmodmap -e 'pointer = 3 2 1'
to reverse the mappings on the buttons. Now Physical Button 1 will be mapped to Button Code 3, and so forth. To confirm this, retype the xmodmap -pp command, and you'll see this:
|
|
|
|
|
|
|
|
|
|
You can always revert to the default with xmodmap -e 'pointer = default'.
Some other standard input parameters that can be used from the command line to change the behavior of a window are the following:
For example, you can make one terminal name, editor, and set your resources in the .Xresources file for the name editor. When you then invoke a new term with the xterm -name editor command, the server will apply the resources for editor to this xterm.
You can log in to remote machines using the xterm -display option. The remote system must allow you to open a display on its machine. This is done with the xhost + command on the remote machine.
-display nodename:displayname.ScreenName
This starts up a remote session on another node. displayname and ScreenName are optional and default to zero if not entered.
When you want to open an xterm on the remote machine, alma, you run the following command:
xterm -display alma:0.0 &
The format for the option into the display parameter is this:
[host]:[server][:screen]
If you are given permission to open a display, you will be logged in to the remote machine. You can verify this with the uname command. Check the DISPLAY with the echo $DISPLAY command.
When you log out with the exit command, the remote session and the xterm are terminated.
All the colors in the X Windows system are located in the /usr/lib/X11/rgb.txt file. This file consists of four columns: the first three columns specify red, green, and blue values, and the last entry specifies the name that you can use in your
parameters.
A partial listing of the rgb.txt file is shown in Listing 46.3.
255 250 250 snow 248 248 255 ghost white 248 248 255 GhostWhite 245 245 245 white smoke 245 245 245 WhiteSmoke 220 220 220 gainsboro 255 250 240 floral white 255 250 240 FloralWhite 253 245 230 old lace 253 245 230 OldLace 250 240 230 linen 250 235 215 antique white 255 239 213 PapayaWhip 255 235 205 blanched almond 255 235 205 BlanchedAlmond 255 218 185 peach puff 255 218 185 PeachPuff 255 222 173 navajo white 255 228 181 moccasin 255 248 220 cornsilk 255 255 240 ivory 255 250 205 lemon chiffon 255 250 205 LemonChiffon 255 245 238 seashell 240 255 240 honeydew 245 255 250 mint cream 255 240 245 LavenderBlush 255 228 225 misty rose 255 228 225 MistyRose 255 255 255 white 0 0 0 black 47 79 79 dark slate grey 47 79 79 DarkSlateGrey 105 105 105 dim gray 105 105 105 DimGray 105 105 105 dim grey 105 105 105 DimGrey 112 128 144 slate gray 112 128 144 SlateGray 112 128 144 slate grey 112 128 144 SlateGrey 119 136 153 light slate gray 119 136 153 LightSlateGray 119 136 153 light slate grey 119 136 153 LightSlateGrey 190 190 190 gray 190 190 190 grey 211 211 211 light grey
Since the red, green, and blue have 256 values each, the number of possible colors is 16,777,216. Not many workstations can display that many colors at one time. Therefore, X uses a facility to map these colors onto the display, which is called a
colormap. A color display uses several bits for displaying entries from this map. The xdpyinfo program gives you the number of bits for the display. This is a frame buffer. A 1 bit frame signifies a black-and-white display. An 8 bit frame buffer signifies
28 entries, or 256 possible colors.
Unfortunately, due to different phosphors on different screens, your color specification on one monitor may be completely different on another monitor. Tektronix provides a tool called xtici, an API and docs to counter such problems by using the
international CIEXYZ standard for color specifications. This is called the Color Management System (CMS), which uses a model called HVC (hue-value-chroma). In the X11R5 (or later) release look for Xcms for more details, or contact Tektronix.
Fonts in the X Windows system are designed for maximum flexibility. There are two good utilities to help you sift through some of the 400 or so font types on a basic system:
First, let's examine the font names themselves. Use the xlsfonts command to list the fonts on your system. Type the command on an xterm, and since the listing from xlsfonts is very long, be sure to pipe to a text file for review. You should get a
listing in which each line is of the form
-foundry-family-wt-sl-wd-p-pts-hr-vr-sp-ave-charset-style
The foundry is the company that first developed the font. The most common foundries are misc., Adobe, Bitstream, and B&H. You may see more on your system from the results of your xlsfonts command.
A font of the misc. foundry has a fixed width and height per character type of font; the rest of the fonts were donated by their respective manufacturers.
The family is the general type of font: Courier, Helvetica, New Century Schoolguide, Lucida, and so on. Some families are monospaced (that is, all their characters have the same width). The other families are proportionally spaced (that is, each
character has a separate width). Courier and Lucida are monospaced fonts. New Century Schoolguide is proportionally spaced.
You would use monospaced information for tabular information or running text. This makes your text line up cleanly in running displays. Proportionally spaced fonts are helpful for text in buttons or menu items.
The wt and sl parameters are for weights and slants, respectively. The common weights are bold and medium. Bold text is drawn with a pen thicker than the normal pen. The common slants are roman (r), oblique (o), and italic (i). Roman text is upright,
oblique text has characters sheared to the right. Italic text is similar to oblique text, but the characters show a smoother effect. You may also have a reverse oblique (ro) and reverse italic (ri) when the text leans to the left instead of to the right.
The p stands for the point size, which has traditionally been 1/72 inch. Most monitors traditionally support only 75 or 100 dots per inch (dpi) resolution. Since X fonts are bitmaps, it seems logical that the most common fonts within X are of two
flavors: 75 dpi and 100 dpi. This is the number that is found in the two fields hr and vr, which stand for the horizontal and vertical resolution, respectively. In almost all cases you will specify either 75 or 100 in each of these fields.
The sp refers to the spacing between two characters on the screen. This could be m for monospaced, p for proportional, and c for fixed fonts where each character occupies a fixed box.
The ave is the 1/10 average width of all the characters in the set.
The character set and style is usually set to ISO8859-1. This refers to the ISO Latin-1 character set, which includes characters found in the ASCII and other European character sets.
Now that you have seen the large number of options just to define a font, you can rely on using wildcards to specify most of the options for a font. The server will match the first font name that matches your specification with a wild card. In other
words, you only have to specify the parameters you want to change and use the asterisk for the rest.
For example, *courier-roman will get the first specification for the roman-weighted Courier font. However, *courier will get the bold Courier font. This is because the bold specification exists before the Roman specification in the fonts file.
The font search path is the path used by the server to search for the fonts in your system. This path is usually set to the following value:
/usr/lib/X11/fonts/misc,/usr/lib/X11/fonts/75dpi,/usr/lib/X11/fon ts/100dpi,
In each of these directories is a file called fonts.dir. This is a listing of all the fonts in the directory and has two entries per line. The first entry gives a font filename, the second entry gives the complete font description. The first line in the
file gives the number of entries in the file.
You can create another file in the font path to alias your own font names. This file is called fonts.alias. The server uses only the first one it finds in its path, so just keep one such file in the first directory in your font path. The fonts.alias
format is very similar to the fonts.dir file, except that the first entry is not a filename, it is an alias for a font name. So if you want to specify a special font type for all your editor xterms, you would have a line such as this:
editterm *lucida-medium-r-*-100*
Then you can invoke your xterm with the command
xterm -fn editterm &
to get an xterm window with the desired font. This is a lot better than typing in the full font specification. Also, by changing the alias once, you can change it for all scripts that use this alias, rather than modifying each script individually.
A good place to start is the /usr/lib/X11/fonts/misc directory, where a fonts.alias exists from your initial X installation. This file has the fixed and variable aliases defined for you to work with.
The xfontsel program helps you get a better feel for some of the parameters of a particular font. (See Figure 46.13.)
Figure 46.13. Using xfontsel.
You can move your pointer to any one of the parameters in the first line, and click Button1. As you move the pointer on a field, the field will draw a box around itself to show that it has focus.
If any font options exist for your selection, you will be presented a pop-up menu to select from. Move the mouse to a selection and click on the selection. You will see your selection displayed in the font specification string, as well as a sample of
what the font will look like on the fonts display screen below that.
This guide covers features up to X11R5. At the time of writing, X11R6 is about to be released. Here are some of its expected features:
Contact the X Consortium for details on availability.
There are many GUI fronts to X Win