|
VMS DECwindows Guide to Xlib (Release 4)
Programming: VAX Binding
- After receiving notification that the server
has mapped the window, the client writes two messages into the window.
For information about using the DRAW IMAGE STRING routine, see
Chapter 8.
- If the user clicks MB1, the client draws
rectangles defined in the initialization loop. If the user clicks MB2,
the client exits the system. The client determines which button the
user has 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 RECTANGLE routine has the following
format:
X$DRAW_RECTANGLES(display, drawable_id, gc_id, rectangles,
num_rectangles)
|
Figure 6-8 Rectangles Drawn Using the DRAW RECTANGLES
Routine
6.4.2 Drawing Arcs
Xlib routines enable clients to draw either single or multiple arcs. To
draw a single arc, use the DRAW ARC routine, specifying a rectangle
that defines the boundaries of the arc and two angles that determine
the start and extent of the arc, as in the following:
PARAMETER X = 50, Y = 100,
1 WIDTH = 25, LENGTH = 50,
1 ANGLE1 = 5760, ANGLE2 = 5760
.
.
.
CALL X$DRAW_ARC(DISPLAY, WINDOW, GC, X, Y, WIDTH, HEIGHT,
1 ANGLE1, ANGLE2)
|
The server draws an arc within a rectangle. The client specifies the
upper left corner of the rectangle, relative to the origin of the
drawable. The center of the rectangle is the center of the arc. The
width and height of the rectangle are the major and minor axes of the
arc, respectively.
Two angles specify the start and extent of the arc. The angles are
signed integers in degrees scaled up by 64. For example, a client would
specify a 90-degree arc as 64*90 or 5760 . The start of the arc is
specified by the first angle, relative to the three o'clock position
from the center of the rectangle. The extent of the arc is specified by
the second angle, relative to the start of the arc. Positive integers
indicate counterclockwise motion; negative integers indicate clockwise
motion.
To draw multiple arcs, use the following method:
- Define an array of arc data structures.
- Call the DRAW ARCS routine, specifying the array that defines the
arcs and the number of array elements.
Figure 6-9 illustrates the arc data structure.
Figure 6-9 Arc Data Structure
Xlib enables clients to create and work with both on-screen graphics,
such as lines and cursors, and off-screen images, such as pixmaps.
Chapter 4 and Chapter 6 describe how to work with on-screen
graphics objects.
This chapter describes how to work with off-screen graphics resources,
including the following topics:
- Creating and freeing pixmaps
- Creating and managing bitmaps
- Working with images
7.1 Creating and Freeing Pixmaps
A pixmap is an area of memory into which clients can
either define an image or temporarily save part of a screen. Pixmaps
are useful for defining cursors and icons, for creating tiling
patterns, and for saving portions of a window that have been exposed.
Additionally, drawing complicated graphics sequences into pixmaps and
then copying the pixmaps to a window are often faster than drawing the
sequences directly to a window.
Use the CREATE PIXMAP routine to create a pixmap. The routine creates a
pixmap of a specified width, height, and depth. If the width or height
is zero or the depth is not supported by the drawable root window, the
server returns an error. The pixmap must be associated with a window,
which can be either an input-output or an input-only window.
Example 7-1 illustrates creating a pixmap to use as a backing store
for drawing the star of Example 6-5.
Example 7-1 Creating a Pixmap |
C Create window WINDOW on display DPY, defined
C as follows:
C Position: x = 100,y = 100
C Width = 600
C Height = 600
C GC refers to the graphics context
INTEGER*4 PIXMAP
INTEGER*4 EXPOSE_FLAG
.
.
.
C
C Create graphics context
C
GC_MASK = X$M_GC_FOREGROUND .OR. X$M_GC_BACKGROUND
(1) XGCVL.X$L_GCVL_FOREGROUND =
1 DEFINE_COLOR(DPY, SCREEN, VISUAL, 3)
XGCVL.X$L_GCVL_BACKGROUND =
1 DEFINE_COLOR(DPY, SCREEN, VISUAL, 3)
GC = X$CREATE_GC(DPY, WINDOW, GC_MASK, XGCVL)
C
C Create the pixmap
C
(2) PIXMAP = X$CREATE_PIXMAP(DPY, WINDOW, WINDOW_W, WINDOW_H, DEPTH)
(3) CALL X$FILL_RECTANGLE(DPY, PIXMAP, GC, 0, 0, WINDOW_W,
1 WINDOW_H)
CALL X$SET_FOREGROUND(DPY, GC, DEFINE_COLOR(DPY, SCREEN,
1 VISUAL, 2))
(4) CALL X$FILL_POLYGON(DPY, PIXMAP, GC, PT_ARR, 6, X$C_COMPLEX,
1 X$C_COORD_MODE_ORIGIN)
.
.
.
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 filled polygon, click MB1')
CALL X$DRAW_IMAGE_STRING(DPY, WINDOW, GC,
1 150, 75, 'To exit, click MB2')
(5) IF (EXPOSE_FLAG .EQ. 0) THEN
EXPOSE_FLAG = 1
ELSE
CALL X$COPY_AREA(DPY, PIXMAP, WINDOW, GC, 0, 0,
1 WINDOW_W, WINDOW_H, 0, 0)
CALL X$DRAW_IMAGE_STRING(DPY, WINDOW, GC,
1 150, 75, 'To exit, click MB2')
END IF
END IF
IF (EVENT.EVNT_TYPE .EQ. X$C_BUTTON_PRESS .AND.
1 EVENT.EVNT_BUTTON.X$L_BTEV_BUTTON .EQ. X$C_BUTTON1) THEN
CALL X$COPY_AREA(DPY, PIXMAP, WINDOW, GC, 0, 0,
1 WINDOW_W, WINDOW_H, 0, 0)
CALL X$DRAW_IMAGE_STRING(DPY, WINDOW, GC,
1 150, 75, 'To exit, click MB2')
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
END
|
- Pixmaps use only the foreground member of the
graphics context to define color. Because the client is using the
pixmap as backing store, which is copied into the window to repaint
exposed areas, both foreground and background members of the graphics
context are first defined as the window background color.
- The pixmap has the width, height, and depth
of the window.
- FILL RECTANGLE fills the pixmap with the
background color of the window. After filling the pixmap to ensure that
pixel values of both the pixmap and window background are the same, the
foreground color is redefined for graphics operations.
- After redefining foreground color, the client
draws the polygon into the pixmap. For a description of specifying and
filling the polygon, see Example 6-5.
- At the first window exposure, the client
draws only the text into the window. On subsequent exposures, the
client copies the pixmap into the window to repaint exposed areas. For
a description of handling exposure events, see Chapter 9.
Note that the CREATE PIXMAP routine is not a synchronous routine and
does not return an error if the routine fails to create a pixmap.
Although Xlib returns a resource ID for this routine, it does not
indicate that a valid resource was created by the server. Refer to
Section 9.13.3 for a method to check if a pixmap, or any X resource, has
been created.
When a client no longer needs a pixmap, use the FREE PIXMAP routine to
free storage associated with it. FREE PIXMAP first deletes the
association between the pixmap identifier and the pixmap and then frees
pixmap storage.
7.2 Creating and Managing Bitmaps
Xlib enables clients to create files of bitmap data and then to use
those files to create either bitmaps or pixmaps. To create a bitmap
data file, use the WRITE BITMAP FILE routine. Example 7-2 illustrates
creating a pixmap and writing the pixmap data into a bitmap data file.
Example 7-2 Creating a Bitmap Data File |
PT_ARR(1).X$W_GPNT_X = 20
PT_ARR(1).X$W_GPNT_Y = 0
PT_ARR(2).X$W_GPNT_X = 20
PT_ARR(2).X$W_GPNT_Y = 5
PT_ARR(3).X$W_GPNT_X = 20
PT_ARR(3).X$W_GPNT_Y = 10
PT_ARR(4).X$W_GPNT_X = 20
PT_ARR(4).X$W_GPNT_Y = 15
PT_ARR(5).X$W_GPNT_X = 20
PT_ARR(5).X$W_GPNT_Y = 20
.
.
.
C
C Create the pixmap
C
PIXMAP = X$CREATE_PIXMAP(DPY, WINDOW, PIX_WIDTH, PIX_HEIGHT,
1 DEPTH)
CALL X$FILL_RECTANGLE(DPY, PIXMAP, GC, 0, 0, PIX_WIDTH,
1 PIX_HEIGHT)
CALL X$SET_FOREGROUND(DPY, GC, DEFINE_COLOR(DPY, SCREEN,
1 VISUAL, 2))
CALL X$DRAW_LINES(DPY, PIXMAP, GC, PT_ARR, 5, X$C_COORD_MODE)
STATUS = X$WRITE_BITMAP_FILE(DPY, 'BITFILE.DAT', PIXMAP,
1 20, 20, 0, 0)
|
The client first creates a pixmap using the method described in
Section 7.1 and then calls the WRITE BITMAP FILE routine to write the
pixmap data into the BITFILE.DAT bitmap file.
To create a bitmap or pixmap from a bitmap data file, use either the
CREATE BITMAP FROM DATA or CREATE PIXMAP FROM DATA routine.
Example 7-3 illustrates creating a pixmap from the bitmap data stored
in BITFILE.DAT.
Example 7-3 Creating a Pixmap from Bitmap
Data |
.
.
.
LOGICAL*1 LINES(60)
PARAMETER PIX_WIDTH = 16, PIX_HEIGHT = 16
DATA LINES /'AA'X, 'AA'X, '0A'X, '55'X, '55'X, '05'X,
1 'AA'X, 'AA'X, '0A'X, '55'X, '55'X, '05'X, 'AA'X,
1 'AA'X, '0A'X, '55'X, '55'X, '05'X, 'AA'X, 'AA'X,
1 '0A'X, '55'X, '55'X, '05'X, 'AA'X, 'AA'X, '0A'X,
1 '55'X, '55'X, '05'X, 'AA'X, 'AA'X, '0A'X, '55'X,
1 '55'X, '05'X, 'AA'X, 'AA'X, '0A'X, '55'X, '55'X,
1 '05'X, 'AA'X, 'AA'X, '0A'X, '55'X, '55'X, '05'X,
1 'AA'X, 'AA'X, '0A'X, '55'X, '55'X, '05'X, 'AA'X,
1 'AA'X, '0A'X, '55'X, '55'X, '05'X/
.
.
.
C
C Create the pixmap
C
PIX_FOREGROUND = XGCVL.X$L_GCVL_FOREGROUND
PIX_BACKGROUND = XGCVL.X$L_GCVL_BACKGROUND
PIXMAP = X$CREATE_PIX_FROM_BITMAP_DATA(DPY, WINDOW, LINES,
1 PIX_WIDTH, PIX_HEIGHT, PIX_FOREGROUND,
1 PIX_BACKGROUND, DEPTH)
CALL X$SET_WINDOW_BACKGROUND_PIXMAP(DPY, WINDOW, PIXMAP)
.
.
.
|
The client uses the pixmap to define window background.
7.3 Working with Images
Instead of managing images directly, clients perform operations on them
by using the image data structure, which includes a pointer to data
such as the LINES array defined in Example 7-3. In addition to the
image data, the image data structure includes pointers to
client-defined functions that perform the following operations:
- Destroying an image
- Getting a pixel from the image
- Storing a pixel in the image
- Extracting part of the image
- Adding a constant to the image
If the client has not defined a function, the corresponding Xlib
routine is called by default.
Figure 7-1 illustrates the data structure.
Figure 7-1 Image Data Structure
5643ximage_pic.tex
Table 7-1 describes the members of the data structure.
Table 7-1 Image Data Structure Members
Member Name |
Contents |
X$L_IMAG_WIDTH
|
Specifies the width of the image.
|
X$L_IMAG_HEIGHT
|
Specifies the height of the image.
|
X$L_IMAG_OFFSET
|
Specifies the number of pixels offset in the x direction. Specifying an
offset permits the server to ignore the beginning of scanlines and
rapidly display images when Z pixmap format is used.
|
X$L_IMAG_FORMAT
|
Specifies whether the data is stored in XY pixmap or Z pixmap format.
The following flags facilitate specifying data format:
Flag Name |
Description |
x$c_xy_bitmap
|
A single bitmap representing one plane
|
x$c_xy_pixmap
|
A set of bitmaps representing individual planes
|
x$c_z_pixmap
|
Data organized as a list of pixel values viewed as a horizontal row
|
|
X$A_IMAG_DATA
|
Specifies the address of the image data.
|
X$L_IMAG_BYTE_ORDER
|
Indicates whether the least significant or the most significant byte is
first.
|
X$L_IMAG_BITMAP_UNIT
|
Specifies whether the bitmap is organized in units of 8-, 16-, or
32-bits.
|
X$L_IMAG_BITMAP_BIT_ORDER
|
Specifies whether the bitmap order is least or most significant.
|
X$L_IMAG_BITMAP_PAD
|
Specifies whether padding in XY format or Z format should be done in
units of 8-, 16-, or 32-bits.
|
X$L_IMAG_DEPTH
|
Specifies the depth of the image.
|
X$L_IMAG_BYTES_PER_LINE
|
Specifies the bytes per line to be used as an accelerator.
|
X$L_IMAG_BITS_PER_PIXEL
|
Indicates for Z format the number of bits per pixel.
|
X$L_IMAG_RED_MASK
|
Specifies the red value of Z format.
|
X$L_IMAG_GREEN_MASK
|
Specifies the green value of Z format.
|
X$L_IMAG_BLUE_MASK
|
Specifies blue values of Z format.
|
X$A_IMAG_OBDATA
|
Specifies a data structure that contains object routines.
|
X$A_IMAG_CREATE_IMAGE
|
Specifies a client-defined function that creates an image.
|
X$A_IMAG_DESTROY_IMAGE
|
Specifies a client-defined function that destroys an image.
|
X$A_IMAG_GET_PIXEL
|
Specifies a client-defined function that gets the value of a pixel in
the image.
|
X$A_IMAG_PUT_PIXEL
|
Specifies a client-defined function that changes the value of a pixel
in the image.
|
X$A_IMAG_SUB_IMAGE
|
Specifies a client-defined function that creates a new image from an
existing one.
|
X$A_IMAG_ADD_PIXEL
|
Specifies a client-defined function that increments each pixel value in
the image by a constant.
|
To create an image, use either the CREATE IMAGE or the GET IMAGE
routine. CREATE IMAGE initializes an image data structure, including a
reference to the image data. For example, the following call creates an
image data structure that points to the image data LINES, illustrated
in Example 7-3:
RECORD /X$IMAGE/ IMAGE
.
.
.
PARAMETER WINDOW_W = 600, WINDOW_H = 600,
1 PIX_WIDTH = 16, PIX_HEIGHT = 16,
1 BITMAP_PAD 16, BYTES_PER_LINE 16
.
.
.
STATUS = X$CREATE_IMAGE(DPY, VISUAL, DEPTH, X$C_Z_PIXMAP,
1 0, LINES, PIX_WIDTH, PIX_HEIGHT, BITMAP_PAD,
1 BYTES_PER_LINE, IMAGE)
IF (STATUS .EQ. 0) THEN
WRITE(6,*) 'Image not created!'
CALL SYS$EXIT(%VAL(1))
ENDIF
.
.
.
|
Note that the CREATE IMAGE routine does not allocate storage space for
the image data.
To create an image from a drawable, use the GET IMAGE routine.
In the following example, the client creates an image from a pixmap:
PARAMETER X_ORIGIN = 0, Y_ORIGIN = 0,
1 PIX_WIDTH = 16, PIX_HEIGHT = 16
.
.
.
IMAGE = X$GET_IMAGE(DPY, PIXMAP, X_ORIGIN, Y_ORIGIN,
1 PIX_WIDTH, PIX_HEIGHT, XGCVL.X$L_GCVL_PLANE_MASK,
1 X$C_Z_PIXMAP)
.
.
.
|
When the client calls the GET IMAGE routine and the drawable is a
window, the window must be mapped. In addition, if there are no
inferiors or overlapping windows, the specified rectangle of the window
should be fully visible on the screen and wholly contained within the
outside edges of the window. In other words, an error results if the
GET IMAGE routine is called to get a portion of a window that is
off-screen.
To transfer an image from memory to a drawable, use the PUT IMAGE
routine.
In the following example, the client transfers the image from memory to
a window:
PARAMETER SRC_X = 0, SRC_Y = 0,
1 DST_X = 200, DST_Y = 200,
1 PIX_WIDTH = 16, PIX_HEIGHT = 16
.
.
.
CALL X$PUT_IMAGE(DPY, WINDOW, GC, IMAGE, SRC_X, SRC_Y,
1 DST_X, DST_Y, PIX_WIDTH, PIX_HEIGHT)
.
.
.
|
The call transfers the entire image, which was created in the call to
GET IMAGE, from memory to coordinates (200, 200) in the window.
As the description of the image data structure indicates, Xlib enables
clients to store an image in the following ways:
- As a bitmap---XY bitmap format stores the image as a
two-dimensional array. Figure 7-2 illustrates XY bitmap format.
- As a set of bitmaps---XY pixmap format stores the image as a stack
of bitmaps. Figure 7-3 illustrates XY pixmap format.
- As a list of pixel values---Z pixmap format stores the image as a
list of pixel values viewed as a horizontal row. Each example of
creating an image uses Z pixmap format.
Figure 7-4 illustrates scanline order.
Figure 7-2 XY Bitmap Format
Figure 7-3 XY Pixmap Format
Figure 7-4 Z Format
Xlib includes routines to change images by manipulating their pixel
values and creating new images out of subsections of existing images.
Table 7-2 lists these routines and their use. Clients can override
these routines by defining functions referred to in the image data
structure.
Table 7-2 Routines That Change Images
Routine |
Description |
ADD PIXEL
|
Increments each pixel in an image by a constant value
|
GET PIXEL
|
Returns the pixel value of an image
|
PUT PIXEL
|
Sets the pixel value of an image
|
SUB IMAGE
|
Creates a new image out of a subsection of an existing image
|
When a client no longer needs an image, use the DESTROY IMAGE routine
to deallocate memory associated with the image data structure.
|