XEmacs 21.2.41 "Polyhymnia".
[chise/xemacs-chise.git] / man / internals / internals.texi
index f432589..8cc49ad 100644 (file)
@@ -135,7 +135,7 @@ This Info file contains v1.0 of the XEmacs Internals Manual.
 * Specifiers::
 * Menus::
 * Subprocesses::
-* Interface to X Windows::
+* Interface to the X Window System::
 * Index::
 
 @detailmenu
@@ -1218,7 +1218,7 @@ name as the value of the Lisp variable @code{top-level}.
 
   When the Lisp initialization code is done, the C code enters the event
 loop, and stays there for the duration of the XEmacs process.  The code
-for the event loop is contained in @file{keyboard.c}, and is called
+for the event loop is contained in @file{cmdloop.c}, and is called
 @code{Fcommand_loop_1()}.  Note that this event loop could very well be
 written in Lisp, and in fact a Lisp version exists; but apparently,
 doing this makes XEmacs run noticeably slower.
@@ -1626,11 +1626,11 @@ stuffs a pointer together with a tag, as follows:
 
 A tag of 00 is used for all pointer object types, a tag of 10 is used
 for characters, and the other two tags 01 and 11 are joined together to
-form the integer object type.  This representation gives us 31 bits
-integers, 30 bits characters and pointers are represented directly
-without any bit masking.  This representation, though, assumes that
-pointers to structs are always aligned to multiples of 4, so the lower 2
-bits are always zero.
+form the integer object type.  This representation gives us 31 bit
+integers and 30 bit characters, while pointers are represented directly
+without any bit masking or shifting.  This representation, though,
+assumes that pointers to structs are always aligned to multiples of 4,
+so the lower 2 bits are always zero.
 
 Lisp objects use the typedef @code{Lisp_Object}, but the actual C type
 used for the Lisp object can vary.  It can be either a simple type
@@ -1641,24 +1641,24 @@ preferable because it ensures that the compiler will actually use a
 machine word to represent the object (some compilers will use more
 general and less efficient code for unions and structs even if they can
 fit in a machine word).  The union type, however, has the advantage of
-stricter type checking (if you accidentally pass an integer where a Lisp
-object is desired, you get a compile error), and it makes it easier to
-decode Lisp objects when debugging.  The choice of which type to use is
-determined by the preprocessor constant @code{USE_UNION_TYPE} which is
-defined via the @code{--use-union-type} option to @code{configure}.
-
-Various macros are used to construct Lisp objects and extract the
-components.  Macros of the form @code{XINT()}, @code{XCHAR()},
-@code{XSTRING()}, @code{XSYMBOL()}, etc. shift out the tag field if
-needed cast it to the appropriate type.  @code{XINT()} needs to be a bit
-tricky so that negative numbers are properly sign-extended.  Since
+stricter type checking.  If you accidentally pass an integer where a Lisp
+object is desired, you get a compile error.  The choice of which type
+to use is determined by the preprocessor constant @code{USE_UNION_TYPE}
+which is defined via the @code{--use-union-type} option to
+@code{configure}.
+
+Various macros are used to convert between Lisp_Objects and the
+corresponding C type.  Macros of the form @code{XINT()}, @code{XCHAR()},
+@code{XSTRING()}, @code{XSYMBOL()}, do any required bit shifting and/or
+masking and cast it to the appropriate type.  @code{XINT()} needs to be
+a bit tricky so that negative numbers are properly sign-extended.  Since
 integers are stored left-shifted, if the right-shift operator does an
 arithmetic shift (i.e. it leaves the most-significant bit as-is rather
 than shifting in a zero, so that it mimics a divide-by-two even for
 negative numbers) the shift to remove the tag bit is enough.  This is
 the case on all the systems we support.
 
-Note that when @code{ERROR_CHECK_TYPECHECK} is defined, the extractor
+Note that when @code{ERROR_CHECK_TYPECHECK} is defined, the converter
 macros become more complicated---they check the tag bits and/or the
 type field in the first four bytes of a record type to ensure that the
 object is really of the correct type.  This is great for catching places
@@ -1668,25 +1668,29 @@ unpredictable (and sometimes not easily traceable) results.
 
 There are similar @code{XSET@var{TYPE}()} macros that construct a Lisp
 object.  These macros are of the form @code{XSET@var{TYPE}
-(@var{lvalue}, @var{result})},
-i.e. they have to be a statement rather than just used in an expression.
-The reason for this is that standard C doesn't let you ``construct'' a
-structure (but GCC does).  Granted, this sometimes isn't too convenient;
-for the case of integers, at least, you can use the function
-@code{make_int()}, which constructs and @emph{returns} an integer
-Lisp object.  Note that the @code{XSET@var{TYPE}()} macros are also
-affected by @code{ERROR_CHECK_TYPECHECK} and make sure that the
-structure is of the right type in the case of record types, where the
-type is contained in the structure.
+(@var{lvalue}, @var{result})}, i.e. they have to be a statement rather
+than just used in an expression.  The reason for this is that standard C
+doesn't let you ``construct'' a structure (but GCC does).  Granted, this
+sometimes isn't too convenient; for the case of integers, at least, you
+can use the function @code{make_int()}, which constructs and
+@emph{returns} an integer Lisp object.  Note that the
+@code{XSET@var{TYPE}()} macros are also affected by
+@code{ERROR_CHECK_TYPECHECK} and make sure that the structure is of the
+right type in the case of record types, where the type is contained in
+the structure.
 
 The C programmer is responsible for @strong{guaranteeing} that a
-Lisp_Object is is the correct type before using the @code{X@var{TYPE}}
+Lisp_Object is the correct type before using the @code{X@var{TYPE}}
 macros.  This is especially important in the case of lists.  Use
 @code{XCAR} and @code{XCDR} if a Lisp_Object is certainly a cons cell,
 else use @code{Fcar()} and @code{Fcdr()}.  Trust other C code, but not
 Lisp code.  On the other hand, if XEmacs has an internal logic error,
-it's better to crash immediately, so sprinkle ``unreachable''
-@code{abort()}s liberally about the source code.
+it's better to crash immediately, so sprinkle @code{assert()}s and
+``unreachable'' @code{abort()}s liberally about the source code.  Where
+performance is an issue, use @code{type_checking_assert},
+@code{bufpos_checking_assert}, and @code{gc_checking_assert}, which do
+nothing unless the corresponding configure error checking flag was
+specified.
 
 @node Rules When Writing New C Code, A Summary of the Various XEmacs Modules, How Lisp Objects Are Represented in C, Top
 @chapter Rules When Writing New C Code
@@ -1717,21 +1721,6 @@ been found by compiling with C++.  The ability to use both C and C++
 tools means that a greater variety of development tools are available to
 the developer.
 
