DIRECTORY Buttons USING [ButtonProc, Create], CedarInitOps USING [Sleep], CedarSnapshot USING [CheckpointProc, Register, RollbackProc], ClassIncreek USING [ActionBody, GetAction, Increek, IncreekError, NewStdIncreek, SetAtLatest], Graphics, InputFocus USING [CaptureButtons, ReleaseButtons, SetInputFocus], MessageWindow USING [Append], Process USING [Abort, Pause, Seconds, SecondsToTicks], Rope USING [Equal, ROPE], TIPUser USING [TIPScreenCoords], UserProfile USING [Number], VFonts USING [defaultGFont], ViewerClasses USING [Column, NotifyProc, Viewer], ViewerOps, ViewerSpecs, VirtualDesktops, WindowManager USING [RestoreCursor], WindowManagerPrivate USING [rootViewerTree]; VirtualDesktopsImpl: CEDAR MONITOR IMPORTS Buttons, CedarSnapshot, CedarInitOps, ClassIncreek, Graphics, InputFocus, MessageWindow, Process, Rope, UserProfile, VFonts, ViewerOps, ViewerSpecs, WindowManager, WindowManagerPrivate EXPORTS VirtualDesktops SHARES ViewerClasses, ViewerOps = BEGIN OPEN ViewerClasses, VirtualDesktops; Desktop: TYPE = RECORD [ tree: ARRAY Column OF Viewer _ ALL[NIL], name: Rope.ROPE _ NIL, centerX: INTEGER _ ViewerSpecs.openLeftWidth, centerY: INTEGER _ ViewerSpecs.openBottomY ]; desktops: ARRAY [0..nVDesktops) OF Desktop ; ViewerColumn: PROC [viewer: Viewer] RETURNS [column: Column] = INLINE {RETURN[IF viewer.iconic THEN static ELSE viewer.column]}; TransferViewer: PUBLIC PROC [viewer: Viewer, from: VirtualDesktop _ currentVDesktop, to: VirtualDesktop] = BEGIN v: Viewer; column: Column ~ ViewerColumn[viewer]; current: BOOL = (desktops[from].tree=WindowManagerPrivate.rootViewerTree); IF desktops[from].tree[column]=viewer THEN BEGIN desktops[from].tree[column] _ viewer.sibling; IF current THEN WindowManagerPrivate.rootViewerTree[column] _ viewer.sibling; END ELSE FOR v _ desktops[from].tree[column], v.sibling UNTIL v.sibling=viewer DO REPEAT FINISHED => v.sibling _ v.sibling.sibling; ENDLOOP; viewer.sibling _ NIL; IF desktops[to].tree[column] = NIL THEN desktops[to].tree[column] _ viewer ELSE FOR v _ desktops[to].tree[column], v.sibling UNTIL v.sibling=NIL DO REPEAT FINISHED => v.sibling _ viewer; ENDLOOP; viewer.visible _ (to=currentVDesktop); END; FlyTo: PUBLIC ENTRY PROC [to: VirtualDesktop] = BEGIN OPEN ViewerOps; SafeStaticXfer: PROC = BEGIN s: Viewer; v: Viewer _ WindowManagerPrivate.rootViewerTree[static]; UNTIL v=NIL DO s _ v.sibling; TransferViewer[v, currentVDesktop, to]; v _ s; ENDLOOP; END; MakeVis: PROC [v: Viewer] = { IF v.parent = NIL OR (v.parent.visible AND ~v.parent.iconic) THEN v.visible _ TRUE}; MakeNotVis: PROC [v: Viewer] = {v.visible _ FALSE}; InputFocus.SetInputFocus[]; DisablePainting; IF to#currentVDesktop THEN BEGIN desktops[currentVDesktop].tree _ WindowManagerPrivate.rootViewerTree; desktops[currentVDesktop].centerX _ ViewerSpecs.openLeftWidth; desktops[currentVDesktop].centerY _ ViewerSpecs.openBottomY; SafeStaticXfer[]; WindowManagerPrivate.rootViewerTree _ desktops[to].tree; RecursivelyEnumerate[desktops[currentVDesktop].tree[left], MakeNotVis]; RecursivelyEnumerate[desktops[currentVDesktop].tree[right], MakeNotVis]; SetCenter[desktops[to].centerX, desktops[to].centerY]; currentVDesktop _ to; END; RecursivelyEnumerate[desktops[to].tree[left], MakeVis]; RecursivelyEnumerate[desktops[to].tree[right], MakeVis]; RecursivelyEnumerate[desktops[to].tree[static], MakeVis]; ResetPaintCache; EnablePainting; PaintEverything; MessageWindow.Append["Desktop: ", TRUE]; MessageWindow.Append[desktops[currentVDesktop].name]; WindowManager.RestoreCursor; END; SetCenter: PROC [x, y: INTEGER] = BEGIN OPEN ViewerSpecs; openLeftWidth _ x; openRightLeftX _ openLeftLeftX+openLeftWidth; openRightWidth _ screenW-openLeftWidth; openBottomY _ y; END; RecursivelyEnumerate: PROC [top: Viewer, p: PROC [Viewer]] = BEGIN FOR v: Viewer _ top, v.sibling UNTIL v=NIL DO p[v]; IF v.child#NIL THEN RecursivelyEnumerate[v.child, p]; ENDLOOP; END; currentVDesktop: PUBLIC VirtualDesktop _ 4; -- middle start FlyButtonProc: Buttons.ButtonProc = BEGIN paintLock _ TRUE; InputFocus.SetInputFocus[]; InputFocus.CaptureButtons[VirtualNotify, ViewerOps.FetchViewerClass[$Button].tipTable]; ViewerOps.DisablePainting; desktops[currentVDesktop].tree _ WindowManagerPrivate.rootViewerTree; -- update since changes VirtualDesktopDisplay; paintLock _ FALSE; END; lineWidth: CARDINAL = 4; VirtualDesktopDisplay: PROC = BEGIN OPEN Graphics; DrawViewer: PROC [x1, y1, x2, y2: INTEGER] = BEGIN myGrey: CARDINAL = 122645B; DrawBox[context, [x1, y1, x2, y2]]; IF x1+1 InputFocus.ReleaseButtons[]; mouse: TIPUser.TIPScreenCoords; IF paintLock THEN RETURN; FOR list: LIST OF REF ANY _ input, list.rest UNTIL list = NIL DO WITH list.first SELECT FROM x: ATOM => SELECT x FROM $Hit => IF inverted THEN BEGIN InputFocus.ReleaseButtons[]; inverted _ FALSE; context _ NIL; ViewerOps.EnablePainting; FlyTo[invertedDesktop]; END; $Mark => BEGIN desktop: VirtualDesktop _ WhichDesktop[mouse]; IF inverted THEN BEGIN IF invertedDesktop=desktop THEN RETURN; InvertDesktop[invertedDesktop]; END; InvertDesktop[invertedDesktop_desktop]; inverted _ TRUE; END; ENDCASE => NULL; -- button junk x: TIPUser.TIPScreenCoords => mouse _ x; ENDCASE => NULL; -- button junk ENDLOOP; END; VDXY: PROC [desktop: VirtualDesktop] RETURNS [x, y: INTEGER] = BEGIN x _ SELECT desktop MOD 3 FROM 0 => 0, 1 => ViewerSpecs.screenW/3+lineWidth, ENDCASE => ViewerSpecs.screenW/3+ViewerSpecs.screenW/3+lineWidth; y _ SELECT desktop/3 FROM 0 => 0, 1 => ViewerSpecs.screenH/3+lineWidth, ENDCASE => ViewerSpecs.screenH/3+ViewerSpecs.screenH/3+lineWidth; END; InvertDesktop: PROC [desktop: VirtualDesktop] = BEGIN OPEN Graphics; xc, yc: INTEGER; [xc, yc] _ VDXY[desktop]; SetColor[context, black]; [] _ SetPaintMode[context, invert]; DrawBox[context, [xc, yc, xc+ViewerSpecs.screenW/3-(IF xc=0 THEN 0 ELSE lineWidth), yc+ViewerSpecs.screenH/3-(IF yc=0 THEN 0 ELSE lineWidth)]]; END; WhichDesktop: PROC [mouse: TIPUser.TIPScreenCoords] RETURNS [desktop: VirtualDesktop] = BEGIN RETURN[mouse.mouseX/(ViewerSpecs.screenW/3) + 3*(mouse.mouseY/(ViewerSpecs.screenH/3))] END; GetName: PUBLIC PROC [vd: VirtualDesktop _ currentVDesktop] RETURNS [name: Rope.ROPE] = {RETURN[desktops[vd].name]}; SetName: PUBLIC PROC [name: Rope.ROPE, vd: VirtualDesktop _ currentVDesktop] = {desktops[vd].name _ name}; GetRoot: PUBLIC PROC [vd: VirtualDesktop _ currentVDesktop] RETURNS [viewers: ARRAY ViewerClasses.Column OF ViewerClasses.Viewer] = BEGIN desktops[currentVDesktop].tree _ WindowManagerPrivate.rootViewerTree; RETURN[desktops[vd].tree]; END; EnumerateViewers: PUBLIC PROC [enum: ViewerOps.EnumProc] = BEGIN quit: BOOLEAN _ FALSE; desktops[currentVDesktop].tree _ WindowManagerPrivate.rootViewerTree; FOR d: CARDINAL IN VirtualDesktop UNTIL quit DO FOR c: Column DECREASING IN Column UNTIL quit DO v, next: Viewer; v _ desktops[d].tree[c]; UNTIL v=NIL DO next _ v.sibling; IF ~enum[v] THEN {quit _ TRUE; EXIT}; v _ next; ENDLOOP; ENDLOOP; ENDLOOP; END; FindViewer: PUBLIC PROC [name: Rope.ROPE] RETURNS [viewer: Viewer, desktop: VirtualDesktop] = BEGIN MatchName: PROC [top: Viewer] RETURNS [Viewer] = { FOR v: Viewer _ top, v.sibling UNTIL v=NIL DO IF Rope.Equal[name, v.name, FALSE] THEN RETURN[v]; ENDLOOP; RETURN[NIL]; }; desktops[currentVDesktop].tree _ WindowManagerPrivate.rootViewerTree; FOR d: CARDINAL IN VirtualDesktop DO FOR c: Column DECREASING IN Column DO IF (viewer_MatchName[desktops[d].tree[c]])#NIL THEN RETURN [viewer, d]; ENDLOOP; ENDLOOP; RETURN [NIL, currentVDesktop]; END; idleProcess: PROCESS _ NIL; AutoIdle: PROC = TRUSTED BEGIN ENABLE ANY => GOTO Punt; -- punt if bad number or ABORTED increek: ClassIncreek.Increek; action: ClassIncreek.ActionBody; idleTime: Process.Seconds; idleTime _ 60 * UserProfile.Number["AutoIdleTimeout", 20]; IF idleTime<=0 THEN RETURN; increek _ ClassIncreek.NewStdIncreek[]; DO -- forever ClassIncreek.SetAtLatest[increek]; Process.Pause[Process.SecondsToTicks[idleTime]]; action _ ClassIncreek.GetAction[increek, dontWait, ----, clicksAndMotion ! ClassIncreek.IncreekError => LOOP]; WITH a: action SELECT FROM timedOut => CedarInitOps.Sleep[]; -- idle ENDCASE; ENDLOOP; EXITS Punt => NULL; END; IdleOn: CedarSnapshot.RollbackProc = BEGIN idleProcess _ FORK AutoIdle[]; END; IdleOff: CedarSnapshot.CheckpointProc = TRUSTED BEGIN Process.Abort[idleProcess]; JOIN idleProcess; idleProcess _ NIL; END; IdleProc: Buttons.ButtonProc = TRUSTED {CedarInitOps.Sleep[]}; [] _ Buttons.Create[info: [name: "Idle"], proc: IdleProc, fork: TRUE, documentation: "Hide desktop pending user login"]; -- [] _ Buttons.Create[info: [name: "Fly"], proc: FlyButtonProc, fork: TRUE, -- documentation: "Display virtual desktops"]; desktops[0].name _ "Zero"; desktops[1].name _ "One"; desktops[2].name _ "Two"; desktops[3].name _ "Three"; desktops[4].name _ "Four"; desktops[5].name _ "Five"; desktops[6].name _ "Six"; desktops[7].name _ "Seven"; desktops[8].name _ "Eight"; TRUSTED {CedarSnapshot.Register[IdleOff, IdleOn]; IdleOn[rollback]}; END. „VirtualDesktopsImpl.mesa; Edited by McGregor on October 26, 1982 1:12 pm Last Edited by: Maxwell, January 21, 1983 8:56 am Κ œ– "Mesa" style˜JšΟc™Jš.™.J™1J™šΟk ˜ Jšœžœ˜#Jšœ žœ ˜Jšœžœ*˜=Jšœ žœL˜^J˜ Jšœ žœ1˜AJšœžœ ˜Jšœžœ)˜6Jšœžœ žœ˜Jšœžœ˜ Jšœ žœ ˜Jšœžœ˜Jšœžœ˜1J˜ J˜ J˜Jšœžœ˜$Jšœžœ˜,J˜—Jšœž ˜"J˜šžœ5˜˜MJšž˜—šžœžœ,žœž˜MJšžœžœ"˜1Jšžœ˜—Jšœžœ˜Jšžœžœžœ#˜Jš žœžœ*žœ žœž˜HJšžœžœ˜&Jšžœ˜—J˜&Jšžœ˜J˜—Jš Ÿœžœžœžœžœžœ ˜E˜šŸœžœž˜J˜ J˜8šžœžœž˜J˜Jšœ'˜'J˜Jšžœ˜—Jšžœ˜—J˜šŸœžœbžœ˜uJ˜—šŸ œžœžœ˜3J˜—J˜J˜J˜šžœžœž˜ J˜EJ˜>J˜J˜šœ@žœ˜EJ˜2—šœGžœ˜LJ˜.J˜—J˜J˜J˜J˜J˜J˜J˜J˜J˜J˜Jšžœ>˜EJšžœ˜J˜J˜—…—(Ά4Φ