XDL_VIEW - VOLUME 2
===================

Version: 4.0

John W. Campbell, CCLRC Daresbury Laboratory


CONTENTS
--------



CHAPTER 1: USING XDL_VIEW IN APPLICATION SOFTWARE 

1.1  INTRODUCTION
1.2  The Basic Structure of an Applications Program
1.3  Laying Out View-Objects
1.4  Application Program Example
1.5  Some Other Considerations


CHAPTER 2: THE DESIGN OF XDL_VIEW 

2.1  INTRODUCTION
2.2  The View-Objects List
2.3  'C' Structures Associated with the View-Objects List
2.4  Routines for Managing the View-Objects List
2.5  The Initialisation Routine
2.6  Event Handling
2.7  The Fortran to 'C' Interface
2.8  Fonts


CHAPTER 3: CREATING NEW VIEW-OBJECTS 

3.1  INTRODUCTION
3.2  Writing Code for a New View-Object
3.3  General Layout of the Code
3.4  The View-object Template File
3.5  View-objects without an Active Strip
3.6  View-objects with Keyboard Input
3.7  Layout Considerations
3.8  Library Window Routines


CHAPTER 4: REPAINT, EVENT-HANDLING, ON-OFF & TIDY-UP ROUTINE CALLS 

4.1  INTRODUCTION
4.2  Repaint/Event-Handling Routine Calls
4.3  On-Off Routine Calls
4.4  Tidy-Up Routine Calls


CHAPTER 5: STANDARD LAYOUT PARAMETERS 

5.1  INTRODUCTION


CHAPTER 6: VIEW-OBJECT UNIQUE NUMBER IDENTIFIERS 

6.1  INTRODUCTION


CHAPTER 7: INSTALLATION NOTES 

7.1  INTRODUCTION


CHAPTER 1: USING XDL_VIEW IN APPLICATION SOFTWARE  
==================================================


1.1 INTRODUCTION
 
This section gives some details of the  basic  design  philosophy  used  in
preparing the XDL_VIEW  software  which  needs  to  be  understood  if  the
application programmer is to use the view-objects  effectively.  The  basic
requirements  for  the  development  of  the  software  have  already  been
described in volume 1 of the User Documentation for XDL_VIEW.
 
The XDL_VIEW software falls into two main categories:
 
1) A set of routines for managing a set of view-objects.
 
2)  The software for the individual view-objects,  some  of  which  are  of
    general use (menu area, parameter table etc.) and  some  of  which  are
    more application specific (e.g. the film image view-object).
 
 
The management software is required partly for convenience and partly as  a
consequence of requiring a Fortran interface to the  view-object  routines.
The XLIB library routines interface provided is C based and makes extensive
use of structures, and a variety of data types which do not  map  naturally
on to Fortran 77. Because of the Fortran requirement, it was  decided  that
the view-objects should be identified  indirectly  through  a  'view-object
handle' which is a unique integer, selected by the application  programmer,
for each view-object  created  within  an  application.  (cf  Fortran  file
logical unit numbers). One of the main functions of the management routines
is to maintain a table relating  the  view-object  handles  to  the  actual
view-objects and  their  associated  data.  The  management  routines  also
provide an initialisation routine and a routine for polling  for  input  to
the application from selected view-objects.
 
List of sections:
 
   The Basic Structure of an Applications Program
   Laying Out View-Objects
   Application Program Example
   Some Other Considerations
 
1.2 THE BASIC STRUCTURE OF AN APPLICATIONS PROGRAM
 
The basic structure  for  a  program  using  XDL_VIEW  view-objects  is  as
follows:
 
1)  Call the XDL_VIEW initialisation routine. This mustbe called  and  must
    be the first call to an XDL_VIEW routine.
 
    (xdl_open_view for C or xdlf_open_view for Fortran)
 
2) Create view-objects using calls to the appropriate routines
 
    (e.g. xdl_menu_area (xdlf_menu_area) for a menu area etc.)
 
3)  Set up a list of the view-object  handles  for  the  view-objects  from
    which the program is prepared to accept input.
 
4) Poll for input from the listed view-objects
 
    (call xdl_get_events in C or xdlf_get_events in Fortran)
 
5) Service the returned input.
 
    The polling routine returns the view-object handle of  the  view-object
    for which the input was made. Specific  routines  are  then  called  to
    access     the     input     data      (e.g.      xdl_menu_area_getitem
    (xdlf_menu_area_getitem) to determine the item selected  from  a  menu)
    and the approriate action is taken by the program.
 
 
The procedure then followed will depend on the nature of the  program.  For
example the program may return to step 4 to repeat  the  polling  from  the
same view-objects or go back to step 3 to change the list  of  view-objects
from  which  input  can  be  accepted  before  next  polling   for   input.
Alternatively, when required, the user may create new view-objects  (and/or
delete unwanted ones) and then have a new  polling  loop.  A  program  will
normally have at least one polling loop  and  more  complex  programs  will
often have several.
 
The way in which colour is handled by the XDL_VIEW routines also needs some
explanation. The routines were developed initially for  workstations  which
have 8 bit pseudocolor available. Because of the nature of the handling  of
colour in X-windows, it was decided that an application should specify  its
colour requirements at the start. This is particularly important if a large
number of colorcells or colorcells with overlay  planes  are  required.  It
enables the allocation of read-write  cells  in  the  default  colormap  if
available or the allocation of a new  virtual  colormap  if  required.  The
allocation  of  the  colour  requirements  at  the  start  means  that  the
individual view-object routines need not be concerned about  the  colorcell
availablity at the time that they are actually invoked thus simplifying one
aspect of their coding. It also means  that,  provided  no  more  than  256
colorcells are  used,  a  single  colormap  will  be  used  for  the  whole
application. The application's colour requirements are specified  when  the
XDL_VIEW intitialisation routine is called. The routines should however  be
able to run on other colour displays (in particular true or  direct  colour
displays) and should provide some sort of monochrome option.
 
The handling of the Fortran/C interface, which may be of interest  to  some
application programmers, is described in chapter 2.
 
 
1.3 LAYING OUT VIEW-OBJECTS
 
The xdl_view view-objects have routines which will return the required size
of the window given the various program specific  parameters  which  affect
it. Given these values, it is possible to work out  a  layout  manually  or
write a routine to work out a layout for a particular program. For  even  a
moderately complicated layout, this may be quite tedious and so  a  set  of
routines, the 'xdl_view layout routines' have been written to  assist  with
this task. using these routines, the  basic  look  of  the  layout  may  be
preserved and new positions and sizes automatically calculated if the  size
requirements of any of  the  individual  objects  are  changed.  The  basic
procedure requires that the layout is analysed so that it can be defined in
terms of pairs of objects  and/or  previously  defined  pairs.  Each  newly
defined pair may be in a horizontal or  vertical  direction.  Minimum  size
requirements are given for the individual objects and recursive  procedures
are used to calculate the overall size requirement for the  layout  and  to
reset the sizes and positions of the individual objects. There is  also  an
option to include a table (regular rows and columns of single  objects)  as
an item of a pair.
 
 
1.4 APPLICATION PROGRAM EXAMPLE
 
This section shows how to write a simple  program  to  perform  a  selected
transformation on a set of data read from a file and write out  a  file  of
the transformed data. The program creates a base frame on which a menu area
and an I/O window are positioned. The menu has the following  items  and  a
quit button:
 
 * Read Data File
 
 * Perform Transformation A
 
 * Perform Transformation B
 
 * Write Data File
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
    Figure 1.1 Display from the Example Program
 
Versions of the program in both 'C' and Fortran are given below:
 
Programxdl_example.c
 
