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


Previous Contents Index

Use the GET VISUAL INFO routine to return a list of visual structures that match a specified template.

The GET VISUAL INFO routine has the following format:

X$GET_VISUAL_INFO(display, vinfo_mask, vinfo_template,
num_items_return [,items_return] [,items_size]
[,items_buff_return])

Use the MATCH VISUAL INFO routine to return the visual information for a visual type that matches the specified depth and class for a screen. Because multiple visual types that match the specified depth and class can exist, the exact visual chosen is undefined.

Note that the MATCH VISUAL INFO routine is a convenience routine that matches one visual of a particular class and depth. The GET VISUAL INFO routine, however, can find any number of visuals that match any combination of characteristics.

The MATCH VISUAL INFO routine has the following format:

X$MATCH_VISUAL_INFO(display, screen_number, depth, class,
vinfo_return)

5.3 Sharing Color Resources

Xlib provides the following ways to share color resources:

The choice of using a named color or specifying an exact color depends on the needs of the client. For instance, if the client is producing a bar graph, specifying the named VMS DECwindows color "Red" as a color value may be sufficient, regardless of the hue that VMS DECwindows names "Red". However, if the client is reproducing a portrait, specifying an exact red color value might be necessary to produce accurate skin tones. For a list of named colors, see the SYS$MANAGER:DECW$RGB.COM file.

Note that because of differences in hardware, no two monitors display colors exactly the same, even though the same named colors are specified.

5.3.1 Using Named Colors

VMS DECwindows includes named colors that clients can share. To use a named color, call the ALLOC NAMED COLOR routine. ALLOC NAMED COLOR determines whether the color map defines a value for the specified color. If the color exists, the server returns the index to the color map. If the color does not exist, the server returns an error.

Example 5-1 illustrates specifying a color using ALLOC NAMED COLOR.

Example 5-1 Using Named VMS DECwindows Colors

        INTEGER*4 FUNCTION DEFINE_COLOR(DISP, SCRN, VISU, N) 
 
        INCLUDE 'SYS$LIBRARY:DECW$XLIBDEF' 
 
 
        INTEGER*4 DISP, SCRN, N 
        RECORD /X$VISUAL/ VISU      ! visual type 
(1)      RECORD /X$COLOR/ SCREEN_COLOR 
        INTEGER*4 STR_SIZE, STATUS, COLOR_MAP 
(2)      CHARACTER*15 COLOR_NAME(3) 
        DATA COLOR_NAME /'DARK SLATE BLUE', 'LIGHT GREY    ', 'FIREBRICK     '/ 
           
        IF (VISU.X$L_VISU_CLASS .EQ. X$C_TRUE_COLOR .OR. 
        1   VISU.X$L_VISU_CLASS .EQ. X$C_PSEUDO_COLOR .OR. 
        1   VISU.X$L_VISU_CLASS .EQ. X$C_DIRECT_COLOR .OR. 
        1   VISU.X$L_VISU_CLASS .EQ. X$C_STATIC_COLOR) .THEN. 
 
            COLOR_MAP = X$DEFAULT_COLORMAP_OF_SCREEN(SCRN) 
(3)      STATUS = STR$TRIM(COLOR_NAME(N), 
        1               COLOR_NAME(N), STR_SIZE) 
