From: tomo Date: Tue, 2 May 2000 12:32:34 +0000 (+0000) Subject: XEmacs 21.2.29 "Hestia". X-Git-Tag: r21-2-29^2 X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=686ee3a640d8c762cf443c392674ee8e578272c2;p=chise%2Fxemacs-chise.git- XEmacs 21.2.29 "Hestia". --- diff --git a/info/cl.info-3 b/info/cl.info-3 index 1783ddb..6d81217 100644 --- a/info/cl.info-3 +++ b/info/cl.info-3 @@ -831,7 +831,7 @@ from Emacs Lisp. * Menu: -* Property Lists:: `remprop', `getf', `remf' +* Property Lists:: `getf', `remf' * Creating Symbols:: `gensym', `gentemp'  @@ -841,19 +841,9 @@ Property Lists ============== 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, diff --git a/info/cl.info-6 b/info/cl.info-6 index a3d0e27..b4d07ac 100644 --- a/info/cl.info-6 +++ b/info/cl.info-6 @@ -186,7 +186,6 @@ Function Index * 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. diff --git a/info/internals.info-3 b/info/internals.info-3 index c6ed97c..7a87402 100644 --- a/info/internals.info-3 +++ b/info/internals.info-3 @@ -446,7 +446,7 @@ A Summary of the Various XEmacs Modules * Modules for Internationalization::  -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 ================= diff --git a/info/internals.info-4 b/info/internals.info-4 index af2f27c..98c7705 100644 --- a/info/internals.info-4 +++ b/info/internals.info-4 @@ -597,7 +597,7 @@ method. None of this code is currently working. Asian-language support, and is not currently used.  -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 ************************************ @@ -622,7 +622,7 @@ Allocation of Objects in XEmacs Lisp * Compiled Function::  -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 ========================== @@ -937,7 +937,7 @@ Garbage Collection - Step by Step * sweep_bit_vectors_1::  -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 ---------- diff --git a/info/internals.info-5 b/info/internals.info-5 index 163f1c5..f25698f 100644 --- a/info/internals.info-5 +++ b/info/internals.info-5 @@ -238,7 +238,7 @@ i.e. marked (`C_READONLY_RECORD_HEADER'). The object in question is 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 @@ -949,58 +949,68 @@ Compiled Function Not yet documented.  -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::  -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. diff --git a/info/internals.info-6 b/info/internals.info-6 index 66d9da0..cef86b7 100644 --- a/info/internals.info-6 +++ b/info/internals.info-6 @@ -38,6 +38,368 @@ may be included in a translation approved by the Free Software Foundation instead of in the original English.  +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. + + +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:: + + +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. + + +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). + + +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). + + +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. + + +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. + + +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'. + + +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. + + +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:: + + +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. + + 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 @@ -412,7 +774,7 @@ Evaluation; Stack Frames; Bindings * Catch and Throw::  -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 ========== @@ -679,7 +1041,7 @@ Symbols and Variables * Symbol Values::  -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 ======================= @@ -698,322 +1060,3 @@ property list is used as a more general mechanism of associating additional values with particular names, and once again the namespace is independent of the function and variable namespaces. - -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. - - -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'. - - -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. - - -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.) - - -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.). - diff --git a/info/internals.info-7 b/info/internals.info-7 index 2562605..e8f9206 100644 --- a/info/internals.info-7 +++ b/info/internals.info-7 @@ -38,6 +38,325 @@ may be included in a translation approved by the Free Software Foundation instead of in the original English.  +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. + + +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'. + + +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. + + +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.) + + +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.). + + File: internals.info, Node: Buffer Lists, Next: Markers and Extents, Prev: The Text in a Buffer, Up: Buffers and Textual Representation Buffer Lists @@ -248,7 +567,7 @@ representation is that it's compact and is compatible with ASCII. * CCL::  -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 ============== @@ -355,7 +674,7 @@ common usage of "byte"). * JIS7::  -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) --------------------------------- @@ -459,7 +778,7 @@ followed later by the exact details.) * Internal Character Encoding::  -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 ------------------------ @@ -738,7 +1057,7 @@ blocking data together in order to achieve efficiency. * Lstream Methods:: Creating new lstream types.  -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 =================== @@ -797,421 +1116,3 @@ print decoding encoding - -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. - - -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'. - - -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:: - - -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. - - -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'. - - -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.) - - -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'. - diff --git a/info/internals.info-8 b/info/internals.info-8 index b0c7fbd..dc5125e 100644 --- a/info/internals.info-8 +++ b/info/internals.info-8 @@ -38,6 +38,424 @@ may be included in a translation approved by the Free Software Foundation instead of in the original English.  +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. + + +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'. + + +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:: + + +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. + + +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'. + + +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.) + + +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'. + + File: internals.info, Node: The Redisplay Mechanism, Next: Extents, Prev: Consoles; Devices; Frames; Windows, Up: Top The Redisplay Mechanism @@ -65,7 +483,7 @@ of Redisplay: * Redisplay Piece by Piece::  -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 =========================== @@ -218,11 +636,11 @@ Extents * 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.  -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 ======================= @@ -701,171 +1119,3 @@ Interface to X Windows Not yet documented. - -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. - - diff --git a/info/lispref.info-44 b/info/lispref.info-44 index e2e76dc..4fae459 100644 --- a/info/lispref.info-44 +++ b/info/lispref.info-44 @@ -1514,7 +1514,7 @@ Index * 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. @@ -2247,6 +2247,7 @@ Index * 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. @@ -2472,7 +2473,7 @@ Index * 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. @@ -2587,6 +2588,7 @@ Index * 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. @@ -2795,7 +2797,7 @@ Index * setcar: Setcar. * setcdr: Setcdr. * setenv: System Environment. -* setplist: Symbol Plists. +* setplist: Object Plists. * setprv: System Environment. * setq: Setting Variables. * setq-default: Default Value. @@ -2974,7 +2976,7 @@ Index * 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.