void rd_data(), wr_data(), trans_a(), trans_b();
main()
{
   float a[1000];            /* Data array */
   int ncolors[2];           /* Array for numbers of colours */
   int nplanes[2];           /* Array for numbers of overlay planes */
   int vhlist[2];            /* View-objects list for events input */
   int item;                 /* Returned menu item number */
   int quit;                 /* Returned menu quit option selected flag */
   int vh;                   /* Returned view-object handle from events
                                loop*/
   char filnam[101];         /* String to hold file name */
   static char *names[] =
   {"Read Data File",
    "Perform Transformation A",
    "Perform Transformation B",
    "Write Data File"
   };

   /* Initialise (only default short colour map needed)*/
   xdl_open_view (0, ncolors, nplanes);

   /* Set up base frame */
   xdl_base_frame (1, 530, 420, "Example", 0, "Examp", 0, -1, -1);

   /* Set up menu area and i/o window */
   xdl_menu_area (2, 1, 10, 10, 0, 6, 25, 2, 1, 25, 250, 400);
   xdl_io_window (3, 1, 270, 10, 0, 0, 0, 250, 400, 2, 100);

   /* Set menu details */
   xdl_menu_area_setmenu (2, 4, names, 0, "Options", 0, "Quit", 0, 2);

   /* Menu servicing loop */
   next:
   vhlist[0] = 2;
   vh = xdl_get_events (1, vhlist);
   if (vh==2)
   {
      xdl_menu_area_getitem (2, &item, &quit);
      if (quit==1) exit(1);
      switch (item)
      {
         case 1:
            /* Get file name and read data file */
            xdl_io_window_print (3, "Input file name: ", 0);
            vhlist[0] = 3;
            vh = xdl_get_events (1, vhlist);
            xdl_io_window_getstring (3, filnam, 100);
            rd_data (filnam, a);
            break;
         case 2:
            /* Transformation A on data */
            trans_a (a);
            break;
         case 3:
            /* Transformation B on data */
            trans_b (a);
            break;
         case 4:
            /* Get file name and write data file */
            xdl_io_window_print (3, "Output file name: ", 0);
            vhlist[0] = 3;
            vh = xdl_get_events (1, vhlist);
            xdl_io_window_getstring (3, filnam, 100);
            wr_data (filnam, a);
            break;
      }
   }
   goto next;
}

/* Dummy data processing routines */
void rd_data (filnam, a) char *filnam; float a;
{ printf ("\nOpen file %s and read data into 'a'", filnam); return;}
void wr_data (filnam, a) char *filnam; float a;
{ printf ("\nOpen file %s and write data from 'a'", filnam); return;}
void trans_a (a) float a; {printf ("\nTransformation A"); return;}
void trans_b (a) float a; {printf ("\nTransformation B"); return;}
 
Program xdl_example.for
 
      REAL A(1000)
      INTEGER XDLSTR
      INTEGER NCOLRS(2), NPLANS(2), IVHLIS(2)
      INTEGER ITEM, IQUIT, IVH, IERR
      CHARACTER*100 FILNAM
      CHARACTER*25 NAMES(4)
      DATA NAMES /'Read Data File',
     *            'Perform Transformation A',
     *            'Perform Transformation B',
     *            'Write Data File'/

C====== Initialise (only default short colour map needed)
      CALL XDLF_OPEN_VIEW (0, NCOLRS, NPLANS, IERR)

C====== Set up base frame
      CALL XDLF_BASE_FRAME (1, 530, 420, XDLSTR('Example'), 7,
     *                      XDLSTR('Examp'), 5, -1, -1)

C====== Set up menu area and i/o window
      CALL XDLF_MENU_AREA (2, 1, 10, 10, 0, 6, 25, 2, 1, 25,
     *                     250, 400, IERR)
      CALL XDLF_IO_WINDOW (3, 1, 270, 10, 0, 0, 0, 250, 400, 2, 100,
     *                     IERR)

C====== Set menu details
      CALL XDLF_MENU_AREA_SETMENU (2, 4, XDLSTR(NAMES), 25,
     *                             XDLSTR('Options'), 7,
     *                             XDLSTR('Quit'), 4, 2, IERR)

C====== Menu servicing loop
100   IVHLIS(1) = 2
      CALL XDLF_GET_EVENTS (1, IVHLIS, IVH)
      IF (IVH.EQ.2) THEN
         CALL XDLF_MENU_AREA_GETITEM (2, ITEM, IQUIT)
         IF (IQUIT.EQ.1) STOP
         IF (ITEM.EQ.1) THEN
            CALL XDLF_IO_WINDOW_PRINT
     *           (3, XDLSTR('Input file name: '), 17, 0, IERR)
            IVHLIS(1) = 3
            CALL XDLF_GET_EVENTS (1, IVHLIS, IVH)
            CALL XDLF_IO_WINDOW_GETSTRING (3, XDLSTR(FILNAM),
     *                                     100, IERR)
            CALL RDDAT (FILNAM, A)
            GO TO 100
         ELSE IF (ITEM.EQ.2) THEN
            CALL TRANSA (A)
            GO TO 100
         ELSE IF (ITEM.EQ.3) THEN
            CALL TRANSB (A)
            GO TO 100
         ELSE IF (ITEM.EQ.4) THEN
            CALL XDLF_IO_WINDOW_PRINT
     *           (3, XDLSTR('Output file name: '), 18, 0, IERR)
            IVHLIS(1) = 3
            CALL XDLF_GET_EVENTS (1, IVHLIS, IVH)
            CALL XDLF_IO_WINDOW_GETSTRING (3, XDLSTR(FILNAM),
     *                                     100, IERR)
            CALL WRDAT (FILNAM, A)
            GO TO 100
         ENDIF
      ENDIF
      GO TO 100
      END

C====== Dummy data processing routines
      SUBROUTINE RDDAT (FILNAM, A)
      CHARACTER*(*) FILNAM
      REAL A(1000)
      WRITE (6,*) 'Open file', FILNAM, 'and read data into ''a'''
      RETURN
      END
      SUBROUTINE TRANSA (A)
      REAL A(1000)
      WRITE (6,*) 'Transformation A'
      RETURN
      END
      SUBROUTINE TRANSB (A)
      REAL A(1000)
      WRITE (6,*) 'Transformation B'
      RETURN
      END
      SUBROUTINE WRDAT (FILNAM, A)
      CHARACTER*(*) FILNAM
      REAL A(1000)
      WRITE (6,*) 'Open file', FILNAM, 'and write data from ''a'''
      RETURN
      END
 
 
 
1.5 SOME OTHER CONSIDERATIONS
 
The application program should not, in general,  have  any  form  of  input
which will block the program i.e. it should avoid reading  input  from  the
terminal input stream using normal Fortran (or C) read statements; instead,
it should use a window such as the I/O window for such input as this allows
for event handling to continue while the input is awaited.  (Some  routines
are now available to perform non-blocking reads  from  the  standard  input
whilst events are being handled; however these are  best  avoided  wherever
possible as they depend on alarm functions etc.)
 
If the program enters a time consuming process, e.g. a long computation  or
reading a large file, then, if feasible, the routine  xdl_flush_events,  in
'C', or xdlf_flush_events, in  Fortran,  should  be  called  at  reasonably
frequent intervals to allow background event  handling  to  continue.  Note
that during such a process, the program is not waiting for any input from a
view-object.
 
It should also be noted  that  pop-up  view-objects,  such  as  the  pop-up
dialogue box, lock out the display until a response is made to them.  Their
use should be avoided as much as possible and they should not be used as  a
means of inputting information to the program  just  to  make  life  a  bit
easier for the programmer. Where possible an I/O window  view-object  on  a
control item view-object containing a panel I/O item should be used.
 
 

CHAPTER 2: THE DESIGN OF XDL_VIEW  
==================================


2.1 INTRODUCTION
 
The basic requirements that the XDL_VIEW software was designed to meet  and
the basic philosophy of the routines have already been described in section
1.1 of Volume 1 and section 1.1 of this volume. A more detailed description
of items relating to the XDL_VIEW  management  routines  is  given  in  the
following sections. The items described are:
 
 * The view-object list
 
 * The initialisation routine
 
 * The event handling routine(s)
 
 
List of sections:
 
   The View-Objects List
   'C' Structures Associated with the View-Objects List
   Routines for Managing the View-Objects List
   The Initialisation Routine
   Event Handling
   The Fortran to 'C' Interface
   Fonts
 
2.2 THE VIEW-OBJECTS LIST
 
The heart of the management of the XDL_VIEW view-objects is an array  of  C
structures with one element for each view-object currently present for  the
application. The structure includes a list of all windows  associated  with
the  view-object,  pointers  to  global  data  areas  associated  with  the
view-object and the names of  callback  and  other  routines  for  use  for
example in the event handling.
 