(4)      STATUS = X$ALLOC_NAMED_COLOR(DISP, COLOR_MAP, 
        1                COLOR_NAME(N)(1:STR_SIZE), SCREEN_COLOR) 
            IF (STATUS) THEN 
                DEFINE_COLOR = SCREEN_COLOR.X$L_COLR_PIXEL 
            ELSE 
                WRITE(6,*) 'Color not allocated!' 
                CALL LIB$SIGNAL(%VAL(STATUS)) 
                DEFINE_COLOR = 0 
            END IF 
        ELSE 
            IF (N .EQ. 1 .OR. N .EQ. 3) 
        1        DEFINE_COLOR = X$BLACK_PIXEL_OF_SCREEN(DISP) 
 
            IF (N .EQ. 2 ) 
        1        DEFINE_COLOR = X$WHITE_PIXEL_OF_SCREEN(DISP) 
        END IF 
 
        RETURN 
        END 

  1. Allocate storage for a color data structure that defines the closest RGB values supported by the hardware.
    For an illustration of the color data structure, see Section 5.3.2.
  2. Create an array to store the names of predefined VMS DECwindows colors used by the client. In the sample program, the client uses three named colors: dark slate blue, light grey, and firebrick. When allocating a color, the client refers to the array element that stores the appropriately named VMS DECwindows color.
  3. Xlib requires clients to pass names of predefined colors without padding. In the DEFINE_COLOR function, the names of predefined colors are stored in an array of three 15-byte members. Because the names light grey and firebrick require less than 15 bytes of storage, they are padded.
    To pass the names without padding, use the system-defined procedure STR$TRIM, which returns to the STR_SIZE variable the length of the string minus any trailing blanks.
  4. The ALLOC NAMED COLOR routine has the following format:

    X$ALLOC_NAMED_COLOR(display, colormap_id, color_name,
    [screen_def_return], [exact_def_return])


    The client refers to array COLOR_NAME to pass the name of the color. The client passes only the substring that contains the predefined name; blanks used to pad the array are ignored.

5.3.2 Specifying Exact Color Values

To specify exact color values, use the following method:

  1. Assign values to a color data structure.
  2. Call the ALLOC COLOR routine, specifying the color map from which the client allocates the definition. ALLOC COLOR returns a pixel value and changes the RGB values to indicate the closest color supported by the hardware.

Xlib provides a color data structure enabling clients to specify exact color values when sharing colors. (Routines that allocate colors for exclusive use and that query available colors also use the color data structure. For information about using the color data structure for these purposes, see Section 5.4.)

Figure 5-5 illustrates the color data structure.

Figure 5-5 Color Data Structure


Xlib provides clients with routines that draw graphics into windows and pixmaps. This chapter describes how to create and manage graphics drawn into windows, including the following topics:

Chapter 7 describes drawing graphics into pixmaps.

6.1 Graphics Coordinates

Xlib graphics coordinates define the position of graphics drawn in a window or pixmap. Coordinates are either relative to the origin of the window or pixmap in which the graphics object is drawn or relative to a previously drawn graphics object.

Xlib graphics coordinates are similar to the coordinates that define window position. Xlib measures length along the x-axis from the origin to the right. Xlib measures length along the y-axis from the origin down. Xlib specifies coordinates in units of pixels.

6.2 Using Graphics Routines Efficiently

If clients use the same drawable and graphics context for each call, Xlib handles back-to-back calls of DRAW POINT, DRAW LINE, DRAW SEGMENT, DRAW RECTANGLE, FILL ARC, and FILL RECTANGLE in a batch. Batching increases efficiency by reducing the number of requests to the server.

When drawing more than a single point, line, rectangle, or arc, clients can also increase efficiency by using routines that draw or fill multiple graphics (DRAW POINTS, DRAW LINES, DRAW SEGMENTS, DRAW RECTANGLES, DRAW ARCS, FILL ARCS, and FILL RECTANGLES). Clipping negatively affects efficiency. Consequently, clients should ensure that graphics they draw to a window or pixmap are within the boundary of the drawable. Drawing outside the window or pixmap decreases performance. Clients should also ensure that windows into which they are drawing graphics are not occluded.

The most efficient method for clearing multiple areas is using the FILL RECTANGLES routine. By using the FILL RECTANGLES routine, clients can increase server performance. For information about using FILL RECTANGLES to clear areas, see Section 6.6.1.

6.3 Drawing Points and Lines

Xlib includes routines that draw points and lines. When clients draw more than one point or line, performance is affected. Performance is most efficient if clients use Xlib routines that draw multiple points or lines rather than calling single point and line-drawing routines many times.

This section describes using routines that draw both single and multiple points and lines.

