			SAOimage Notes	

				    by Donald H. Gudehus			SAOimage Notes	

			NON-SOURCE FILES

	The files MAKE.LST, [.BTNLIB]MAKE.LST, and [.VMS]MAKE.LST 
	contain lists of C subprograms which must be compiled to build
	SAOimage.

	The file MAKE.COM is the main command procedure to build and link
	SAOimage on a VMS system.

	The file [.VMS]MAKE.COM is a command procedure to build and link
        SAOimage on a VMS system.  It is called by MAKE.COM on the 
	root directory.

	The file MAKEFILE.DEC is a command procedure to build 
	SAOimage on a DEC UNIX system.  Provision for IRAF usage
	is included.

	The file README.TXT contains brief installation instructions for
	UNIX and VMS, and information on making changes to the source code
	for the purpose of adding remote IO and adding or changing buttons.
	
	The file [.VMS]README.VMS contains detailed instructions for building
	and installing SAOimage on a VMS system.  IRAF usage is discussed.
	One executes MAKE.COM which calls MAKE.LST, [.BTNLIB]MAKE.COM, 
	[.BTNLIB]MAKE.LST, [.VMS]MAKE.COM, and [.VMS]MAKE.LST.

	The file SETUP.COM is meant to be run on a VMS system from
	SYLOGIN.COM.  It must be edited by the user to properly 
	describe the capabilities of the computer on which SAOimage
	will be running.

	The file [.VMS]SAOSETUP.COM is meant to be run on a VMS system from
        SYLOGIN.COM.  This version is somewhat different than the root
        directory version.

        The file [.VMS]SETUP.COM is meant to be run on a VMS system from
        SYLOGIN.COM.  This version is less complete than the root 
	directory version.

	The file SAOIMAGE.HLP contains a brief description in VMS help 
	library format of how to operate SAOimage.  A glossary of terms
	in non-alphabetical order is given.  This glossary repeats the
	information in the hard copy user manual.

        The file [.VMS]SAOIMAGE.HLP contains a brief description in VMS help
        library format of how to operate SAOimage.  A glossary of terms
        in alphabetical order is given.  This glossary repeats the
        information in the hard copy user manual.

			HOW TO MAKE MODIFICATIONS

             To add new image formats, just add appropriate calls in
	init_image() in the file IMAGEREAD.C (to return dimensions) and 
	load_image() in the file IMAGEREAD.C (to load the passed buffer).
	You should add a commandline switch needed to recognize your image in 
	PARSE_FILETYPE() in CMDIMAGE.C  If your image file names have a 
	unique suffix, you may use that	to recognize the file type in 
	CHECK_IMAGE() in IMGCHECK.C.
	     To add remote IO from other processes, use one of the
	connection records in [.HFILES]CONTROL.H (initialized 
	[.DEFS]CONTROL.DEF) and follow the example in IRAFIO.C  It is 
	very simple: you just put the pointer to your callback in the 
	record and open the connection.
	     To add or change buttons, you must edit the ____.mnu files
	in the panel subdirectory.  You must look at the hfiles in btnlib
	and btnlib/tool to understand how the buttons are described.  You
	may use text strings and/or your own bitmaps.  To make new buttons,
	compile the library in btnlib/tool and then do the make in the panel
	subdirectory.  The button font is in the code, it does not use any
	runtime resources.
	
				FLOW
           (B=Boot, F=FITS image load,I=IRAF image load)

main (maininit.c)                               B
  XSetErrorHandler - for DEBUG
    crash_on_error (maininit.c)
      fprintf
      XGetErrorText
      exit
  ieee_handler - for SUN
  abrupt_underflow_
  setrlimit - not VMS
  init_params (maininit.c)                      B
    parse_cmdline (cmdparse.c)                  B    
      init_cmdline (cmdnew.c)                   B
        string_cmdline
      parse_display
      parse_filetype (cmdimage.c)
        usage
      parse_connection (cmdimage.c)             B
        strcmp
        open_imtool_connection (irafio.c)   not B
        close_imtool_connection             not B
        rename_imtool_connection            not B
          calloc_errchk
          strcpy
        si_init (ctcmd.c)                   not B
          new_display ... (imgnew.c)
          make_scalemap ...  
        open_rtsock_connection ... (rtio.c) not B
      parse_fileread (cmdimage.c)
        usage
      parse_rotate
      parse_scale
      parse_color
      parse_etc (cmdparse.c)
      parse_filename (cmdimage.c)
        usage
    say_goodbye
      free_gc (ctrlgc.c)
        XFreeFont
        XFreeGC
      XCloseDisplay
      exit
    check_image
    init_server (maininit.c)
      XOpenDisplay
      strcat
      exit_errmsg
    init_connections (ctrlcntn.c)                  B
      (*control.IRAF_in.func)()
        open_imtool_connection (irafio.c)          B
          open_connection (ctrlcntn.c)             B
            open_mailbox (ctrlmbox.c)              B
              zopnvi (zfiovi.c)                    B
              read_connection ... (ctrlcntn.c)
              flush_mailbox (ctrlmbox.c)
            open_pipe - not VMS
            open_socket_listener - not VMS
            accept_socket_connection - not VMS
            ZSelectAsyncInput
            init_select
            ButtonSelectMask - not VMS
          control.IRAF_in.func = read_imtool_packet (irafpipe.c)
  init_packages (maininit.c)                       B
    init_image (imgread.c)                         B
      init_fits (readfits.c)
      init_irafimh
      init_saoccd
      get_fbconfig ... (irafenv.c)
      init_img
        set_coordsys
        set_imgtran
      init_dispcen
    say_goodbye ...
    init_color (clralloc.c)
      init_visual (clrinit.c)
        DefaultScreen
        DisplayPlanes
        WhitePixel
        BlackPixel
        DefaultVisual
        DefaultColormap
        XVisualIDFromVisual
        XGetVisualInfo
        XFree
        verify_pseudocolor (clrinit.c)
          XGetVisualInfo
          XFreebcopy
      init_hard_colors
      lookup_cursor_colors (clrhard.c)
        lookup_color  
      free_color_cells
      free_cursor_cell_color
      init_overlay_color (clrsetup.c)
        init_cellstore
        set_cursor_overlay_color
        copy_xcolor_rgb
        make_cellstore_from_tables
        XStoreColors
      alloc_colors (clralloc.c)
      init_cell_color (clrsetup.c)
        alloc_cursor_cell_color (clrhard.c)
          alloc_hard_color
        make_cellstore_from_tables
        XStoreColors
      init_haltone_color
      exit_errmsg
    init_windows1 (wndwinit.c)
      DefaultRootWindow
      DisplayWidth
      DisplayHeight
      set_window_basics
      create_window (wndwcre.c)
        XCreateWindow
        exit_errmsg
        XSetStandardProperties
        XSetWMHints
        XMapWindow
        XSelectAsyncInput - VMS
    init_mousepointers
    init_gc (ctrlgc.c)
      XCreateGC
    init_cgraph_text
    init_imaging_buffers
    init_windows2 (wndwinit.c)
      set_border_color
      init_window_basics
      get_window_dimensions
      configure_windowgroup
      create_window ... (wndwcre.c)
    init_software_cursors
    init_colorbox (grphinit.c)
      init_main_colorbar (grphinit.c)
        XCreateSimpleWindow
        XMapWindow
        set_colorbar_image (grphinit.c)
          fill_colorbar
          make_halftone_colorbar (grphbtmp.c)
            bzero
            byte_dither_sample (grphbtmp.c)
            byte_diffuse_sample (grphbtmp.c)
    init_display_buffers (mainbffr.c)
      init_panbuf (mainbffr.c)
      init_dispbuf (mainbffr.c)
    init_panbox_coords (panwndw.c)
      set_coordsys
      set_transform
      combine_transform
      set_edges
    init_magnifier (mgfyinit.c)   Result depends on control.magni_track, 
                                                    control.coord_track
    new_display ... (imgnew.c)                         B
      set_disptran
      load_mainbuf (imgnew.c)
        set_buftran
        set_fbuftran
        bzero
        load_image (imgread.c)                     B
          i_transform (crdtrans.c)
          read_array (readarr.c)
            open_disk (ctrldisk.c)
              open
              fflush - on VMS
              perror
            lseek_disk
              lseek
              fflush
              perror - on VMS
            read_data
              read_disk
                read
                perror
                fflush
            scale_data_u1
            scale_data_i2
            scale_data_u2
            scale_data_i4
            scale_data_r4
            ieee_vax
            scale_data_r8
            close_disk
             close
             perror
             fflush
          load_saoccd
          load_einstein
          load_rosat
          load_logo
          rotate_buf (imgtrans.c)
            transfer_buf
            zflip_buf (imgflip.c)
            xflip_buf (imgflip.c)
            yflip_buf (imgflip.c)
            square_buf (imgtrans.c)
            cwturn_buf
            unsquare_buf (imgtrans.c)
        free
        show_filename (imgnew.c)
          XClearArea
          set_edit_gc
          XDrawImageString
      new_pancursor
      new_scalemap (sclctrl.c)                     B
        new_histogram
        make_scalemap ... (sclmap.c)               B
        color_logo
        set_imtool_colors (irafdisp.c)
      combine_transform
      set_edges
      set_dispoff
      adjust_cursor_coords ... (csrcoord.c)
      set_magnifier
      map_dispbox ... (display.c)
      disp_dispbox ... (display.c)
    new_panimage (imgnew.c)                        B
      load_image ...  
      copy_buf_replicate
      switch
      copy_buf_subsample
      copy_buf_sum
      coy_buf_max
      map_panbox
    set_gc_with_background
    init_buttonmenu
    init_buttonbox_settings (menuctrl.c)  The buttons get initialized
    init_region_draw (rgndraw.c)
      set_submenu_toggle
      get_fontstruct
    mount_buttonmenu
  control_event_loop (mainevnt.c)                  B
    sys$clref
    XSelectAsyncInput (mainevnt.c)
    XPending
    XNextEvent
    select
    perror
    respond_to_connection (ctrlcntn.c)
      open_connection - not VMS ...
      close_connection - not VMS ...
      (*port->func)(port)
        read_imtool_packet (irafpipe.c)              I   
          read_connection ... (ctrlcntn.c)  Attempts to read 16 bytes;  returns
					    actual number read
            read_mailbox (ctrlmbox.c)                I
              zardvi                                 I
              zawtvi                                 I
              fflush
            read_disk - not VMS
          swap_bytes
          check_packet_sum (irafpipe.c)
            swap_bytes
            exit_errmsg
          flush_connection
          imtool_response (irafimtl.c)               I  Is sent imhead.thingct
	    case FEEDBACK
              bzero                                    I
              map_dispbox ... (display.c)
              disp_dispbox ... (display.c)
              bzero
              map_panbox
              disp_panbox
              imtool_newimage ... (irafimtl.c)
	    case WCS
              get_frame_no
              write_imtool_connection
	      read_connection
	      update_wcs (irafenv.c)
	      imtool_newimage (irafimtl.c)
                get_frame_no
                get_fbconfig ... (irafenv.c)
                imtool_reinit (irafdisp.c)
                  d_transform (crdtrans.c)
                  init_img
                  init_dispcen
                  init_imagebuf
                  new_panbox ... (panwndw.c)
                update_wcs (irafenv.c)
                  sprintf
                  set_path_iraf
                  fopen
                  strcpy
                  strcat
                  combine_transform
                  set_trans_speed
                  invert_transform
                  guess_true_file_coords
                  show_filename (imgnew.c)
                set_tdisp (crdtemp.c)
                set_disptran
                combine_transform
                set_edges
                set_dispoff
                new_pancursor
                adjust_cursor_coords (csrcoord.c)
                  disp_coords_changed
                  set_polygon_from_file_coords
                  set_annuli_from_file_coords ... (csrcoord.c)
                  set_cursor_from_file_coords (csrcoord.c)
                    d_transform (crdtrans.c)
                    reset_textcursor_coords
                    make_cursor (csrshape.c)
                      switch
                      make_circur (csrshape.c)
                      make_ellipse (csrshape.c)
                      make_boxcur (csrshape.c)
                      make_arrow (csrshape.c)
                  note_current_disp_transform (csrcoord.c)
                set_magnifier
                set_imtool_scale ... (irafdisp.c)
  	        new_display ... (imgnew.c)
                get_frame_no (irafimtl.c)
                strcpy
                write_imtool_connection (irafio.c)
                read_connection ... (ctrlcntn.c)              Used for WCS
                strncmp
                update_wcs ... (irafenv.c)
            case IMCURSOR
              get_frame_no (irafimtl.c)
              send_curpos_to_iraf (iraffdbk.c)
                write_connection
              send_curpos_to_iraf_trigger (iraffdbk.c)
                set_trigger_key_mouse (wndwmaus.c)
                  XQueryPointer
                  XDefineCursor
                  XSync
                  XWarpPointer
                  new_dispboxmouse (wndwmaus.c)
                    XDefineCursor
                set_iraf_key_trigger (mainkey.c)
              set_cursor_from_iraf (iraffdbk.c)
              erase_cursor (csrdraw.c)
                  draw_cursor (csrdraw.c)
                   draw_textcursor
                   set_gc ...
                    XDrawLines
                    XDrawSegments
                    XDrawRectangles
                d_transform (crdtrans.c)
                add_polygon_vertex
                set_annuli_from_file_coords (csrcoord.c)
                  d_transform (crdtrans.c)
                  make_cursor ... (csrshape.c)
                set_cursor_from_file_coords ... (csrcoord.c)
                save_cursor_as_region ... (csrsave.c)
                disp_region
                disp_dispbox ... (display.c)
                disp_cursor (csrdraw.c)
                  draw_annuli (csrdraw.c)
                    set_gc ...
                    XDrawLines
                  draw_cursor... (csrdraw.c)
                d_transform (crdtrans.c)
                draw_magnifier
                label_region_cycle_magnifier (rgnctrl.c)
            case LOOK_FEEL
            case OVERLAY	
              do_overlay_from_imtoool (imtlovrly.c)  For OVERLAY.  Returns
			number of remaining bytes to be read
                read_connection ... (ctrlcntn.c)
                sscanf
                reset_regions
                delete_annuli
                erase_cursor
                set_cursor_from_file_coords
                disp_dispbox
                disp_panbox
                touch_submenu_button
                set_cursor_from_file_coords
                make_new_annulus
                draw_annuli
                set_cursor_file_coords
                save_cursor_as_region
                disp_region
                d_transform
                draw_magnifier
                label_region_cycle_magnifier
                disp_panbox
                disp_dispbox
                draw_on_frame
                vect_on_frame
                display_vect_on_frame
	    case LUT
              new_color_table (clrctrl.c)           For LUT
                fetch_colortable
                set_submenu_toggle
                make_cellstore_from_tables
                XStoreColors
                draw_cgraph
                label_gamma
              new_color_table_download (clrmenu.c)
            case MEMORY
              get_frame_no
              imtool_output (irafio.c)
                bzero
                compact_short_to_byte
                write_connection
                  write_mailbox (ctrlmbox.c)
                    zawrvi
                    zawtvi
                  write_disk
              imtool_input (irafio.c)                   I
                read_connection (ctrlcntn.c)
                  read_mailbox (ctrlmbox.c)
                    zardvi
                    zawtvi
                    fflush
                  read_disk - not VMS
                expand_byte_to_short (irafio.c)
                bcopy
              set_imtool_scale (irafdisp.c)             I
                touch_submenu_button (menuctrl.c)
                  set_gc_with_background
                  ButtonNumber (remote.c)
                  TouchButton
                make_scalemap (sclmap.c)
                  histogram_equalize
                  linear_scale (sclmap.c)
                  wrap_scale (sclmap.c)
                  sqrt_scale (sclmap.c)
                  log_scale (sclmap.c)
                set_imtool_colors (irafdisp.c)
              disp_subpiece (irafdisp.c)               I
                d_transform (crdtrans.c)
                set_edges (crdset.c)
                set_dispoff
                map_dispbox (display.c)
                  unset_blink
                  make_halftone_display
                  clear_margins (display.c)
                  map_buf_repzoom_adj
                  map_buf_subzoom_adj
                  map_buf_repzoom 
                  map_buf_subzoom (disppxmp.c)
                disp_dispbox (display.c)
                  disp_window (display.c)
                    set_gc_with_background
                    set_gc
                    XPutImage
                  XSync
                  disp_regions (rgndraw.c)
                    disp_region (rgndraw.c)
                      set_region_gc (rgndraw.c)
                        set_edit_gc
                        set_text_gc
                        set_gc ...
                      draw_region (rgndraw.c)
                        draw_annuli ... (csrdraw.c)
                        draw_cursor
                        draw_region_label
                        XDrawPoint
                      label_annuli (rgndraw.c)
                        label_region (rgndraw.c)
                          mark_include (rgndraw.c)
                          draw_region_label
                          XDrawLine
                          draw_region_label
                      label_region
                  disp_cursor... (csrdraw.c)
                new_panimage ... (imgnew.c)
                disp_panbox
              map_dispbox ... (display.c) fudge
              read_connection ... (ctrlcntn.c)
    ZPending
    ZSelectAsyncInput
    sys$waitfr
    sys$clref
    control_cursor (csrctrl.c)
      point_region (rgnctrl.c)
        region_indicated_by_pointer
        unsave_region ... (rgndrop.c)
        disp_dispbox
        set_cursor_file_coords
        save_cursor_as_region (csrsave.c)
          copy_annulus (csrsave.c)
            copy_cursor
            copy_annulus
        disp_region
      report_cursor_inf (csrcoord.c)
        switch
      note_trigger_key_position
      save_textcursor
      delete_annulus (csrgrab.c)
        size_annulus
        on_annulus
        remove_annulus (csrgrab.c)
          draw_cursor ... (csrdraw.c)
          free_cursor
      grab_polygon_vertex (csrpoly1.c)
        draw_cursor
        on_polygon_vertex
        closest_polygon_line
        add_polygon_vertex
      start_size
      set_polygon_file_coords
      set_cursor_file_coords ... (csrcoord.c)
      update_annuli_centers
      note_trigger_key_position
      make_new_annulus (csranli.c)
        copy_cursor
      draw_annuli ... (csrdraw.c)
      report_cursor_info (csrcoord.c)
        cursor_area
      disp_dispbox ... (display.c)
      XSync
      XCheckIfEvent
      move_annuli (csranli.c)
        draw_annuli ... (csrdraw.c)
      move_cursor (csrmove.c)
        draw_cursor ... (csrdraw.c)
        move_textcursor
        set_polygon_hashmarks
      size_annuli (csrgrab.c)
        draw_cursor ... (csrdraw.c)
        size_annulus
        grab_annulus
        make_cursor
      size_cursor (csrmove.c)
        angle_cursor
        draw_cursor
        switch
        size_polygon
        draw_cursor
        make_cursor
      angle_cursor (csrmove.c)
        atan2
        draw_cursor
        make_cursor
      request_delete_polygon_vertex (csrpoly1.c)
        on_polygon_vertex
        delete_polygon_vertex
        draw_cursor
        delete_polygon_vertex
      disp_dispbox ... (display.c)
    control_color (clrctrl.c)
      XSync
      XCheckIfEvent
      vary_colors
    control_cgraph
    control_pan (panctrl.c)
      print_table ... (mgfytabl.c)
      i_transform (crdtrans.c)
      d_transform (crdtrans.c)
      draw_magnifier
      XSync
      XCheckIfEvent
      reset_tdisp
      new_pancursor
      panedge_zoom (crdtemp.c)
        i_transform
        choose_zoom
      XCheckWindowEvent
      set_tdisp
      new_display (imgnew.c)
        set_disptran
        load_mainbuf
        new_pancursor
        new_scalemap
        combine_transform
        set_edges
        set_dispoff
        adjust_cursor_coords
        set_magnifier
        map_dispbox
        disp_dispbox
      show_dispcoords (panimage.c) Gives Center: X= , Y= , Blocking:
        d_transform (crdtrans.c)
    control_blink
    set_gc_with_background
    control_buttonbox (menuinit.c)
      ButtonControl (event.c)
        btn_Event (event.c)
          btn_Event
        btn_Control (event.c)
          btn_PutImage
          btn_PushButton
          btn_ReleaseButton
          btn_DrawButton
          fprintf
          XPending
          XNextEvent
        XPutBackEvent
    dispatch_select (mainslct.c)  This is where button presses are interpreted
      grab_keys_for_textcursor (mainkey.c)
      switch
      select_environment (mainslct.c)  This responds to the track and 
                                       coord buttons being pressed
        say_goodbye
        raise_windows (wndwinit.c)
        get_new_cmd
        screen_dump
      select_scalemap  (sclctrl.c)
        save_blink
        new_scalemap ... (sclctrl.c)
        map_panbox
        disp_panbox
        map_dispbox ... (display.c)
        disp_dispbox ... (display.c)
      select_pan (panctrl.c)
        reset_tdisp
        set_tdisp (crdtemp.c)
        new_pancursor
        XSync
        new_display
        show_dispcoords
      select_cursor (csrslct.c)
        grab_keys_for_textcursor
          make_cursor ... (csrshape.c)
          draw_annuli
          free_cursor
        delete_annuli (csranli.c)
        set_submenu_toggle
        disp_dispbox ... (display.c)
        erase_cursor
        clear_textcursor
        enable_annuli_button
        enable_ortho_button
        make_cursor ... (csrshape.c)
        start_polygon
        new_textcursor
        collapse_polygon
        make_new_annulus
        erase_cursor
        make_cursor ... (csrshape.c)
        disp_cursor ... (csrdraw.c)
      select_color (clrctrl.c)
        invert_rgb
        reinit_color
        new_color_table (clrctrl.c)
          fetch_colortable (clrmenu.c)  Selects built-in LUTs or files
            read_color_file (clrmenu.c) Called if a file is used.  Return is
					pointer to ColorTable
              init_edit_popup (editctrl.c)
                init_popwin
                get_edit_struct
                init_edit_struct
                load_edit_struct
              open_input_file
              parse_color_file (clrread.c)  Takes file pointer and returns
					    pointer to ctable
	        advance_to_ascii
                strncmp
                fprintf
                parse_color_table (clrread.c)  Reads one color
                  check_parens
                  next_token
                  advance_to_ascii (clrread.c)
                    fgets
                    fprintf
                    find_token (clrread.c)
                    strcpy
                    isalpha
                    prep_alpha
                    check_parens
                  fprintf
                  isalpha
                  prep_alpha (clrread.c)
                  strncmp
                  sscanf
            write_color_file
              init_edit_popup
              open_output_file
              XBell
              fprintf
              print_one_color (clrmenu.c)
                fprintf
              fclose
            load_newtable (clrmenu.c)  Gets called if built-in or file
              load_subtable (clrmenu.c)
          set_submenu_toggle
          make_cell
          store_from_tables
          XStoreColors
          draw_cgraph
          label_gamma
      select_halftone
      select_region (rgnctrl.c)
        cycle_regions (rgnctrl.c)
          delete_annuli ... (csranli.c)
          disp_dispbox ... (display.c)
          erase_cursor
          copy_region_to_cursor (csrsave.c)
            memcpy
            copy_annulus
            copy_polygon_region_to_cursor
          reload_textcursor
          disp_cursor ... (csrdraw.c)
          d_transform (crdtrans.c)
          draw_magnifier
          label_region_cycle_magnifier (rgnctrl.c)
          touch_submenu_button ... (menuctrl.c)
          enable_annuli_button
          set_submenu_toggle
          enable_ortho_button
          enable_annuli_button
        toggle_region_labeling
        match_region (csrsave.c)
        unsave_region ... (rgndrop.c)
        disp_dispbox ... (display.c)
        toggle_region_visibility
        reset_regions (rgnctrl.c)
          free_cursor
          disp_dispbox ... (display.c)
        write_regions
        read_regions
      new_dispboxmouse
    switch
    redraw_window (wndwinit.c)
      disp_dispbox ... (display.c)
      redraw_magnifier ... (mfgyctrl.c)
      draw_colorbar
      display_graphbox
      draw_cgraph
      label_color_graph
      draw_colorbar
      label_colorbar
      disp_panbox
      show_filename (imgnew.c)
    magnify_disp (mgfyctrl.c)    This is where the effects of track are seen
      XSync
      XCheckWindowEvent
      label_file_coords_proportional (mgfyctrl.c)
        set_edit_gc
        d_transform (crdtrans.c)
        draw_proportional_number
        get_pixel_val (mgfyval.c)
          i_transform (crdtrans.c)
        integer_string
        real_string
      label_file_coords (mgfyctrl.c)             B, F, I
        set_edit_gc
        d_transform (crdtrans.c)
        XDrawImageString
    magnify_pan (mgfyctrl.c)
      XSync
      XCheckWindowEvent
      draw_magnifier
    map_graphbix
    key_response (mainkey.c)
      XLookupString
      trigger_curpos_to_iraf (iraffdbk.c)           B, F, I
        i_transform (crdtrans.c)
        move_annuli (csranli.c)
          draw_annuli ... (csrdraw.c)
        update_annuli_centers
        save_cursor_as_region ... (csrsave.c)
        add_polygon_vertex
        set_cursor_file_coords (csrcoord.c)
          d_transform (crdtrans.c)
        make_cursor ... (csrshape.c)
        disp_dispbox ... (display.c)
        disp_region
        send_curpos_to_iraf ... (iraffdbk.c)
        note_trigger_key_position
        set_trigger_key_mouse
        set_iraf_key_trigger
      textcursor_keyentry
      magnify_pan
      magnify_disp ... (mgfyctrl.c)
      XSync
      XWarpPointer
      disp_panbox
      disp_dispbox ... (display.c)
      raise_windows
      get_new_cmd
        init_edit_popup
        get_edit_input (editctrl.c)
          map_popwin
          XClearWindow
          set_edit_gc
          XDrawImageString
          draw_new_string
          XNextEvent
          switch
          adjust_desktop
          set_edit_gc
          draw_new_string
          redraw_edit_string
          redraw_window
          bcopy
        new_command (cmdnew.c)
          clear_params (cmdnew.c)
          make_argv
          form_tokens
          parse_cmdline (cmdparse.c)                    F
            init_cmdline (cmdnew.c)              
              string_cmdline
            parse_display
            parse_filetype (cmdimage.c)
              usage
            parse_connection (cmdimage.c)               F
              strcmp
              open_imtool_connection (irafio.c) 
              close_imtool_connection            
              rename_imtool_connection           
                calloc_errchk
                strcpy
              si_init (ctcmd.c)                  
                new_display
                make_scalemap ...  
              open_rtsock_connection (rtio.c)   
                open_connection ...
                read_rtio_packet
                  read_connection ... (ctrlcntn.c)
                  close_connection - not VMS
                    close_mailbox
                    close_pipe - not VMS
                    close_socket - not VMS
                    ButtonSelectMask - not VMS
                    open_connection - not VMS ...
                    free - not VMS
                    close_connection - not VMS
                  flush_connection
                    flush_mailbox
                      read_mailbox
                    flush_pipe - not VMS
                    flush_socket - not VMS
                  si_command
                open_connection ...
              open_rtfifo_connection                
                open_connection ...
            parse_fileread (cmdimage.c)
              usage
            parse_rotate
            parse_scale
            parse_color
            parse_etc (cmdparse.c)
            parse_filename (cmdimage.c)
              usage
          free_argv
          reinit_color
          check_image
          redo_displays (cmdnew.c)
            new_scalemap (sclctrl.c)                     F
              new_histogram
              make_scalemap ... (sclmap.c)  
              color_logo
              set_imtool_colors (irafdisp.c)
            map_panbox
            disp_panbox
            map_dispbox ... (display.c)
            disp_dispbox ... (display.c)
            redraw_magnifier (mgfyctrl.c)
              d_transform (crdtrans.c)
              draw_magnifier
          new_file (cmdnew.c)
            init_image (imgread.c)                      F
              init_fits (readfits.c)
              init_irafimh
              init_saoccd
              get_fbconfig (irafenv.c)
	        getenv
                fopen
                sscanf
              init_img
                set_coordsys
                set_imgtran
              init_dispcen
            init_imagebuf
            set_tdisp (crdtemp.c)
            new_display (imgnew.c)                      F
              set_disptran
              load_mainbuf (imgnew.c)
                set_buftran
                set_fbuftran
                bzero
                load_image (imgread.c)                  F
                  i_transform (crdtrans.c)
                  read_array (readarr.c)
                    open_disk (ctrldisk.c) ...
                    lseek_disk ...
                    read_data
                      read_disk ...
                    scale_data_u1
                    scale_data_i2 (readint.c)
                    scale_data_u2
                    scale_data_i4
                    scale_data_r4
                    ieee_vax
                    scale_data_r8
                    close_disk ...
                  load_saoccd
                  load_einstein
                  load_rosat
                  load_logo
                  rotate_buf (imgtrans.c) ...
                free
                show_filename (imgnew.c)
            new_panbox (panwndw.c)
              init_panbox_dimensions
              XMoveResizeWindow
              XResizeWindow
              init_panbox_coords
              init_panbuf
              new_panimage ... (imgnew.c)                 F
              new_pancursor
            disp_panbox
          touch_submenu_button ... (menuctrl.c)
          redo_magnifier
      say_goodbye
      print_table (mgfytabl.c)
        get_key_buf_coords
        set_table_params (mgfytabl.c)
        output_column_labels
        output_pixval_table (mgfytabl.c)
          get_pixel_val ... (mgfyval.c)
            i_transform
          integer_string
          real_string
      ascii_region (rgnctrl.c)                      text on overlay plane
        set_cursor_file_coords ... (csrcoord.c)
        save_cursor_as_region ... (csrsave.c)
        disp_region
        region_indicated_by_pointer
        unsave_region (rgndrop.c)
        disp_dispbox ... (display.c)
    adjust_desktop
    adjust_graphbox
  say_goodbye ...
    free_gc ...
    XCloseDisplay
    exit


