DIRECTORY Atom, RefTab, UnsafePropList, Xl, XlCursor, XlUtils, XTk, XTkDB, XTkFastAccessPrivate, XTkFriends, XTkOps, XTkPrivate; XTkImpl: CEDAR MONITOR LOCKS widget USING widget: Widget IMPORTS RefTab, UnsafePropList, Xl, XlCursor, XlUtils, XTk, XTkDB, XTkFastAccessPrivate EXPORTS XTk, XTkFriends, XTkOps, XTkPrivate = BEGIN OPEN Xl, XTk, XTkFriends; detailsForSynchronous: PUBLIC Xl.Details ¬ NEW[Xl.DetailsRec ¬ [synchronous: TRUE, localErrors: inline]]; detailsForFlushNoErrors: PUBLIC Xl.Details ¬ NEW[Xl.DetailsRec ¬ [flush: now, errorMatch: NEW[Xl.MatchRep ¬ [proc: IgnoreErrors, handles: NIL, tq: Xl.CreateTQ[]]]]]; detailsForFlushSoonNoErrors: PUBLIC Xl.Details ¬ NEW[Xl.DetailsRec ¬ [flush: soon, errorMatch: NEW[Xl.MatchRep ¬ [proc: IgnoreErrors, handles: NIL, tq: Xl.CreateTQ[]]]]]; detailsForNoErrors: PUBLIC Xl.Details ¬ NEW[Xl.DetailsRec ¬ [errorMatch: NEW[Xl.MatchRep ¬ [proc: IgnoreErrors, handles: NIL, tq: Xl.CreateTQ[]]]]]; debugErrCount: CARD ¬ 0; IgnoreErrors: Xl.EventProcType = {debugErrCount ¬ debugErrCount+1}; classTable: RefTab.Ref ¬ RefTab.Create[]; aliasTable: RefTab.Ref ¬ RefTab.Create[]; --key: "alias" val: "key" keyTable: RefTab.Ref ¬ RefTab.Create[]; --key: "key" val: not importasnt XTkBadAlias: SIGNAL = CODE; AliasNotifierKey: PUBLIC PROC [key: REF, alias: REF ¬ NIL] = { IF alias=NIL THEN alias ¬ key; IF RefTab.Fetch[keyTable, alias].found THEN { IF alias#key THEN SIGNAL XTkBadAlias; --this aliases is somebody elses key }; IF ~RefTab.Insert[aliasTable, alias, key] THEN { IF RefTab.Fetch[aliasTable, alias].val#key THEN SIGNAL XTkBadAlias; --definition has changed }; [] ¬ RefTab.Store[keyTable, key, key]; --keys can have many aliases }; AllNotifiers: TYPE = LIST OF NotifierHead; NotifierHead: TYPE = RECORD [key: REF, list: NotifierList]; NotifierList: TYPE = LIST OF NofierRec; NofierRec: TYPE = RECORD [proc: WidgetNotifyProc, registerData: REF ¬ NIL]; CallNotifierList: PROC [list: NotifierList, widget: Widget, callData: REF ¬ NIL, event: Event ¬ NIL] = { FOR l: NotifierList ¬ list, l.rest WHILE l#NIL DO l.first.proc[widget: widget, registerData: l.first.registerData, callData: callData, event: event]; ENDLOOP }; CallNotifiers: PUBLIC PROC [widget: Widget, key: REF, callData: REF ¬ NIL, event: Event ¬ NIL] = { FOR al: AllNotifiers ¬ NARROW[widget.notifiers], al.rest WHILE al#NIL DO IF al.first.key=key THEN { CallNotifierList[al.first.list, widget, callData, event]; RETURN; }; ENDLOOP; }; RemoveNotifiers: PUBLIC PROC [widget: Widget, key: REF] = { [] ¬ GetNRemoveNotifiers[widget, key]; }; GetNRemoveNotifiers: ENTRY PROC [widget: Widget, key: REF] RETURNS [notifiers: NotifierList ¬ NIL] = { head: AllNotifiers ¬ NARROW[widget.notifiers]; IF head#NIL THEN { IF head.first.key=key THEN { notifiers ¬ head.first.list; widget.notifiers ¬ head.rest; RETURN }; WHILE head.rest#NIL DO IF head.rest.first.key=key THEN { notifiers ¬ head.rest.first.list; head.rest ¬ head.rest.rest; RETURN }; head ¬ head.rest ENDLOOP }; }; UnregisterFromSingleList: INTERNAL PROC [list: NotifierList, proc: WidgetNotifyProc, registerData: REF ¬ NIL] RETURNS [NotifierList] = { WHILE list#NIL AND list.first.proc=proc AND list.first.registerData=registerData DO list _ list.rest ENDLOOP; IF list#NIL THEN { lag: NotifierList _ list; WHILE lag#NIL AND lag.rest#NIL DO IF lag.rest.first.proc=proc AND lag.rest.first.registerData=registerData THEN {lag.rest _ lag.rest.rest} ELSE {lag _ lag.rest}; ENDLOOP; }; RETURN [list] }; InternalRegisterNotifier: INTERNAL PROC [widget: Widget, real: REF, proc: WidgetNotifyProc, registerData: REF ¬ NIL] = { head: AllNotifiers ¬ NARROW[widget.notifiers]; this: AllNotifiers ¬ NIL; FOR al: AllNotifiers ¬ head, al.rest WHILE al#NIL DO IF al.first.key=real THEN {this ¬ al; EXIT}; ENDLOOP; IF this=NIL THEN { this ¬ CONS[NotifierHead[key: real, list: NIL], head]; widget.notifiers ¬ this }; this.first.list ¬ CONS[[proc, registerData], this.first.list] }; RegisterNotifier: PUBLIC PROC [widget: Widget, key: REF, procLX: WidgetNotifyProc, registerData: REF ¬ NIL] = { EntryRegisterNotifier: ENTRY PROC [widget: Widget, real: REF, proc: WidgetNotifyProc, registerData: REF] = { InternalRegisterNotifier[widget, real, proc, registerData]; }; p: WidgetNotifyProc ¬ procLX; --checks globality real: REF ¬ RefTab.Fetch[aliasTable, key].val; IF real=NIL THEN real ¬ key; EntryRegisterNotifier[widget, real, p, registerData]; }; UnRegisterNotifier: PUBLIC PROC [widget: Widget, key: REF, procLX: WidgetNotifyProc, registerData: REF ¬ NIL] = { EntryUnRegisterNotifier: ENTRY PROC [widget: Widget, real: REF, proc: WidgetNotifyProc, registerData: REF] = { head: AllNotifiers ¬ NARROW[widget.notifiers]; this: AllNotifiers ¬ NIL; FOR al: AllNotifiers ¬ head, al.rest WHILE al#NIL DO IF al.first.key=real THEN {this ¬ al; EXIT}; ENDLOOP; IF this#NIL AND this.first.list#NIL THEN this.first.list _ UnregisterFromSingleList[this.first.list, proc, registerData]; }; p: WidgetNotifyProc ¬ procLX; --checks globality real: REF ¬ RefTab.Fetch[aliasTable, key].val; IF real=NIL THEN real ¬ key; EntryUnRegisterNotifier[widget, real, p, registerData]; }; CallAndRegisterOnPostRealize: PUBLIC <> PROC [widget: Widget, proc: WidgetNotifyProc, registerData: REF ¬ NIL] = { p: WidgetNotifyProc ¬ proc; --checks globality MustCall: ENTRY PROC [widget: Widget, proc: WidgetNotifyProc, registerData: REF] RETURNS [mustCall: BOOL] = { mustCall ¬ widget.state=realized; InternalRegisterNotifier[widget, postWindowCreationLRReal, p, registerData] }; IF widget.state>=dead THEN RETURN; IF MustCall[widget, proc, registerData] THEN p[widget, registerData]; }; NewNotifyKey: PROC [a: ATOM] RETURNS [key: REF ATOM] = { key ¬ NEW[ATOM¬a]; AliasNotifierKey[key: key, alias: a]; }; preWindowCreationLRKey: PUBLIC ATOM ¬ $preWindowCreation; preWindowCreationKey: PUBLIC ATOM ¬ $preWindowCreation; postWindowCreationLRKey: PUBLIC ATOM ¬ $postWindowCreation; postWindowCreationKey: PUBLIC ATOM ¬ $postWindowCreation; postConfigureLRKey: PUBLIC ATOM ¬ $postConfigure; postConfigureKey: PUBLIC ATOM ¬ $postConfigure; postWindowDestructionLRKey: PUBLIC ATOM ¬ $postWindowDestruction; postWindowDestructionKey: PUBLIC ATOM ¬ $postWindowDestruction; preStopFastAccessKey: PUBLIC ATOM ¬ $preStopFastAccess; postStopFastAccessLRKey: PUBLIC ATOM ¬ $postStopFastAccess; postStopFastAccessKey: PUBLIC ATOM ¬ $postStopFastAccess; bindScreenLRKey: PUBLIC ATOM ¬ $bindScreen; bindScreenKey: PUBLIC ATOM ¬ $bindScreen; forgetScreenLRKey: PUBLIC ATOM ¬ $forgetScreen; forgetScreenKey: PUBLIC ATOM ¬ $forgetScreen; postWidgetDestructionKey: PUBLIC ATOM ¬ $postWidgetDestruction; preWindowCreationLRReal: REF ATOM ¬ NewNotifyKey[preWindowCreationLRKey]; postWindowCreationLRReal: REF ATOM ¬ NewNotifyKey[postWindowCreationLRKey]; postConfigureLRReal: REF ATOM ¬ NewNotifyKey[postConfigureLRKey]; postWindowDestructionLRReal: REF ATOM ¬ NewNotifyKey[postWindowDestructionLRKey]; preStopFastAccessReal: REF ATOM ¬ NewNotifyKey[preStopFastAccessKey]; postStopFastAccessLRReal: REF ATOM ¬ NewNotifyKey[postStopFastAccessLRKey]; forgetScreenLRReal: REF ATOM ¬ NewNotifyKey[forgetScreenLRKey]; bindScreenLRReal: REF ATOM ¬ NewNotifyKey[bindScreenLRKey]; postWidgetDestructionReal: REF ATOM ¬ NewNotifyKey[postWidgetDestructionKey]; AddPermanentMatch: PUBLIC PROC [widget: Widget, matchRep: MatchRep, generate: SetOfEvent] = { EntryPart: ENTRY PROC [widget: Widget, matchRep: MatchRep, generate: SetOfEvent] RETURNS [realized: BOOL] = { widget.attributes.eventMask ¬ Xl.ORSetOfEvents[widget.attributes.eventMask, generate]; widget.matchListX ¬ CONS[matchRep, widget.matchListX]; realized ¬ widget.state=realized AND widget.window#Xl.nullWindow AND widget.actualMapping=0 THEN {maySkip[x] ¬ TRUE; proposed.pos.x ¬ widget.s.geometry.pos.x}; IF widget.s.geometry.pos.y>=0 THEN {maySkip[y] ¬ TRUE; proposed.pos.y ¬ widget.s.geometry.pos.y}; IF widget.s.geometry.size.width>0 THEN {maySkip[w] ¬ TRUE; proposed.size.width ¬ widget.s.geometry.size.width}; IF widget.s.geometry.size.height>0 THEN {maySkip[h] ¬ TRUE; proposed.size.height ¬ widget.s.geometry.size.height}; IF widget.s.geometry.borderWidth>0 THEN {maySkip[b] ¬ TRUE; proposed.borderWidth ¬ widget.s.geometry.borderWidth}; IF maySkip=gAllTrue THEN RETURN [proposed]; }; IF widget.state>realized AND GetWidgetFlag[widget, preferredSizeFromDB] THEN { IF maySkip[x] AND maySkip[y] AND maySkip[b] THEN preferred.size ¬ XTkDB.GetSizeFromDB[widget] ELSE preferred ¬ XTkDB.GetGeometryFromDB[widget]; IF preferred.pos.x>=0 THEN {maySkip[x] ¬ TRUE; proposed.pos.x ¬ preferred.pos.x}; IF preferred.pos.y>=0 THEN {maySkip[y] ¬ TRUE; proposed.pos.y ¬ preferred.pos.y}; IF preferred.size.width>0 THEN {maySkip[w] ¬ TRUE; proposed.size.width ¬ preferred.size.width}; IF preferred.size.height>0 THEN {maySkip[h] ¬ TRUE; proposed.size.height ¬ preferred.size.height}; IF preferred.borderWidth>=0 THEN {maySkip[b] ¬ TRUE; proposed.borderWidth ¬ preferred.borderWidth}; IF maySkip=gAllTrue THEN RETURN [proposed]; }; preferred ¬ widget.s.class.preferredSizeLR[widget, mode, proposed, maySkip]; }; PreStopFastAccess: PUBLIC TerminateProc = { Recurse: EachChild = {PreStopFastAccess[child, reason]}; IF widget.fastAccessAllowed=ok THEN { parent: Widget ¬ widget.parent; widget.fastAccessAllowed ¬ warned; CallNotifiers[widget, preStopFastAccessReal, IF reason=normal THEN $normal ELSE $error]; FOR class: Class ¬ widget.s.class, class.super WHILE class#NIL DO IF class.preStopFastAccess#NIL THEN class.preStopFastAccess[widget, reason]; ENDLOOP; ShallowInternalEnumerateChildren[widget, Recurse]; }; }; FullStopFastAccessRecurseLR: PROC [w: Widget, protectPaintTQ: PROC [TQ], reason: TerminationReason] = { Recurse: EachChild = { FullStopFastAccessRecurseLR[child, protectPaintTQ, reason] }; IF w.state>=warned THEN RETURN; IF w.fastAccessAllowed=ok THEN PreStopFastAccess[w, reason]; w.state ¬ warned; FOR class: Class ¬ w.s.class, class.super WHILE class#NIL DO IF class.fullStopFastAccessLR#NIL THEN class.fullStopFastAccessLR[w, protectPaintTQ, reason]; ENDLOOP; ShallowInternalEnumerateChildren[w, Recurse]; FOR list: LIST OF TQ ¬ GetNRemoveSyncsFastAccess[w], list.rest WHILE list#NIL DO protectPaintTQ[list.first]; ENDLOOP; }; synchFastAccessKey: REF INT ~ NEW[INT]; SynchronizeFastAccess: PUBLIC ENTRY PROC [widget: Widget, protectTQ: TQ] = TRUSTED { IF protectTQ#NIL THEN { WITH UnsafePropList.GetProp[@widget.props, synchFastAccessKey] SELECT FROM lst: LIST OF TQ => { list: LIST OF TQ ¬ CONS[protectTQ, lst]; [] ¬ UnsafePropList.PutProp[LOOPHOLE[@widget.props], synchFastAccessKey, list]; } ENDCASE => { UnsafePropList.TrustedAddNewProp[LOOPHOLE[@widget.props], synchFastAccessKey, LIST[protectTQ]]; }; }; }; GetNRemoveSyncsFastAccess: ENTRY PROC [widget: Widget] RETURNS [LIST OF TQ ¬ NIL] = TRUSTED { old: REF ~ UnsafePropList.RemProp[LOOPHOLE[@widget.props], synchFastAccessKey]; WITH old SELECT FROM lst: LIST OF TQ => RETURN [lst]; ENDCASE => {} }; FullStopFastAccessLR: PUBLIC PROC [w: Widget, reason: TerminationReason] = { tqSet: XTkFastAccessPrivate.TQSet ¬ NIL; MyQueueTQ: PROC [waitTQ: TQ] = { IF waitTQ#NIL AND waitTQ#w.rootTQ THEN tqSet ¬ XTkFastAccessPrivate.Include[tqSet, waitTQ] }; IF w.state>=warned THEN RETURN; FullStopFastAccessRecurseLR[w, MyQueueTQ, reason]; IF tqSet#NIL THEN XTkFastAccessPrivate.Synchronize[tqSet]; CallNotifiers[w, postStopFastAccessLRReal, $normal]; }; DestroyWidgetLR: PUBLIC PROC [widget: Widget] = { DestroyChild: XTk.EachChild = { IF child.state0 THEN { widget.depth ¬ w.depth; IF w.screenDepth#NIL AND w.screenDepth.depth=widget.depth THEN widget.screenDepth ¬ w.screenDepth; RETURN }; ENDLOOP; } }; SetupScreenDepth: PUBLIC PROC [widget: Widget] = { IF widget.depth<=0 AND widget.screenDepth#NIL THEN { widget.depth ¬ widget.screenDepth.depth; }; IF widget.depth<=0 THEN InheritDepth[widget]; IF widget.screenDepth=NIL THEN { screen: Screen ¬ FindScreen[widget]; IF widget.depth>0 THEN { FOR sdl: ScreenDepthL ¬ screen.screenDepthL, sdl.rest WHILE sdl#NIL DO IF widget.depth=sdl.first.depth THEN {widget.screenDepth ¬ sdl.first; RETURN}; ENDLOOP; ERROR; } ELSE { FOR w: Widget ¬ widget.parent, w.parent WHILE w#NIL DO IF w.screenDepth#NIL THEN { widget.screenDepth ¬ w.screenDepth; widget.depth ¬ widget.screenDepth.depth; RETURN }; ENDLOOP; FOR sdl: ScreenDepthL ¬ screen.screenDepthL, sdl.rest WHILE sdl#NIL DO IF sdl.first.depth=1 AND sdl.first.nVisualTypes>0 THEN { widget.screenDepth ¬ sdl.first; widget.depth ¬ widget.screenDepth.depth; RETURN }; ENDLOOP; FOR sdl: ScreenDepthL ¬ screen.screenDepthL, sdl.rest WHILE sdl#NIL DO IF sdl.first.depth=screen.rootDepth AND sdl.first.nVisualTypes>0 THEN { widget.screenDepth ¬ sdl.first; widget.depth ¬ widget.screenDepth.depth; RETURN }; ENDLOOP; FOR sdl: ScreenDepthL ¬ screen.screenDepthL, sdl.rest WHILE sdl#NIL DO IF sdl.first.nVisualTypes>0 THEN { widget.screenDepth ¬ sdl.first; widget.depth ¬ widget.screenDepth.depth; RETURN }; ENDLOOP; ERROR; }; }; }; FindVisual: PROC [widget: Widget] RETURNS [Visual ¬ nullVisual] = { v: Xl.Visual ¬ widget.visual; IF v=nullVisual THEN { IF widget.parent#NIL AND widget.screenDepth=widget.parent.screenDepth THEN RETURN [widget.parent.visual]; --most frequent ERROR; } ELSE { FOR vtl: LIST OF READONLY VisualType ¬ widget.screenDepth.visuals, vtl.rest WHILE vtl#NIL DO IF vtl.first.visual=v THEN RETURN [v]; ENDLOOP; ERROR; --visual not supported by screen for this depth }; }; IScreenBound: PROC [widget: Widget] RETURNS [BOOL] = INLINE { RETURN [widget.state<=screened]; }; ScreenBound: PUBLIC PROC [widget: Widget] RETURNS [BOOL] = { RETURN [IScreenBound[widget]]; }; BindScreenFromParent: PROC [widget: Widget] = { IF ~IScreenBound[widget] THEN { parent: Widget ¬ widget.parent; --crash if parent doesn't exist or isn't IScreenBound is ok IF ~IScreenBound[parent] THEN ERROR; BindScreenLR[widget, parent.rootTQ, parent.screenDepth.screen, parent.screenDepth]; }; }; HardScreenFromParentLR: PROC [child: Widget] = { parent: Widget ¬ child.parent; IF ~IScreenBound[parent] THEN ERROR; BindScreenLR[child, parent.rootTQ, parent.screenDepth.screen, parent.screenDepth]; }; AssignParentAndCheckScreenLR: PUBLIC PROC [child, parent: Widget] = { child.parent ¬ parent; IF IScreenBound[parent] THEN HardScreenFromParentLR[child] }; BindScreenLR: PUBLIC PROC [widget: Widget, rootTQ: TQ, screen: Xl.Screen, screenDepth: Xl.ScreenDepth ¬ NIL] = { Recurse: EachChild = {BindScreenLR[child, rootTQ, screen, screenDepth]}; IF widget.state>=dead THEN ERROR; IF ~IScreenBound[widget] THEN { IF screen=NIL THEN screen ¬ screenDepth.screen; widget.state ¬ screened; widget.connection ¬ screen.connection; widget.rootTQ ¬ rootTQ; FOR class: Class ¬ widget.s.class, class.super WHILE class#NIL DO IF class.bindScreenLX#NIL THEN class.bindScreenLX[widget, rootTQ, screen, screenDepth]; ENDLOOP; IF widget.screenDepth=NIL THEN widget.screenDepth ¬ screenDepth; CallNotifiers[widget, bindScreenLRReal, NIL<>]; ShallowInternalEnumerateChildren[widget, Recurse]; }; }; ForgetScreenLR: PUBLIC PROC [widget: Widget] = { Recurse: EachChild = {ForgetScreenLR[child]}; IF IScreenBound[widget] THEN { reason: TerminationReason ¬ errorConnection; IF widget.fastAccessAllowed=unconfigured THEN { widget.actualMapping ¬ unconfigured; IF mapping=dontUse AND widget.parent#NIL AND widget.parent.actualMapping { IF widget.actualMapping=mapped THEN mapping ¬ unmapped ELSE mapping ¬ dontUse }; mapIfUnmapped => { IF widget.actualMapping=unmapped THEN mapping ¬ mapped ELSE mapping ¬ dontUse }; unmapIfUnconfigured => { IF widget.actualMapping=unconfigured THEN mapping ¬ unmapped ELSE mapping ¬ dontUse }; mapIfUnconfigured => { IF widget.actualMapping=unconfigured THEN mapping ¬ mapped ELSE mapping ¬ dontUse }; ENDCASE => { IF mapping = widget.actualMapping THEN mapping ¬ dontUse; }; IF mapping<=unmapped THEN { IF widget.parent#NIL THEN { IF widget.parent.actualMapping>=unconfigured THEN mapping ¬ dontUse; } ELSE { IF widget.state > screened THEN mapping ¬ dontUse; }; }; existW ¬ widget.actualMapping CallNotifiers[widget, postWindowCreationLRReal, NIL]; existW => CallNotifiers[widget, postConfigureLRReal, NIL]; ENDCASE => {}; }; }; BorderColorDefined: PROC [w: Widget] RETURNS [BOOL] = INLINE { RETURN [w.attributes.borderPixmap#illegalPixmap OR w.attributes.borderPixel#illegalPixel] }; AssignToActual: PROC [widget: Widget, geometry: Xl.Geometry, mapping: Mapping] = INLINE { IF geometry.pos.x # dontUse THEN widget.actual.pos.x ¬ geometry.pos.x; IF geometry.pos.y # dontUse THEN widget.actual.pos.y ¬ geometry.pos.y; IF geometry.size.width # dontUse THEN widget.actual.size.width ¬ geometry.size.width; IF geometry.size.height # dontUse THEN widget.actual.size.height ¬ geometry.size.height; IF geometry.borderWidth # dontUse THEN widget.actual.borderWidth ¬ geometry.borderWidth; IF mapping # dontUse THEN widget.actualMapping ¬ mapping; }; SimpleConfigureOneLevelLR: PUBLIC ConfigureProc = { EntryOrEventMask: ENTRY PROC [widget: Widget] = { widget.attributes.eventMask ¬ Xl.ORSetOfEvents[widget.attributes.eventMask, widget.s.class.eventMask]; }; existW, createW, destroyW: BOOL; existW ¬ widget.actualMapping widget.attributes.cursor ¬ XlCursor.SharedStandardCursor[widget.connection, rc­]; rwp: REF WidgetProc => rwp­[widget]; ENDCASE => {}; }; IF widget.attributes.backgroundPixel=illegalPixel AND IllegalPixmap[widget.attributes.backgroundPixmap] THEN { WITH widget.s.class.backgroundKey SELECT FROM a: ATOM => { widget.attributes.backgroundPixel ¬ SELECT a FROM $white => widget.screenDepth.screen.whitePixel, $black => widget.screenDepth.screen.blackPixel, $none => illegalPixel, ENDCASE => widget.screenDepth.screen.whitePixel; }; rwp: REF WidgetProc => rwp­[widget]; ENDCASE => {}; }; IF ~BorderColorDefined[widget] THEN { WITH widget.s.class.borderColorKey SELECT FROM a: ATOM => { widget.attributes.borderPixel ¬ SELECT a FROM $white => widget.screenDepth.screen.whitePixel, $black => widget.screenDepth.screen.blackPixel, $none => illegalPixel, ENDCASE => widget.screenDepth.screen.blackPixel; }; rwp: REF WidgetProc => rwp­[widget]; ENDCASE => {}; }; }; IF geometry.pos.x = widget.actual.pos.x THEN geometry.pos.x ¬ dontUse; IF geometry.pos.y = widget.actual.pos.y THEN geometry.pos.y ¬ dontUse; IF geometry.size.width = widget.actual.size.width THEN geometry.size.width ¬ dontUse; IF geometry.size.height = widget.actual.size.height THEN geometry.size.height ¬ dontUse; IF geometry.borderWidth = widget.actual.borderWidth THEN geometry.borderWidth ¬ dontUse; IF mapping = widget.actualMapping THEN mapping ¬ dontUse; AssignToActual[widget, geometry, mapping]; SELECT TRUE FROM createW => { EntryOrEventMask[widget]; IF mapping=dontUse THEN widget.actualMapping ¬ mapping ¬ mapped; widget.s.class.actualCreateWindowLR[widget]; }; existW => { c: Xl.Connection ~ widget.connection; win: Xl.Window ~ widget.window; IF Xl.Alive[c] AND win#Xl.nullWindow THEN { IF mapping=unmapped THEN Xl.UnmapWindow[c, win, detailsForNoErrors]; Xl.ConfigureWindow[c: c, window: win, geometry: geometry]; IF mapping=mapped THEN Xl.MapWindow[c, win, detailsForNoErrors]; }; }; ENDCASE => { }; }; SimpleDestroyWindowLR: PUBLIC TerminateProc = { c: Xl.Connection ~ widget.connection; win: Xl.Window ~ widget.window; widget.actualMapping ¬ MAX[widget.actualMapping, unconfigured]; IF reason=normal AND Xl.Alive[c] AND win#Xl.nullWindow THEN { Xl.DestroyWindow[c, win, detailsForNoErrors]; }; widget.window ¬ Xl.nullWindow; }; DontMapCreateWindowLR: PUBLIC WidgetProc = { visual: Visual ¬ FindVisual[widget]; parentWindow: Xl.Window ¬ widget.parent.window; widget.window ¬ Xl.CreateWindow[c: widget.connection, matchList: CollectMatchesLR[widget], parent: parentWindow, geometry: widget.actual, visual: visual, depth: widget.depth, attributes: widget.attributes]; }; DefaultActualCreateWindowLR: PUBLIC WidgetProc = { DontMapCreateWindowLR[widget]; IF widget.actualMapping=mapped THEN Xl.MapWindow[widget.connection, widget.window]; }; IgnorePleaseResizeChild: PUBLIC WidgetNChildProc = { }; CollectMatchesLR: PUBLIC PROC [widget: Widget] RETURNS [ml: Xl.MatchList ¬ NIL] = { FOR lx: LIST OF MatchRep ¬ widget.matchListX, lx.rest WHILE lx # NIL DO m: Match ¬ NEW[MatchRep ¬ lx.first]; IF m.tq=NIL THEN m.tq ¬ widget.rootTQ; ml ¬ CONS[m, ml]; ENDLOOP; IF widget.matchList1 # NIL THEN { GetMatchList1: ENTRY PROC [widget: Widget] RETURNS [ml: Xl.MatchList] = { ml ¬ widget.matchList1; widget.matchList1 ¬ NIL; }; FOR lx: Xl.MatchList ¬ GetMatchList1[widget], lx.rest WHILE lx # NIL DO m: Match ¬ NEW[MatchRep ¬ lx.first­]; IF m.tq=NIL THEN m.tq ¬ widget.rootTQ; ml ¬ CONS[m, ml]; ENDLOOP; }; }; PropagateUpPleaseResizeChild: PUBLIC WidgetNChildProc = { IF widget.parent#NIL THEN { PleaseResizeChild[widget.parent, widget]; }; }; SimplePreferredSizeOneLevel: PUBLIC PreferredSizeProc = { RETURN [widget.s.geometry]; }; SimpleClassName: PUBLIC ClassNameProc = { RETURN [widget.s.class.classNameHint]; }; NoteChildChangePropagate: PUBLIC PROC [widget: Widget, top: Widget ¬ NIL] = { WHILE widget#NIL AND widget.state=dead THEN ERROR; IF geometry.size.width>0 THEN widget.s.geometry.size.width ¬ geometry.size.width; IF geometry.size.height>0 THEN widget.s.geometry.size.height ¬ geometry.size.height; IF geometry.pos.x#dontUse THEN widget.s.geometry.pos.x ¬ geometry.pos.x; IF geometry.pos.y#dontUse THEN widget.s.geometry.pos.y ¬ geometry.pos.y; IF geometry.borderWidth#dontUse THEN widget.s.geometry.borderWidth ¬ geometry.borderWidth; IF widget.s.geometry#widget.actual OR widget.s.mapping=dontUse THEN { IF widget.parent#NIL THEN NoteChildChange[widget.parent]; }; }; NoteMappingChange: PUBLIC PROC [widget: Widget, mapping: Mapping ¬ dontUse] = { IF widget.state>=dead THEN ERROR; IF mapping#dontUse THEN widget.s.mapping ¬ mapping; IF widget.s.mapping#widget.actualMapping OR widget.s.mapping=dontUse THEN { IF widget.parent#NIL THEN NoteChildChange[widget.parent]; }; }; NoteAndStartReconfigure: PUBLIC PROC [widget: Widget, geometry: Geometry ¬ [], mapping: Mapping ¬ dontUse] = { ReconfigureParentNow: PROC [widget: Widget] = { parent: Widget ¬ widget.parent; IF parent=NIL THEN ERROR; --shell to be handled differently... StartReconfigureChildren[parent]; }; IF widget.state>=dead THEN ERROR; NoteMappingChange[widget, mapping]; NoteGeometryChange[widget, geometry]; ReconfigureParentNow[widget]; }; NoteGeometryChangePropagate: PUBLIC PROC [widget: Widget, geometry: Geometry ¬ [], top: Widget ¬ NIL] = { NoteGeometryChange[widget, geometry]; IF widget.s.geometry#widget.actual OR widget.s.mapping=dontUse THEN { NoteChildChangePropagate[widget.parent, top]; }; }; NoteMappingChangePropagate: PUBLIC PROC [widget: Widget, mapping: Mapping ¬ dontUse, top: Widget ¬ NIL] = { NoteMappingChange[widget, mapping]; IF widget.s.mapping#widget.actualMapping OR widget.s.mapping=dontUse THEN { NoteChildChangePropagate[widget.parent, top]; }; }; ReconfigureChildrenLR: PUBLIC PROC [self: Widget] = { IF self#NIL AND self.state op[orphan]; ENDCASE => DestroyWidgetLR[orphan]; }; defaultSuper: REF ClassRec ¬ NEW[ClassRec[0]]; --used for defaults in CreateClass; NOT used in runtime chaining for efficiency reasons. defaultSuper.configureLR ¬ SimpleConfigureOneLevelLR; defaultSuper.preferredSizeLR ¬ SimplePreferredSizeOneLevel; defaultSuper.pleaseResizeChild ¬ IgnorePleaseResizeChild; defaultSuper.className ¬ SimpleClassName; defaultSuper.actualCreateWindowLR ¬ DefaultActualCreateWindowLR; END. ’ XTkImpl.mesa Copyright Σ 1988, 1989, 1990, 1991, 1992, 1993 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, August 3, 1990 1:59 pm PDT Christian Jacobi, May 4, 1993 2:37 pm PDT --Resumable signal from debugger (while debugging application) --Resume means reuse is ok; abort means reuse is not ok --not monitored because typically called in module initializations --alias already defined <> --sub to super order for no good reason <> <> <> --sub to super order for no good reason --rarely used, not worth optimizing --Removes all registered TQ's for SynchronizeFastAccess and returns them. --Used on all widgets; optimizing worth while. <> <> --collect tqs and wait a little for slow stoppers IF widget=NIL THEN ERROR; IF widget=NIL THEN ERROR; --recurse ancestor first-- --do the job for this level-- --inherit by copy --set up --initializes or restricts classField to superclasses of class --called before window is set up ! <> --try to find using inheritance --try to find screen using visual --dont search for a screen supporting that depth... --a reasonable root should have something set up at least --check existence of required depth on screen --well; to bad if we guessed the first screen and it doesnt provide the depth... --but root widgets should be more clever and provide screenDepth --try inheriting a screenDepth and use its depth --make a screenDepth up --try 1 bit per pixel first --try rootDepth --try any bit per pixel --try inheriting from parent --if it can not be inherited it should be specified! --I'm to lazy to make one up, and wouldn't know which --check whether supplied visual is legal --sub to super order to give subclass first chance to recognize not yet initialized values --sub to super order for no good reason Assigns the defined values into widget, for undefined values leave widget alone. -- -- Κ+'–(cedarcode) style•NewlineDelimiter ™code™ Kšœ ΟeœO™ZK™7K™)K™—šΟk œ˜ K˜K˜K˜K˜K˜ K˜K˜K˜Kšœ˜K˜ K˜K˜ K˜—šΟnœžœžœ˜Kšžœžœ˜!KšžœP˜WKšžœ&˜-—Kšžœžœ˜K˜Kšœžœžœžœ˜iKš œžœžœ*žœ-žœ˜₯Kš œžœžœ+žœ-žœ˜ͺš œžœžœžœ-žœ˜”K˜Kšœžœ˜KšŸ œ7˜C—K˜K˜)Kšœ*Οc˜CKšœ(  ˜HK˜šŸ œžœžœ˜K™?K™7—K˜š Ÿœžœžœžœ žœžœ˜>K™BKšžœžœžœ˜šžœ%žœ˜.Kšžœ žœžœ $˜JK˜—šžœ(žœ˜0K™šžœ)žœ˜0Kšžœ  ˜,—K˜—Kšœ!Πbfœ ˜CK˜K™—Kšœžœžœžœ˜*Kšœžœžœžœ˜;Kšœžœžœžœ ˜'Kš œ žœžœ(žœžœ˜KK˜š Ÿœžœ0žœžœžœ˜hšžœ žœžœž˜1K˜cKšž˜—K˜K˜—šŸ œžœžœžœ žœžœžœ˜bš žœžœžœžœž˜Hšžœžœ˜Kšœ9˜9Kšžœ˜K˜—Kšžœ˜—K˜K˜—šŸœžœžœžœ˜;K˜&K˜K˜—š Ÿœžœžœžœžœžœ˜fKšœžœ˜.šžœžœžœ˜šžœžœ˜K˜K˜Kšž˜K˜—šžœ žœž˜šžœžœ˜!K˜"K˜Kšž˜K˜—K˜Kšž˜—K˜—K˜K˜—š Ÿœžœžœ<žœžœžœ˜ˆš žœžœžœžœ&ž˜SKšœ˜Kšžœ˜—šžœžœžœ˜Kšœ˜š žœžœžœ žœž˜!šžœžœ*˜IKšžœ˜Kšžœ˜—Kšžœ˜ —K˜—Kšžœ˜ K˜K˜—š Ÿœžœžœžœ(žœžœ˜xKšœžœ˜.Kšœžœ˜šžœ"žœžœž˜4Kšžœžœ žœ˜,Kšžœ˜—šžœžœžœ˜Kšœžœžœ ˜7K˜K˜—Kšœžœ'˜=K˜K˜—š Ÿœžœžœžœ*žœžœ˜oš Ÿœžœžœžœ(žœ˜lKšœ;˜;K˜—Kšœ ˜0Kšœžœ&˜/Kšžœžœžœ ˜Kšœ5˜5K˜K˜—š Ÿœžœžœžœ*žœžœ˜qš Ÿœžœžœžœ(žœ˜nKšœžœ˜.Kšœžœ˜šžœ"žœžœž˜4Kšžœžœ žœ˜,Kšžœ˜—š žœžœžœžœžœ˜)KšœP˜P—K˜—Kšœ ˜0Kšœžœ&˜/Kšžœžœžœ ˜Kšœ7˜7K˜K˜—š Ÿœžœ žœ8žœžœ˜zKšœ ˜.š Ÿœžœžœ8žœžœ žœ˜mK˜!KšœK˜KKšœ˜—Kšžœžœžœ˜"Kšžœ&žœ˜EK˜—˜š Ÿ œžœžœžœžœžœ˜8Kšœžœžœ˜K˜%K˜K˜—Kšœžœžœ˜:Kšœžœžœ˜8K˜Kšœžœžœ˜™>šžœ žœ˜Kšžœžœ˜šžœ˜K˜šžœ žœžœž˜,K˜Kšžœ˜—šžœžœ˜Kšžœ O˜VK˜—Kšžœ ˜K˜——K˜—K˜šŸœžœžœžœ˜Ušžœžœžœ5žœ˜VK˜Kšžœ˜—Kšžœ˜ K˜K˜—šŸ œžœžœ ˜6Kš  Πbc ™"K™RJš ™šžœžœžœž˜/Kšžœžœžœžœ˜8Kšžœ˜—Jš !™!šžœžœ˜"šžœžœžœ*ž˜9K˜7š žœžœžœžœ"žœžœž˜IKšžœžœžœ ˜9Kšžœ˜—Kšžœ˜—K˜—Kš 4™4Kš 9™9Kšžœ$˜*K˜—K˜šŸ œžœ˜'šžœžœ˜šžœ%žœžœž˜6šžœ žœ˜K˜šžœžœžœ"žœ˜?K˜#—Kšž˜K˜—Kšžœ˜—K˜—K˜—K˜šŸœžœžœ˜2šžœžœžœžœ˜4K˜)K˜—Kšžœžœ˜-šžœžœžœ˜ K˜$šžœ˜šžœ˜Kš .™.šžœ3žœžœž˜FKšžœžœ"žœ˜NKšžœ˜—Kš P™PKš @™@Kšžœ˜K˜—šžœ˜Kš 1™1šžœ%žœžœž˜6šžœžœžœ˜K˜$K˜)Kšž˜K˜—Kšžœ˜—Kš ™Kš ™šžœ3žœžœž˜Fšžœžœžœ˜8K˜ K˜)Kšž˜Kšœ˜—Kšžœ˜—Kš œ  ™šžœ3žœžœž˜Fšžœ"žœžœ˜GK˜ K˜)Kšž˜Kšœ˜—Kšžœ˜—Kš ™šžœ3žœžœž˜Fšžœžœ˜"K˜ K˜)Kšž˜Kšœ˜—Kšžœ˜—Kšžœ˜K˜——K˜—K˜K˜—šŸ œžœžœ˜CK˜šžœ˜šžœ˜Kš ™Kš žœžœžœ.žœžœ ˜yKš 4™4Kš 5™5Kšžœ˜K˜—šžœ˜Kš (™(š žœžœžœžœ3žœžœž˜\Kšžœžœžœ˜&Kšžœ˜ —Kšžœ /˜6K˜——K˜K˜—š Ÿ œžœžœžœžœ˜=Kšžœ˜ K˜K˜—š Ÿ œžœžœžœžœ˜Kšžœ*žœ(˜ZK˜—K˜šŸœžœ=žœ˜YKšœP™PKšžœžœ&˜FKšžœžœ&˜FKšžœžœ0˜UKšžœ žœ2˜XKšžœ žœ2˜XKšžœžœ ˜9K˜—K˜šŸœžœ˜3šŸœžœžœ˜1Kšœf˜fK˜—Kšœžœ˜ K˜K˜+Kšœžœ ˜+Kšœ žœ˜+Kšžœ žœžœ˜šžœ žœ˜šžœžœžœ˜Kšžœžœ#˜9K˜—K˜Kšžœžœ˜CKšžœžœ˜AKšžœžœ  o˜²šžœ,žœ˜4šžœžœž˜)šœžœ!˜(K˜Q—Kšœžœ˜%Kšžœ˜—K˜—šžœ0žœ4žœ˜ošžœžœž˜-šœžœ˜ šœ$žœž˜1K˜/K˜/K˜Kšžœ)˜0—K˜—Kšœžœ˜%Kšžœ˜—K˜—šžœžœ˜&šžœžœž˜.šœžœ˜ šœ žœž˜-K˜/K˜/K˜Kšžœ)˜0—K˜—Kšœžœ˜%Kšžœ˜—K˜—K˜—Kšžœ&žœ˜FKšžœ&žœ˜FKšžœ0žœ˜UKšžœ2žœ ˜XKšžœ2žœ ˜XKšžœ žœ˜9Kš ™Kšœ*˜*Kš ™šžœžœž˜šœ ˜ Kšœ˜Kšžœžœ)˜@Kšœ,˜,Kšœ˜—šœ ˜ K˜%K˜šžœ žœžœ˜+šžœžœ˜K˜,—K˜:šžœžœ˜K˜*—K˜—Kšœ˜—šžœ˜ Kšœ˜——K˜K˜—šŸœžœ˜/K˜%K˜Kšœžœ%˜?šžœžœ žœžœ˜=K˜-K˜—K˜K˜K˜—šŸœžœ˜,K˜$K˜/K˜ΞK˜—K˜šŸœžœ˜2Kšœ˜šžœžœ˜$Kšœ0˜0—K˜—K˜šŸœžœ˜4K˜—K˜š Ÿœžœžœžœžœ˜Sš žœžœžœ'žœžœž˜GKšœ žœ˜$Kšžœžœžœ˜&Kšœžœ˜Kšžœ˜—šžœžœžœ˜!šŸ œžœžœžœ˜IKšœ,žœ˜0Kšœ˜—šžœ3žœžœž˜GKšœ žœ˜%Kšžœžœžœ˜&Kšœžœ˜Kšžœ˜—K˜—K˜K˜—šŸœžœ˜9šžœžœžœ˜Kšœ)˜)K˜—K˜—K˜šŸœžœ˜9Kšžœ˜K˜K˜—šŸœžœ˜)Kšžœ ˜&K˜—K˜šŸœžœžœ žœ˜Mšžœžœžœž˜)Kšœ˜Kšžœ žœžœ˜K˜Kšžœ˜—K˜K™—šŸœžœžœ.˜MKšžœžœžœ˜!Kšžœžœ4˜QKšžœžœ6˜TKšžœžœ*˜HKšžœžœ*˜HKšžœžœ6˜Zšžœ!žœžœ˜FKšžœžœžœ ˜9K˜—K˜K™—šŸœžœžœ1˜OKšžœžœžœ˜!Kšžœžœ˜3šžœ'žœžœ˜LKšžœžœžœ ˜9K˜—K˜K™—šŸœžœžœJ˜nšŸœžœ˜/K˜Kš žœžœžœžœ $˜>Kšœ!˜!K˜—Kšžœžœžœ˜!Kšœ#˜#Kšœ%˜%Kšœ˜K˜K™—šŸœžœžœ9žœ˜iKšœ%˜%šžœ!žœžœ˜FKšœ-˜-K˜—Kšœ˜K™—šŸœžœžœ<žœ˜kKšœ#˜#šžœ'žœžœ˜LKšœ-˜-K˜—Kšœ˜K™—šŸœž œ˜5š žœžœžœžœ-žœ˜VKšœNžœ˜TK˜—K˜K˜—šŸœžœžœ˜:Kšœžœ&˜2šžœžœ˜Kšžœžœžœ žœ(˜OK˜—K˜K™—š Ÿ œžœžœ*žœžœ˜Tšœžœ˜K˜š žœžœžœžœžœ˜@Kšœ˜K˜—Kšœ˜Kš žœžœžœ/žœžœ ˜Kšœ˜—šžœžœ˜Kšžœžœžœ žœ(˜OK˜—K˜—K˜š Ÿ œžœžœ)žœžœžœ˜ƒšŸœžœ˜3Kšžœ žœžœ!˜8Kšžœžœžœ"˜@K˜—K˜;Kšœ žœ.˜:K˜K˜"Kšœ(˜(K˜K˜—Kšœžœžœžœ˜šŸœžœžœ+žœ˜RKšœžœžœžœžœžœžœžœ˜UKšœ(˜(K˜K˜—šŸ œžœžœ5˜Mšžœ&žœž˜5Kšœžœ˜!Kšžœ˜#—Kšœ˜K™—šœžœ žœ X˜ˆK˜5K˜;K˜9K˜)K˜@—K˜Kšžœ˜K˜—…—˜ΐΜ‰