-Almost every module contains a @code{syms_of_*()} function and a
-@code{vars_of_*()} function.  The former declares any Lisp primitives
-you have defined and defines any symbols you will be using.  The latter
-declares any global Lisp variables you have added and initializes global
-C variables in the module.  For each such function, declare it in
-@file{symsinit.h} and make sure it's called in the appropriate place in
-@file{emacs.c}.  @strong{Important}: There are stringent requirements on
-exactly what can go into these functions.  See the comment in
-@file{emacs.c}.  The reason for this is to avoid obscure unwanted
-interactions during initialization.  If you don't follow these rules,
-you'll be sorry!  If you want to do anything that isn't allowed, create
-a @code{complex_vars_of_*()} function for it.  Doing this is tricky,
-though: You have to make sure your function is called at the right time
-so that all the initialization dependencies work out.
-
 Every module includes @file{<config.h>} (angle brackets so that
 @samp{--srcdir} works correctly; @file{config.h} may or may not be in
 the same directory as the C sources) and @file{lisp.h}.  @file{config.h}
@@ -1740,13 +1729,32 @@ system header files) to ensure that certain tricks played by various
 @file{s/} and @file{m/} files work out correctly.
 
 When including header files, always use angle brackets, not double
-quotes, except when the file to be included is in the same directory as
-the including file.  If either file is a generated file, then that is
-not likely to be the case.  In order to understand why we have this
-rule, imagine what happens when you do a build in the source directory
-using @samp{./configure} and another build in another directory using
-@samp{../work/configure}.  There will be two different @file{config.h}
-files.  Which one will be used if you @samp{#include "config.h"}?
+quotes, except when the file to be included is always in the same
+directory as the including file.  If either file is a generated file,
+then that is not likely to be the case.  In order to understand why we
+have this rule, imagine what happens when you do a build in the source
+directory using @samp{./configure} and another build in another
+directory using @samp{../work/configure}.  There will be two different
+@file{config.h} files.  Which one will be used if you @samp{#include
+"config.h"}?
+
+Almost every module contains a @code{syms_of_*()} function and a
+@code{vars_of_*()} function.  The former declares any Lisp primitives
+you have defined and defines any symbols you will be using.  The latter
+declares any global Lisp variables you have added and initializes global
+C variables in the module.  @strong{Important}: There are stringent
+requirements on exactly what can go into these functions.  See the
+comment in @file{emacs.c}.  The reason for this is to avoid obscure
+unwanted interactions during initialization.  If you don't follow these
+rules, you'll be sorry!  If you want to do anything that isn't allowed,
+create a @code{complex_vars_of_*()} function for it.  Doing this is
+tricky, though: you have to make sure your function is called at the
+right time so that all the initialization dependencies work out.
+
+Declare each function of these kinds in @file{symsinit.h}.  Make sure
+it's called in the appropriate place in @file{emacs.c}.  You never need
+to include @file{symsinit.h} directly, because it is included by
+@file{lisp.h}.
 
 @strong{All global and static variables that are to be modifiable must
 be declared uninitialized.}  This means that you may not use the
@@ -1791,7 +1799,7 @@ The C source code makes heavy use of C preprocessor macros.  One popular
 macro style is:
 
 @example
-#define FOO(var, value) do @{           \
+#define FOO(var, value) do @{            \
   Lisp_Object FOO_value = (value);      \
   ... /* compute using FOO_value */     \
   (var) = bar;                          \
@@ -1808,7 +1816,7 @@ Lisp lists are popular data structures in the C code as well as in
 Elisp.  There are two sets of macros that iterate over lists.
 @code{EXTERNAL_LIST_LOOP_@var{n}} should be used when the list has been
 supplied by the user, and cannot be trusted to be acyclic and
-nil-terminated.  A @code{malformed-list} or @code{circular-list} error
+@code{nil}-terminated.  A @code{malformed-list} or @code{circular-list} error
 will be generated if the list being iterated over is not entirely
 kosher.  @code{LIST_LOOP_@var{n}}, on the other hand, is faster and less
 safe, and can be used only on trusted lists.
@@ -2597,13 +2605,19 @@ proceed writing new Mule-aware code.
 @node Techniques for XEmacs Developers,  , Coding for Mule, Rules When Writing New C Code
 @section Techniques for XEmacs Developers
 
+To make a purified XEmacs, do: @code{make puremacs}.
 To make a quantified XEmacs, do: @code{make quantmacs}.
 
-You simply can't dump Quantified and Purified images.  Run the image
-like so:  @code{quantmacs -batch -l loadup.el run-temacs @var{xemacs-args...}}.
+You simply can't dump Quantified and Purified images (unless using the
+portable dumper).  Purify gets confused when xemacs frees memory in one
+process that was allocated in a @emph{different} process on a different
+machine!.  Run it like so:
+@example
+temacs -batch -l loadup.el run-temacs @var{xemacs-args...}
+@end example
 
 Before you go through the trouble, are you compiling with all
-debugging and error-checking off?  If not try that first.  Be warned
+debugging and error-checking off?  If not, try that first.  Be warned
 that while Quantify is directly responsible for quite a few
 optimizations which have been made to XEmacs, doing a run which
 generates results which can be acted upon is not necessarily a trivial
@@ -2642,14 +2656,116 @@ Unfortunately, Emacs Lisp is slow, and is going to stay slow.  Function
 calls in elisp are especially expensive.  Iterating over a long list is
 going to be 30 times faster implemented in C than in Elisp.
 