The view-object routines are coded in such a way that  multiple  copies  of
any particular view-object may be used as required. In most cases,  when  a
new view-object is created, the  routine  which  is  called  to  create  it
allocates an area of memory for a view-object specific C structure to  hold
any items of data which are required for communication bewteen the  various
routines  associated  with  that  view-object.  Thus  each  instance  of  a
view-object has its own 'global data' area.
 
 
2.3 'C' STRUCTURES ASSOCIATED WITH THE VIEW-OBJECTS LIST
 
The format of the view-objects list structure is as follows:
 
typedef struct
{
   int        vh;         /*The view object handle as set in the
                            application program*/
   Window     wid;        /*The (top level) window id for this
                            view-object*/
   int        vh_parent;  /*View object handle of parent if view-object is
                            a sub_window of another view-object in the
                            XDL_view_objects list*/
   int        type;       /*A unique integer value identifying the
                            view-object type. This is for safety checking
                            to ensure that, when a routine is called to
                            manipulate or get data from a view-object
                            identified by the view-object handle, the
                            view-object is of the correct type*/
   char *gd;              /*Pointer to structure of data items used for
                            communicating between the functions of the
                            view-object ('global data' area)*/
   int        num_win ;   /*Number of window objects associated with
                            this view-object (subwindows etc.)*/
   XDl_window *win_list;  /*Array of  window objects associated with
                            this view-object. (includes the top level
                            window of the view-object*/
   void    (*on_off)();   /*Pointer to view-object's on/off function to
                            be called to turn program input from the
                            view-object on or off. This will be called
                            by the xdl_get_events routine. A null may
                            be given if such a routine is not required
                            or implemented*/
   void (*tidy_up)();     /*Pointer to the view_object's tidy up
                            function to be called when the view-object is
                            deleted by calling the xdl_delete_view_object
                            routine. This routine will for example free
                            any memory areas allocated by the view object.
                            (It need not free the global data area as this
                            will be automatically freed by the
                            xdl_delete_view_object routine). A NULL may
                            be given if such a routine is not required*/
}
   XDl_view_object;
 
As already indicated, the entry for a view-object contains a pointer  to  a
list of windows associated with the view-object. Each entry in this list is
a structure with the following format:
 
typedef struct
{
   Window wid;            /*Window i.d. for the window*/
   void (*repaint)();     /*Repaint routine to be called on expose,
                            configure notify (resize) */
   void (*ehp)();         /*Event Handling Procedure for other events*/
   XDl_libdata *libdata;  /*Pointer to XDl_libdata structure for a library
                            routine window - otherwise NULL*/
}
   XDl_window;
 
If a window is associated with some special library type of routine (e.g. a
panel item) then  an  additional  structure  of  type  XDl_libdata  may  be
present. This has the following format:
 
typedef struct
{
   char *gd;              /*Pointer to a private data area used by the
                            library window function*/
   void (*callback)();    /*Callback routine to return data to
                            view-object*/
   void (*tidy_up)();     /*Tidy up routine to be called when library
                            routine window is deleted via
                            xdl_delete_view_object (this need not free gd
                            as this will be done automatically by
                            xdl_delete_view_object)*/
}
   XDl_libdata;
 
 
 
2.4 ROUTINES FOR MANAGING THE VIEW-OBJECTS LIST
 
A number of routines are available for managing the list  of  view-objects.
These include the following:
 
 
xdl_open_view
 
   Initialises the view-objects list  amongst  other  functions  (see  next
   section).
 
xdl_new_view_object
 
   Add a new view-object to the list of view-objects.
 
xdl_add_window
 
   Add details of a window to the windows list for a view object.
 
xdl_add_libwin
 
   Add library routine window to the list of windows for a view-object.
 
xdl_delete_view_object
 
   Delete a view-object from the view-objects list.
 
xdl_get_events
 
   Event handling (also xdl_getio_events)
 
xdl_getiv
 
   Get offset in view-objects list for a view-object given the  view-object
   handle.
 
xdl_get_global
 
   Get 'global data' pointer from a window id.
 
xdl_get_vh
 
   Get view-object handle for  the  view-object  associated  with  a  given
   window id.
 
 
A list of all the routines in the xdl_view.c source file is given in Volume
3 of the documentation. The calls to the repaint,  event  handling,  on_off
and tidy_up routines are also described in Volume 3 of the documentation.
 
 
2.5 THE INITIALISATION ROUTINE
 
The initialisation routine xdl_open_view (or  xdlf_open_view  for  Fortran)
must be called before any other XDL_VIEW routine. As already indicated,  it
initialises the array of XDl_view_object structures. It also  sets  up,  in
addition to a a small default colour map which contains the colours  black,
white and the six primary and secondary colours, colour maps based  on  the
user's requirements for the application. In  addition  to  these  items,  a
number of other global data items, which may be used within  the  code  for
the individual view-objects, are set up by the initialisation routine.
 
The global data items set up are as follows:
 
1) X-windows Display and Screen Parameters
 
    Display      *XDL_display;             Display.
    XtAppContext XDL_app;                  Application Context
    int          XDL_screen;               Screen no.
    int          XDL_open = 0;             XDL_VIEW opened flag.
 
 
2) View-objects List
 
    int          XDL_num_view_objects;     Number of view-objects set up.
    XDl_view_object  **XDL_view_objects;   Array of pointers to
                                           XDL_view_object structures
    int          XDL_max_alloc_objects;    Max. no. of view-objects for
                                           which table space has been
                                           allocated.
 
 
3) Fonts
 
    XFontStruct  *XDL_fontinfo;            Standard (small) font.
    XFontStruct  *XDL_fontinfo_bold;       Standard (small) bold font.
    XFontStruct  *XDL_fonts[5];            Fonts very small, small,
                                           medium, large and very large.
    XFontStruct  *XDL_bold_fonts[5];       Bold fonts very small, small,
                                           medium, large and very large.
 
 
4) Default Cursor (Arrow pointing up and left)
 
    Cursor       XDL_default_cursor;       Default cursor.
 
 
5) Colour Requirements
 
    int          XDL_color;                Colour availability flag
                                           = 0, not available - monochrome
                                           = 1, grays
                                           = 2, colour
    int          XDL_display_type;         Display type to be used
                                           = StaticGray, GrayScale,
                                             StaticColor, PseudoColor,
                                             TrueColor or DirectColor
                                             (Values defined in X.h)
    int          XDL_csets_alloc;          =1 requested colour sets
                                              allocated with writeable
                                              colour cells
                                           =0 requested colour sets not
                                              allocated (static display
                                              type or less than 8 bit
                                              planes)
    int          XDL_display_cells;        No. of color cells available.
    Visual       *XDL_visual;              Visual for creating windows.
    int          XDL_pw_depth;             Depth for paint windows.
    Colormap     XDL_colormap;             Colormap selected for the
                                           application.
    int          XDL_num_colorsets;        Number of colormap sets (in
                                           addition to the standard short
                                           pallette).
    XDl_colorset XDL_colorsets[MAXCOLORSETS];
                                           Array of allocated colormap
                                           sets
    unsigned long  XDL_blackpixel;         Black pixel no.
    unsigned long  XDL_whitepixel;         White pixel no.
    unsigned long  XDL_redpixel;           Red pixel no.
    unsigned long  XDL_yellowpixel;        Yellow pixel no.
    unsigned long  XDL_greenpixel;         Green pixel no.
    unsigned long  XDL_cyanpixel;          Cyan pixel no.
    unsigned long  XDL_bluepixel;          Blue pixel no.
    unsigned long  XDL_magentapixel;       Magenta pixel no.
 
 
6) Graphics Context for 'active strip' (used by routines in xdl_view.c)
 
    GC XDL_active_strip_gc;                GC for standard 'view-object
                                           active for input to the
                                           application' window use.
 
 
7) Flag for event handling routine (xdl_get_events)
 
    int XDL_return_data_vh;                Data returned from 'active'
                                           view-object.
                                           flag = 0, none returned.
                                                > 0, the view-object
                                                     handle of the
                                                     view-object
                                                     returning the data.
 
 
8) Select/Paste Options
 
    Atom XDL_paste_buffer;                 Atom for xdl_view cut/paste
                                           string buffers.
 
 
9) Handling events at timed intervals
 
    int XDL_tmr_events;                    Timer events handling in
                                           progress flag.
                                           =0 no, =1 yes
 
 
