|
VMS DECwindows Guide to Xlib (Release 4)
Programming: VAX Binding
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:
- Using named VMS DECwindows colors
- Specifying exact color values
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
|
- 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.
- 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.
- 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.
- 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:
- Assign values to a color data structure.
- 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:
- Drawing points, lines, rectangles, and arcs
- Filling rectangles, polygons, and arcs
- Copying graphics
- Limiting graphics to a region of a window or pixmap
- Clearing graphics from a window
- Creating cursors
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:
- Define an array of point data structures.
- 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
Table 6-1 describes the members of the data structure.
The server determines the location of points according to the following:
- If the client specifies the constant
x$c_coord_mode_origin, the server defines all points
in the array relative to the origin of the drawable.
- If the client specifies the constant
x$c_coord_mode_previous, the server defines the
coordinates of the first point in the array relative to the origin of
the drawable and the coordinates of each subsequent point relative to
the point preceding it in the array.
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
|
- 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.
- 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.
- 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:
- 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.
- Call the DRAW LINES routine, specifying the following:
- The array that defines the points.
- The number of points that define the line.
- The coordinate system the server uses to locate the points.
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
.
.
.
|
- The program uses point data structures to
define beginning and ending points of lines.
- 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
|
|