VMS DECwindows Guide to Xlib (Release 4) Programming: MIT C Binding


Previous Contents Index

  1. The client assigns window width and height the value of 600 (pixels) each.
  2. 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.
  3. 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:

Clients creating input-only windows can define the following attributes:

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:

  1. Assign values to the relevant members of a set window attributes data structure.
  2. 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) 
{ 
                    .
                    .
                    .

  1. Allocate storage for a set window attributes data structure used to define window attributes.
  2. 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.
  3. 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:

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);        
}  

  1. 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.
  2. 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; 
}                                                          


Previous Next Contents Index