Appendix E. Writing a Device Handler

E.1 Introduction

PGPLOT can be configured for a particular installation by adding or removing ``device handlers''. A device handler is a subroutine which handles all the device-specific aspects of graphical output for a particular device or class of devices.

To write a new device handler, it is simplest to start by modifying an existing one. This Appendix explains what the device handler must do, but it does not explain how to do it---which is, of course, very hardware-dependent.

E.2 The device dispatch routine GREXEC

All graphical output and input is handled by a ``device dispatch routine'' in PGPLOT, called GREXEC. Routine GREXEC is called whenever PGPLOT needs to determine device-specific information or perform graphical I/O. This routine in turn calls on the appropriate device handler. Reconfiguring PGPLOT involves modifying the GREXEC routine to use a different set of device handlers; no other changes to PGPLOT are needed.

Usually the Fortran code for GREXEC is created automatically from a list of selected device handlers during the installation of PGPLOT.

Table E.1: Example Device Dispatch Routine
C*GREXEC -- PGPLOT device handler dispatch routine
C+
      SUBROUTINE GREXEC(IDEV,IFUNC,RBUF,NBUF,CHR,LCHR)
      INTEGER IDEV, IFUNC, NBUF, LCHR
      REAL    RBUF(*)
      CHARACTER*(*) CHR
C---
      INTEGER NDEV
      PARAMETER (NDEV=6)
      CHARACTER*10 MSG
