-- Copyright (C) 1981, 1982, 1984 by Xerox Corporation. All rights reserved.
-- GateDMT.mesa, HGM, 1-Dec-84 18:51:34
-- From DMT.mesa of 7-Aug-81 17:33:38, updated to DMT of 24-Nov-82 8:20:42
-- Updated to DMT of 26-May-83 10:51:55
DIRECTORY
Display USING [Black, Block, MeasureBlock, replaceFlags, Text, White],
Environment USING [Block],
Exec USING [AddCommand, ExecProc],
Inline USING [LowHalf],
MouseFace USING [Point, position, SetPosition],
Process USING [
Abort, Detach, EnableAborts, priorityNormal, SecondsToTicks, SetPriority, Pause],
String USING [AppendChar],
System USING [GetClockPulses, GreenwichMeanTime],
Time USING [Current, Unpack, Unpacked],
ToolFont USING [StringWidth],
ToolWindow USING [
Activate, AdjustProcType, Create, CreateSubwindow, Deactivate,
DisplayProcType, Show, TransitionProcType],
UserInput USING [
AttentionProcType, ClearInputFocusOnMatch, SetAttention, SetInputFocus],
UserTerminal USING [
Background, hasBorder, screenHeight, screenWidth, SetBackground, SetBorder],
Window USING [
Box, Dims, GetParent, Handle, SetDisplayProc, Slide, ValidateTree],
WindowFont USING [defaultFont, FontHeight, Handle];
GateDMT: MONITOR
IMPORTS
Display, Exec, Inline, MouseFace, Process, String, System, Time,
ToolFont, ToolWindow, UserInput, UserTerminal, Window, WindowFont =
BEGIN
seed: CARDINAL;
Random: PROCEDURE [low, high: CARDINAL ← 0] RETURNS [val: CARDINAL] =
BEGIN
seed ← seed + Inline.LowHalf[System.GetClockPulses[]];
RETURN[IF high = 0 THEN seed ELSE ((seed MOD (high-low+1)) + low)];
END;
margin: CARDINAL = 4 + 4 + 4;
separation: CARDINAL = 2;
toolWindow, subWindow: Window.Handle ← NIL;
swBox: Window.Box;
running: BOOLEAN ← FALSE;
wait: CONDITION ← [timeout: Process.SecondsToTicks[5]];
bouncer: PROCESS;
Run: ENTRY PROCEDURE =
BEGIN
ENABLE UNWIND => NULL;
oldBackground: UserTerminal.Background ← UserTerminal.SetBackground[white];
IF UserTerminal.hasBorder THEN UserTerminal.SetBorder[377B, 377B];
DO
ENABLE ABORTED => EXIT;
WAIT wait;
PaintTime[Time.Current[], FALSE];
IF Random[high: 2] # 0 THEN LOOP;
Window.Slide[
subWindow,
swBox.place ← [
x: Random[high: UserTerminal.screenWidth-swBox.dims.w],
y: Random[high: UserTerminal.screenHeight-swBox.dims.h]]];
[] ← Window.SetDisplayProc[subWindow, InternalDisplay];
Window.ValidateTree[];
[] ← Window.SetDisplayProc[subWindow, EntryDisplay];
ENDLOOP;
running ← FALSE;
[] ← UserTerminal.SetBackground[oldBackground];
IF UserTerminal.hasBorder THEN UserTerminal.SetBorder[210B, 42B];
END;
EntryDisplay: ENTRY ToolWindow.DisplayProcType = {
ENABLE UNWIND => NULL; PaintTime[Time.Current[], TRUE]};
InternalDisplay: INTERNAL ToolWindow.DisplayProcType = {
PaintTime[Time.Current[], TRUE]};
-- Time Painting
displayed: RECORD [seconds: [0..60), weekday: [0..7)];
PaintTime: INTERNAL PROCEDURE [time: System.GreenwichMeanTime, all: BOOLEAN] =
BEGIN OPEN ToolFont;
font: WindowFont.Handle ← WindowFont.defaultFont;
timeWidth: CARDINAL;
unp: Time.Unpacked ← Time.Unpack[time];
s: STRING ← [8];
AppendDec2: PROCEDURE [n: CARDINAL] =
BEGIN
String.AppendChar[s, '0 + n/10];
String.AppendChar[s, '0 + n MOD 10];
END;
AppendDec2[unp.hour];
String.AppendChar[s, ':];
AppendDec2[unp.minute];
String.AppendChar[s, ':];
AppendDec2[unp.second];
timeWidth ← StringWidth[s, font];
IF all OR displayed.weekday # unp.weekday THEN
BEGIN
weekdays: STRING = "MondayTuesdayWednesdayThursdayFridaySaturdaySunday"L;
offsets: ARRAY [0..7] OF CARDINAL = [0, 6, 13, 22, 30, 36, 44, 50];
day: CARDINAL = unp.weekday;
one: CARDINAL ← margin/3;
two: CARDINAL = 2*one;
dayBlock: Environment.Block = [
LOOPHOLE[LONG[@weekdays.text]],
offsets[day], offsets[day+1]];
dayWidth: CARDINAL = Display.MeasureBlock[
window: subWindow, block: dayBlock, place: [0,0]].newPlace.x;
Display.White[subWindow, [[0, 0], swBox.dims]];
Display.Black[
subWindow, [[one, one], [swBox.dims.w - 2*one, swBox.dims.h - 2*one]]];
Display.White[
subWindow, [[two, two], [swBox.dims.w - 2*two, swBox.dims.h - 2*two]]];
[] ← Display.Block[
window: subWindow,
block: dayBlock,
place: [x: (swBox.dims.w-dayWidth)/2, y: margin],
flags: Display.replaceFlags];
END;
[] ← Display.Text[
window: subWindow,
string: s,
place: [
x: (swBox.dims.w - timeWidth)/2,
y: WindowFont.FontHeight[font] + margin + separation], font: font,
flags: Display.replaceFlags];
displayed ← [unp.second, unp.weekday];
RETURN
END;
AdjustProc: ENTRY ToolWindow.AdjustProcType = {};
AttentionProc: ENTRY UserInput.AttentionProcType = {
Process.Detach[FORK StopRunning[toolWindow]]};
StopRunning: PROCEDURE [w: Window.Handle] = {
Process.SetPriority[Process.priorityNormal];
[] ← ToolWindow.Deactivate[w]};
StartRunning: ENTRY PROC [window: Window.Handle] = {
IF running THEN RETURN;
IF subWindow = NIL THEN subWindow ← ToolWindow.CreateSubwindow[
parent: window, display: EntryDisplay, box: swBox];
UserInput.SetInputFocus[subWindow, NIL, FALSE];
UserInput.SetAttention[subWindow.GetParent[], AttentionProc];
UserInput.SetAttention[subWindow, AttentionProc];
bouncer ← FORK Run;
running ← TRUE};
TransitionProc: ToolWindow.TransitionProcType = {
ENABLE UNWIND => NULL;
SELECT new FROM
inactive, tiny => {
IF old = active THEN {
UserInput.ClearInputFocusOnMatch[subWindow];
Process.Abort[bouncer];
JOIN bouncer};
IF new = inactive THEN subWindow ← NIL};
active => IF old # active THEN StartRunning[window];
ENDCASE};
DMTCommand: Exec.ExecProc = {ToolWindow.Activate[toolWindow]};
Init: PROCEDURE =
BEGIN OPEN ToolFont;
swBox.dims.w ← StringWidth["Wednesday"L, WindowFont.defaultFont] + 2*margin;
swBox.dims.h ← 2*WindowFont.FontHeight[WindowFont.defaultFont] + 2*margin + 2;
swBox.place ← [0,0];
toolWindow ← ToolWindow.Create[
name: "GateDMT"L, adjust: AdjustProc, transition: TransitionProc,
box: [place: [0,0], dims: [w: UserTerminal.screenWidth, h: UserTerminal.screenHeight]],
initialState: active, named: FALSE];
TransitionProc[window: toolWindow, old: inactive, new: active];
ToolWindow.Show[toolWindow];
Exec.AddCommand["DMT.~"L, DMTCommand];
Process.EnableAborts[@wait];
END;
KillCopyright: PROCEDURE =
BEGIN
initialPosition: MouseFace.Point ← MouseFace.position↑;
Process.Pause[Process.SecondsToTicks[10*60]];
IF initialPosition # MouseFace.position↑ THEN RETURN;
FOR i: CARDINAL IN [100..500) DO
MouseFace.SetPosition[[i, i]];
Process.Pause[1];
ENDLOOP;
END;
Init[];
Process.Detach[FORK KillCopyright[]];
END...