10) Pointers list for XDLSTR function
 
    char * XDL_pointers[MAXPOINTERS];      List of string pointers.
    int    XDL_pointers_index;             Last index to pointers
                                           currently used (list used in
                                           a circular manner).
 
 
 
The definitions are included in the file 'xdl_view_extern.h'  which  should
be included in all view-objects source code files.
 
 
2.6 EVENT HANDLING
 
An important part of XDL_VIEW is the X event handling  mechanism.  This  is
normally done through a call from the application program  to  the  routine
xdl_get_events (in C) or xdlf_get_events (in Fortran). When the routine  is
called, the user specifies a list  of  the  view  objects  from  which  the
program is ready to receive  input  ('active'  view-objects).  The  routine
services all the X events, passing them on to the approriate event handling
routines, as defined in the XDl_view_objects array, until an  event  causes
program input from one of the active  view-objects;  when  this  occurs,  a
return is made from the  routine  giving  the  view-object  handle  of  the
routine from which  the  input  originated.  The  structure  of  the  event
handling routine is shown below:
 
Structure of the event handling routine xdl_get_events
 
 
              Set XDL_return_data_vh, the data  returned
              from view-object flag, to zero.
                                |
              For each view-object in the user specified
              active view-objects list, call the  on/off
              routine specified for that view-object  in
              the XDL_view_objects array (unless a NULL)
              with the flag set to 'on'.
                                |
    |-------------------------->|
    |                           |
    |         Get (wait for) next X event and find  the
    |         id of the window associated with it (wid)
    |                           |
    |         Find the offset in  the  XDL_view_objects
    |         array (iv) for the view-object  to  which
    |         the window  belongs  and  the  XDl_window
    |         structure associated with the window.
    |                           |
    |         If the event was a Configure Notify or an
    |         Expose, then call the repaint routine for
    |         that window (unless a NULL) as defined in
    |         the XDL_window structure. Otherwise  call
    |         the  general  event  handling   procedure
    |         (unless  a  NULL)  from  the   XDL_window
    |         structure.
    |                           |
    |         Has the XDL_return_data_vh flag been  set
    |<--No--- to a view-object handle?
    |                           |
    |                          Yes
    |                           |
    |         Is the view-object in the list of  active
    |         view-objects (reset XDL_return_data_vh to
    |<--No--- zero before continuing)
                                |
                               Yes
                                |
              For each view-object in the user specified
              active view-objects list, call the  on/off
              routine specified for that view-object  in
              the XDL_view_objects array (unless a NULL)
              with the flag set to 'off'.
                                |
              Flush display and return  the  view-object
              handle to the calling program.
 
 
When the program is not waiting for events from a view-object and is in the
middle of a long calculation, it may be desirable to  call,  at  intervals,
the routine xdl_flush_events (in C) or xdlf_flush_events  (in  Fortran)  to
service any X events  currently  in  the  event  queue.  This  will  enable
'background' activity to continue in the windows of  the  view-objects  for
events which do not give rise to program input.
 
Routines are also available which  will  handle  keyboard  input  from  the
standard   input   stream   whilst   handling    events    xdl_getio_events
(xdlf_getio_events). Their use is best avoided if possible.
 
 
2.7 THE FORTRAN TO 'C' INTERFACE
 
Some thought has been  given  to  the  portability  of  the  Fortran  to  C
interface. Passing integer and real parameters seems to pose  no  problems.
When needed, the address of a character string is  passed  as  a  parameter
using a function XDLSTR to return an index to an internal table of pointers
which contains the address of the character string. The  string  length  is
always passed as an additional, integer, parameter. A  table  relating  the
routine names expected by the linker to those within the C source  code  is
set up within each view-object source code file. Two parameter  definitions
in a file xdl_view_systyp.h select the option to be  used  for  the  XDLSTR
routine and the form of the linking name. These  are  CHAR_STRING_TYPE  and
LINKTYP. The xdl_systyp.h  file  also  contains  a  few  other  definitions
required to cope with variations in system functions available on different
operating systems or versions of operating systems.  The  required  options
are set in this file for a range of machine types and others will be  added
as the information becomes available.
 
For routines, which return character strings, it may be  useful  to  follow
the example of a  routine  such  as  xdl_io_window_getstring.  The  routine
allows for either the return of the character data into  a  Fortran  string
padded with blanks, if the 'max_len' parameter is given a negative value in
the call, or into a null terminated C string, if the 'max_len' parameter is
given a positive value. The xdl_copy_chars routine is available  to  assist
such an implementation.
 
 
2.8 FONTS
 
The original set of view-objects were written to  use  the  five  sizes  of
Courier fonts as set up by the the  xdl_open_view  initialisation  routine.
These fonts are available in both normal and bold print (structure pointers
*XDL_fonts[5]  and  *XDL_bold_fonts[5]).   The   following   default   font
specifications are now used within the routines:
 
   static char *font_default[] =
     {
       "*adobe-courier-medium-r*--8*",
       "*adobe-courier-medium-r*--12*",
       "*adobe-courier-medium-r*--14*",
       "*adobe-courier-medium-r*--18*",
       "*adobe-courier-medium-r*--24*"};   /* Default fontnames */

   static char *font_bold_default[] =
     {
       "*adobe-courier-bold-r*--8*",
       "*adobe-courier-bold-r*--12*",
       "*adobe-courier-bold-r*--14*",
       "*adobe-courier-bold-r*--18*",
       "*adobe-courier-bold-r*--24*"};   /* Default fontnames */
 
Fonts will normally be defined as X-windows resources Xdl*font1...Xdl*font5
and Xdl*boldFont1...Xdl*boldFont5. There are  five  normal  and  five  bold
fonts. These should normally be fixed width fonts. Each series must  be  in
ascending size order. Bold fonts must match normal fonts to within 1  pixel
in width and two in height. Some of the view-objects assume that the  small
font does not exceed 7x13 in pixels in size; a warning will  be  output  if
this size is exceeded.
 
The following is an example of specifing the fonts as X-windows resources:
 
Xdl*font1:  -adobe-courier-medium-r-normal--10-100-75-75-m-60-iso8859-1
Xdl*font2:  -adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1
Xdl*font3:  -adobe-courier-medium-r-normal--14-140-75-75-m-90-iso8859-1
Xdl*font4:  -adobe-courier-medium-r-normal--18-180-75-75-m-110-iso8859-1
Xdl*font5:  -adobe-courier-medium-r-normal--24-240-75-75-m-150-iso8859-1

Xdl*boldFont1:  -adobe-courier-bold-r-normal--10-100-75-75-m-60-iso8859-1
Xdl*boldFont2:  -adobe-courier-bold-r-normal--12-120-75-75-m-70-iso8859-1
Xdl*boldFont3:  -adobe-courier-bold-r-normal--14-140-75-75-m-90-iso8859-1
Xdl*boldFont4:  -adobe-courier-bold-r-normal--18-180-75-75-m-110-iso8859-1
Xdl*boldFont5:  -adobe-courier-bold-r-normal--24-240-75-75-m-150-iso8859-1
 
 
 

CHAPTER 3: CREATING NEW VIEW-OBJECTS  
=====================================


3.1 INTRODUCTION
 
This chapter gives some advice on how to code a new  XDL_VIEW  view-object.
Though the fundamental requirements are few it is recommended that any  new
view-objects should be coded in the  same  style  as  those  which  already
exist. It is also desirable to follow the internal documentation  style  so
that documentation may be extracted  automatically  from  the  source  file
using the 'extract_doc' program.
 
List of sections:
 
   Writing Code for a New View-Object
   General Layout of the Code
   The View-object Template File
   View-objects without an Active Strip
   View-objects with Keyboard Input
   Layout Considerations
   Library Window Routines
 
3.2 WRITING CODE FOR A NEW VIEW-OBJECT
 
A single source code file should be provided  for  each  view-object.  This
will contain the code used to set up  the  object,  code  to  handle  event
callbacks etc. and additional application callable  routines  if  required.
Fortran interfaces should be provided to the application callable  routines
in a manner which will cope with a range of different computer types.
 
The fundamental requirements for coding a view-object are few. The  routine
for creating the view-object must have a view-object handle as one  of  its
parameters. A top level window must be created and a call must be  made  to
the routine xdl_new_view_object to add  the  view-object  to  the  list  of
view-objects. For any additional windows created, entries must be added  to
the view-object's list of windows by calling the routine xdl_add_window (or
xdl_add_libwin) for each added window.
 
