This exercise demonstrates how to use standard X utilities to create icons
and generate PostScript screendumps of X applications. It also introduces
some Xlib calls (beginning with X rather than Xt) that are
frequently needed in applications built on top of the X Toolkit.
- Make a new copy of your dialogs program, naming it bitmaps.
Use X's standard bitmap client to create an icon for the
application. Use standard naming conventions for
this, calling the file bitmaps.xbm.
Make the icon 32x32 in size (if it
doesn't fit well on the screen, just resize the bitmap
window). Remember to keep the design fairly simple, since it will
be small on the screen. When you are done, save it in a file and
exit bitmap. Now, re-enter bitmap, this time
specifying the name of your file rather than a size. It should come
up in a reduced size that's convenient for making a screendump (if
not, just shrink the size of the window manually). Use the techniques
you learned in Exercise 1 to print a copy.
- Now follow Example 11-2 in the text to associate the icon
you designed with the bitmaps program. You will need to
incorporate the following changes:
- include the Shell header file
[Warning: this must be after the Intrinsics header file, but should be
before the Athena header files. Figure out why.]
- include your icon file (note that this goes between quotes, not
angle brackets)
- add a variable of type Pixmap for the icon
- create the pixmap using a call to XCreateBitmapFromData (be careful
with spelling when you mimic this)
- activate the icon with a call to XtVaSetValues that sets the
XtNiconPixmap resource
- change your Makefile so it re-compiles whenever you alter the icon
What is the name of the resource that specifies an icon, and what
widget class is it associated with?
- Experiment with the other resource settings that influence the main
application window. Note that the user has been having to position
the main window of the application. The geometry resource
can cause the window to appear automatically, at a specified
position. (The position is calculated in the same way that it would
be if the user specified the -geometry command-line option;
see Exercise 1). In this case, the application developer chooses
the position in advance and specifies it in the same way that the
icon pixmap resource is set.
What is the resource named constant for this (see Volume 5's
description of shells)? What would the resource setting look like to
position the window at coordinates 100,100?
Implement the resource setting needed to position the application window
at roughly the center of the screen.
It is also possible to bring up a window in "iconic" form to begin
with. This may be handy when you want to bring up a main window, plus
a couple of other windows that are initially closed. The availability
of icons will signal to the user that other windows are available. Use
the iconic resource of shells to force your program to begin in
closed (iconic) form.
When both geometry and iconic resources are set, what are the
positions of the icon? the window?
- Another use for icons is to create toolbox-style pushbuttons, where a
graphical icon takes the place of any word label. Change the quit
button to have a picture instead of the word "quit":
- create a small icon for the button, storing it in a file with
a name that conforms to normal conventions
- include the file in your application
- define a second pixmap, and create it the same way you did the
application icon
- in the call to XtVaCreateManagedWidget that builds the button,
set the appropriate resource to your new pixmap (use the description
of the Command widget class in Vol. 5 to determine which resource
is needed)
- The cursor is another example of icon use in X applications. So far,
you have only been using the default cursor, but you can change the
cursor in any X window -- or in the case of a widget-based application,
you can change the cursor for any widget(s).
One of X's "fonts" is actually a collection of predefined cursor shapes.
Change the cursor for the quit button in bitmaps to a
skull-and-crossbones, following this procedure:
- gain access to the predefined cursor names by include'ing
X11/cursorfont.h
- figure out which of the predefined cursor names refers to the
skull-and-crossbones [hint: use the X client for viewing fonts that
you learned in Exercise 5, giving it the font name "cursor"]
- define a cursor variable, declaring it to be of type Cursor
- in your initialization code, create the cursor of your choice, using
a call to the Xlib routine, XCreateFontCursor:
cursor-variable = XCreateFontCursor
(XtDisplay(toplevel), some-cursor-name);
This step creates a server-side resource, but it does not associate
the cursor with any window(s).
- A cursor cannot be assigned until after the widget has been
realized. Immediately after realization, add the following call to
another Xlib routine, XDefineCursor:
XdefineCursor (XtDisplay(quit_button),
XtWindow(quit_button), cursor-variable);
The named widget - and all its children -- will use the cursor you
defined, rather than the default one.
Run the program, observing when the cursor changes shape.
How can you make the new cursor apply to all widgets in the
whole application?