GREX

Adaption of an old plot package by MicroWay to Unix using PGPLOT

This document has been updated at the instance when the installation at Holt (ubuntu) is migrated to Elder (cygwin)
November 2012.

This is the README file grex_readme.html

Contents:

Manuals:



 

The directory pgplot/4mw contains a minimum of interface routines, allowing
fortran programs to call a few XWindows screen graphics functions as if it
were MicroWay's. The pgplot-package is used as the graphics kernel.
Some functions are still not implemented (1995-NOV-30 (2002-07-10)).
 

PGPLOT library changes

The PGPLOT library needs a few changes and additions. We take version 5.2.2. to start from. The affected subroutines show traces of update signed by HGS:
On Holt,
$ cd ~/pgplot5.2.2/pgplot
$ locate '*.f' +i HGS

On Holt, the most recent xwdriver is named  xwdriv.c ; other versions, including the original, carry info in the file name.

drivers-hgs/:
    xwdriv.c
src-hgs/:
    grcurs.f
    grrec0.f
    pgband.f
    pgend.f
    pgpap.f

Save the originals in src-ori/ and move the  src-hgs/  and  drivers-hgs/  files into  src/ and  drivers/ , respectively,

$ cd src
$ mv grcurs.f grrec0.f pgband.f pgend.f pgpap.f ../src-ori
$ cd ../src-hgs
$ mv
grcurs.f grrec0.f pgband.f pgend.f pgpap.f ../src
and, mutatis mutandis, for drivers (xwdriv.c the only file)

Go through the usual make procedure. For CYGWIN, use

$ cd /usr/local/pgplot
# select driver in drivers.list
$ makemake ~/pgplot5.2.2/pgplot linux g77_gcc
$ make

and note the gcc compiler flags so you can compile xwdriv.c (sub) and pgxwin_server.c (main).
Examples from running make on Elder:

g77 -c -u -Wall -fPIC -O /home/HGS/pgplot522/pgplot/src/pgscir.f
gcc -c -Wall -fPIC -DPG_PPU -O -I. /home/HGS/pgplot522/pgplot/sys/grfileio.c
gcc -c -Wall -fPIC -DPG_PPU -O -I. -I/usr/X11R6/include /home/HGS/pgplot522/pgplot/drivers/xwdriv.c

                               -/-/-/-/\-\-\-\-

The remainder of this document deals with Microway's grex library.

Different keyboards:

In keydefs.f I have started to lay down codes that reassign keycodes.
Basically you want to be able to accept a user's press on the e.g.
*-key on the numeric keypad (code -86), but if a users types on an
HP Unix workstation, this key will send the ascii code 42.
Basically, what you have to do is

$ setenv PGPLOT_KEYBOARD LINUX+N  # alt     export PGPLOT_KEYBOARD=LINUX+N
$ setenv PGPLOT_KEYBOARD PC101+N  #  "      export PGPLOT_KEYBOARD=PC101+N

where the +N signifies that you have a numerical keypad and you are
going to use it. If your keypad maps the special keys
( . + - * / Enter ) on the numerical keycodes to ordinary codes, issue
the environment settings with -N instead of +N.

If you start programming using ier=pause(), do the following:

      include '/usr/local/pgplot/keys.fh'
      incluc\de '/usr/local/pgplot/grex.fh'

      key=pause()
      if (key.eq.kbc_Ins) then
       ...
      elseif (key.eq.kbc_Del) then
       ...
      elseif (key.eq.kbn_Del) then
       ...
       ...
      endif

Have a look at  keydefs.f  to see the names.

Consider the two /-keys that you have, one on your standard keyboard and the other on the numeric keypad.
Let's call them S-/ and N-/, respectively. The functionality what is done after pressing one of the other key must lie in your application. You might allow the N-/ key, so that your program would read

      include '/usr/local/pgplot/keys.fh'
      ...
      ier=pause()
      if (ier.eq.ichar('/').or.ier.eq.kbn_Slash) then
         call slash_function ()
      ...