+Heavily used small code fragments need to be fast.  The traditional way
+to implement such code fragments in C is with macros.  But macros in C
+are known to be broken.
+
+Macro arguments that are repeatedly evaluated may suffer from repeated
+side effects or suboptimal performance.
+
+Variable names used in macros may collide with caller's variables,
+causing (at least) unwanted compiler warnings.
+
+In order to solve these problems, and maintain statement semantics, one
+should use the @code{do @{ ... @} while (0)} trick while trying to
+reference macro arguments exactly once using local variables.
+
+Let's take a look at this poor macro definition:
+
+@example
+#define MARK_OBJECT(obj) \
+  if (!marked_p (obj)) mark_object (obj), did_mark = 1
+@end example
+
+This macro evaluates its argument twice, and also fails if used like this:
+@example
+  if (flag) MARK_OBJECT (obj); else do_something();
+@end example
+
+A much better definition is
+
+@example
+#define MARK_OBJECT(obj) do @{ \
+  Lisp_Object mo_obj = (obj); \
+  if (!marked_p (mo_obj))     \
+    @{                         \
+      mark_object (mo_obj);   \
+      did_mark = 1;           \
+    @}                         \
+@} while (0)
+@end example
+
+Notice the elimination of double evaluation by using the local variable
+with the obscure name.  Writing safe and efficient macros requires great
+care.  The one problem with macros that cannot be portably worked around
+is, since a C block has no value, a macro used as an expression rather
+than a statement cannot use the techniques just described to avoid
+multiple evaluation.
+
+In most cases where a macro has function semantics, an inline function
+is a better implementation technique.  Modern compiler optimizers tend
+to inline functions even if they have no @code{inline} keyword, and
+configure magic ensures that the @code{inline} keyword can be safely
+used as an additional compiler hint.  Inline functions used in a single
+.c files are easy.  The function must already be defined to be
+@code{static}.  Just add another @code{inline} keyword to the
+definition.
+
+@example
+inline static int
+heavily_used_small_function (int arg)
+@{
+  ...
+@}
+@end example
+
+Inline functions in header files are trickier, because we would like to
+make the following optimization if the function is @emph{not} inlined
+(for example, because we're compiling for debugging).  We would like the
+function to be defined externally exactly once, and each calling
+translation unit would create an external reference to the function,
+instead of including a definition of the inline function in the object
+code of every translation unit that uses it.  This optimization is
+currently only available for gcc.  But you don't have to worry about the
+trickiness; just define your inline functions in header files using this
+pattern:
+
+@example
+INLINE_HEADER int
+i_used_to_be_a_crufty_macro_but_look_at_me_now (int arg);
+INLINE_HEADER int
+i_used_to_be_a_crufty_macro_but_look_at_me_now (int arg)
+@{
+  ...
+@}
+@end example
+
+The declaration right before the definition is to prevent warnings when
+compiling with @code{gcc -Wmissing-declarations}.  I consider issuing
+this warning for inline functions a gcc bug, but the gcc maintainers disagree.
+
+Every header which contains inline functions, either directly by using
+@code{INLINE_HEADER} or indirectly by using @code{DECLARE_LRECORD} must
+be added to @file{inline.c}'s includes to make the optimization
+described above work.  (Optimization note: if all INLINE_HEADER
+functions are in fact inlined in all translation units, then the linker
+can just discard @code{inline.o}, since it contains only unreferenced code).
+
 To get started debugging XEmacs, take a look at the @file{.gdbinit} and
-@file{.dbxrc} files in the @file{src} directory.
-@xref{Q2.1.15 - How to Debug an XEmacs problem with a debugger,,,
-xemacs-faq, XEmacs FAQ}.
+@file{.dbxrc} files in the @file{src} directory.  See the section in the
+XEmacs FAQ on How to Debug an XEmacs problem with a debugger.
 
 After making source code changes, run @code{make check} to ensure that
-you haven't introduced any regressions.  If you're feeling ambitious,
-you can try to improve the test suite in @file{tests/automated}.
+you haven't introduced any regressions.  If you want to make xemacs more
+reliable, please improve the test suite in @file{tests/automated}.
+
+Did you make sure you didn't introduce any new compiler warnings?
+
+Before submitting a patch, please try compiling at least once with
+
+@example
+configure --with-mule --with-union-type --error-checking=all
+@end example
 
 Here are things to know when you create a new source file:
 
@@ -2676,23 +2792,6 @@ Header files should @emph{not} include @code{<config.h>} and
 @code{"lisp.h"}.  It is the responsibility of the @file{.c} files that
 use it to do so.
 
-@item
-If the header uses @code{INLINE}, either directly or through
-@code{DECLARE_LRECORD}, then it must be added to @file{inline.c}'s
-includes.
-
-@item
-Try compiling at least once with
-
-@example
-gcc --with-mule --with-union-type --error-checking=all
-@end example
-
-@item
-Did I mention that you should run the test suite?
-@example
-make check
-@end example
 @end itemize
 
 Here is a checklist of things to do when creating a new lisp object type
@@ -2704,17 +2803,20 @@ create @var{foo}.h
 @item
 create @var{foo}.c
 @item
-add definitions of syms_of_@var{foo}, etc. to @var{foo}.c
+add definitions of @code{syms_of_@var{foo}}, etc. to @file{@var{foo}.c}
+@item
+add declarations of @code{syms_of_@var{foo}}, etc. to @file{symsinit.h}
 @item
-add declarations of syms_of_@var{foo}, etc. to symsinit.h
+add calls to @code{syms_of_@var{foo}}, etc. to @file{emacs.c}
 @item
-add calls to syms_of_@var{foo}, etc. to emacs.c(main_1)
+add definitions of macros like @code{CHECK_@var{FOO}} and
+@code{@var{FOO}P} to @file{@var{foo}.h}
 @item
-add definitions of macros like CHECK_FOO and FOOP to @var{foo}.h
+add the new type index to @code{enum lrecord_type}
 @item
-add the new type index to enum lrecord_type
+add a DEFINE_LRECORD_IMPLEMENTATION call to @file{@var{foo}.c}
 @item
-add DEFINE_LRECORD_IMPLEMENTATION call to @var{foo}.c
+add an INIT_LRECORD_IMPLEMENTATION call to @code{syms_of_@var{foo}.c}
 @end enumerate
 
 @node A Summary of the Various XEmacs Modules, Allocation of Objects in XEmacs Lisp, Rules When Writing New C Code, Top
@@ -2811,7 +2913,7 @@ chosen by @file{configure}.
 
 
 @example
-crt0.c
+ecrt0.c
 lastfile.c
 pre-crt0.c
 @end example
@@ -2946,14 +3048,6 @@ provided by the @samp{--error-check-*} configuration options.
 
 
 @example
-prefix-args.c
-@end example
-
-This is actually the source for a small, self-contained program
-used during building.
-
-
-@example
 universe.h
 @end example
 
@@ -2965,7 +3059,6 @@ This is not currently used.
 @section Basic Lisp Modules
 
 @example
-emacsfns.h
 lisp-disunion.h
 lisp-union.h
 lisp.h
@@ -3311,8 +3404,12 @@ Most of this could be implemented in Lisp.
 
 @example
 event-Xt.c
+event-msw.c
 event-stream.c
 event-tty.c
+events-mod.h
+gpmevent.c
+gpmevent.h
 events.c
 events.h
 @end example
@@ -3367,10 +3464,10 @@ relevant keymaps.)
 
 
 @example
-keyboard.c
+cmdloop.c
 @end example
 
-@file{keyboard.c} contains functions that implement the actual editor
+@file{cmdloop.c} contains functions that implement the actual editor
 command loop---i.e. the event loop that cyclically retrieves and
 dispatches events.  This code is also rather tricky, just like
 @file{event-stream.c}.
@@ -3408,13 +3505,31 @@ code is loaded).
 @section Modules for the Basic Displayable Lisp Objects
 
 @example
-device-ns.h
-device-stream.c
-device-stream.h
+console-msw.c
+console-msw.h
+console-stream.c
+console-stream.h
+console-tty.c
+console-tty.h
+console-x.c
+console-x.h
+console.c
+console.h
+@end example
+
+These modules implement the @dfn{console} Lisp object type.  A console
+contains multiple display devices, but only one keyboard and mouse.
+Most of the time, a console will contain exactly one device.
+
+Consoles are the top of a lisp object inclusion hierarchy.  Consoles
+contain devices, which contain frames, which contain windows.
+
+
+
+@example
+device-msw.c
 device-tty.c
-device-tty.h
 device-x.c
-device-x.h
 device.c
 device.h
 @end example
