 |
VMS DECwindows Guide to Xlib (Release 4)
Programming: MIT C Binding
- The client assigns window width and height
the value of 600 (pixels) each.
- The client specifies the position of the
window using two display information routines, WIDTH OF SCREEN and
HEIGHT OF SCREEN. The x and y
coordinates define the top left outside corner of the window borders
relative to the inside of the parent border. In this case, the parent
is the root window, which does not have a border.
- The CREATE SIMPLE WINDOW routine call has
the following format:
window_id = XCreateSimpleWindow(display, parent_id, x_coord,
y_coord, width, height, border_width, border_id,
background_id)
|
The client specifies a black border ten pixels wide, a white
background, and a size of 600 by 600 pixels. The window manager
overrides border width and color. CREATE SIMPLE WINDOW returns a
unique identifier, win1, used in subsequent calls related to
the window.
3.2.2 Defining Window Attributes
To create a window whose attributes are different from the parent
window, use the CREATE WINDOW routine. The CREATE WINDOW routine
enables clients to specify the following window attributes when
creating an input-output window:
- Default contents of an input-output window
- Border of an input-output window
- Treatment of the window when it or its relative is obscured
- Treatment of the window when it or its relative is moved
- Information the window receives about operations associated with
other windows
- Color
- Cursor
Clients creating input-only windows can define the following attributes:
- Treatment of the window when it or its relative is moved
- Information the window receives about operations associated with
other windows
- Cursor
Specifying other attributes for an input-only window causes the server
to generate an error. Input-only windows cannot have input-output
windows as children.
Use the following method to define window attributes:
- Assign values to the relevant members of a set window attributes
data structure.
- Indicate the defined attribute by specifying the appropriate flag
in the value_mask argument of the CREATE WINDOW
routine. If more than one attribute is to be defined, indicate the
attributes by doing a bitwise OR on the appropriate flags.
The following illustrates the set window attributes data structure:
typedef struct {
Pixmap background_pixmap;
unsigned long background_pixel;
Pixmap border_pixmap;
unsigned long border_pixel;
int bit_gravity;
int win_gravity;
int backing_store;
unsigned long backing_planes;
unsigned long backing_pixel;
Bool save_under;
long event_mask;
long do_not_propagate_mask;
Bool override_redirect;
Colormap colormap;
Cursor cursor;
} XSetWindowAttributes;
|
Table 3-1 describes the members of the data structure.
Table 3-1 Set Window Attributes Data Structure Members
Member Name |
Contents |
background_pixmap
|
Defines the window
The background_pixmap member can assume one of three possible values:
pixmap identifier, the constant None (default), or the constant
ParentRelative.
|
background_pixel
|
Causes the server to override the specified value for the
background_pixmap member. This is equivalent to specifying a pixmap of
any size filled with the background pixel and used to paint the window
background.
|
border_pixmap
|
Defines the window border.
|
border_pixel
|
Causes the server
to override the border_pixmap member.
|
bit_gravity
|
Defines how the contents of the window
should be moved when the window is resized. By default, the server does
not retain window contents. For more information about bit gravity, see
Section 3.7.
|
win_gravity
|
Defines how the server should reposition the
newly created window when its parent window is resized. By default, the
server does not move the newly created window. For more information
about window gravity, see Section 3.7.
|
backing_store
|
Provides a hint to the server about how
the client wants it to manage obscured portions of the window.
|
backing_planes
|
Indicates (with bits set to one) which
bit planes of the window hold dynamic data that must be preserved if
the window obscures or is obscured by another window.
|
backing_pixel
|
Defines what values to use in
planes not specified by the backing_planes member. The server is free
to save only specified bit planes and to regenerate the remaining
planes with the specified pixel value. Bits that extend beyond the
number per pixel of the window are ignored.
|
save_under
|
Informs the server
that the client would like the contents of the screen saved when the
window obscures them.
|
event_mask
|
Defines which types of events associated with the
window the server should report to the client. For more information
about defining event types, see Chapter 9.
|
do_not_propagate_mask
|
Defines which kinds of events should not
be propagated to ancestors. For more information about managing events,
see Chapter 9.
|
override_redirect
|
Specifies whether calls to
map and configure the window should override a request by another
client to redirect those calls. For more information about redirecting
calls, see Chapter 9.
|
color map
|
Specifies the color map, if any, that
best reflects the colors of the window. The color map must have the
same visual type as the window. If it does not, the server issues an
error. For more information about the color map and visual types, see
Chapter 5.
|
cursor
|
Causes the server to use a particular cursor when the pointer is in the
window.
|
Table 3-2 lists default values for the set window attributes data
structure.
Table 3-2 Default Values of the Set Window Attributes Data Structure
Member Name |
Default Value |
background_pixmap
|
None
|
background_pixel
|
Undefined
|
border_pixmap
|
Copied from the parent window
|
border_pixel
|
Undefined
|
bit_gravity
|
Window contents not retained
|
win_gravity
|
Window not moved
|
backing_store
|
Window contents not retained
|
backing_planes
|
All 1s
|
backing_pixel
|
0
|
save_under
|
False
|
event_mask
|
Empty set
|
do_not_propagate_mask
|
Empty set
|
override_redirect
|
False
|
colormap
|
Copied from parent
|
cursor
|
None
|
Xlib assigns a flag for each member of the set window attributes data
structure to facilitate referring to the members, as listed in
Table 3-3.
Table 3-3 Set Window Attributes Data Structure Flags
Flag Name |
Set Window Attributes Member |
CWBackPixmap
|
background_pixmap
|
CWBackPixel
|
background_pixel
|
CWBorderPixmap
|
border_pixmap
|
CWBorderPixel
|
border_pixel
|
CWBitGravity
|
bit_gravity
|
CWWinGravity
|
win_gravity
|
CWBackingStore
|
backing_store
|
CWBackingPlanes
|
backing_planes
|
CWBackingPixel
|
backing_pixel
|
CWSaveUnder
|
save_under
|
CWEventMask
|
event_mask
|
CWDontPropagate
|
do_not_propagate
|
CWOverrideRedirect
|
override_redirect
|
CWColormap
|
colormap
|
CWCursor
|
cursor
|
Example 3-2 illustrates how clients can define window attributes while
creating input-output windows with the CREATE WINDOW routine. The
program creates a parent window and two children windows. The hierarchy
of the subwindows is determined by the order in which the program
creates them. In this case, subwin1 is superior to
subwin2, which is created last.
Example 3-2 Defining Attributes When Creating
Windows |
Window window, subwindow1,subwindow2;
int n;
.
.
.
static void doCreateWindows( )
{
int windowW = 600;
int windowH = 600;
int windowX = (WidthOfScreen(screen)-windowW)>>1;
int windowY = (HeightOfScreen(screen)-windowH)>>1;
int subwindow1X = 150;
int subwindow1Y = 100;
int subwindow1W = 300;
int subwindow1H = 400;
int subwindow2X = 275;
int subwindow2Y = 125;
int subwindow2W = 50;
int subwindow2H = 150;
(1) XSetWindowAttributes xswa;
.
.
.
/* Create the window window */
(2) xswa.event_mask = ExposureMask | ButtonPressMask;
xswa.background_pixel = doDefineColor(1);
(3) window = XCreateWindow(dpy, XRootWindowOfScreen(screen),
windowX, windowY, windowW, windowH, 0,
XDefaultDepthOfScreen(screen), InputOutput,
XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa);
/* Create the window subwindow1 */
xswa.background_pixel = doDefineColor(3);
subwindow1 = XCreateWindow(dpy, window, subwindow1X, subwindow1Y, subwindow1W,
subwindow1H, 4, XDefaultDepthOfScreen(screen), InputOutput,
XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa);
/* Create the window subwindow2 */
xswa.background_pixel = doDefineColor(3);
subwindow2 = XCreateWindow(dpy, window, subwindow2X, subwindow2Y, subwindow2W,
subwindow2H, 4, XDefaultDepthOfScreen(screen), InputOutput,
XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa);
}
.
.
.
static int doDefineColor(n)
{
.
.
.
|
- Allocate storage for a set window attributes
data structure used to define window attributes.
- Set the attributes of the parent window. The
client indicates an interest in window exposure and button press
events. For more information about events, see Chapter 9.
The
client defines the window background by calling the client-defined
doDefineColor routine. For more information about defining
colors, see Chapter 5.
- The CREATE WINDOW routine call has the
following format:
window_id_return=XCreateWindow(display, parent_id, x_coord,
y_coord, width, height, border_width, depth, class,
visual_struc,
attributes_mask, attributes)
|
The depth of a window is its number of bits per pixel. The call
passes a display information routine to indicate that the client wants
the parent window depth to be identical to the display depth. The
window class can be either input only or input-output, specified by the
following constants:
If the window is the same class as the parent, pass the constant
CopyFromParent. The visual type indicates how the
window displays color values. For more information about visual types,
see Chapter 5.
3.3 Destroying Windows
When a client no longer needs a window, the client should destroy it
using either the DESTROY WINDOW or the DESTROY SUBWINDOWS routine.
DESTROY WINDOW destroys a specified window and all its subwindows.
DESTROY SUBWINDOWS destroys all subwindows of a specified window in
bottom-to-top stacking order.
Destroying a window frees all storage allocated for that window. If the
window is mapped to the screen, the server notifies all applications
that the window has been destroyed.
3.4 Mapping and Unmapping Windows
After creating a window, the client can map it to a screen using the
MAP WINDOW or MAP SUBWINDOWS routine. Mapping generally makes a window
visible at the location the client specified when creating it. Part or
all of the window is not visible when the following conditions occur:
- One or more windows higher in the stacking order obscure it
- One or more window ancestors are not mapped
- The new window extends beyond the boundary of its parent
MAP WINDOW maps a window. If the window is an inferior, and one or more
of its ancestors have not been mapped, the server considers the window
to be mapped after the call, even though the window is not visible on
the screen. The window becomes visible when its ancestors are mapped.
To map all subwindows of a specified window in top-to-bottom order, use
MAP SUBWINDOWS. Using the MAP SUBWINDOWS routine to map several windows
may be more efficient than calling the MAP WINDOW routine to map each
window. The MAP SUBWINDOWS routine enables the server to map all of the
windows at one time instead of mapping a single window with the MAP
WINDOW routine.
To ensure that the window is completely visible, use the MAP RAISED
routine. MAP RAISED reorders the stack with the window on top and then
maps the window.
Example 3-3 illustrates how a window is mapped and raised to the top
of the stack.
Example 3-3 Mapping and Raising Windows |
Window window,subwindow1,subwindow2;
/* Create windows in the following order: window, subwindow2, subwindow1 */
.
.
.
static void doMapWindows( )
{
XMapWindow(dpy, window);
(1) XMapWindow(dpy, subwindow2);
(2) XMapRaised(dpy, subwindow1);
}
|
- In this example, the client created
subwindow1 after subwindow2, putting
subwindow1 at the top of the stack.
Consequently, whether
subwindow2 were to be mapped before or after
subwindow1, subwindow1 would obscure
subwindow2. The effect is illustrated in Figure 3-5.
- Mapping and raising subwindow2 moves
it to the top of the stack. It is now visible, as Figure 3-6
illustrates.
When the client no longer needs a window mapped to the screen, call
UNMAP WINDOW.
If the window is a parent, its children are no longer visible after the
call, although they are still mapped. The children become visible when
the parent is mapped again.
To unmap all subwindows of a specified window, use UNMAP SUBWINDOWS.
UNMAP SUBWINDOWS results in an UNMAP WINDOW call on all subwindows of
the parent, from bottom-to-top stacking order.
Figure 3-5 Window Before Restacking
Figure 3-6 Restacked Window
3.5 Associating Properties with Windows
Xlib enables clients to associate data with a window. This data is
considered a property of the window. For example, a
client could store text as a window property. Although a property must
be data of only one type, it can be stored in 8-bit, 16-bit, and 32-bit
formats.
Xlib uses atoms to uniquely identify properties. An
atom is a string paired with an identifier. For example, a client could
use the atom XA_WM_ICON_NAME to name a window icon stored for later
use. The atom XA_WM_ICON_NAME pairs the string XA_WM_ICON_NAME with a
value, 37, that uniquely identifies a property.
In DECW$INCLUDE:XATOMS.H, VMS DECwindows includes predefined atoms such
as XA_WM_ICON_NAME for commonly used properties. Table 3-4 lists by
function all predefined atoms except those used to identify font
properties and atoms used to communicate with the window manager. See
Chapter 12 for a list of atoms related to window management. See
Chapter 8 for a list of atoms related to fonts.
Table 3-4 Predefined Atoms
For Global Selection |
XA_PRIMARY
|
XA_SECONDARY
|
For Cut Buffers |
XA_CUT_BUFFER0
|
XA_CUT_BUFFER1
|
XA_CUT_BUFFER2
|
XA_CUT_BUFFER3
|
XA_CUT_BUFFER4
|
XA_CUT_BUFFER5
|
XA_CUT_BUFFER6
|
XA_CUT_BUFFER7
|
For Color Maps |
XA_RGB_COLOR_MAP
|
XA_RGB_BEST_MAP
|
XA_RGB_BLUE_MAP
|
XA_RGB_RED_MAP
|
XA_RGB_GREEN_MAP
|
XA_RGB_GRAY_MAP
|
XA_RGB_DEFAULT_MAP
|
|
For Resources |
XA_RESOURCE_MANAGER
|
XA_ARC
|
XA_ATOM
|
XA_BITMAP
|
XA_CARDINAL
|
XA_COLORMAP
|
XA_CURSOR
|
XA_DRAWABLE
|
XA_FONT
|
XA_INTEGER
|
XA_PIXMAP
|
XA_POINT
|
XA_RECTANGLE
|
XA_STRING
|
XA_VISUALID
|
XA_WINDOW
|
Note
The Inter-Client Communications Convention (ICCC) discourages the use
of cut buffer atoms. Use the primary and secondary atoms as the
selection mechanism.
|
In addition to providing predefined atoms, Xlib enables clients to
create atom names of their own. To create an atom name, use the INTERN
ATOM routine, as in the following example:
.
.
.
Atom atom_id;
char *name = "MY_ATOM";
Bool if_exists;
atom_id = XInternAtom(dpy, name, if_exists);
.
.
.
|
The routine returns an identifier associated with the string MY_ATOM.
If the atom does not exist in the atom table, Xlib returns the value
none. Note that any atom identifier and its associated name remain
defined until the server is reset. Example 3-4 uses the INTERN ATOM
routine to exchange properties between two windows.
To get the name of an atom, use the GET ATOM NAME routine, as in the
following example:
.
.
.
char *name;
Atom atom_id = 39;
name = XGetAtomName(dpy, atom_id);
.
.
.
|
The routine returns a string associated with the atom identifier.
Xlib enables clients to change, obtain, update, and interchange
properties. Example 3-4 illustrates exchanging properties between two
subwindows. The example uses the CHANGE PROPERTY routine to set a
property on the parent window and the GET PROPERTY routine to get the
data from the parent window. In addition, the example uses the INTERN
ATOM routine.
Example 3-4 Exchanging Window Properties |
#define windowWidth 600
#define windowHeight 600
#define subwindowWidth 300
#define subwindowHeight 150
#define true 1
display *dpy;
window win, subwin1, sunwin2;
gc gc;
screen *screen;
int n;
atom atom_id;
char *name = "my_atom";
bool if_exists;
.
.
.
static void doCreateWindows( )
{
int winW = windowWidth;
int winH = windowHeight;
int winX = 100;
int winY = 100;
int subwindow1X = 150;
int subwindow1Y = 100;
int subwindow2X = 150;
int subwindow2Y = 350;
XSetWindowAttributes xswa;
/* Create the win window */
xswa.event_mask = ExposureMask | ButtonPressMask | PropertyChangeMask;
xswa.background_pixel = doDefineColor(1);
win = XCreateWindow(dpy, RootWindowOfScreen(screen),
winX, winY, winW, winH, 0,
DefaultDepthOfScreen(screen), InputOutput,
DefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa);
/* Create the subwindows */
xswa.event_mask = ExposureMask| ButtonPressMask;
xswa.background_pixel = doDefineColor(2);
subwin1 = XCreateWindow(dpy, win, subwindow1X, subwindow1Y, subwindowWidth,
subwindowHeight, 0, DefaultDepthOfScreen(screen), InputOutput,
DefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa);
subwin2 = XCreateWindow(dpy, win, subwindow2X, subwindow2Y, subwindowWidth,
subwindowHeight, 0, DefaultDepthOfScreen(screen), InputOutput,
DefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa);
.
.
.
/***** Handle events ******/
static void doHandleEvents( )
{
XEvent event;
for ( ; ; ) {
XNextEvent(dpy, &event);
switch (event.type) {
case Expose: doExpose(&event); break;
case ButtonPress: doButtonPress(&event);break;
case PropertyNotify: doPropertyNotify(&event);break;
}
}
}
.
.
.
/***** Handle button presses *******/
static void doButtonPress(eventP)
XEvent *eventP;
{
char *property_data = "You clicked MB1";
if (eventP->xbutton.button == Button2) sys$exit(1);
if (eventP->xbutton.window == subwin1 && eventP->xbutton.button == Button1)
(1) XChangeProperty(dpy, win, atom_id, XA_STRING, 16,
PropModeReplace, property_data, 15);
return;
}
/***** Get the property and draw text into the subwindow *******/
static void doPropertyNotify(eventP)
XEvent *eventP;
{
long offset = 0;
long length = 1000;
Atom type_returned;
int format_returned;
unsigned long num_items_returned, bytes_remaining;
unsigned char *property_returned;
if (eventP->xproperty.atom == atom_id){
(2) XGetWindowProperty(dpy, win, atom_id, offset, length,
true, XA_STRING, &type_returned, &format_returned,
&num_items_returned, &bytes_remaining, &property_returned);
(3) XDrawString(dpy, subwin2, gc, 75, 75, property_returned,
num_items_returned);
}
return;
}
|
|