1 SUB SMG_INPUT_CLR(STRING Prompt, LONG Row, LONG Col, LONG Length, & STRING Inpstr, LONG Timeout, LONG Vir_disp_num) !---------------------------------------------------------------& ! & ! SMG_INPUT_CLR & ! & ! Creation Date: 3-July-1985 & ! Author: Ken Messer & ! Purpose: General input routine & ! & ! Modification history & ! & ! Date Description of change(s) & ! & ! 8-Jan-86 Handle control characters & ! 20-Nov-86 Repaint pasteboard if ctrl-W typed & ! & !---------------------------------------------------------------& ! & ! Copyright (c) 1985 - Ken Messer, Allied Electronics, Inc., & ! 401 E. 8th St., Ft. Worth, TX 76102 & ! & ! This software may be copied and distributed freely to anyone & ! for non-commerical use provided that this copyright notice is & ! included. & !---------------------------------------------------------------& OPTION TYPE = INTEGER, SIZE = INTEGER LONG %include "SMG$LIBRARY:SMG.DFN" DECLARE WORD Term_code, & Total_char_recvd, & Received_string_length DECLARE LONG Return_status, & Readcol, & Max_length, & Partial_flag DECLARE LONG CONSTANT True = -1, & False = 0 DECLARE STRING Dummy, & Partial_Inpstr EXTERNAL LONG FUNCTION SMG$Ring_bell, & SMG$Put_chars, & SMG$Erase_line, & SMG$Read_string, & SMG$Set_cursor_abs EXTERNAL LONG CONSTANT SS$_Normal EXTERNAL STRING FUNCTION Get_Error_Message(LONG) EXTERNAL SUB SMG$Repaint_Screen !---------------------------------------------------------------& ! & ! M a i n P r o g r a m L o g i c & ! & !---------------------------------------------------------------& ! & ! P r o g r a m F l o w & ! & ! 1) Calculate the column where input will start based upon & ! the length (or absence) of the prompt. If a prompt & ! exists, input will start two spaces beyond its' end, & ! otherwise, it will take place at row/column. & ! 2) Display the prompt (if any) at the location specified & ! by the row/column parameters. & ! 3) Display the input field paint character in reverse & ! video. The length of this field is specified by the & ! input length parameter. & ! 4) Reset the cursor to the location calculated in step 1. & ! 5) Take the input. & ! & !---------------------------------------------------------------& Set_Up: SELECT LEN(Prompt) CASE 0 Readcol = Col CASE ELSE Readcol = Col + LEN(Prompt) + 1 END SELECT Inpstr = "" Total_char_recvd = 0 Max_length = Length Display_Prompt: Return_status = SMG$Put_chars(Display_id(Vir_disp_num),Prompt,Row,Col,,,,) IF Return_status AND SS$_Normal = 0 THEN PRINT Get_Error_Message(Return_status) STOP END IF Display_Paint_Character: Return_status = SMG$Put_chars(Display_id(Vir_disp_num), & STRING$(Max_length,ASCII(Paint_char)),Row,Readcol,, & Input_display_attr,,) IF Return_status AND SS$_Normal = 0 THEN PRINT Get_Error_Message(Return_status) STOP END IF Reset_Cursor: Return_status = SMG$Set_cursor_abs(Display_id(Vir_disp_num),Row,Readcol) IF Return_status AND SS$_Normal = 0 THEN PRINT Get_Error_Message(Return_status) STOP END IF Get_Input: ! call the read routine with the timeout parameter omitted unless ! a specific timeout was requested - a timeout value of zero ! produces undesirable results IF Timeout < 1 THEN Return_status = SMG$Read_string(Current_keyboard_id,Inpstr,, & Max_length, Input_function_modifier1,, & Term_set_mask_desc(0) BY REF, Received_string_length, & Term_code, Display_id(Vir_disp_num),,Input_display_attr,) ELSE Return_status = SMG$Read_string(Current_keyboard_id,Inpstr,, & Max_length, Input_function_modifier1,Timeout, & Term_set_mask_desc(0) BY REF,Received_string_length, & Term_code,Display_id(Vir_disp_num),,Input_display_attr,) END IF Total_char_recvd = Total_char_recvd + Received_string_length IF Partial_flag THEN Inpstr = Partial_Inpstr + Inpstr Partial_flag = False END IF Parse_Terminator_Code: SELECT Term_code CASE 13 ! carriage return ! OK CASE 1 TO 12, 14 TO 17,19,20,22,25,26 ! control keys - allow only if first ! character typed - some of these will not work ! unless the PASTHRU characteristic is set on ! the terminal port - the port must be set NOTTYSNC ! to allow ctrl-q/ctrl-s to pass thru IF LEN(Inpstr) = 0 THEN Inpstr = "~CTRL_" + CHR$(Term_code + 64) + "~" GOTO Done ELSE Return_status = SMG$Ring_bell(Display_id(Vir_disp_num),) Max_length = Length - Received_string_length Partial_flag = True Partial_Inpstr = Inpstr Inpstr = "" GOTO Get_Input END IF CASE 27 TO 31 ! illegal terminators - don't allow Return_status = SMG$Ring_bell(Display_id(Vir_disp_num),) Max_length = Length - Received_string_length Partial_flag = True Partial_Inpstr = Inpstr Inpstr = "" GOTO Get_Input CASE 18,21,24 ! ctrl-R,ctrl-U,ctrl-X - the user wants to ! start over Return_status = SMG$Put_chars(Display_id(Vir_disp_num), & STRING$(Max_length,ASCII(Paint_char)), & Row,Readcol,,Input_display_attr,,) Return_status = SMG$Set_cursor_abs(Display_id(Vir_disp_num), & Row,Readcol) Inpstr = "" Partial_flag = False Max_length = Length GOTO Get_Input CASE 23 ! ctrl-W - repaint the pasteboard CALL SMG$Repaint_Screen(Current_pasteboard_id) Inpstr = "" Total_char_recvd = 0 Max_length = Length Partial_flag = False GOTO Display_Paint_Character CASE 127 ! delete - write the delete sequence (backspace, ! paint character, backspace) and go back for ! more input ! of course, if we're at the beginning of the ! field, we can't go back SELECT Total_char_recvd CASE 0 Return_status = SMG$Ring_bell(Display_id(Vir_disp_num),) GOTO Get_Input CASE ELSE Total_char_recvd = Total_char_recvd - 1 Max_length = Length - Total_char_recvd Return_status = SMG$Put_chars(Display_id(Vir_disp_num), & Del_seq,,,,Input_display_attr,,) Partial_flag = True Partial_Inpstr = SEG$(Inpstr,1,Total_char_recvd) GOTO Get_Input END SELECT CASE 256 TO 316 ! function key - valid only if first ! character typed - otherwise, ignore it GOTO Handle_Function_Keys IF LEN(Inpstr) = 0 Return_status = SMG$Ring_bell(Display_id(Vir_disp_num),) Max_length = Length - Received_string_length Partial_flag = True Partial_Inpstr = Inpstr Inpstr = "" GOTO Get_Input CASE 509 ! Timeout - flag it and exit Timeout = -1 GOTO Done CASE 510 ! buffer full - do another read - only a ! CR, DEL, or ctrl-U,ctrl-R,ctrl-X,ctrl-W ! will be allowed to terminate the read - ! anything else will be ignored (ring the bell) Final_read: ! Execute a one character read with no echo IF Timeout < 1 THEN Return_status = SMG$Read_string(Current_keyboard_id,Dummy,,1,& Input_function_modifier2,,,,Term_code, & Display_id(Vir_disp_num),,,) ELSE Return_status = SMG$Read_string(Current_keyboard_id,Dummy,,1,& Input_function_modifier2,Timeout,,,Term_code,& Display_id(Vir_disp_num),,,) END IF IF Return_status AND SS$_Normal = 0 THEN PRINT Get_Error_Message(Return_status) STOP END IF SELECT Term_code CASE 13 ! CR ! OK CASE 18,21,24 ! ctrl-R,ctrl-U,ctrl-X Return_status = SMG$Put_chars(Display_id(Vir_disp_num), & STRING$(Max_length,ASCII(Paint_char)),Row, & Readcol,,Input_display_attr,,) Return_status = SMG$Set_cursor_abs(Display_id(Vir_disp_num), & Row,Readcol) Inpstr = "" Partial_flag = False Max_length = Length GOTO Get_Input CASE 23 ! ctrl-W - repaint the pasteboard CALL SMG$Repaint_Screen(Current_pasteboard_id) Inpstr = "" Total_char_recvd = 0 Max_length = Length Partial_flag = False GOTO Display_Paint_Character CASE 127 ! delete Max_length = 1 Total_char_recvd = Length - 1 Return_status = SMG$Put_chars(Display_id(Vir_disp_num), & Del_seq,,,,Input_display_attr,,) Partial_flag = True Partial_Inpstr = SEG$(Inpstr,1,Length - 1) GOTO Get_Input CASE 509 ! Timeout Timeout = -1 CASE ELSE ! anything else not allowed Return_status = SMG$Ring_bell(Display_id(Vir_disp_num),) GOTO Final_read END SELECT END SELECT GOTO Done Handle_Function_Keys: ! build a return value based upon the function key typed SELECT Term_code CASE 256 TO 259 ! PF1 to PF4 Inpstr = "~PF" + NUM1$(Term_code - 255) + "~" CASE 260 TO 269 ! application keypad keys Inpstr = "~KP" + NUM1$(Term_code - 260) + "~" CASE 270 Inpstr = "~ENTER~" CASE 271 Inpstr = "~MINUS~" CASE 272 Inpstr = "~COMMA~" CASE 273 Inpstr = "~PERIOD~" CASE 274 Inpstr = "~UP~" CASE 275 Inpstr = "~DOWN~" CASE 276 Inpstr = "~LEFT~" CASE 277 Inpstr = "~RIGHT~" CASE 286 TO 294, 297 TO 300 Inpstr = "~F" + NUM1$(Term_code - 280) + "~" CASE 295 Inpstr = "~HELP~" CASE 296 Inpstr = "~DO~" CASE 311 Inpstr = "~FIND~" CASE 312 Inpstr = "~INSERT HERE~" CASE 313 Inpstr = "~REMOVE~" CASE 314 Inpstr = "~SELECT~" CASE 315 Inpstr = "~PREV SCREEN~" CASE 316 Inpstr = "~NEXT SCREEN~" END SELECT Done: ! zero the timeout parameter unless a timeout occurred Timeout = 0 UNLESS Timeout = -1 ! erase the line Return_status = SMG$Erase_line(Display_id(Vir_disp_num),Row,1) IF Return_status AND SS$_Normal = 0 THEN PRINT Get_Error_Message(Return_status) STOP END IF Exit_Routine: SUBEXIT END SUB