-- ColorWorldImpl.mesa
-- Public interfaces to start and stop the color display and color cursor
-- Maureen Stone, July 21, 1982 11:57 am
-- Doug Wyatt, September 1, 1982 3:52 pm

DIRECTORY
Graphics USING [Context, NewContext],
Interminal USING [TurnOnColorCursor, TurnOffColorCursor],
ColorDevice USING [New],
ColorDisplay USING [Mode, HasMode, SetMode, TurnOn, disconnected],
ColorPackagePrivate USING [DeviceProc],
ColorMap USING [StandardMap, SetGamma],
ColorWorld USING [];

ColorWorldImpl: CEDAR PROGRAM
IMPORTS Interminal, ColorDevice, Graphics, ColorDisplay, ColorMap
EXPORTS ColorWorld, ColorPackagePrivate = {

colorOn: BOOLEANFALSE;

--valid values for bpp (bits per pixel) are:
--Dolphins: 1, 2 or 4
--Dorados: 1, 4, 8 and 24
--Turn on color is expensive. It will take about 10 seconds worse case
--If you call it more than once it will automatically do a TurnOffColor
HasMode: PUBLIC PROCEDURE[bpp: INT] RETURNS[BOOLEAN] = TRUSTED {
RETURN[(SELECT bpp FROM
1 => ColorDisplay.HasMode[[full: FALSE, bitsPerPixelA: 1, bitsPerPixelB: 0]],
2 => ColorDisplay.HasMode[[full: FALSE, bitsPerPixelA: 2, bitsPerPixelB: 0]],
4 => ColorDisplay.HasMode[[full: FALSE, bitsPerPixelA: 4, bitsPerPixelB: 0]],
8 => ColorDisplay.HasMode[[full: FALSE, bitsPerPixelA: 8, bitsPerPixelB: 0]],
24 => ColorDisplay.HasMode[[full: TRUE, bitsPerPixelA: 0, bitsPerPixelB: 0]],
ENDCASE => FALSE)];
};

TurnOnColor: PUBLIC PROC[bpp: INT, onLeft: BOOLEANTRUE] RETURNS[BOOLEAN] = {
ok: BOOLEANFALSE;
mode: ColorDisplay.Mode ← (IF bpp=24 THEN [TRUE,0,0] ELSE[FALSE,bpp,0]);
TRUSTED { ok ← ColorDisplay.SetMode[mode] };
IF ok THEN {
 ColorMap.SetGamma[2.2];
IF bpp # 24 THEN ColorMap.StandardMap[];
TRUSTED {ColorDisplay.TurnOn[]};
TRUSTED {Interminal.TurnOnColorCursor[bpp,onLeft]};
colorOn ← TRUE;
};
RETURN[ok];
};

--TurnOffColor jumps the cursor back to the bi-level display and deallocates the
--color framebuffer.
TurnOffColor: PUBLIC PROC = {
TRUSTED {Interminal.TurnOffColorCursor[]};
TRUSTED {[] ← ColorDisplay.SetMode[ColorDisplay.disconnected]};
colorOn ← FALSE;
};

NewProc: ColorPackagePrivate.DeviceProc ← ColorDevice.New;
SetNewContextProc: PUBLIC PROC[new: ColorPackagePrivate.DeviceProc] = {NewProc ← new};

NewContext: PUBLIC PROC RETURNS[Graphics.Context] = {
IF ~colorOn THEN RETURN[NIL]
ELSE RETURN[Graphics.NewContext[NewProc[]]];
};

}.