pcs/newpcs/pwindows.s

265 lines
9.6 KiB
Common Lisp
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; -*- 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)
'()))))))