If a user doesn't have a numeric keypad he/she can still press the S-/ key. It's worse if you want to discriminate between S-/ and N-/
That functionality will not be attained except on a narrow range of keyboards, other communication problems not withstanding.

Thus, the keydefs.f duties are to recognize the codes that different keyboards generate and map them to the labels printed on the top face of the keys. Mnemonics in keys.fh should help to code up subroutines in a convenient way.

On the HP-unix workstation keyboard the Ins and Del keys don't generate sensible codes.  Maybe spending more time to understand all implications of the KeySym construct in pgplot/drivers/xwdriv.c would help solve the problem. But I have found four rarely used keys, namely Shift-F9 to Shift-F12, two of which can be used to substitute for Ins and Del.
 

Monitor key presses:

   To toggle monitor mode:
      on the Linux-PC keyboard, press PrintScrn,
      on the HP-Unix press Shift-F11
   These functions have been built into  graphic_pause (grex.f)
   and the pgplot/drivers/xwdriv.c
   The system will print on the stdout the keysym and key codes,
   the location of the mouse pointer at the moment when the key
   was pressed,
   and what pause makes of the key codes.

                               -/-/-/-/\-\-\-\-

Known problems with use of pgplot at the graphic screen system

The screen communication is slow, particularly when drawing characters.
Therefore, response times are frustratingly long when text is to be entered
at graphic prompters. The entering of words cannot be described as being
fluent.

The scope of inkey$ is much shorter than on the PC. The user has to have
an idea where in the program the poll is issued in order to be prepared
and press a key or button. ~/Oload/p/gra/otes18.f contains an example:
The sensitive phase is entered after the drawing is complete. Pressing
the P key (ASCII 80) while the system finishes the plot will recall the
GO-mode (qgor=.false.)

Known problems with Fortran portability:

grex.f   The call to boolean function IXOR might need adjustment.
 Intended: Exclusive-Or function of two integer*4 variables,
 result integer*4. On some systems the function is termed
             IEOR (=generic name), XOR (=generic name), 
             JIEOR (=specific name).
all programs There appears to be a problem with calling routines with constants 0 .. 15 as ther parameters. Under consideration

Musing along on inkey$:

(only ideas so far)

   $ inkey_main PID
will start a little graphic window with a copy mechanism between the
keyboard (using key_pause_s18) and a file /tmp/hgsPID.ink
All inkey$ has to do in the future is open the file that corresponds
to the PID of its main, read and delete the record. There is a slight
chance of collision though. And we have to reserve a unit number.
And the open/close activities may slow down the system too heavily.

      integer function inkey$()
      integer getpid
      data ipid/-1/, fn/'/tmp/hgs######.ink'/, iun/98/
      character fn*32

      include 'cmwg.fc'
      integer graphic_pause, grcurs_pmode

      inkey$=0
      if (imode.lt.18) return

      if (iun.lt.0) then
c old code from     ier=grcurs_pmode(1)  ...

      else
         if (ipid.lt.0) then
            ipid=getpid()
            i=index  (fn,'#')
            j=index_l(fn,'#')
            write (fn(i:j),'(i6.6)') ipid
         endif
         key=0
         open (unit=iun,file=fn,err=99)
         read (iun,'(i5)',end=99) key
         close (iun)
 99      inkey$=key
      endif
      return

      entry inkey_fun (iv)
      if (iv.ge.0.and.iv.le.99) iun=iv
      inkey_fun=iun
      return
      end
 

Writing to other devices than /XWINDOW:

Unless prompting routines are called, a set of device drivers can
be chosen aprt from /XWINDOW. The device is opened in graphics_mode
(called by e.g. set_video_mode(18)) using the contents of the
  environment variable
  PGPLOT_DEVICE
If this variable is undeclared, /XWINDOW is the default. Regularly,
the other device will be a file, written by one of the available (i.e.
actually installed) driver subroutines. The user must expressly send
the file to the device.
 

Files in ./pgplot/4mw