It is desirable, however, to follow the presentation and  coding  style  of
the original set of view-objects such  as  xdl_menu_area,  xdl_param_table,
xdl_io_window and xdl_film_image. Some basic  requirements  are  common  to
almost all view-objects. To describe the recommended coding layout  and  to
assist with the writing of new view-objects, a template file xdl_template.c
has been prepared to act as a starting point. This contains  the  essential
skeleton for a view-object which has at least one paint  window  and  which
returns some data to the application program when required. Thus the  basic
coding for including an active strip window is included. Keyboard input  is
not included in this template file but an alternative file  which  includes
code for handling the keyboard focus is  available  as  xdl_template_kbd.c.
Some details of how to cope with other requirements are given following the
description of the template code and reference  is  made  to  some  of  the
original view-objects where appropriate.
 
Where possible, the layout should allow  for  font  specifications  of  any
size. However, the small font size may be used with 'hard wired' sizes  and
may be assumed not to exceed 7x13 pixels in size. The five fonts (normal or
bold) may also be assumed to be in ascending order of size. The size  of  a
normal font and the corresponding bold font may be assumed not to differ by
more than one pixel in width and two in height.
 
 
3.3 GENERAL LAYOUT OF THE CODE
 
The general layout of the coding is as follows:
 
 
1) Header Information for routine creating the view-object:
 
 
      * Routine Header
 
      * Description of Fortran call
 
      * Inclusion of xdl_view_extern.h and other header files
 
      * Parameter definitions for the view-object
 
      * Definition of the global data structure for the view-object
 
      * Definition of the routine types
 
      * Definition of the Fortran binding names (for LINKTYP options)
 
      * Definition of the Fortran binding routines
 
 
2) The code for the view-object creation routine.
 
3) The code for the Fortran binding of the view-object creation routine.
 
4) Private service routines as follows:
 
 
      * Repaint routine for the active strip (if present)
 
      * Repaint routines for the view-object's windows
 
      * Event handling routines for the view-object's windows
 
      * View-object on_off routine
 
      * View-object tidy_up routine
 
      * Other service routines as needed
 
      * Panel item callback routines if needed
 
 
5) Application callable routines:
 
 
      * Routines  to  change  the  state  of  the  view-object  (+  Fortran
        bindings)
 
      * Routines to return data to the application (+ Fortran bindings)
 
        (Each should have a section of documentation in its header)
 
 
 
It is suggested in particular that the following be preserved:
 
 
 * The general style of the  existing  view-objects  appearance  should  be
   followed where possible (e.g. use of active  strip,  restrained  use  of
   colour, border  width  and  height  around  the  main  inner  window  of
   BORDER_WIDTH and BORDER_HEIGHT).
 
 * The view_object should be given a name e.g. with two parts separated  by
   an underscore (e.g. menu_area, film_image).
 
 * The name of the routine for creating the view-object should  be  of  the
   form xdl_view_name  (e.g.  xdl_menu_area)  and  the  equivalent  fortran
   binding name be xdlf_view_name.
 
 * All routines within the view-object source code file should  start  with
   the  above   name   e.g.   for   xdl_param_table,   xdl_param_table_rp1,
   xdl_param_table_ep1,  xdl_param_table_on_off,   xdl_param_table_tidy_up,
   xdl_param_table_getvalue etc.
 
 * The on/off routine name should be of the form  xdl_view_name_on_off  and
   the tidy up routine name should be of the form xdl_view_name_tidy_up.
 
 * The  name  of  the  global  data  structure  should  be  of   the   form
   XDl_view_name e.g. XDl_param_table.
 
 * The use of the variable 'gd' as a temporary pointer to the  global  data
   structure.
 
 * The way of setting up the top level window and handling the presence  or
   absence of a parent view-object.
 
 * The handling of the Fortran/C  interface  (Especially  with  respect  to
   character strings and link names).
 
 * The handling of the call checking in the application  callable  routines
   for  modifying  the  view-object  state  or  returning  data  from   the
   view-object.
 
 
Also, it is desirable to follow the documentation scheme  as  indicated  in
the template files as a program (extrac_doc) is available to  extract  this
documentation from the files. The documentation sections are as follows:
 
 
 * A title line enclosed by:
 
 
   /*-Title: ...
   -end*.
 
 
 * An introductory section enclosed by:
 
 
   /*-Intro:
   ...
   -end*/
 
 
 * A header section for each set of routines to be documented enclosed by:
 
 
   /*-Section: ...section_title...
   ...
   -end*/
 
 
 * The main routine header and each application routine  header  should  be
   laid out with the calls described as indicated. The document  extraction
   program will be searching for Routine header sections:
 
 
   /*-Routine: ...brief_description... - ...routine_name...
   ...
   ... (description)
   ...
   -end*/
 
 
 * Also sections describing the Fortran call:
 
 
   /*-Fortran:
       ...subroutine_call_syntax...
   -end*/

   /*-Parameters:
   ...
   ...  (description of parameters)
   ...
   -end*/
 
 
 * Also sections describing the 'C' call:
 
 
   /*-C:*/
        ...function_definition...
   /*end*/

   /*-Parameters:*/
   ...
   ... (parameter specifications - different form may be adopted if parameters
   ...  defined in definition (see extract_doc program documentation)
   ...
   /*end*/

   /*-Doc:

   Return: ...description_of_the_function_return(s)...

   -end*/
 
 
 
For further details, see the documentation of the extract_doc program.
 
Each new view-object coded must be assigned a unique integer which is  used
in checking that application routines called are for the  correct  type  of
view-object. The user wishing to create his/her  own  routines  should  use
numbers  greater  than  100000.  If  a  view-object  is  included  in   the
distribution set then it will be reassigned a number less than 100000.  The
assignment of the same number to more than one view-object does not prevent
anything working correctly if the correct  routines  are  called  with  the
correct view-object handles; it just removes a safety net.
 
 
3.4 THE VIEW-OBJECT TEMPLATE FILE
 
When using the template file as a starting point for the  code  for  a  new
view-object, the text 'view_name' must be replaced by the name of  the  new
routine (preferably again a two  part  name  linked  with  an  underscore).
Places where an ellipsis (...) occurs will need  altering  or  filling  out
with code specific to the new view-object.
 
The template  file  is  reproduced  below  with  added  comments  following
exclamation marks. These comments are designed to explain the coding in the
template and to help the programmer to add the code required  for  the  new
view-object. Reference is made to existing view-objects for examples  where
appropriate.
 
/*-Title: ...    ! Title for this set of routines
-end*/

/*-Intro:
...    ! General description of the view object
-end*/

/*Routines List:
...    ! Names and very brief descriptions of user callable routines
       ! (not used in extracted documentation)
*/

! Code starts with a standard format of header

/*-Routine: ... - ...   ! Brief description and routine name
...                     ! Description of the routine
-end*/

/*
************************
**    xdl_view_name   **
************************

Purpose: ! Brief description of the view-object given here

Author:  ...

! Fortran call described next
/*-Fortran:
       CALL XDLF_VIEW_NAME (IVH, IVHPARENT, IX, IY, ICSET, ... , IERR)
-end*/

/*-Parameters:
         IVH       (R)   View-object handle (see vh)
         IVHPARENT (R)   View-object handle for parent 0=none
                         (see vh_parent)
         IX        (R)   X position if parent given (see x)
         IY        (R)   Y position if parent given (see y)
         ICSET     (R)   Colorset number (see cset)
         ...       ! Add other parameters here as needed
         IERR      (W)   Returns status from xdl_view_name call
-end*/

/* Include XDL external data and headers */

! The following header file is always included
#include "xdl_view_ext.h"
! Other header files may be required e.g. xdl_panel_items.h
! (see xdl_param_table, xdl_film_image for examples)

#define ...  ! Put any parameter definitions here (see xdl_film_image for
             ! examples)

/* Define structure for the global data for the view-object */

! The global data area for the view-object is now defined. This
! must contain all data items which are required for communication
! between the routines for the view object an which are specific to
! a particular instance of the view-object. A few items (or very
! similar ones are always included)
typedef struct
{
   Window wframe;                 /* Primary window id */
   Window wpaint;                 /* Paint window id */
   Window wact;                   /* Active strip window */
   GC          paint_gc;          /* GC for paint window */
   int         on_off;            /* Program awaiting input =1, not =0 */
   ...     ! Add other items specific to the view-object here
}
   XDl_view_name;  ! Name based on view-object name