CLRCTRL.C;2
CLRMENU.C;5
CMDDISP.C;3
CMDPARSE.C;9
CTRLGC.C;3
DRAWVECT.C;114
IEEEVAX.C
IMGCHECK.C;5
IMGNEW.C;7
IMGPARAM.C;11
IMGREAD.C;8
IMTLOVRLY.C;121
IMTOOLRC.;3
IRAFDISP.C;19
IRAFFDBK.C;16
IRAFIMTL.C;36
IRAFIO.C;11
IRAFPIPE.C;13
MAINEVNT.C;8
MGFYCTRL.C;23
MGFYVAL.C;2
READARR.C;18
READFITS.C;4
READINT.C
RGNCTRL.C;3
RGNDRAW.C;6
[.HFILES]CONSTANT.H
[.HFILES]CONTROL.H
[.DEFS]COLORMAP.DEF
			FILES MODIFIED BY DHG

PROBLEM:  
IEEE-754 32-bit floating point numbers contained in FITS files
were being displayed with pixel intensities too small by a factor of 4.
SOLUTION:  May - July, 1993
The parameter ARR_IEEER4 was added to the file [.HFILES]CONSTANT.H.
The file MGFYVAL.C, Subroutine get_pixel_val was modified to respond 
to ARR_IEEER4.  Action is the same as for ARR_R4.
The file READFITS.C, Subroutine init_fits was modified to by replacing 
ARR_R4 with ARR_IEEER4.
The file MGFYCTRL.C, Subroutine label_file_coords was modified by adding 
the parameter ARR_IEEER4.  Action is the same as for ARR_R4.
The file READARR.C, Subroutine read_array was modified to respond to case
ARR_IEEER4 and call subroutine ieee_vax.
The new file IEEEVAX.C was created and its name added to MAKE.LST.

PROBLEM:  May 6, 1993
Numbers with exponential notation were being cut off at the right end of 
the tracking window on a VAXstation with 100 dpi.
SOLUTION:
The file MGFYCTRL.C, Subroutine label_file_coords was modified by 
replacing the number 26 with 28 in the call to XDrawImageString.

PROBLEM:
If a file name with a capitalized FITS extension was entered, it was ignored.
SOLUTION:  May 6, 1993
The file IMGCHECK.C, Subroutine check_image was modified to allow 
recognition of a capitalized FITS extension.

PROBLEM:
There was no provision for referencing the center of the first pixel
as 1.5, 1.5, as in the MIIPS convention.
SOLUTION:  August 3, 1993
The subroutine parse_rotate in file CMDDISP.C was modified to make
img.index_base = 0, 1, and 2, for the switches zero, half, and one, 
respectively.  These correspond to an image display, the IRAF convention,
and the MIIPS convention, respectively.  Note that the former "one" switch
now means something different.  The effect of the former "one" switch is
accomplished by use of the "half" switch.  This relationship is more intuitive.
The subroutine init_img in IMGPARAM.C was modified to respond to values
of image->index_base = 0, 1, and 2, and adjust the starting pixel 
coordinates in the corner of the map accordingly.
The subroutine usage, in CMDPARSE.C was modified to print a message
about the switches zero, half, and one, which are for the starting 
corner equal to (0.0, 0.0), (0.5, 0.5), and (1.0, 1.0), respectively.

PROBLEM:  
When a single line of data with a number of pixels less than 
the number of bytes in a line of the buffer was sent, the image appeared
in the pan box and zoom box, but not in the display box.  If the image 
was panned zoomed or panned, the image was then displayed.
SOLUTION:  August 4, 1993
It was observed that coord->bd.dstYhght in map_buf_subzoom
was always zero under these conditions, which then prevented the display
buffer from being loaded.  This error propagated from imtool_input in
IRAFIO.C, where *y2 was being prevented from incrementing.  The incremental
increase now has a minimum value of 1.
 
PROBLEM:  
When a non-IRAF image processing program, e.g., MIIPS, used the 
imtool protocol, the text "(IRAF)" appeared below the file name.  
SOLUTION:  August 4, 1993
The constant IOP_MIIPS was introduced into the file [.HFILES]CONTROL.H
In the subroutine imtool_response, in IRAFIMTL.C, the parameter imhead->t
in the unused imtool header labeled, ZOOM/PAN, is loaded into 
control.look_and_feel.
In the subroutine show_filename, in IMGNEW.C, an if statement involving
img.file_type == SOP_Imtool && control.look_and_feel == IOP_MIIPS is used
to determine whether to write the text "(MIIPS)".

PROBLEM:
When a FITS file was loaded prior to an array type file, the scaling and 
bias from the FITS file were retained, causing the pixel intensity values 
to be incorrect for the array type file.
SOLUTION:  August 14, 1993
In the subroutine init_image, in IMGREAD.C, img.fscaled was set equal to 0,
for the case image.file_type=SOP_Array.

PROBLEM:
If a file with a range of values was loaded via the imtool protocol and the
cursor was set on the pixel with the actual minimum or maximum intensity 
value, or the IRAF clipped minimum and maximum intensity value, the
intensity value displayed was prefixed with < or >, respectively.
SOLUTION:  August 10, 1993
In subroutine label_file_coords, in MGFYCTRL.C, the format statement was 
changed from < and > to <= and >=, respectively.

PROBLEM:
If the SAOimage desktop width was larger than the width of the buffer, under an
Imtool load, the image would be initially aligned with the left side of the
desktop, be rolled over, and display incorrect coordinates.  Operation of
the zoom or pan controls would then correct the display.
SOLUTION:  August 14, 1993
In subroutine disp_subpiece in IRAFDISP.C, the statement if( coord.bd.block 
< 0 ) was removed so that set_dispoff(...) is always called.

PROBLEM:
When the cursor coordinates are sent back to the communicating program via
the Imtool protocol, only the file coordinates are included.  MIIPS, for
example, needs desktop window and frame buffer coordinates as well.
SOLUTION:  August 16, 1999
The subroutine trigger_curpos_to_iraf in IRAFFDBK.C was modified to calculate,
encode into ASCII, and send the necessary coordinates.

PROBLEM:
When several images are loaded into the frame buffer, such as is possible with
MIIPS, if the previous images were being displayed at a non unity zoom, the
new additional image would come up at unity zoom and the old images would be
displayed at their old zoom.
SOLUTION:  September 6, 1993
In subroutine imtool_newimage in IRAFIMTL.C, the image was redrawn if 
the old zoom was not unity.

PROBLEM:
In MIIPS, the capital lock key is often used.  If not unlocked this would cause
tracking of coordinates and the magnifier to stop.  However, tracking was
desired to be on even with the capital lock key on.
SOLUTION:  September, 1993
In subroutine control_event_loop in MAINEVNT.C, when control.look_and_feel
equals IOP_MIIPS, only the ShiftMask is used, not both that and the LockMask.

PROBLEM:
When SAOimage is started with switch +magnifier, magnifier tracking does not
take place.
SOLUTION:  September 4, 1993
In subroutine parse_etc in CMDPARSE.C, the logic for magnifier tracking was
corrected.

PROBLEM:
It was desired to have several kinds of cursors be displayed on the screen
under external control.  It was also desired to write into the displayed 
image at locations where editing had most recently been done, outlining these
areas with circles or rectangles.
SOLUTION:  August, 1993
A new imhead.subunit equal to 13 was introduced in read_imtool_packet in 
IRAFPIPE.C, and in imtool_response in IRAFIMTL.C, corresponding to OVERLAY.
A new subroutine, do_overlay_from_imtool, in IMTLOVRLY.C is called from
imtool_response.  This subroutine interprets the data sent via the Imtool
protocol and calls the routines which draw and erase the various 
built in cursors in various colors.  Annuli and regions may be drawn as well.
It also calls the new subroutine draw_on_frame in DRAWVECT.C which can
draw circles and rectangles in the frame buffer.  The actual drawing of
vectors in this buffer is carried out in the new subroutine vect_on_frame in 
DRAWVECT.C
The subroutine reset_regions in RGNCTRL.C was declared as not being static,
in order that it could be called from do_overlay_from_imtool.
In subroutines label_region and label_region_cycle_magnifier in RGNDRAW.C, 
adjustments of 0.5 pixels are made when control.look_and_feel equal IOP_MIIPS
so that the region cursor coordinates are displayed correctly.  

PROBLEM:
There wasn't a way to load a new color lookup table into SAOimage from a
connecting program.  Also, the available lookup tables did not display enough
contrast between closely spaced intensity levels, and did not display enough
rollover.
SOLUTION:  October 21, 1994
In the file [.DEFS]COLORMAP.DEF, a new lookup table was installed with adjacent 
colors having high constrast and exhibiting 5 cycles of rollover.  This was
given the name e_map.  Another lookup table, black and white with 8 cycles
of rollover and named f_map was also added.  The preceding 2 color tables,
c_map and d_map, were uncommented.  In subroutine fetch_colortable in 
CLRMENU.C, e_map and f_map were registered as MOP_Init_I and MOP_Init_J.
Also a new subroutine, new_color_table_download, was introduced in CLRMENU.C.
The 2 existing color tables that were newly uncommented, were registered as 
MOP_Init_G and MOP_Init_H.  MOP_Init_J was registered in CONSTANT.H.
In the subroutine imtool_response, in IRAFIMTL.C, the case LUT was
introduced to give remote access to the color LUTs.  The parameter imhead->z
contains the MOP_Init_x values which are passed to new_color_table.
Because new_color_table was declared as static in CLRCTRL.C, this module
was changed also.

PROBLEM:
On VMS systems, when SAOimage is launched, an annoying message about not 
finding font 6X13 received.  If the etc and new buttons are clicked, the 
message "Could not open font:  9x15" is displayed.
SOLUTION:  September 25, 1993
In subroutine open_font in file CTRLGC.C, ifndef VMS is used prevent this 
message.

PROBLEM:
On an SGI, byte_swap in READINT.C was not being recognized because both
a variable and a subroutine had this name.  
SOLUTION:  November 29, 1995
The name of the subroutine was changed to byte_swap_.

PROBLEM:
On a LINUX system, a segmentation fault resulted when cursor positions were
requested in SAODEMO4 and SAODEMO6.
SOLUTION:  January 6, 1996
Albert Hybl found that in IRAFFDBK.C, the array string[40] was too small
by 3 bytes.  The declaration was changed to char string[43].

PROBLEM:
There is no way to differentiate the enhanced version of SAOimage from the
original when looking at the screen.
SOLUTION:  August 16, 1999
The labels in CLRMENU.C, CTRLUSKT.C, DISPPSCT.C, HISTLIST.C, and 
WNDWINIT.C were modified.

img->file_type is used in
cmdimage.c  
imgcheck.c  SOP_SAD assigned for .SAD extension in subroutine check_image
imgnew.c  see below
imgread.c  nothing done yet
irafdisp.c SOP_IMTOOL is established here
maininit.c  no change
rgnctrl.c
rgnread.c
rtcmd.c
sclctrl.c

