update.
[chise/xemacs-chise.git-] / man / internals / internals.texi
index a59e3c1..db888d1 100644 (file)
@@ -1721,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}
@@ -1753,6 +1738,24 @@ 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
 ``declare with initializer'' form for these variables, such as @code{int
@@ -4864,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
@@ -5865,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
@@ -5874,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:
@@ -5893,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
@@ -5925,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.
 
@@ -5943,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
@@ -5976,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.
 
@@ -6017,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
@@ -6042,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
@@ -8734,8 +8734,8 @@ 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
 @code{Fglyph_height} is called. Instantiation causes an image-instance
-to be created and cached. This cache is on a device basis for all glyphs
-except glyph-widgets, and on a window basis for glyph widgets.  The
+to be created and cached. This cache is on a per-device basis for all glyphs
+except widget-glyphs, and on a per-window basis for widgets-glyphs.  The
 caching is done by @code{image_instantiate} and is necessary because it
 is generally possible to display an image-instance in multiple
 domains. For instance if we create a Pixmap, we can actually display
@@ -8752,6 +8752,74 @@ cached on an XEmacs window basis.
 Any action on a glyph first consults the cache before actually
 instantiating a widget.
 
+@section Glyph Instantiation
+
+Glyph instantiation is a hairy topic and requires some explanation. The
+guts of glyph instantiation is contained within
+@code{image_instantiate}. A glyph contains an image which is a
+specifier. When a glyph function - for instance @code{Fglyph_height} -
+asks for a property of the glyph that can only be determined from its
+instantiated state, then the glyph image is instantiated and an image
+instance created. The instantiation process is governed by the specifier
+code and goes through a series of steps:
+
+@itemize @bullet
+@item
+Validation. Instantiation of image instances happens dynamically - often
+within the guts of redisplay. Thus it is often not feasible to catch
+instantiator errors at instantiation time. Instead the instantiator is
+validated at the time it is added to the image specifier. This function
+is defined by @code{image_validate} and at a simple level validates
+keyword value pairs.
+@item
+Duplication. The specifier code by default takes a copy of the
+instantiator. This is reasonable for most specifiers but in the case of
+widget-glyphs can be problematic, since some of the properties in the
+instantiator - for instance callbacks - could cause infinite recursion
+in the copying process. Thus the image code defines a function -
+@code{image_copy_instantiator} - which will selectively copy values.
+This is controlled by the way that a keyword is defined either using
+@code{IIFORMAT_VALID_KEYWORD} or
+@code{IIFORMAT_VALID_NONCOPY_KEYWORD}. Note that the image caching and
+redisplay code relies on instantiator copying to ensure that current and
+new instantiators are actually different rather than referring to the
+same thing.
+@item
+Normalization. Once the instantiator has been copied it must be
+converted into a form that is viable at instantiation time. This can
+involve no changes at all, but typically involves things like converting
+file names to the actual data. This function is defined by
+@code{image_going_to_add} and @code{normalize_image_instantiator}.
+@item
+Instantiation. When an image instance is actually required for display
+it is instantiated using @code{image_instantiate}. This involves calling
+instantiate methods that are specific to the type of image being
+instantiated.
+@end itemize
+
+The final instantiation phase also involves a number of steps. In order
+to understand these we need to describe a number of concepts.
+
+An image is instantiated in a @dfn{domain}, where a domain can be any
+one of a device, frame, window or image-instance. The domain gives the
+image-instance context and identity and properties that affect the
+appearance of the image-instance may be different for the same glyph
+instantiated in different domains. An example is the face used to
+display the image-instance.
+
+Although an image is instantiated in a particular domain the
+instantiation domain is not necessarily the domain in which the
+image-instance is cached. For example a pixmap can be instantiated in a
+window be actually be cached on a per-device basis. The domain in which
+the image-instance is actually cached is called the
+@dfn{governing-domain}. A governing-domain is currently either a device
+or a window. Widget-glyphs and text-glyphs have a window as a
+governing-domain, all other image-instances have a device as the
+governing-domain. The governing domain for an image-instance is
+determined using the governing_domain image-instance method.
+
+@section Widget-Glyphs
+
 @section Widget-Glyphs in the MS-Windows Environment
 
 To Do
@@ -8763,6 +8831,24 @@ 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.
 
+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 @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 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.
+
 @node Specifiers, Menus, Glyphs, Top
 @chapter Specifiers