/* Define routine types */

int xdl_view_name();          ! Define all routines for the view-object
void xdl_view_name_rps();     ! (Fortran bindings will be defined below)
void xdl_view_name_rp1();
void xdl_view_name_ep1();
void xdl_view_name_on_off();
void xdl_view_name_tidy_up();
int xdl_view_name_getdata();

/* Define Fortran binding names */    ! Application callable routines

#if    LINKTYP == 1

#define xdlf_view_name xdlf_view_name_
#define xdlf_view_name_getdata xdlf_view_name_getdata_
! Add additional routines here and below

#elif  LINKTYP == 2

#define xdlf_view_name XDLF_view_name
#define xdlf_view_name_getdata XDLF_VIEW_NAME_GETDATA
! Add additional routines here and below

#endif

! Define fortran binding routines
void xdlf_view_name();
void xdlf_view_name_getdata();
! Add additional routines here

! View-object creation routine follows
/*-C:*/
int xdl_view_name (vh, vh_parent, x, y, cset, ... )
/*end*/

/*Parameters:*/
int       vh;             /* User selected view-object handle (R)*/
int       vh_parent;      /* View-object handle for the parent base frame,
                             if 0 then a base  level frame is created to
                             enclose the view-object (R)*/
int       x;              /* x coordinate for the view-object
                             If no parent may be -1 to give default x (R)*/
int       y;              /* y coordinate for the view-object
                             If no parent may be -1 to give default y (R)*/
int       cset;           /* Number of the colorset to be used (R) */
...
/*end*/

/*-Doc:
Return:  Status flag =0 OK, >0 error
         bit 0 set: Requested parent not found in the view-objects list
         ...  ! Add other conditions as required
-end*/
{
   Window wframe;              /* Top level window id*/
   Window wparent;             /* Parent window id */
   XDl_view_name * gd;         /* Pointer to view-object's global data
                                  structure */
   int err;                    /* Error return flag */
   int iv;                     /* Offset into XDL_view_objects array */
   int width;                  /* View-object width */
   int height;                 /* View-object height */
   int area_width;             /* Paint area width */
   int area_height;            /* Paint area height */
   int x_area;                 /* x position of paint area within
                                  the view-object*/
   int y_area;                 /* y position of paint area within
                                  the view-object */

   err = 0;

   /* Get size requirements */  ! e.g for the top level window and the
                                ! paint window
   width = ... ;
   height = ... ;
   area_width = ... ;
   area_height = ... ;
   x_area = ... ;
   y_area = ...;

   /* Create the top level frame (or base frame) window for the routine */

! The following section will be appropriate for most view-objects. It
! has been used in xdl_menu_area, xdl_param_table, xdl_film_image etc.
   /* Check that parent_vh present if requested */

   if (vh_parent>0)
   {
      iv = xdl_getiv (vh_parent);
      if (iv<0)
      /* Create frame window as parent window was given */
      {
         err |= 1;
         return err;
      }
      wparent = XDL_view_objects[iv]->wid;
      wframe = xdl_create_frame_window (wparent, x, y, width, height,
                                        cset);
   }else{
   /* Create base frame window as no parent frame window was specified */
      wframe = xdl_create_base_frame_window ("xdl_view_name", "xdl_view",
                          x, y, width, height);
   }

   /* Create structure for the routines' global data */

   gd = (XDl_view_name *) malloc (sizeof(XDl_view_name));
! gd has been generally used as a temporary pointer to the global data
! for a view-object

   /* Add new view-object to the list of view-objects */

   xdl_new_view_object (vh, wframe, vh_parent, gd, 999...,
                        xdl_view_name_on_off, xdl_view_name_tidy_up);
! The fifth parameter is an integer which should be unique to a particular
! type of view-object. It is used to check that, when an application calls
! one of the other routines associated with the view-object (e.g.
! xdl_view_name_getdata in this template file), the view-object accessed
! via the view-object handle is of the correct type.
! Note definition of on_off and tidy_up routines

   /* Some initialisations */

   gd->wframe = wframe;
   gd->on_off = 0; ! Set on/off flag to 'inactive' state. This will
                   ! subsequently be set on or off via the on-off
                   ! routine defined in the xdl_new_view_object call
                   ! above
! Initialise other items in the global data structure as needed

   /* Create active strip window */

   gd->wact = xdl_create_active_strip (gd->wframe, vh, area_width...,
                                       xdl_view_name_rps);
! Check the required width in the above call
! Note definition of active strip repaint routine

   /* Create paint window */ ! Note that the window is added to the
                             ! windows list

   gd->wpaint = xdl_create_paint_window (wframe, x_area, y_area, 1,
                                         area_width, area_height, cset);

   xdl_add_window (vh, gd->wpaint, xdl_view_name_rp1, xdl_view_name_ep1);
! Note definition of repaint and event handling routines

   /* Prepare for event handling */

   XSelectInput (XDL_display, gd->wpaint, ExposureMask|StructureNotifyMask|
                    ... );  ! Add other event inputs as required

   /* Create and initialise GC */ ! Remember to free any GCs created
                                  ! in the tidy_up routine

   gd->paint_gc = XCreateGC (XDL_display, gd->wpaint, 0, NULL);

   XSetForeground (XDL_display, gd->paint_gc, XDL_blackpixel);

   XSetFont (XDL_display, gd->paint_gc, ... ); ! Set a font if needed

   return 0;
}

! Fortran binding routine follows.
! Add extra parameters as needed.
! For an example of passing a character string using the xdlstr function
! see the xdlf_param_table subroutine

/* Fortran binding: xdlf_view_name */

void xdlf_view_name (ivh, ivhparent, ix, iy, icset, ... , ierr)

int *ivh, *ivhparent, *ix, *iy, *icset, *ierr;
...
{
   *ierr = xdl_view_name (*ivh, *ivhparent, *ix, *iy, *icset, ... );
   return;
}

/*==================================================*/
/*         'Private' SERVICE ROUTINES               */
/*==================================================*/

/*
*********************************
**     xdl_view_name_rps       **
*********************************

PURPOSE: Repaint active strip window

RETURN:  None

AUTHOR:  ...

*/

void xdl_view_name_rps (wid, event, iv, global, callback)

Window wid;
XEvent *event;
int iv;
char * global;
void (*callback)();

{
   XDl_view_name * gd;  /* Pointer to global data area */

   gd = (XDl_view_name *) global;
   if (gd->on_off==0)
   {
      xdl_active_strip_off (wid);
   }
   else
   {
      xdl_active_strip_on (wid, "...", 0);
   }
! Note that the final parameter of the xdl_active_strip_on call indicates
! the status of the keyboard focus when this is relevant to the
! view-object. In this case it is not and a value of 0 is given.
}

! A window repaint routine follows; there will normally be one such routine
! for each window associated with the view-object.
/*
*********************************
**     xdl_view_name_rp1       **
*********************************

Purpose: Repaint paint window

Return:  None

Author:  ...

*/

void xdl_view_name_rp1 (wid, event, iv, global, callback)

Window wid;
XEvent *event;
int iv;
char * global;
void (*callback)();

{
   XDl_view_name * gd;     /* Pointer to global data area */

   gd = (XDl_view_name *) global;

   /* Repaint code */

   ... ! This must be added as needed for the particular view-object
       ! See for example xdl_param_table_rp1, xdl_film_image_rp1 etc.

   return;
}

! A general event handling routine follows; there will normally be one
! such routine for each window associated with the view-object.
/*
*********************************
**     xdl_view_name_ep1       **
*********************************

Purpose: Event handling from paint window

Return:  None

Author:  ...

*/

void xdl_view_name_ep1 (wid, event, iv, global, callback)

Window wid;
XEvent *event;
int iv;
char * global;
void (*callback)();

{
   XDl_view_name *gd;      /* Pointer to the global data area */

   gd = (XDl_view_name *) global;

   ... ! This must be added as needed for the particular view-object
       ! See for example xdl_param_table_ep1, xdl_film_image_ep1 etc.

   return;
}

