|
VMS DECwindows Guide to Xlib (Release 4) Programming: MIT C
Binding
VMS DECwindows Guide to Xlib (Release 4)
Programming: MIT C Binding
August 1991
This manual is a guide to programming Xlib routines.
Revision/Update Information:
This is a new manual.
Operating System:
VMS Version 5.4
Software Version:
VMS DECwindows Motif Version 1.0
Digital Equipment Corporation
Maynard, Massachusetts
August 1991
The information in this document is subject to change without notice
and should not be construed as a commitment by Compaq Computer
Corporation. Compaq Computer Corporation assumes no responsibility for
any errors that may appear in this document.
The software described in this document is furnished under a license
and may be used or copied only in accordance with the terms of such
license.
No responsibility is assumed for the use or reliability of software on
equipment that is not supplied by Compaq Computer Corporation or its
affiliated companies.
Restricted Rights: Use, duplication, or disclosure by the U.S.
Government is subject to restrictions as set forth in subparagraph
(c)(1)(ii) of the Rights in Technical Data and Computer Software clause
at DFARS 252.227-7013.
Copyright ©1991
The following are trademarks of Compaq Computer Corporation:
Bookreader, CDA, DEC, DECnet, DECwindows, DECwrite, Digital, LinkWorks,
LiveLink, LN03, MicroVAX, PrintServer, ReGIS, ULTRIX, VAX, VAXcluster,
VAXserver, VAXstation, VMS, VT, XUI, and the DIGITAL logo.
Adobe is a registered trademark of Adobe Systems Incorporated.
BITSTREAM is a registered trademark of Bitstream, Inc.
Helvetica is a trademark of Linotype AG or its subsidiaries, or both.
ITC Avant Garde Gothic is a registered trademark of International
Typeface Corporation.
Motif is a trademark of the Open Software Foundation, Inc.
Open Software Foundation, OSF, OSF/Motif, and Motif are trademarks of
the Open Software Foundation, Inc.
PostScript is a registered trademark of Adobe Systems Incorporated.
Sony is a registered trademark of Sony Corporation.
Times is a trademark of Linotype AG or its subsidiaries, or both.
ZK5642
This document was prepared using DECdocument, Version V3.3-1e.
Preface
This manual describes how to program Xlib routines using the MIT C
binding. VMS DECwindows includes the MIT binding for Xlib programmers
using the C programming language and other languages that support
pointers.
The manual includes an overview of Xlib and tutorials that show how to
use Xlib routines.
Note
This manual uses a generic format when referring to Xlib routine names
in text. Routine names are represented in all uppercase letters with
separating spaces. In addition, the X prefix has been omitted. For
example, in text the routine name is written as OPEN DISPLAY; however,
the MIT C binding format of the same routine is XOpenDisplay.
See the X Window System for a complete reference and description of all MIT
C Binding Xlib routines.
|
Intended Audience
This manual is intended for experienced programmers who need to learn
graphics programming using Xlib routines. Readers should be familiar
with a high-level language. The manual requires minimal knowledge of
graphics programming.
Document Structure
This manual is organized as follows:
- Chapter 1 provides an overview of Xlib, a sample Xlib program,
and a guide to debugging Xlib programs.
- Chapters 2 through 12 provide tutorials that show how to use Xlib
routines and include descriptions of predefined Xlib data structures
and code examples that illustrate the concepts described.
This manual also includes the following appendixes:
- Appendix A is a guide to using the VMS DECwindows font compiler.
- Appendix B provides information about VMS DECwindows named colors.
- Appendix C lists VMS DECwindows fonts.
Associated Documents
The following documents contain additional information:
- X Window System---Provides detailed descriptions of each Xlib routine,
as well as, the Inter-Client Communication Conventions Manual (ICCCM),
the X Logical Font Description Conventions, and the X Window System
Protocol.
- DECwindows Motif for OpenVMS Guide to Non-C Bindings---Describes non-C bindings for Xlib, Intrinsics, Motif
Toolkit, and Digital extension routines.
- DECwindows Extensions to Motif---Provides reference information on the Digital
extensions to Motif.
- DECwindows Companion to the OSF/Motif Style Guide---Covers style issues for Digital extensions to Motif
and topics not addressed in the OSF/Motif Style Guide.
- DECwindows Motif Guide to Application Programming---Describes how to program with the Digital extensions
to the Motif Toolkit. It supplements the OSF/Motif Programmer's Guide.
- X and Motif Quick Reference Guide---Provides quick reference information on Xlib,
Intrinsics, and the Motif Toolkit.
- OSF/Motif Style Guide---Describes style guidelines for applications based on
the Motif Toolkit.
- OSF/Motif Programmer's Guide---Describes how to program with the Motif Window
Manager, Motif Toolkit, and the Motif User Interface Language (UIL).
- OSF/Motif Programmer's Reference---Provides reference information on the Motif Toolkit.
Conventions
The following conventions are used in this manual:
mouse
|
The term
mouse is used to refer to any pointing device, such as a
mouse, a puck, or a stylus.
|
MB1 (Select)
MB2 (Drag)
MB3 (Menu)
|
MB1 indicates the left mouse button, MB2 indicates the middle mouse
button, and MB3 indicates the right mouse button. (The buttons can be
redefined by the user.)
|
Ctrl+x
|
A sequence such as Ctrl+x (or Ctrl/x) indicates that you must hold down
the key labeled Ctrl while you press another key or a pointing device
button.
|
.
.
.
|
A vertical ellipsis indicates the omission of items from a code example
or command format; the items are omitted because they are not important
to the topic being discussed.
|
[ ]
|
In format descriptions, brackets indicate that whatever is enclosed
within the brackets is optional; you can select none, one, or all of
the choices. (Brackets are not, however, optional in the syntax of a
directory name in a file specification or in the syntax of a substring
specification in an assignment statement.)
|
boldface text
|
Boldface text represents the introduction of a new term or the name of
an argument, an attribute, or a reason.
Boldface text is also used to show user input in online versions of
the book.
|
italic text
|
Italic text represents information that can vary in system messages
(for example, Internal error
number).
|
UPPERCASE TEXT
|
Uppercase letters indicate that you must enter a command (for example,
enter OPEN/READ), or they indicate the name of a routine, the name of a
file, the name of a file protection code, or the abbreviation for a
system privilege.
|
-
|
Hyphens in coding examples indicate that additional arguments to the
request are provided on the line that follows.
|
numbers
|
Unless otherwise noted, all numbers in the text are assumed to be
decimal. Nondecimal radixes---binary, octal, or hexadecimal---are
explicitly indicated.
|
Chapter 1 Programming Overview of Xlib
The VMS DECwindows programming environment includes Xlib, a library of
low-level routines that enable the VMS DECwindows programmer to perform
windowing and graphics operations.
This chapter provides the following:
- An overview of the library
- A description of error handling conditions
- Xlib debugging techniques
Additionally, the chapter includes an introductory Xlib program. The
program includes annotations that are explained more completely in the
programming descriptions in later chapters of this guide.
1.1 Overview of Xlib
The VMS DECwindows programming environment enables application
programs, called clients, to interact with
workstations using the X Window System, Version 11 protocol software.
The program that controls workstation devices such as screens and
pointing devices is the server.
Xlib is a library of routines that enables a client to communicate with
the server to create and manage the following:
- Connections between clients and the server
- Windows
- Colors
- Graphics characteristics such as line width and line style
- Graphics
- Cursors
- Fonts and text
- Pixmaps and offscreen images
- Windowing and sending graphics between clients
- Client notification of windowing and graphics operations
Xlib processes some client requests, such as requests to measure the
width of a character string, within the Xlib library. It sends other
client requests, such as those pertaining to putting graphics on a
screen or receiving device input, to the server.
The server returns information to clients through either replies or
events. Replies and events both return information to clients; the
server returns replies synchronously and events asynchronously.
See the X Window System for a list of routines that cause Xlib to send
requests to the server.
Figure 1-1 illustrates the relationships among client, Xlib, and
server. The client calls Xlib routines, which always reside on the
client system. If possible, Xlib processes calls internally and returns
information to the client when appropriate. When an Xlib routine
requires server intervention, Xlib generates a request and sends the
request to the server.
The server may or may not reside on the same system as the client and
Xlib. In either case, Xlib communicates with the server through a
transport protocol, which can be either local shared memory or DECnet
networking software.
Figure 1-1 Client, Xlib, and Server
1.2 Sample Xlib Program
The introductory Xlib program described in Example 1-1 illustrates the
structure of a typical client program that uses Xlib windowing and
graphic operations. The program creates two windows, draws text into
one of them, and exits if the user clicks any mouse button while the
cursor is in the window containing text.
The main loop of the program comprises two client-defined routines:
doInitialize and doHandleEvents.
This section describes these routines and introduces fundamental
concepts about Xlib resources, windowing, and event-handling.
1.2.1 Sample Initialization Routine
The sample program begins by calling a client-defined routine,
doInitialize. The routine creates the resources the client
needs to perform tasks. Xlib resources include windows, fonts, pixmaps,
cursors, color maps, and data structures that define the
characteristics of graphics objects. The sample program uses a default
font, default cursor, default color map, client-defined windows, and a
client-defined data structure that specifies the characteristics of the
text displayed.
The doInitialize routine makes a connection between the client
and the server. The client-server connection is called the
display.
After making the connection, or opening the display, the client can get
display information from the server. For example, immediately after
opening the display, the program calls the DEFAULT SCREEN OF DISPLAY
routine to get the identifier of the default screen. The program uses
the identifier as an argument in a variety of routines it calls later.
1.2.1.1 Creating Windows
A window is an area of the screen that either receives input or both
receives input and displays graphics.
Windows in the X Window System are hierarchically related. At the base
of the hierarchy is the root window.
All windows that a client creates after opening a display are
inferiors of the root window. The sample program
includes two inferiors of the root window. First generation inferiors
of a window are its children. The root window has one
child, identified in the sample as window1. The window named
window2 is an inferior of the root window and a child of
window1.
To complete the window genealogy, all windows created before a
specified window and hierarchically related to it are its ancestors. In
the sample program, window1 has one ancestor (the root
window); window2 has two ancestors (the root window and
window1).
1.2.1.2 Defining Colors
Defining background and foreground colors is part of the process of
creating windows in the sample program. The doDefineColor
routine allocates named VMS DECwindows colors for client use in a way
that permits other clients to share the same color resource. For
example, the routine specifies the VMS DECwindows color named
"light grey" as the background color of window2. If
other clients were using VMS DECwindows color resources, they too could
access the VMS DECwindows data structure that defines "light
grey." Sharing enables clients to use color resources efficiently.
The sample program calls the doDefineColor routine again in
the next step of initialization, creating the graphics context that
defines the characteristics of a graphics object. In this case, the
program defines foreground and background colors used when writing text.
1.2.1.3 Working with the Window Manager
Most clients run on systems that have a window manager, which is an
Xlib application that controls conflicts between clients. Clients
provide the window manager with information about how it should treat
client resources, although the manager can ignore the information. The
sample program provides the window manager with information about the
size and placement of window1. Additionally, the program
assigns a name that the window manager displays in the title bar of
window1.
1.2.1.4 Making Windows Visible on the Screen
Creating windows does not make them visible on the screen. To make its
windows visible, a client must map them, painting the
windows on a specified screen. The last step of initializing
the sample program is to map window1 and window2.
1.2.2 Sample Event-Handling Routine
The core of an Xlib program is a loop in which the client waits for the
server to notify it of an event, which is a report of
either a change in the state of a device or the execution of a routine
call by another client. The server can report 30 types of events
associated with the following occurrences:
- Key presses and releases
- Pointer motion
- Window entries and exits
- Changes of keyboards receiving input
- Changes in keyboard configuration
- Window and graphics exposures
- Changes in window hierarchy and configuration
- Requests by other clients to change windows
- Changes in available color resources
- Communication from other clients
When an event occurs, the server sends information about the event to
Xlib. Xlib stores the information in a data structure. If the client
has specified an interest in that kind of event, Xlib puts the data
structure on an event queue. The doHandleEvents routine polls
the event queue to determine if it contains an event of interest to the
client. When the routine finds an event that is of interest to the
client, the doHandleEvents routine calls one or more other
routines.
Because Xlib clients do their essential work in response to events,
they are considered event driven.
The sample program continually checks its event queue to determine if a
window has been made visible or a button has been clicked. When the
server informs it of either kind of event, the program performs its
real work, as follows.
If the event is a window exposure, the program calls the
doExpose routine. This routine determines whether the window
exposed is window2 and if the event is the first instance of
the exposure. If both conditions are true, the program writes a message
into the window.
If the event is a button press, the program calls the
doButtonPress routine. This routine checks to make certain the
cursor is in window2 when the user clicks the mouse button. If
the user clicks the mouse button when the cursor is in
window1, the program reminds the user to click on
window2. Otherwise, the program initiates a series of shutdown
routines.
The shutdown routines unmap window1 and window2, free
resources allocated for the windows, break the connection between the
sample program and its server, and exit the system. On the VMS
operating system, clients only need to call SYS$EXIT. Exiting the
system causes the other shutdown operations to occur. The call to
SYS$EXIT breaks the connection between client and server, which frees
resources allocated for client windows, and so forth.
See Example 1-1 for the sample Xlib program.
Note that using the #include directives in the sample program requires
that the .h files were extracted during VAX C installation. In
addition, note that the .h files reside in the SYS$COMMON:DECW$INCLUDE
directory. For programs that use the X11 logical in include directives,
users can redefine the logical X11 to DECW$INCLUDE with the following
format:
Example 1-1 Sample Xlib Program |
#include <decw$include/Xlib.h>
#include <decw$include/Xutil.h>
#define FontName\
"-Adobe-New Century Schoolbook-Medium-R-Normal--*-140-*-*-P-*-ISO8859-1"
#define WindowName "Sample Xlib Program"
Display *dpy;
Window window1,window2;
GC gc;
Screen *screen;
int n, state = 0;
char *message[]= {
"Click here to exit",
"Click HERE to exit!"
};
static void doInitialize( );
static int doDefineColor( );
static void doCreateWindows( );
static void doCreateGraphicsContext( );
static void doLoadFont( );
static void doExpose( );
static void doMapWindows( );
static void doHandleEvents( );
static void doButtonPress( );
/***** The main program *****/
static int main()
{
doInitialize( );
doHandleEvents( );
}
/***** doInitialize *****/
static void doInitialize( )
{
(1) dpy = XOpenDisplay(0);
if (!dpy){
printf("Display not opened!\n");
exit(-1);
}
screen = XDefaultScreenOfDisplay(dpy);
(2) XSynchronize(dpy,1);
doCreateWindows( );
doCreateGraphicsContext( );
doLoadFont( );
doMapWindows( );
}
/***** Create the windows *****/
(3)static void doCreateWindows( )
{
int window1W = 400;
int window1H = 300;
int window1X = (XWidthOfScreen(screen)-window1W)>>1;
int window1Y = (XHeightOfScreen(screen)-window1H)>>1;
int window2X = 50;
int window2Y = 75;
int window2W = 300;
int window2H = 150;
XSetWindowAttributes xswa;
/* Create the window1 window */
xswa.event_mask = ExposureMask | ButtonPressMask;
xswa.background_pixel = doDefineColor(1);
window1 = XCreateWindow(dpy, XRootWindowOfScreen(screen),
window1X, window1Y, window1W, window1H, 0,
XDefaultDepthOfScreen(screen), InputOutput,
XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa);
/* Create the window2 window */
xswa.event_mask = ExposureMask | ButtonPressMask;
xswa.background_pixel = doDefineColor(2);
window2 = XCreateWindow(dpy, window1, window2X, window2Y, window2W,
window2H, 4, XDefaultDepthOfScreen(screen), InputOutput,
XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa);
XStoreName(dpy, window1, WindowName);
}
/***** Create the graphics context *****/
(4)static void doCreateGraphicsContext( )
{
XGCValues xgcv;
/* Create graphics context. */
xgcv.foreground = doDefineColor(3);
xgcv.background = doDefineColor(2);
gc = XCreateGC(dpy, window2, GCForeground | GCBackground, &xgcv);
}
/***** Load the font for text writing *****/
(5)static void doLoadFont( )
{
Font font;
font = XLoadFont(dpy, FontName);
XSetFont(dpy, gc, font);
}
/***** Create color *****/
(6)static int doDefineColor(n)
{
int pixel;
XColor exact_color,screen_color;
char *colors[] = {
"dark slate blue",
"light grey",
"firebrick"
};
if ((XDefaultVisualOfScreen(screen))->class == TrueColor
|| (XDefaultVisualOfScreen(screen))->class == PseudoColor
|| (XDefaultVisualOfScreen(screen))->class == DirectColor
|| (XDefaultVisualOfScreen(screen))->class == StaticColor)
if (XAllocNamedColor(dpy, XDefaultColormapOfScreen(screen),
colors[n-1], &screen_color, &exact_color))
return screen_color.pixel;
else
printf("Color not allocated!");
else
switch (n) {
case 1: return XBlackPixelOfScreen(screen); break;
case 2: return XWhitePixelOfScreen(screen); break;
case 3: return XBlackPixelOfScreen(screen); break;
}
}
/***** Map the windows *****/
(7)static void doMapWindows( )
{
XMapWindow(dpy, window1);
XMapWindow(dpy, window2);
}
/***** Handle the events *****/
(8)static void doHandleEvents( )
{
XEvent event;
for ( ; ; ) {
XNextEvent(dpy, &event);
switch (event.type) {
case Expose: doExpose(&event); break;
case ButtonPress: doButtonPress(&event); break;
}
}
}
/***** Write the message in the window *****/
static void doExpose(eventP)
XEvent *eventP;
{
/* If this is an expose event on our child window, then write the text. */
if (eventP->xexpose.window != window2) return;
XClearWindow(dpy, window2);
XDrawImageString(dpy, window2, gc, 75, 75, message[state],
strlen(message[state]));
}
/***** Shutdown *****/
static void doButtonPress(eventP)
XEvent *eventP;
{
if (eventP->xexpose.window != window2) {
state = 1;
XDrawImageString(dpy, window2, gc, 75, 75, message[state],
strlen(message[state]));
return;
}
/* Destroy the windows */
(9) XDestroyWindow(dpy, window1);
XCloseDisplay(dpy);
sys$exit (1);
}
|
|