		Implementation Notes
		       on the
		    Xgopher client


These notes describe Xgopher version 1.1, completed in April 1992.
The implementor and author of these notes can be contacted at:

	Allan Tuchman
	Computing and Communications Services Office (CCSO)
	University of Illinois at Urbana-Champaign
	1304 W. Springfield Ave.
	Urbana, Illinois   61801

	(217) 244-0048
	a-tuchman@uiuc.edu


Source Organization
-------------------
The xgopher source files are organized by function.  They are:

    xgopher.c - main program, initialize X, set up initial request.
    list.c    - create and maintain all gopher item and gopher directory
		data structures.  This provides the backbone of xgopher.
    util.c    - does gopher processing, get and process gopher requests
    misc.c    - misc things like time functions that may be host dependent
    net.c     - open, read, and write from a network connection
    help.c    - manage help file data.

   ------  No file above here has any connection to the X window system -----

    gui.c     - interface between the previous files and X functions
    options.c - retrieve application resources
    cso.c     - create, manage, and process requests for CSO name servers
    index.c   - create and manage panel to get keywords for index searches
    panel.c   - create and manage the main xgopher panel
    error.c   - create and manage the error pop up
    save.c    - create and manage the file save pop up and functions
    text.c    - create and manage the text display pop ups
    KeyWSink.c- subclass of AsciiSink widget that can highlight
		selected keywords

The include files are used to provide functions definitions, 
configuration options, data structure declarations, share data,
and define bitmaps.  They are:

    conf.h       - configuration parameters
    gopher.h     - data structure definitions for items and directories
    options.h    - the definition of the application resources structure
    resources.h  - the global definition of the app. resources structure
    globals.h    - a couple of variables, symbolic constants, and macros
    xglobals.h   - shared values defined in the X files
    listP.h      - resources used only in list.c (provided by options.c)
    prefixP.h    - resources used only in util.c (provided by options.c)
    KeyWSink.h   - public header file for KeyWSink widget
    KeyWSinkP.h  - private header file for KeyWSink widget
    bitmaps/*    - contains bitmaps and icons.

    gui.h,  list.h,  misc.h,  net.h,  util.h, help.h,  cso.h,
    index.h, error.h
                 - function declaration headers

Other files:

    Imakefile    - used to generate a Makefile
    README, RELEASE_NOTES, IMPL_NOTES
		 - documentation files interesting to the installer/programmer
    xgopher.help - a sample help file
    xgopher.man  - a Unix manual page for xgopher
    xgopher.ad   - the applications defaults file.  It MUST be used!
    Version      - contains the current Xgopher source version number.


I have tried to keep major operating system dependencies all in the
file misc.c. Different versions of Unix may have slightly different
programming requirements.  These slight variations are handled through
preprocessor directives in the appropriate source files.


Resource Usage
--------------

I have made considerable effort to maintain and reuse every resource
allocated.  Memory for major data structures is never freed back to the
system, but structures that are no longer in use are maintained and reused
again later.  The idea is that it is expensive to get and build
things, but cheap to reuse them.  This philosophy applies to
  . gopher items (the lines you see on the screen and their selector
    information).
  . gopher directories
  . X window text popups
  . Other popups, panels, and help data.
  . Lists created and used to display the X directory and bookmark
    contents lists.


Positioning Popup Windows
-------------------------

Everyone has there own preferences as to where popups should appear.
There are good arguments for having them 1) near the cursor, 2) a
constant position on the main application window, and 3) a constant
location on the screen.

If you want to change popup positions, here's how to do it in the
source program.  Future versions of Xgopher may allow such
preferences in the application defaults file.

Text (and help) displays are not transient windows, and I leave their
placement to the window manager and the user's window manager preferences.
For all transient windows I place them with a single, pretty general
function call.  The call 

    positionPopup(w, from, fromWidget, x, y, hJust, vJust);

is used just before poping-up widget w.  If one wants to change
the pop-up location or policy for a specific widget, one need
only change the parameters to this procedure.  The rest or the
parameters are:

    from  takes it value from the set of symbolic constants:
	  { POS_none, POS_pointer, POS_appPanel, POS_screen }, which
	  do respectively,  no positioning, position at the pointer
	  location, position relative to an application window, or 
	  position relative to the screen.
    
    fromWidget
	  For from=POS_appPanel, this is the widget (window) to position on.
    
    x, y  provide a location in percent across the application window
	  or screen (depending on from).  For example, x=50, y=50
	  represents the center of either the window or the screen.
	
    hJust, vJust
	  are horizontal and vertical justification requirements.  For
	  hJust = 0 the left edge of the popup is positioned at x;
	  hJust = 1 the center of the popup is positioned at x;
	  hJust = 2 the right edge of the popup is positioned at x.
	  The same is true for vJust, using top, middle, and bottom
	  against y.

	  These justifications do not take into account the size of
	  the window manager decorations, but they're close enough
	  anyway to be pretty useful.

After positioning, positionPopup forces the complete popup to lie
on screen by "shoving" it, if necessary, just enough to get it fully
on the display.


Gopher Directory Data Structure
-------------------------------

The gopher directories are maintained in a dynamic n-ary tree
as long as each is active.  A directory is active if 

 1) it is the current directory
 2) it is in the bookmark list
 3) it is the ancestor of the current directory or a directory
    in the bookmark list.

Once a directory becomes inactive, the directory data structure
is removed from the tree and moved back to a "free list".

The gopher items associated with a directory are maintained in
a linked list referenced by the directory data structure.  They
are saved (cached) with the directory until either the directory
is released or they become stale.  A time field in the directory
structure identifies the time that the directory contents were
last fetched.  Whenever the contents are needed, the time is
checked, and if some user-specified threshold of elapsed time
is exceeded, then the directory contents are freed and re-requested
from the server.


	Dynamic Directory Tree Node structure (gopherDir)

			        .
			       / \
			        |
			        |
           +-------------+------------+----------+-----------+
           |  markCount  |   parent   |  active  |  sibling +|---->
           +-------------++----------++-----+----+----+------+
      <----|+selectorItem | children | time | content | next+|---->
           +-------------++----------+------+---------+------+
	   | index string|	|                 |
	   +-------------+      |                 +-->
			       \ /                


The list header is used to maintain free lists and the directory
contents list:

	List Header (similar for gopherItemList and gopherDirList)

	  +--------+
	  | first +|--->
	  +--------+
	  | last  +|--->
	  +--------+


Other Contributors
------------------

Xgopher version 1.0 was by and large a total rewrite.  It
does however re-use some code and ideas from previous versions.
I cannot determine from older versions who did what, so I want
to credit:

  . jonathan@Think.COM  (apparently responsible for WAIS software)
  . Paul Lindner at University fo Minnesota who wrote the 
    original Xgopher client.

Of course, the present author assumes responsibility for any
problems introduced.