! The following is the routine which will be called by the routine
! xdl_get_events to switch a view-object into its input 'active' or
! 'inactive' state
/*
***********************************
**     xdl_view_name_on_off      **
***********************************

Purpose: Routine called when switching application input on/off

Return:  None

Author:  ...

*/

void xdl_view_name_on_off (iv, i)

int iv;       /* Offset in XDL_view_objects array */
int i;        /* flag =1 on, =0 off */

{
   XDl_view_name *gd;        /* Pointer to global data area */

   gd = (XDl_view_name *) XDL_view_objects[iv]->gd;
   if (i==1)
   {
      gd->on_off = 1;
      ... ! This must be added as needed for the particular view-object
          ! See for example xdl_menu_area_on_off etc.
      xdl_active_strip_on (gd->wact, "...", 0);
! The last parameter in the above call may be different for view-objects
! with keyboard input (see for example xdl_io_window_on_off routine)
   }
   else
   {
      gd->on_off = 0;
      ... ! This must be added as needed for the particular view-object
          ! See for example xdl_menu_area_on_off etc.
      xdl_active_strip_off (gd->wact);
   }
   return;
}

! The following routine will be called when the view-object is deleted
/*
************************************
**     xdl_view_name_tidy_up      **
************************************

Purpose: Routine called to tidy up before view-object is deleted

Return: None

Author:  ...

*/

void xdl_view_name_tidy_up (global)

char * global;    /* Pointer to global data area */

{
   XDl_view_name *gd;    /* Pointer to the global data area */

   gd = (XDl_view_name *) global;
   ... ! Free any areas of memory allocated by the view-object (except
       ! for the global data area which will automatically be freed by
       ! the xdl_delete_view_object routine). Free any other resources
       ! allocated. (see for example xdl_film_image_tidy_up)
   XFreeGC (XDL_display, gd->paint_gc);
   return;
}

/*===========================================================*/
/*         'Public' APPLICATION CALLABLE ROUTINES            */
/*===========================================================*/

! Example of layout of a routine to return the data from a view-object
! (see for example xdl_param_table_getvalue)
/*Routine: ... - ... ! Brief description and name
...        ! Purpose, name and description of the routine
...
-end*/

/*
***********************************
**     xdl_view_name_getdata     **
***********************************

Purpose: Get returned data ... from the view_name

Author:  ...
/*-Fortran:
         CALL XDLF_VIEW_NAME_GETDATA (IVH, ..., IERR)
-end*/

/*-Parameters:
         IVH      (R)  View-object handle (see vh)
         ...
         IERR     (W)  Returns status from xdl_view_name_gedata call

-end*/

/*-C:*/
int xdl_view_name_getdata (vh, ... )
/*end*/

/*Parameters:*/
int vh;          /* View-object handle (R)*/
... ! Add parameters here as needed
/*end*/

/*-Doc:
Return:  Status = 0 OK, >0 error
                  bit 0 set:  View-object handle not found
                  bit 1 set:  View handle does not match view object
                  ...
-end*/
{
   int iv;               /* Offset in XDL_view_objects array */
   XDl_view_name *gd;    /* pointer to the global data area */

   iv = xdl_getiv (vh);

   /* Check validity of the call */

   if (iv<0) {xdl_view_iv_errmsg ("xdl_view_name_getdata",vh); return 1;}
   if (XDL_view_objects[iv]->type!=999...)
   {
      xdl_view_type_errmsg ("xdl_view_name_getdata", vh, "xdl_view_name");
      return 2;
   }

   gd = (XDl_view_name *) XDL_view_objects[iv]->gd;

   /* Return the required data */

   ... ! The code here will normally access data items from the global
       ! data area (pointed to by gd) and return the relevant information
       ! through the parameter list for this function

   return 0;
}

/* Fortran binding xdlf_view_name_getdata */

void xdlf_view_name_getdata (ivh, ..., ierr)
int *ivh, *ierr;
...
{
   *ierr = xdl_view_name_getdata (*ivh, ... );
! Examples of returning parameter values including text string values
! may be found in xdlf_menu_area_getitem and xdlf_param_table_getvalue
   return;
}
 
 
 
3.5 VIEW-OBJECTS WITHOUT AN ACTIVE STRIP
 
In some cases the view-object will  not  require  to  return  data  to  the
calling application program (e.g. progress bar view-object). In  this  case
the code for including an active strip as given in the template file may be
omitted.
 
The following changes would be made:
 
 
1) Remove the call to create the active strip
 
    gd->wact = xdl_create_active_strip (gd->wframe......
 
2) Remove the routine xdl_view_name_rps and references to it
 
3)  Remove the routine xdl_view_name_on_off and references to  it;  in  the
    xdl_new_view_object call, replace its name with a NULL.
 
4)  Remove references to the on_off item from the  XDl_view_name  structure
    (e.g. gd->on_off)
 
 
 
3.6 VIEW-OBJECTS WITH KEYBOARD INPUT
 
In view objects with keyboard input, the question of keyboard focus has  to
be considered. When an active strip is included and the view-object  is  in
its active state, the message in the active strip should be in  bold  print
when the view-object has the keyboard focus and be in normal print when  it
has lost the keyboard focus. The following additions/changes  are  required
to the template code described above (a  file  including  such  changes  is
available as xdl_template_kbd.c):
 
 
1)  Add the integer item kbd_focus to the XDl_view_name structure.
 
2)  Initialise this flag to  zero  when  the  global  data  area  has  been
    allocated.
 
3)  In the xdl_view_name_rps routine, use the  flag  gd->kbd_focus  as  the
    final   parameter   in   calling   the   routine   xdl_active_strip_on.
    (normal/bold print flag)
 
4)  In the xdl_view_name_on_off routine, when called to  set  the  'active'
    state, get the keyboard focus if possible  and  set  the  gd->kbd_focus
    flag as appropriate.
 
5)  In the event handling routine,  check  for  keyboard  focus  gained  or
    keyboard focus lost events. If  gained,  set  gd->kbd_focus  to  1  and
    re-draw the active  strip  with  the  message  in  bold  print  if  the
    view-object is in its active state (gd->on_off  ==  1).  If  lost,  set
    gd->kbd_focus to 0 and re-draw the active strip  with  the  message  in
    normal print if the view-object is in its active state.  Also,  if  the
    view-object is in its active state, get the keyboard focus  if  Button1
    of the mouse was pressed.
 
 
Examples of  view-objects  with  keyboard  input  include  the  I/O  window
view-object and the parameter table view-object.
 
 
3.7 LAYOUT CONSIDERATIONS
 
When a view-object has an active strip, then this is  situated  just  below
the top of the top-level window. It's origin  pixel  is  situated  at  x  =
BORDER_WIDTH, y = BORDER_HEIGHT. If w is the width of the top-level  window
for the view-object then the width of the active strip will normally be  (w
- 2*BORDER_WIDTH - 2). The total height of the active strip  plus  the  top
border is given by ACT_STRIP_HEIGHT. The window of a  view-object  situated
immediately below the active strip will normally have its  origin  at  x  =
BORDER_WIDTH, y = ACT_STRIP_HEIGHT + BORDER_HEIGHT  (leaving  a  border  of
height BORDER_HEIGHT between the active strip and the window). Thus,  where
appropriate, top and bottom borders will be  of  height  BORDER_HEIGHT  and
side borders will be of width BORDER_WIDTH. Examples of view-objects  using
these border sizes are the  menu  area  view-object,  the  parameter  table
view-object and the I/O window view-object.
 
The parameters BORDER_WIDTH, BORDER_HEIGHT and ACT_STRIP_HEIGHT are defined
in the header file xdl_view_extern.h.
 
Where appropriate, a routine should be provided to calculate the size of  a
view-object  given  a  set  of  set-up   parameters.   Examples   are   the
xdl_menu_area_getsize, xdl_io_window_getsize,  xdl_param_table_getsize  and
xdl_film_image_getsize routines.
 
 
3.8 LIBRARY WINDOW ROUTINES
 