-rw-rw-r--    1 hgs      users         703 Jun 22  1999 addgrex.f
-rw-rw-r--    1 hgs      users         491 Jun 22  1999 bmwg.f
-rw-rw-r--    1 hgs      users         490 Jun 17  1997 cmwg.fc
-rw-rw-r--    1 hgs      users        1290 Jan 29  1998 fcmd
-rwxrw-r--    1 hgs      users         146 Jun  8 13:48 fcs
-rw-rw-r--    1 hgs      users         200 Jun 18  1997 fcs-all
-rw-rw-r--    1 hgs      users       24981 Jul  9 17:25 grex.f
-rw-rw-r--    1 hgs      users        2907 Oct 19  1998 grex.fh
-rw-rw-r--    1 hgs      users       15960 Jul  9 19:17 grex.readme
-rw-rw-r--    1 hgs      users     1032181 Jan 29  1998 inkey-main
-rw-rw-r--    1 hgs      users         913 Jan 29  1998 inkey-main.f
-rw-rw-r--    1 hgs      users        3713 Jul  9 18:12 keydefs.f
-rw-rw-r--    1 hgs      users        1682 Jul  9 17:47 keys.fh
-rw-rw-r--    1 hgs      users       41276 Jul  9 18:53 libgrex.a
-rw-rw-r--    1 hgs      users        6808 Jul  9 18:53 libnogrex.a
-rw-rw-r--    1 hgs      users        2234 Jun  8 14:04 libnotexx.a
-rw-rw-r--    1 hgs      users        1987 Oct 27  1999 nogrex.f
-rw-rw-r--    1 hgs      users         871 Jun 22  1999 notexx.f
-rw-rw-r--    1 hgs      users         745 Jul  9 18:52 pause.f
-rw-rw-r--    1 hgs      users       29792 Nov 19  1996 scrchars.dat
-rw-rw-r--    1 hgs      users        1362 Jun 16 19:31 setmode.f
-rw-rw-r--    1 hgs      users        1483 Jun 22  1999 timer.f

addgrex.f    - subroutines colored_rectangle, open_rectangle.

bmwg.f       - block data common /cmwg/
cmwg.fc      - common /cmwg/ to hold screen type definitions.
...............The associated block data is in grex.f.

fcmd         - make main program (Fortran compile and link)

fcs          - shell script to compile and archive.
...............Usage:
                            setenv F77OPT "-fno-backslash -fdollar-ok"
                            fcs grex grex
                            fcs addgrex grex
                            fcs keydefs grex
                            fcs pause grex
                            fcs setmode grex
                            fcs timer grex
                            fcs bmwg grex
                            fcs nogrex nogrex
                            fcs pause nogrex
                            fcs bmwg nogrex
                            fcs notexx notexx

fcs-all      - shell script containing the above fcs commands

grex.f       - interface graphic function subroutines.

grex.fh      - type declarations of function subroutines in grex.f.
...............Useful INCLUDE '/usr/local/pgplot/grex.fh'.

keydefs.f    - block data keyboard codes.
...............Keyboard switching routines (02-07-09)

keys.fh      - common /keyboard_codes/ to signify codes with mnemonic names.

libgrex.a    - the library.
libnogrex.a  - the library with elimination routines nogrex.o bmwg.o pause.o
libnotexx.a  - the library with the curses elimination routine notexx.o

nogrex.f     - nongraphical (dummy) set_video_mode get_video_mode get_device_
...............limits graphics_mode and graphics_pause

notexx.f     - noncurses text_pause text_mode is_text_mode

pause.f      - interface to switch between graphical / textual
...............pause routines.

scrchars.dat - data file with MicroWay style screen characters

setmode.f    - graphical routines  set_video_mode get_video_mode
...............get_device_limits

timer.f      - interface nongraphic functions.

Your system might require additional adaption in order to obtain the correct keyboard scanning.

Function pause() in graphics mode returns key codes (mouse buttons and keyboard).
I have tried to keep the following groups of keys together:


In grex.f, function pause, in an if-clause after
      CALL PGCURS(x,y,ch)
      ic=PGQKCD(icd)
      ich=ichar(ch)
these key groups are created. The scheme might have to be changed.