C---
      GOTO(1,2,3,4,5,6) IDEV
      IF (IDEV.EQ.0) THEN
          RBUF(1) = NDEV
          NBUF = 1
      ELSE
          WRITE (MSG,'(I10)') IDEV
          CALL GRWARN('Unknown device code in GREXEC: '//MSG)
      END IF
      RETURN
C---
1     CALL NUDRIV(IFUNC,RBUF,NBUF,CHR,LCHR)
      RETURN
2     CALL PSDRIV(IFUNC,RBUF,NBUF,CHR,LCHR,1)
      RETURN
3     CALL PSDRIV(IFUNC,RBUF,NBUF,CHR,LCHR,2)
      RETURN
4     CALL TTDRIV(IFUNC,RBUF,NBUF,CHR,LCHR,1)
      RETURN
5     CALL XWDRIV(IFUNC,RBUF,NBUF,CHR,LCHR,1)
      RETURN
6     CALL XWDRIV(IFUNC,RBUF,NBUF,CHR,LCHR,2)
      RETURN
C
      END

Table E.1 gives an example. The first argument (IDEV) is an integer specifying the type of the currently selected device. Routine GREXEC calls the appropriate device handler for this type, passing the remaining arguments to the device handler. If IDEV is zero, GREXEC returns the number of device types available. Some device handlers handle more than one PGPLOT device type: e.g., in the above example PSDRIV handles both types PS and VPS. The last argument passed to the device handler is an integer specifying which of the supported types is required. This argument is omitted for handlers that support only one type (NUDRIV in the above example).

To reconfigure PGPLOT, GREXEC must be modified as follows: (a) set parameter NDEV to the number of device types; (b) make sure that the computed-goto statement has NDEV branches; (c) supply a target for each branch to call the appropriate device handler.

E.3 Device handler interface

A device handler is a Fortran (or Fortran-callable) subroutine. The name of the subroutine must be of the form xxDRIV, where xx is a two-character code for the device type, usually the first two letters of the type; this code must (of course) be different for each different device handler.
      SUBROUTINE xxDRIV (OPCODE, RBUF, NBUF, CHR, LCHR, MODE)
      INTEGER        OPCODE
      REAL           RBUF(*)
      INTEGER        NBUF
      CHARACTER*(*)  CHR
      INTEGER        LCHR
      INTEGER        MODE
The first argument (OPCODE) is an integer ``operation code'' which specifies what operation the device handler is to perform; it is an input parameter to the subroutine (see Table E.2). The MODE argument is another input parameter that distinguishes between multiple device types supported by the same handler. The other arguments are used for both input and output, and their meaning depends on the value of the operation code. Not all arguments are used for every operation code. RBUF is a floating-point array used to pass numerical data to or from the device handler, and NBUF indicates how many elements of the array are used. CHR is a character variable used to pass character data to or from the device handler, and LCHR indicates how many characters are used. NBUF or LCHR should be set to zero if no data of the corresponding type are passed. If the function requested by the operation code (OPCODE) is not implemented in the device handler, the subroutine should set NBUF = -1 before returning.

The device handler subroutine can communicate with PGPLOT only through the arguments. It should not attempt to reference the PGPLOT common blocks (this is because the internal structure of the PGPLOT common blocks may change). Data stored internally by the handler between calls should be placed in static storage (use the Fortran SAVE statement).

Table E.2: Device Handler Operation Codes
Opcode Function
1 Return device type
2 Return maximum dimensions of view surface, and range of color index
3 Return device scale
4 Return device capabilities
5 Return default device/file name
6 Return default size of view surface
7 Return miscellaneous defaults
8 Select device
9 Open workstation
10 Close workstation
11 Begin picture
12 Draw line
13 Draw dot
14 End picture
15 Set color index
16 Flush buffer
17 Read cursor
18 Erase alpha screen
19 Set line style
20 Polygon fill
21 Set color representation
22 Set line width
23 Escape function
24 Rectangle fill
25 Set fill pattern
26 Line of pixels
27 Scaling information
28 Draw marker
29 Query color representation
30 Scroll rectangle

E.4 Handler state

PGPLOT will send commands to the device handler in a set sequence. Inquiry commands (opcodes 1--7 and 29) may be sent at any time, whether or not a device has been selected for output. The open workstation and close workstation commands are used to open and close a device. The begin picture and end picture commands are used to start and finish a ``frame'' (one page on a hardcopy device). Graphical output commands (opcodes 12--13, 16--20, and 22--28) are only used between begin picture and end picture. The set-color-representation command (opcode 21) can be used at any time that a device is open. Thus the sequence of commands for a plot consisting of two frames will be:
(query commands)
open workstation
    (query commands, set color rep)
    begin picture
        (graphical output commands)
    end picture
    (query commands, set color rep)
    begin picture
        (graphical output commands)
    end picture
close workstation
Any violation of this sequence is due to a bug in PGPLOT. Device handlers should attempt to trap all errors, including I/O errors (e.g., insufficient disk space or insufficient memory), and issue a warning message rather than terminating execution of the program.

E.5 Summary of operations


OPCODE = 1, Return device type

This is an inquiry function; the handler returns the name by which the the user will refer to the device type, e.g., 'PS' for a PostScript device handler. This name must be different for each mode of each device handler installed in PGPLOT, and should preferably be unique in the first two or three characters. A descriptive character string (displayed by routine PGLDEV) should be included in parentheses after the name, e.g., 'PS (PostScript file, landscape orientation)'.

Parameters returned by handler:


OPCODE = 2, Return maximum dimensions of view surface, and range of color index

This is an inquiry function; the handler returns the maximum dimensions of the plot surface, and the range of color indices available. These will usually be the same as the default dimensions, but if it is possible to make a larger image, the maximum dimensions may be larger. If there is no set upper limit to a dimension, the corresponding maximum should be set to -1. All dimensions are in device coordinates. All devices should support color indices 0 and 1; color and gray-scale devices will allow color indices >1 up to a device-dependent maximum value (which should not exceed 255). Color index 0 is the background color and is used to erase; if it is not possible to erase by overwriting in the background color, then requests to write in color index 0 should be ignored.

Parameters returned by handler:


OPCODE = 3, Return device scale

This is an inquiry function; the handler returns the device scale in device coordinate units per inch (1 inch = 25.4 mm). Usually, the units of the device coordinates are pixels, so this also gives the physical resolution in pixels per inch. For hardcopy devices, the values should be as accurate as possible, to ensure that an image has the correct scale. For video display terminals and other devices where the scale is variable, nominal values should be returned.

Parameters returned by handler:


OPCODE = 4, Return device capabilities

This is an inquiry function which is used to inform PGPLOT of the device's capabilities. If the device lacks a capability in hardware, PGPLOT will try to emulate it.

Parameters returned by handler:


OPCODE = 5, Return default device/file name

This is an inquiry routine. The device handler returns the device or file name to be used if the PGPLOT device specification does not include one. (On VMS, the default file name may also be used to fill in missing fields of the supplied file name, e.g., disk, directory, and file type.)

Parameters returned by handler:


OPCODE = 6, Return default size of view surface

This is an inquiry function; the handler returns the default dimensions of the plot surface in device coordinates. At present, PGPLOT assumes that the device coordinates of the bottom left corner are (0,0). Note: on some devices the default size can change during PGPLOT execution; e.g., on windowing workstations the window manager may allow the user to change the size of the PGPLOT window. PGPLOT uses this opcode to determine the current the default size before starting each new page.

Parameters returned by handler:


OPCODE = 7, Return miscellaneous defaults

This is an inquiry routine. The handler returns a scale-factor to be used for the ``obsolete character set'' used by old GRPCKG routines but not by PGPLOT.

Parameters returned by handler:


OPCODE = 8, Select device

A PGPLOT device handler may handle more than one open device at once. All graphical I/O operations apply to the ``active'' device. This opcode is used to select a new active device; note that opcode 9 (open workstation) also changes the active device.

Parameters passed to handler:


OPCODE = 9, Open workstation

Allocate an I/O channel to the requested device and open the device. Any hardware resets that need to be done once for a plot session (which could consist of several frames) should be done here. Allocate buffer, if its size is fixed for the device. No visible I/O should be performed on an interactive device: e.g., the screen should not be cleared; this should be deferred until the begin picture call.

Parameters passed to handler:

Parameters returned by handler:


OPCODE = 10, Close workstation

Close the device opened by the open workstation command, and deallocate any resources allocated for the device (e.g., memory, I/O channels).

OPCODE = 11, Begin picture

Prepare the workstation for plotting. This command has two arguments which specify a size for the view surface overriding the default size; if the device handler is unable to change the size of the view surface, it may ignore these arguments. On interactive devices, erase the screen. Note: this command has no way to return an error to the user; if an error occurs (e.g., insufficient memory for a frame buffer), the handler should issue an error message (with routine GRWARN) and ignore subsequent output commands, rather than terminating execution of the program.

Parameters passed to handler:


OPCODE = 12, Draw line

Draw a straight line from device coordinates (x1,y1) to (x2,y2) using the current line attributes (color index, line style, and line width). The coordinates are floating point, and may need to be rounded to the nearest integer before they are passed to the hardware; they are in the range (0,0) to the maxima specified with begin picture.

Parameters passed to handler:


OPCODE = 13, Draw dot

Draw a dot at device coordinates (x,y) using the current line attributes (color index and line width). The result should be an approximation to a filled circle of diameter equal to the line width, or a dot of minimum size if line width is 0. The coordinates are floating point, and may need to be rounded to the nearest integer before they are passed to the hardware.

Parameters passed to handler:


OPCODE = 14, End picture

Terminate the current frame. On hardcopy devices always advance the paper. On interactive devices, clear the screen only if requested. Deallocate buffers that were created by begin picture (OPCODE = 11).

Parameters passed to handler:


OPCODE = 15, Set color index

Set the color index for subsequent plotting. The default color index is 1.

Parameters passed to handler:


OPCODE = 16, Flush buffer

If the handler is buffering output to an interactive device, it should flush its buffers to ensure that the displayed image is up to date. Hardcopy devices can ignore this opcode.

OPCODE = 17, Read cursor

This function is not used if OPCODE = 4 indicates that the device has no cursor.

The handler should make the cursor visible at position (x,y), allow the user to move the cursor, and wait for a key stroke. It should then return the new cursor (x,y) position and the character (key stroke) typed. (If it is not possible to make the cursor visible at a particular position, the handler may ignore the requested (x,y) coordinates.) On a device with a mouse or similar device, clicking mouse-button 1 should return character `A', mouse-button 2 should return `D', and mouse-button 3 should return `X'.

If the hardware permits, the handler should interpret the ``mode'' as specified in the description of routine PGBAND. The exact appearance of the dynamic ``rubber band'' lines may be hardware specific; if possible, they should be drawn with the current color index, but they must not erase previously drawn graphics. Handlers that cannot draw the ``rubber band'' lines should treat all modes as mode = 0.

Parameters passed to handler:

Parameters returned by handler:


OPCODE = 18, Erase alpha screen

If the graphics device is a terminal that displays both graphics and text on the same screen, clear the text screen, leaving graphics unchanged. All other devices should ignore this opcode.

OPCODE = 19, Set line style

This opcode is not used if OPCODE = 4 indicates that the device does not support hardware dashing; PGPLOT will use software-generated dashed lines.

Parameters passed to handler:


OPCODE = 20, Polygon fill

This function is not used if OPCODE = 4 indicates that the device does not support hardware polygon fill. The polygon may be arbitrarily complex (concave or re-entrant); if the hardware cannot cope with this, the handler should set the OPCODE = 4 response to disable hardware fill. If hardware fill is enabled, the handler should respond to this function by filling the polygon with the current color index. To draw an N-sided polygon, PGPLOT uses this opcode N+1 times.

Parameters passed to handler on first call:

Parameters passed to handler on next N calls:


OPCODE = 21, Set color representation

Assign the specified (R,G,B) color, or the best available approximation, to the specified color index. If colors cannot be changed dynamically, ignore the request.

Parameters passed to handler:


OPCODE = 22, Set line width

This function is not used if OPCODE = 4 indicates that the device does not support hardware thick lines. Subsequent lines and dots should be drawn with the requested width, or the closest available approximation. The units of line-width are 0.005 inches. A requested line-width of zero should give the narrowest line available on the device (``hair line'').

Parameters passed to handler:


OPCODE = 23, Escape function

This function allows an arbitrary character string to be sent to the device handler. The interpretation is up to the handler; usually, the string will be sent directly to the device or ignored. Use of this function should be avoided.

Parameters passed to handler:


OPCODE = 24, Rectangle fill

This function is not used if OPCODE = 4 indicates that the device does not support hardware rectangle fill.

Parameters passed to handler:


OPCODE = 25, Set fill pattern

This function is not yet implemented.

OPCODE = 26, Line of pixels or Image

This operation is used for gray-scale and color imaging (e.g., routine PGGRAY). It is used in two different ways, depending whether OPCODE=4 reports CHR(7:7) = 'P' or 'Q'.

Case P

This function is used to write a horizontal line of pixels on the device screen with specified color indices; it should be more efficient to do this with one device handler call rather than separate calls for each pixel. If the device handler implements this operation, it is important that the device coordinates should be true pixel numbers.

Parameters passed to handler:

Case Q

This case is used for devices like PostScript where PGPLOT cannot address individual device pixels; the handler, or the device, must map the image array onto hardware pixels, taking care of clipping. In this case, the first call specifies the parameters of the image, and subsequent calls pass color indices of image pixels, and a final call indicates the end of the image.

Parameters passed to handler on first call:

Parameters passed to handler on first call:

Parameters passed to handler on last call:


OPCODE = 27, Scaling information

This function is only used if OPCODE = 4 indicates a cursor of type X. It is used to tell the device handler what the user's (world) coordinate system is. The handler may ignore the information, or it may use it to generate a read-out of the cursor position in the world coordinate system.

Parameters passed to handler:


OPCODE = 28, Draw marker

This function is only used if OPCODE = 4 indicates that the device handler can draw graph markers. If it is to be used, the device handler (or hardware) must know how to draw each of the markers numbered 0 to 31 (see Figure 4.1).

Parameters passed to handler:


OPCODE = 29, Query color representation

This function ay be called at any time after open workstation (9) and before close workstation (10). It will not be called if the handler does not report itself as having this capability. The handler should attempt to return the actual color representation in use on the device, if it is possible that this is different from the values requested. Otherwise it should return the values requested in the last call with opcode 21 (set color representation) for this color index. (Re-calling opcode 21 with the values returned by opcode 29 should not change the actual color representation!) If the handler does not have this capability, PGQCR will return R=G=B=0.0 for color index 0 and R=G=B=1.0 for all other color indices.

Parameters passed to handler:

Parameters returned by handler:


OPCODE = 30, Scroll rectangle

This function is not used if OPCODE = 4 indicates that the device does not support scrolling. If it is to be used, then the device handler should be capable of scrolling a rectangular region of the display-surface, both horizontally and vertically, by an integral number of device coordinates. A horizontal scroll of positive dx device pixels is defined to mean that all but the rightmost dx pixels of the rectangle should be copied dx pixels to the right of their original positions. The vacated dx pixels at the left edge of the rectangle are to be filled with the background color. Vertical scrolling is defined similarly.

Parameters passed to handler:

All of these parameters are intended to be integral, and should be rounded to the nearest integer. Note that RBUF(5) and RBUF(6) are allowed to exceed the lengths of the corresponding sides of the scrolling region. In such cases the region should be completely filled with the background color.


Next: Appendix F
PGPLOT
Tim Pearson, California Institute of Technology, tjp·astro.caltech.edu
Copyright © 1995-1996 California Institute of Technology