Routines, such as those for creating  and  manipulating  the  panel  items,
provide standard window items which  may  be  used  within  the  coding  of
view-objects. They differ from the main view-objects in that they are  used
to serve the internal needs of a view-object rather than  directly  serving
the needs of the application program. As a consequence  they  do  not  have
view-object handles. They create windows which belong to the view-object in
a manner similar to that of other windows created within the  view-object's
own code. Because, however, they are library routines, which may be  shared
by many view-objects, they normally require a separate global data area  to
be set up for each instance created. Also, as they are  not  identified  by
view-object handles, they return data to the  view-object  via  a  callback
mechanism. When the window from a library window routine is  added  to  the
windows list of a view-object, the routine xdl_add_libwin is  used  instead
of xdl_add_window. This allows three extra items to be added to the  stored
window data namely:
 
 
1) A pointer to the library routine's global data area
 
2) A pointer to the callback routine to be used
 
3)  A pointer to a tidy_up routine to be called when  the  library  routine
    window item is deleted.
 
 
When an event is processed (xdl_get_events or xdl_flush_events),  it  is  a
pointer to the library routine's own global data area that is passed  as  a
parameter to the event handling routine rather than a pointer to the global
data for the view-object and a pointer to the callback routine is passed as
the final parameter rather than a NULL. When a view-object is deleted  then
the tidy_up routines, associated with any  library  window  routines  used,
will be called.
 
 

CHAPTER 4: REPAINT, EVENT-HANDLING, ON-OFF & TIDY-UP ROUTINE CALLS  
===================================================================


4.1 INTRODUCTION
 
This chpater describes the calls made to  the  various  types  of  routines
which may be called by the XDL_VIEW management routines. The routines under
consideration are the following:
 
 
a) Event Handling Routines
 
   These are called by the xdl_get_events routine  when  an  event  from  a
   view-object window is  processed.  The  events  are  considered  in  two
   classes with Expose and Configure Notify  events  causing  the  window's
   repaint routine to be called and with other events causing the  window's
   general event handling routine to be called.
 
b) On-off Routine
 
   The on-off routine for a view-object is  called  by  the  xdl_get_events
   routine when the view-object is one of those in the list of view-objects
   from which the application is prepared to receive input.  It  is  called
   once with the 'on' option at the start of the xdl_get_events routine and
   a second time  with  the  'off'  option  set  just  before  the  routine
   xdl_get_events makes a return to the calling program.
 
c) Tidy-up Routine
 
   This routine is called by  the  xdl_delete_view_object  routine  when  a
   view-object is deleted. It enables the user to  free  any  workspace  or
   other resources allocated to the view-object just prior to its  removal.
   Tidy-up routines will also be called for any library routines associated
   with the view-object.
 
 
List of sections:
 
   Repaint/Event-Handling Routine Calls
   On-Off Routine Calls
   Tidy-Up Routine Calls
 
4.2 REPAINT/EVENT-HANDLING ROUTINE CALLS
 
The repaint and general event handling routines are called as follows:
 
   (*repaint/ehp) (wid, event, iv, global, callback)

   Window wid;          The (X) window id of the window in generating the
                        event.

   XEvent *event;       A pointer to the XEvent structure for the X
                        event.

   int iv;              The offset in the XDL_view_objects array for the
                        view-object to which the window belongs.

   char *global;        A pointer to the global data area associated
                        with the window. This will normally be the
                        global data area associated with the view-object
                        to which the window belongs except in the case
                        of a library routine window in which case it will
                        be a private data area for the routine.

   void (*callback)()   This will normally be a NULL except for events
                        associated with windows created by library
                        routines such as the panel item routines.
 
 
 
4.3 ON-OFF ROUTINE CALLS
 
The on-off routine is called as follows:
 
   (*on_off) (iv, iflag)

   int iv;        The offset in the XDL_view_objects array for the
                  view-object to which the window belongs.

   int iflag;     Flag = 1, set view-object to program input 'on' mode.
                       = 0, set view-object to program input 'off' mode.
 
 
 
4.4 TIDY-UP ROUTINE CALLS
 
The tidy-up routine is called as follows:
 
   (*tidy_up) (global)

   char *global;        A pointer to the global data area associated
                        with the window. This will normally be the
                        global data area associated with the view-object
                        to which the window belongs except in the case
                        of a library routine window in which case it will
                        be a private data area for the routine.
 
 
 

CHAPTER 5: STANDARD LAYOUT PARAMETERS  
======================================


5.1 INTRODUCTION
 
A few parameters recommended for general use in the layout of  view-objects
are defined in the xdl_view.h header file. These are as follows:
 
BORDER_WIDTH
 
   Minimum left/right border width for normal use. This is for  the  border
   between the top level window (frame or base frame) of a view object  and
   windows (e.g. paint windows) laid out within it. It is also used  as  an
   offset for the left hand side of an active strip.
 
BORDER_HEIGHT
 
   Minimum top/bottom border height for normal use. This is for the  border
   between the top level window (frame or base frame) of a view object  and
   windows (e.g. paint windows) laid out within it. It is also used  as  an
   offset for the top of an active strip.
 
ACT_STRIP_HEIGHT
 
   This is the total height required from the top of a window containing an
   active strip to the bottom of the  strip.  The  next  window  below  the
   active strip should normally start at  a  y  value  of  BORDER_HEIGHT  +
   ACT_STRIP_HEIGHT.
 
 

CHAPTER 6: VIEW-OBJECT UNIQUE NUMBER IDENTIFIERS  
=================================================


6.1 INTRODUCTION
 
A list of the  Unique  Numbers  associated  with  the  currently  available
view-objects is given below. Any  further  view-objects  which  are  to  be
included in the distribution set  will  be  assigned  a  number  less  than
100000. For routines created by a user for  private  use,  numbers  greater
than 100000 should be selected.
 
        Base Frame View-object           1001

        Pop-up Frame View-object         1002

        Menu Area View-object            1051

        Parameter Table View-object      1041

        I/O window View-object           1031

        Text Table View-object           1021

        Graphics Window View-object      1071

        Pop-up Notice View-object        ----

        Pop-up Dialogue Box View-object  ----

        Pop-up Menu View-object          ----

        Progress Bar View-object         2001

        Blank View-object                1091

        Image View-object                1085

       (Film Image View-object           1081)

        Laue Simulations View-object     1061

        Rotation Simulations View-Object 2111

        Show Unique Data View-Object     2112

        Control Object: Panel Choice     2101

        Control Object: Panel Button     2102

        Control Object: Panel Label      2103

        Control Object: Panel Value      2104

        Control Object: Panel Slider     2105

        Control Object: Panel I/O Item   2106
 
 

CHAPTER 7: INSTALLATION NOTES  
==============================


7.1 INTRODUCTION
 
The xdl_view routines will normally be supplied (for  a  Unix  system)  via
anonymous 'ftp'. The user should create a directory to contain the xdl_view
routines. The files should be read into  this  directory  using  the  'tar'
utility. Normally the routines will be supplied as part  of  the  Daresbury
Laboratory Laue Software suite and/or the  CCP4  suite  and  the  directory
structure  for  these  cases  should  be  followed.  Any  files   such   as
'Changes.txt', Changes or 'README' files in the top level directory for the
xdl_view routines should be examined.
 
If the routines are to  be  installed  on  a  new  Unix  system,  the  file
xdl_systyp.h will need to  be  edited  as  to  set  the  values  of  a  few
parameters parameters as appropriate for the system on which  the  software
is to be used.
 
The C source code files (subdirectory 'src') should be compiled  using  the
-D switch on the C compiler to define the machine type unless the  required
symbols are already known to the compiler. The  supplied  Makefile  may  be
used after appropriate editing of items  as  indicated  in  the  file.  The
Makefile puts the object modules in a library in a user defined  directory.
Programs linked with this library or any xdl_view routines will  also  need
to be linked with the 'X-Intrinsics' (Xt) and 'Xlib'  (X11)  libraries.  If
supplied with the Laue Software suite, then there is a make file 'lmake' in
$CCP4_MASTER/laue/make which may be used (after modification if needed)  to
make a library of the xdl_view routines.
 
In addition to the XDL_VIEW source code  files,  there  is  a  subdirectory
'doc' containing the documentation files. The documentation files are in  a
form which can be printed using the TIDYTEXT program supplied with the CCP4
or LAUE software suites. Hard copies of the documentation will  usually  be
available from Daresbury if requested.
 
The subdirectory 'templates' contains skeleton C source  code  files  which
may be used by the user as the basis for coding new view-objects.
 
The routines should be considered as belonging to the  CCP4  suite  or  the
Daresbury Laboratory Laue Software suite and the conditions of distribution
pertaining to these apply.
 