sop_imtool is referred to in:
imgcheck.c
imgnew.c  else if incorporated to produce (MIIPS) for 
          control.look_and_feel == IOP_MIIPS in subroutine show_filename
imgread.c
irafdisp.c
rgnread.c
rgnwrite.c

irafimtl.c control.look_and_feel = imhead->t & 077in irafimtl.c in
           subroutine imtool_response 

SOP_SAD introduced in CONSTANT.H
Unfortunately, img.file_type is used for file types, and image processing
  programs, and connection protocols (SOP_Imtool).


		POSSIBLE INITIAL DIFFICULTIES UNDER OpenVMS

1.  Starting Situation:
	1)  In DISK$DISK_1:[X_WINDOWS.SAOIMAGE]SETUP.COM, we have 
$ SAOIMAGE :== $SAODIR:SAOIMAGE.EXE -G 886x886-2+134 -Q -one +coord +magnifier
	2)  In SYS$MANAGER:SYLOGIN.COM we have 
	@DISK$DISK_1:[X_WINDOWS.SAOIMAGE]SETUP.COM

    Result:
	1)  If we enter SAOIMAGE, the SAOimage window comes up and
	messages are written to the calling window.  The calling window
	does not return to the DCL prompt unless a Control/C is issued.
	At that point, the response of SAOimage ceases, except that the
	close button will still operate.  If etc and quit are selected 
	in SAOimage, however, the DCL prompt will return.  If SAOIMGE
	is entered a second time, the same window and icon are used.
	Commands, as listed in the "User Manual for SAOimage" will be 
	honored when they follow SAOIMAGE.
	2)  If we enter SPAWN/NOWAIT/IN=NL: SAOIMAGE, SAOimage comes up
	and messages are written to the calling windows.  The calling 
	window will return to the DCL prompt if a CR is issued.  SAOimage
	will still remain functional at this point.  If the same command
	is entered a second time, the error "alternate colormap not yet 
	supported" will be sent to the screen.  If etc and quit are selected
	in SAOimage, no error results.  IRAF can send a file to SAOimage in
	this mode.
	3)  If SPAWN/NOWAIT/IN=NL: SAOIMAGE is entered as an application
	definition in the Session Manager, no window comes up.
	4)  If SAOIMAGE is entered as an application definition in the 
	Session Manager, a window will come up, but no values are sent to
	any window.  IRAF can send a file to SAOimage, however.
	5)  If the foreign definition 
        $ SAO :== SPAWN/NOWAIT/INPUT=NL: SAOIMAGE
	is created in SYS$MANAGER:SYLOGIN.COM, SAOimage performs correctly.


			DESCRIPTION OF SOURCE FILES

CLRALLOC.C
 * Module:      clralloc.c (Color Alloc)
 * Purpose:     Allocate and free colors
 * Subroutine:  alloc_color()                   returns: int
 * Subroutine:  free_color_cells()              returns: void
 * Xlib calls:  XAllocColorCells(), XFreeColors()

 * Subroutine:  alloc_colors
 * Purpose:     Allocate color cells with and overlay plane if possible
 * Returns:     1 if allocated an acceptable number of cells, else 0
 * Method:      Try for at least min cells in default colormap, if failed
 *              try to create a private colormap.

 * Subroutine:  alloc_color_cells
 * Returns:     1 if alloc's at least min cells, else 0
 * PostState:
 * Xlib calls:  XAllocColorCells()
 * Method:      Grab as many cells as possible with overlay as specified

 * Subroutine:  free_color_cells
 * Purpose:     un-alloc alloc'd color map cells
 * Xlib calls:  XFreeColors()

 * Subroutine:  create_colormap
 * Purpose:     Create a private colormap with some of the default map's colors
 *              copied into it.  The copied colors are static (reducing the
 *              number of available colors should the user attempt to increase
 *              them later on.

CLRCTRL.C
 * Module:      clrctrl.c (Color Control)
 * Purpose:     Control colors
 * Subroutine:  select_color()                  returns: void
 * Subroutine:  control_color()                 returns: void
 * Subroutine:  invert_rgb()                    returns: void
 * Subroutine:  reinit_color()                  returns: void
 * Xlib call:   XStoreColors()

 * Subroutine:  select_color
 * Purpose:     Things to do when a buttonbox color menu button is selected

 * Subroutine:  control_color
 * Purpose:     Alter color based on mouse events

 * Subroutine:  new_color_table
 * Purpose:     Install a new pre-defined color table

 * Subroutine:  invert_rgb
 * Purpose:     Reverse all colors at once (respond to invert button)

 * Subroutine:  reinit_color
 * Purpose:     Make necessary adjustment after a request to change use of
 *              color resources
 
CLRHARD.C
 * Module:      clrhard.c (Color Hard)
 * Purpose:     Get common named colors
 * Subroutine:  init_hard_colors()              returns: void
 *              lookup_cursor_colors()          returns: void
 *              alloc_cursor_cell_color()       returns: int
 *              free_cursor_cell_color()        returns: void
 * Xlib calls:  XAllocNamedColor(), XAllocColor()
 * Xlib calls:  XFreeColors(), XLookupColor()

 * Subroutine:  init_hard_colors
 * Purpose:     Set up basic hardware colors
 The basic colors for cursors is set up in this subroutine

 * Subroutine:  lookup_cursor_colors
 * Purpose:     Get color parameters from named cursor colors

 * Subroutine:  alloc_cursor_cell_color
 * Purpose:     Allocate defined colors for cursors and overlays

 * Subroutine:  free_cursor_cell_color
 * Purpose:     Free cell color overlay colors

 * Subroutine:  free_readonly_color
 * Purpose:     Free cursor color if it is not one of the essential ones

 * Subroutine:  get_hard_color
 * Purpose:     Alloc a read-only color cell with a common color

 * Subroutine:  lookup_color
 * Purpose:     Set up the rgb values in the Xcolor

 * Subroutine:  alloc_hard_color
 * Purpose:     Given rgb values, set the pixel

CLRINIT.C
 * Module:      clrinit.c (Color Initialize)
 * Purpose:     Allocate the needed colors
 * Subroutine:  init_color()                    returns: void
 * Xlib calls:  XGetVisualInfo(), XFree()

 * Subroutine:  init_color
 * Purpose:     Claim and set up colors (and do any needed initial work)

 * Subroutine:  init_visual
 * Purpose:     Get basic info about the color hardware on hand

 * Subroutine:  verify_pseudocolor
 * Purpose:     Verify that server can provide a satisfactory colormap
 * Returns:     1 if yes, else 0
 * PostState:   Fills in visual info in passed vinfo
 * Xlib calls:  XGetVisualInfo(), XFree()

CLRMAP.C
 * Module:      clrmap.c (Color Map)
 * Purpose:     Set up the cell storemap XColor array
 * Subroutine:  make_cellstore_from_tables()    returns: void
 * Subroutine:  make_cellstore_from_cellmaps()  returns: void
 * Subroutine:  make_cellmap_from_table()       returns: void
 * Xlib calls:  none

 * Subroutine:  make_cellstore_from_table
 * Purpose:     Fill the color map according to the color vertex tables

 * Subroutine:  make_cellstore_from_cellmaps
 * Purpose:     Fill XColor storemap from individual cellmaps

 * Subroutine:  make_cellmap_from_table
 * Purpose:     Fill cellstore values based on table values
 * Method:      Set map values using interpolated ramps between map entries

CLRMENU.C
 * Module:      clrmenu.c (Color Menu)
 * Purpose:     Read and Write file and internally stored color tables
 * Subroutine:  fetch_colortable()              returns: int
 * Xlib calls:  none

 * Subroutine:  fetch_colortable
 * Purpose:     Get a new pre-defined color table and load it for use
 * Returns:     1 if succeeded, else 0
 
 * Subroutine:  read_color_file
 * Purpose:     Open and read a color table file, and load it into the
 *              current color table.

 * Subroutine: write_color_file
 * Purpose:    Open and write a color table file

 * Subroutine:
 * Purpose:

 * Subroutine:  load_newtable
 * Purpose:     Load an internally stored color table for use

 * Subroutine:  load_subtable
 * Purpose:     Load one color of the internal color table

CLRREAD.C
 * Module:      clrread.c (Color Read)
 * Purpose:     Read and Write file and internally stored color tables
 * Subroutine:  parse_color_file()              returns: int
 * Xlib calls:  none

 * Subroutine:  parse_color_file
 * Purpose:     Parse values after color identifier

 * Subroutine:  parse_color_table
 * Purpose:     Read color table entries for one color
 * Note:        Values may start with word "gamma" and its value

 * Subroutine:  advance_to_ascii
 * Purpose:     Get next processable line, and prepare a copy for processing
 * Returns:     Positive character count if string starts with a name
 *              Negative val if string starts with a number or paren
 *              0 if file ended, or first character was neither char nor num

 * Subroutine:  find_token
 * Purpose:     Point at first non-space character if it might be parsable
 * Returns:     index of character, or -1 if line ends or is comment

 * Subroutine:  prep_alpha
 * Purpose:     Convert all characters to upper case and null terminate word
 * Returns:     Number of characters in the word

CLRSETUP.C
 * Module:      clrsetup.c (Color Setup)
 * Purpose:     Set parameters for the current color mode
 * Subroutine:  init_overlay_color()            returns: void
 * Subroutine:  init_cell_color()               returns: void
 * Subroutine:  init_halftone_color()           returns: void
 * Xlib calls:  XStoreColors()

 * Subroutine:  init_overlay_color
 * Purpose:     Set up color parameters unique to overlay type usage
 * Xlib calls:  XStoreColors()

 * Subroutine:  init_cell_color
 * Purpose:     Set up color parameters unique to cell usage without overlay
 * Xlib calls:  XStoreColors()

 * Subroutine:  init_halftone_color
 * Purpose:     Initialize color parameters for halftone mode

 * Subroutine:  init_cellstore
 * Purpose:     Set the pixel values in the color cellstore

 * Subroutine:  copy_xcolor_rgb
 * Purpose:     Copy the red, green, and blue valuesto another XColor

CLRVARY.C
 * Module:      clrvary.c (Color Vary)
 * Purpose:     Interactive color manipulation keyed to mouse position
 * Subroutine:  vary_colors()                           returns: void

 * Subroutine:  vary_colors
 * Purpose:     Modify colors as per mode and the mouse position

 * Subroutine:  vary_contrast_and_bias
 * Purpose:     change color table cell_levels as per new contrast and bias

CMDDISP.C
 * Module:      cmddisp.c (Command Display)
 * Purpose:     Set options from command line pertaining to display
 * Subroutine:  parse_rotate()                  returns: int
 * Subroutine:  parse_scale()                   returns: int
 * Subroutine:  parse_color()                   returns: int
 * Subroutine:  parse_display()                 returns: int
 * Xlib calls:  none

 * Subroutine:  parse_rotate
 * Purpose:     Parse command line for coordinate adjustment or rotation
 *              parameters
 * Returns:     1 if one of its parameters was found, else 0

 * Subroutine:  parse_color
 * Purpose:     Parse command line for display color parameters
 * Returns:     1 if one of its parameters was found, else 0

 * Subroutine:  parse_scale
 * Purpose:     Parse command line for image scaling parameters
 * Returns:     1 if one of its parameters was found, else 0

 * Subroutine:  parse_display
 * Purpose:     Parse the command line for window and server parameters
 
CMDIMAGE.C
 * Module:      cmdimage.c (Command Image File)
 * Purpose:     Set options from command line
 * Subroutine:  parse_filename()                        returns: int
 * Subroutine:  parse_filetype()                        returns: int
 * Subroutione: parse_fileread()                        returns: int
 * Subroutione: parse_connection()                      returns: int
 * Xlib calls:  none

 * Subroutine:  parse_filename
 * Purpose:     Parse commandline to find an image file name

 * Subroutine:  parse_filetype
 * Purpose:     Parse command line for image file type

 * Subroutine:  parse_fileread
 * Purpose:     Parse command line for image file reading parameters

 * Subroutine:  parse_connection
 * Purpose:     Parse command line for socket or pipe connection stuff

CMDNEW.C
 * Module:	cmdnew.c (Command New)
 * Purpose:	Orchestrate remembering and forgeting commandline arguments
 * Subroutine:	init_cmdline()			return: void
 * Subroutine:	get_new_cmd()			return: void
 * Xlib calls:	none

 * Subroutine:	init_cmdline
 * Purpose:	Save the original command line in a static string for use
 *		as an initial command line by get_new_command
 * Called by:	parse_cmdline() in CmdParse.c

 * Subroutine:	get_new_cmd
 * Purpose:	Enter a new command line and respond to it.
 * Called by:	key_response() in MainKey.c
 * Called by:	select_environment() in MainSelect.c

 * Subroutine:	new_command
 * Purpose:	Given a new command line, parse it and do what is called for
 * Returns:	1 = success, 0 = user decided not to do anything, -1 = error

 * Subroutine:	redo_displays
 * make the new lookup table */
 * refill display buffers with rescaled values and display */

 * Subroutine:	clear_params
 * Purpose:	Undo parameters checked for defaults when loading a new image

 * Subroutine:	reset_dispparams
 * Purpose:	Set the current display parameters for reloading the image

 * Subroutine:	make_argv
 * Purpose:	Allocate space used for commandline

 * Subroutine:	free_argv
 * Purpose:	Free the space used for parsing the command line

 * Subroutine:	form_tokens
 * Purpose:	Break a command string into tokens (mimic initial command line)
 * Returns:	Count of tokens

 * Subroutine:	new_file
 * Purpose:	Having the image record set, do all that is needed to load
 *		a new image file

CMDPARSE.C
 * Module:	cmdparse.c (Command Parse)
 * Purpose:	Set options from command line
 * Subroutine:	parse_cmdline()			returns: int
 * Subroutine:	string_cmdline()		returns: void
 * Subroutine:	usage()				returns: int
 * Xlib calls:	none

 * Subroutine:	parse_cmdline
 * Purpose:	Process options to set filename and change defaults
 * Returns:	-1 on error, 0 OK but no filename, 1 OK and new filename given

 * Subroutine:	parse_etc
 * Purpose:	Parse command line for things settings from the etc menu

 * Subroutine:	string_cmdline
 * Purpose:	Print tokens on one line to be like original command line

 * Subroutine:	usage
 * Purpose:	Print error mesage and list of command line switches
 * returns:	-1
 * Use:		Use to print msg and return -1 to indicate an error:
 * Example:	if(error) return( usage(errmess,argc,argv,i-?,i) );

CRDINVRT.C
 * Module:	crdinvrt.c (Coordinate Invert)
 * Purpose:	Compute reverse transform and unknown transform parameters
 * Subroutine:	invert_matrix()			returns: void
 * Subroutine:	compute_iadd_invert()		returns: void
 * Xlib calls:	none

 * Subroutine:	invert_matrix
 * Purpose:	Compute parameters of the inverse transform
 * Method:	Uses LU decomposition method

 * Subroutine:	compute_iadd_invert
 * Purpose:	Compute the offsets used for integer transforms
 * Method:	Uses matrix inversion

 * Subroutine:	lu_decompose
 * Purpose:	lower upper decompose matrix (in place) for matrix inversion

 * Subroutine:	lu_backsub
 * Purpose:	LowerUpper backsubstitute one column to solve matrix inversion

CRDROT.C
 *
 * Subroutine:	rotate_transform
 * Purpose:	Perform requested transformation of image coordinates
 * Method:	Transform img coords to what they would be without rotation
 * Parameter:	rotcode: 0 = no change
 *		 1, 2, 3 = rotation of 90, 180, and 270 degrees
 *		 4 = flip the Y coordinates (top becomes bottom
 *		 5, 6, 7 = rotate the flipped image 90, 180, and 270 degrees
 * Notes:
 * Sequence is applied before conversions already in imgtofile
 *  - starting with img coords,
 *   A. shift origin of img buffer coordinates to exact center of buffer
 *   B. undo rotation of img buffer (about origin - now at center of buffer)
 *   C. shift origin to where it would be in unrotated buffer
 * As each transform is applied to the front, we apply them in reverse order
 *  the result is, from img->A,B,C,imgtofile(as given)->file

 * Subroutine:	move_mtrx
 * Purpose:	Apply a given linear translation to the passed Transform
 * Parameter:	prior: 1: move, do transform, move, 0: do transform, move
 * Parameter:	ioff: offset of integer coord (i.e. 0.5), needed for prior=1
 * Note:	ioff is not used for turn or flip, as it is assumed that both
 * 		will be bracketed between two moves (to place origin at center)

 * Subroutine:	flip_mtrx
 * Purpose:	Apply a mirror reflection to the passed Transform

 * Subroutine:	turn_mtrx
 * Purpose:	Apply given angular rotation to the passed Transform
 * Note:	the pivot is 0,0 of the passed Transform's coordinate system
 * Exception:	only multiples of 90 degrees are allowed

 * Subroutine:	mult_mtrx
 * Purpose:	Multiply two sets of transformation matrices to produce a
 *		new combined matrix
 * Method:	algorithm is 3x3 matrix multiplication (3rd row is 0 0 1)
 *		[i][j] is sum of products of column j of 1st and row i of 2nd
 * Note:	iadd is computed to be able to transform from integer coords
 *  calculation uses integer input offset of first and float offset of second

CRDSET.C
 * Module:	crdset.c (Coordinate Set)
 * Purpose:	Set up coordinate system parameters and translation matrices
 * Subroutine:	set_coordsys()		returns: void
 * Subroutine:	set_transform()		returns: void
 * Subroutine:	set_imgtran()		returns: void
 * Subroutine:	set_fbuftran()		returns: void
 * Subroutine:	set_buftran()		returns: void
 * Subroutine:	set_edges()		returns: void
 * Xlib calls:	none
 * Notes:
 *  the base coordinate system is the img
 *  coordinate conversions are computed by passing through the img
 *  the img has 0.0, 0.0 as its upper left corner
 *  files often have 0.5,0.5 at lower left corner (index from 1, ioff = 0.0)
 *  disp, buffer, and pan have 0.0,0.0 in upper left corner (ioff = 0.5)
 *  integer values refer to the center of the pixel in its coordinate system
 *  translations always produce a real (float) value output

 * Subroutine:	set_coordsys
 * Purpose:	Set basic params for a coordinate system

 * Subroutine:	set_transform
 * Purpose:	Calculate transforms given where to put A on B
 * Note:	Forward transform is A to B

 * Subroutine:	set_imgtran
 * Purpose:	Set the img-to-file transform

 * Subroutine:	set_fbuftran
 * Purpose:	Set buffer-to-filebuffer transform, should the
 *		two buffers differ.
 * Note:	Two buffers have same dimensions (and are usually the same)

 * Subroutine:	set_buftran
 * Purpose:	Set buffer-to-img transform (& buf-to-file)
 * Note:	adjusts alignment so as not to waste buffer space
 * Note:	edges later used to check whether requested display is
 *		available
 * Exception:	assumes buf is not smaller than disp

 * Subroutine:	set_edges
 * Purpose:	Set up parameter to map image data from src (A) to dst (B)
 *		Set up the edges of dst sys (B) as plotted in src (A)
 * Note:	Used to set up transfer of image data from A to B

CRDSYNTH.C
 * Module:	crdsynth.c (Coordinate Synthesis)
 * Purpose:	Support the computing of transform matrices and shortcuts
 * Subroutine:	invert_transform()		returns: void
 * Subroutine:	compute_iadd()			returns: void
 * Subroutine:	combine_transform()		returns: void
 * Subroutine:	set_trans_speed()		returns: void
 * Xlib calls:	none

 * Subroutine:	invert_transform
 * Purpose:	Create matrix to perform opposite transformation
 *		Given AtoB (old) and Bsys ioff, compute BtoA (new)

 * Subroutine:	compute_iadd
 * Purpose:	Compute the offsets used for integer transforms

 * Subroutine:	combine_transform
 * combine two sets of transform parameters into a single set
 * first and second apply to sequence starting with the input values
 * algorithm is 3x3 matrix multiplication (3rd row is 0 0 1)
 * combination[i][j] is sum of products of column j of 1st and row i of 2nd

 * Subroutine:	set_trans_speed
 * Purpose:	Set parameters for fast integer computation

 * Subroutine:	integer_test
 * Returns:	0 if not possible, 1 for zoom up, -1 for zoom down
 * Purpose:	Test zoom to determine whether it could be computed
 *		with integer math

CRDTEMP.C
 * Module:	crdtemp.c (Coordinate Temporary)
 * Purpose:	Calculate display coordinates for pan and zoom
 * Subroutine:	set_tdisp()			returns: void
 * Subroutine:	reset_tdisp()			returns: void
 * Subroutine:	set_disptran()			returns: void
 * Subroutine:	panedge_zoom()			returns: void
 * Subroutine:	set_dispoff()			returns: void
 * Xlib calls:	none

 * Subroutine:	set_tdisp
 * Purpose:	set needed parameters for proposed display
 * PreState:	tid.cenX, tid.cenY, tid.zoom, and tid.block must be set

 * Subroutine:	reset_tdisp
 * Purpose:	Reset temp disp proposal to the current disp params

 * Subroutine:	set_disptran
 * Purpose:	Set display parameters and translations as per temp

 * Subroutine:	panedge_zoom
 * Purpose:	set up zoom given edges of desired display and
 *		appropriate img transform

 * Subroutine:	choose_zoom
 * Purpose:	Select the zoom to best fit indicated image subsection to
 *		display window
 * Method:	Choose a zoom which comes closest to putting the ref point
 *		on an edge while still enclosing it
 * Returns:	Source-to-dest integer blocking code

 * Subroutine:	set_dispoff
 * Purpose:	Set the special window (dest) coords for mapping a display
 * Note:	Round pixel index in if on an edge between pixels
 * Note:	A is src (buf), B is dst (disp)

CRDTRANS.C
 * Module:	crdtrans.c (Coordinate Transformation)
 * Purpose:	Transform x,y, coordinates through transformation matrix
 * Subroutine:	d_transform()			returns: void
 * Subroutine:	i_transform()			returns: void
 * Xlib calls:	none

 * Subroutine:	d_transform
 * Purpose:	Perform coordinate translation on floating point
 *		x and y values
 The argument list is given as:
 void d_transform ( trans, xin, yin, xout, yout )
     Transform *trans;
     double xin, yin;
     float *xout, *yout;
 In the call, trans is given for example, as &coord.imgtofile.  A list of
 possible transformations is given in coord.h.

 * Subroutine:	i_transform
 * Purpose:	Perform coordinate translation using integer input values
 * Note:	Does some checking for computational short-cuts

CSRANLI.C
 * Module:	csranli.c (Cursor Annuli)
 * Purpose:	Deal with annuli of the software cursor
 * Subroutine:	make_new_annulus()
 * Subroutine:	move_annuli()
 * Subroutine:	update_annuli_centers()			returns: void
 *  The interaction for annuli is as follows:
 *  On menu button: set annuli flag (turn button off if point or polygon).
 *  On middle button:
 *   Push: free annuli if grabbed.  Make cursor at mouse or inc position.
 *   Move: size with annuli restrictions
 *   Release: install new annuli record, redraw all cursors.
 *  Left button: move all centers

 * Subroutine:	make_new_annulus
 * Purpose:	Copy the cursor onto an annulus

 * Subroutine:	delete_annuli
 * Purpose:	Remove all but the innermost annulus
 * Called by:	select_cursor() in CursorCtrl.c
 * Subroutine:	move_annuli
 * Purpose:	Change annuli location

 * Subroutine:	recenter_annuli_centers
 * Purpose:	Update cursor location params

CSRAREA.C
 * Module:	csrarea.c (Cursor Area)
 * Purpose:	Calculate areas of cursors
 * Subroutine:	cursor_area();				returns: double

 * Subroutine:	cursor_area
 * Purpose:	Calculate area, in float units file pixels, enclosed by cursor
 * Method:	Use mathematical formula appropriate to cursor type

 * Subroutine:	test_cross
 * Purpose:	Test the edges of a polygon to see if any cross each other
 * method:	Starting with last edge, test each edge against subsequent
 *		edges.  Routine recurses with for next edge.  Adjacent edges
 *		are not tested since neighbors cannot cross but neighbors do
 *		share a common point.

 * Subroutine:	intercept
 * Purpose:	Test this edge against the reference edge
 * Method:	A) Minmax test if two edges have overlapping coordinates.
 *		B) Calculate the intercept of the two lines.
 *		C) Test if intercept is within both edges.

