;;; $Header: /ct/debug/windowfnc.l,v 1.20 84/01/26 16:01:23 susan Exp $ ;;; $Log: /ct/debug/windowfnc.l,v $ ;;;Revision 1.20 84/01/26 16:01:23 susan ;;;Made all vms/unix dependencies happen at runtime. ;;; ;;;Revision 1.19 84/01/07 11:46:01 susan ;;;Removed a couple of local function definitions from the file. ;;; ;;;Revision 1.18 84/01/06 13:40:06 susan ;;;Changed db%get_files to know whether the file has to exist ;;; ;;;Revision 1.17 83/12/16 13:43:03 susan ;;;Revitalized the ability to dump the screen to a file. ;;; ;;;Revision 1.16 83/12/12 16:50:22 susan ;;;Changed ct_send to ct_csend and added calls to get-iv and ;;;set-iv. Fixed cursor movement so that it doesn't echo ;;;in the command line (db%bottom_mode_line). ;;; ;;;Revision 1.15 83/11/28 16:13:55 susan ;;;Made *db%blanks* 79 rather than 80 characters, this ;;;seems to make curses happy---UGH! ;;; ;;;Revision 1.14 83/11/10 17:17:41 susan ;;;Changed all sorts of things...made db%change_mode_line ;;;work correctly. Echo the first character in a command and ;;;then echo the entire command before a . Give ;;;a warning message if a isn't given after a command, ;;;but force the user to explicitly blow it off. ;;;Change db%user_interface_error and db%throw_control_g to ;;;see if *db%user_window* has a curses-window and if not ;;;to write error messages to *db%output_window*. ;;; ;;;Revision 1.13 83/10/26 10:46:08 susan ;;;Fixed db%screen_refresh to actually do the right thing. ;;; Took away all arguments to this function. ;;; ;;;Revision 1.12 83/10/25 17:13:35 susan ;;;Caused commands to be echoed before the carriage ;;;return is hit so that the user can check before ;;;actually entering the command. ;;;Played around with db%change_mode_line ;;; ;;;Revision 1.11 83/10/19 17:00:38 susan ;;;Commented out the loading of Peter's dump to screen pgm. ;;; ;;;Revision 1.10 83/10/18 12:45:23 susan ;;;Changed *help_file* to *db%help_file* and moved where the ;;;file lives to a different place. ;;; ;;;Revision 1.9 83/10/18 11:43:39 susan ;;;Fixed calling variables within loop 'char' when then ;;;should have been 'number' under db%wgetchn and db%wgetchns ;;; ;;;Revision 1.8 83/10/17 02:34:16 susan ;;;Added (wmove window 0 0) before adding the db%blanks ;;;to clear out a mode line ;;; ;;;Revision 1.7 83/10/17 01:01:50 susan ;;;Fixed curses strangeness by removing a (wclear window) ;;;in db%change_mode_line and adding a (wmove window 0 0) ;;;before adding the string of db%blanks to the window. ;;; ;;;Revision 1.6 83/10/16 20:03:26 susan ;;;Allow for capital letters ;;; ;;;Revision 1.5 83/10/16 14:02:58 susan ;;;Fixed non-matching parentheses ;;; ;;;Revision 1.4 83/10/16 11:40:09 susan ;;;Changed functions to handle echoing myself rather ;;;than having echo turned on. ;;; ;;;Revision 1.3 83/10/12 16:30:23 susan ;;;Made the loading of Peter's dump_to_screen file and ;;;execution of the function contigent on the fact that ;;;we're on the Unix Vax ;;; ;;;Revision 1.2 83/10/12 11:53:09 susan ;;;Revised handling of arrow keys to not go back and refresh ;;;the "Command: " line...stops the jumping back and forth between ;;;windows. ;;;Also, added a ct_load of 'dumpscrint, Peter's dump_to_screen function ;;;to be used with debugging ;;; ;;;Revision 1.1 83/10/09 11:10:59 susan ;;;Initial revision ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ;;; WINDOW_FNC ;;; ;;; ;;; ;;; Susan Rosenbaum August, 1983 ;;; ;;; ;;; ;;; Functions for managing the user interface. Does all of the ;;; ;;; decision making process as to whether a particular key is ;;; ;;; acceptable as input to the current function. ;;; ;;; ;;; ;;; This file is part of a proprietary software project. Source ;;; ;;; code and documentation describing implementation details are ;;; ;;; available on a confidential, non-disclosure basis only. These ;;; ;;; materials, including this file in particular, are trade secrets ;;; ;;; of Computer * Thought Corporation. ;;; ;;; ;;; ;;; (c) Copyright 1982 and 1983, Computer * Thought Corporation. ;;; ;;; All Rights Reserved. ;;; ;;; ;;; ;;; Reference materials: ;;; ;;; Foderaro and Sklower, The FRANZ LISP Manual, September 1981. ;;; ;;; Weinreb and Moon, LISP MACHINE MANUAL, Symbolics, July 1981. ;;; ;;; Charniak et al., 1980. Artificial Intelligence Programming. ;;; ;;; Miller, 1982. The C*T Ada Tutor: Guide to the Implementation. ;;; ;;; ;;; ;;; The following code assumes familiarity with these materials. ;;; ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Ensure presence of needed files. (comment Assumes ct_load and some suitable file_map are present) (eval-when (compile load eval) (ct_load 'aip)) ;AIP macros pkg. (eval-when (compile load eval) (ct_load 'compat)) ;Franz/LM compat pkg. (eval-when (compile load eval) (ct_load 'ctstrl)) ;;Bill's string stuff (eval-when (compile load eval) (ct_load 'dbutils));;debugger utils. (eval-when (compile load eval) (ct_load 'ctflav)) ; ; flavor stuff (eval-when (compile load eval) (ct_load 'scroll)) ; ; db%debug_window ; ; methods #+franz (eval-when (compile load eval) (ct_load 'format)) ; Print formating ;;load this dump-to-screen file specifically when we want it, not ;;all of the time ;; #+(and franz ;; (not vms)) ;; (eval-when (compile load eval) (ct_load 'dumpscrint));;dumpto screen ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Compiler Declarations and Global Variables -- #+franz (declare (macros t)) #+franz (setq *flavor-expand-macros* t) ; declare the local functions to this file #+franz (declare (localf db%wgetch db%wgetchn db%wgetchns db%screen_snapshot db%screen_refresh db%throw_control_g)) ;;;Constants corresponding to the ascii code for ;;;the control characters that are handled (defconst control_g 7) (defconst control_h 8) (defconst control_l 12) (defconst control_u 21 ) (defconst *slash* 47 ) (defconst left_bracket #+franz 91 #+lispm 133) (defconst question_mark 63 ) ;;;maximum number of lines for a window (defvar *db%lines* 24) ;;;maximum number of columns for a window (defvar *db%cols* 80) ;;;keep track of the current location on the screen when ;;;prompting the user for a series of intormation (defvar *db%current_line* 0) (defvar *db%current_col* 0) ;;;the file that is displayed in the *db%user_window* when a ;;;? or help-me is typed (defconst *db%help_file* (cond ((and (status feature unix) (status feature vms)) "sys$ctada:help.fil") ((and (status feature unix) (status nofeature vms)) "/ct/debug/help.fil") ((status feature lispm) "bigbird://ct//debug//help.fil"))) (declare (special *db%echop* *db%doing_command* *db%user_window* *db%menu_command_list* *db%single_screen_command_list* *db%window_command_list* *db%debugger_command_list* *db%bottom_mode_line* *db%current_window* *db%command_string* *db%current_file* *db%top_mode_line* *db%output_window* *current_exposed_window_list*)) ;;;used on the mode lines to cause a reverse video on the entire screen (declare (special *db%blanks*)) (setq *db%blanks* "") (loop for i from 1 to 79 do (setq *db%blanks* (ct_string_append " " *db%blanks*))) ;;;;;;;;;;;;;;;;;;;;;;; ;;;INTERNAL/EXTERNAL FUNCTIONS ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; (defun db%wgetch (window) ;;;;;;;;; #|Get a character from the given window...the legal characters are return, linefeed, rubout, backspace, and all printable characters |# (loop for char = (wgetch window) if (and (status feature debugging) (equal char control_h)) ;do we want a picture do (db%screen_snapshot window) else if (equal char control_l) ;refresh wanted? do (db%screen_refresh) else if (and (equal char control_g) *db%doing_command*) do (db%throw_control_g) else if (or ;legal character? (eq char #\return) (eq char #\linefeed) (eq char #\rubout) (eq char #\backspace) (eq char #\space) (and (>= char 32) (< char 127))) do (return char))) ;;;;;; (defun db%tyi (window) ;;;;;; #|Get a character from the given window for the ct_tyi function. Everything except control_h and control_l are returned with no outlawing of input characters. |# (loop for char = (wgetch window) if (and (status feature debugging) (equal char control_h)) ;do we want a picture do (db%screen_snapshot window) ;;of the screen? else if (equal char control_l) ;refresh wanted? do (db%screen_refresh) else do (return char))) ;;;;;;;;;; (defun db%wgetchn (window) ;;;;;;;;;; #| Get a number from the given window. The legal characters handled here are return, linefeed, rubout, backspace, and 0-9. |# (loop for number = (wgetch window) if (and (status feature debugging) (equal number control_h)) ;is a picture wanted? do (db%screen_snapshot window) else if (equal number control_l) ;is a refresh wanted? do (db%screen_refresh) else if (and (equal number control_g) *db%doing_command*) do (db%throw_control_g) else if (or (eq number #\return) (eq number #\linefeed) (eq number #\rubout) (eq number #\backspace) (and (> number *slash*) ;;a "/" (< number #/:))) do (return number))) ;;;;;;;;;;; (defun db%wgetchns (window) ;;;;;;;;;;; #| Get numbers from the given window. The legal characters handled here are return, linefeed, space, rubout, backspace, and 0-9, + and - |# (loop for number = (wgetch window) if (and (status feature debugging) (equal number control_h)) ;is a picture wanted? do (db%screen_snapshot window) else if (equal number control_l) ;is a refresh wanted? do (db%screen_refresh) else if (and (equal number control_g) *db%doing_command*) do (db%throw_control_g) else if (or ;legal number? (eq number #\return) (eq number #\linefeed) (eq number #\rubout) (eq number #\space) (eq number #\backspace) (eq number #/+) (eq number #/-) (and (> number *slash*) ;;a "/" (< number #/:))) do (return number))) ;;;;;;;;;;;;;; (defun db%wgetcommand (window) ;;;;;;;;;;;;;; #| Get a command from the user...either a debugger command or a screen handling request--returns a list containing the 2-letter command input by the user |# (loop for char = (wgetch window) with return_value = nil if (and (status feature debugging) (equal char control_h)) do (db%screen_snapshot window) else if (equal char control_l) do (db%screen_refresh) else if (equal char question_mark) do (ct_csend db%debug_window *db%user_window* :add-file *db%help_file*) else ;;perhaps a debugger command do (progn (setq return_value (db%wgetcommand_char window char)) (ct_if (not (equal return_value 'arrow)) (return return_value))))) ;;;;;;;;;;;;;;;;;;; (defun db%wgetcommand_char (window char) ;;;;;;;;;;;;;;;;;;; #|Get a character from the given window with which to complete a debugger command..the legal characters are a-z, arrow keys, and control-g. 'char will be passed in and the rest must be input in this function |# (loop for char1 = char with char2 = nil with char3 = nil if (not (equal char1 #\esc)) do (progn (wstandout window) (waddch window (ct_char_upcase char1)) (wrefresh window) (wstandend window)) if (equal char1 control_g) ;;abort this command? do (db%throw_control_g) else if (or (and ;legal character?--a-z (> char1 #/`) (< char1 #/{)) (eq char1 #/^)) ;beginning of the 'secret command' do (progn (setq char2 (wgetch window)) (ct_if (equal char2 control_g) ;control_g = abort (db%throw_control_g)) (let* ((command_char (list (ascii char1) (ascii char2))) ;;the command_stream can come from any of the ;;specials containing commands (command_stream (or (assoc command_char *db%menu_command_list*) (assoc command_char *db%single_screen_command_list*) (assoc command_char *db%window_command_list*) (assoc command_char *db%debugger_command_list*))) ;;echo the command currently being entered (command_print (ct_string_append *db%command_string* (third command_stream)))) ;;if exists, display the command currently being ;;entered on the window (ct_if command_stream (progn (db%change_mode_line window command_print) (ct_csend db%debug_window *db%current_window* :reposition_cursor))) (ct_if (or (and (> char2 #/') ;legal character?--a-z (< char2 #/})) (eq char2 #/&)) ;last character for the 'secret cmd. (return (loop for char3 = (wgetch window) if (or (equal char3 #\return) (equal char3 #\linefeed)) do (return #+franz (list (ascii char1) (ascii char2)) #+lispm (list (ascii (- char1 32)) (ascii (- char2 32)))) else if (equal char3 control_g) do (return (db%throw_control_g)) else do (db%user_interface_error "Illegal Character--Use to select the command" ))) (progn (db%user_interface_error "Illegal Command") (*throw 'db%catch_command nil))))) else if (equal char1 #\esc) ;;arrow key? do (progn (setq char2 (wgetch window)) (ct_if (or (equal char2 left_bracket) (equal char #/O)) (progn (setq char3 (wgetch window)) (ct_selectq char3 (#+franz 65 ;;up-arrow (ct_csend db%debug_window *db%current_window* :up_arrow)) (#+franz 66 ;;down-arrow (ct_csend db%debug_window *db%current_window* :down_arrow)) (#+franz 67 ;;right arrow (ct_csend db%debug_window *db%current_window* :right_arrow)) (#+franz 68 ;;left arrow (ct_csend db%debug_window *db%current_window* :left_arrow))) (return 'arrow)) (progn (db%user_interface_error "Illegal Command") (*throw 'db%catch_command nil)))) else do (progn (db%user_interface_error "Illegal Command") (*throw 'db%catch_command nil)))) ;;;;;;;;;;;;;;;;;; (defun db%screen_snapshot (window) ;;;;;;;;;;;;;;;;;; #| Take a picture of the current screen and save it in a file under the current directory with the name 'g###'. |# #+(and franz (not vms)) (dump_screen_to_file (get_pname (gensym))) (ct_if *db%echop* (progn (waddch window #\backspace) ;back up from ^H (waddch window #\backspace) (waddch window #\backspace))) (wrefresh window)) ;;;;;;;;;;;;;;;;; (defun db%screen_refresh () ;;;;;;;;;;;;;;;;; ;;refresh the entire screen by refreshing 'curscr (let ((curscr (getcurscr))) (wrefresh curscr) (ct_csend db%debug_window *db%current_window* :reposition_cursor))) ;;;;;;;;;;;;;;;;;;;;;;; (defun db%redisplay_after_menu (menu_window) ;;;;;;;;;;;;;;;;;;;;;;; #| Refresh the screen by touching and refreshing each of the currently exposed windows after clearing the menu window from the screen. |# ;;first, clean out the menu_window (ct_csend db%debug_window menu_window :display-string "") ;;if entries in the *current_exposed_window_list*, refresh them; ;;otherwise, refresh by clearing the screen (ct_if *current_exposed_window_list* (loop for window in *current_exposed_window_list* ;refresh each window do (ct_if (instancep window) (progn (ct_csend db%debug_window window :touchwin) (ct_csend db%debug_window window :wrefresh)) (progn (touchwin window) (wrefresh window)))) ;; (progn ;; (clear) ;; (refresh)) ) (ct_if *db%current_window* (ct_csend db%debug_window *db%current_window* :reposition_cursor))) ;;;;;;;;;; (defun db%wgetstr (window) ;;;;;;;;;; #| Get a string from the user on the given window. The character is retrieved from the function db%wgetch. If a backspace or rubout is input, the last character is removed from the screen. Input is taken until a return or linefeed is typed. All echo is done by the db%wgetch function. Echo itself is turned off.|# (loop for char = (db%wgetch window) with string = "" until (or ;finished? (eq char #\return) (eq char #\linefeed)) do (ct_selectq char ((#\rubout #\backspace) (cond ((not (equal string "")) ;;if not a blank input already, notice the ;;last char, and move back over it. Clobber ;;the last char from the input buffer and ;;clear to end of line. Add backspaces ;;and spaces to keep reverse video happy (waddch window #\backspace) (waddch window #\space) (waddch window #\backspace) (touchwin window) (wrefresh window) (setq string (substring string #+lispm 0 #+franz 1 (1- (string-length string)))) ))) (t (waddch window char) (wrefresh window) (setq string (ct_string_append string char)))) ;update string finally (progn (tyo #\return) ;echo the return (return string)))) ;return the string ;;;;;;;;;; (defun db%wgetnum (window) ;;;;;;;;;; #|Get a number from the user on the current window. If a rubout or backspace is input, the last number typed is removed from the screen, with the number being generated updated accordingly. Input is taken until a return or linefeed is typed. The value returned is the actual number input, not its character representation |# (loop for char = (db%wgetchn window) with num = 0 with input_num = nil with place = 1 until (or (eq char #\return) ;finished? (eq char #\linefeed)) do (ct_selectq char ((#\rubout #\backspace) (cond ((not (equal input_num nil)) ;;if not a blank input already, notice the ;;last number, and move back over it. Clobber ;;the last number from the input buffer, ;;recompute the number and ;;clear to end of line. Add spaces and ;;backspace to appease reverse video (waddch window #\backspace) (waddch window #\space) (waddch window #\backspace) (wrefresh window) (touchwin window) (setq num (quotient (- num (mod num place)) place)) (setq place (quotient place 10)) (ct_if (eq place 1) (setq input_num nil)))) (t (progn (waddch window num) (wrefresh window) (setq input_num t) (setq num (+ (* num place) (- char 48))) ;update number (setq place (* 10 place)) ;keep track of )))) ;place value finally (progn (tyo #\return) ;echo the return (return num)))) ;return the number ;;;;;;;;;;;;;;;;;;; (defun db%wgetnumberstring (window) ;;;;;;;;;;;;;;;;;;; #| Get a string of numbers from the user on the given window. The character is retrieved from the function db%wgetchns. If a backspace or rubout is input, the last character is removed from the screen. Input is taken until a return or linefeed is typed. The value of the numbers will be handled by the calling function. This function returns everything in a one long string |# (loop for char = (db%wgetchns window) with string = "" until (or ;finished? (eq char #\return) (eq char #\linefeed)) do (ct_selectq char ((#\rubout #\backspace) (cond ((not (equal string "")) ;;if not a blank input already, notice the ;;last char, and move back over it. Clobber ;;the last char from the input buffer and ;;clear to end of line. Add spaces and ;;backspaces to appease reverse video (waddch window #\backspace) (waddch window #\space) (waddch window #\backspace) (wrefresh window) (setq string (substring string #+lispm 0 #+franz 1 (1- (string-length string))))))) (t (progn (waddch window char) (wrefresh window) (setq string (ct_string_append string char))))) ;update string finally (progn (tyo #\return) ;echo the return (return string)))) ;return the string ;;;;;;;;;;;;;;;;;; (defun db%wgetmenu_choices (window menu_prompt) ;;;;;;;;;;;;;;;;;;; #| Get a string of numbers from the user on the given window. The character is retrieved from the function db%wgetch. If a backspace or rubout is input, the last character is removed from the screen. Input is taken until a return or linefeed is typed. |# (loop for char = (db%wgetmenu_input window menu_prompt) with string = "" until (or ;finished? (eq char #\return) (eq char #\linefeed)) do (ct_selectq char ((#\rubout #\backspace) (cond ((not (equal string "")) ;;if not a blank input already, notice the ;;last char, and move back over it. Clobber ;;the last char from the input buffer and ;;clear to end of line. Add spaces and ;;backspaces to appease reverse video (waddch window #\backspace) (waddch window #\space) (waddch window #\backspace) (setq string (substring string #+lispm 0 #+franz 1 (1- (string-length string)))) (touchwin window) (wrefresh window)))) (t (waddch window char) (wrefresh window) (setq string (ct_string_append string char)))) ;update string finally (progn (return string)))) ;;;;;;;;;;;;;;;;;; (defun db%wgetmenu_input (window menu_prompt) ;;;;;;;;;;;;;;;;;; #| Get a number from the given window to be returned as the selection from a menu. The legal characters handled here are return, linefeed, rubout, backspace, and 0-9, + and - |# (loop for number = (wgetch window) if (and (status feature debugging) (equal number control_h)) ;is a picture wanted? do (db%screen_snapshot window) else if (equal number control_l) ;is a refresh wanted? do (db%screen_refresh) else if (equal number control_g) ;abort the menu selection process? do (db%throw_control_g) else if (or ;legal number? (eq number #\return) (eq number #\linefeed) (eq number #\rubout) (eq number #\space) (eq number #\backspace) (eq number #/+) (eq number #/-) (and (> number *slash*) ;;a "/" (< number #/:))) do (return number) else do (progn (let ((command nil) (command_stream nil) (command_function nil) (command_print nil)) (setq command (db%wgetcommand_char window number)) (setq command_stream (assoc command *db%menu_command_list*)) (ct_if (not command_stream) (progn (db%user_interface_error "Illegal Menu Command") (db%change_mode_line window menu_prompt)) (progn (setq command_function (second command_stream)) (setq command_print (ct_string_append "Executing: " (third command_stream))) (db%change_mode_line window command_print) (eval command_function) (db%change_mode_line window menu_prompt))))))) ;;;;;;;;;;;;;;;;;;;;; (defun db%wgetwindow_choices (window menu_prompt) ;;;;;;;;;;;;;;;;;;;;; #| Accept a select group of commands on a window. Used when only one window is shown to the user---when the debugger hasn't been chosen as an option or when a syntatic error has occured and the debugger or testing cannot legally be entered |# (noecho) (setq *db%doing_command* t) (loop do (*catch 'db%catch_command (progn (ct_csend db%debug_window *db%current_window* :reposition_cursor) (loop for number = (wgetch window) if (and (status feature debugging) (equal number control_h)) ;is a picture wanted? do (db%screen_snapshot window) else if (equal number control_l) ;is a refresh wanted? do (db%screen_refresh) else ;get the command do (progn (let ((command nil) (command_stream nil) (command_function nil) (command_print nil)) (setq command (db%wgetcommand_char window number)) (setq command_stream (or (assoc command *db%menu_command_list*) (assoc command *db%single_screen_command_list*))) (ct_if (not command_stream) (progn ;illegal command #+franz (tyo control_g) #+lispm (beep) #+franz (drain) (db%user_interface_error "Illegal Window Command") (db%change_mode_line *db%bottom_mode_line* menu_prompt) (ct_csend db%debug_window *db%current_window* :reposition_cursor)) (progn ;legal command (setq command_function (second command_stream)) ;;CURSES loses here ;;(setq command_print ;;(ct_string_append "Executing: " ;;(third command_stream))) ;;echo the command currently executing ;;(db%change_mode_line *db%bottom_mode_line* ;;command_print) ;;perform the desired function (eval command_function) ;;change the mode line back to its original state (db%change_mode_line *db%bottom_mode_line* menu_prompt) (ct_csend db%debug_window *db%current_window* :reposition_cursor)))))))))) ;;;;;;;;; (defun db%wclear (window) ;;;;;;;;; #| Clear the given window of all information, touch it and refresh it. |# (wclear window) (touchwin window) (wrefresh window)) ;;;;;;;;;;;; (defun db%get_files (win prompt must_existp) ;;;;;;;;;;;; #| Get input from the user of file names until a carriage return is received on an empty line. Each file name is entered on a separate line |# (let* ((source_list nil)) (setq *db%current_col* 0) (db%new_lines win 2) (wstandout win) ;;display the prompt for the command (waddstr win prompt) (wstandend win) (wrefresh win) (setq *db%current_col* 10) (db%new_lines win 1) (setq source_list (loop for file_name = (db%wgetstr win) until (equal file_name "") if (and must_existp (not (probef file_name))) ;does this file exist? ;;check must_existp first to see if ;;it needs to and signal error if ;;it doesn't do (progn (beep) (drain) (db%new_lines win 1) (wclrtoeol win) (waddstr win "Invalid File Name; Re-input: ") (wrefresh win)) else collect file_name do (db%new_lines win 1))) source_list)) ;;;;;;;;;;; (defun db%get_file (win prompt must_existp) ;;;;;;;;;;; #|Get one file name from the user |# (let (file_name nil) (setq *db%current_col* 0) (db%new_lines win 2) (wstandout win) ;;display the prompt for the command (waddstr win prompt) (wstandend win) (wrefresh win) (setq *db%current_col* 10) (db%new_lines win 1) (loop for file_name = (db%wgetstr win) if (equal file_name "") do (return nil) else if (and must_existp (not (probef file_name))) ;does this file exist-- ;;check must_existp first to see if ;;it needs to and signal error ;;if it's not around do (progn (beep) (drain) (db%new_lines win 1) (wclrtoeol win) (waddstr win "Invalid File Name; Re-input: ") (wrefresh win)) else do (return file_name) ;return the file name do (db%new_lines win 1)))) ;;;;;;;;;;;; (defun db%new_lines (win number) ;;;;;;;;;;;; #| See if a scroll is needed before the next type-out of a line on the screen...causes the current window 'win' to wrap-around if necessary by seeing how many lines 'number' are wanted for the line increment|# (let ((line_num (+ *db%current_line* number)) (max_lines (1- *db%lines*))) (touchwin win) (ct_if (or ;see if need to scroll (= line_num max_lines) (> line_num max_lines)) (progn ;if so, wrap around to the top (setq *db%current_line* 0) (wmove win *db%current_line* 0) (wclrtoeol win) (wmove win (1+ *db%current_line*) 0)) (progn ;otherwise, clear the lines (ct_if (> number 1) ;are about to input onto (loop for i from 1 to (1- number) with line_num = *db%current_line* do (progn (setq line_num (1+ line_num)) (wmove win line_num 0) (wclrtoeol win)))) (setq *db%current_line* (+ number *db%current_line*)) (wmove win *db%current_line* 0))) (wclrtoeol win) (wmove win *db%current_line* *db%current_col*) (wrefresh win))) ;;;;;;;;;;;;;; (defun db%center_strings (&rest args) ;;;;;;;;;;;;;; #| Takes an arbitrary number of strings and centers them on the screen. A list is return of ((position string) (position string)) for each string in the list, where position is the column on which to being the string. |# (let* ((numstrings (length args)) (strlength 0) (spacelength 0) (strformat nil)) (loop for string in args do (setq strlength (+ strlength (string-length string)))) (setq spacelength (quotient (- *db%cols* strlength) (1+ numstrings))) (setq strformat (loop for string in args with start = 0 do (setq start (+ start spacelength)) collect (list start string) do (setq start (+ (string-length string) start)))) strformat)) ;;;;;;;;;;;;;;;;;;; (defun db%change_mode_line (window new_line) ;;;;;;;;;;;;;;;;;; #| Display 'new_line on 'window in reverse video by adding *db%blanks* to reverse the entire line and then writing 'new_line on top of that |# (move 0 0) (refresh) (wstandout window) (wmove window 0 0) (wclrtoeol window) (waddstr window *db%blanks*) (wmove window 0 0) (waddstr window new_line) (wmove window 0 (1+ (string-length new_line))) (wrefresh window) (wstandend window) (standend)) (defun db%change_file_name (file_name) #| Display a new file name on the db%top_mode_line |# ; change the current file name (setq *db%current_file* file_name) (db%change_mode_line *db%top_mode_line* (ct_string_append "File Name: " file_name))) ;;;;;;;;;;;;;;;;;;; (defun db%add_to_mode_line (window pos new_line) ;;;;;;;;;;;;;;;;;;; #| Add 'new_line to the current mode line at position 'pos |# (wmove window 0 pos) (for i from 1 to (length new_line) do (waddch window " ")) (wmove window 0 pos) (waddstr window new_line) (wrefresh window)) ;;;;;;;;;;;;;;;;;;;;;;; (defun db%user_interface_error (error_string) ;;;;;;;;;;;;;;;;;;;;;;; #| Signal a user interface error by beeping, adding 'error_string to the *db%user_window*, and then repositioning the cursor on the current window |# ;;see if there is a curses-window for the *db%user_window* ;;if is, write to that; otherwise, write to the ;;*db%output_window* (let ((error_window (ct_if (get-iv db%debug_window *db%user_window* curses-window) *db%user_window* *db%output_window*))) #+franz (tyo control_g) #+lispm (beep) #+franz (drain) (ct_format error_window "~A~%" error_string) (ct_csend db%debug_window *db%current_window* :reposition_cursor))) ;;;;;;;;;;;;;;;;;; (defun db%throw_control_g () ;;;;;;;;;;;;;;;;;; #| Throw out of the current debug command after rudely beeping |# ;;see if there is a curses-window for the *db%user_window* ;;if is, write to that; otherwise, if there is ;;one for *db%output_window*, write to that; else write ;;to (terminal_output) (let ((error_window (cond ((get-iv db%debug_window *db%user_window* curses-window) *db%user_window*) ((get-iv db%debug_window *db%output_window* curses-window) *db%output_window*) (t (terminal_output))))) #+franz (tyo control_g) #+lispm (beep) #+franz (drain) (ct_format error_window "Command Aborted~%") (*throw 'db%catch_command nil))) ;;;;TESTING FUNCTIONS #| ;;;; (defun test () ;;;; (initscr) (nocrmode) (raw) (tyi) (let ((tempstring nil) (win (newwin 0 0 0 0))) (wstandout win) (waddstr win "Input now: ") (wstandend win) (waddstr win " ") (wrefresh win) (setq temp (db%wgetstr win)) (wstandend win) (wrefresh win) (noraw) (endwin) temp )) |#