* Menu:
-* Property Lists:: `remprop', `getf', `remf'
+* Property Lists:: `getf', `remf'
* Creating Symbols:: `gensym', `gentemp'
\1f
==============
These functions augment the standard Emacs Lisp functions `get' and
-`put' for operating on properties attached to symbols. There are also
+`put' for operating on properties attached to objects. There are also
functions for working with property lists as first-class data
-structures not attached to particular symbols.
-
- - Function: remprop symbol property
- This function removes the entry for PROPERTY from the property
- list of SYMBOL. It returns a true value if the property was
- indeed found and removed, or `nil' if there was no such property.
- (This function was probably omitted from Emacs originally because,
- since `get' did not allow a DEFAULT, it was very difficult to
- distinguish between a missing property and a property whose value
- was `nil'; thus, setting a property to `nil' was close enough to
- `remprop' for most purposes.)
+structures not attached to particular objects.
- Function: getf place property &optional default
This function scans the list PLACE as if it were a property list,
* remove-duplicates: Sequence Functions.
* remove-if: Sequence Functions.
* remove-if-not: Sequence Functions.
-* remprop: Property Lists.
* remq: Sequence Functions.
* replace: Sequence Functions.
* rest: List Functions.
* Modules for Internationalization::
\1f
-File: internals.info, Node: Low-Level Modules, Next: Basic Lisp Modules, Up: A Summary of the Various XEmacs Modules
+File: internals.info, Node: Low-Level Modules, Next: Basic Lisp Modules, Prev: A Summary of the Various XEmacs Modules, Up: A Summary of the Various XEmacs Modules
Low-Level Modules
=================
Asian-language support, and is not currently used.
\1f
-File: internals.info, Node: Allocation of Objects in XEmacs Lisp, Next: Events and the Event Loop, Prev: A Summary of the Various XEmacs Modules, Up: Top
+File: internals.info, Node: Allocation of Objects in XEmacs Lisp, Next: Dumping, Prev: A Summary of the Various XEmacs Modules, Up: Top
Allocation of Objects in XEmacs Lisp
************************************
* Compiled Function::
\1f
-File: internals.info, Node: Introduction to Allocation, Next: Garbage Collection, Up: Allocation of Objects in XEmacs Lisp
+File: internals.info, Node: Introduction to Allocation, Next: Garbage Collection, Prev: Allocation of Objects in XEmacs Lisp, Up: Allocation of Objects in XEmacs Lisp
Introduction to Allocation
==========================
* sweep_bit_vectors_1::
\1f
-File: internals.info, Node: Invocation, Next: garbage_collect_1, Up: Garbage Collection - Step by Step
+File: internals.info, Node: Invocation, Next: garbage_collect_1, Prev: Garbage Collection - Step by Step, Up: Garbage Collection - Step by Step
Invocation
----------
already marked, and need not be marked for the second time (checked by
`MARKED_RECORD_HEADER_P'). If it is a special, unmarkable object
(`UNMARKABLE_RECORD_HEADER_P', apparently, these are objects that sit
-in some CONST space, and can therefore not be marked, see
+in some const space, and can therefore not be marked, see
`this_one_is_unmarkable' in `alloc.c').
Now, the actual marking is feasible. We do so by once using the macro
Not yet documented.
\1f
-File: internals.info, Node: Events and the Event Loop, Next: Evaluation; Stack Frames; Bindings, Prev: Allocation of Objects in XEmacs Lisp, Up: Top
-
-Events and the Event Loop
-*************************
+File: internals.info, Node: Dumping, Next: Events and the Event Loop, Prev: Allocation of Objects in XEmacs Lisp, Up: Top
+
+Dumping
+*******
+
+What is dumping and its justification
+=====================================
+
+ The C code of XEmacs is just a Lisp engine with a lot of built-in
+primitives useful for writing an editor. The editor itself is written
+mostly in Lisp, and represents around 100K lines of code. Loading and
+executing the initialization of all this code takes a bit a time (five
+to ten times the usual startup time of current xemacs) and requires
+having all the lisp source files around. Having to reload them each
+time the editor is started would not be acceptable.
+
+ The traditional solution to this problem is called dumping: the build
+process first creates the lisp engine under the name `temacs', then
+runs it until it has finished loading and initializing all the lisp
+code, and eventually creates a new executable called `xemacs' including
+both the object code in `temacs' and all the contents of the memory
+after the initialization.
+
+ This solution, while working, has a huge problem: the creation of the
+new executable from the actual contents of memory is an extremely
+system-specific process, quite error-prone, and which interferes with a
+lot of system libraries (like malloc). It is even getting worse
+nowadays with libraries using constructors which are automatically
+called when the program is started (even before main()) which tend to
+crash when they are called multiple times, once before dumping and once
+after (IRIX 6.x libz.so pulls in some C++ image libraries thru
+dependencies which have this problem). Writing the dumper is also one
+of the most difficult parts of porting XEmacs to a new operating system.
+Basically, `dumping' is an operation that is just not officially
+supported on many operating systems.
+
+ The aim of the portable dumper is to solve the same problem as the
+system-specific dumper, that is to be able to reload quickly, using only
+a small number of files, the fully initialized lisp part of the editor,
+without any system-specific hacks.
* Menu:
-* Introduction to Events::
-* Main Loop::
-* Specifics of the Event Gathering Mechanism::
-* Specifics About the Emacs Event::
-* The Event Stream Callback Routines::
-* Other Event Loop Functions::
-* Converting Events::
-* Dispatching Events; The Command Builder::
+* Overview::
+* Data descriptions::
+* Dumping phase::
+* Reloading phase::
+* Remaining issues::
\1f
-File: internals.info, Node: Introduction to Events, Next: Main Loop, Up: Events and the Event Loop
-
-Introduction to Events
-======================
-
- An event is an object that encapsulates information about an
-interesting occurrence in the operating system. Events are generated
-either by user action, direct (e.g. typing on the keyboard or moving
-the mouse) or indirect (moving another window, thereby generating an
-expose event on an Emacs frame), or as a result of some other typically
-asynchronous action happening, such as output from a subprocess being
-ready or a timer expiring. Events come into the system in an
-asynchronous fashion (typically through a callback being called) and
-are converted into a synchronous event queue (first-in, first-out) in a
-process that we will call "collection".
-
- Note that each application has its own event queue. (It is
-immaterial whether the collection process directly puts the events in
-the proper application's queue, or puts them into a single system
-queue, which is later split up.)
-
- The most basic level of event collection is done by the operating
-system or window system. Typically, XEmacs does its own event
-collection as well. Often there are multiple layers of collection in
-XEmacs, with events from various sources being collected into a queue,
-which is then combined with other sources to go into another queue
-(i.e. a second level of collection), with perhaps another level on top
-of this, etc.
-
- XEmacs has its own types of events (called "Emacs events"), which
-provides an abstract layer on top of the system-dependent nature of the
-most basic events that are received. Part of the complex nature of the
-XEmacs event collection process involves converting from the
-operating-system events into the proper Emacs events--there may not be
-a one-to-one correspondence.
-
- Emacs events are documented in `events.h'; I'll discuss them later.
+File: internals.info, Node: Overview, Next: Data descriptions, Prev: Dumping, Up: Dumping
+
+Overview
+========
+
+ The portable dumping system has to:
+
+ 1. At dump time, write all initialized, non-quickly-rebuildable data
+ to a file [Note: currently named `xemacs.dmp', but the name will
+ change], along with all informations needed for the reloading.
+
+ 2. When starting xemacs, reload the dump file, relocate it to its new
+ starting address if needed, and reinitialize all pointers to this
+ data. Also, rebuild all the quickly rebuildable data.
Foundation instead of in the original English.
\1f
+File: internals.info, Node: Data descriptions, Next: Dumping phase, Prev: Overview, Up: Dumping
+
+Data descriptions
+=================
+
+ The more complex task of the dumper is to be able to write lisp
+objects (lrecords) and C structs to disk and reload them at a different
+address, updating all the pointers they include in the process. This
+is done by using external data descriptions that give information about
+the layout of the structures in memory.
+
+ The specification of these descriptions is in lrecord.h. A
+description of an lrecord is an array of struct lrecord_description.
+Each of these structs include a type, an offset in the structure and
+some optional parameters depending on the type. For instance, here is
+the string description:
+
+ static const struct lrecord_description string_description[] = {
+ { XD_BYTECOUNT, offsetof (Lisp_String, size) },
+ { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data), XD_INDIRECT(0, 1) },
+ { XD_LISP_OBJECT, offsetof (Lisp_String, plist) },
+ { XD_END }
+ };
+
+ The first line indicates a member of type Bytecount, which is used by
+the next, indirect directive. The second means "there is a pointer to
+some opaque data in the field `data'". The length of said data is
+given by the expression `XD_INDIRECT(0, 1)', which means "the value in
+the 0th line of the description (welcome to C) plus one". The third
+line means "there is a Lisp_Object member `plist' in the Lisp_String
+structure". `XD_END' then ends the description.
+
+ This gives us all the information we need to move around what is
+pointed to by a structure (C or lrecord) and, by transitivity,
+everything that it points to. The only missing information for dumping
+is the size of the structure. For lrecords, this is part of the
+lrecord_implementation, so we don't need to duplicate it. For C
+structures we use a struct struct_description, which includes a size
+field and a pointer to an associated array of lrecord_description.
+
+\1f
+File: internals.info, Node: Dumping phase, Next: Reloading phase, Prev: Data descriptions, Up: Dumping
+
+Dumping phase
+=============
+
+ Dumping is done by calling the function pdump() (in alloc.c) which is
+invoked from Fdump_emacs (in emacs.c). This function performs a number
+of tasks.
+
+* Menu:
+
+* Object inventory::
+* Address allocation::
+* The header::
+* Data dumping::
+* Pointers dumping::
+
+\1f
+File: internals.info, Node: Object inventory, Next: Address allocation, Prev: Dumping phase, Up: Dumping phase
+
+Object inventory
+----------------
+
+ The first task is to build the list of the objects to dump. This
+includes:
+
+ * lisp objects
+
+ * C structures
+
+ We end up with one `pdump_entry_list_elmt' per object group (arrays
+of C structs are kept together) which includes a pointer to the first
+object of the group, the per-object size and the count of objects in the
+group, along with some other information which is initialized later.
+
+ These entries are linked together in `pdump_entry_list' structures
+and can be enumerated thru either:
+
+ 1. the `pdump_object_table', an array of `pdump_entry_list', one per
+ lrecord type, indexed by type number.
+
+ 2. the `pdump_opaque_data_list', used for the opaque data which does
+ not include pointers, and hence does not need descriptions.
+
+ 3. the `pdump_struct_table', which is a vector of
+ `struct_description'/`pdump_entry_list' pairs, used for non-opaque
+ C structures.
+
+ This uses a marking strategy similar to the garbage collector. Some
+differences though:
+
+ 1. We do not use the mark bit (which does not exist for C structures
+ anyway), we use a big hash table instead.
+
+ 2. We do not use the mark function of lrecords but instead rely on the
+ external descriptions. This happens essentially because we need to
+ follow pointers to C structures and opaque data in addition to
+ Lisp_Object members.
+
+ This is done by `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.
+
+ 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 `pdump_add_entry()' and looked up with
+`pdump_get_entry()'. There is no need for entry removal. The hash
+value is computed quite basically from the object pointer by
+`pdump_make_hash()'.
+
+ The roots for the marking are:
+
+ 1. the `staticpro''ed variables (there is a special
+ `staticpro_nodump()' call for protected variables we do not want
+ to dump).
+
+ 2. the `pdump_wire''d variables (`staticpro' is equivalent to
+ `staticpro_nodump()' + `pdump_wire()').
+
+ 3. the `dumpstruct''ed variables, which points to C structures.
+
+ This does not include the GCPRO'ed variables, the specbinds, the
+catchtags, the backlist, the redisplay or the profiling info, since we
+do not want to rebuild the actual chain of lisp calls which end up to
+the dump-emacs call, only the global variables.
+
+ Weak lists and weak hash tables are dumped as if they were their
+non-weak equivalent (without changing their type, of course). This has
+not yet been a problem.
+
+\1f
+File: internals.info, Node: Address allocation, Next: The header, Prev: Object inventory, Up: Dumping phase
+
+Address allocation
+------------------
+
+ The next step is to allocate the offsets of each of the objects in
+the final dump file. This is done by `pdump_allocate_offset()' which
+is called indirectly by `pdump_scan_by_alignment()'.
+
+ The strategy to deal with alignment problems uses these facts:
+
+ 1. real world alignment requirements are powers of two.
+
+ 2. 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 upper bound of the alignment requirements of a given
+ structure by looking at which power of two its size is a multiple.
+
+ 3. the non-variant part of variable size lrecords has an alignment
+ requirement of 4.
+
+ Hence, for each lrecord type, C struct type or opaque data block the
+alignment requirement is computed as a power of two, with a minimum of
+2^2 for lrecords. `pdump_scan_by_alignment()' then scans all the
+`pdump_entry_list_elmt''s, the ones with the highest requirements
+first. This ensures the best packing.
+
+ The maximum alignment requirement we take into account is 2^8.
+
+ `pdump_allocate_offset()' only has to do a linear allocation,
+starting at offset 256 (this leaves room for the header and keep the
+alignments happy).
+
+\1f
+File: internals.info, Node: The header, Next: Data dumping, Prev: Address allocation, Up: Dumping phase
+
+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).
+
+\1f
+File: internals.info, Node: Data dumping, Next: Pointers dumping, Prev: The header, Up: Dumping phase
+
+Data dumping
+------------
+
+ The data is dumped in the same order as the addresses were allocated
+by `pdump_dump_data()', called from `pdump_scan_by_alignment()'. This
+function copies the data to a temporary buffer, relocates all pointers
+in the object to the addresses allocated in step Address Allocation,
+and writes it to the file. Using the same order means that, if we are
+careful with lrecords whose size is not a multiple of 4, we are ensured
+that the object is always written at the offset in the file allocated
+in step Address Allocation.
+
+\1f
+File: internals.info, Node: Pointers dumping, Prev: Data dumping, Up: Dumping phase
+
+Pointers dumping
+----------------
+
+ A bunch of tables needed to reassign properly the global pointers are
+then written. They are:
+
+ 1. the staticpro array
+
+ 2. the dumpstruct array
+
+ 3. the lrecord_implementation_table array
+
+ 4. a vector of all the offsets to the objects in the file that
+ include a description (for faster relocation at reload time)
+
+ 5. the pdump_wired and pdump_wired_list arrays
+
+ For each of the arrays 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 `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.
+
+ This is the end of the dumping part.
+
+\1f
+File: internals.info, Node: Reloading phase, Next: Remaining issues, Prev: Dumping phase, Up: Dumping
+
+Reloading phase
+===============
+
+File loading
+------------
+
+ The file is mmap'ed in memory (which ensures a PAGESIZE alignment, at
+least 4096), or if mmap is unavailable or fails, a 256-bytes aligned
+malloc is done and the file is loaded.
+
+ Some variables are reinitialized from the values found in the header.
+
+ The difference between the actual loading address and the
+reloc_address is computed and will be used for all the relocations.
+
+Putting back the staticvec
+--------------------------
+
+ The staticvec array is memcpy'd from the file and the variables it
+points to are reset to the relocated objects addresses.
+
+Putting back the dumpstructed variables
+---------------------------------------
+
+ The variables pointed to by dumpstruct in the dump phase are reset to
+the right relocated object addresses.
+
+lrecord_implementations_table
+-----------------------------
+
+ The lrecord_implementations_table is reset to its dump time state and
+the right lrecord_type_index values are put in.
+
+Object relocation
+-----------------
+
+ All the objects are relocated using their description and their
+offset by `pdump_reloc_one'. This step is unnecessary if the
+reloc_address is equal to the file loading address.
+
+Putting back the pdump_wire and pdump_wire_list variables
+---------------------------------------------------------
+
+ Same as Putting back the dumpstructed variables.
+
+Reorganize the hash tables
+--------------------------
+
+ Since some of the hash values in the lisp hash tables are
+address-dependent, their layout is now wrong. So we go through each of
+them and have them resorted by calling `pdump_reorganize_hash_table'.
+
+\1f
+File: internals.info, Node: Remaining issues, Prev: Reloading phase, Up: Dumping
+
+Remaining issues
+================
+
+ The build process will have to start a post-dump xemacs, ask it the
+loading address (which will, hopefully, be always the same between
+different xemacs invocations) and relocate the file to the new address.
+This way the object relocation phase will not have to be done, which
+means no writes in the objects and that, because of the use of mmap, the
+dumped data will be shared between all the xemacs running on the
+computer.
+
+ Some executable signature will be necessary to ensure that a given
+dump file is really associated with a given executable, or random
+crashes will occur. Maybe a random number set at compile or configure
+time thru a define. This will also allow for having
+differently-compiled xemacsen on the same system (mule and no-mule
+comes to mind).
+
+ The DOC file contents should probably end up in the dump file.
+
+\1f
+File: internals.info, Node: Events and the Event Loop, Next: Evaluation; Stack Frames; Bindings, Prev: Dumping, Up: Top
+
+Events and the Event Loop
+*************************
+
+* Menu:
+
+* Introduction to Events::
+* Main Loop::
+* Specifics of the Event Gathering Mechanism::
+* Specifics About the Emacs Event::
+* The Event Stream Callback Routines::
+* Other Event Loop Functions::
+* Converting Events::
+* Dispatching Events; The Command Builder::
+
+\1f
+File: internals.info, Node: Introduction to Events, Next: Main Loop, Prev: Events and the Event Loop, Up: Events and the Event Loop
+
+Introduction to Events
+======================
+
+ An event is an object that encapsulates information about an
+interesting occurrence in the operating system. Events are generated
+either by user action, direct (e.g. typing on the keyboard or moving
+the mouse) or indirect (moving another window, thereby generating an
+expose event on an Emacs frame), or as a result of some other typically
+asynchronous action happening, such as output from a subprocess being
+ready or a timer expiring. Events come into the system in an
+asynchronous fashion (typically through a callback being called) and
+are converted into a synchronous event queue (first-in, first-out) in a
+process that we will call "collection".
+
+ Note that each application has its own event queue. (It is
+immaterial whether the collection process directly puts the events in
+the proper application's queue, or puts them into a single system
+queue, which is later split up.)
+
+ The most basic level of event collection is done by the operating
+system or window system. Typically, XEmacs does its own event
+collection as well. Often there are multiple layers of collection in
+XEmacs, with events from various sources being collected into a queue,
+which is then combined with other sources to go into another queue
+(i.e. a second level of collection), with perhaps another level on top
+of this, etc.
+
+ XEmacs has its own types of events (called "Emacs events"), which
+provides an abstract layer on top of the system-dependent nature of the
+most basic events that are received. Part of the complex nature of the
+XEmacs event collection process involves converting from the
+operating-system events into the proper Emacs events--there may not be
+a one-to-one correspondence.
+
+ Emacs events are documented in `events.h'; I'll discuss them later.
+
+\1f
File: internals.info, Node: Main Loop, Next: Specifics of the Event Gathering Mechanism, Prev: Introduction to Events, Up: Events and the Event Loop
Main Loop
* Catch and Throw::
\1f
-File: internals.info, Node: Evaluation, Next: Dynamic Binding; The specbinding Stack; Unwind-Protects, Up: Evaluation; Stack Frames; Bindings
+File: internals.info, Node: Evaluation, Next: Dynamic Binding; The specbinding Stack; Unwind-Protects, Prev: Evaluation; Stack Frames; Bindings, Up: Evaluation; Stack Frames; Bindings
Evaluation
==========
* Symbol Values::
\1f
-File: internals.info, Node: Introduction to Symbols, Next: Obarrays, Up: Symbols and Variables
+File: internals.info, Node: Introduction to Symbols, Next: Obarrays, Prev: Symbols and Variables, Up: Symbols and Variables
Introduction to Symbols
=======================
additional values with particular names, and once again the namespace is
independent of the function and variable namespaces.
-\1f
-File: internals.info, Node: Obarrays, Next: Symbol Values, Prev: Introduction to Symbols, Up: Symbols and Variables
-
-Obarrays
-========
-
- The identity of symbols with their names is accomplished through a
-structure called an obarray, which is just a poorly-implemented hash
-table mapping from strings to symbols whose name is that string. (I say
-"poorly implemented" because an obarray appears in Lisp as a vector
-with some hidden fields rather than as its own opaque type. This is an
-Emacs Lisp artifact that should be fixed.)
-
- Obarrays are implemented as a vector of some fixed size (which should
-be a prime for best results), where each "bucket" of the vector
-contains one or more symbols, threaded through a hidden `next' field in
-the symbol. Lookup of a symbol in an obarray, and adding a symbol to
-an obarray, is accomplished through standard hash-table techniques.
-
- The standard Lisp function for working with symbols and obarrays is
-`intern'. This looks up a symbol in an obarray given its name; if it's
-not found, a new symbol is automatically created with the specified
-name, added to the obarray, and returned. This is what happens when the
-Lisp reader encounters a symbol (or more precisely, encounters the name
-of a symbol) in some text that it is reading. There is a standard
-obarray called `obarray' that is used for this purpose, although the
-Lisp programmer is free to create his own obarrays and `intern' symbols
-in them.
-
- Note that, once a symbol is in an obarray, it stays there until
-something is done about it, and the standard obarray `obarray' always
-stays around, so once you use any particular variable name, a
-corresponding symbol will stay around in `obarray' until you exit
-XEmacs.
-
- Note that `obarray' itself is a variable, and as such there is a
-symbol in `obarray' whose name is `"obarray"' and which contains
-`obarray' as its value.
-
- Note also that this call to `intern' occurs only when in the Lisp
-reader, not when the code is executed (at which point the symbol is
-already around, stored as such in the definition of the function).
-
- You can create your own obarray using `make-vector' (this is
-horrible but is an artifact) and intern symbols into that obarray.
-Doing that will result in two or more symbols with the same name.
-However, at most one of these symbols is in the standard `obarray': You
-cannot have two symbols of the same name in any particular obarray.
-Note that you cannot add a symbol to an obarray in any fashion other
-than using `intern': i.e. you can't take an existing symbol and put it
-in an existing obarray. Nor can you change the name of an existing
-symbol. (Since obarrays are vectors, you can violate the consistency of
-things by storing directly into the vector, but let's ignore that
-possibility.)
-
- Usually symbols are created by `intern', but if you really want, you
-can explicitly create a symbol using `make-symbol', giving it some
-name. The resulting symbol is not in any obarray (i.e. it is
-"uninterned"), and you can't add it to any obarray. Therefore its
-primary purpose is as a symbol to use in macros to avoid namespace
-pollution. It can also be used as a carrier of information, but cons
-cells could probably be used just as well.
-
- You can also use `intern-soft' to look up a symbol but not create a
-new one, and `unintern' to remove a symbol from an obarray. This
-returns the removed symbol. (Remember: You can't put the symbol back
-into any obarray.) Finally, `mapatoms' maps over all of the symbols in
-an obarray.
-
-\1f
-File: internals.info, Node: Symbol Values, Prev: Obarrays, Up: Symbols and Variables
-
-Symbol Values
-=============
-
- The value field of a symbol normally contains a Lisp object.
-However, a symbol can be "unbound", meaning that it logically has no
-value. This is internally indicated by storing a special Lisp object,
-called "the unbound marker" and stored in the global variable
-`Qunbound'. The unbound marker is of a special Lisp object type called
-"symbol-value-magic". It is impossible for the Lisp programmer to
-directly create or access any object of this type.
-
- *You must not let any "symbol-value-magic" object escape to the Lisp
-level.* Printing any of these objects will cause the message `INTERNAL
-EMACS BUG' to appear as part of the print representation. (You may see
-this normally when you call `debug_print()' from the debugger on a Lisp
-object.) If you let one of these objects escape to the Lisp level, you
-will violate a number of assumptions contained in the C code and make
-the unbound marker not function right.
-
- When a symbol is created, its value field (and function field) are
-set to `Qunbound'. The Lisp programmer can restore these conditions
-later using `makunbound' or `fmakunbound', and can query to see whether
-the value of function fields are "bound" (i.e. have a value other than
-`Qunbound') using `boundp' and `fboundp'. The fields are set to a
-normal Lisp object using `set' (or `setq') and `fset'.
-
- Other symbol-value-magic objects are used as special markers to
-indicate variables that have non-normal properties. This includes any
-variables that are tied into C variables (setting the variable magically
-sets some global variable in the C code, and likewise for retrieving the
-variable's value), variables that magically tie into slots in the
-current buffer, variables that are buffer-local, etc. The
-symbol-value-magic object is stored in the value cell in place of a
-normal object, and the code to retrieve a symbol's value (i.e.
-`symbol-value') knows how to do special things with them. This means
-that you should not just fetch the value cell directly if you want a
-symbol's value.
-
- The exact workings of this are rather complex and involved and are
-well-documented in comments in `buffer.c', `symbols.c', and `lisp.h'.
-
-\1f
-File: internals.info, Node: Buffers and Textual Representation, Next: MULE Character Sets and Encodings, Prev: Symbols and Variables, Up: Top
-
-Buffers and Textual Representation
-**********************************
-
-* Menu:
-
-* Introduction to Buffers:: A buffer holds a block of text such as a file.
-* The Text in a Buffer:: Representation of the text in a buffer.
-* Buffer Lists:: Keeping track of all buffers.
-* Markers and Extents:: Tagging locations within a buffer.
-* Bufbytes and Emchars:: Representation of individual characters.
-* The Buffer Object:: The Lisp object corresponding to a buffer.
-
-\1f
-File: internals.info, Node: Introduction to Buffers, Next: The Text in a Buffer, Up: Buffers and Textual Representation
-
-Introduction to Buffers
-=======================
-
- A buffer is logically just a Lisp object that holds some text. In
-this, it is like a string, but a buffer is optimized for frequent
-insertion and deletion, while a string is not. Furthermore:
-
- 1. Buffers are "permanent" objects, i.e. once you create them, they
- remain around, and need to be explicitly deleted before they go
- away.
-
- 2. Each buffer has a unique name, which is a string. Buffers are
- normally referred to by name. In this respect, they are like
- symbols.
-
- 3. Buffers have a default insertion position, called "point".
- Inserting text (unless you explicitly give a position) goes at
- point, and moves point forward past the text. This is what is
- going on when you type text into Emacs.
-
- 4. Buffers have lots of extra properties associated with them.
-
- 5. Buffers can be "displayed". What this means is that there exist a
- number of "windows", which are objects that correspond to some
- visible section of your display, and each window has an associated
- buffer, and the current contents of the buffer are shown in that
- section of the display. The redisplay mechanism (which takes care
- of doing this) knows how to look at the text of a buffer and come
- up with some reasonable way of displaying this. Many of the
- properties of a buffer control how the buffer's text is displayed.
-
- 6. One buffer is distinguished and called the "current buffer". It is
- stored in the variable `current_buffer'. Buffer operations operate
- on this buffer by default. When you are typing text into a
- buffer, the buffer you are typing into is always `current_buffer'.
- Switching to a different window changes the current buffer. Note
- that Lisp code can temporarily change the current buffer using
- `set-buffer' (often enclosed in a `save-excursion' so that the
- former current buffer gets restored when the code is finished).
- However, calling `set-buffer' will NOT cause a permanent change in
- the current buffer. The reason for this is that the top-level
- event loop sets `current_buffer' to the buffer of the selected
- window, each time it finishes executing a user command.
-
- Make sure you understand the distinction between "current buffer"
-and "buffer of the selected window", and the distinction between
-"point" of the current buffer and "window-point" of the selected
-window. (This latter distinction is explained in detail in the section
-on windows.)
-
-\1f
-File: internals.info, Node: The Text in a Buffer, Next: Buffer Lists, Prev: Introduction to Buffers, Up: Buffers and Textual Representation
-
-The Text in a Buffer
-====================
-
- The text in a buffer consists of a sequence of zero or more
-characters. A "character" is an integer that logically represents a
-letter, number, space, or other unit of text. Most of the characters
-that you will typically encounter belong to the ASCII set of characters,
-but there are also characters for various sorts of accented letters,
-special symbols, Chinese and Japanese ideograms (i.e. Kanji, Katakana,
-etc.), Cyrillic and Greek letters, etc. The actual number of possible
-characters is quite large.
-
- For now, we can view a character as some non-negative integer that
-has some shape that defines how it typically appears (e.g. as an
-uppercase A). (The exact way in which a character appears depends on the
-font used to display the character.) The internal type of characters in
-the C code is an `Emchar'; this is just an `int', but using a symbolic
-type makes the code clearer.
-
- Between every character in a buffer is a "buffer position" or
-"character position". We can speak of the character before or after a
-particular buffer position, and when you insert a character at a
-particular position, all characters after that position end up at new
-positions. When we speak of the character "at" a position, we really
-mean the character after the position. (This schizophrenia between a
-buffer position being "between" a character and "on" a character is
-rampant in Emacs.)
-
- Buffer positions are numbered starting at 1. This means that
-position 1 is before the first character, and position 0 is not valid.
-If there are N characters in a buffer, then buffer position N+1 is
-after the last one, and position N+2 is not valid.
-
- The internal makeup of the Emchar integer varies depending on whether
-we have compiled with MULE support. If not, the Emchar integer is an
-8-bit integer with possible values from 0 - 255. 0 - 127 are the
-standard ASCII characters, while 128 - 255 are the characters from the
-ISO-8859-1 character set. If we have compiled with MULE support, an
-Emchar is a 19-bit integer, with the various bits having meanings
-according to a complex scheme that will be detailed later. The
-characters numbered 0 - 255 still have the same meanings as for the
-non-MULE case, though.
-
- Internally, the text in a buffer is represented in a fairly simple
-fashion: as a contiguous array of bytes, with a "gap" of some size in
-the middle. Although the gap is of some substantial size in bytes,
-there is no text contained within it: From the perspective of the text
-in the buffer, it does not exist. The gap logically sits at some buffer
-position, between two characters (or possibly at the beginning or end of
-the buffer). Insertion of text in a buffer at a particular position is
-always accomplished by first moving the gap to that position (i.e.
-through some block moving of text), then writing the text into the
-beginning of the gap, thereby shrinking the gap. If the gap shrinks
-down to nothing, a new gap is created. (What actually happens is that a
-new gap is "created" at the end of the buffer's text, which requires
-nothing more than changing a couple of indices; then the gap is "moved"
-to the position where the insertion needs to take place by moving up in
-memory all the text after that position.) Similarly, deletion occurs
-by moving the gap to the place where the text is to be deleted, and
-then simply expanding the gap to include the deleted text.
-("Expanding" and "shrinking" the gap as just described means just that
-the internal indices that keep track of where the gap is located are
-changed.)
-
- Note that the total amount of memory allocated for a buffer text
-never decreases while the buffer is live. Therefore, if you load up a
-20-megabyte file and then delete all but one character, there will be a
-20-megabyte gap, which won't get any smaller (except by inserting
-characters back again). Once the buffer is killed, the memory allocated
-for the buffer text will be freed, but it will still be sitting on the
-heap, taking up virtual memory, and will not be released back to the
-operating system. (However, if you have compiled XEmacs with rel-alloc,
-the situation is different. In this case, the space _will_ be released
-back to the operating system. However, this tends to result in a
-noticeable speed penalty.)
-
- Astute readers may notice that the text in a buffer is represented as
-an array of _bytes_, while (at least in the MULE case) an Emchar is a
-19-bit integer, which clearly cannot fit in a byte. This means (of
-course) that the text in a buffer uses a different representation from
-an Emchar: specifically, the 19-bit Emchar becomes a series of one to
-four bytes. The conversion between these two representations is complex
-and will be described later.
-
- In the non-MULE case, everything is very simple: An Emchar is an
-8-bit value, which fits neatly into one byte.
-
- If we are given a buffer position and want to retrieve the character
-at that position, we need to follow these steps:
-
- 1. Pretend there's no gap, and convert the buffer position into a
- "byte index" that indexes to the appropriate byte in the buffer's
- stream of textual bytes. By convention, byte indices begin at 1,
- just like buffer positions. In the non-MULE case, byte indices
- and buffer positions are identical, since one character equals one
- byte.
-
- 2. Convert the byte index into a "memory index", which takes the gap
- into account. The memory index is a direct index into the block of
- memory that stores the text of a buffer. This basically just
- involves checking to see if the byte index is past the gap, and if
- so, adding the size of the gap to it. By convention, memory
- indices begin at 1, just like buffer positions and byte indices,
- and when referring to the position that is "at" the gap, we always
- use the memory position at the _beginning_, not at the end, of the
- gap.
-
- 3. Fetch the appropriate bytes at the determined memory position.
-
- 4. Convert these bytes into an Emchar.
-
- In the non-Mule case, (3) and (4) boil down to a simple one-byte
-memory access.
-
- Note that we have defined three types of positions in a buffer:
-
- 1. "buffer positions" or "character positions", typedef `Bufpos'
-
- 2. "byte indices", typedef `Bytind'
-
- 3. "memory indices", typedef `Memind'
-
- All three typedefs are just `int's, but defining them this way makes
-things a lot clearer.
-
- Most code works with buffer positions. In particular, all Lisp code
-that refers to text in a buffer uses buffer positions. Lisp code does
-not know that byte indices or memory indices exist.
-
- Finally, we have a typedef for the bytes in a buffer. This is a
-`Bufbyte', which is an unsigned char. Referring to them as Bufbytes
-underscores the fact that we are working with a string of bytes in the
-internal Emacs buffer representation rather than in one of a number of
-possible alternative representations (e.g. EUC-encoded text, etc.).
-
Foundation instead of in the original English.
\1f
+File: internals.info, Node: Obarrays, Next: Symbol Values, Prev: Introduction to Symbols, Up: Symbols and Variables
+
+Obarrays
+========
+
+ The identity of symbols with their names is accomplished through a
+structure called an obarray, which is just a poorly-implemented hash
+table mapping from strings to symbols whose name is that string. (I say
+"poorly implemented" because an obarray appears in Lisp as a vector
+with some hidden fields rather than as its own opaque type. This is an
+Emacs Lisp artifact that should be fixed.)
+
+ Obarrays are implemented as a vector of some fixed size (which should
+be a prime for best results), where each "bucket" of the vector
+contains one or more symbols, threaded through a hidden `next' field in
+the symbol. Lookup of a symbol in an obarray, and adding a symbol to
+an obarray, is accomplished through standard hash-table techniques.
+
+ The standard Lisp function for working with symbols and obarrays is
+`intern'. This looks up a symbol in an obarray given its name; if it's
+not found, a new symbol is automatically created with the specified
+name, added to the obarray, and returned. This is what happens when the
+Lisp reader encounters a symbol (or more precisely, encounters the name
+of a symbol) in some text that it is reading. There is a standard
+obarray called `obarray' that is used for this purpose, although the
+Lisp programmer is free to create his own obarrays and `intern' symbols
+in them.
+
+ Note that, once a symbol is in an obarray, it stays there until
+something is done about it, and the standard obarray `obarray' always
+stays around, so once you use any particular variable name, a
+corresponding symbol will stay around in `obarray' until you exit
+XEmacs.
+
+ Note that `obarray' itself is a variable, and as such there is a
+symbol in `obarray' whose name is `"obarray"' and which contains
+`obarray' as its value.
+
+ Note also that this call to `intern' occurs only when in the Lisp
+reader, not when the code is executed (at which point the symbol is
+already around, stored as such in the definition of the function).
+
+ You can create your own obarray using `make-vector' (this is
+horrible but is an artifact) and intern symbols into that obarray.
+Doing that will result in two or more symbols with the same name.
+However, at most one of these symbols is in the standard `obarray': You
+cannot have two symbols of the same name in any particular obarray.
+Note that you cannot add a symbol to an obarray in any fashion other
+than using `intern': i.e. you can't take an existing symbol and put it
+in an existing obarray. Nor can you change the name of an existing
+symbol. (Since obarrays are vectors, you can violate the consistency of
+things by storing directly into the vector, but let's ignore that
+possibility.)
+
+ Usually symbols are created by `intern', but if you really want, you
+can explicitly create a symbol using `make-symbol', giving it some
+name. The resulting symbol is not in any obarray (i.e. it is
+"uninterned"), and you can't add it to any obarray. Therefore its
+primary purpose is as a symbol to use in macros to avoid namespace
+pollution. It can also be used as a carrier of information, but cons
+cells could probably be used just as well.
+
+ You can also use `intern-soft' to look up a symbol but not create a
+new one, and `unintern' to remove a symbol from an obarray. This
+returns the removed symbol. (Remember: You can't put the symbol back
+into any obarray.) Finally, `mapatoms' maps over all of the symbols in
+an obarray.
+
+\1f
+File: internals.info, Node: Symbol Values, Prev: Obarrays, Up: Symbols and Variables
+
+Symbol Values
+=============
+
+ The value field of a symbol normally contains a Lisp object.
+However, a symbol can be "unbound", meaning that it logically has no
+value. This is internally indicated by storing a special Lisp object,
+called "the unbound marker" and stored in the global variable
+`Qunbound'. The unbound marker is of a special Lisp object type called
+"symbol-value-magic". It is impossible for the Lisp programmer to
+directly create or access any object of this type.
+
+ *You must not let any "symbol-value-magic" object escape to the Lisp
+level.* Printing any of these objects will cause the message `INTERNAL
+EMACS BUG' to appear as part of the print representation. (You may see
+this normally when you call `debug_print()' from the debugger on a Lisp
+object.) If you let one of these objects escape to the Lisp level, you
+will violate a number of assumptions contained in the C code and make
+the unbound marker not function right.
+
+ When a symbol is created, its value field (and function field) are
+set to `Qunbound'. The Lisp programmer can restore these conditions
+later using `makunbound' or `fmakunbound', and can query to see whether
+the value of function fields are "bound" (i.e. have a value other than
+`Qunbound') using `boundp' and `fboundp'. The fields are set to a
+normal Lisp object using `set' (or `setq') and `fset'.
+
+ Other symbol-value-magic objects are used as special markers to
+indicate variables that have non-normal properties. This includes any
+variables that are tied into C variables (setting the variable magically
+sets some global variable in the C code, and likewise for retrieving the
+variable's value), variables that magically tie into slots in the
+current buffer, variables that are buffer-local, etc. The
+symbol-value-magic object is stored in the value cell in place of a
+normal object, and the code to retrieve a symbol's value (i.e.
+`symbol-value') knows how to do special things with them. This means
+that you should not just fetch the value cell directly if you want a
+symbol's value.
+
+ The exact workings of this are rather complex and involved and are
+well-documented in comments in `buffer.c', `symbols.c', and `lisp.h'.
+
+\1f
+File: internals.info, Node: Buffers and Textual Representation, Next: MULE Character Sets and Encodings, Prev: Symbols and Variables, Up: Top
+
+Buffers and Textual Representation
+**********************************
+
+* Menu:
+
+* Introduction to Buffers:: A buffer holds a block of text such as a file.
+* The Text in a Buffer:: Representation of the text in a buffer.
+* Buffer Lists:: Keeping track of all buffers.
+* Markers and Extents:: Tagging locations within a buffer.
+* Bufbytes and Emchars:: Representation of individual characters.
+* The Buffer Object:: The Lisp object corresponding to a buffer.
+
+\1f
+File: internals.info, Node: Introduction to Buffers, Next: The Text in a Buffer, Prev: Buffers and Textual Representation, Up: Buffers and Textual Representation
+
+Introduction to Buffers
+=======================
+
+ A buffer is logically just a Lisp object that holds some text. In
+this, it is like a string, but a buffer is optimized for frequent
+insertion and deletion, while a string is not. Furthermore:
+
+ 1. Buffers are "permanent" objects, i.e. once you create them, they
+ remain around, and need to be explicitly deleted before they go
+ away.
+
+ 2. Each buffer has a unique name, which is a string. Buffers are
+ normally referred to by name. In this respect, they are like
+ symbols.
+
+ 3. Buffers have a default insertion position, called "point".
+ Inserting text (unless you explicitly give a position) goes at
+ point, and moves point forward past the text. This is what is
+ going on when you type text into Emacs.
+
+ 4. Buffers have lots of extra properties associated with them.
+
+ 5. Buffers can be "displayed". What this means is that there exist a
+ number of "windows", which are objects that correspond to some
+ visible section of your display, and each window has an associated
+ buffer, and the current contents of the buffer are shown in that
+ section of the display. The redisplay mechanism (which takes care
+ of doing this) knows how to look at the text of a buffer and come
+ up with some reasonable way of displaying this. Many of the
+ properties of a buffer control how the buffer's text is displayed.
+
+ 6. One buffer is distinguished and called the "current buffer". It is
+ stored in the variable `current_buffer'. Buffer operations operate
+ on this buffer by default. When you are typing text into a
+ buffer, the buffer you are typing into is always `current_buffer'.
+ Switching to a different window changes the current buffer. Note
+ that Lisp code can temporarily change the current buffer using
+ `set-buffer' (often enclosed in a `save-excursion' so that the
+ former current buffer gets restored when the code is finished).
+ However, calling `set-buffer' will NOT cause a permanent change in
+ the current buffer. The reason for this is that the top-level
+ event loop sets `current_buffer' to the buffer of the selected
+ window, each time it finishes executing a user command.
+
+ Make sure you understand the distinction between "current buffer"
+and "buffer of the selected window", and the distinction between
+"point" of the current buffer and "window-point" of the selected
+window. (This latter distinction is explained in detail in the section
+on windows.)
+
+\1f
+File: internals.info, Node: The Text in a Buffer, Next: Buffer Lists, Prev: Introduction to Buffers, Up: Buffers and Textual Representation
+
+The Text in a Buffer
+====================
+
+ The text in a buffer consists of a sequence of zero or more
+characters. A "character" is an integer that logically represents a
+letter, number, space, or other unit of text. Most of the characters
+that you will typically encounter belong to the ASCII set of characters,
+but there are also characters for various sorts of accented letters,
+special symbols, Chinese and Japanese ideograms (i.e. Kanji, Katakana,
+etc.), Cyrillic and Greek letters, etc. The actual number of possible
+characters is quite large.
+
+ For now, we can view a character as some non-negative integer that
+has some shape that defines how it typically appears (e.g. as an
+uppercase A). (The exact way in which a character appears depends on the
+font used to display the character.) The internal type of characters in
+the C code is an `Emchar'; this is just an `int', but using a symbolic
+type makes the code clearer.
+
+ Between every character in a buffer is a "buffer position" or
+"character position". We can speak of the character before or after a
+particular buffer position, and when you insert a character at a
+particular position, all characters after that position end up at new
+positions. When we speak of the character "at" a position, we really
+mean the character after the position. (This schizophrenia between a
+buffer position being "between" a character and "on" a character is
+rampant in Emacs.)
+
+ Buffer positions are numbered starting at 1. This means that
+position 1 is before the first character, and position 0 is not valid.
+If there are N characters in a buffer, then buffer position N+1 is
+after the last one, and position N+2 is not valid.
+
+ The internal makeup of the Emchar integer varies depending on whether
+we have compiled with MULE support. If not, the Emchar integer is an
+8-bit integer with possible values from 0 - 255. 0 - 127 are the
+standard ASCII characters, while 128 - 255 are the characters from the
+ISO-8859-1 character set. If we have compiled with MULE support, an
+Emchar is a 19-bit integer, with the various bits having meanings
+according to a complex scheme that will be detailed later. The
+characters numbered 0 - 255 still have the same meanings as for the
+non-MULE case, though.
+
+ Internally, the text in a buffer is represented in a fairly simple
+fashion: as a contiguous array of bytes, with a "gap" of some size in
+the middle. Although the gap is of some substantial size in bytes,
+there is no text contained within it: From the perspective of the text
+in the buffer, it does not exist. The gap logically sits at some buffer
+position, between two characters (or possibly at the beginning or end of
+the buffer). Insertion of text in a buffer at a particular position is
+always accomplished by first moving the gap to that position (i.e.
+through some block moving of text), then writing the text into the
+beginning of the gap, thereby shrinking the gap. If the gap shrinks
+down to nothing, a new gap is created. (What actually happens is that a
+new gap is "created" at the end of the buffer's text, which requires
+nothing more than changing a couple of indices; then the gap is "moved"
+to the position where the insertion needs to take place by moving up in
+memory all the text after that position.) Similarly, deletion occurs
+by moving the gap to the place where the text is to be deleted, and
+then simply expanding the gap to include the deleted text.
+("Expanding" and "shrinking" the gap as just described means just that
+the internal indices that keep track of where the gap is located are
+changed.)
+
+ Note that the total amount of memory allocated for a buffer text
+never decreases while the buffer is live. Therefore, if you load up a
+20-megabyte file and then delete all but one character, there will be a
+20-megabyte gap, which won't get any smaller (except by inserting
+characters back again). Once the buffer is killed, the memory allocated
+for the buffer text will be freed, but it will still be sitting on the
+heap, taking up virtual memory, and will not be released back to the
+operating system. (However, if you have compiled XEmacs with rel-alloc,
+the situation is different. In this case, the space _will_ be released
+back to the operating system. However, this tends to result in a
+noticeable speed penalty.)
+
+ Astute readers may notice that the text in a buffer is represented as
+an array of _bytes_, while (at least in the MULE case) an Emchar is a
+19-bit integer, which clearly cannot fit in a byte. This means (of
+course) that the text in a buffer uses a different representation from
+an Emchar: specifically, the 19-bit Emchar becomes a series of one to
+four bytes. The conversion between these two representations is complex
+and will be described later.
+
+ In the non-MULE case, everything is very simple: An Emchar is an
+8-bit value, which fits neatly into one byte.
+
+ If we are given a buffer position and want to retrieve the character
+at that position, we need to follow these steps:
+
+ 1. Pretend there's no gap, and convert the buffer position into a
+ "byte index" that indexes to the appropriate byte in the buffer's
+ stream of textual bytes. By convention, byte indices begin at 1,
+ just like buffer positions. In the non-MULE case, byte indices
+ and buffer positions are identical, since one character equals one
+ byte.
+
+ 2. Convert the byte index into a "memory index", which takes the gap
+ into account. The memory index is a direct index into the block of
+ memory that stores the text of a buffer. This basically just
+ involves checking to see if the byte index is past the gap, and if
+ so, adding the size of the gap to it. By convention, memory
+ indices begin at 1, just like buffer positions and byte indices,
+ and when referring to the position that is "at" the gap, we always
+ use the memory position at the _beginning_, not at the end, of the
+ gap.
+
+ 3. Fetch the appropriate bytes at the determined memory position.
+
+ 4. Convert these bytes into an Emchar.
+
+ In the non-Mule case, (3) and (4) boil down to a simple one-byte
+memory access.
+
+ Note that we have defined three types of positions in a buffer:
+
+ 1. "buffer positions" or "character positions", typedef `Bufpos'
+
+ 2. "byte indices", typedef `Bytind'
+
+ 3. "memory indices", typedef `Memind'
+
+ All three typedefs are just `int's, but defining them this way makes
+things a lot clearer.
+
+ Most code works with buffer positions. In particular, all Lisp code
+that refers to text in a buffer uses buffer positions. Lisp code does
+not know that byte indices or memory indices exist.
+
+ Finally, we have a typedef for the bytes in a buffer. This is a
+`Bufbyte', which is an unsigned char. Referring to them as Bufbytes
+underscores the fact that we are working with a string of bytes in the
+internal Emacs buffer representation rather than in one of a number of
+possible alternative representations (e.g. EUC-encoded text, etc.).
+
+\1f
File: internals.info, Node: Buffer Lists, Next: Markers and Extents, Prev: The Text in a Buffer, Up: Buffers and Textual Representation
Buffer Lists
* CCL::
\1f
-File: internals.info, Node: Character Sets, Next: Encodings, Up: MULE Character Sets and Encodings
+File: internals.info, Node: Character Sets, Next: Encodings, Prev: MULE Character Sets and Encodings, Up: MULE Character Sets and Encodings
Character Sets
==============
* JIS7::
\1f
-File: internals.info, Node: Japanese EUC (Extended Unix Code), Next: JIS7, Up: Encodings
+File: internals.info, Node: Japanese EUC (Extended Unix Code), Next: JIS7, Prev: Encodings, Up: Encodings
Japanese EUC (Extended Unix Code)
---------------------------------
* Internal Character Encoding::
\1f
-File: internals.info, Node: Internal String Encoding, Next: Internal Character Encoding, Up: Internal Mule Encodings
+File: internals.info, Node: Internal String Encoding, Next: Internal Character Encoding, Prev: Internal Mule Encodings, Up: Internal Mule Encodings
Internal String Encoding
------------------------
* Lstream Methods:: Creating new lstream types.
\1f
-File: internals.info, Node: Creating an Lstream, Next: Lstream Types, Up: Lstreams
+File: internals.info, Node: Creating an Lstream, Next: Lstream Types, Prev: Lstreams, Up: Lstreams
Creating an Lstream
===================
decoding
encoding
-\1f
-File: internals.info, Node: Lstream Functions, Next: Lstream Methods, Prev: Lstream Types, Up: Lstreams
-
-Lstream Functions
-=================
-
- - Function: Lstream * Lstream_new (Lstream_implementation *IMP, CONST
- char *MODE)
- Allocate and return a new Lstream. This function is not really
- meant to be called directly; rather, each stream type should
- provide its own stream creation function, which creates the stream
- and does any other necessary creation stuff (e.g. opening a file).
-
- - Function: void Lstream_set_buffering (Lstream *LSTR,
- Lstream_buffering BUFFERING, int BUFFERING_SIZE)
- Change the buffering of a stream. See `lstream.h'. By default the
- buffering is `STREAM_BLOCK_BUFFERED'.
-
- - Function: int Lstream_flush (Lstream *LSTR)
- Flush out any pending unwritten data in the stream. Clear any
- buffered input data. Returns 0 on success, -1 on error.
-
- - Macro: int Lstream_putc (Lstream *STREAM, int C)
- Write out one byte to the stream. This is a macro and so it is
- very efficient. The C argument is only evaluated once but the
- STREAM argument is evaluated more than once. Returns 0 on
- success, -1 on error.
-
- - Macro: int Lstream_getc (Lstream *STREAM)
- Read one byte from the stream. This is a macro and so it is very
- efficient. The STREAM argument is evaluated more than once.
- Return value is -1 for EOF or error.
-
- - Macro: void Lstream_ungetc (Lstream *STREAM, int C)
- Push one byte back onto the input queue. This will be the next
- byte read from the stream. Any number of bytes can be pushed back
- and will be read in the reverse order they were pushed back--most
- recent first. (This is necessary for consistency--if there are a
- number of bytes that have been unread and I read and unread a
- byte, it needs to be the first to be read again.) This is a macro
- and so it is very efficient. The C argument is only evaluated
- once but the STREAM argument is evaluated more than once.
-
- - Function: int Lstream_fputc (Lstream *STREAM, int C)
- - Function: int Lstream_fgetc (Lstream *STREAM)
- - Function: void Lstream_fungetc (Lstream *STREAM, int C)
- Function equivalents of the above macros.
-
- - Function: ssize_t Lstream_read (Lstream *STREAM, void *DATA, size_t
- SIZE)
- Read SIZE bytes of DATA from the stream. Return the number of
- bytes read. 0 means EOF. -1 means an error occurred and no bytes
- were read.
-
- - Function: ssize_t Lstream_write (Lstream *STREAM, void *DATA, size_t
- SIZE)
- Write SIZE bytes of DATA to the stream. Return the number of
- bytes written. -1 means an error occurred and no bytes were
- written.
-
- - Function: void Lstream_unread (Lstream *STREAM, void *DATA, size_t
- SIZE)
- Push back SIZE bytes of DATA onto the input queue. The next call
- to `Lstream_read()' with the same size will read the same bytes
- back. Note that this will be the case even if there is other
- pending unread data.
-
- - Function: int Lstream_close (Lstream *STREAM)
- Close the stream. All data will be flushed out.
-
- - Function: void Lstream_reopen (Lstream *STREAM)
- Reopen a closed stream. This enables I/O on it again. This is not
- meant to be called except from a wrapper routine that reinitializes
- variables and such--the close routine may well have freed some
- necessary storage structures, for example.
-
- - Function: void Lstream_rewind (Lstream *STREAM)
- Rewind the stream to the beginning.
-
-\1f
-File: internals.info, Node: Lstream Methods, Prev: Lstream Functions, Up: Lstreams
-
-Lstream Methods
-===============
-
- - Lstream Method: ssize_t reader (Lstream *STREAM, unsigned char
- *DATA, size_t SIZE)
- Read some data from the stream's end and store it into DATA, which
- can hold SIZE bytes. Return the number of bytes read. A return
- value of 0 means no bytes can be read at this time. This may be
- because of an EOF, or because there is a granularity greater than
- one byte that the stream imposes on the returned data, and SIZE is
- less than this granularity. (This will happen frequently for
- streams that need to return whole characters, because
- `Lstream_read()' calls the reader function repeatedly until it has
- the number of bytes it wants or until 0 is returned.) The lstream
- functions do not treat a 0 return as EOF or do anything special;
- however, the calling function will interpret any 0 it gets back as
- EOF. This will normally not happen unless the caller calls
- `Lstream_read()' with a very small size.
-
- This function can be `NULL' if the stream is output-only.
-
- - Lstream Method: ssize_t writer (Lstream *STREAM, CONST unsigned char
- *DATA, size_t SIZE)
- Send some data to the stream's end. Data to be sent is in DATA
- and is SIZE bytes. Return the number of bytes sent. This
- function can send and return fewer bytes than is passed in; in that
- case, the function will just be called again until there is no
- data left or 0 is returned. A return value of 0 means that no
- more data can be currently stored, but there is no error; the data
- will be squirreled away until the writer can accept data. (This is
- useful, e.g., if you're dealing with a non-blocking file
- descriptor and are getting `EWOULDBLOCK' errors.) This function
- can be `NULL' if the stream is input-only.
-
- - Lstream Method: int rewinder (Lstream *STREAM)
- Rewind the stream. If this is `NULL', the stream is not seekable.
-
- - Lstream Method: int seekable_p (Lstream *STREAM)
- Indicate whether this stream is seekable--i.e. it can be rewound.
- This method is ignored if the stream does not have a rewind
- method. If this method is not present, the result is determined
- by whether a rewind method is present.
-
- - Lstream Method: int flusher (Lstream *STREAM)
- Perform any additional operations necessary to flush the data in
- this stream.
-
- - Lstream Method: int pseudo_closer (Lstream *STREAM)
-
- - Lstream Method: int closer (Lstream *STREAM)
- Perform any additional operations necessary to close this stream
- down. May be `NULL'. This function is called when
- `Lstream_close()' is called or when the stream is
- garbage-collected. When this function is called, all pending data
- in the stream will already have been written out.
-
- - Lstream Method: Lisp_Object marker (Lisp_Object LSTREAM, void
- (*MARKFUN) (Lisp_Object))
- Mark this object for garbage collection. Same semantics as a
- standard `Lisp_Object' marker. This function can be `NULL'.
-
-\1f
-File: internals.info, Node: Consoles; Devices; Frames; Windows, Next: The Redisplay Mechanism, Prev: Lstreams, Up: Top
-
-Consoles; Devices; Frames; Windows
-**********************************
-
-* Menu:
-
-* Introduction to Consoles; Devices; Frames; Windows::
-* Point::
-* Window Hierarchy::
-* The Window Object::
-
-\1f
-File: internals.info, Node: Introduction to Consoles; Devices; Frames; Windows, Next: Point, Up: Consoles; Devices; Frames; Windows
-
-Introduction to Consoles; Devices; Frames; Windows
-==================================================
-
- A window-system window that you see on the screen is called a
-"frame" in Emacs terminology. Each frame is subdivided into one or
-more non-overlapping panes, called (confusingly) "windows". Each
-window displays the text of a buffer in it. (See above on Buffers.) Note
-that buffers and windows are independent entities: Two or more windows
-can be displaying the same buffer (potentially in different locations),
-and a buffer can be displayed in no windows.
-
- A single display screen that contains one or more frames is called a
-"display". Under most circumstances, there is only one display.
-However, more than one display can exist, for example if you have a
-"multi-headed" console, i.e. one with a single keyboard but multiple
-displays. (Typically in such a situation, the various displays act like
-one large display, in that the mouse is only in one of them at a time,
-and moving the mouse off of one moves it into another.) In some cases,
-the different displays will have different characteristics, e.g. one
-color and one mono.
-
- XEmacs can display frames on multiple displays. It can even deal
-simultaneously with frames on multiple keyboards (called "consoles" in
-XEmacs terminology). Here is one case where this might be useful: You
-are using XEmacs on your workstation at work, and leave it running.
-Then you go home and dial in on a TTY line, and you can use the
-already-running XEmacs process to display another frame on your local
-TTY.
-
- Thus, there is a hierarchy console -> display -> frame -> window.
-There is a separate Lisp object type for each of these four concepts.
-Furthermore, there is logically a "selected console", "selected
-display", "selected frame", and "selected window". Each of these
-objects is distinguished in various ways, such as being the default
-object for various functions that act on objects of that type. Note
-that every containing object rememembers the "selected" object among
-the objects that it contains: e.g. not only is there a selected window,
-but every frame remembers the last window in it that was selected, and
-changing the selected frame causes the remembered window within it to
-become the selected window. Similar relationships apply for consoles
-to devices and devices to frames.
-
-\1f
-File: internals.info, Node: Point, Next: Window Hierarchy, Prev: Introduction to Consoles; Devices; Frames; Windows, Up: Consoles; Devices; Frames; Windows
-
-Point
-=====
-
- Recall that every buffer has a current insertion position, called
-"point". Now, two or more windows may be displaying the same buffer,
-and the text cursor in the two windows (i.e. `point') can be in two
-different places. You may ask, how can that be, since each buffer has
-only one value of `point'? The answer is that each window also has a
-value of `point' that is squirreled away in it. There is only one
-selected window, and the value of "point" in that buffer corresponds to
-that window. When the selected window is changed from one window to
-another displaying the same buffer, the old value of `point' is stored
-into the old window's "point" and the value of `point' from the new
-window is retrieved and made the value of `point' in the buffer. This
-means that `window-point' for the selected window is potentially
-inaccurate, and if you want to retrieve the correct value of `point'
-for a window, you must special-case on the selected window and retrieve
-the buffer's point instead. This is related to why
-`save-window-excursion' does not save the selected window's value of
-`point'.
-
-\1f
-File: internals.info, Node: Window Hierarchy, Next: The Window Object, Prev: Point, Up: Consoles; Devices; Frames; Windows
-
-Window Hierarchy
-================
-
- If a frame contains multiple windows (panes), they are always created
-by splitting an existing window along the horizontal or vertical axis.
-Terminology is a bit confusing here: to "split a window horizontally"
-means to create two side-by-side windows, i.e. to make a _vertical_ cut
-in a window. Likewise, to "split a window vertically" means to create
-two windows, one above the other, by making a _horizontal_ cut.
-
- If you split a window and then split again along the same axis, you
-will end up with a number of panes all arranged along the same axis.
-The precise way in which the splits were made should not be important,
-and this is reflected internally. Internally, all windows are arranged
-in a tree, consisting of two types of windows, "combination" windows
-(which have children, and are covered completely by those children) and
-"leaf" windows, which have no children and are visible. Every
-combination window has two or more children, all arranged along the same
-axis. There are (logically) two subtypes of windows, depending on
-whether their children are horizontally or vertically arrayed. There is
-always one root window, which is either a leaf window (if the frame
-contains only one window) or a combination window (if the frame contains
-more than one window). In the latter case, the root window will have
-two or more children, either horizontally or vertically arrayed, and
-each of those children will be either a leaf window or another
-combination window.
-
- Here are some rules:
-
- 1. Horizontal combination windows can never have children that are
- horizontal combination windows; same for vertical.
-
- 2. Only leaf windows can be split (obviously) and this splitting does
- one of two things: (a) turns the leaf window into a combination
- window and creates two new leaf children, or (b) turns the leaf
- window into one of the two new leaves and creates the other leaf.
- Rule (1) dictates which of these two outcomes happens.
-
- 3. Every combination window must have at least two children.
-
- 4. Leaf windows can never become combination windows. They can be
- deleted, however. If this results in a violation of (3), the
- parent combination window also gets deleted.
-
- 5. All functions that accept windows must be prepared to accept
- combination windows, and do something sane (e.g. signal an error
- if so). Combination windows _do_ escape to the Lisp level.
-
- 6. All windows have three fields governing their contents: these are
- "hchild" (a list of horizontally-arrayed children), "vchild" (a
- list of vertically-arrayed children), and "buffer" (the buffer
- contained in a leaf window). Exactly one of these will be
- non-nil. Remember that "horizontally-arrayed" means
- "side-by-side" and "vertically-arrayed" means "one above the
- other".
-
- 7. Leaf windows also have markers in their `start' (the first buffer
- position displayed in the window) and `pointm' (the window's
- stashed value of `point'--see above) fields, while combination
- windows have nil in these fields.
-
- 8. The list of children for a window is threaded through the `next'
- and `prev' fields of each child window.
-
- 9. *Deleted windows can be undeleted*. This happens as a result of
- restoring a window configuration, and is unlike frames, displays,
- and consoles, which, once deleted, can never be restored.
- Deleting a window does nothing except set a special `dead' bit to
- 1 and clear out the `next', `prev', `hchild', and `vchild' fields,
- for GC purposes.
-
- 10. Most frames actually have two top-level windows--one for the
- minibuffer and one (the "root") for everything else. The modeline
- (if present) separates these two. The `next' field of the root
- points to the minibuffer, and the `prev' field of the minibuffer
- points to the root. The other `next' and `prev' fields are `nil',
- and the frame points to both of these windows. Minibuffer-less
- frames have no minibuffer window, and the `next' and `prev' of the
- root window are `nil'. Minibuffer-only frames have no root
- window, and the `next' of the minibuffer window is `nil' but the
- `prev' points to itself. (#### This is an artifact that should be
- fixed.)
-
-\1f
-File: internals.info, Node: The Window Object, Prev: Window Hierarchy, Up: Consoles; Devices; Frames; Windows
-
-The Window Object
-=================
-
- Windows have the following accessible fields:
-
-`frame'
- The frame that this window is on.
-
-`mini_p'
- Non-`nil' if this window is a minibuffer window.
-
-`buffer'
- The buffer that the window is displaying. This may change often
- during the life of the window.
-
-`dedicated'
- Non-`nil' if this window is dedicated to its buffer.
-
-`pointm'
- This is the value of point in the current buffer when this window
- is selected; when it is not selected, it retains its previous
- value.
-
-`start'
- The position in the buffer that is the first character to be
- displayed in the window.
-
-`force_start'
- If this flag is non-`nil', it says that the window has been
- scrolled explicitly by the Lisp program. This affects what the
- next redisplay does if point is off the screen: instead of
- scrolling the window to show the text around point, it moves point
- to a location that is on the screen.
-
-`last_modified'
- The `modified' field of the window's buffer, as of the last time a
- redisplay completed in this window.
-
-`last_point'
- The buffer's value of point, as of the last time a redisplay
- completed in this window.
-
-`left'
- This is the left-hand edge of the window, measured in columns.
- (The leftmost column on the screen is column 0.)
-
-`top'
- This is the top edge of the window, measured in lines. (The top
- line on the screen is line 0.)
-
-`height'
- The height of the window, measured in lines.
-
-`width'
- The width of the window, measured in columns.
-
-`next'
- This is the window that is the next in the chain of siblings. It
- is `nil' in a window that is the rightmost or bottommost of a
- group of siblings.
-
-`prev'
- This is the window that is the previous in the chain of siblings.
- It is `nil' in a window that is the leftmost or topmost of a group
- of siblings.
-
-`parent'
- Internally, XEmacs arranges windows in a tree; each group of
- siblings has a parent window whose area includes all the siblings.
- This field points to a window's parent.
-
- Parent windows do not display buffers, and play little role in
- display except to shape their child windows. Emacs Lisp programs
- usually have no access to the parent windows; they operate on the
- windows at the leaves of the tree, which actually display buffers.
-
-`hscroll'
- This is the number of columns that the display in the window is
- scrolled horizontally to the left. Normally, this is 0.
-
-`use_time'
- This is the last time that the window was selected. The function
- `get-lru-window' uses this field.
-
-`display_table'
- The window's display table, or `nil' if none is specified for it.
-
-`update_mode_line'
- Non-`nil' means this window's mode line needs to be updated.
-
-`base_line_number'
- The line number of a certain position in the buffer, or `nil'.
- This is used for displaying the line number of point in the mode
- line.
-
-`base_line_pos'
- The position in the buffer for which the line number is known, or
- `nil' meaning none is known.
-
-`region_showing'
- If the region (or part of it) is highlighted in this window, this
- field holds the mark position that made one end of that region.
- Otherwise, this field is `nil'.
-
Foundation instead of in the original English.
\1f
+File: internals.info, Node: Lstream Functions, Next: Lstream Methods, Prev: Lstream Types, Up: Lstreams
+
+Lstream Functions
+=================
+
+ - Function: Lstream * Lstream_new (Lstream_implementation *IMP, const
+ char *MODE)
+ Allocate and return a new Lstream. This function is not really
+ meant to be called directly; rather, each stream type should
+ provide its own stream creation function, which creates the stream
+ and does any other necessary creation stuff (e.g. opening a file).
+
+ - Function: void Lstream_set_buffering (Lstream *LSTR,
+ Lstream_buffering BUFFERING, int BUFFERING_SIZE)
+ Change the buffering of a stream. See `lstream.h'. By default the
+ buffering is `STREAM_BLOCK_BUFFERED'.
+
+ - Function: int Lstream_flush (Lstream *LSTR)
+ Flush out any pending unwritten data in the stream. Clear any
+ buffered input data. Returns 0 on success, -1 on error.
+
+ - Macro: int Lstream_putc (Lstream *STREAM, int C)
+ Write out one byte to the stream. This is a macro and so it is
+ very efficient. The C argument is only evaluated once but the
+ STREAM argument is evaluated more than once. Returns 0 on
+ success, -1 on error.
+
+ - Macro: int Lstream_getc (Lstream *STREAM)
+ Read one byte from the stream. This is a macro and so it is very
+ efficient. The STREAM argument is evaluated more than once.
+ Return value is -1 for EOF or error.
+
+ - Macro: void Lstream_ungetc (Lstream *STREAM, int C)
+ Push one byte back onto the input queue. This will be the next
+ byte read from the stream. Any number of bytes can be pushed back
+ and will be read in the reverse order they were pushed back--most
+ recent first. (This is necessary for consistency--if there are a
+ number of bytes that have been unread and I read and unread a
+ byte, it needs to be the first to be read again.) This is a macro
+ and so it is very efficient. The C argument is only evaluated
+ once but the STREAM argument is evaluated more than once.
+
+ - Function: int Lstream_fputc (Lstream *STREAM, int C)
+ - Function: int Lstream_fgetc (Lstream *STREAM)
+ - Function: void Lstream_fungetc (Lstream *STREAM, int C)
+ Function equivalents of the above macros.
+
+ - Function: ssize_t Lstream_read (Lstream *STREAM, void *DATA, size_t
+ SIZE)
+ Read SIZE bytes of DATA from the stream. Return the number of
+ bytes read. 0 means EOF. -1 means an error occurred and no bytes
+ were read.
+
+ - Function: ssize_t Lstream_write (Lstream *STREAM, void *DATA, size_t
+ SIZE)
+ Write SIZE bytes of DATA to the stream. Return the number of
+ bytes written. -1 means an error occurred and no bytes were
+ written.
+
+ - Function: void Lstream_unread (Lstream *STREAM, void *DATA, size_t
+ SIZE)
+ Push back SIZE bytes of DATA onto the input queue. The next call
+ to `Lstream_read()' with the same size will read the same bytes
+ back. Note that this will be the case even if there is other
+ pending unread data.
+
+ - Function: int Lstream_close (Lstream *STREAM)
+ Close the stream. All data will be flushed out.
+
+ - Function: void Lstream_reopen (Lstream *STREAM)
+ Reopen a closed stream. This enables I/O on it again. This is not
+ meant to be called except from a wrapper routine that reinitializes
+ variables and such--the close routine may well have freed some
+ necessary storage structures, for example.
+
+ - Function: void Lstream_rewind (Lstream *STREAM)
+ Rewind the stream to the beginning.
+
+\1f
+File: internals.info, Node: Lstream Methods, Prev: Lstream Functions, Up: Lstreams
+
+Lstream Methods
+===============
+
+ - Lstream Method: ssize_t reader (Lstream *STREAM, unsigned char
+ *DATA, size_t SIZE)
+ Read some data from the stream's end and store it into DATA, which
+ can hold SIZE bytes. Return the number of bytes read. A return
+ value of 0 means no bytes can be read at this time. This may be
+ because of an EOF, or because there is a granularity greater than
+ one byte that the stream imposes on the returned data, and SIZE is
+ less than this granularity. (This will happen frequently for
+ streams that need to return whole characters, because
+ `Lstream_read()' calls the reader function repeatedly until it has
+ the number of bytes it wants or until 0 is returned.) The lstream
+ functions do not treat a 0 return as EOF or do anything special;
+ however, the calling function will interpret any 0 it gets back as
+ EOF. This will normally not happen unless the caller calls
+ `Lstream_read()' with a very small size.
+
+ This function can be `NULL' if the stream is output-only.
+
+ - Lstream Method: ssize_t writer (Lstream *STREAM, const unsigned char
+ *DATA, size_t SIZE)
+ Send some data to the stream's end. Data to be sent is in DATA
+ and is SIZE bytes. Return the number of bytes sent. This
+ function can send and return fewer bytes than is passed in; in that
+ case, the function will just be called again until there is no
+ data left or 0 is returned. A return value of 0 means that no
+ more data can be currently stored, but there is no error; the data
+ will be squirreled away until the writer can accept data. (This is
+ useful, e.g., if you're dealing with a non-blocking file
+ descriptor and are getting `EWOULDBLOCK' errors.) This function
+ can be `NULL' if the stream is input-only.
+
+ - Lstream Method: int rewinder (Lstream *STREAM)
+ Rewind the stream. If this is `NULL', the stream is not seekable.
+
+ - Lstream Method: int seekable_p (Lstream *STREAM)
+ Indicate whether this stream is seekable--i.e. it can be rewound.
+ This method is ignored if the stream does not have a rewind
+ method. If this method is not present, the result is determined
+ by whether a rewind method is present.
+
+ - Lstream Method: int flusher (Lstream *STREAM)
+ Perform any additional operations necessary to flush the data in
+ this stream.
+
+ - Lstream Method: int pseudo_closer (Lstream *STREAM)
+
+ - Lstream Method: int closer (Lstream *STREAM)
+ Perform any additional operations necessary to close this stream
+ down. May be `NULL'. This function is called when
+ `Lstream_close()' is called or when the stream is
+ garbage-collected. When this function is called, all pending data
+ in the stream will already have been written out.
+
+ - Lstream Method: Lisp_Object marker (Lisp_Object LSTREAM, void
+ (*MARKFUN) (Lisp_Object))
+ Mark this object for garbage collection. Same semantics as a
+ standard `Lisp_Object' marker. This function can be `NULL'.
+
+\1f
+File: internals.info, Node: Consoles; Devices; Frames; Windows, Next: The Redisplay Mechanism, Prev: Lstreams, Up: Top
+
+Consoles; Devices; Frames; Windows
+**********************************
+
+* Menu:
+
+* Introduction to Consoles; Devices; Frames; Windows::
+* Point::
+* Window Hierarchy::
+* The Window Object::
+
+\1f
+File: internals.info, Node: Introduction to Consoles; Devices; Frames; Windows, Next: Point, Prev: Consoles; Devices; Frames; Windows, Up: Consoles; Devices; Frames; Windows
+
+Introduction to Consoles; Devices; Frames; Windows
+==================================================
+
+ A window-system window that you see on the screen is called a
+"frame" in Emacs terminology. Each frame is subdivided into one or
+more non-overlapping panes, called (confusingly) "windows". Each
+window displays the text of a buffer in it. (See above on Buffers.) Note
+that buffers and windows are independent entities: Two or more windows
+can be displaying the same buffer (potentially in different locations),
+and a buffer can be displayed in no windows.
+
+ A single display screen that contains one or more frames is called a
+"display". Under most circumstances, there is only one display.
+However, more than one display can exist, for example if you have a
+"multi-headed" console, i.e. one with a single keyboard but multiple
+displays. (Typically in such a situation, the various displays act like
+one large display, in that the mouse is only in one of them at a time,
+and moving the mouse off of one moves it into another.) In some cases,
+the different displays will have different characteristics, e.g. one
+color and one mono.
+
+ XEmacs can display frames on multiple displays. It can even deal
+simultaneously with frames on multiple keyboards (called "consoles" in
+XEmacs terminology). Here is one case where this might be useful: You
+are using XEmacs on your workstation at work, and leave it running.
+Then you go home and dial in on a TTY line, and you can use the
+already-running XEmacs process to display another frame on your local
+TTY.
+
+ Thus, there is a hierarchy console -> display -> frame -> window.
+There is a separate Lisp object type for each of these four concepts.
+Furthermore, there is logically a "selected console", "selected
+display", "selected frame", and "selected window". Each of these
+objects is distinguished in various ways, such as being the default
+object for various functions that act on objects of that type. Note
+that every containing object rememembers the "selected" object among
+the objects that it contains: e.g. not only is there a selected window,
+but every frame remembers the last window in it that was selected, and
+changing the selected frame causes the remembered window within it to
+become the selected window. Similar relationships apply for consoles
+to devices and devices to frames.
+
+\1f
+File: internals.info, Node: Point, Next: Window Hierarchy, Prev: Introduction to Consoles; Devices; Frames; Windows, Up: Consoles; Devices; Frames; Windows
+
+Point
+=====
+
+ Recall that every buffer has a current insertion position, called
+"point". Now, two or more windows may be displaying the same buffer,
+and the text cursor in the two windows (i.e. `point') can be in two
+different places. You may ask, how can that be, since each buffer has
+only one value of `point'? The answer is that each window also has a
+value of `point' that is squirreled away in it. There is only one
+selected window, and the value of "point" in that buffer corresponds to
+that window. When the selected window is changed from one window to
+another displaying the same buffer, the old value of `point' is stored
+into the old window's "point" and the value of `point' from the new
+window is retrieved and made the value of `point' in the buffer. This
+means that `window-point' for the selected window is potentially
+inaccurate, and if you want to retrieve the correct value of `point'
+for a window, you must special-case on the selected window and retrieve
+the buffer's point instead. This is related to why
+`save-window-excursion' does not save the selected window's value of
+`point'.
+
+\1f
+File: internals.info, Node: Window Hierarchy, Next: The Window Object, Prev: Point, Up: Consoles; Devices; Frames; Windows
+
+Window Hierarchy
+================
+
+ If a frame contains multiple windows (panes), they are always created
+by splitting an existing window along the horizontal or vertical axis.
+Terminology is a bit confusing here: to "split a window horizontally"
+means to create two side-by-side windows, i.e. to make a _vertical_ cut
+in a window. Likewise, to "split a window vertically" means to create
+two windows, one above the other, by making a _horizontal_ cut.
+
+ If you split a window and then split again along the same axis, you
+will end up with a number of panes all arranged along the same axis.
+The precise way in which the splits were made should not be important,
+and this is reflected internally. Internally, all windows are arranged
+in a tree, consisting of two types of windows, "combination" windows
+(which have children, and are covered completely by those children) and
+"leaf" windows, which have no children and are visible. Every
+combination window has two or more children, all arranged along the same
+axis. There are (logically) two subtypes of windows, depending on
+whether their children are horizontally or vertically arrayed. There is
+always one root window, which is either a leaf window (if the frame
+contains only one window) or a combination window (if the frame contains
+more than one window). In the latter case, the root window will have
+two or more children, either horizontally or vertically arrayed, and
+each of those children will be either a leaf window or another
+combination window.
+
+ Here are some rules:
+
+ 1. Horizontal combination windows can never have children that are
+ horizontal combination windows; same for vertical.
+
+ 2. Only leaf windows can be split (obviously) and this splitting does
+ one of two things: (a) turns the leaf window into a combination
+ window and creates two new leaf children, or (b) turns the leaf
+ window into one of the two new leaves and creates the other leaf.
+ Rule (1) dictates which of these two outcomes happens.
+
+ 3. Every combination window must have at least two children.
+
+ 4. Leaf windows can never become combination windows. They can be
+ deleted, however. If this results in a violation of (3), the
+ parent combination window also gets deleted.
+
+ 5. All functions that accept windows must be prepared to accept
+ combination windows, and do something sane (e.g. signal an error
+ if so). Combination windows _do_ escape to the Lisp level.
+
+ 6. All windows have three fields governing their contents: these are
+ "hchild" (a list of horizontally-arrayed children), "vchild" (a
+ list of vertically-arrayed children), and "buffer" (the buffer
+ contained in a leaf window). Exactly one of these will be
+ non-nil. Remember that "horizontally-arrayed" means
+ "side-by-side" and "vertically-arrayed" means "one above the
+ other".
+
+ 7. Leaf windows also have markers in their `start' (the first buffer
+ position displayed in the window) and `pointm' (the window's
+ stashed value of `point'--see above) fields, while combination
+ windows have nil in these fields.
+
+ 8. The list of children for a window is threaded through the `next'
+ and `prev' fields of each child window.
+
+ 9. *Deleted windows can be undeleted*. This happens as a result of
+ restoring a window configuration, and is unlike frames, displays,
+ and consoles, which, once deleted, can never be restored.
+ Deleting a window does nothing except set a special `dead' bit to
+ 1 and clear out the `next', `prev', `hchild', and `vchild' fields,
+ for GC purposes.
+
+ 10. Most frames actually have two top-level windows--one for the
+ minibuffer and one (the "root") for everything else. The modeline
+ (if present) separates these two. The `next' field of the root
+ points to the minibuffer, and the `prev' field of the minibuffer
+ points to the root. The other `next' and `prev' fields are `nil',
+ and the frame points to both of these windows. Minibuffer-less
+ frames have no minibuffer window, and the `next' and `prev' of the
+ root window are `nil'. Minibuffer-only frames have no root
+ window, and the `next' of the minibuffer window is `nil' but the
+ `prev' points to itself. (#### This is an artifact that should be
+ fixed.)
+
+\1f
+File: internals.info, Node: The Window Object, Prev: Window Hierarchy, Up: Consoles; Devices; Frames; Windows
+
+The Window Object
+=================
+
+ Windows have the following accessible fields:
+
+`frame'
+ The frame that this window is on.
+
+`mini_p'
+ Non-`nil' if this window is a minibuffer window.
+
+`buffer'
+ The buffer that the window is displaying. This may change often
+ during the life of the window.
+
+`dedicated'
+ Non-`nil' if this window is dedicated to its buffer.
+
+`pointm'
+ This is the value of point in the current buffer when this window
+ is selected; when it is not selected, it retains its previous
+ value.
+
+`start'
+ The position in the buffer that is the first character to be
+ displayed in the window.
+
+`force_start'
+ If this flag is non-`nil', it says that the window has been
+ scrolled explicitly by the Lisp program. This affects what the
+ next redisplay does if point is off the screen: instead of
+ scrolling the window to show the text around point, it moves point
+ to a location that is on the screen.
+
+`last_modified'
+ The `modified' field of the window's buffer, as of the last time a
+ redisplay completed in this window.
+
+`last_point'
+ The buffer's value of point, as of the last time a redisplay
+ completed in this window.
+
+`left'
+ This is the left-hand edge of the window, measured in columns.
+ (The leftmost column on the screen is column 0.)
+
+`top'
+ This is the top edge of the window, measured in lines. (The top
+ line on the screen is line 0.)
+
+`height'
+ The height of the window, measured in lines.
+
+`width'
+ The width of the window, measured in columns.
+
+`next'
+ This is the window that is the next in the chain of siblings. It
+ is `nil' in a window that is the rightmost or bottommost of a
+ group of siblings.
+
+`prev'
+ This is the window that is the previous in the chain of siblings.
+ It is `nil' in a window that is the leftmost or topmost of a group
+ of siblings.
+
+`parent'
+ Internally, XEmacs arranges windows in a tree; each group of
+ siblings has a parent window whose area includes all the siblings.
+ This field points to a window's parent.
+
+ Parent windows do not display buffers, and play little role in
+ display except to shape their child windows. Emacs Lisp programs
+ usually have no access to the parent windows; they operate on the
+ windows at the leaves of the tree, which actually display buffers.
+
+`hscroll'
+ This is the number of columns that the display in the window is
+ scrolled horizontally to the left. Normally, this is 0.
+
+`use_time'
+ This is the last time that the window was selected. The function
+ `get-lru-window' uses this field.
+
+`display_table'
+ The window's display table, or `nil' if none is specified for it.
+
+`update_mode_line'
+ Non-`nil' means this window's mode line needs to be updated.
+
+`base_line_number'
+ The line number of a certain position in the buffer, or `nil'.
+ This is used for displaying the line number of point in the mode
+ line.
+
+`base_line_pos'
+ The position in the buffer for which the line number is known, or
+ `nil' meaning none is known.
+
+`region_showing'
+ If the region (or part of it) is highlighted in this window, this
+ field holds the mark position that made one end of that region.
+ Otherwise, this field is `nil'.
+
+\1f
File: internals.info, Node: The Redisplay Mechanism, Next: Extents, Prev: Consoles; Devices; Frames; Windows, Up: Top
The Redisplay Mechanism
* Redisplay Piece by Piece::
\1f
-File: internals.info, Node: Critical Redisplay Sections, Next: Line Start Cache, Up: The Redisplay Mechanism
+File: internals.info, Node: Critical Redisplay Sections, Next: Line Start Cache, Prev: The Redisplay Mechanism, Up: The Redisplay Mechanism
Critical Redisplay Sections
===========================
* Extent Ordering:: How extents are ordered internally.
* Format of the Extent Info:: The extent information in a buffer or string.
* Zero-Length Extents:: A weird special case.
-* Mathematics of Extent Ordering:: A rigorous foundation.
+* Mathematics of Extent Ordering:: A rigorous foundation.
* Extent Fragments:: Cached information useful for redisplay.
\1f
-File: internals.info, Node: Introduction to Extents, Next: Extent Ordering, Up: Extents
+File: internals.info, Node: Introduction to Extents, Next: Extent Ordering, Prev: Extents, Up: Extents
Introduction to Extents
=======================
Not yet documented.
-\1f
-File: internals.info, Node: Index, Prev: Interface to X Windows, Up: Top
-
-Index
-*****
-
-* Menu:
-
-* Amdahl Corporation: XEmacs.
-* Andreessen, Marc: XEmacs.
-* asynchronous subprocesses: Modules for Interfacing with the Operating System.
-* Baur, Steve: XEmacs.
-* Benson, Eric: Lucid Emacs.
-* bridge, playing: XEmacs From the Outside.
-* Buchholz, Martin: XEmacs.
-* Bufbyte: Character-Related Data Types.
-* Bufpos: Character-Related Data Types.
-* Bytecount: Character-Related Data Types.
-* bytecount_to_charcount: Working With Character and Byte Positions.
-* Bytind: Character-Related Data Types.
-* C vs. Lisp: The Lisp Language.
-* caller-protects (GCPRO rule): Writing Lisp Primitives.
-* case table: Modules for Other Aspects of the Lisp Interpreter and Object System.
-* Charcount: Character-Related Data Types.
-* charcount_to_bytecount: Working With Character and Byte Positions.
-* charptr_emchar: Working With Character and Byte Positions.
-* charptr_n_addr: Working With Character and Byte Positions.
-* closer: Lstream Methods.
-* closure: The XEmacs Object System (Abstractly Speaking).
-* Coding for Mule: Coding for Mule.
-* Common Lisp: The Lisp Language.
-* compact_string_chars: compact_string_chars.
-* conservative garbage collection: GCPROing.
-* copy-on-write: General Coding Rules.
-* critical redisplay sections: Critical Redisplay Sections.
-* DEC_CHARPTR: Working With Character and Byte Positions.
-* Devin, Matthieu: Lucid Emacs.
-* display order of extents: Mathematics of Extent Ordering.
-* dynamic array: Low-Level Modules.
-* dynamic scoping: The Lisp Language.
-* dynamic types: The Lisp Language.
-* Emchar: Character-Related Data Types.
-* Energize: Lucid Emacs.
-* Epoch <1>: XEmacs.
-* Epoch: Lucid Emacs.
-* Extbyte: Character-Related Data Types.
-* Extcount: Character-Related Data Types.
-* extent fragment: Extent Fragments.
-* extent mathematics: Mathematics of Extent Ordering.
-* extent ordering: Mathematics of Extent Ordering.
-* extents, display order: Mathematics of Extent Ordering.
-* external widget: Modules for Interfacing with X Windows.
-* flusher: Lstream Methods.
-* Free Software Foundation: A History of Emacs.
-* frob block: Introduction to Allocation.
-* FSF: A History of Emacs.
-* FSF Emacs <1>: GNU Emacs 20.
-* FSF Emacs: GNU Emacs 19.
-* garbage collection: Garbage Collection.
-* garbage collection protection: Writing Lisp Primitives.
-* garbage collection step by step: Garbage Collection - Step by Step.
-* garbage collection, conservative: GCPROing.
-* garbage collection, invocation: Invocation.
-* garbage_collect_1: garbage_collect_1.
-* gc_sweep: gc_sweep.
-* GNU Emacs 19: GNU Emacs 19.
-* GNU Emacs 20: GNU Emacs 20.
-* Gosling, James <1>: The Lisp Language.
-* Gosling, James: Through Version 18.
-* Great Usenet Renaming: Through Version 18.
-* Hackers (Steven Levy): A History of Emacs.
-* hierarchy of windows: Window Hierarchy.
-* history of Emacs: A History of Emacs.
-* Illinois, University of: XEmacs.
-* INC_CHARPTR: Working With Character and Byte Positions.
-* interactive: Modules for Standard Editing Operations.
-* interning: The XEmacs Object System (Abstractly Speaking).
-* ITS (Incompatible Timesharing System): A History of Emacs.
-* Java: The Lisp Language.
-* Java vs. Lisp: The Lisp Language.
-* Jones, Kyle: XEmacs.
-* Kaplan, Simon: XEmacs.
-* Levy, Steven: A History of Emacs.
-* line start cache: Line Start Cache.
-* Lisp vs. C: The Lisp Language.
-* Lisp vs. Java: The Lisp Language.
-* lstream: Modules for Interfacing with the File System.
-* Lstream_close: Lstream Functions.
-* Lstream_fgetc: Lstream Functions.
-* Lstream_flush: Lstream Functions.
-* Lstream_fputc: Lstream Functions.
-* Lstream_fungetc: Lstream Functions.
-* Lstream_getc: Lstream Functions.
-* Lstream_new: Lstream Functions.
-* Lstream_putc: Lstream Functions.
-* Lstream_read: Lstream Functions.
-* Lstream_reopen: Lstream Functions.
-* Lstream_rewind: Lstream Functions.
-* Lstream_set_buffering: Lstream Functions.
-* Lstream_ungetc: Lstream Functions.
-* Lstream_unread: Lstream Functions.
-* Lstream_write: Lstream Functions.
-* Lucid Emacs: Lucid Emacs.
-* Lucid Inc.: Lucid Emacs.
-* mark and sweep: Garbage Collection.
-* mark method <1>: lrecords.
-* mark method: Modules for Other Aspects of the Lisp Interpreter and Object System.
-* mark_object: mark_object.
-* marker: Lstream Methods.
-* mathematics of extents: Mathematics of Extent Ordering.
-* MAX_EMCHAR_LEN: Working With Character and Byte Positions.
-* merging attempts: XEmacs.
-* MIT: A History of Emacs.
-* Mlynarik, Richard: GNU Emacs 19.
-* MULE merged XEmacs appears: XEmacs.
-* NAS: Modules for Interfacing with the Operating System.
-* native sound: Modules for Interfacing with the Operating System.
-* network connections: Modules for Interfacing with the Operating System.
-* network sound: Modules for Interfacing with the Operating System.
-* Niksic, Hrvoje: XEmacs.
-* pane: Modules for the Basic Displayable Lisp Objects.
-* permanent objects: The XEmacs Object System (Abstractly Speaking).
-* pi, calculating: XEmacs From the Outside.
-* pseudo_closer: Lstream Methods.
-* pure space: Basic Lisp Modules.
-* read syntax: The XEmacs Object System (Abstractly Speaking).
-* read-eval-print: XEmacs From the Outside.
-* reader: Lstream Methods.
-* record type: How Lisp Objects Are Represented in C.
-* Redisplay Piece by Piece: Redisplay Piece by Piece.
-* relocating allocator: Low-Level Modules.
-* rename to XEmacs: XEmacs.
-* rewinder: Lstream Methods.
-* RMS: A History of Emacs.
-* scanner: Modules for Other Aspects of the Lisp Interpreter and Object System.
-* scoping, dynamic: The Lisp Language.
-* seekable_p: Lstream Methods.
-* selections: Modules for Interfacing with X Windows.
-* set_charptr_emchar: Working With Character and Byte Positions.
-* Sexton, Harlan: Lucid Emacs.
-* sound, native: Modules for Interfacing with the Operating System.
-* sound, network: Modules for Interfacing with the Operating System.
-* SPARCWorks: XEmacs.
-* Stallman, Richard: A History of Emacs.
-* subprocesses, asynchronous: Modules for Interfacing with the Operating System.
-* subprocesses, synchronous: Modules for Interfacing with the Operating System.
-* Sun Microsystems: XEmacs.
-* sweep_bit_vectors_1: sweep_bit_vectors_1.
-* sweep_lcrecords_1: sweep_lcrecords_1.
-* sweep_strings: sweep_strings.
-* synchronous subprocesses: Modules for Interfacing with the Operating System.
-* taxes, doing: XEmacs From the Outside.
-* TECO: A History of Emacs.
-* temporary objects: The XEmacs Object System (Abstractly Speaking).
-* Thompson, Chuck: XEmacs.
-* types, dynamic: The Lisp Language.
-* University of Illinois: XEmacs.
-* Win-Emacs: XEmacs.
-* window (in Emacs): Modules for the Basic Displayable Lisp Objects.
-* window hierarchy: Window Hierarchy.
-* window point internals: The Window Object.
-* Wing, Ben: XEmacs.
-* writer: Lstream Methods.
-* XEmacs: XEmacs.
-* XEmacs goes it alone: XEmacs.
-* Zawinski, Jamie: Lucid Emacs.
-
-
* generate-new-buffer: Creating Buffers.
* generate-new-buffer-name: Buffer Names.
* generic-specifier-p: Specifier Types.
-* get: Symbol Plists.
+* get: Object Plists.
* get-buffer: Buffer Names.
* get-buffer-create: Creating Buffers.
* get-buffer-process: Process Buffers.
* objc-mode-map: Standard Keymaps.
* object: Lisp Data Types.
* object to string: Output Functions.
+* object-plist: Object Plists.
* oblique: Font Instance Characteristics.
* obsolete buffer: Modification Time.
* occur-mode-map: Standard Keymaps.
* purecopy: Pure Storage.
* purify-flag: Pure Storage.
* push-mark: The Mark.
-* put: Symbol Plists.
+* put: Object Plists.
* put-char-table: Working With Char Tables.
* put-database: Working With a Database.
* put-range-table: Working With Range Tables.
* remove-range-table: Working With Range Tables.
* remove-specifier: Other Specification Functions.
* remove-text-properties: Changing Properties.
+* remprop: Object Plists.
* remrassoc: Association Lists.
* remrassq: Association Lists.
* rename-auto-save-file: Auto-Saving.
* setcar: Setcar.
* setcdr: Setcdr.
* setenv: System Environment.
-* setplist: Symbol Plists.
+* setplist: Object Plists.
* setprv: System Environment.
* setq: Setting Variables.
* setq-default: Default Value.
* symbol name hashing: Creating Symbols.
* symbol-function: Function Cells.
* symbol-name: Creating Symbols.
-* symbol-plist: Symbol Plists.
+* symbol-plist: Object Plists.
* symbol-value: Accessing Variables.
* symbolp: Symbols.
* symbol constituent: Syntax Class Table.