CSRCOORD.C
 * Module:	csrcoord.c (Cursor Coordinates)
 * Purpose:	Calculate coordinates for cursor functions
 * Subroutine:	set_cursor_file_coords()	returns: void	
 * Subroutine:	adjust_cursor_coords()		returns: void	
 * Subroutine:	set_cursor_from_file_coords()	returns: void	
 * Subroutine:	set_annuli_from_file_coords()	returns: void
 * Subroutine:	note_current_disp_transform()	returns: void	
 * Subroutine:	report_cursor_info()		returns: void	

 *  Subroutine:	set_cursor_file_coords
 *  Purpose:	Set img coords of cursor

 *  Subroutine:	adjust_cursor_coords
 *  Purpose:	If the display image has been altered, change the cursor
 *		parameters in the same way, so that the cursor has the same
 *		relationship to the image.  old cursor is not erased, image
 *		redraw usually does that

 *  Subroutine:	set_cursor_from_file_coords
 *  Purpose:	Set cursor window coordinates from its file coordinates

 *  Subroutine:	set_annuli_from_file_coords
 *  Purpose:	Set annuli window coordinates from their file coordinates

 *  Subroutine:	note_current_disp_transform
 *  Purpose:	Note current transform

 *  Subroutine:	disp_params_changed
 *  Purpose:	Check if current transform has changed

 *  Subroutine:	report_cursor_info
 *  Purpose:	Calculate and report curosr params in file coordinates

CSRCTRL.C
 * Module:	csrctrl.c (Cursor Control)
 * Purpose:	Manipulate the software cursor in response to mouse events
 * Subroutine:	control_cursor()		returns: void

 *  Subroutine:	control_cursor
 *  Purpose:	Respond to mouse commands
 *  Note:	When not tracking, call on ButtonPress only.
 *		When tracking priority set, enter on Press, Release, & Motion

CSRDRAW.C
 * Module:	csrdraw.c (Cursor Draw)
 * Purpose:	Display and draw the software cursor
 * Subroutine:	disp_cursor()			returns: void
 * Subroutine:	erase_cursor()			returns: void
 * Subroutine:	draw_cursor()			returns: void
 * Subroutine:	draw_annuli()			returns: void
 * Subroutine:	draw_point()
 * Subroutine:	erase_point()
 * Xlib calls:	XDrawLines(), XDrawRectangles()

 *  Subroutine:	disp_cursor
 *  Purpose:	Draw the software cursor, if it is to be visible

 *  Subroutine:	erase_cursor
 *  Purpose:	Undraw the cursor

 *  Subroutine:	draw_cursor
 *  Purpose:	Draw a cursor as indicated
 This subroutine can draw or erase an annulus

 *  Subroutine:	draw_annuli
 *  Purpose:	Draw all annuli in specified color and function

CSRGRAB.C
 * Module:	csrgrab.c (Cursor Grab)
 * Purpose:	Surgically resize or delete annular cursors
 * Subroutine:	size_annuli()			returns: void
 * Subroutine:	delete_annulus()		returns: void

 * Subroutine:	size_annuli
 * Purpose:	Change size of cursor to intersect current mouse cursor
 *		while keeping aspect ratio of cursor constant

 * Subroutine:	delete_annulus
 * Purpose:	Respond to a mouse request to delete an annulus

 * Subroutine:	size_annulus
 * Purpose:	Change size of cursor to intersect current mouse cursor
 *		while keeping aspect ratio of cursor constant

 * Subroutine:	remove_annulus
 * Purpose:	Remove an annular ring from annulus linked list and screen

 * Subroutine:	grab_annulus
 * Purpose:	Set up cursor to for a size annulus interaction
 * Called by:	size_annuli()

 * Subroutine:	on_annulus
 * Purpose:	Compare size of cursor with annuli
 * Returns:	Code describing relation to annuli
 * PostState:	Sets pointer to nearest annulus inside of cursor

CSRMOVE.C
 * Module:	csrmove.c (Cursor Move)
 * Purpose:	Move, resize, or rotate the software cursor
 * Subroutine:	move_cursor()			returns: void
 * Subroutine:	size_cursor()			returns: void
 * Subroutine:	angle_cursor()			returns: void
 * Subroutine:  start_size()			returns: int
 * Called by:	control_cursor() in CursorCtrl.c

 *  Subroutine:	move_cursor
 *  Purpose:	Change cursor location cursor

 *  Subroutine:	size_cursor
 *  Purpose:	Change size of cursor to intersect current mouse cursor
 *		on side or at corner depending on side argument

 *  Subroutine:	angle_cursor
 *  Purpose:	Change angle of cursor to line up with current mouse cursor

 *  Subroutine:	start_size
 *  Purpose:	Calculate restrictions applied to sizing restrictions can apply
 *		where x and y dimensions are independent zones are defines
 *		by 2 rays from center through rayX/2,rayY and rayX,rayY/2
 *  Returns:	Code to indicate kind of sizing to do

CSRPOLY1.C
 * Module:	csrpoly1.c (Cursor Polygon)
 * Purpose:	Manipulate vertex lists for drawing polygon cursor
 * Subroutine:	grab_polygon_vertex()			returns: void
 * Subroutine:	size_polygon()				returns: void
 * Subroutine:	request_delete_polygon_vertex()		returns: int
 * Subroutine:	size_polygon_from_file_coords()		returns: void
 * Subroutine:	set_polygon_file_coords()		returns: void

 * Subroutine:	grab_polygon_vertex
 * Purpose:	Identify or create polygon vertex for manipulation
 *		Used when initiating a move or size action
 * Called by:	control_cursor() in CursorCtrl.c

 * Subroutine:	request_delete_polygon_vertex
 * Purpose:	Remove a polygon vertex if mouse is close enough to grab it
 * Returns:	1 if image must be redrawn, else 0
 * Called by:	control_cursor() in CursorCtrl.c

 * Subroutine:	size_polygon
 * Purpose:	Move the tracked vertex of the polygon
 * Called by:	size_cursor() in CursorMove.c

 * Subroutine:	set_polygon_file_coords
 * Purpose:	Update all display coordinates and then the file coordinates
 *		for vertices
 * Called by:	control_cursor() in CursorCtrl.c

 * Subroutine:	set_polygon_from_file_coords
 * Purpose:	Update polygon coordinates from file coordinates for
 *		current display window
 * Called by:	adjust_cursor() in CursorCoord.c
 * Called by:	start_polygon() in CursorPolyPt.c
 * Called by:	make_polygon() in RegionMake.c

 * Subroutine:	on_polygon_vertex
 * Purpose:	Test for being on a polygon point, return its index
 * Note:	If more than one vertex are within range, choose closest
 * Note:	(if ambiguity, favor point towards end - top down search)

CSRPOLY2.C
 * Module:	csrpoly2.c (Cursor Polygon Points)
 * Purpose:	Maintain the vertex lists for drawing a polygon cursor
 * Subroutine:	start_polygon()				returns: void
 * Subroutine:	collapse_polygon()			returns: void
 * Subroutine:	add_polygon_vertex()			returns: void
 * Subroutine:	delete_polygon_vertex()			returns: void
 * Subroutine:	set_polygon_hashmarks()			returns: void
 * Subroutine:	set_active_polygon_hashmark()		returns: void
 * Subroutine:	copy_polygon_region_to_cursor()		returns: void

 * Subroutine:	collapse_polygon
 * Purpose:	Reset polygon to the last manipulated point

 * Subroutine:	start_polygon
 * Purpose:	Install polygon drawing stuff for the active cursor

 * Subroutine:	add_polygon_vertex

 * Subroutine:	delete_polygon_vertex

 * Subroutine:	set_polygon_hashmarks

 * Subroutine:	set_active_polygon_hashmark

 * Subroutine:	copy_polygon_region_to_cursor
 * Purpose:	Install stuff to making a polygon copy the active cursor
 * Note:	Must be called by copy_cursor()

CSRPOLY3.C
 * Module:	csrpoly3.c (Cursor Polygon Line)
 * Purpose:	Manipulate vertex lists for drawing polygon cursor
 * Subroutine:	closest_polygon_line()		returns: int

 * Subroutine:	closest_polygon_line
 * Purpose:	Test for the closest polygon segment
 * Note:	in case of tie chose segment forming smallest angle with
 *		vector from pointer to closest point on segment
 * Method:	top down search

 * Subroutine:	distance_from_segment
 * Returns:	square of shortest distance from reference to line segment
 * Method:	Determine closest point on line, if it is in segment, return
 *		its distance, else return distance to  closest endpoint
 * Method:      Equation of the line of the segement: ax + b = y
 *		  a = (y2-y1)/(x2-x1), b = y1 - (a * x1)
 *		Perpendicular line passing through x, y: aax + bb = y
 *		  aa = -1/a, bb = y_ref - (aa * x_ref)
 *		Intersection of two lines: x_norm, y_norm
 *		  x_norm = (b - bb) / (a - aa), y_norm = (a * x_norm) + b

 * Subroutine:	cos_to_segment
 * Returns:	cosine squared of angle between vector from reference to
 *		closest point on line and vector along line away from reference
 * Method:	cos = vector scalar (cross) product / product of lengths
 * Note:	Cosine-squared uses one multiply where cosine needs 2 sqrts

CSRSAVE.C
 * Module:	csrsave.c (Cursor Save)
 * Purpose:	Make new copies of the cursor or replace the cursor by copying
 * Subroutine:	get_new_cursor()		returns: struct cursorRec *
 * Subroutine:	free_cursor()			returns: void
 * Subroutine:	copy_cursor()			returns: struct cursorRec *
 * Subroutine:	save_cursor_as_region()		returns: void
 * Subroutine:	copy_region_to_cursor()		returns: void
 * Subroutine:	match_region()			returns: int

 *  Subroutine:	get_new_cursor()
 *  Returns:	Returns space for cursor including points
 *  Note:	Space is alloc'd as single chunk and can be freed en mass

 *  Subroutine:	free_cursor
 *  Purpose:	Free alloc'd cursor space

 *  Subroutine:	copy_cursor
 *  Returns:	A copy of the cursor in a newly allocated cursor record

 *  Subroutine:	save_cursor_as_region
 *  Purpose:	Copy the cursor onto a region of type include or exclude

 *  Subroutine:	copy_annulus
 *  Purpose:	Reconstruct annulus structure for copy
 *  Returns:	Complete copy of the annulus chain given
 *  Method:	Given an annulus chain, copy this link, add a copy of the
 *		rest of the chain (by recursion) and return the copy

 *  Subroutine:	copy_region_to_cursor
 *  Purpose:	Copy region onto cursor

 *  Subroutine:	match_region
 *  Purpose:	Compare a region with a cursor
 *  Returns:	0 if perfect match, else 1

CSRSHAPE.C
 * Module:	csrshape.c (Cursor Shape)
 * Purpose:	Make basic software cursors
 * Subroutine:	make_cursor()			returns: void
 * Subroutine:	change_circle_granularity()	returns: void

 *  Subroutine	make_cursor
 *  Purpose:	Remake the current cursor polygon list

 *  Subroutine:	make_arrow
 *  Purpose:	Given tip and tail, make line including arrow head
 *  Returns:	Number of points needed to draw arrow
 cursor->type=1536 = 3000 octal

 *  Subroutine:	make_boxcur
 *  Purpose:	Set the corner coordinates for the rotating box cursor
 *  Returns:	Number of points needed to draw box
 cursor->type=768 = 1400 octal

 *  Subroutine:	make_circur
 *  Purpose:	Create a new circle cursor with given center and radius
 *  Returns:	Number of points needed to draw circle
 cursor->type=1024 = 2000 octal

 *  Subroutine:	make_ellipse
 *  Purpose:	Create an elliptical cursor with given center and radii
 *  Returns:	Number of points needed to draw ellipse
 cursor->type=1280 = 2400 octal

 *  Subroutine:	change_circle_granularity
 *  Purpose:	Change number of points used to draw circles and ellipses

 cursor->type=256 for point = 400 octal

CSRSLCT.C
 * Module:	csrslct.c (Cursor Select)
 * Purpose:	Initialize and change states of the software cursor
 * Subroutine:	select_cursor()			returns: void
 * Subroutine:	init_software_cursors()		returns: void

 *  Subroutine:	select_cursor
 *  Purpose:	Respond to command input from user interface

 *  Subroutine:	init_software_cursors
 *  Purpose:	Initialize the cursor parameters
 *  Prestate:	Color must be determined and dispbox must be created and sized

CSRTEXT.C
 * Module:	CrsrText.c (CursorText)
 * Purpose:	Initialize and change states of the software cursor
 * Subroutine:	init_textcursor()		returns: void
 * Subroutine:	new_textcursor()		returns: void
 * Subroutine:	draw_textcursor()		returns: void
 * Subroutine:	reset_textcursor_coords()	returns: void
 * Subroutine:	move_textcursor()		returns: void
 * Subroutine:	textcursor_keyentry()		returns: void
 * Subroutine:	reload_textcursor()		returns: void
 * Subroutine:	save_textcursor()		returns: void

 *  Subroutine:	init_textcursor
 *  Purpose:	initialize editor parameters for text cursor editing

 *  Subroutine:	new_textcursor()
 *  Purpose:	set up cursor struct for text cursor interactions

 *  Subroutine:	clear_textcursor
 *  Purpose:	empty text cursor buffer and ungrab keyboard input

 *  Subroutine:	save_textcursor
 *  Purpose:	save string in editor on region save event

 *  Subroutine:	reload_textcursor
 *  Purpose:	Put cursor string into editor buffer

 *  Subroutine:	textcursor_keyentry
 *  Purpose:	Respond to key entry while in textcursor mode

 *  Subroutine:	draw_textcursor
 *  Purpose:	draw a cursor, using only cursorRec info

 *  Subroutine:	draw_textcursor_cursor
 *  Xlib calls:	XDrawImageString()

 *  Subroutine:	reset_textcursor_coords

 *  Subroutine:	move_textcursor
 *  Purpose:	Move the text drawing coords when text cursor is moved

 *  Subroutine:	clear_text_area
 *  Purpose:	Clear area around edit string, mindful of mask in use
 *  Note:	Assumes only called with GXcopy, AllPlanes, ImageString cursor

 *  Subroutine:	blacken_textcursor_cursor
 *  Xlib calls:	XDrawImageString()

 *  Subroutine:	write_text_region
 *  Purpose:	Write detail part of region file line for a text cursor

CTRLCNTN.C
 * Module:	ctrlcntn.c (Control Connection)
 * Purpose:	Handle all IO with remote independent processes
 * Subroutine:	init_connections()		returns: void
 * Subroutine:	open_connection()		returns: int
 * Subroutine:	close_connection()		returns: void
 * Subroutine:	flush_connection()		returns: void
 * Subroutine:	respond_to_connection()		returns: void
 * Subroutine:	read_connection()		returns: int
 * Subroutine:	write_connection()		returns: int

 * Subroutine:	init_connections
 * Purpose:	Sets up connections after display connection has been opened
 * Note:	necessary since parser precedes display connection

 * Subroutine:	open_connection
 * Purpose:	Opens a connection to a remote process and updates event 
 *              handlers
 * Returns:	-1 on failure, else IPC number
   We have the declaration struct connectRec *connection
   In CONTROL.H connectRec is defined as 
struct connectRec {
  int type;             /* named pipe, socket, or VMS mailbox */
  int protocol;         /* packet type (IRAF, AIPS, HRC, CMD) */
  int fd;               /* file descriptor */
  int open;             /* 0 if closed, else open */
  int direction;        /* read, write, read/write, listen */
  char *name;           /* pipe device name or net socket address */
  int address;          /* network address or parent listener fd */
  void (*func)();       /* function to call when this connection signalled */
  int mask[4];          /* mask bit for file descriptor */
  struct connectRec *next;      /* linklist queue for event handling */
  struct connectRec *affiliate; /* internal binding for listener/connection */
};
   For VMS, connection->type is first set equal to IOP_mailbox (or 3) within
   this subroutine.  When SAOimage starts, this subroutine calls
   open_mailbox(connection->name, connection->direction, 1) with
   connection->name equal to /dev/imt1o, and connection->direction equal to
   -1.  In open_mailbox, the -1 is interpreted as IOP_Read, and mode is 
   accordingly set to READ_ONLY (or 1).  ZOPNVI(device_name, &mode, &ipc) 
   is then called to open a mailbox.  This subroutine is called a second
   time with connection->name equal to /dev/imt1i, connection->direction
   equal to 1.  Open_mailbox is called again where the 1 is interpreted as
   IOP_Write, and mode is accordingly set to WRITE_ONLY (or 3).  ZOPNVI 
   is then called to open another mailbox.
   The general call is made as open_connection(connection) where connection is
   defined as struct connectRec *connection.  
   In open_imtool_connection in IRAFIO.C it is called as 
   open_connection(&control.IRAF_in) where control is declared as
   extern struct controlRec control;  controlRec is defined in CONTRO.C as