@@ -3435,10 +3550,9 @@ subtypes (X, TTY, NeXTstep, Microsoft Windows, etc.) as devices do.
 
 
 @example
-frame-ns.h
+frame-msw.c
 frame-tty.c
 frame-x.c
-frame-x.h
 frame.c
 frame.h
 @end example
@@ -3490,7 +3604,10 @@ faces.h
 
 @example
 bitmaps.h
-glyphs-ns.h
+glyphs-eimage.c
+glyphs-msw.c
+glyphs-msw.h
+glyphs-widget.c
 glyphs-x.c
 glyphs-x.h
 glyphs.c
@@ -3500,7 +3617,8 @@ glyphs.h
 
 
 @example
-objects-ns.h
+objects-msw.c
+objects-msw.h
 objects-tty.c
 objects-tty.h
 objects-x.c
@@ -3512,13 +3630,18 @@ objects.h
 
 
 @example
+menubar-msw.c
+menubar-msw.h
 menubar-x.c
 menubar.c
+menubar.h
 @end example
 
 
 
 @example
+scrollbar-msw.c
+scrollbar-msw.h
 scrollbar-x.c
 scrollbar-x.h
 scrollbar.c
@@ -3528,6 +3651,7 @@ scrollbar.h
 
 
 @example
+toolbar-msw.c
 toolbar-x.c
 toolbar.c
 toolbar.h
@@ -3554,6 +3678,7 @@ gifalloc.c
 @end example
 
 These modules decode GIF-format image files, for use with glyphs.
+These files were removed due to Unisys patent infringement concerns.
 
 
 
@@ -3562,6 +3687,7 @@ These modules decode GIF-format image files, for use with glyphs.
 
 @example
 redisplay-output.c
+redisplay-msw.c
 redisplay-tty.c
 redisplay-x.c
 redisplay.c
@@ -3656,7 +3782,7 @@ streams and C++ I/O streams.
 Similar to other subsystems in XEmacs, lstreams are separated into
 generic functions and a set of methods for the different types of
 lstreams.  @file{lstream.c} provides implementations of many different
-types of streams; others are provided, e.g., in @file{mule-coding.c}.
+types of streams; others are provided, e.g., in @file{file-coding.c}.
 
 
 
@@ -4121,16 +4247,6 @@ AIX prior to 4.1.
 
 
 
-@example
-msdos.c
-msdos.h
-@end example
-
-These modules are used for MS-DOS support, which does not work in
-XEmacs.
-
-
-
 @node Modules for Interfacing with X Windows, Modules for Internationalization, Modules for Interfacing with the Operating System, A Summary of the Various XEmacs Modules
 @section Modules for Interfacing with X Windows
 
@@ -4198,7 +4314,10 @@ needs to be rewritten.
 
 
 @example
-xselect.c
+select-msw.c
+select-x.c
+select.c
+select.h
 @end example
 
 @cindex selections
@@ -4281,8 +4400,8 @@ mule-canna.c
 mule-ccl.c
 mule-charset.c
 mule-charset.h
-mule-coding.c
-mule-coding.h
+file-coding.c
+file-coding.h
 mule-mcpath.c
 mule-mcpath.h
 mule-wnnfns.c
@@ -4294,13 +4413,13 @@ actually provides a general interface for all sorts of languages, not
 just Asian languages (although they are generally the most complicated
 to support).  This code is still in beta.
 
-@file{mule-charset.*} and @file{mule-coding.*} provide the heart of the
+@file{mule-charset.*} and @file{file-coding.*} provide the heart of the
 XEmacs MULE support.  @file{mule-charset.*} implements the @dfn{charset}
 Lisp object type, which encapsulates a character set (an ordered one- or
 two-dimensional set of characters, such as US ASCII or JISX0208 Japanese
 Kanji).
 
-@file{mule-coding.*} implements the @dfn{coding-system} Lisp object
+@file{file-coding.*} implements the @dfn{coding-system} Lisp object
 type, which encapsulates a method of converting between different
 encodings.  An encoding is a representation of a stream of characters,
 possibly from multiple character sets, using a stream of bytes or words,
@@ -4694,7 +4813,7 @@ for example @code{or}, @code{and}, @code{if}, @code{cond}, @code{while},
 @code{setq}, etc., miscellaneous @code{gui_item_...} functions,
 everything related to @code{eval} (@code{Feval_buffer}, @code{call0},
 ...) and inside @code{Fsignal}. The latter is used to handle signals, as
-for example the ones raised by every @code{QUITE}-macro triggered after
+for example the ones raised by every @code{QUIT}-macro triggered after
 pressing Ctrl-g.
 
 @node garbage_collect_1, mark_object, Invocation, Garbage Collection - Step by Step
@@ -4748,7 +4867,7 @@ shown in their processed order:
 @itemize @bullet
 @item
 all constant symbols and static variables that are registered via
-@code{staticpro}@ in the array @code{staticvec}.
+@code{staticpro}@ in the dynarr @code{staticpros}.
 @xref{Adding Global Lisp Variables}.
 @item
 all Lisp objects that are created in C functions and that must be
@@ -4952,7 +5071,7 @@ For a description about the internals: @xref{lrecords}.
 
 Our next candidates are the other objects that behave quite differently
 than everything else: the strings. They consists of two parts, a
-fixed-size portion (@code{struct Lisp_string}) holding the string's
+fixed-size portion (@code{struct Lisp_String}) holding the string's
 length, its property list and a pointer to the second part, and the
 actual string data, which is stored in string-chars blocks comparable to
 frob blocks. In this block, the data is not only freed, but also a
@@ -5166,7 +5285,9 @@ more defensive but less efficient and is used for error-checking.)
 
   All lrecords have at the beginning of their structure a @code{struct
 lrecord_header}.  This just contains a type number and some flags,
-including the mark bit.  The type number, thru the
+including the mark bit.  All builtin type numbers are defined as
+constants in @code{enum lrecord_type}, to allow the compiler to generate
+more efficient code for @code{@var{type}P}.  The type number, thru the
 @code{lrecord_implementation_table}, gives access to a @code{struct
 lrecord_implementation}, which is a structure containing method pointers
 and such.  There is one of these for each type, and it is a global,
@@ -5201,21 +5322,21 @@ type.
 Whenever you create an lrecord, you need to call either
 @code{DEFINE_LRECORD_IMPLEMENTATION()} or
 @code{DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION()}.  This needs to be
