-- ColorDisplay.mesa
-- Last edit by Maureen Stone, June 9, 1982 4:04 pm
-- Last edit by Doug Wyatt, 10-Jul-81 0:50:42
DIRECTORY
Inline USING [LongMult],
UserTerminal USING [CursorArray];
ColorDisplay: DEFINITIONS
IMPORTS Inline = {
-- Processor-independent interface to color display.
-- Types
Mode: TYPE = RECORD[full: BOOLEAN, bitsPerPixelA,bitsPerPixelB: [0..8]];
-- Mode encodes the possible color display modes.
-- full=TRUE specifies 24 bit per pixel mode; the other fields are ignored
-- full=FALSE specifies a mapped mode with one or two bitmaps, each with the given
-- number of bits per pixel. Acceptable values are 0 (no bitmap), 1, 2, 4, or 8.
-- Not all modes are implemented on a particular processor; see HasMode, below.
disconnected: Mode = [FALSE,0,0];
-- The initial mode, with the color display entirely disabled.
-- Setting this mode releases the resources used by the color display.
-- Processors lacking color displays have only this mode.
Byte: TYPE = [0..256);
Pair: TYPE = MACHINE DEPENDENT RECORD[r,g: Byte];
ByteSeq: TYPE = RECORD[PACKED SEQUENCE COMPUTED CARDINAL OF Byte];
PairSeq: TYPE = RECORD[PACKED SEQUENCE COMPUTED CARDINAL OF Pair];
CursorArray: TYPE = UserTerminal.CursorArray;
Coordinate: TYPE = MACHINE DEPENDENT RECORD [x, y: INTEGER];
-- The cursor mode indicates whether, given a bit=1 in the cursor array,
-- the corresponding pixel value is set to all ones or all zeros. For 24 bpp mode
-- and the conventional color maps, the correspondence is ones=white and zeros=black.
CursorMode: TYPE = {ones,zeros};
-- Interface variables
pixelsPerInch: READONLY CARDINAL; -- size of a pixel
displayType: READONLY CARDINAL; -- display type; 0 means display not available
mixedRG: READONLY BOOLEAN; -- red and green interleaved in 24 bit mode
-- The following variables may be changed by SetMode!
curmode: READONLY Mode; -- the current mode
width,height: READONLY CARDINAL; -- size of raster in current mode
baseA,baseB,baseC: READONLY LONG POINTER; -- bitmap address
wplA,wplB,wplC: READONLY CARDINAL; -- bitmap words per line
cursorPosition: READONLY LONG POINTER TO Coordinate;
cursorWidth: READONLY INTEGER; --defined as 16 for now
cursorHeight: READONLY INTEGER; --defined as 16 for now
-- Procedures
HasMode: PROCEDURE[mode: Mode] RETURNS[BOOLEAN];
-- Return TRUE if the specified mode is available.
GetMode: PROCEDURE RETURNS[Mode] = INLINE { RETURN[curmode] };
-- Return the current mode.
SetMode: PROCEDURE[mode: Mode] RETURNS[BOOLEAN];
-- Establish the specified mode. Allocate bitmap and colormap storage as necessary.
-- Return TRUE if successful, FALSE if mode is not available.
-- Subsequent bitmap or colormap changes will affect the color image,
-- but the image will not appear on the screen until TurnOn is called.
-- If mode=disconnected, disable the color display, releasing all storage.
-- All following procedures should be used only when GetMode[]#disconnected.
TurnOn: PROCEDURE;
-- Turn the display on, causing an image to appear on the screen.
TurnOff: PROCEDURE;
-- Turn the display off, causing the screen to be dark.
-- The display's storage is retained; the image will reappear if TurnOn is called.
Show: PROCEDURE[a,b,c: BOOLEAN ← TRUE];
-- Make the specified bitmap visible (TRUE) or invisible (FALSE).
-- Procedures for mapped modes (mode.full=FALSE)
GetColor: PROCEDURE[pixelA,pixelB: CARDINAL ← 0] RETURNS[r,g,b: Byte];
-- Return the current color map entry for the given pixel value(s).
SetColor: PROCEDURE[pixelA,pixelB: CARDINAL ← 0, r,g,b: Byte];
-- Set the color map entry for the given pixel value(s).
-- If the display is 'on', the screen will show the change by the next frame time.
-- Procedures for manipulating the cursor
SetCursorPattern: PROC [cursorPattern: CursorArray];
GetCursorPattern: PROCEDURE RETURNS [cursorPattern: CursorArray];
SetCursorPosition: PROCEDURE [newMousePosition: Coordinate];
SetCursorMode: PROC [color: CursorMode];
--the cursor must be hidden and restored when the area of the
--framebuffer occupied by the cursor is changed.
HideCursor: PROC; --restore the frame buffer
RestoreCursor: PROC; --draw the cursor at its last position
--the cursor must be locked while a scanline is being drawn
--ONLY ColorDeviceImpl should call these two procedures
SetLock: PROC;
ClearLock: PROC;
--called ONLY by ColorDisplayImpl to indicate that the display mode changed
NotifyCursor: PROC;
-- Procedures for 24 bit per pixel mode (mode.full=TRUE)
InBounds: PROC[x,y: CARDINAL] RETURNS[BOOLEAN] = INLINE {
RETURN[curmode.full AND x<width AND y<height] };
GetR: PRIVATE PROC[x,y: CARDINAL] RETURNS[Byte] = INLINE { IF mixedRG
THEN RETURN[LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO PairSeq][x].r]
ELSE RETURN[LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO ByteSeq][x]] };
GetG: PRIVATE PROC[x,y: CARDINAL] RETURNS[Byte] = INLINE { IF mixedRG
THEN RETURN[LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO PairSeq][x].g]
ELSE RETURN[LOOPHOLE[baseB + Inline.LongMult[wplB,y],LONG POINTER TO ByteSeq][x]] };
GetB: PRIVATE PROC[x,y: CARDINAL] RETURNS[Byte] = INLINE { IF mixedRG
THEN RETURN[LOOPHOLE[baseB + Inline.LongMult[wplB,y],LONG POINTER TO ByteSeq][x]]
ELSE RETURN[LOOPHOLE[baseC + Inline.LongMult[wplC,y],LONG POINTER TO ByteSeq][x]] };
SetR: PRIVATE PROC[x,y: CARDINAL, r: Byte] = INLINE { IF mixedRG
THEN LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO PairSeq][x].r ← r
ELSE LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO ByteSeq][x] ← r };
SetG: PRIVATE PROC[x,y: CARDINAL, g: Byte] = INLINE { IF mixedRG
THEN LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO PairSeq][x].g ← g
ELSE LOOPHOLE[baseB + Inline.LongMult[wplB,y],LONG POINTER TO ByteSeq][x] ← g };
SetB: PRIVATE PROC[x,y: CARDINAL, b: Byte] = INLINE { IF mixedRG
THEN LOOPHOLE[baseB + Inline.LongMult[wplB,y],LONG POINTER TO ByteSeq][x] ← b
ELSE LOOPHOLE[baseC + Inline.LongMult[wplC,y],LONG POINTER TO ByteSeq][x] ← b };
GetPixel: PUBLIC PROC[x,y: CARDINAL] RETURNS[r,g,b: Byte] = INLINE {
IF InBounds[x,y] THEN RETURN[r: GetR[x,y], g: GetG[x,y], b: GetB[x,y]]
ELSE RETURN[0,0,0] };
-- Return the color of the pixel at coordinates (x,y).
-- The pixel with coordinates (0,0) is at the upper left corner of the screen.
-- Returns [0,0,0] if x or y is out of range.
SetPixel: PUBLIC PROC[x,y: CARDINAL, r,g,b: Byte] = INLINE {
IF InBounds[x,y] THEN { SetR[x,y,r]; SetG[x,y,g]; SetB[x,y,b] } };
-- Set the pixel at coordinates (x,y) to the specified color.
-- The pixel with coordinates (0,0) is at the upper left corner of the screen.
-- Ignored if x or y is out of range.
SetRed: PUBLIC PROC[x,y: CARDINAL, value: Byte] = INLINE {
IF InBounds[x,y] THEN SetR[x,y,value] };
SetGreen: PUBLIC PROC[x,y: CARDINAL, value: Byte] = INLINE {
IF InBounds[x,y] THEN SetG[x,y,value] };
SetBlue: PUBLIC PROC[x,y: CARDINAL, value: Byte] = INLINE {
IF InBounds[x,y] THEN SetB[x,y,value] };
-- Set red, green, or blue value for a pixel independently.
GetRedMap,GetGreenMap,GetBlueMap: PROCEDURE[in: Byte] RETURNS[out: Byte];
-- Return the current entry from the red, green, or blue map.
SetRedMap,SetGreenMap,SetBlueMap: PROCEDURE[in,out: Byte];
-- Set an entry in the red, green, or blue map.
-- If the display is 'on', the screen will show the change by the next frame time.
}.