User's programs can make use of keydefs.f and keys.fh.

      include '/usr/local/pgplot/keys.fh'
      integer pause,set_video_mode
      ier=set_video_mode(18)
      key=pause()
      if (key.eq.kbc_LArrow) then
         ip=ip-1
      elseif (key.eq.kbc_F(1)) then
         call xyz
etc.

The assignment might have to be changed in order to obtain correspondence with the key codes returned by pause. Then, block data program keydefs.f must be updated.

To enter monitor mode for the retrieved keycodes, one can either call the integer function
      ier = monitor_graphic_pause (q_true_false)
or use a toggle function built into graphic_pause:


A little main program that will print the key codes will be useful.
(1) An engineering version of grex.f contains a print statement after
      CALL PGCURS(x,y,ch)
      ic=PGQKCD(icd)
      ich=ichar(ch)
      print '(2a,3i10)',' <GrPaus>>> char, icd, ic, ich = ',ch, icd, ic, ich
    to display the values  ch, icd, ich. (ic is a 2byte unsigned representation of icd.)
    The pause() -> graphic_pause() function provides this under the condition qmon=.true.

(2) A little test program:
    /home/hgs/util/p/chpal.f          - subroutine
    /home/hgs/util/p/mc/chpalt.f      - main
       start the program and choose  T (Return) at the graphic prompter.  The system will report the
       conversion between keyboard strokes and the character code returned by pause().

(3)
      PROGRAM TKB
      integer set_video_mode, pause
      ier=set_video_mode (18)
      ier=monitor_graphic_pause(.true.)
c                                \_____set qmon = .true.
 1    ier=pause()
      print *,ier
      if (ier.ne.19) goto 1             ! ^S will terminate TKB
      stop
      end

(3a) Link TKB using

setenv F77OPT "-fno-backslash -fdollar-ok"
setenv F77MOPT "-fno-backslash -fdollar-ok"

cd /pgplot/4mw
./fcmd TKB.f
 

#!/bin/sh
## Usage:      fcmd [-m] program-name[.o]
##
## Purpose:    Compile and link a Fortran MAIN program by fort77 driver.
##             A poor man's make.
##
## Parameter:  program-name not ending with .f or .o will be completed with .f
##             For link-only: specify  program-name.o
##
## Options:    -m   - link map will be produced: program-name.map
##                    and a compiler list: program-name.l
##
## Edit fcmd:  libraries             $LIBS
##             compiler options      $FORT77O
##             installation path     $BINP
##             outfile extension     $FNOX
##
## Environment:  $F77MOPT  -  more compile options
##
if [ x$1 = x-h ]; then
   grep -e '^##' $0 | awk '{print substr($0,4,999)}'
   exit
fi
LDMAP=
if [ x$1 = x-m ]; then
   LDMAP=-m
   shift
fi

LIBS="-a archive \
   -L/home/hgs/util -ltexx -lcurse -lutil      \
   -L/usr/local/pgplot -lpgplot -lgrex  -lpgplot \
   -L/home/hgs/util -ltexx -lcurse -lutil      \
   -L/usr/lib/X11R5    -lX11                     \
   -L/home/hgs/util   -lcurses       \
   -L/opt/fortran/lib -lU77                 \
   -L/usr/lib -lcl -a shared -lisamstub -lc "

FORT77O="+E6 +E1 +U77"

BINP=.

FNOX=

export FORT77O BINP LIBS FNOX LDMAP
#
# That's it for definitions, folks.
#
 

GREX MANUAL

           subroutine grex (m,n)
