HP OpenVMS Systems Documentation

Content starts here

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


Previous Contents Index

  1. 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.
  2. 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.
  3. 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:

  1. Define an array of arc data structures.
  2. 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
  1. 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.
  2. The pixmap has the width, height, and depth of the window.
  3. 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.
  4. 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.
  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.


Previous Next Contents Index