DIRECTORY Atom USING [PropList], Xl USING [Attributes, Connection, dontUse, Event, Geometry, MatchList, MatchRep, nullVisual, nullWindow, Point, Screen, ScreenDepth, SetOfEvent, Size, TQ, unspecifiedEvents, Visual, Window]; XTk: CEDAR DEFINITIONS ~ BEGIN OPEN Xl; Event: TYPE = Xl.Event; TQ: TYPE = Xl.TQ; Widget: TYPE = REF WidgetRep; dontUse: INT = Xl.dontUse; rootLockingOrder: INT = 5; --useful if you create your own rootTQ Mapping: TYPE = {mapped, unmapped, unconfigured, dontUse, unmapIfMapped, mapIfUnmapped, unmapIfUnconfigured, mapIfUnconfigured}; WidgetSpec: TYPE = RECORD [ class: Class ¬ NIL, geometry: Xl.Geometry ¬ [], --as requested mapping: Mapping ¬ dontUse, --as requested instName: ATOM ¬ NIL, --key for database lookup; class might overwrite this clientData: REF ¬ NIL --reserved for clients ]; FastAccessState: TYPE = {ok, warned}; WindowState: TYPE = {realized, warned, screened, existing, dead}; WidgetRep: TYPE = MONITORED RECORD [ s: WidgetSpec ¬ [], --public read - write depth: INTEGER ¬ 0, --public read - write visual: Visual ¬ nullVisual, --public read - write attributes: Attributes ¬ [], --public read - write flags: PRIVATE WidgetFlags ¬ ALL[FALSE], --private to prevent unmonitored access parent: <> Widget ¬ NIL, matchListX: PRIVATE LIST OF MatchRep ¬ NIL, --permanent matchList1: PRIVATE MatchList ¬ NIL, --temporary connection: <> Connection ¬ NIL, window: <> Window ¬ nullWindow, screenDepth: <> ScreenDepth ¬ NIL, fastAccessAllowed: <> FastAccessState ¬ warned, -- not monitored. state: <> WindowState ¬ existing, -- (rootTQ+LX)! actual: <> Xl.Geometry ¬ [], --final geometry actualMapping: <> Mapping ¬ dontUse, --final visibility (rootTQ) rootTQ: <> TQ ¬ NIL, --initialized on BindScreen notifiers: PRIVATE REF ¬ NIL, props: PRIVATE REF ¬ NIL, wClassData: PRIVATE SEQUENCE leng: NAT OF REF ]; CreateWidget: PROC [widgetSpec: WidgetSpec, class: Class ¬ NIL, arguments: Atom.PropList ¬ NIL] RETURNS [Widget]; DestroyWidget: PROC [widget: Widget, startReconfigureParent: BOOL ¬ TRUE]; WidgetFlagKey: TYPE = {wf0, wf1, wf2, wf3, wf4, wf5, wf6, wf7, wf8, wf9, wf10, wf11, wf12, wf13, wf14, wf15, wf16, wf17, wf18, wf19, wf20, wf21, wf22, wf23, wf24, wf25, wf26, wf27, wf28, wf29, wf30, wf31}; WidgetFlags: TYPE = PACKED ARRAY WidgetFlagKey OF BOOL ¬ ALL[FALSE]; SetWidgetFlag: PROC [widget: Widget, key: WidgetFlagKey, value: BOOL ¬ TRUE]; GetWidgetFlag: PROC [widget: Widget, key: WidgetFlagKey] RETURNS [BOOL] = INLINE { RETURN [widget.flags[key]]; }; mustReConsiderChildren: WidgetFlagKey = wf0; --Set by any child which wants parent to reconsider its children. preferredSizeFromDB: WidgetFlagKey = wf1; --if this flag is set and the window not realized the database is queried for the preferred size of a widget. Otherwise, and, when the database doesn't provide a value the normal class method is used. preferredSizeCurrent: WidgetFlagKey = wf2; --if this flag is set and the window already is realized the specified size of the widget is to be used. Otherwise the normal class method is used. ClassFlagKey: TYPE = {cf0, cf1, cf2, cf3, cf4, cf5, cf6, cf7, cf8, cf9, cf10, cf11, cf12, cf13, cf14, cf15, cf16, cf17, cf18, cf19, cf20, cf21, cf22, cf23, cf24, cf25, cf26, cf27, cf28, cf29, cf30, cf31}; ClassFlags: TYPE = PACKED ARRAY ClassFlagKey OF BOOL ¬ ALL[FALSE]; SetClassFlag: PROC [class: ImplementorClass, key: ClassFlagKey, value: BOOL ¬ TRUE]; GetClassFlag: PROC [class: Class, key: ClassFlagKey] RETURNS [BOOL] = INLINE { RETURN [class.flags[key]]; }; GetWidgetProp: PROC [widget: Widget, key: REF] RETURNS [REF]; PutWidgetProp: PROC [widget: Widget, key: REF, value: REF ¬ NIL]; WidgetNotifyProc: TYPE = PROC [widget: Widget, registerData, callData: REF ¬ NIL, event: Event ¬ NIL]; RegisterNotifier: PROC [widget: Widget, key: REF, procLX: WidgetNotifyProc, registerData: REF ¬ NIL]; UnRegisterNotifier: PROC [widget: Widget, key: REF, procLX: WidgetNotifyProc, registerData: REF ¬ NIL]; preWindowCreationLRKey: READONLY ATOM; -- ¬ $preWindowCreation preWindowCreationKey: READONLY ATOM; -- ¬ $preWindowCreation postWindowCreationLRKey: READONLY ATOM; -- ¬ $postWindowCreation postWindowCreationKey: READONLY ATOM; -- ¬ $postWindowCreation postConfigureLRKey: READONLY ATOM; -- ¬ $postConfigure postConfigureKey: READONLY ATOM; -- ¬ $postConfigure postWindowDestructionLRKey: READONLY ATOM; -- ¬ $postWindowDestruction postWindowDestructionKey: READONLY ATOM; -- ¬ $postWindowDestruction preStopFastAccessKey: READONLY ATOM; -- ¬ $preStopFastAccess postStopFastAccessLRKey: READONLY ATOM; -- ¬ $postStopFastAccess postStopFastAccessKey: READONLY ATOM; -- ¬ $postStopFastAccess bindScreenLRKey: PUBLIC ATOM; -- ¬ $bindScreen bindScreenKey: PUBLIC ATOM; -- ¬ $bindScreen forgetScreenLRKey: PUBLIC ATOM; -- ¬ $forgetScreen forgetScreenKey: PUBLIC ATOM; -- ¬ $forgetScreen postWidgetDestructionKey: READONLY ATOM; -- ¬ $postWidgetDestruction AddPermanentMatch: PROC [widget: Widget, matchRep: MatchRep, generate: SetOfEvent ¬ unspecifiedEvents]; AddTemporaryMatch: PROC [widget: Widget, matchRep: MatchRep, generate: SetOfEvent ¬ unspecifiedEvents]; G: PROC [w, h, b: INT ¬ dontUse] RETURNS [Geometry] = INLINE { RETURN [[pos: [dontUse, dontUse], size: [w, h], borderWidth: b]] }; RootWidget: PROC [widget: Widget] RETURNS [Widget]; BorderWidth: PROC [widget: Widget] RETURNS [INT]; ScreenBound: PROC [widget: Widget] RETURNS [BOOL]; SynchronizeFastAccess: PROC [widget: Widget, protectTQ: TQ]; OrphanProc: TYPE = PROC [orphan: Widget]; RegisterOrphanProc: PROC [self: Widget, orphanProcLR: OrphanProc ¬ NIL]; HasClass: PROC [widget: Widget, class: Class] RETURNS [BOOL] = INLINE {IF HasProperClass[widget, class] THEN RETURN [TRUE] ELSE RETURN [HasSubClass[widget, class]]}; HasProperClass: PROC [widget: Widget, class: Class] RETURNS [BOOL] = INLINE {RETURN [widget.s.class=class]}; HasSubClass: PROC [widget: Widget, class: Class] RETURNS [BOOL]; HasClassKey: PROC [widget: Widget, classKey: ATOM] RETURNS [BOOL] = INLINE {IF HasProperClassKey[widget, classKey] THEN RETURN [TRUE] ELSE RETURN [HasSubClassKey[widget, classKey]]}; HasProperClassKey: PROC [widget: Widget, classKey: ATOM] RETURNS [BOOL] = INLINE {RETURN [widget.s.class.key=classKey]}; HasSubClassKey: PROC [widget: Widget, classKey: ATOM] RETURNS [BOOL]; ClassName: PROC [widget: Widget] RETURNS [ATOM] = INLINE { RETURN [widget.s.class.className[widget]] }; NoteChildChange: PROC [widget: Widget]; NoteChildChangePropagate: PROC [widget: Widget, top: Widget ¬ NIL]; NoteGeometryChange: PROC [widget: Widget, geometry: Geometry ¬ []]; NoteGeometryChangePropagate: PROC [widget: Widget, geometry: Geometry ¬ [], top: Widget ¬ NIL]; NoteMappingChange: PROC [widget: Widget, mapping: Mapping ¬ dontUse]; NoteMappingChangePropagate: PROC [widget: Widget, mapping: Mapping ¬ dontUse, top: Widget ¬ NIL]; StartReconfigureChildren: PROC [widget: Widget]; NoteAndStartReconfigure: PROC [widget: Widget, geometry: Geometry ¬ [], mapping: Mapping ¬ dontUse]; ShallowInternalEnumerateChildren: PROC [widget: Widget, proc: EachChild, data: REF ¬ NIL]; Class: TYPE = REF READONLY ClassRec; ImplementorClass: TYPE = REF ClassRec; ClassRec: TYPE = RECORD [ key: ATOM ¬ NIL, properties: Atom.PropList ¬ NIL, --Do not use if you don't understand the inheritance and locking model. classNameHint: ATOM ¬ NIL, super: Class ¬ NIL, wDataIdx: NAT ¬ 0, wDataNum: NAT ¬ 0,--number of subClassData entries in widgets flags: ClassFlags ¬ ALL[FALSE], --private to prevent unmonitored access configureLR: PRIVATE ConfigureProc ¬ NIL, --** actualCreateWindowLR: PRIVATE WidgetProc ¬ NIL, --** destroyWindowLR: PRIVATE TerminateProc ¬ NIL, --** removeChildLR: PRIVATE RemoveChildProc ¬ NIL, --** pleaseResizeChild: WidgetNChildProc ¬ NIL, preferredSizeLR: PreferredSizeProc ¬ NIL, --** preStopFastAccess: TerminateProc ¬ NIL, --++ fullStopFastAccessLR: FullStopFastAccessProc ¬ NIL, --** bindScreenLX: BindScreenProc ¬ NIL, --** forgetScreenLR: TerminateProc ¬ NIL, --** destroyWidget: WidgetProc ¬ NIL, internalEnumerateChildren: PRIVATE InternalEnumerateChildrenProc ¬ NIL, --++ superWithIEC: PRIVATE Class ¬ NIL, initInstPart: PRIVATE InitInstancePartProc ¬ NIL, cursorKey: PRIVATE REF ¬ NIL, backgroundKey: PRIVATE REF ¬ NIL, borderColorKey: PRIVATE REF ¬ NIL, eventMask: PRIVATE SetOfEvent ¬ unspecifiedEvents, className: PRIVATE ClassNameProc ¬ NIL, createSubClass: PRIVATE CreateSubClassProc ¬ NIL, cDataIdx: NAT ¬ 0, cDataNum: NAT ¬ 0,--number of cClassData entries in class cClassData: SEQUENCE leng: NAT OF REF ]; WidgetProc: TYPE = PROC [widget: Widget]; InitInstancePartProc: TYPE = PROC [widget: Widget, arguments: Atom.PropList]; InternalEnumerateChildrenProc: TYPE = PROC [self: Widget, classLevel: Class, proc: EachChild, data: REF] RETURNS [stop: BOOL ¬ FALSE]; EachChild: TYPE = PROC [parent: Widget, child: Widget, data: REF] RETURNS [stop: BOOL ¬ FALSE]; WidgetNChildProc: TYPE = PROC [widget, child: Widget]; RemoveChildProc: TYPE = PROC [widget, child: Widget] RETURNS [done: BOOL ¬ FALSE]; FullStopFastAccessProc: TYPE = PROC [widget: Widget, protectTQLR: TQProc, reason: TerminationReason]; TQProc: TYPE = PROC [tq: TQ]; GeometryOption: TYPE = {x, y, w, h, b}; GeometryRequest: TYPE = PACKED ARRAY GeometryOption OF BOOL ¬ ALL[FALSE]; PreferredSizeProc: TYPE = PROC [widget: Widget, mode: ATOM ¬ NIL, proposed: Xl.Geometry ¬ [], maySkip: GeometryRequest ¬ ALL[FALSE]] RETURNS [preferred: Xl.Geometry ¬ []]; ConfigureProc: TYPE = PROC [widget: Widget, geometry: Xl.Geometry ¬ [], mapping: Mapping ¬ dontUse, reConsiderChildren: BOOL ¬ FALSE]; TerminateProc: TYPE = PROC [widget: Widget, reason: TerminationReason]; TerminationReason: TYPE = {normal, errorWindow, errorConnection}; BindScreenProc: TYPE = PROC [widget: Widget, rootTQ: TQ, screen: Xl.Screen, screenDepth: Xl.ScreenDepth ¬ NIL]; ClassNameProc: TYPE = PROC [widget: Widget] RETURNS [key: ATOM ¬ NIL]; CreateSubClassProc: TYPE = PROC [superClass: Class, newClass: ImplementorClass, bottom: BOOL]; BasicMethodsRec: TYPE = RECORD [--used for class creations key: ATOM, classNameHint: ATOM ¬ NIL, --useful for className super: Class ¬ NIL, wDataNum: NAT ¬ 0, cDataNum: NAT ¬ 0, addFlags: ClassFlags ¬ ALL[FALSE], preferredSizeLR: PreferredSizeProc ¬ NIL, configureLR: ConfigureProc ¬ NIL, actualCreateWindowLR: WidgetProc ¬ NIL, destroyWindowLR: TerminateProc ¬ NIL, removeChildLR: RemoveChildProc ¬ NIL, pleaseResizeChild: WidgetNChildProc ¬ NIL, preStopFastAccess: TerminateProc ¬ NIL, fullStopFastAccessLR: FullStopFastAccessProc ¬ NIL, bindScreenLX: BindScreenProc ¬ NIL, forgetScreenLR: TerminateProc ¬ NIL, destroyWidget: WidgetProc ¬ NIL, internalEnumerateChildren: InternalEnumerateChildrenProc ¬ NIL, initInstPart: InitInstancePartProc ¬ NIL, cursorKey: REF ¬ NIL, backgroundKey: REF ¬ NIL, borderColorKey: REF ¬ NIL, eventMask: SetOfEvent ¬ unspecifiedEvents, className: ClassNameProc ¬ NIL, createSubClass: CreateSubClassProc ¬ NIL ]; END. Aό XTk.mesa Copyright Σ 1988, 1989, 1990, 1991 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, October 13, 1988 12:38:47 pm PDT Christian Jacobi, April 7, 1992 11:16 am PDT Willie-s, September 30, 1991 6:36 pm PDT This is a quite simple toolkit. Every visual object is called a widget; a widget is the data structure around a window. This toolkit is influenced by the standard X toolkit intrinsics, but it is simplified, scaled down, and, cedarized. Documentation Friendly use expected; Clients of a widget must NOT change most of the fields directly. Widgets are robust in the sense that fooling with a widget will not harm another top level widget tree. Widgets allow complete access of the whole X11 protocol by exposing the underlying window (Xl layer); they serve mainly to split the window creation process into phases to simplify geometry management and enable migration. This package splits the "world" into three sides Its implementation, and, the X window client interface. Mechanisms to make the whole show possible. Widget class implementors. Are a little bit priviledged, and, also have more duties. They should be able to play many inheritance games. Widget clients. This is the main issue of the package: Widget clients should be easy to program. Widget clients should not modify most widget fields directly. Phases Creation: Data structures are created. Screen binding: Enables fonts and sizes for geometry management. Realization (Configure): Creation of X windows; finish set up of event matching requirements. Running: Handle events; nothing happens unless widget client or widget class provides event handler. Interactive modifications (Configure): ... Fast stop interactive access. Unrealization: Destroy X window. Forgeting screen. Widget destruction: (Get rid of circular references for the benefit of D-Machines) Synchronization issues Widgets of a particular tree should be created in a single thread (field access is NOT monitorized). Once the widget tree is created and left to events, further structural modifications, realization or resizing are only allowed with the lock of the "rootTQ". Convention: Forked access to widget is NOT allwed before the widget is included in a widget tree defining the "rootTQ). Event procedures may use different threads as they desire; except if they refer to other widgets the procedure should wait until that widget is realized to make sure the rootTQ of it is defined. Critical event procedures might simply run on "rootTQ" instead of testing widget for realization before use. The postfix LR (Locking Root) on a procedure means the procedure must be called only with the rootTQ lock hold. This also implies that LR marked procedure or procedure variables must not be assigned to unmarked procedure variables or parameters. The reverse does NOT hold: A LR marked procedure may of course call procedures without locking requirements, and, an unmarked procedure may be assigned to an LR marked variable. This convention allows easy textual recognition whether the minimum locks are hold. It does not protect from holding locks too often. The locking requirements are relaxed while creation of a widget because of the restriction of asynchrounous access. The postfix LX is used for procedures which have special locking rules documented with the procedure. E.g. whether or not invokation of an LX procedure from an unmonitored caller is legal depends on its parameters. For the case of multiple locks used, watch for the locking order. "rootTQ" should have a order=rootLockingOrder Termination and cleanup issues Termination procedures have two phases; the first phase may be called on any thread to stop interactions; the second phase is supposed to run on rootTQ. Normal termination is supposed to clean up completely and return all resources. Error termination is considered a bug and should happen only while debugging applications; in the case of error terminations data structures might be left alone and circular references unbroken. X resources won't be returned either. Termination because of dying connection is considered rude and clean up of internal data structures might be optional. X resources will be claimed back by X and need not be delt with anyway. Types and procedures public for all clients Some types are, but some fields and dependent type might be less public Class methods will only see mapping IN [mapped..dontUse], widget.actualMapping IN [mapped, unmapped, unconfigured] Client may ask for any value --Fields useful for initialization of widgets Clients and class implementors: please use only =ok or #ok; all other values are private to XTkImpl --Monitor used for small leaf procedures. The idea is that it this is safer then to have packages use global monitors. This way in case of errors only single widgets wedge and take only a single widgets tree down. This makes debugging easier. --When changed, the new value is automatically set by XTkImpl before class procedures are called. Readonly even to class implementors. --When changed, the new value is automatically set by XTkImpl before class procedures are called. Readonly even to class implementors. --Normally set by class when mapping change is made. --Every layer in class hierarchy can put some class dependent data here Creates a widget and lets class initialize fields. Arguments will be seen by all subclasses while the creation. Warning: Certain classes might not support this procedure. Efficiency hint: Keep number of arguments small. Destroys widget. Option: friendly asks parent of widget to re-consider its children. Callable from any thread. Flags Flags are a long list of boolean values to store some information faster then with property lists. Flags must be changed only with the proper procedure to make it an atomic operation. Applications must reserve flags explicitly; the documentation says how. ClassFlags are inherited at sub class creation. Properties Fetches a value from the widgets property list; NIL if not found. Puts a property key value pair on the widgets property list. A nil value removes the property. Notifiers LOCKING RULES: Notifiers on LR marked keys must not be invoked outside the lock of the root. Further locking convention: Notifiers on LR marked keys are to be protected from general client invocation (but not registration). Type for notifier procedure. registerData from RegisterNotifier. callData depending on actual caller. Warning: many built in usages do not specify event. Registers a callback notifier for widget. The notifier proc's will be called according to the specification of "key". LOCKING RULE: procedures with the LR postfix must only be registered with authorized LR keys. Undo of RegisterNotifier on widget with matching key and identical procLX and registerData Notifiers called in realization (configure) before window creation. Called on rootTQ. Do not expect coordinates to be already set up. Notifiers called in realization (configure) after window creation. Note that the window usually is not yet mapped. Called on rootTQ. Notifiers called after Configure if neither window creation or destruction is involved. Called on rootTQ. Notifiers called in configure after window destruction. Called on rootTQ. Notifiers called in early phase of widget destruction to stop interactions accessing window. Called on random thread, not monitored. [small window of multiple calls] Notifiers called in late phase of widget destruction (after window destruction) useful to break cycles. Called on rootTQ. Notifiers called when screen is installed. Called on installed rootTQ. Notifiers called when forgetting screen. Called on rootTQ. Notifiers called in late phase of widget destruction (this callback is not invoked by garabage collection). Called on random thread, not monitored. [small window of multiple calls] Restrict usage to breaking circular structures, as this notification might be disabled in debugging worlds. Widget operations Adds a match to the permanent match-list of a widget which is used for all realizations. Catches event if X server generates it; Tells X server to generate event... If window is already realized then also issues X request. ORs generate into widget.s.attributes. A nil tq defaults to the rootTQ. Adds a match to the temporary match-list of a widget to be used on next realization. Catches event if X server generates it; Tells X server to generate event... If window is already realized then also issues X request. ORs generate into widget.s.attributes. A nil tq defaults to the rootTQ. Returns root widget of widget Defined only after widget tree has assembled Returns borderWidth of widget; won't return dontUse Returns whether widget is bound to a screen On next FullStopFastAccess the widget will try to synchronize with protectTQ. Please consider this a heavy weight operation. Orphanization When a parent widget dies, is destroyed, or, decides to remove and destroy a child, it gives the child widget a chance to save itself. This is useful if a widget contains valuable application state. Orphanization is typically registered by the client of a widget instance. The default behaviour for destruction is to destroy the widget without notification to the parent. Will be called on rootTQ. Asynchronous and environment access is already stopped before the orphan proc is called. Once an orphan proc is called, old parent widget will not touch orphan anymore. Registers orphan procedure. An eventual previously registered orphan procedure is removed. NIL resets default behaviour. Class access Returns whether a widget has a particular class or subclass thereof Returns whether a widget has a particular class exactly Returns whether a widget has a proper subclass of class Returns whether a widget has a particular class or subclass thereof Returns whether a widget has a particular class exactly Returns whether a widget has a proper subclass of classKey Returns useful key for database lookup Not unique ! Resizing, Widget Tree operations Notifies widget that on of its children whishes a change in state. The note will not be acted upon until the next checking time of widget. Callable from any thread. Like NoteChildChange but further ancestors are notified too. Stops propagation at top. (top=NIL is shortcut for root). Stores new geometry in widget and notifies direct parent of desired change (if any). The note will not be acted upon until the next checking time of widget. The parent will do its best at the next checking time (on next StartReconfigure), but does not give any guarantee. Callable from any thread. (Monitors structure only, not correctness of geometry) Stores new geometry in widget and notifies direct parent of desired change (if any). The note will not be acted upon until the next checking time of widget . The parent will do its best at the next checking time (on next StartReconfigure), but does not give any guarantee. Callable from any thread. (Monitors structure only, not correctness of geometry) Stores new mapping in widget and notifies direct parent of desired change (if any). The note will not be acted upon until the next checking time of widget. The parent will do its best at the next checking time (on next StartReconfigure), but does not give any guarantee. Callable from any thread. (Monitors structure only, not correctness of geometry) Like NoteChildChange but further ancestors are notified too. Stops propagation at top. (top=NIL is shortcut for root). Checks size and mapping whishes of widget's children and configure them if appropriate. Callable from any thread. Conveniance proc. Stores new geometry in widget, notifies direct parent, and, StartReconfigureChildren of parent. Callable from any thread. Shallow enumerates children widgets as used for propagation through widget tree! may include hidden children and therefore is probably not useful for general clients. Adding or removing children while enumeration might not be considered in time. Callable from any thread. Types not used by simple clients ... but by widget sub class implementations ** means: called on rootTQ only ++ means: called on any thread --Index into wClassData of widget for start of fields --This field is set automatically at class creation; client values are ignored --This layer in the class hierarchy occupies fields [wDataIdx..wDataIdx+wDataNum) --Creation of window(realization), change of mapping, geometry -- If creation: Connection filled in; preRealizers are called before calling class proc --If a widget is reconfigured, it has no choice but must do it exactly as requested --It might reconfigure its children in turn... --It is ok to default this procedure --If a non-defaulted configureLR proc wants to inherit, it must do so itself. --Recursion through widget tree must be provided, it is not built in. --Interactive access is already stopped externally if window needs to be destroyed. --Used by some ConfigureProc's; especially the default configureLR. --The actual create window part and eventaul mapping, all widget fields (except widget.window) are already set up by caller. --Called instead of configureLR when window destruction is requested. --Subclass chaining and tree recursion automatically. --Called when child widget needs to be removed. --It is ok if a widget class does NOT recognize and remove its children. --Subclass chaining automatically. --Once widget destruction is started removeChildLR might not be called anymore. --Caller takes care of stopping and forgetting screen. --Can be called from any child (unsynchronized) on its parent. --Might be ignored, children resized, or request propagated up the widget tree --If the proc decides to resize children it must do so on the rootTQ. --Defaulting this procedure in a root class means ignoring request. --If a non-defaulted pleaseResizeChild proc wants to inherit, it must do so itself. --Returns preferred geometry for itself --maySkip: dimension is not asked for [but might be returned anyway] --proposed: proposal for dimension --preferredSizeLR might or might not take advantage of maySkip and proposed --but any returned value#dontUse might be used even if maySkip was true. --If a non-defaulted preferredSizeLR proc wants to inherit, it must do so itself --Environment (screen, connection) must be available --If widget is terminated it must stop doing interactions --Subclass chaining and tree recursion automatically --If widget is terminated it must stop doing interactions --Subclass chaining and tree recursion automatically --Subclass chaining and tree recursion automatically --Subclass chaining and tree recursion automatically --Subclass chaining and optional tree recursion automatically --Shallow enumerates children widgets as used for propagation through widget tree! Not thaught for general client usage. Should be fast, not use locking as it is used in terminators. Used for procedures automatically recursing through widget tree. --Adding or removing children while enumeration might not be considered in time. --Chained, in unknown order. --Allows to fast stop chaining internalEnumerateChildren --Called from CreateWidget only --Chained: super class first, sub class afterwards --Used if cursor is illegal at realization time; inherits if NIL --Used if background is illegal at realization time; inherits if NIL --Used if background is illegal at realization time; inherits if NIL --Used for initialization; ors with inherited classes --Should return key for database lookup. --Called anytime any thread. --Called in CreateClass only, just before returning --Chained: Called super class first, sub class afterwards, for every layer in class hierarchy providing this procedure. --index into cClassData of class for start of fields --This field is set automatically at class creation; client values are ignored --This layer in the class hierarchy occupies fields [cDataIdx..cDataIdx+cDataNum) --Every layer in class hierarchy can put some data here --child must be NIL, or, child of widget --Conservative: Returns TRUE when child removed; Returns FALSE when child not removed or not found. --Termination should be propagated to children --Normal termination should destroy the window --Other termination should not access the connection; it or the window might be broken --Returns a class name --this is not unique but handy for class key in database lookup --Called when a new class or subclass is generated --Called chained, super class first --bottom means: createdClass=superClass Procedures for Widget Class implementors For real stuff look at the XTkFriends interface --general fields --basic methods --usefull for SimpleRealizeOneLevel ΚI–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ΟeœC™NKšœ=™=K™,K™(K™—šΟk œ˜ Kšœžœ ˜Kšœžœžœ%˜ΎK˜—KšΟnœžœž ˜Kšœžœžœ˜K™šœ™K™K™WK™sK™—šΟb ™ K™™K™‹K™—™0™9K™+—™K™n—™Kšœ‘™‘—K™—™K™&K™@K™]K™dKšœ*™*Kšœ™K™!K™KšœR™RK™—™Kšœ…™…Kšœz™zKšœ΅™΅K™Kšœφ™φKšœ±™±Kšœ†™†Kšœu™uK™KšœΧ™ΧK™Kšœr™rK™—™Kšœ˜™˜K™SK™μK™ΏK™—K™—š +™+™GK˜—Kšœžœ ˜Kšžœžœžœ˜K˜Kšœžœžœ ˜K˜Kšœ žœ˜KšœžœΟc&˜AK˜šœ žœs˜€šœ™Kšœ™Kšœ8™8—K™K˜—šœ žœžœ˜Kš‘-™-Kšœžœ˜Kšœ‘˜+Kšœ‘˜*Kšœ žœžœ‘5˜KKšœ žœžœ‘˜,Kšœ˜K˜—šœžœ˜%Kšœc™cK˜—šœ žœ0˜AK˜—šœ žœž œžœ˜$Kšœυ™υKšœ‘˜2Kšœžœ ‘˜/Kšœ‘˜2Kšœ‘˜2Kšœžœžœžœ‘'˜PKšœ Οsœ žœ˜#Kšœ ž œžœ žœ‘ ˜7Kšœ žœ žœ‘ ˜0Kšœ’œžœ˜*Kšœ ’œ˜)Kšœ’œžœ˜,šœ’œ‘˜MKšœ’œo™‡—šœ ’œ‘˜;Kšœ‡™‡—Kšœ ’œ‘˜7šœ’œ‘˜JK™5—Kšœ ’œžœžœ‘˜;Kšœ ž œžœ˜Kšœž œžœ˜šœ žœžœžœž˜-Kš‘G™G—Kšœ˜—K˜š Ÿ œžœ)žœžœžœ ˜rKš‘2™2Kšœ ‘3™šœžœžœ‘œ‘˜Kš‘C™CKšœ1‘™BK™—Kšœžœžœ‘œ‘˜6šœžœžœ‘œ‘˜4KšœX™XKš‘™K™—Kšœžœžœ‘œ‘˜Fšœžœžœ‘œ‘˜DKš‘8™8Kš‘™K™—šœžœžœ‘œ‘˜Kš‘{™{K˜—Kšœžœžœ‘œ‘ ˜.šœžœžœ‘œ‘ ˜-Kšœ3‘™GK™—Kšœžœžœ‘œ‘˜2šœžœžœ‘œ‘˜1Kšœ1‘ ™;K™—šœžœžœ‘œ‘˜DKš‘k™kKš‘H™HKšœk‘™l—K™K˜—š ™K˜šŸœžœP˜gK™XK™KKšœ:™:Kšœ'™'Kšœ!™!K˜—šŸœžœP˜gKšœT™TK™KKšœ:™:Kšœ'™'Kšœ!™!K˜—š Ÿœžœ žœ žœžœ˜>Kšžœ:˜@K˜K˜—šŸ œžœžœ ˜3Kš‘™Kšœ,™,K™—šŸ œžœžœžœ˜1Kš‘3™3K˜—šŸ œžœžœžœ˜2Kš‘œ$™+K™—šŸœžœžœ˜™>Kšœ<™™>Kš‘[™[Kš‘S™SKš‘.™.Kš‘$™$Kš‘œ ‘-™MKš‘E™EKš‘S™S—šœžœžœ‘˜4Kš‘œ‘œ ‘™CKš‘|™|—šœžœžœ‘˜2Kš‘œ ‘(™GKšœ4‘™5—šœžœžœ‘˜2Kš‘1™1KšœH™HKšœ!‘™$Kšœ‘#œ ‘ ™RKšœ5‘™6—šœ&žœ˜*Kš‘>™>Kš‘<Πbc‘™NKš‘E™EKš‘C™CKš‘œ‘-™S—šœ%žœ‘˜.Kš‘(™(Kš‘E™EKš‘#™#Kš‘K™KKšœ7‘œ ‘™IKš‘œ‘,™PKš‘4™4—šœ#žœ‘˜,Kš‘9™9Kš‘œ2™4—šœ/žœ‘˜8Kš‘9™9Kš‘œ2™4—šœžœ‘˜(Kš‘œ2™4—šœ žœ‘˜)Kš‘œ2™4—šœžœ˜!Kš‘œ;™=—šœžœ!žœ‘˜LKš‘œP‘)œ™ϊKšœP™PKšœ™šœžœ žœ˜"Kšœ8™8——šœžœžœ˜1Kš‘™Kš‘2™2—šœ ž œžœ˜Kšœ@™@—šœž œžœ˜!KšœD™D—šœžœžœžœ˜"KšœD™D—šœ žœ ˜2Kšœ6™6—šœ žœžœ˜'Kš‘(™(Kš‘™—šœžœžœ˜1Kš‘3™3Kš‘x™x—šœ žœ˜Kš‘4™4Kš‘N™N—šœ žœ‘'˜9Kš‘Q™Q—šœ žœžœžœž˜%Kšœ7™7—Kšœ˜—K˜šœ žœžœ˜)K™—šœžœžœ,˜MK™—Kš œžœžœ:žœžœžœžœ˜†K˜š œ žœžœ'žœžœžœžœ˜_K™—šœžœžœ˜6Kš‘(™(K™—š œžœžœžœžœžœ˜RKš‘œc™eK™—šœžœžœB˜eK™—šœžœžœžœ˜K™—Kšœžœ˜'Kšœžœžœžœžœžœžœžœ˜JK˜šœžœžœžœžœ9žœžœžœ˜«K˜—š œžœžœ^žœžœ˜†K˜K™—šœžœžœ-˜GKšœžœ*˜AK™.K™.K™VK™—š œžœžœžœ3žœ˜oK™—š œžœžœžœžœžœ˜FK™K™?K™—šœžœžœ9žœ˜^K™2K™#Kšœ'™'—K˜K˜—š (™(Kšœ/™/K˜šœžœžœ‘˜:Kš‘™Kšœžœ˜ Kšœžœžœ‘˜1Kšœžœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœžœ˜"Kš‘™Kšœ%žœ˜*Kšœžœ˜"Kšœ#žœ˜(Kšœ!žœ˜&Kšœ!žœ˜&Kšœ&žœ˜+Kšœ#žœ˜(Kšœ/žœ˜4Kšœžœ˜#Kšœ žœ˜$Kšœžœ˜ Kšœ;žœ˜?Kšœ%žœ˜)Kšœ#™#Kšœ žœžœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœ*˜*K™Kšœžœ˜Kšœ%ž˜(Kšœ˜——K˜Kšžœ˜K˜—…—+p΅