pcs/newpcs/pwindows.s

265 lines
9.6 KiB
ArmAsm
Raw Permalink Normal View History

2023-05-20 05:57:05 -04:00
; -*- Mode: Lisp -*- Filename: pwindows.s
; Last Revision: 10-Oct-85 1500ct
;--------------------------------------------------------------------------;
; ;
; TI SCHEME -- PCS Compiler ;
; Copyright 1985 (c) Texas Instruments ;
; ;
; John Jensen ;
; ;
; Window Manipulation Routines ;
; ;
;--------------------------------------------------------------------------;
;;; MAKE-WINDOW returns a "default" window object with the following
;;; attributes:
;;;
;;; Upper Left Hand Corner = 0,0
;;; Size (Lines, Columns) = 25,80 or 30,80 (the entire screen)
;;; Cursor Position = 0,0
;;; Text Color = White (on IBM, high intensity white)
;;; Border Color (if bordered) = Green (on IBM, low intensity green)
;;; Transcript Recording = Enabled
(define make-window ; MAKE-WINDOW
(lambda args
(let ((label (car args))
(bordered? (cadr args)))
(if (or (null? label) (string? label))
(let ((window (%make-window label)))
(when bordered?
(%reify-port! window 6 (if (eqv? pcs-machine-type 1)
#b00001100 ; TIPC green
#b00001010))) ; IBM green
window)
(begin
(%error-invalid-operand 'MAKE-WINDOW label)
'())))))
;;; WINDOW-CLEAR erases the data portion of a window (writes blanks using
;;; the current text attributes) and positions the cursor in position
;;; 0,0 (the upper left hand corner of the window). If the window is
;;; bordered, the border is re-drawn by this operation. This operation
;;; more properly may be considered a "window-initialize" operation.
(define WINDOW-CLEAR ; WINDOW-CLEAR
(lambda (window)
(if (or (window? window) (null? window))
(%clear-window window)
(begin
(%error-invalid-operand 'WINDOW-CLEAR window)
'()))))
;;; The "delete-window" function completely erases the area of the CRT which
;;; is covered by a given window, including the borders. This function
;;; accomplishes the erasing of the borders by expanding the dimensions
;;; of the window (temporarily) so that the borders are included in the
;;; data portion of the window; setting the border attribute to "no
;;; border"; and issuing a "%clear-window" operation to clear the text
;;; portion of the (temporarily) expanded window. After clearing the
;;; window and border, the original attributes of the window are
;;; restored.
;;;
;;; Note: when expanding the size of the window to account for the
;;; right and bottom borders, this routine takes advantage of the fact
;;; that %reify-port will not allow a window's boundaries to be set
;;; to be larger than the physical device size. Therefore, no check
;;; is performed to see if the right and bottom borders are off the
;;; screen.
(define WINDOW-DELETE ; DELETE-WINDOW
(lambda (window)
(if (or (window? window) (null? window))
(if (eqv? (%reify-port window 6) -1)
(%clear-window window) ; if not bordered, just do a %clear-window
(let ((ul-line (%reify-port window 2)) ; save current attributes
(ul-col (%reify-port window 3)) ; for later restoration
(n-lines (%reify-port window 4))
(n-cols (%reify-port window 5))
(b-attrib (%reify-port window 6))
(t-lines '())
(t-cols '()))
(begin
(when (> ul-line 0)
(begin ; increase window size to include top border
(%reify-port! window 2 (-1+ ul-line))
(%reify-port! window 4 (1+ n-lines))))
(when (> ul-col 0)
(begin ; increase window size to include left border
(%reify-port! window 3 (-1+ ul-col))
(%reify-port! window 5 (1+ n-cols))))
(set! t-lines (%reify-port window 4)) ; get new window size
(set! t-cols (%reify-port window 5))
(%reify-port! window 4 (1+ t-lines)) ; include bottom border
(%reify-port! window 5 (1+ t-cols)) ; include right border
(%reify-port! window 6 -1) ; indicate no border
(%clear-window window)
(%reify-port! window 2 ul-line) ; restore the original
(%reify-port! window 3 ul-col) ; attributes to the user's
(%reify-port! window 4 n-lines) ; window
(%reify-port! window 5 n-cols)
(%reify-port! window 6 b-attrib))))
(begin
(%error-invalid-operand 'WINDOW-DELETE window)
'()))))
;;; WINDOW-GET-POSITION conses the coordinates of the upper left hand
;;; position of a window into a pair as: (line . column)
(define WINDOW-GET-POSITION ; WINDOW-GET-POSITION
(lambda (window)
(if (or (window? window) (null? window))
(cons (%reify-port window 2) (%reify-port window 3))
(begin
(%error-invalid-operand 'WINDOW-GET-POSITION window)
'()))))
;;; WINDOW-GET-SIZE conses the number of lines and columns in a window
;;; (excluding the border columns, if any) into a pair as:
;;; (lines . columns)
(define WINDOW-GET-SIZE ; WINDOW-GET-SIZE
(lambda (window)
(if (or (window? window) (null? window))
(cons (%reify-port window 4) (%reify-port window 5))
(begin
(%error-invalid-operand 'WINDOW-GET-SIZE window)
'()))))
;;; WINDOW-GET-CURSOR conses the line and column number of the current
;;; cursor position into a pair as: (line . column)
(define WINDOW-GET-CURSOR ; WINDOW-GET-CURSOR
(lambda (window)
(if (or (window? window) (null? window))
(cons (%reify-port window 0) (%reify-port window 1))
(begin
(%error-invalid-operand 'WINDOW-GET-CURSOR window)
'()))))
;;; The following routines modify the position, size, and cursor position
;;; of a window by side effecting the appropriate fields in a window
;;; object. An argument value of '() indicates that a particular
;;; field's value is to remain unchanged.
(define WINDOW-SET-POSITION!)
(define WINDOW-SET-SIZE!)
(define WINDOW-SET-CURSOR!)
(letrec ((chk-and-set
(lambda (window line column instruction-name L C)
(cond
((not (or (window? window) (null? window)))
(error (string-append "Invalid Window Argument to "
(symbol->string instruction-name))
window))
((and line
(or (not (integer? line))
(negative? line)))
(error (string-append "Invalid Line Number to "
(symbol->string instruction-name))
line))
((and column
(or (not (integer? column))
(negative? column)))
(error (string-append "Invalid Column Number to "
(symbol->string instruction-name))
column))
(else
(when line (%reify-port! window L line))
(when column (%reify-port! window C column))
window)))))
(set! WINDOW-SET-POSITION! ; WINDOW-SET-POSITION!
(lambda (window ul-line ul-col)
(chk-and-set window ul-line ul-col
'WINDOW-SET-POSITION! 2 3)))
(set! WINDOW-SET-SIZE! ; WINDOW-SET-SIZE!
(lambda (window n-lines n-cols)
(chk-and-set window n-lines n-cols
'WINDOW-SET-SIZE! 4 5)))
(set! WINDOW-SET-CURSOR! ; WINDOW-SET-CURSOR!
(lambda (window cur-line cur-col)
(chk-and-set window cur-line cur-col
'WINDOW-SET-CURSOR! 0 1))))
;;; Pop-Up window manipulation.
;;;
;;; "WINDOW-POPUP" preserves the data on the screen which will be
;;; covered by the pop-up window, initializes the window, and
;;; returns the pop-up window object to the caller.
;;;
;;; "WINDOW-POPUP-DELETE" restores the region of the CRT covered by a
;;; window created "WINDOW-POPUP" to its state prior to the
;;; pop-up window's appearance.
(define WINDOW-POPUP)
(define WINDOW-POPUP-DELETE)
(let ((pop-up-list '()))
(begin
(set! WINDOW-POPUP ; WINDOW-POPUP
(lambda (window)
(if (or (window? window) (null? window))
(begin
(set! pop-up-list
(cons (cons window (window-save-contents window)) pop-up-list))
(window-delete window)
(%clear-window window)
window)
(begin
(%error-invalid-operand 'WINDOW-POPUP window)
'()))))
(set! WINDOW-POPUP-DELETE ; WINDOW-POPUP-DELETE
(lambda (window)
(let ((saved-data (assq window pop-up-list)))
(when (not (null? saved-data))
(window-restore-contents window (cdr saved-data))
(set! pop-up-list (delq! saved-data pop-up-list))
window)))) ))
;;; The following routines get and set window attributes which are not
;;; modifiable by any of the above routines. It is necessary to explicitly
;;; name the attribute you wish to examine/modify.
(define WINDOW-GET-ATTRIBUTE)
(define WINDOW-SET-ATTRIBUTE!)
(letrec ((attr-list '((border-attributes . 6)
(text-attributes . 7)
(window-flags . 8)))
(check-and-map-args
(lambda (window attribute)
(if (or (window? window) (null? window))
(cdr (assq attribute attr-list))
#!FALSE))))
(set! WINDOW-GET-ATTRIBUTE
(lambda (window attribute)
(let ((mapped-attribute (check-and-map-args window attribute)))
(if mapped-attribute
(%reify-port window mapped-attribute)
(begin
(%error-invalid-operand-list 'WINDOW-GET-ATTRIBUTE
window attribute)
'())))))
(set! WINDOW-SET-ATTRIBUTE!
(lambda (window attribute value)
(let ((mapped-attribute (check-and-map-args window attribute)))
(if (and mapped-attribute
(integer? value)
(< value #x3fff)
(> value #x-3fff))
(%reify-port! window mapped-attribute value)
(begin
(%error-invalid-operand-list 'WINDOW-SET-ATTRIBUTE!
window attribute value)
'()))))))