-specified in a C file, at the top level.  What this actually does is
-define and initialize the implementation structure for the lrecord. (And
-possibly declares a function @code{error_check_foo()} that implements
-the @code{XFOO()} macro when error-checking is enabled.)  The arguments
-to the macros are the actual type name (this is used to construct the C
-variable name of the lrecord implementation structure and related
-structures using the @samp{##} macro concatenation operator), a string
-that names the type on the Lisp level (this may not be the same as the C
-type name; typically, the C type name has underscores, while the Lisp
-string has dashes), various method pointers, and the name of the C
-structure that contains the object.  The methods are used to encapsulate
-type-specific information about the object, such as how to print it or
-mark it for garbage collection, so that it's easy to add new object
-types without having to add a specific case for each new type in a bunch
-of different places.
+specified in a @file{.c} file, at the top level.  What this actually
+does is define and initialize the implementation structure for the
+lrecord. (And possibly declares a function @code{error_check_foo()} that
+implements the @code{XFOO()} macro when error-checking is enabled.)  The
+arguments to the macros are the actual type name (this is used to
+construct the C variable name of the lrecord implementation structure
+and related structures using the @samp{##} macro concatenation
+operator), a string that names the type on the Lisp level (this may not
+be the same as the C type name; typically, the C type name has
+underscores, while the Lisp string has dashes), various method pointers,
+and the name of the C structure that contains the object.  The methods
+are used to encapsulate type-specific information about the object, such
+as how to print it or mark it for garbage collection, so that it's easy
+to add new object types without having to add a specific case for each
+new type in a bunch of different places.
 
   The difference between @code{DEFINE_LRECORD_IMPLEMENTATION()} and
 @code{DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION()} is that the former is
@@ -5229,21 +5350,20 @@ to determine the actual size of a particular object of that type.
   For the purpose of keeping allocation statistics, the allocation
 engine keeps a list of all the different types that exist.  Note that,
 since @code{DEFINE_LRECORD_IMPLEMENTATION()} is a macro that is
-specified at top-level, there is no way for it to add to the list of all
-existing types.  What happens instead is that each implementation
-structure contains in it a dynamically assigned number that is
-particular to that type. (Or rather, it contains a pointer to another
-structure that contains this number.  This evasiveness is done so that
-the implementation structure can be declared const.) In the sweep stage
-of garbage collection, each lrecord is examined to see if its
-implementation structure has its dynamically-assigned number set.  If
-not, it must be a new type, and it is added to the list of known types
-and a new number assigned.  The number is used to index into an array
-holding the number of objects of each type and the total memory
-allocated for objects of that type.  The statistics in this array are
-also computed during the sweep stage.  These statistics are returned by
-the call to @code{garbage-collect} and are printed out at the end of the
-loadup phase.
+specified at top-level, there is no way for it to initialize the global
+data structures containing type information, like
+@code{lrecord_implementations_table}.  For this reason a call to
+@code{INIT_LRECORD_IMPLEMENTATION} must be added to the same source file
+containing @code{DEFINE_LRECORD_IMPLEMENTATION}, but instead of to the
+top level, to one of the init functions, typically
+@code{syms_of_@var{foo}.c}.  @code{INIT_LRECORD_IMPLEMENTATION} must be
+called before an object of this type is used.
+
+The type number is also used to index into an array holding the number
+of objects of each type and the total memory allocated for objects of
+that type.  The statistics in this array are computed during the sweep
+stage.  These statistics are returned by the call to
+@code{garbage-collect}.
 
   Note that for every type defined with a @code{DEFINE_LRECORD_*()}
 macro, there needs to be a @code{DECLARE_LRECORD_IMPLEMENTATION()}
@@ -5255,6 +5375,15 @@ included by @file{inline.c}.
 file.  To create one of these, copy an existing model and modify as
 necessary.
 
+  @strong{Please note:} If you define an lrecord in an external
+dynamically-loaded module, you must use @code{DECLARE_EXTERNAL_LRECORD},
+@code{DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION}, and
+@code{DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION} instead of the
+non-EXTERNAL forms. These macros will dynamically add new type numbers
+to the global enum that records them, whereas the non-EXTERNAL forms
+assume that the programmer has already inserted the correct type numbers
+into the enum's code at compile-time.
+
   The various methods in the lrecord implementation structure are:
 
 @enumerate
@@ -5264,7 +5393,7 @@ A @dfn{mark} method.  This is called during the marking stage and passed
 a function pointer (usually the @code{mark_object()} function), which is
 used to mark an object.  All Lisp objects that are contained within the
 object need to be marked by applying this function to them.  The mark
-method should also return a Lisp object, which should be either nil or
+method should also return a Lisp object, which should be either @code{nil} or
 an object to mark. (This can be used in lieu of calling
 @code{mark_object()} on the object, to reduce the recursion depth, and
 consequently should be the most heavily nested sub-object, such as a
@@ -5449,16 +5578,15 @@ warning system, when memory gets to 75%, 85%, and 95% full.
 (On some systems, the memory warnings are not functional.)
 
   Allocated memory that is going to be used to make a Lisp object
-is created using @code{allocate_lisp_storage()}.  This calls @code{xmalloc()}
-but also verifies that the pointer to the memory can fit into
-a Lisp word (remember that some bits are taken away for a type
-tag and a mark bit).  If not, an error is issued through @code{memory_full()}.
-@code{allocate_lisp_storage()} is called by @code{alloc_lcrecord()},
-@code{ALLOCATE_FIXED_TYPE()}, and the vector and bit-vector creation
-routines.  These routines also call @code{INCREMENT_CONS_COUNTER()} at the
-appropriate times; this keeps statistics on how much memory is
-allocated, so that garbage-collection can be invoked when the
-threshold is reached.
+is created using @code{allocate_lisp_storage()}.  This just calls
+@code{xmalloc()}.  It used to verify that the pointer to the memory can
+fit into a Lisp word, before the current Lisp object representation was
+introduced.  @code{allocate_lisp_storage()} is called by
+@code{alloc_lcrecord()}, @code{ALLOCATE_FIXED_TYPE()}, and the vector
+and bit-vector creation routines.  These routines also call
+@code{INCREMENT_CONS_COUNTER()} at the appropriate times; this keeps
+statistics on how much memory is allocated, so that garbage-collection
+can be invoked when the threshold is reached.
 
 @node Cons, Vector, Low-level allocation, Allocation of Objects in XEmacs Lisp
 @section Cons
@@ -5688,7 +5816,7 @@ field and a pointer to an associated array of lrecord_description.
 @node Dumping phase, Reloading phase, Data descriptions, Dumping
 @section Dumping phase
 
-Dumping is done by calling the function pdump() (in alloc.c) which is
+Dumping is done by calling the function pdump() (in dumper.c) which is
 invoked from Fdump_emacs (in emacs.c).  This function performs a number
 of tasks.
 
@@ -5740,7 +5868,7 @@ differences though:
 @enumerate
 @item
 We do not use the mark bit (which does not exist for C structures
-anyway), we use a big hash table instead.
+anyway); we use a big hash table instead.
 
 @item
 We do not use the mark function of lrecords but instead rely on the
@@ -5749,15 +5877,15 @@ follow pointers to C structures and opaque data in addition to
 Lisp_Object members.
 @end enumerate
 
-This is done by @code{pdump_register_object}, which handles Lisp_Object
-variables, and pdump_register_struct which handles C structures, which
-both delegate the description management to pdump_register_sub.
+This is done by @code{pdump_register_object()}, which handles Lisp_Object
+variables, and @code{pdump_register_struct()} which handles C structures,
+which both delegate the description management to @code{pdump_register_sub()}.
 
 The hash table doubles as a map object to pdump_entry_list_elmt (i.e.
 allows us to look up a pdump_entry_list_elmt with the object it points
 to).  Entries are added with @code{pdump_add_entry()} and looked up with
 @code{pdump_get_entry()}.  There is no need for entry removal.  The hash
-value is computed quite basically from the object pointer by
+value is computed quite simply from the object pointer by
 @code{pdump_make_hash()}.
 
 The roots for the marking are:
@@ -5768,11 +5896,13 @@ the @code{staticpro}'ed variables (there is a special @code{staticpro_nodump()}
 call for protected variables we do not want to dump).
 
 @item
-the @code{pdump_wire}'d variables (@code{staticpro} is equivalent to
-@code{staticpro_nodump()} + @code{pdump_wire()}).
+the variables registered via @code{dump_add_root_object}
+(@code{staticpro()} is equivalent to @code{staticpro_nodump()} +
+@code{dump_add_root_object()}).
 
 @item
-the @code{dumpstruct}'ed variables, which points to C structures.
+the variables registered via @code{dump_add_root_struct_ptr}, each of
+which points to a C structure.
 @end enumerate
 
 This does not include the GCPRO'ed variables, the specbinds, the
@@ -5800,7 +5930,7 @@ real world alignment requirements are powers of two.
 
 @item
 the C compiler is required to adjust the size of a struct so that you
-can have an array of them next to each other.  This means you can have a
+can have an array of them next to each other.  This means you can have an
 upper bound of the alignment requirements of a given structure by
 looking at which power of two its size is a multiple.
 
@@ -5818,18 +5948,17 @@ first.  This ensures the best packing.
 The maximum alignment requirement we take into account is 2^8.
 
 @code{pdump_allocate_offset()} only has to do a linear allocation,
-starting at offset 256 (this leaves room for the header and keep the
+starting at offset 256 (this leaves room for the header and keeps the
 alignments happy).
 
 @node The header, Data dumping, Address allocation, Dumping phase
 @subsection The header
 
 The next step creates the file and writes a header with a signature and
-some random informations in it (number of staticpro, number of assigned
-lrecord types, etc...).  The reloc_address field, which indicates at
-which address the file should be loaded if we want to avoid post-reload
-relocation, is set to 0.  It then seeks to offset 256 (base offset for
-the objects).
+some random information in it.  The @code{reloc_address} field, which
+indicates at which address the file should be loaded if we want to avoid
+post-reload relocation, is set to 0.  It then seeks to offset 256 (base
+offset for the objects).
 
 @node Data dumping, Pointers dumping, The header, Dumping phase
 @subsection Data dumping
@@ -5851,29 +5980,32 @@ then written.  They are:
 
 @enumerate
 @item
-the staticpro array
-@item
-the dumpstruct array
+the pdump_root_struct_ptrs dynarr
 @item
-the lrecord_implementation_table array
+the pdump_opaques dynarr
 @item
 a vector of all the offsets to the objects in the file that include a
 description (for faster relocation at reload time)
 @item
-the pdump_wired and pdump_wired_list arrays
+the pdump_root_objects and pdump_weak_object_chains dynarrs.
 @end enumerate
 
-For each of the arrays we write both the pointer to the variables and
+For each of the dynarrs we write both the pointer to the variables and
 the relocated offset of the object they point to.  Since these variables
 are global, the pointers are still valid when restarting the program and
 are used to regenerate the global pointers.
 
-The @code{pdump_wired_list} array is a special case.  The variables it
-points to are the head of weak linked lists of lisp objects of the same
-type.  Not all objects of this list are dumped so the relocated pointer
-we associate with them points to the first dumped object of the list, or
-Qnil if none is available.  This is also the reason why they are not
-used as roots for the purpose of object enumeration.
+The @code{pdump_weak_object_chains} dynarr is a special case.  The
+variables it points to are the head of weak linked lists of lisp objects
+of the same type.  Not all objects of this list are dumped so the
+relocated pointer we associate with them points to the first dumped
+object of the list, or Qnil if none is available.  This is also the
+reason why they are not used as roots for the purpose of object
+enumeration.
+
+Some very important information like the @code{staticpros} and
+@code{lrecord_implementations_table} are handled indirectly using
+@code{dump_add_opaque} or @code{dump_add_root_struct_ptr}.
 
 This is the end of the dumping part.
 
@@ -5892,22 +6024,15 @@ The difference between the actual loading address and the reloc_address
 is computed and will be used for all the relocations.
 
 
-@subsection Putting back the staticvec
+@subsection Putting back the pdump_opaques
 
-The staticvec array is memcpy'd from the file and the variables it
-points to are reset to the relocated objects addresses.
+The memory contents are restored in the obvious and trivial way.
 
 
-@subsection Putting back the dumpstructed variables
+@subsection Putting back the pdump_root_struct_ptrs
 
-The variables pointed to by dumpstruct in the dump phase are reset to
-the right relocated object addresses.
-
-
-@subsection lrecord_implementations_table
-
-The lrecord_implementations_table is reset to its dump time state and
-the right lrecord_type_index values are put in.
+The variables pointed to by pdump_root_struct_ptrs in the dump phase are
+reset to the right relocated object addresses.
 
 
 @subsection Object relocation
@@ -5917,9 +6042,9 @@ by @code{pdump_reloc_one}.  This step is unnecessary if the
 reloc_address is equal to the file loading address.
 
 
-@subsection Putting back the pdump_wire and pdump_wire_list variables
+@subsection Putting back the pdump_root_objects and pdump_weak_object_chains
 
-Same as Putting back the dumpstructed variables.
+Same as Putting back the pdump_root_struct_ptrs.
 
 
 @subsection Reorganize the hash tables
@@ -7024,7 +7149,7 @@ elsewhere.
 buffer positions in them as integers, and every time text is inserted or
 deleted, these positions must be updated.  In order to minimize the
 amount of shuffling that needs to be done, the positions in markers and
-extents (there's one per marker, two per extent) and stored in Meminds.
+extents (there's one per marker, two per extent) are stored in Meminds.
 This means that they only need to be moved when the text is physically
 moved in memory; since the gap structure tries to minimize this, it also
 minimizes the number of marker and extent indices that need to be
@@ -7053,19 +7178,19 @@ Many are accessible indirectly in Lisp programs via Lisp primitives.
 @table @code
 @item name
 The buffer name is a string that names the buffer.  It is guaranteed to
-be unique.  @xref{Buffer Names,,, lispref, XEmacs Lisp Programmer's
+be unique.  @xref{Buffer Names,,, lispref, XEmacs Lisp Reference
 Manual}.
 
 @item save_modified
 This field contains the time when the buffer was last saved, as an
-integer.  @xref{Buffer Modification,,, lispref, XEmacs Lisp Programmer's
+integer.  @xref{Buffer Modification,,, lispref, XEmacs Lisp Reference
 Manual}.
 
 @item modtime
 This field contains the modification time of the visited file.  It is
 set when the file is written or read.  Every time the buffer is written
 to the file, this field is compared to the modification time of the
-file.  @xref{Buffer Modification,,, lispref, XEmacs Lisp Programmer's
+file.  @xref{Buffer Modification,,, lispref, XEmacs Lisp Reference
 Manual}.
 
 @item auto_save_modified
@@ -7077,39 +7202,39 @@ the last time the buffer was displayed in a window.
 
 @item undo_list
 This field points to the buffer's undo list.  @xref{Undo,,, lispref,
-XEmacs Lisp Programmer's Manual}.
+XEmacs Lisp Reference Manual}.
 
 @item syntax_table_v
 This field contains the syntax table for the buffer.  @xref{Syntax
-Tables,,, lispref, XEmacs Lisp Programmer's Manual}.
+Tables,,, lispref, XEmacs Lisp Reference Manual}.
 
 @item downcase_table
 This field contains the conversion table for converting text to lower
-case.  @xref{Case Tables,,, lispref, XEmacs Lisp Programmer's Manual}.
+case.  @xref{Case Tables,,, lispref, XEmacs Lisp Reference Manual}.
 
 @item upcase_table
 This field contains the conversion table for converting text to upper
-case.  @xref{Case Tables,,, lispref, XEmacs Lisp Programmer's Manual}.
+case.  @xref{Case Tables,,, lispref, XEmacs Lisp Reference Manual}.
 
 @item case_canon_table
 This field contains the conversion table for canonicalizing text for
 case-folding search.  @xref{Case Tables,,, lispref, XEmacs Lisp
-Programmer's Manual}.
+Reference Manual}.
 
 @item case_eqv_table
 This field contains the equivalence table for case-folding search.
-@xref{Case Tables,,, lispref, XEmacs Lisp Programmer's Manual}.
+@xref{Case Tables,,, lispref, XEmacs Lisp Reference Manual}.
 
 @item display_table
 This field contains the buffer's display table, or @code{nil} if it
 doesn't have one.  @xref{Display Tables,,, lispref, XEmacs Lisp
-Programmer's Manual}.
+Reference Manual}.
 
 @item markers
 This field contains the chain of all markers that currently point into
 the buffer.  Deletion of text in the buffer, and motion of the buffer's
 gap, must check each of these markers and perhaps update it.
-@xref{Markers,,, lispref, XEmacs Lisp Programmer's Manual}.
+@xref{Markers,,, lispref, XEmacs Lisp Reference Manual}.
 
 @item backed_up
 This field is a flag that tells whether a backup file has been made for
@@ -7118,7 +7243,7 @@ the visited file of this buffer.
 @item mark
 This field contains the mark for the buffer.  The mark is a marker,
 hence it is also included on the list @code{markers}.  @xref{The Mark,,,
-lispref, XEmacs Lisp Programmer's Manual}.
+lispref, XEmacs Lisp Reference Manual}.
 
 @item mark_active
 This field is non-@code{nil} if the buffer's mark is active.
@@ -7128,12 +7253,12 @@ This field contains the association list describing the variables local
 in this buffer, and their values, with the exception of local variables
 that have special slots in the buffer object.  (Those slots are omitted
 from this table.)  @xref{Buffer-Local Variables,,, lispref, XEmacs Lisp
-Programmer's Manual}.
+Reference Manual}.
 
 @item modeline_format
 This field contains a Lisp object which controls how to display the mode
 line for this buffer.  @xref{Modeline Format,,, lispref, XEmacs Lisp
-Programmer's Manual}.
+Reference Manual}.
 
 @item base_buffer
 This field holds the buffer's base buffer (if it is an indirect buffer),
@@ -7512,7 +7637,7 @@ this is the code executed to handle any stuff that needs to be done
 other encoded/decoded data has been written out.  This is not used for
 charset CCL programs.
 
-REGISTER: 0..7  -- refered by RRR or rrr
+REGISTER: 0..7  -- referred by RRR or rrr
 
 OPERATOR BIT FIELD (27-bit): XXXXXXXXXXXXXXX RRR TTTTT
         TTTTT (5-bit): operator type
@@ -7988,7 +8113,7 @@ All windows have three fields governing their contents:
 these are @dfn{hchild} (a list of horizontally-arrayed children),
 @dfn{vchild} (a list of vertically-arrayed children), and @dfn{buffer}
 (the buffer contained in a leaf window).  Exactly one of
-these will be non-nil.  Remember that @dfn{horizontally-arrayed}
+these will be non-@code{nil}.  Remember that @dfn{horizontally-arrayed}
 means ``side-by-side'' and @dfn{vertically-arrayed} means
 @dfn{one above the other}.
 
@@ -7996,7 +8121,7 @@ means ``side-by-side'' and @dfn{vertically-arrayed} means
 Leaf windows also have markers in their @code{start} (the
 first buffer position displayed in the window) and @code{pointm}
 (the window's stashed value of @code{point}---see above) fields,
-while combination windows have nil in these fields.
+while combination windows have @code{nil} in these fields.
 
 @item
 The list of children for a window is threaded through the
@@ -8406,7 +8531,7 @@ generalized to handle integers and linked list equally well).
 @section Zero-Length Extents
 
   Extents can be zero-length, and will end up that way if their endpoints
-are explicitly set that way or if their detachable property is nil
+are explicitly set that way or if their detachable property is @code{nil}
 and all the text in the extent is deleted. (The exception is open-open
 zero-length extents, which are barred from existing because there is
 no sensible way to define their properties.  Deletion of the text in
@@ -8598,12 +8723,13 @@ Not yet documented.
 
 Glyphs are graphical elements that can be displayed in XEmacs buffers or
 gutters. We use the term graphical element here in the broadest possible
-sense since glyphs can be as mundane as text to as arcane as a native
+sense since glyphs can be as mundane as text or as arcane as a native
 tab widget.
 
 In XEmacs, glyphs represent the uninstantiated state of graphical
 elements, i.e. they hold all the information necessary to produce an
-image on-screen but the image does not exist at this stage.
+image on-screen but the image need not exist at this stage, and multiple
+screen images can be instantiated from a single glyph.
 
 Glyphs are lazily instantiated by calling one of the glyph
 functions. This usually occurs within redisplay when
@@ -8621,7 +8747,7 @@ and every usage - and this would be extremely memory and cpu intensive.
 Widget-glyphs (a.k.a native widgets) are not cached in this way. This is
 because widget-glyph image-instances on screen are toolkit windows, and
 thus cannot be reused in multiple XEmacs domains. Thus widget-glyphs are
-cached on a window basis.
+cached on an XEmacs window basis.  
 
 Any action on a glyph first consults the cache before actually
 instantiating a widget.
@@ -8632,28 +8758,10 @@ To Do
 
 @section Widget-Glyphs in the X Environment
 
-Widget-glyphs under X make heavy use of lwlib for manipulating the
-native toolkit objects. This is primarily so that different toolkits can
-be supported for widget-glyphs, just as they are supported for features
-such as menubars etc.
-
-Lwlib is extremely poorly documented and quite hairy so here is my
-understanding of what goes on.
-
-Lwlib maintains a set of widget_instances which mirror the hierarchical
-state of Xt widgets. I think this is so that widgets can be updated and
-manipulated generically by the lwlib library. For instance
-update_one_widget_instance can cope with multiple types of widget and
-multiple types of toolkit. Each element in the widget hierarchy is updated
-from its corresponding widget_instance by walking the widget_instance
-tree recursively.
-
-This has desirable properties such as lw_modify_all_widgets which is
-called from glyphs-x.c and updates all the properties of a widget
-without having to know what the widget is or what toolkit it is from.
-Unfortunately this also has hairy properties such as making the lwlib
-code quite complex. And of course lwlib has to know at some level what
-the widget is and how to set its properties.
+Widget-glyphs under X make heavy use of lwlib (@pxref{Lucid Widget
+Library}) for manipulating the native toolkit objects. This is primarily
+so that different toolkits can be supported for widget-glyphs, just as
+they are supported for features such as menubars etc.
 
 @node Specifiers, Menus, Glyphs, Top
 @chapter Specifiers
@@ -8712,7 +8820,7 @@ a function to call (either @code{eval} or @code{call-interactively}) and
 its argument, which is the callback function or form given in the menu's
 description.
 
-@node Subprocesses, Interface to X Windows, Menus, Top
+@node Subprocesses, Interface to the X Window System, Menus, Top
 @chapter Subprocesses
 
   The fields of a process are:
@@ -8785,10 +8893,139 @@ The name of the terminal that the subprocess is using,
 or @code{nil} if it is using pipes.
 @end table
 
-@node Interface to X Windows, Index , Subprocesses, Top
-@chapter Interface to X Windows
+@node Interface to the X Window System, Index, Subprocesses, Top
+@chapter Interface to the X Window System
 
-Not yet documented.
+Mostly undocumented.
+
+@menu
+* Lucid Widget Library::        An interface to various widget sets.
+@end menu
+
+@node Lucid Widget Library, , , Interface to the X Window System
+@section Lucid Widget Library
+
+Lwlib is extremely poorly documented and quite hairy.  The author(s)
+blame that on X, Xt, and Motif, with some justice, but also sufficient
+hypocrisy to avoid drawing the obvious conclusion about their own work.
+
+The Lucid Widget Library is composed of two more or less independent
+pieces.  The first, as the name suggests, is a set of widgets.  These
+widgets are intended to resemble and improve on widgets provided in the
+Motif toolkit but not in the Athena widgets, including menubars and
+scrollbars.  Recent additions by Andy Piper integrate some ``modern''
+widgets by Edward Falk, including checkboxes, radio buttons, progress
+gauges, and index tab controls (aka notebooks).
+
+The second piece of the Lucid widget library is a generic interface to
+several toolkits for X (including Xt, the Athena widget set, and Motif,
+as well as the Lucid widgets themselves) so that core XEmacs code need
+not know which widget set has been used to build the graphical user
+interface.
+
+@menu
+* Generic Widget Interface::    The lwlib generic widget interface.
+* Scrollbars::
+* Menubars::
+* Checkboxes and Radio Buttons::
+* Progress Bars::
+* Tab Controls::
+@end menu
+
+@node Generic Widget Interface, Scrollbars, , Lucid Widget Library
+@subsection Generic Widget Interface
+
+In general in any toolkit a widget may be a composite object.  In Xt,
+all widgets have an X window that they manage, but typically a complex
+widget will have widget children, each of which manages a subwindow of
+the parent widget's X window.  These children may themselves be
+composite widgets.  Thus a widget is actually a tree or hierarchy of
+widgets.
+
+For each toolkit widget, lwlib maintains a tree of @code{widget_values}
+which mirror the hierarchical state of Xt widgets (including Motif,
+Athena, 3D Athena, and Falk's widget sets).  Each @code{widget_value}
+has @code{contents} member, which points to the head of a linked list of
+its children.  The linked list of siblings is chained through the
+@code{next} member of @code{widget_value}.
+
+@example
+           +-----------+
+           | composite |
+           +-----------+
+                 |
+                 | contents
+                 V
+             +-------+ next +-------+ next +-------+
+             | child |----->| child |----->| child |
+             +-------+      +-------+      +-------+
+                                |
+                                | contents
+                                V
+                         +-------------+ next +-------------+
+                         | grand child |----->| grand child |
+                         +-------------+      +-------------+
+
+The @code{widget_value} hierarchy of a composite widget with two simple
+children and one composite child.
+@end example
+
+The @code{widget_instance} structure maintains the inverse view of the
+tree.  As for the @code{widget_value}, siblings are chained through the
+@code{next} member.  However, rather than naming children, the
+@code{widget_instance} tree links to parents.
+
+@example
+           +-----------+
+           | composite |
+           +-----------+
+                 A
+                 | parent
+                 |
+             +-------+ next +-------+ next +-------+
+             | child |----->| child |----->| child |
+             +-------+      +-------+      +-------+
+                                A
+                                | parent
+                                |
+                         +-------------+ next +-------------+
+                         | grand child |----->| grand child |
+                         +-------------+      +-------------+
+
+The @code{widget_value} hierarchy of a composite widget with two simple
+children and one composite child.
+@end example
+
+This permits widgets derived from different toolkits to be updated and
+manipulated generically by the lwlib library. For instance
+@code{update_one_widget_instance} can cope with multiple types of widget
+and multiple types of toolkit. Each element in the widget hierarchy is
+updated from its corresponding @code{widget_value} by walking the
+@code{widget_value} tree.  This has desirable properties.  For example,
+@code{lw_modify_all_widgets} is called from @file{glyphs-x.c} and
+updates all the properties of a widget without having to know what the
+widget is or what toolkit it is from.  Unfortunately this also has its
+hairy properties; the lwlib code quite complex. And of course lwlib has
+to know at some level what the widget is and how to set its properties.
+
+The @code{widget_instance} structure also contains a pointer to the root
+of its tree.  Widget instances are further confi
+
+
+@node Scrollbars, Menubars, Generic Widget Interface, Lucid Widget Library
+@subsection Scrollbars
+
+@node Menubars, Checkboxes and Radio Buttons, Scrollbars, Lucid Widget Library
+@subsection Menubars
+
+@node Checkboxes and Radio Buttons, Progress Bars, Menubars, Lucid Widget Library
+@subsection Checkboxes and Radio Buttons
+
+@node Progress Bars, Tab Controls, Checkboxes and Radio Buttons, Lucid Widget Library
+@subsection Progress Bars
+
+@node Tab Controls, , Progress Bars, Lucid Widget Library
+@subsection Tab Controls
 
 @include index.texi
 
@@ -8798,4 +9035,3 @@ Not yet documented.
 @c That's all
 
 @bye
-