c grex.f comments
c
c This set is supposed to mock up MicroWay grex calls. The grex entry
c is rarely used. The entries under grex are internally used (after
c selecting a graphics mode).
c
c The description below is quite brief.
c
c The MicroWay text modes are less well mocked up using the curses library
c (keyword texx, c.f. routines in ~/util/c ~/util/libtexx.a and ./notexx.f)
c
c Additional routines are in ./addgrex.f ./setmode.f ./timer.f  and ./pause.f
c Elimination routines are in notexx.f and nogrex.f
c
c In the subroutines below there are some additional entries:
c They should be called before the graphics mode is switched on.
c
c Mode 18 seems to work o.k. The other modes are sort of prepared but untested.
c
c..............................   ..P/S means a parameter-setting routine
c                                       that must be called before
c                                       set_video_mode / graphics_mode
c
c ier=graphics_mode (mode)              The work horse used by set_video_mode.
c                                       Will set up the screen mode.
c                                       See graphics_mode for detailed documentation
c
c ier=prepare_grey (qq).......... ..P/S qq=.true. Will create greys under
c                                       define_color.
c
c ier=use_mwchars (qq)........... ..P/S qq=.true. Will use ported MicroWay
c                                       graphic character set instead of pgplot.
c
c ier=prepare_mwchars(iun,filename) P/S can be used to redefine file unit [8]
c                                       and file name
c                                          ['/usr/local/pgplot/scrchars.dat']
c
c ier=define_xwindow_size (imode,nx,ny,q_keep_resolution)
c ..................................P/S q_keep_resolution=.false. will scale
c                                       the plot plain to the window,
c                                       q_keep_resolution=.true. will clip
c                                       the bounds (viewport effect).
c
c ier=shut_graphics (qq)............P/S to remove graphic window after
c                                       switching modes.
c                                       Implies a request CALL PGASK(.false.)
c                                       To reinstate prompting before opening
c                                       a new window, ier=ask_graphics(.true.)
c
c ier=ask_graphics (qq).............P/S take away or reinstate the PGPLOT
c                                       prompter that appears before a
c                                       graphic window is destroyed.
c
c ier=graphic_pause ()                  will be called from ier=pause()
c                                       if libgrex.a libnotexx.a are linked in.
c                                       Instead, if libnogrex.a libcurse.a
c                                       libcurses.sl libtexx.a are linked in,
c                                       text_pause() will be called.
c
c ier=monitor_graphics_pause (qq)       Initiates monitoring of key codes
c                                       as they are pressed under
c                                       graphic_pause.
c
c
c The following two entries deal with
c PGPLOT characters.
c ------------------
c ier=define_text_font (ifont)          1,2,3,4, default=2 (roman)
c
c rer=define_text_height (real_height)  to adjust PGPLOT's text height.
c                                       PGPLOT has a tendency to generate
c                                       sparse looking text.
c
c
c New graphics:
c -------------
c ier=define_color (ic,iv)              ic=0..16, iv=0..63 assigns a palette of 16 colours
c                                       from a color range of 64 different nuances according
c                                       pc-screen mode 18
c
c set_regrex (q)                        q=true: last in define_color, refresh the screen
c                                       from the grex internal pixmap copy.
c                                       Refresh is slow; save time by deffering the update
c                                       to the last define_color in a loop.
c                                       (This was unneccessary on the HP-UX workstation;
c                                       on LINUX, the screen would only be refreshed in the
c                                       area that was drawn last. Maybe there is an XW-command
c                                       or option. Set_regrex is a temporary workaround).
c
c ier=define_f_color (ic,iv)            is an alternative to define_color.
c                                       Since define_color works o.k. for
c                                       screen mode 18 this routine could
c                                       host the model for higher modes.
c
c ier=adjust_hue (ic,iv)
c
c          ic > 3   iv=0,...,iccap:    reset the hue of that color;
c                                      next call to define_color will make normal color.
c          ic > 3   iv<0 or iv>iccap:  reset the hue of all colors.
c
c          ic < 1   change luminosity, iv < 0  darker, iv > 0 more pale.
c
c          ic = 1   change red, iv < 0 less red, iv > 0 more red,
c          ic = 2,3 same in green, blue
c
c
c ier=pause_for_text (qq)               .true.:  The cursor will be viewed
c                                                off the nominal position.
c                                       .false.: The curser will be viewed
c                                                at the nominal position.
c
c ier=last_cursor_loc (i,j)             After a mouse click, this entry
c                                       will return the mouse position.
c                                       Thus,
c
c                          include '/usr/local/pgplot/keys.fh'
c                          include '/usr/local/pgplot/grex.fh'
c                          ...
c                          ier=pause()
c                          if (ier.eq.mouse_left) ler=last_cursor_loc(i,j)
c
c                                       will work well together.
c
c ier=open_rectangle (ix,iy,ix,iy,ixe,iye,ithick)   (./addgrex.f)
c
c ier=colored_rectangle (ix,iy,ixe,iye,icol)        (./addgrex.f)
c
c ier=graphic_scrtext (text,i,j,k,iorient) like graphic_text. New parameter
c                                       iorient = 0  horizontal text
c                                                 1  vertical text
c                                       This procedure is supposed to work
c                                       with magnify_text in the MicroWay way.
c                                       The procedure is by-passed unless
c                                          ier=use_mwchars (.true.)
c                                       The first time it is called it reads
c                 Obs! file unit 8      character data from unit 8, file
c                                       /usr/local/pgplot/scrchars.dat
c
c
c see ~/Oload/p/mpp/fcm for a good set of grex library references.
c see ~/Ttide/p/m/fcm for a good set of grex library eliminations.
c
c There are block data and .fh files to assist in coding keyboard
c polling statements: keydefs.f and keys.fh
c
c A set of type declarations are in grex.fh
c
c The screen mode definitions are in bmwg.f (block data)
c
c graphics_mode (mode)
c    mode is a screen mode, of which 18 is the smallest graphic mode.
c    The idea is that capabilites are set at typical values in each mode
c    (number of pixels in X and Y, number of different colours, range of
c    palette). There ought to be a free mode slot which a user can set up
c    freely (on a PC your choices were limited to the modes defined by the
c    factory of your video card, and not all of them were defined in a
c    unique way). This feature is still missing.
c
c    Anyway.
c    When graphics_mode executes, it will set up the font, the drawing area,
c    the decoding parameters for the keyboard, the plot device, and the
c    basic colouring scheme.
c    The keyboard and the plot device must be given through the environment:
c
c    setenv PGPLOT_DEVICE device         The device must be from the list of
c                                        enabled PGPLOT drivers. See
c                                $ grep -v '^\!' /usr/local/pgplot/drivers.list
c                                           Default = /XWINDOW
c
c    setenv PGPLOT_KEYBOARD keyboard[opt]Legal keyboard choices are
c                                              PC101
c                                              LINUX
c                                           (...more to be considered?)
c                                           Else HP-workstation
c                                           Options:
c                                              +N - Numeric Keypad generates
c                                                   special numbers and codes
c                                              -N - Numeric keypad generates
c                                                   special numbers but normal
c                                                   codes
c                                           (...more to be considered:
c                                            Numeric keypad generates standard
c                                            ASCII codes at the number keys?)
c
c