struct controlRec {
  int mode;             /* active event response mode */
  int *response;        /* widget returned data pointer */
  int eventmask;        /* current event mask */
  int priority;         /* special event tracking mask */
  int completed;        /* event response completed flag */
  int verbose;          /* print-messages-about-process-statuses */
  int tracking;         /* magnifier and color graph tracking */
  int magni_track;      /* track mouse with magni box */
  int coord_track;      /* track mouse with coord string */
  int print_buttons;    /* include buttons in hardcopy output */
  int printer;          /* PostScript, Imagen Impress, etc. */
  int look_and_feel;    /* SAO, Motif, OpenLook */
  int remote_connected; /* must select for more than just X events */
  int select_size;      /* size of mask to check for event */
  int select_mask[4];   /* combined select masks for all connections */
   However, in CONTROL.H we have struct connectRec IRAF_in;
   In open_rtsock_connection and open_rtfifo_connection in RTIO.C it is 
   called as open_connection(&control.aux_in)
   For VMS, connection->type is first set equal to IOP_mailbox=3
   Then open_mailbox(connection->name, connection->direction, 1) is called.

 * Subroutine:	close_connection
 * Purpose:	Close the remote process connection and update event handlers

 * Subroutine:	flush_connection
 * Purpose:	Suck all bytes out of a pipe open for reading

 * Subroutine:	respond_to_connection
 * Purpose:	call the function for this connection event

 * Subroutine:	read_connection
 * Purpose:	read specified number of bytes from connection into buf
   Returns the actual number of bytes sent

 * Subroutine:	write_connection
 * Purpose:	write specified number of bytes to connection from buf

 * Subroutine:	init_select
 * Purpose:	Initialize event handler parameters
 * Note:	SYSV machines don't have an easy way to get the number of
 *		device bits in the select mask.  Most have 64.  Under BSD,
 *		Sun uses 32 (1 int), Apollo uses 128 (4 ints).

CTRLDISK.C
 * Module:	ctrldisk.c (Control Disk Access)
 * Purpose:	Open, close, read, and write disk files and streams.
 *		Centralized to facilitate selecting system specific code.
 * Subroutine:	open_disk()		returns: int
 * Subroutine:	fcntl_disk()		returns: void
 * Subroutine:	flush_disk()		returns: void
 * Subroutine:	lseek_disk()		returns: int
 * Subroutine:	read_disk()		returns: int
 * Subroutine:	write_disk()		returns: int
 * Subroutine:	close_disk()		returns: void
 * UNIX calls:	open(), fcntl(), lseek(), read(), write(), close()

 * Subroutine:	open_disk
 * Returns:	File descriptor of open file (suitable for read())

 * Subroutine:	fcntl_disk
 * Purpose:	Change an open file's flags, check for errors

 * Subroutine:	flush_disk
 * Purpose:	Read to functional end of file (useful with dynamic IO)

 * Subroutine:	lseek_disk
 * Purpose:	Skip into a disk file before reading, check for errors

 * Subroutine:	read_disk
 * Purpose:	Read bytes from a disk file, check for errors
 * Returns:	Number of bytes read, or error flag (-1)
 * Note:	If report_error is 0, reading fewer than nbytes
 *		is not treated as an error.
 * Note:	BSD4.3 interrupts reads on any signal.  Thus reads may
 *		be broken into (hopefully consecutive) pieces.

 * Subroutine:	write_disk
 * Purpose:	Write data to the open disk file or stream

 * Subroutine:	close_disk
 * Purpose:	Close a disk file

 * VMS versions of disk functions.  This implementation of these functions
 * for VMS uses the standard C library calls, just as on Unix.  Although
 * this is the easiest approach for now, there are some problems:
 *
 *	Performance	The VAX/VMS C library functions dealing with
 *			file i/o have never been very efficient.  Better
 *			performance (with some loss of generality, of
 *			course) can be gained by using RMS system routines.
 *			The VMS_OPEN_OPTIONS below should help, though.
 *
 *	VMS Files	VMS supports a number of different file types,
 *			which are sometimes handled differently by the
 *			the C library functions.  For example, a read()
 *			operation on a file with a record size of 512
 *			bytes will return a maximum of 512 bytes, regardless
 *			of the number requested in the call.  Thus, for
 *			these functions, we must loop around until all the
 *			i/o requested has been performed.
 *
 *	Seeking		Depending on the type of file being accessed, the
 *			operation of seeking to a byte offset in a file
 *			is somewhat unpredictable.  For stream files, it
 *			is usually okay, but for record files, only byte
 *			offsets that are on a record boundary are allowed.
 *			(As a result of this behavior, the -skip and -header
 *			command line options may not always perform as
 *			expected on VMS.)
 *
 * Note:  perror(NULL) will not work on VMS; some character string must
 *	be specified, even if just "".

 * Subroutine:	open_disk
 * Returns:	File descriptor of open file (suitable for read())

 * Subroutine:	fcntl_disk
 * Purpose:	Change an open file's flags, check for errors

 * Subroutine:	lseek_disk
 * Purpose:	Skip into a disk file before reading, check for errors

 * Subroutine:	read_disk
 * Purpose:	Read bytes from a disk file, check for errors
 * Returns:	Number of bytes read, or error flag (-1)
 * Note:	If report_error is 0, reading fewer than nbytes
 *		is not treated as an error.

 * Subroutine:	write_disk
 * Purpose:	Write data to the open disk file or stream

 * Subroutine:	close_disk
 * Purpose:	Close a disk file

CTRLFILE.C
 * Module:	ctrlfile.c (Control File)
 * Purpose:	Prompt for file name and open file for specified purpose
 * Subroutine:	open_output_file()
 * Subroutine:	open_input_file()
 * Subroutine:	swap_bytes()
 * UNIX calls:	fopen(), lstat(), unlink(), extern int errno

 * Subroutine:	open_output_file
 * Purpose:	Open a file for writing, as specified by user
 * Post state:	Sets pointer to file, open and ready for writing
 * Returns:	2 = append, 1 = new file, 0 = user decided not to, -1 = error

 * Subroutine:	open_input_file
 * Purpose:	Open a file for reading, as specified by user
 * Note:	Sets pointer of file open and ready for reading
 * Returns:	1 on success, 0 if user decided not to, -1 on error

 * Subroutine:	file_exists
 * Purpose:	does a file exist for opening (1=yes, 0=no, -1=problem)

 * Subroutine:	swap_bytes
 * Purpose:	Swap bytes in place, (swab is not guaranteed to work in place)

CTRLGC.C
 * Module:	ctrlgc.c (Control Graphics Context)
 * Purpose:	Create a GC and set the GC params when needed
 * Subroutine:	init_gc()			returns: void
 * Subroutine:	free_gc()			returns: void
 * Subroutine:	set_gc()			returns: GC
 * Subroutine:	set_gc_with_background()	returns: GC
 * Subroutine:	set_text_gc()			returns: GC
 * Subroutine:	set_edit_gc()			returns: GC
 * Subroutine:	get_fontstruct()		returns: XFontStruct *
 * Xlib calls:	XCreateGC(), XSetMask(), XSetFunction(), XSetForeground()
 * Xlib calls:	XChangeGC(), XLoadQueryFont()

 * Subroutine:	init_gc()
 * Purpose:	Create the gc and set initial values
 * Xlib calls:	XCreateGC()

 * Subroutine:	free_gc
 * Purpose:	free resources loaded by server before exiting

 * Subroutine:	set_gc()
 * Purpose:	Adjust gc params as specified for simple drawing
 * Xlib calls:	XSetMask(), XSetFunction(), XSetForeground()

 * Subroutine:	set_gc_with_background
 * Purpose:	Adjust gc params as specified for drawing with a background
 * Xlib calls:	XSetMask(), XSetFunction(), XSetForeground(), XSetBackground()

 * Subroutine:	set_text_gc
 * Purpose:	Adjust gc params as specified for basic text
 * Xlib calls:	XChangeGC()
 * Note:	Most gc values are cached, but new font flushes vals to server

 * Subroutine:	set_edit_gc
 * Purpose:	Adjust gc params as specified for text with a background
 * Xlib calls:	XChangeGC()

 * Subroutine:	get_fontstruct
 * Returns:	Pointer to the specified fontstruct

 * Subroutine:	init_font
 * Purpose:	Load the fonts used by this program
 * Returns:	Font on success, else 0

 * Subroutine:	open_font
 * Purpose:	Load a font or announce failure
 * Returns:	1 on success, else 0
 * Xlib calls:	XLoadQueryFont()

CTRLMBOX.C
 * Module:	ctrlmbox.c (ControlMailbox)
 * Purpose:	Handle a VMS mailbox for IO
 * Subroutine:	open_mailbox()		returns: int
 * Subroutine:	close_mailbox()		returns: void
 * Subroutine:	flush_mailbox()		returns: void

 * Subroutine:	open_mailbox
 * Purpose:	Open a VMS mailbox I/O
 * Returns:	Channel number on success else -1.
 * The call is made as open_mailbox(device_name, direction, flush_flag).
   where
     char *device_name;   /* i: name of mailbox device */
     int direction;       /* i: IOP_Write=1, IOP_Read=-1, IOP_ReadWrite=0 */
     int flush_flag;      /* i: 1=flush, 0=don't flush */
   direction is given by connection->direction, which is set equal to
   listener->direction in CTRLSCKT.C. 
   Question:  where is device_name set?


 * Subroutine:	close_mailbox
 * Purpose:	Close a mailbox connection
 * Returns:	0 on success else -1.

 * Subroutine:	flush_mailbox
 * Purpose:	Suck all bytes out of a pipe open for reading

 * Subroutine:	read_mailbox
 * Purpose:	Read VMS mailbox
 * Returns:	Byte count, 0 on EOF, -1 on error
   Returns the actual number of bytes sent
   The values of the received bytes can be printed out for diagnositc
   purposes here.

 * Subroutine:	write_mailbox
 * Purpose:	Write to VMS mailbox
 * Returns:	Byte count, 0 on EOF, -1 on error

CTRLPIPE.C
 * Module:	ctrlpipe.c (Control Pipe Device)
 * Purpose:	Open a pipe device for IO
 * Subroutine:	open_pipe()	returns: int
 * Subroutine:	close_pipe()	returns: void
 * Subroutine:	flush_pipe()	returns: void

 * Subroutine:	open_pipe
 * Purpose:	Open a channel on a named device for pipe I/O
 * Returns:	Channel number on success (0-64) else -1.
 * Note:	select_mask and mask_size are augmented, not initialized

 * Subroutine:	close_pipe
 * Purpose:	Close pipe connection

 * Subroutine:	flush_pipe
 * Purpose:	Suck all bytes out of a pipe open for reading

CTRLSCKT.C
 * Module:	ctrlsckt.c (Control Socket)
 * Purpose:	Open a pipe device for IO
 * Subroutine:	open_socket_listener()		returns: int
 * Subroutine:	accept_socket_connection()	returns: struct *connectRec
 * Subroutine:	close_socket()			returns: void
 * Subroutine:	flush_socket()			returns: void

 * Subroutine:	open_socket_listener
 * Purpose:	Get a socket on which to listen for connections

 * Subroutine:	accept_socket_connection
 * Purpose:	accept a connection requested of the socket listener

 * Subroutine:	flush_socket
 * Purpose:	flush all pending input on this socket connection

 * Subroutine:	close_socket
 * Purpose:	close this socket's file descriptor

DISPBLNK.C
 * Module:	dispblnk.c (Display Blink)
 * Purpose:	Switch between stored displays
 * Subroutine:	save_blink()		returns: void
 * Subroutine:	free_blink()		returns: void
 * Subroutine:	clear_blink()		returns: void
 * Subroutine:	unset_blink()		returns: void
 * Subroutine:	control_blink()		returns: void

 * Subroutine:	save_blink
 * Purpose:	Save the current display in a blink buffer

 * Subroutine:	free_blink
 * Purpose:	When dispbox changes size, dump all current buffers

 * Subroutine:	clear_blink
 * Purpose:	Reset basic blink parameters when color arrangements change

 * Subroutine:	unset_blink
 * Purpose:	Indicate that display no longer holds a blinking image
 *		Use when display is redrawn by regular display update routine

 * Subroutine:	display_blink

 * Subroutine:	control_blink
 * Purpose:	Control blinking of stored displays
 * For each new button press, put it on top of stack and display its buffer
 * For each button release, if it is on top of stack, release it and display
 *  one below, else just release it

DISPBTMP.C
 * Module:	dispbtmp.c (Display Bitmap)
 * Purpose:	Routines to map 16 bit data to a single plane bitmap
 * Subroutine:	init_halftone()			returns: void
 * Subroutine:	select_halftone()		returns: void
 * Subroutine:	make_halftone_panimage()	returns: void
 * Subroutine:	make_halftone_display()		returns: void
 * Xlib calls:	none

 * Subroutine:	init_halftone
 * Purpose:	Initialize color struct pointers for halftoning

 * Subroutine:	select_halftone
 * Purpose:	Respond to halftone selection command

 * Subroutine:	new_halftone
 * Purpose:	Redo halftone images of both dispbox and panbox

 * Subroutine:	make_halftone_panimage
 * Purpose:	Make halftone bitmap for pan window (panbox)

 * Subroutine:	make_halftone_display
 * Purpose:	Make halftone bitmap for display window (dispbox)

DISPDFSE.C
 * Module:	dispdfse.c (Display Error Diffusion)
 * Purpose:	Map 16 bit data to a single plane bitmap using error diffusion
 * Subroutine:	diffuse_sample()		returns: void
 * Subroutine:	diffuse_replicate()		returns: void
 * Xlib calls:	none

 * Subroutine:	diffuse_sample
 * Purpose:	Perform subsampling and error diffusion to produce a bitmap
 *		image from 16 bit signed data through a scaling lookup table.
 *		Used when bitmap is same size or smaller than data image.
 * Method:	Sample every zoom'th data element in each direction

 * Subroutine:	diffuse_replicate
 * Purpose:	Perform replication and error diffusion to produce a bitmap
 *		image from 16 bit signed data through a scaling lookup table.
 *		Used when bitmap is larger than data image.
 * Method:	Repeat data element zoom times in each direction

DISPDTHR.C
 * Module:	dispdthr.c (Display Dither)
 * Purpose:	Map 16 bit data to a single plane bitmap using dithering
 * Subroutine:	dither_sample()			returns: void
 * Subroutine:	dither_replicate()		returns: void
 * Xlib calls:	none
 * Method:	Image dithering based on 16x16 square of values from 0 to 255.
 * Note:	Matrix is short to allow compare with 256 (not a uchar val)
 * Note:	Lookup is used to rescale input data to 0-255 range
 * Note:	Most loops check by pointer val, saving indexing overhead
 * Note:	Seperate code used for forward and reverse video rather than
 *		switching foreground and background val, because non-image
 *		area of display must not change

 * Subroutine:	zoom_dither_sample
 * Purpose:	Perform subsampling and dithering to produce a bitmap image
 *		from 16 bit signed data through a scaling lookup table.
 *		Used when bitmap is same size or smaller than data image.
 * Method:	Sample every zoom'th data element in each direction
 * Note:	x, y, width, and height define a subsection within output.
 *		Bits outside of subsection are unchanged.

 * Subroutine:	zoom_dither_replicate
 * Purpose:	Perform replication and dithering to produce a bitmap image
 *		from 16 bit signed data through a scaling lookup table.
 *		Used when bitmap is larger than data image.
 * Method:	Repeat data element zoom times in each direction

DISPLAY.C
 * Module:	display.c (Display)
 * Purpose:	Draw images in their windows, including the main display
 * Subroutine:	disp_window()			returns: void
 * Subroutine:	disp_dispbox()			returns: void
 * Subroutine:	map_dispbox()			returns: void
 * Subroutine:	clear_margins()			returns: void
 * Xlib calls:	XPutImage(), XSync();

 * Subroutine:	disp_window
 * Purpose:	Redraw the window's display image with no frills
 * Xlib call:	XPutImage()

 * Subroutine:	disp_dispbox
 * Purpose:	Redraw the dispbox window display including cursor graphics

 * Subroutine:	map_dispbox
 * Purpose:	Redraw the main display buffer from the short image buffer