6.3.1 Drawing Points

To draw a single point, use the DRAW POINT routine, specifying x-axis and y-axis coordinates, as in the following:


        PARAMETER X = 100, Y = 100 
                    .
                    .
                    .
        CALL X$DRAW_POINT(DPY, WINDOW, GC, X, Y) 

If drawing more than one point, use the following method:

  1. Define an array of point data structures.
  2. Call the DRAW POINTS routine, specifying the array that defines the points, the number of points the server is to draw, and the coordinate system the server is to use. The server draws the points in the order specified by the array.

Xlib includes the point data structure to enable clients to define an array of points easily. Figure 6-1 illustrates the data structure.

Figure 6-1 Point Data Structure


point_pic.tex

Table 6-1 describes the members of the data structure.

Table 6-1 Point Data Structure Members
Member Name Contents
X$W_GPNT_X Defines the x value of the coordinate of a point
X$W_GPNT_Y Defines the y value of the coordinate of a point

The server determines the location of points according to the following:

The server refers to the following members of the GC data structure to define the characteristics of points it draws:
Function Plane mask
Foreground Subwindow mode
Clip x origin Clip y origin
Clip mask  

Chapter 4 describes GC data structure members.

Example 6-1 uses the DRAW POINTS routine to draw a circle of points each time the user clicks MB1.

Figure 6-2 illustrates sample output from the program.

Example 6-1 Drawing Multiple Points

C    Create window WINDOW on display DPY, defined as follows:    
C         Position: x = 100,y = 100                    
C         Width = 600                                  
C         Height = 600                                   
C   GC refers to the graphics context   
 
        PARAMETER   POINT_CNT = 100, RADIUS = 50 
                    .
                    .
                    .
 
C 
C       Handle events 
C 
        DO WHILE (.TRUE.) 
 
            CALL X$NEXT_EVENT(DPY, EVENT) 
 
(1)      IF (EVENT.EVNT_TYPE .EQ. X$C_EXPOSE) THEN 
                CALL X$DRAW_IMAGE_STRING(DPY, WINDOW, GC, 
        1           150, 25, 'To create points, click MB1') 
                CALL X$DRAW_IMAGE_STRING(DPY, WINDOW, GC, 
        1           150, 50, 'Each click creates a new circle of points') 
                CALL X$DRAW_IMAGE_STRING(DPY, WINDOW, GC, 
        1           150, 75, 'To exit, click MB2') 
            END IF 
 
(2)      IF (EVENT.EVNT_TYPE .EQ. X$C_BUTTON_PRESS .AND. 
        1       EVENT.EVNT_BUTTON.X$L_BTEV_BUTTON .EQ. X$C_BUTTON1) THEN 
 
            X = EVENT.EVNT_BUTTON.X$L_BTEV_X 
            Y = EVENT.EVNT_BUTTON.X$L_BTEV_Y 
 
            DO I = 1, POINT_CNT 
                POINT_ARR(I).X$W_GPNT_X = X + RADIUS * COS(FLOAT(I)) 
                POINT_ARR(I).X$W_GPNT_Y = Y + RADIUS * SIN(FLOAT(I)) 
            END DO 
 
(3)      CALL X$DRAW_POINTS(DPY, WINDOW, GC, POINT_ARR, POINT_CNT, 
        1               X$C_COORD_MODE_ORIGIN) 
 
            ENDIF       
            IF (EVENT.EVNT_TYPE .EQ. X$C_BUTTON_PRESS .AND. 
        1       EVENT.EVNT_BUTTON.X$L_BTEV_BUTTON .EQ. X$C_BUTTON2) THEN 
                CALL SYS$EXIT(%VAL(1)) 
            END IF 
        END DO 

  1. After receiving notification that the server has mapped the window, the client writes three messages into the window. For information about using the DRAW IMAGE STRING routine, see Chapter 8.
  2. If the user clicks MB1, the client draws 50 points. If the user clicks MB2, the client exits from the system. The client determines which button the user clicked by referring to the button member of the button event data structure. For more information about the button event data structure, see Chapter 9.
  3. The DRAW POINTS routine has the following format:

    X$DRAW_POINTS(display, drawable_id, gc_id, points, num_points,
    point_mode)


    The point_mode argument specifies whether coordinates are relative to the origin of the drawable or to the previous point in the array.