Table 1. You may change the defaults using define_xwindow_size (mode,ixm,jxm,qkeep_resolution) before graphics_mode
How lwb and lnb control color allocation is best seen in the code, integer function define_f_color.
Obs! modes 19-23 haven't yet been verified.
                          mode
Variable        purpose
18
19
20
21
22
23
24
lxm lym           Window size

640x480
320x240
640x480
640x480 720x560 960x720
1024x768
 lwb   
      iand(j,lwb-1) sets color
4
64
64
64
4
4
4
 lnb
     another boolean for colour

2
6
6
6
6
6
2
lccap  nr.of colors on palette

16
64
64
64
64
64
16

 

SETMODE MANUAL


      integer function set_video_mode (mode)
c setmode.f comments
c
c ier=set_video_mode (mode)         switch to the indicated mode;
c                                   call graphics_mode if mode > 17
c                                   call text_mode if mode < 18
c
c ier=get_video_mode ()             returns the current active mode
c
c ier=get_device_limits (i,j,k)     returns the current mode through the calling name
c                                   and through the calling list the following parameters
c                                   i - width of screen in pixles
c                                   j - height of screen in pixels
c                                   k - number of palette entries
c
c
 

KEYDEFS MANUAL

      subroutine xxx_keyboard ()
c keydefs.f comments
c You are invited to help extend this routine. In grex.f you will have to add calls to the
c new subroutines. Look at the source code.
 

c
c
c
c