 * Subroutine:	clear_margins
 * Purpose:	Take action to indicate unfilled display margins

DISPPSCT.C
 * Module:	disppsct.c (Display Postscript)
 * Purpose:	Dump contents of the display window to a postscript printer.
 * Subroutine:	screen_dump()			returns: void
 * Copyright:	1989 NOAO & Smithsonian Astrophysical Observatory
 *		You may do anything you like with this file except remove
 *		this copyright.  The Smithsonian Astrophysical Observatory
 *		makes no representations about the suitability of this
 *		software for any purpose.  It is provided "as is" without
 *		express or implied warranty.
 * Origin:      Doug Tody, NOAO (written for IRAF's Imtool)
 * Modified:	{0} Michael VanHilst	initial version		1 July 1989
 *		{1} Jay Travisano (STScI)    VMS changes        10 Nov 1989
 *              {2} MVH BSDonly strings.h compatability           19 Feb 1990
 *		{n} <who> -- <does what> -- <when>

 * SCREENDUMP -- Make a hardcopy of the indicated region of the screen on a
 * hardcopy device.  Currently only two output formats are supported, Sun
 * rasterfile output, or Postscript output for devices such as the Apple laser
 * writer.  Postscript output is the default; rasterfile output is enabled
 * if the variable 'R_RASTERFILE' is defined in the environment, with the
 * string value being an sprintf format string with one decimal integer
 * argument, used to create the rasterfile filename (e.g., "frame.%d").
 * The variable 'R_DISPOSE' may be defined to specify how the Postscript or
 * Sun rasterfile is to be disposed of.  If 'R_DISPOSE' is not defined and
 * rasterfile output is specified, no dispose command will be issued.  If the
 * variable is not defined and Postscript output is specified, the default
 * dispose command defined above will be executed.
 *

 * BITMAP_TO_POSTSCRIPT -- Translate a memory bitmap into a postscript program
 * using image compression where regions of the image are all zeroes.  This is
 * done as follows: [1] lines of the bitmap are divided into segments of N
 * bytes, [2] if all N bytes are zero a single zero byte is transmitted,
 * otherwise a byte with the value one is transmitted, followed by N bytes of 
 * literal data.  Lines which are entirely zero are not transmitted at all.
 * The goal is to significantly reduce the amount of data to be pushed through
 * the laserwriter serial interface while keeping things simple enough that
 * postscript will hopefully be able to process the bitmap efficiently.
 *
 * NOTE: Postscript is supposed to be able to copy bitmaps directly without
 * any transformations if all the right conditions are met, e.g., unitary
 * matrices, pixrect resolution matches device resolution, etc.  We do not
 * make use of this here due to the great volume of data which would have to
 * pushed through the laserwriter serial interface at 9600 baud to transmit
 * a fully resolved bitmap.  If a parallel interface were available, e.g.,
 * if the laserwriter is on the ethernet, then this would be the way to go.

 * Subroutine:	make_label
 * Purpose:	Generate the label for the output printer page.
 * Unix call:	time(), gethostname(), getpwuid(), endpwent()

DISPPXMP.C
 * Module:	disppxmp.c (Display Pixmap)
 * Purpose:	Map short buffer to picturebox display buffer
 * Subroutine:	map_buf_subzoom()		returns: void
 * Subroutine:	map_buf_repzoom()		returns: void
 * Subroutine:	map_buf_subzoom_adj()		returns: void
 * Subroutine:	map_buf_repzoom_adj()		returns: void

 * Subroutine:	map_buf_subzoom
 * Purpose:	Map data to a display buffer, zoomed down by sub-sampling

 * Subroutine:	map_buf_repzoom
 * Purpose:	Put zoom replicated image data in the display buffer

EDITCTRL.C
 * Module:	editctrl.c (Editor Control)
 * Purpose:	Top level of text editing session for string input
 * Subroutine:	init_edit_popup()		returns: EditStruct *
 * Subroutine:	get_edit_input()		returns: int
 * Subroutine:	unmap_popwin()			returns: void
 * Xlib calls:	XCreateSimpleWindow(), XMapWindow(), XUnmapWindow()
 * Xlib calls:	XSelectInput(), XNextEvent(), XDrawImageString()

 * Subroutine:	init_edit_popup
 * Purpose:	Get everything ready for running editor sessions

 * Subroutine:	get_edit_input
 * Purpose:	Run popup editor session for text input
 * Xlib calls:	XNextEvent(), XDrawImageString(), XUnmapWindow()
 * Note:	All non-editor events are thrown out during session
 *		(but expose is fielded and configure is saved for end).
 * Returns:	1 if user returns with a response, 0 if user cancels session

 * Subroutine:	unmap_popwin
 * Purpose:	Unmap the popwin: called by routines which control map and
 *		unmap themselves because they use the window for multiple
 *		queries (single query can have auto-unmap)

 * Subroutine:	init_popwin
 * Purpose:	Set the popup parameters and create the popup window
 * Xlib calls:	XCreateSimpleWindow(), XSelectInput();

 * Subroutine:	map_popwin
 * Purpose:	map the popwindow, noting its current size and setting params
 * Xlib calls:	XMapWindow()

EDITDRAW.C
 * Module:	editdraw.c (Editor Draw)
 * Purpose:	Draw the edited line in the popup window
 * Subroutine:	set_edit_draw_func()		returns: void
 * Subroutine:	unset_edit_draw_func()		returns: void
 * Subroutine:	draw_new_string()		returns: void
 * Subroutine:	redraw_edit_string()		returns: void
 * Subroutine:	draw_edit_string()		returns: void
 * Subroutine:	draw_edit_cursor()		returns: void
 * Xlib calls:	XClearArea(), XDrawImageString(), XPutImage()

 *  Subroutine:	set_edit_draw_func
 *  Purpose:	Set draw func to func and mask

 *  Subroutine:	unset_edit_draw_func
 *  Purpose:	Unset draw func to func and mask

 *  Subroutine:	draw_new_string
 *  Purpose:	Draw a string for the first time (new window or new string)

 *  Subroutine:	redraw_edit_string
 *  Purpose:	Redraw the string as it was after a popup window expose event

 *  Subroutine:	draw_edit_string
 *  Purpose:	Display a section of string and the text cursor
 *  Xlib calls:	XDrawImageString()

 *  Subroutine:	draw_edit_cursor
 *  Xlib calls:	XDrawImageString()

 *  Subroutine:	mark_left
 *  Xlib calls:	XPutImage()

 *  Subroutine:	clear_left

 *  Subroutine:	mark_right
 *  Xlib calls:	XPutImage()

 *  Subroutine:	clear_right

 *  Subroutine:	clear_area
 *  Purpose:	Clear area around edit string, mindful of mask in use

EDITEMCS.C
 * Module:	editemcs.c (Editor Emacs)
 * Purpose:	Provide EMACS like response for popup line editor
 * Subroutine:	emacs_response()		returns: int
 * Xlib calls:	XLookupString()

 * Subroutine:	emacs_response
 * Purpose:	Respond to keys in emacs fashion
 * Returns:	1 on event indicating entry, -1 on cancel, else 0
 * Xlib calls:	XLookupString()

EDITINIT.C
 * Module:	editinit.c (Editor Initialization)
 * Subroutine:	get_edit_struct()		returns: EditStruct *
 * Subroutine:	init_edit_struct()		returns: void
 * Subroutine:	load_edit_string()		returns: void
 * Subroutine:	load_edit_struct()		returns: void
 * Subroutine:	store_edit_struct()		returns: void
 * Subroutine:	recall_edit_struct()		returns: void
 * Subroutine:	clear_edit_buf()		returns: void

 * Subroutine:	get_edit_struct
 * Returns:	Newly allocated popup editor structure

 * Subroutine:	init_edit_struct
 * Purpose:	Initialize font and drawing info for popup editor structure

 * Subroutine:	load_edit_string
 * Purpose:	Store a passed string in the current string buffer

 * Subroutine:	load_edit_struct
 * Purpose:	Store a passed string in the editor storage stack
 * Note:	Also makes it the default entry
 * Exception:	Assume no other stored strings (erases any)

 * Subroutine:	recall_edit_struct
 * Purpose:	Retrieve a line from the storage stack

 * Subroutine:	store_edit_struct
 * Purpose:	Put current line in the store stack

 * Subroutine:	clear_edit_buf
 * Purpose:	Set edit buffer string to no characters

EDITLINE.C
 * Module:	editline.c (Editor Line)
 * Purpose:	Manipulate the popup editor character string
 * Subroutine:	insert_chars()			returns: void
 * Subroutine:	delete_chars_backward()		returns: void
 * Subroutine:	delete_chars_forward()		returns: void
 * Subroutine:	next_word_end()			returns: int
 * Subroutine:	last_word_end()			returns: int

 * Subroutine:	insert_chars
 * Purpose:	Insert new characters into the edit line
 * Returns:	Number of characters inserted

 * Subroutine:	delete_chars_backward
 * Purpose:	Delete characters before the active position

 * Subroutine:	delete_chars_forward
 * Purpose:	Delete characters from the active position forward

 * Subroutine:	next_word_end
 * Returns:	The distance from the active position to the next space
 *		following a character (or the end of the line)

 * Subroutine:	last_word_start
 * Returns:	The distance from the active position to the first character
 *		following a space found in a backward search (or the start of
 *		the line)

EDITRDRW.C
 * Module:	editrdrw.c (Editor Redraw)
 * Purpose:	Move cursor and redraw the line after editing
 * Subroutine:	move_edit_cursor()		returns: void
 * Subroutine:	place_edit_cursor()		returns: void
 * Subroutine:	redraw_after_delete()		returns: void
 * Subroutine:	redraw_after_insert()		returns: void
 * Xlib calls:	none

 * Subroutine:	move_edit_cursor

 * Subroutine:	place_edit_cursor

 * Subroutine:	redraw_after_delete
 * Purpose:	Update the displayed string after character deletion
 * Note:	Characters not moved are not redrawn
 * Note:	Characters after any change are redrawn.  If proportional
 *		spacing font is used, they might need it.

 * Subroutine:	redraw_after_insert
 * Purpose:	Update the displayed string after character insertion
 * Note:	Insertion is assumed to be directly before active position
 * Note:	Characters not moved are not redrawn
 * Note:	Characters after any change are redrawn.  If proportional
 *		spacing font is used, they might need it.

GRPHBAR.C
 * Module:	grphbar.c (Color Graph Bar)
 * Purpose:	Fill a buffer with a color chart of the allocated colors
 * Subroutine:	fill_colorbar()			returns: void
 
 * Subroutine:	fill_colorbar
 * Purpose:	Fill byte buffer with bars of increasing value covering
 *		colormap range
 * PostState:	Buffer will contain data to represent a color sweep in one
 *		diirection while repeating itself in the other.  For a
 *		horizontal color bar, there will be vertical stripes of
 *		increasing (or decreasing) colors from left to right.
 * Note:	Positive polarity is from left (horizontal) or top (vertical).

GRPHBTMP.C
 * Module:	grphbtmp.c (Color Graph Bitmap)
 * Purpose:	Create the halftone colorbar
 * Subroutine:	make_halftone_colorbar()	returns: void

 * Subroutine:	make_halftone_panimage
 * Purpose:	Make halftone bitmap for pan window (panbox)

 * Subroutine:	byte_dither_sample
 * Purpose:	Perform subsampling and dithering to produce a bitmap image
 *		from 16 bit signed data through a scaling lookup table.
 *		Used when bitmap is same size or smaller than data image.
 * Method:	Sample every zoom'th data element in each direction
 * Note:	This is a copy of the disp dither code but for byte data

 * Subroutine:	byte_diffuse_sample
 * Purpose:	Perform subsampling and error diffusion to produce a bitmap
 *		image from 16 bit signed data through a scaling lookup table.
 *		Used when bitmap is same size or smaller than data image.
 * Method:	Sample every zoom'th data element in each direction
 * Note:	This is a copy of the DispDiffuse code but for byte data

GRPHCTRL.C
 * Module:	grphctrl.c (Color Graph Control)
 * Purpose:	Manipulate the color graph
 * Subroutine:	map_graphbox()			returns: void
 * Subroutine:	display_graphbox()			returns: void
 * Subroutine:	control_cgraph()		returns: void
 * Xlib calls:	XUnmapWindow(), XMapWindow()
 * Xlib calls:	XSync(), XCheckWindowEvent(), XStoreColors()

 * Subroutine:	map_graphbox
 * Purpose:	Varify size and get everything set when mapping the graphbox
 * Xlib calls:	XUnmapWindow(), XMapWindow()

 * Subroutine:	display_graphbox
 * Purpose:	Put up the graphbox when it is mapped or reexposed

 * Subroutine:	control_cgraph
 * Purpose:	Mouse controlled interaction to alter color table.
 * Called by:	control_event_loop in MainEvent.c
 * Xlib calls:	XSync(), XCheckWindowEvent(), XStoreColors()

GRPHDRAW.C
 * Module:	grphdraw.c (Color Graph Draw)
 * Purpose:	Draw color graph lines
 * Subroutine:	draw_colorbar()				returns: void
 * Subroutine:	draw_cgraph()				returns: void
 * Subroutine:	highlight_active_cgraph_vertex()	returns: void
 * Subroutine:	install_draw_queue_end()		returns: void
 * Subroutine:	replace_draw_queue_end()		returns: void
 * Xlib calls:	XPutImage(), XDrawLines(), XDrawRectangles(), XFillRectangles()

 * Subroutine:	draw_colorbar
 * Purpose:	Put the color bar on the screen
 * Xlib calls:	XPutImage()

 * Subroutine:	draw_cgraph
 * Purpose:	Draw the cgraph graph lines and hash marks
 * Xlib calls:	XDrawLines(), XDrawRectangles()

 * Subroutine:	highlight_active_cgraph_vertex
 * Purpose:	Draw active hash mark as filled box
 * Xlib calls:	XFillRectangles()

 * Subroutine:	install_draw_queue_end
 * Purpose:	Installed newly active line to be last drawn

 * Subroutine:	replace_draw_queue_end
 * Purpose:	Replace end of the draw queue when end color is no longer
 *		active

GRPHGRAB.C
 * Module:	grphgrab.c (Color Graph Grab Vertex)
 * Purpose:	Get or drop a color graph vertex as per a mouse button event
 * Subroutine:	grab_cgraph_vertex()		returns: void
 * Subroutine:	drop_cgraph_vertex()		returns: int

 * Subroutine:	grab_cgraph_vertex
 * Purpose:	When a mouse button is pressed, assign a vertex to that button

 * Subroutine:	drop_cgraph_vertex
 * Purpose:	Delete a vertex if one is under the mouse pointer for drop
 *		event
 * Returns:	1 if a vertex was dropped, else 0

 * Subroutine:	get_color_vertex
 * Purpose:	Handle grab vertex event for single color 
 * Method:	Grab old vertex or make new vertex - under mouse pointer

 * Subroutine:	grab_old_color_vertex
 * Purpose:	Check to see if position is close to an existing hash mark.
 *		If so, set active markers.
 * Returns:	1 if a vertex was grabbed, else 0

 * Subroutine:	install_new_color_vertex
 * Purpose:	Given hash position, install a new vertex, and make active

 * Subroutine:	add_color_vertex
 * Purpose:	Install new vertex in a color subtableRec.

 * Subroutine:	add_color_vertex_hash
 * Purpose:	Add a new hash mark

 * Subroutine:	drop_color_vertex
 * Purpose:	Delete a color table vertex if one is under the mouse position
 * Returns:	1 if vertex was dropped, else 0

GRPHINIT.C
 * Module:	grphinit.c (Color Graph Initialize)
 * Purpose:	Initialize or reset color bar and graph
 * Subroutine:	init_colorbox()			returns: void
 * Subroutine:	init_main_colorbar()		returns: void
 * Subroutine:	adjust_main_colorbar()		returns: void
 * Subroutine:	init_graph_colorbar()		returns: void
 * Subroutine:	adjust_graph_colorbar()		returns: void
 * Subroutine:	map_halftone_colorbar()		returns: void
 * Subroutine:	adjust_color_graph()		returns: void
 * Extern:	cgraph in CgraphCtrl.c (from Cgraph.def)
 * Xlib calls:	XCreateSimpleWindow(), XSelectInput(), XMapSubwindows()
 * Xlib calls:	XUnmapWindow(), XMapWindow()

 * Subroutine:	init_colorbox
 * Purpose:	Handle program init-time color bar and graph initialization

 * Subroutine:	init_main_colorbar
 * Purpose:	Initialize color bar and related params
 * Xlib calls:	XCreateSimpleWindow(), XMapSubwindows()

 * Subroutine:	adjust_main_colorbar
 * Purpose:	Adjust color bar size params and/or color data if needed

 * Subroutine:	init_graph_colorbar
 * Purpose:	Initialize color bar and related params
 * Xlib calls:	XMapSubwindows()

 * Subroutine:	adjust_graph_colorbar
 * Purpose:	Adjust color bar size params and/or color data if needed

 * Subroutine:	map_halftone_colorbar
 * Purpose:	Create and draw the color bar

 * Subroutine:	set_colorbar_image
 * Purpose:	Set the color bar for display of current color set

 * Subroutine:	adjust_color_graph
 * Purpose:	Adjust color graph size params and/or graph if needed
 * Xlib calls:	XCreateSimpleWindow(), XSelectInput(), XMapSubwindows()

GRPHLBL.C
 * Module:	grphlbl.c (Color Graph Label)
 * Purpose:	Initialize or reset color bar and graph
 * Subroutine:	label_colorbar()		returns: void
 * Subroutine:	label_color_graph()		returns: void
 * Subroutine:	label_gamma()			returns: void
 * Subroutine:	init_graph_text()		returns: void
 * Extern:	normform, minform in WndwDesktop.c
 * Extern:	cgraph in CgraphCtrl.c (from Cgraph.def)
 * Xlib call:	XDrawImageString(), XTextExtents(), XTextWidth()

 * Subroutine:	label_colorbar
 * Purpose:	Label the maximum color level by that end of the color bar
 * Xlib call:	XDrawImageString()

 * Subroutine:	label_color_graph
 * Purpose:	Draw entire graph label

 * Subroutine:	label_gamma
 * Purpose:	Label color gamma levels
 * Xlib call:	XDrawImageString()

 * Subroutine:	init_cgraph_text
 * Purpose:	Set basic text parameters for color bar and graph labels
 * Xlib calls:	XTextExtents(), XTextWidth()
 * Note:	To be called before the color and graph windows are created

GRPHLINE.C
 * Module:	grphline.c (Color Graph Line)
 * Purpose:	Assemble lines and hash marks for the color graph
 * Subroutine:	init_cgraph_lines()			returns: void
 * Subroutine:	set_cgraph_line()			returns: void
 * Subroutine:	init_cgraph_bars()			returns: void
 * Subroutine:	set_cgraph_bar()			returns: void
 * Subroutine:	init_cgraph_hash()			returns: void
 * Subroutine:	set_cgraph_hash()			returns: void

 * Subroutine:	init_cgraph_lines
 * Purpose:	Set the fixed color_linegraph coordinates (aligning segments
 *		with the corresponding colorbar stripe)

 * Subroutine:	set_cgraph_line
 * Purpose:	Set the variable colorline coordinates representing intensity
 * PreState:	Must be preceded by init_colorhash whenever window size or
 *		color allocation is changed

 * Subroutine:	init_cgraph_bars
 * Purpose:	Set the fixed colorline coordinates (aligning segment with
 *		the corresponding colorbar stripe)
 * Params:	xzero, yzero, xwidth, yheight describe the graph drawing area
 *		within its (possibly larger) window
 * Method:	Graph starts at _zero edge, evenly spacing the segments to the
 *		far edge.  (count may be less than xwidth or yheight)

 * Subroutine:	set_cgraph_bar
 * Purpose:	Set the variable colorline coordinates representing intensity
 * Params:	xzero, yzero, xwidth, yheight describe the graph drawing area
 *		within its (possibly larger) window

 * Subroutine:	init_cgraph_hash
 * Purpose:	Initialize record parameters used to place the hash marks

 * Subroutine:	set_cgraph_hash
 * Purpose:	Set rectangle positions to mark table vertexes for one color
 * PreState:	Must be preceded by init_colorhash whenever window size or
 *		color allocation is changed
 * Returns:	Table index of hash[0] (or where hypothetical hash[0] would be)

GRPHMOVE.C
 * Module:	grphmove.c (Color Graph Move)
 * Subroutine:	move_cgraph_vertices()		returns: void

 * Subroutine:	move_cgraph_vertices
 * Purpose:	Change values (and position) of designated vertices in
 *		response to mouse movement

 * Subroutine:	move_color_vertex
 * Purpose:	Move one ccolor graph vertex

GRPHOLAP.C
 * Module:	grpholap.c (Color Graph Overlap)
 * Purpose:	Draw color graph lines where they overlap
 * Subroutine:	mark_colorline_overlap()		returns: void
 * Xlib calls:	XDrawSegments(), XDrawRectangles()

 * Subroutine:	mark_colorline_overlap
 * Purpose:	Make line representing more than one color black (or white)

 * Subroutine:	mark_hashmark_overlap
 * Purpose:	Make hashmarks which represent more than one color black

GRPHPOS.C
 * Module:	grphpos.c (Color Graph Position)
 * Subroutine:	select_best_hash_position()		returns: int

 * Subroutine:	select_best_hash_position
 * Purpose:	Select the best place in the list for a new hash mark, based
 *		on its coordinates and those of existing hash marks.
 * Returns:	The hash index to give the new hash mark.
 * Note:	match is used to force new vertex to use same cell_level as
 *		the vertex which it is next to. When vertexes have same
 *		screen coordinate, converting to a real may produce values
 *		in the wrong order.

GRPHTEXT.C
 * Module:	grphtext.c (Color Graph Text)
 * Purpose:	Initialize or reset color bar and graph
 * Subroutine:	init_colorbar_label()		returns: void
 * Subroutine:	init_color_graph_label()	returns: void
 * Subroutine:	create_cgraph_box()		returns: Window
 * Xlib calls:	XMoveWindow(), XResizeWindow(), XMapWindow(), XCreateWindow()
 * Xlib calls:	XTextWidth()

 * Subroutine:	init_color_graph_label
 * Purpose:	Set labeling pieces according to the graph window size
 * Xlib calls:	XMoveWindow(), XResizeWindow(), XMapWindow()

 * Subroutine:	init_colorbar_label
 * Xlib calls:	XResizeWindow()

 * Subroutine:	create_cgraph_box
 * Purpose:	Create window with window gravity and optional colored border
 * Xlib call:	XCreateWindow()

HISTDIST.C
 * Module:	histdist.c (Histogram Equalize Distribute)
 * Subroutine:	distribute_levels()			returns: int

 * Subroutine:	distribute_levels
 * Purpose:	Distribute the levels among histogram sub-groups
 * Returns:	number of groups with no assigned color levels

 * Subroutine:	excess_zgroup
 * Purpose:	Find subrange with zero allotted levels and specified excess.
 *		Assign it one level

 * Subroutine:	range_zgroup
 * Purpose:	Find group with zero allotted levels and specified range.
 *		Assign it one level.

 * Subroutine:	excess_nzgroup
 * Purpose:	Find group with non-zero allotted levels and specified
 *		excess value.  Assign it one additional level.

HISTEQL.C
 * Module:	histeql.c (Histogram Equalize)
 * Purpose:	Fill the scalemap by histogram equalization
 * Subroutine:	histogram_equalize()		returns: void

 * Subroutine:	histogram_equalize
 * Purpose:	Create a scaling map which equalizes image cells per
 *		output level optimization accounts for large cell counts
 *		for single levels (e.g. half of all pixels with value 0)

 * Subroutine:	rescan_histogram
 * Purpose:	Repeat scanning for large count levels as saturation level
 *		is modified.  Repeats until all large count levels are
 *		marked and residual is stable
 * Returns:	1 if a range was modified, 0 if nothing was changed

 * Subroutine:	unmark_peak_links
 * Purpose:	Make singularity links non_uniquely marked (range > 0) and
 *		check count against reference
 * Called by:	histogram_equalize() above

 * Subroutine:	count_nonzero_histogram_entries
 * Called by:	histogram_equalize() in HistEqual.c

HISTLIST.C
 * Module:	histlist.c (Histogram List)
 * Subroutine:	make_equalized_list()	returns: void

 * Subroutine:	make_equalized_list
 * Purpose:	Distributing levels for a subrange section of the histogram

 * Subroutine:	equalize_simply
 * Purpose:	Make a list to describe map using basic allocation method
 * Note:	Allocate levels from "level" to "color_levels"

 * Subroutine:	adjust_list
 * Purpose:	Alter a level of the map and remake section above altered level

static int excess_zgroup ( subrange, excess, range, average )
static int range_zgroup (subrange, excess, range, average)
static int excess_nzgroup ( subrange, excess, average )

HISTMAP.C
 * Module:	histmap.c (Histogram Map)
 * Subroutine:	make_HE_scalemap()		returns: int

 * Subroutine:	generate_scalemap
 * Purpose:	Make scalemap, applying standard histgoram equalization
 *		one subrange group at a time
 * Note:	Value range was broken into groups with an assigned number
 *		of levels for each group.  Each group is either a single
 *		value or a range of values with no excessive peaks, such that
 *		standard (non-optimizing) histogram equaliztion algorithm can
 *		safely be applied.
 * Note:	The original link-list of groups is freed.

 * Subroutine:	make_subrange_scalemap
 * Purpose:	Make a section of scale map using histgroup link as guide 
 * Called by:	make_HE_scalemap() in HistEqual.c

 * Subroutine:	list_to_map
 * Purpose:	Make section of map as defined by list
 * Called by:	make_subrange_scalemap() above

 * Subroutine:	make_gapped_list
 * Purpose:	Allocate levels for a histogram subrange.  Special process
 * 		for situation when more levels than actually used values.

 * Subroutine:	first_shortlist_pass
 * Purpose:	Make a list to describe map allocation using special
 *		allocation method.  Fill the list with each entry ending
 *		at the next actually used value.

 * Subroutine:	add_level_to_short_list

HISTSCAN.C
 * Module:	histscan.c (Histogram Scan)
 * Subroutine:	scan_histogram_for_peaks()	returns: void

 * Subroutine:	scan_histogram_for_peaks
 * Purpose:	Scan the image histogram picking out large cell count values
 *		make sub-groups of the histogram between the large count levels

 * Subroutine:	get_new_subrange_record
 * Purpose:	Create a new link in histogram link list, after one given
 * Returns:	Pointer to new subrange link

 * Subroutine:	fill_subrange_record
 * Purpose:	Set parameters in subrange link list record

HISTZERO.C
 * Module:	histzero.c (Histogram Zero)
 * Subroutine:	resolve_zeroes()			returns: void

 * Subroutine:	resolve_zeroes
 * Purpose:	Combine groups with zero alloted levels with adjoining groups
 * Note:	Adjoining groups are large count single level groups
 * Called by:	histrogram_equalize() above

 * Subroutine:	merge_links
 * Purpose:	Combine two links of histogram group list

IEEEVAX.C
 * Module:	ieeevax.c (IEEE to VAX)
 * Purpose:	Converts an IEEE floating point array to VAX floating point
 * Subroutine:	ieee_vax()			returns: void
 * Called by:	read_array in Readarr.c

IMGCHECK.C
 * Module:	imgcheck.c (Image Check)
 * Purpose:	Check parameters for consistency and check image file size
 * Subroutine:	check_image()			returns: int
 * Xlib calls:	none
 * Unix calls:	stat()

 * Subroutine:	check_image
 * Purpose:	Do some consistency checks on image type and size
 * Returns:	0 if no errors found, else -1

 * Subroutine:	check_array
 * Purpose:	Check array size vs file size etc
 * Returns:	0 if size determined and/or OK, else -1

 * Subroutine:	size_imagefile
 * Purpose:	return size of file adjusted for header and storage type

IMGFLIP.C
 * Module:	imgflip.c (Image Flip)
 * Purpose:	Rotate buffer 180 degrees on any orthogonal axis
 * Subroutine:	xflip_buf()			returns: void
 * Subroutine:	yflip_buf()			returns: void
 * Subroutine:	zflip_buf()			returns: void
 * Subroutine:	transfer_buf()			returns: void
 *  Subroutine:	xflip_buf
 *  Purpose:	Flip buf to make Y coordinates run in opposite direction
 *		(upside down)

 *  Subroutine:	yflip_buf
 *  Purpose:	Mirror buf to make x coordinates run in opposite direction

 * Subroutine:	zflip_buf
 * Purpose:	Turn buf upside down (180 degree rotation on image plane)

 * Subroutine:	transfer_buf
 * Purpose:	Move short values to another buffer with optional reorientation

IMGLOGO.C
 * Module:	imglogo.c
 * Purpose:	Put logo in image buffer
 * Subroutine:	color_logo()	returns: void
 * Subroutine:	load_logo()	returns: void
 * Xlib calls:	none

 * Subroutine:	color_logo
 * Purpose:	redirect lookup table to map parts of logo to static colors

 * Subroutine:	make_logo
 * Purpose:	decode run-length encoded saoimage logo into short buffer

 * Subroutine:	load_logo
 * Purpose:	place logo image in image buffer

IMGNEW.C
 * Module:	imgnew.c (Image New)
 * Purpose:	Middle level routines to do all for a new image or buffer
 * Subroutine:	new_display()			returns: void
 * Subroutine:	new_panimage()			returns: void
 * Subroutine:	show_filename()			returns: void
 *  Subroutine:	new_display
 *  Purpose:	Create all image coordinate parameters from the beginning
 * 		and take care of all that might be affected
 This is called when "center" in pan mode is clicked.

 *  Subroutine:	load_mainbuf
 *  Purpose:	Set buf related coords and load image data into main buffer

 *  Subroutine:	new_panimage
 *  Purpose:	Read image data into the panbox short buffer

 *  Subroutine:	show_filename
 *  Purpose:	Print the image file name in the desktop

IMGPARAM.C
 * Module:	imgparam.c (Image Parameters)
 * Purpose:	Resolve missing image and display parameters
 * Subroutine:	init_img()			returns: void
 * Subroutine:	init_dispcen()			returns: void
 * Xlib calls:	none

 * Subroutine:	init_img
 * Purpose:	Resolve readable subsection selection and fill in
 *		missing params
 * Called by:	init_image in ImageRead.c
 * Called by:	imtool_reinit in RemoteImtool.c

 * Subroutine:	init_dispcen
 * Purpose:	Adjust chosen or default display parameters
 * Called by:	init_image in ImageRead.c
 * Called by:	imtool_reinit in RemoteImtool.c

IMGREAD.C
 * Module:	imgread.c (Image Read)
 * Purpose:	Read image headers and image files
 * Subroutine:	init_image()			returns: int
 * Subroutine:	load_image()
 * Xlib calls:	none

 * Subroutine:	init_image
 * Purpose:	Set the image dimensions
 * Returns:	1 if OK, 0 if trouble
 * Method:	set image info from known values or read from a header

 * Subroutine:	load_image
 * Purpose:	Open if necessary, then read the appropriate image file
 *		and create a 16 bit image array

IMGROT.C
 * Module:	imgrot.c (Image Rotate)
 * Purpose:	Routines to rotate the img buffer 90 degrees
 * Subroutine:	cwturn_buf()			returns: void
 * Subroutine:	ccwturn_buf()			returns: void

 * Subroutine:	cwturn_buf
 * Purpose:	Rotate a square buffer 90 degrees clockwise

 * Subroutine:	ccwturn_buf
 * Purpose:	Rotate a square buffer 90 degrees counter-clockwise

IMGTRANS.C 
 * Module:	imgtrans.c (Image Transformation)
 * Purpose:	Routines to orthogonally translate buffers.
 * Subroutine:	rotate_buf()			returns: void

 * Subroutine:	rotate_buf
 * Purpose:	Rotate a buffer as indicated by the code
 * Parameter:	rotcode
 * 	0-3 = rotate clockwise by code * 90 degrees
 * 	4-7 = flip y axis then rotate clockwise by (code - 4) * 90 degrees
 * Called by:	load_image() in ImageRead.c

 * Subroutine:	square_buf
 * Purpose:	Rearrange lines in a buffer for square symmetry
 * Exception:	Assumes that height of rectangle is greater than width
 * Parameter:	left
 *	left = 1 will put reactangle on left with lines padded out
 *	left = 0 will put rectangle on right with padded in front of lines

 * Subroutine:	unsquare_buf
 * Purpose:	Make rectangular data in square buffer occupy rectangle at top
 * Exception:	Assumes output height is greater than width
 *	left = 1 moves data which is on left side of square
 *	left = 0 moves data which is on right side of square

IMTOOLRC.
# IMTOOL -- Defined frame buffer configurations.  Note that the given nframes
# is only a starting point, and may be modified during execution, hence smaller
# values are preferred.  The configuration numbers may be given in any order,
# but must be unique and in the range 1-64.  NOTE - corresponding entries must
# be present in the dev$graphcap file, for use with IRAF.
#
# Format:  configno nframes width height

 1  2  512  512		# imt1|imt512
 2  2  800  800		# imt2|imt800
 3  2 1024 1024		# imt3|imt1024
 4  1 1600 1600		# imt4|imt1600
 5  1 2048 2048		# imt5|imt2048
 6  1 4096 4096		# imt6|imt4096
 7  1 4096 1024		# imt7|imt4x1
 8  1 1024 4096		# imt8|imt1x4
 9  2 1144  880		# imt9|imtfs	full screen (1152x900 minus frame)
10  2 1144  764		# imt10|imtfs35	full screen at 35mm film aspect ratio
11  2  128  128		# imt11|imt128
12  2  256  256		# imt12|imt256

# Some site specific formats for NOAO.
20  2  388  576		# imt20|imtgec	GEC CCD detector format
21  1 3040  976		# imt21|imtkpca	KPCA detector format (also 2D-Frutti)
22  1  128 1520		# imt22|imt2df1 2D-Frutti
23  1  256 1520		# imt23|imt2df2 2D-Frutti
24  1  512 1520		# imt24|imt2df5 2D-Frutti
25  1  960 1520		# imt25|imt2df9 2D-Frutti
26  1  512  800		# imt26|imtcryo Cryogenic Camera
27  1  348  800		# imt27|imtgcam Gold Camera
28  1  976 3040		# imt28|imt2df9x3 2D-Frutti 
29  1  800  256         # imt29|imtgong Gong Cache Monitor
30  1  256  800         # imt30|imtgong Gong Cache Monitor
31  1 1240  400		# imt31|imtret Reticon CCD detector format
The file name is defined as FBCONFIG_ENV2 in IMTOOL.H, and called up by
get_fbconfig in IRAFENV.C.  A frame size is identified by its configuration
number, not its order in the file;  e.g., configuration number 2 is 800x800
pixels, and is identified in the IMTOOL protocol by 8705.  For IMTOOL headers,
the WCS header should have imhead->t & 077 equal to the configuration 
number - 1.  For other IMTOOL headers (only FEEDBACK now), the configuration 
number should equal imhead->tid & IMT_FBCONFIG - 1, where IMT_FBCONFIG=077.

IRAFCRD.C
 * Module:	irafcrd.c (IRAF Coordinates)
 * Purpose:	Parse wcs filename string for IRAF subsection coordinates
 * Subroutine:	guess_true_file_coords()	returns: int

 * Subroutine:	guess_true_file_coords
 * Purpose:	Parse wcs filename string for the user's "rect" subsection.
 *		If found and parsed, compute new transform for file coord.
 * Returns:	1 if subsection found and parsed successfully, else 0

 * Subroutine:	parse_iraf_subsection
 * Purpose:	Parse for subsection and blocking from the image name
 * Returns:	1 if subsection or blocking was used, else 0

 * Subroutine:	get_subsection_offsets
 * Purpose:	parse subsection syntax for x and y offsets of subsection

 * Subroutine:	fn_substr
 * Purpose:	Find the next instance of a string in another string 
 * Note:	This routine is a bit different in that it ignores spaces
 *		in checking and returns a pointer after the substring

IRAFDISP.C
 * Module:	irafdisp.c (Iraf Display)
 * Purpose:	Respond to input from IRAF meant for Imtool
 * Subroutine:	imtool_reinit()			returns: int
 * Subroutine:	disp_subpiece()			returns: void
 * Subroutine:	set_imtool_scale()		returns: void
 * Subroutine:	set_imtool_color()		returns: void

 * Subroutine:	imtool_reinit
 * Purpose:	Reinitialize parameters after any buffer size change and
 *		before loading new

 * Subroutine:	disp_subpiece
 * Purpose:	Map and display a sub-section of the full buffer.
 This subroutine retrieves the width and height of the desktop display window,
 and compares the values with dx1, dy1, dx2, dy2, where 
 dx1 = left side of subimage measured from left side of buffer
 dy1 = top side of subimage measured from top side of buffer
 dx2 = right side of subimage measured from left side of buffer
 dy2 = bottom side of subimage measured from top side of buffer
 These are floating point values
 The argument list is ( x1, y1, x2, y2) where
 x1 = 0
 y1 = packet_y1
 x2 = frame buffer width - 1
 y2 = packet_y2 - 1
 packet_y1 and packet_y2 
 It is called as disp_subpiece(0, packet_y1, imtool_cols - 1, packet_y2 - 1)
 in imtool_response, where packet... is obtained from imtool_input and
 imtool_cols is obtained from imtool_newimage.
 packet_y1 is the upper coordinate of the subpiece = imhead->y & 077777
 measured in frame buffer coordinates.  packet_y2 is 1 greater than the
 bottom coordinate of the subpiece in frame buffer coordinates.
 imtool_input also loads the data into the array imagebuf starting at 
 location = imagebuf + (y * owdth) + x, where owdth is the buffer width in
 pixels and x and y are in the imtool header.  imagebuf is declared as
 buffer.filebuf

 * Subroutine:	set_imtool_scale
 * Purpose:	Force the scalemap to match the range of imtool image data
 iraf:  color.scale.mode=1 (linear) color.ncolors=200

 * Subroutine:	set_imtool_colors
 * Purpose:	Map colors used as graphics options in imtool

IRAFENV.C
 * Module:	irafenv.c (IRAF Environment)
 * Purpose:	Do things needed to coorinate paths and coordinates with IRAF
 * Subroutine:	update_wcs()		returns: int
 * Subroutine:	get_fbconfig()		returns: int
 * Subroutine:	set_path_iraf()		returns: void
 * Unix calls:	fopen(), fclose(), getenv()

 * Subroutine:	set_path_iraf
 * Purpose:	Construct the pathname of a user datafile by IRAF convention.

 * Subroutine:	update_wcs 
 * Purpose:	Load the screen WCS, if not yet validated, from the user
 *		wcs file, if any.  (wcs =  "WORLD COORDINATE SYSTEM")
 * UNIX calls:	fopen(), fclose()
 * Note:	File format (two lines):
 *		image title (imtool header label string)\n
 *		a b c d tx ty (WCS coordinate transformation matrix)
 This subroutine reads the packet following the WCS header when instructed
 to do so by imtool_response following a call to read_connection and interprets
 the values of 10 tokens for an Imtool load.  
 They are: label xx yx xy yy xo yo low high w_type
 The bias and scale are determined from 
      image->fiscale = (high - low) / (CMS_DATARANGE - 1);
      image->fibias = low - image->fiscale;
 where CMS_DATARANGE=200
 The displayed intensity is determined from
     val = buffer.shortbuf[(int)bufX + ((int)bufY * coord.buf.width)];
     rval = ((double)val * img.fiscale) + img.fibias;
 where val is the unsigned byte value loaded with Imtool.
 Val determines the color.  The correspondence is:
 val (signed byte) val (unsigned byte) color
	0		0		black
	.		.		  .
	.		.		  .
      127	      127		grey
     -128	      128		grey+
	.		.		  .
	.		.		  .
      -56	      200		white-
      -55	      201		green
      -54	      202		black
      -53	      203		white
      -52	      204		red
      -51	      205		green
      -50	      206		blue
      -49	      207		yellow
      -48	      208		black
      -47	      209		white
      -46	      210		yellow
      -45	      211		red
      -44	      212		yellow
      -43	      213		white
      -42	      214		red
      -41	      215		green
      -40	      216		blue
      -39	      217		white
      -38 to -1	      218 to 255	white-

 * Subroutine:	get_fbconfig
 * Purpose:	Read the IMTOOL startup file to get frame buffer sizes.
 * UNIX calls:	fopen(), fclose(), getenv()
 * File format:		configno nframes width height [extra fields]
 *		e.g.,		1  2  512  512
 *				2  2  800  800
 *				3  1 1024 1024		# comment

IRAFFDBK.C
 * Module:	iraffdbk.c (IRAF Feedback)
 * Purpose:	Set the mouse pointer icon for each window and mode
 * Subroutine:	set_cursor_from_iraf()		returns: void
 * Subroutine:	send_curpos_to_iraf()		returns: void
 * Subroutine:	trigger_curpos_to_iraf()	returns: int
 * Subroutine:	set_curpos_to_iraf_trigger()	returns: void
 * Origin:	Some sections modeled after code by Doug Tody, NOAO

 * Subroutine:	set_cursor_from_iraf
 * Purpose:	Respond to an imtool IMCURSOR/IIS_WRITE packet from the pipe
 * Note:	imtool equiv.: Write (set) the logical image cursor position.
 Arguments are fileX and fileY.  Action depends on cursor.type.  Possibilities
 are:
	COP_Polygon = 0x0200    with cursor.annuli
	COP_Point = 0x0100
 This subroutine doesn't read another group of bytes for more information.

 * Subroutine:	send_curpos_to_iraf
 * Purpose:	Return the cursor value on the output datastream to the
 *		client which requested the cursor read.
 * Note:	imtool equivalent subroutine: gio_retcursorval()
 This subroutine encodes the arguments provided in the call, and sends them
 out over via the Imtool protocol.  

 * Subroutine:	set_curpos_to_iraf_trigger
 * Purpose:	Set up mode to send cursor position when a key is struck
 * Note:	Equivalent imtool subroutine: gio_readcursor()
 * GIO_READCURSOR -- Initiate an image cursor read.  Save the current
 * mouse coordinates if outside the imtool window, restore the mouse to the
 * imtool window, and change the cursor shape to indicate that a cursor read
 * is in progress.  May be called while a cursor read is already in progress
 * to reset the cursor-read cursor pixrect.
 This subroutine sets things up so that key_response will use a keypress to
 call trigger_curpos_to_iraf.

 * Subroutine:	trigger_curpos_to_iraf
 * Purpose:	Send cursor position to IRAF in response to trigger event
 This subroutine is called by set_curpos_to_iraf_trigger.  It then 
 calls send_curpos_to_iraf

IRAFIMTL.C
 * Module:	irafimtl.c (IRAF Imtool)
 * Purpose:	Respond to input from IRAF meant for Imtool
 * Subroutine:	imtool_response()	returns: void
 * "For the moment we take an IIS model 70 command/data stream as input; this
 * is used to load images into the image display.  This is a kludge interface
 * for the prototype, convenient since the high level software is written for
 * the IIS." - explanation by Doug Tody

 * Subroutine:	imtool_response
 * Purpose:	Read imtool messages from iraf (return 1 if pipe trouble)
  case FEEDBACK:
     * The IIS feedback unit is used to clear the screen */
     The command is contained in imhead->subunit & 077, which equals 5
     in this case.  This is defined as struct imtoolRec *imhead, where
     imtoolRec is
struct imtoolRec {
  short tid;            /* Type of message identifier ("transfer id") */
  short thingct;        /* Count appropriate to message type */
  short subunit;        /* Intended target type (MEMORY,LUT,FEEDBACK,etc) */
  short checksum;       /* Error check */
  short x, y;           /* (y,x & 01777) are UL coordinates in MEMORY packet */
  short z;              /* (z & 07777) is frame number in FEEDBACK & MEMORY */
  short t;              /* ? */
     If an erase command is sent to SAOimage the screen and pan and magnifier
     boxes are erased, but a 512x512 frame remains on the desktop.

  case WCS:
     * Read or write the WCS for a frame.  The frame number to
     * which the WCS applies is passed in Z and the frame buffer
     * configuration in T.  The client changes the frame buffer
     * configuration in a WCS set.  The WCS text follows the header
     * as byte packed ASCII data.
       frame = get_frame_no(imhead->z);
     It looks for a number of bytes equal to SIZE_WCSBUF=320
  case IMCURSOR: = 020
     * Read or write the logical image cursor.  This is an extension
     * added to provide a high level cursor read facility; this is
     * not the same as a low level access to the IIS cursor subunit.
     * Cursor reads may be either nonblocking (immediate) or blocking,
     * using the keyboard or mouse to terminate the read, and
     * coordinates may be returned in either image (world) or frame
     * buffer pixel coordinates.
    if( imhead->tid & IIS_READ ) = 0100000
      /* Read the logical image cursor.  In the case of a blocking
       * read all we do is initiate a cursor read; completion occurs
       * when the user hits a key or button.
      if( imhead->tid & IMC_SAMPLE ) = 0040000
        /* Sample the cursor position. */
        /* Return the cursor value on the output datastream encoded
         * in a fixed size ascii buffer.
        send_curpos_to_iraf(cursor.file.X, cursor.file.Y, frame_number,
                            imhead->z, 0, "");
      else
        /* Initiate a user triggered cursor read. */
        set_curpos_to_iraf_trigger(frame_number, imhead->z);
This is the section that IRAF and MIIPS use;  imhead->tid = 0100000
    else
      set_cursor_from_iraf((double)(imhead->x & 077777),
                           (double)(imhead->y & 077777));

  case MEMORY:
The variable imtool_cols is used in the argument list for subroutines
imtool_input and disp_subpiece.  It is equal to the width of the image
frame buffer.  Its value is set in a call to imtool_newimage which gets
its value in a call to get_fbconfig which gets it by reading the configuration
file and comparing its list with the configuration number in the Imtool 
header for WCS.

 * Procedure:	imtool_newimage
 * Purpose:	Reset buffer sizes, coordinate systems and parameters as
 *		needed.

 * Subroutine:	get_frame_no
 * Purpose:	Figure out the integer frame number for its mask

IRAFIO.C
 * Module:	irafio.c (IRAF Input Output)
 * Purpose:	Read an image in from the IRAF pipe
 * Subroutine:	open_imtool_connection()	returns: void
 * Subroutine:	close_imtool_connection()	returns: void
 * Subroutine:	rename_imtool_connection()	returns: void
 * Subroutine:	imtool_input()			returns: int
 * Subroutine:	imtool_output()			returns: int

 * Subroutine:	open_imtool_connection
 * Purpose:	open the connection for IRAF

 * Subroutine:	close_imtool_connection
 * Purpose:	close the connection for IRAF

 * Subroutine:	rename_imtool_connection
 * Purpose:	assign a new name to the imtool connection

 * Subroutine:	imtool_output
 * Purpose:	Write image data back to iraf device channel

 * Subroutine:	imtool_input
 * Purpose:	Load image data from iraf input device channel
 * Called by:	imtool_response() in RemoteImtool.c
 * Returns:	-1 if read no bytes, 1 if trouble, else 0

 * Subroutine:	expand_byte_to_short
 * Purpose:	Unpack byte data for use as shorts

IRAFPIPE.C
 * Module:	irafpipe.c (IRAF Pipe Connection)
 * Purpose:	Read an image in from the IRAF pipe
 * Subroutine:	read_imtool_packet()		returns: void

 * Subroutine:	read_imtool_packet()
 * Purpose:	event handler for packet input from iraf
   This subroutine reads the IMHEAD header, declared as 
   struct imtoolRec imhead, ie.,
struct imtoolRec {
  short tid;            /* Type of message identifier ("transfer id") */
  short thingct;        /* Count appropriate to message type */
  short subunit;        /* Intended target type (MEMORY,LUT,FEEDBACK,etc) */
  short checksum;       /* Error check */
  short x, y;           /* (y,x & 01777) are UL coordinates in MEMORY packet */
  short z;              /* (z & 07777) is frame number in FEEDBACK & MEMORY */
  short t;              /* ? */
};
   It does this with the call
   bytes = read_connection(port, (char *)&imhead, sizeof(struct imtoolRec))
   The first 2 bytes of each group read through the mailbox and sent to this
   subroutine, are equal to imhead.tid.  Notice that initially, every other
   group of bytes is sent to this subroutine.  When a group is sent here,
   it always has 16 bytes.  For an image loaded by IRAF we 
   have, in order, 
                                                                   maxnbytes
   If PACKED is true, thing.ct measures bytes rather than words
   bytes =   0    1 =    256 =                                         16
   bytes =   0    0 =      0 =                          Not called      6
   bytes =   0   64 =  16384 = PACKED = IMC_SAMPLE                     16
   bytes =  99  104 =  26723 =                          Not called     40
   bytes =   1   34 =   8705 =                                         16
   bytes =   0 -128 = -32768 =                          Not called      2
   bytes =   0    1 =    256 =                                         16
   bytes =   1    0 =      1 =                          Not called     24
   bytes =   0  114 =  29184 = PACKED = IMC_SAMPLE                     16
   bytes = -56  -56 = -14136 =                          Not called   8192
   bytes =   1  -56 = -14335 =                          Not called   7808
   bytes =   0  114 =  29184 = PACKED = IMC_SAMPLE                     16
   bytes = -56  -56 = -14136 =                          Not called   8192
   bytes =   1  -56 = -14335 =                          Not called   7808
   The second 2 bytes of each group read through the mailbox and sent to this
   subroutine are equal to -imhead.thingct.  For an image loaded by IRAF 
   we have, in order, 
   bytes =   -3   -1 =     -3  
   bytes =    0    0 =      0  Not called
   bytes =  -40   -1 =    -40    
   bytes =  101   99 =  25445  Not called
   bytes =   -1   -1 =     -1
   bytes =    0    0 =      0  Not called
   bytes =  -12   -1 =    -12
   bytes =    1    0 =      1  Not called
   bytes = -128  -63 =  16000
   bytes =  -56  -56 = -14136  Not called
   bytes =    1  -56 = -14335  Not called
   The third 2 bytes of each group read through the mailbox and sent to this
   subroutine are equal to su = imhead.subunit & 077.  For an image loaded 
   by IRAF we have, in order, 
   bytes =  12    1 =   12 = ZOOM/PAN (ignored)
   bytes =   0    0 =    0                         Not called
   bytes =  17    0 =   17 = WCS
   bytes = 107   50                                Not called
   bytes =   5    0 =    5 = FEEDBACK
   bytes =   0    0 =    =                         Not called
   bytes =   2 -128 =    2 = LUT
   bytes =   1    0                                Not called
   bytes =   1    0 =    1 = MEMORY
   bytes = -56  -56                                Not called
   bytes =   1  -56                                Not called
        /* octal codes for the imtool packet (IIS) header */
#define MEMORY          001     /* packet with image data */
#define LUT             02      /* switch display buffer */
#define FEEDBACK        005     /* for imtool, do clear and fbconfig */
#define IMCURSOR        020      /* logical image cursor */
#define WCS             021     /* used to set WCS */
#define PACKED          0040000 /* bit indicates byte data (in tid) */
#define COMMAND         0100000 /* bit with LUT to set disp frame */
#define IIS_READ        0100000 /* tid w/ MEMORY to read back dsip buf */
#define IMC_SAMPLE      0040000 /* code for read cursor now */
#define IMT_FBCONFIG    077     /* mask for fbconfig num (in tid) */
   It finally calls imtoolresponse(port, &imhead, ndatabytes)

 * Subroutine:	check_packet_sum
 * Purpose:	Check packet sum against checksum (and verify byteswap)
 * Returns:	1
   This subroutine is called by read_imtool_packet
   The check is done as follows on the first 16 bytes of a packet
  while( 1 ) {
    /* add up the sum */
    for( i=0, sum=0, p=(short *)packet;  i < 8;  i++ )
      sum += *p++;
    /* sum (including checksum) should roll at 0177777 */
    if( (sum & 0177777) == 0177777 )
      return( 1 );

MGFYCTRL.C
 * Module:	mgfyctrl.c (Magnify Control)
 * Purpose:	Initialize params and organize drawing the magnifier window
 * Subroutine:	magnify_disp()			returns: void
 * Subroutine:	magnify_pan()			returns: void
 * Subroutine:	clear_coord_area()		returns: void
 * Subroutine:	redraw_magnifier()		returns: void
 * Xlib calls:	XCheckWindowEvent(), XSync()

 * Subroutine:	magnify_disp
 * Purpose:	Magnify location of a dispbox event
 * Xlib calls:	XCheckWindowEvent(), XSync()
   The call is made as magnify_disp ( event, view, text ) where view and 
   text are set by control.coord_track and control.magni_track, respectively.

 * Subroutine:	magnify_pan
 * Purpose:	Magnify location of a panbox event
 * Xlib calls:	XCheckWindowEvent(), XSync()

 * Subroutine:	redraw_magnifier
 * Purpose:	Draw image piece in zoombox window, using last coords or
 *		dispbox center

 * Subroutine:	label_file_coords
 * Purpose:	Show pointer coordinates and image value in display window
 * Xlib calls:	XDrawImageString()
   This is called as cursor is moved over desktop and X, Y, and pixel intensity
   are printed out.  
   For the initial boot, img.fscaled=0, img.fiscaled=0, img.fbias=0.000000,
   img.fscale=1.000000, img.fibias=0.000000, and img.fiscale=1.000000.  
   The intensity is read directly from 
     buffer.shortbuf[(int)bufX + ((int)bufY * coord.buf.width)]
   For an Imtool load, img.fscaled=0, img.fiscaled=1, img.fbias=0.000000,
   img.fscale=1.000000, img.fibias=10000.0, and img.fiscale=-0.005025, for
   val=0, rval=10000.
   The intensity is read from
     val = buffer.shortbuf[(int)bufX + ((int)bufY * coord.buf.width)];
     rval = ((double)val * img.fiscale) + img.fibias;
   If a FITS file is loaded before the Imtool load, img.fbias and img.fscale
   are retained from the FITS load.
   For a FITS file load, img.fscaled=1, img.fiscaled=1, img.fbias=map value,
   img.fscale=map value, img.fibias=map value, and img.fiscale=map value.
   The intensity is read from
     rval = (double) *((int *)(buffer.filebuf +
          (((int)fbX + ((int)fbY * coord.fbuf.width)) * sizeof(int))));
     rval = img.fbias + (rval * img.fscale);
   For a SAD load, img.fscaled=0, img.fiscaled=0, img.fbias=0.0
   img.fscale=1.0, img.fibias=0.0, img.fiscale=1.0, 
   The intensity is read from
    val = buffer.shortbuf[(int)bufX + ((int)bufY * coord.buf.width)];
   For a SAD load after FITS load, img.fscaled=1, img.fiscaled=1, 
   img.fbias=-400.000000, img.fscale=0.400000, img.fibias=-400.000000, 
   img.fiscale=0.400000.   The intensity is read from
     rval = (double) *((int *)(buffer.filebuf +
          (((int)fbX + ((int)fbY * coord.fbuf.width)) * sizeof(int))));
     rval = img.fbias + (rval * img.fscale);
   Unfortunately, if a FITS file is loaded before, img.fbias and img.fscale
   are retained from the FITS load, and rval is wrong!  Previous IRAF load is
   ok.
   The limiting intensity values 
   for an img.fscale=1 call are given by buffer.clipmin and buffer.clipmax.  The 
   intensity values are given by 
   val = buffer.shortbuf[(int)bufX + ((int)bufY * coord.buf.width)], where 
   rval = ((double)val * img.fiscale) + img.fibias.
   For an img.fscale=0 call, the intensities are given by
   val = buffer.shortbuf[(int)bufX + ((int)bufY * coord.buf.width)]

 * Subroutine:	clear_coord_area
 * Purpose:	Erase area of coords, esp. when imtool_aux is no longer used

 * Subroutine:	label_file_coords_proportional
 * Purpose:	Show pointer coordinates and image value in display window
 *		Special handling for proporitonal fonts is good for the coords,
 *		but has not been refined for the val section.
 * Xlib call:	XDrawImageString()

 * Subroutine:	draw_proportional_coord
 * Purpose:	Draw proportional text to cover area and place decimal point

 * Subroutine:	blank_scope
 * Purpose:	Fill scope with blank data




MAINBFFR.C
 * Module:	mainbffr.c (Main Buffers)
 * Purpose:	Allocate or reallocate large buffers
 * Subroutine:	init_imaging buffers()		returns: void
 * Subroutine:	init_display_buffers()		returns: void
 * Subroutine:	init_colorbarbuf()		returns: void
 * Subroutine:	init_panbuf()			returns: void
 * Subroutine:	init_dispbuf()			returns: void
 * Subroutine:	init_imagebuf()			returns: int
 * Xlib calls:	none

 * Subroutine:	init_imaging_buffers
 * Purpose:	Allocate major buffers used for imaging

 * Subroutine:	init_display_buffers
 * Purpose:	Allocate buffers used for each window's display

 * Subroutine:	init_panbuf
 * Purpose:	Allocate or reallocate panbox display buffers

 * Subroutine:	init_dispbuf
 * Purpose:	Allocate or reallocate dispbox display buffer

 * Subroutine:	init_imagebuf
 * Purpose:	Allocate or reallocate main image buffer to fit img or as
 *		much as allowed.  Also allocate file data buffer if data
 *		cannot be read directly into i*2 buf.
 * Returns:	1 on success, else 0.
 * Post-state:	buffer.load_filebuf set to 0 if alloc's failed.
 * Method:	Try to allocate enough for entire given image subsection.
 *		If the display is to be rotated, make the short buf square
 *		or double (whichever is less).
 * Parameters:
 *	buffer:		i/o: record structure for imaging buffers
 *	coord.img:	i: coordinate system of image or image subsection
 *	coord.buf:	o: coordinate system of short integer image buffer

MAINEVNT.C
 * Module:	mainevnt.c (Main Event)
 * Purpose:	Main Event Loop and Dispatcher
 * Subroutine:	control_event_loop()		returns: void
 * Xlib calls:	XPending(), XNextEvent()
 * UNIX calls:	select()

 * Subroutine:	control_event_loop
 * Purpose:	Main event loop and dispatcher
 * Xlib calls:	XNextEvent();
   This subroutine is called anytime something happens, such as moving the
   mouse, clicking the mouse, etc. 

MAININIT.C
 * Module:	maininit.c (Main Initialize)
 * Purpose:	Start of the saoimage package
 * Program:	main()
 * Subroutine:	crash_on_error()
 * Xlib calls:	XSetErrorHandler(), XCloseDisplay(), XGetErrorText()
 * UNIX calls:	setrlimit(), ieee_handler(), abrupt_underflow_()

 * Program:	main
 * Purpose:	Get things started, then call event_loop
 * Xlib calls:	XSetErrorHandler()
 * UNIX calls:	setrlimit()

 * Subroutine:	say_goodbye
 * Purpose:	Free server resources before exiting
 * Xlib calls:	XCloseDisplay()

 * Subroutine:	init_params
 * Purpose:	Initialize parameters in the records
 * Note:	Resource or default file not yet used

 * Subroutine:	init_packages
 * Purpose:	Initialize all of the subroutine packages and windows

 * Subroutine:	crash_on_error
 * Purpose:	Special error handler to force crash on error
 * Xlib calls:	XGetErrorText()

 * Subroutine:	init_server
 * Purpose:	Open connection with chosen or default display server


MGFYINIT.C
 * Module:	mgfyinit.c (Magnify Initialize)
 * Purpose:	Initialize parameters for drawing the zoomed piece of image
 *		in the magnifier box
 * Subroutine:	init_magnifier()			returns: void
 * Subroutine:	set_magnifier()				returns: void
 * Subroutine:	set_magnifier_dither()
 * Xlib calls:	XTextWidth()

 * Subroutine:	init_magnifier
 * Purpose:	Init that which gets set only once, and then the rest as well
 * Xlib calls:	XTextWidth()
   This subroutine sets the values of magset.view and magset.label to the values
   of control.magni_track, and control.coord_track, respectively.  These values
   don't seem to be used again.

 * Subroutine:	set_magnifier()
 * Purpose:	Set up initial parameters for magnifier box
 * Use:		Call whenever the magnifier box is resized or the image buffer
 *		is altered (reloaded or altered)

 * Subroutine:	set_magnifier_matrix
 * Purpose:	Change the dither matrix used by scope






SCLMAP.C
 * Module:	sclmap.c (Scale Map)
 * Purpose:	Map image values to display screen values using various
 *		functions
 * Subroutine:	make_scalemap()			returns: void

 * Subroutine:	make_scalemap
 * Purpose:	Make scale map according to type selected
 * Note:	Map goes from image value to hardware value (through ideal
 *		map value using pixels array from XAllocColors)
 iraf:  image_min=0 image_max=199
 loading of file:  image_min, image_max actual values

 * Subroutine:	linear_scale
 * Purpose:	Distribute color levels in the map evenly

 * Subroutine:	wrap_scale
 * Purpose:	Create the image map with a repeating linear scale
 * Note:	Levels below image_min are not mapped

 * Subroutine:	sqrt_scale
 * Purpose:	Distribute color levels in the map by a root or power function.
 * Method:	(level / maxlevel) ranges from 0 to 1.  Raise to a power.
 *		Result curves from 0 to 1.  Map result directly back to
 *		pixel value.

 * Subroutine:	log_scale
 * Purpose:	Distribute color levels in the map by a logorithmic or
 *		exponential curve (powers of e).







 * XZ_ast - Asynchronous System Trap routine for X window and Z events.
 *	Simply set the appropriate event flag.

void XZ_ast (int efn)


COLOR.H
 * Module:	Color.h
 * Purpose:	Define the structs for color control parameters and some
 *		related constants

struct colmapRec {
  int private_used;		/* flag using private colormap */
  int private_installed;	/* flag private map is installed */
  int default_permit;		/* user permission to use default map */
  int default_enable;		/* confirmed ability to use default map */
  int private_permit;		/* user permission to use private map */
  int private_enable;		/* confirmed ability to use private map */
  Colormap default_colormap;	/* default colormap of root */
  Colormap private_colormap;	/* private created colormap */
  XVisualInfo *default_vinfo;	/* info about the default visual */
  XVisualInfo *private_vinfo;	/* info about a private visual */
};

struct cellspecRec {
  int overlay;			/* request for overlay plane */
  int wanted;			/* desired (maximum) number of cells */
  int min;			/* minimum acceptable number of cells */
  int got;			/* actual number of cells reserved */
};

struct colorRec {
  Display *display;		/* display server */
  int screen;			/* screen id for display server */
  int screen_depth;		/* number of color hardware planes */
  Visual *visual;		/* visual of the current colormap */
  Colormap colormap;		/* server colormap being used */
  int monochrome;		/* only one color with fixed values */
  int single_plane;		/* one plane, use dither or diffuse */
  int cursor_overlay;		/* overlay plane in use flag */
  int ncolors;			/* number of colors reserved for image */
  int inverse;			/* forward or inverse values */
  int colormap_mode;		/* halftone, pseudo, fixed */
  int color_tableID;		/* id of predefined colorset */
  int control_mode;		/* ContBias, ThreshSat, gamma */
  int control_mode_ext;		/* R_G_B, RGB (separate, combined) */
  int colors_alloced;		/* flag that colors were alloc'ed */
  int old_mode;			/* previous mode (when new change) */
  int image_plane_mask;		/* mask for image planes only */
  unsigned long overlay_mask;	/* mask with bit for overlay cursor */
  struct scalemodeRec scale;	/* parameters for image scaling modes */
  struct colmapRec map;		/* describe which colormap to use */
  struct cellspecRec cells;	/* request for cells */
  struct palletteRec hard;	/* read-only basic colors */
  struct halftoneRec halftone;	/* halftoning stuff */
  struct curcolorRec cur;	/* cursor drawing stuff */
  struct gcsetRec gcset;	/* specifications of GC's used */
  struct colorTable ctable;	/* pseudocolor vertex table */
  unsigned long pixvalmap[COLMAPSZ];	/* byte val to hardware pixel val */
  XColor cellstore[COLMAPSZ];		/* used to set colors */
};