Figure 6-2 Circles of Points Created Using the DRAW POINTS Routine


6.3.2 Drawing Lines and Line Segments

Xlib includes routines that draw single lines, multiple lines, and line segments. To draw a single line, use the DRAW LINE routine, specifying beginning and ending points, as in the following:


       PARAMETER X1 = 100, Y1 = 100, 
       1     X2 = 200, Y2 = 200 
                    .
                    .
                    .
       CALL X$DRAW_LINE(DISPLAY, WINDOW, GC, X1, Y1, X2, Y2) 

To draw multiple lines, use the following method:

  1. Define an array of points using the point data structure described in Section 6.3.1 to specify beginning and ending line points. The server interprets pairs of array elements as beginning and ending points. For example, if the array that defines the beginning point is point[i] , the server reads point[i+1] as the corresponding ending point.
  2. Call the DRAW LINES routine, specifying the following: The server draws the lines in the order specified by the array.

Clients can specify either the x$c_coord_mode_origin or the x$c_coord_mode_previous constant to indicate how the server determines the location of beginning and ending points. The server uses the methods described in Section 6.3.1.

The server draws lines in the order the client has defined them in the point data structure. Lines join correctly at all intermediate points. If the first and last points coincide, the first and last line also join correctly. For any given line, the server draws pixels only once. The server draws intersecting pixels multiple times if zero-width lines intersect; it draws intersecting pixels of wider lines only once.

Example 6-2 uses the DRAW LINES routine to draw a star when the server notifies the client that the window is mapped.

Example 6-2 Drawing Multiple Lines

C    Create window WINDOW on display DPY, defined as follows:    
C         Position: x = 100,y = 100                    
C         Width = 600                                  
C         Height = 600                                   
C    GC refers to the graphics context   
 
        PARAMETER   POINT_CNT = 100, RADIUS = 50 
                    .
                    .
                    .
C 
C       Handle events 
C 
        DO WHILE (.TRUE.) 
 
            CALL X$NEXT_EVENT(DPY, EVENT) 
 
 
        IF (EVENT.EVNT_TYPE .EQ. X$C_EXPOSE) THEN 
                CALL X$DRAW_IMAGE_STRING(DPY, WINDOW, GC, 
        1           150, 25, 'To create a star, click MB1.') 
                CALL X$DRAW_IMAGE_STRING(DPY, WINDOW, GC, 
        1           150, 50, 'To exit, click MB2.') 
            END IF 
 
(1)      IF (EVENT.EVNT_TYPE .EQ. X$C_BUTTON_PRESS .AND. 
        1       EVENT.EVNT_BUTTON.X$L_BTEV_BUTTON .EQ. X$C_BUTTON1) THEN 
 
            POINT_ARR(1).X$W_GPNT_X = 75 
            POINT_ARR(1).X$W_GPNT_Y = 500 
            POINT_ARR(2).X$W_GPNT_X = 300 
            POINT_ARR(2).X$W_GPNT_Y = 100 
            POINT_ARR(3).X$W_GPNT_X = 525 
            POINT_ARR(3).X$W_GPNT_Y = 500 
            POINT_ARR(4).X$W_GPNT_X = 50 
            POINT_ARR(4).X$W_GPNT_Y = 225 
            POINT_ARR(5).X$W_GPNT_X = 575 
            POINT_ARR(5).X$W_GPNT_Y = 225 
            POINT_ARR(6).X$W_GPNT_X = 75 
            POINT_ARR(6).X$W_GPNT_Y = 500 
 
(2)     CALL X$DRAW_LINES(DPY, WINDOW, GC, POINT_ARR, POINTS, 
        1               X$C_COORD_MODE_ORIGIN) 
            ENDIF       
            IF (EVENT.EVNT_TYPE .EQ. X$C_BUTTON_PRESS .AND. 
        1       EVENT.EVNT_BUTTON.X$L_BTEV_BUTTON .EQ. X$C_BUTTON2) THEN 
                CALL SYS$EXIT(%VAL(1)) 
            END IF 
        END DO 
                    .
                    .
                    .

  1. The program uses point data structures to define beginning and ending points of lines.
  2. The call to draw lines refers to a graphics context (GC), which the client has previously defined, and an array of point data structures. The constant x$c_coord_mode_origin indicates that all points are relative to the origin of WINDOW (100, 100).

Figure 6-3 illustrates the resulting output.

Figure 6-3 Star Created Using the DRAW LINES Routine


Use the DRAW SEGMENTS routine to draw multiple, unconnected lines, defining an array of segments in the segment data structure. Figure 6-4 illustrates the data structure.

Figure 6-4 Segment Data Structure


Table 6-3 describes the members of the data structure.

Table 6-3 Rectangle Data Structure Members
Member Name Contents
X$W_GREC_X Defines the x value of the rectangle origin
X$W_GREC_Y Defines the y value of the rectangle origin
X$W_GREC_WIDTH Defines the width of the rectangle
X$W_GREC_HEIGHT Defines the height of the rectangle

When drawing either single or multiple rectangles, the server refers to the following members of the GC data structure to define rectangle characteristics:
Function Plane mask
Foreground Background
Line width Line style
Join style Fill style
Tile Stipple
Tile/stipple x origin Tile/stipple y origin
Subwindow mode Clip x origin
Clip y origin Clip mask
Dash offset Dashes

Chapter 4 describes the GC data structure members.

Example 6-3 illustrates using the DRAW RECTANGLES routine. Figure 6-8 shows the resulting output.

Example 6-3 Drawing Multiple Rectangles

C    Create window WINDOW on display DPY, defined as follows:    
C         Position: x = 100,y = 100                    
C         Width = 600                                  
C         Height = 600                                   
C    GC refers to the graphics context   
 
        PARAMETER   POINT_CNT = 100, RADIUS = 50 
 
                         .
                         .
                         .
C 
C       Handle events 
C 
        DO WHILE (.TRUE.) 
 
            CALL X$NEXT_EVENT(DPY, EVENT) 
 
(1)          IF (EVENT.EVNT_TYPE .EQ. X$C_EXPOSE) THEN 
                CALL X$DRAW_IMAGE_STRING(DPY, WINDOW, GC, 
        1           150, 25, 'To draw multiple rectangles, click MB1.') 
                CALL X$DRAW_IMAGE_STRING(DPY, WINDOW, GC, 
        1           150, 50, 'To exit, click MB2.') 
            END IF 
 
(2)          IF (EVENT.EVNT_TYPE .EQ. X$C_BUTTON_PRESS .AND. 
        1       EVENT.EVNT_BUTTON.X$L_BTEV_BUTTON .EQ. X$C_BUTTON1) THEN 
 
            DO I = 1, REC_CNT 
                REC_ARR(I).X$W_GREC_X = STEP * I 
                REC_ARR(I).X$W_GREC_Y = STEP * I 
                REC_ARR(I).X$W_GREC_WIDTH = STEP * 2 
                REC_ARR(I).X$W_GREC_HEIGHT = STEP * 3 
            END DO 
 
(3)          CALL X$DRAW_RECTANGLES(DPY, WINDOW, GC, REC_ARR, REC_CNT) 
 
            ENDIF       
 
            IF (EVENT.EVNT_TYPE .EQ. X$C_BUTTON_PRESS .AND. 
        1       EVENT.EVNT_BUTTON.X$L_BTEV_BUTTON .EQ. X$C_BUTTON2) THEN 
                        CALL SYS$EXIT(%VAL(1)) 
            
            END IF 
        END DO 


Previous Next Contents Index