MODULE TPUPlus_LINE IDENT "900409" !**************************************** ! This linedraw TPU code was written by :- ! ! Steve Graham ! British Telecom ! Royston House ! 34 Upper Queen Street ! Belfast ! BT1 6FD ! Northern Ireland ! U.K. ! ! Modified by: ! Rick Stacks - 901211 - incorporated some of Steve Travis's line drawing ! code as found in DEC PROFESSIONAL, Dec 1990, ! Vol. 9, No. 13, pgs. 70-74 ! ! The code is placed in the public domain. It has been tested as completely as ! possible but you are advised that NO WARRANTY, EITHER EXPRESSED OR IMPLIED, ! IS CONVEYED WITH THIS SOFTWARE. ! ! PROCEDURE eve_change_graphic ! PROCEDURE EVE_SET_LINEDRAWING ! PROCEDURE EVE_SET_NOLINEDRAWING ! PROCEDURE eve$copy_over(the_text) ! PROCEDURE up_or_down(which_way) ! PROCEDURE plus_line ! PROCEDURE plus_char ! PROCEDURE left_dangling ! PROCEDURE right_dangling ! PROCEDURE above_dangling ! PROCEDURE below_dangling ! PROCEDURE down_vert ! PROCEDURE up_vert ! PROCEDURE left_horiz ! PROCEDURE right_horiz ! PROCEDURE graph_char ! PROCEDURE line_leftwards ! PROCEDURE line_rightwards ! PROCEDURE line_downwards ! PROCEDURE line_upwards ! PROCEDURE sg_write_ln03_sequence ! PROCEDURE PCE_TOGGLE_LINEDRAW ! PROCEDURE EVE$LINEDRAW_STATUS_FIELD (THE_LENGTH, THE_FORMAT) ! PROCEDURE SG$LINEDRAW_KEYS ! !**************************************** PROCEDURE eve_change_graphic local start_position, ch_gr_range, pat; ON_ERROR [TPU$_STRNOTFOUND]: ENDON_ERROR; IF current_window = eve$command_window THEN eve$$exit_command_window; else start_position := mark (none); ch_gr_range := select_range; IF ch_gr_range = 0 THEN message('Nothing selected.'); return (0); endif; position(beginning_of(ch_gr_range)); pat := any("+|-"); loop EXITIF mark (none) >= end_of (ch_gr_range); EXITIF mark (none) = end_of (current_buffer); EXITIF search(pat,FORWARD,EXACT) = 0; IF index("+|-", current_character) <> 0 THEN sg$lds := sg$lds + "+-"; sg$rds := sg$rds + "+-"; sg$ads := sg$ads + "+|"; sg$bds := sg$bds + "+|"; graph_char; else plus_char; endif; endloop; ch_gr_range := 0; eve$x_select_position := 0; position(start_position); endif; ENDPROCEDURE !**************************************** PROCEDURE EVE_SET_LINEDRAWING LOCAL loop_window; IF sg$line_drawing = "TRUE" then eve_set_nolinedrawing; return; endif; sg$line_drawing := "TRUE"; sg$previous_mode := get_info (current_buffer, "mode"); set (overstrike, current_buffer); loop_window := get_info (window, "first"); loop EXITIF loop_window = 0; ! set (scrolling, loop_window, ON, 0, 0, 0); st_line := get_info(loop_window, "status_line"); IF st_line <> 0 THEN eve$set_status_line(loop_window); endif; loop_window := get_info (window, "next"); endloop; sg$uparrow := lookup_key (up, program); sg$downarrow := lookup_key (down, program); sg$leftarrow := lookup_key (left, program); sg$rightarrow := lookup_key (right, program); add_key_map (eve$x_key_map_list, "first", sg$x_linedraw_keys); pce$linedraw_mode := "LINEDRAW"; !set (text, message_window, no_translate); !message (sg$select_1); !message (sg$select_2); !message (""); !set (text, message_window, blank_tabs); sct_gset; message ("Cursor keys will now draw lines using line drawing set"); eve$update_status_lines; ENDPROCEDURE; !**************************************** PROCEDURE EVE_SET_NOLINEDRAWING local loop_window; sg$line_drawing := "FALSE"; loop_window := get_info (window, "first"); loop EXITIF loop_window = 0; st_line := get_info(loop_window, "status_line"); if st_line <> 0 THEN eve$set_status_line(loop_window); endif; loop_window := get_info (window, "next"); endloop; !set (scrolling, eve$main_window, ON, 5, 5, 0); ! statusline => edit window set (sg$previous_mode, current_buffer); remove_key_map (eve$x_key_map_list, sg$x_linedraw_keys, ALL); pce$linedraw_mode := "NORMAL"; !set(text, message_window, no_translate); !message(sg$select_1); !message(sg$select_3); !message(""); !set(text, message_window, blank_tabs); message ("Cursor keys are now reset to original definitions "); eve$update_status_lines; ENDPROCEDURE; !**************************************** PROCEDURE eve$copy_over(the_text) ! Copy_text in overstrike mode LOCAL old_mode; old_mode := get_info(current_buffer, "mode"); set(OVERSTRIKE, current_buffer); copy_text(the_text); set(old_mode, current_buffer); ENDPROCEDURE; !**************************************** PROCEDURE up_or_down(which_way) LOCAL temp_col, last_col, new_col, eob, buf; buf := current_buffer; EOB := end_of(buf); last_col := get_info(buf,'offset_column'); IF (last_col <> sg$_prev_column) THEN sg$_target_column := last_col; ENDIF; move_vertical(which_way); new_col := get_info(buf,'offset_column'); ! Now get as close to the target as possible IF new_col <> sg$_target_column THEN IF new_col < sg$_target_column THEN loop EXITIF mark(none) = EOB; EXITIF current_character = ''; EXITIF new_col >= sg$_target_column; move_horizontal(1); temp_col := get_info(buf,'offset_column'); IF temp_col > sg$_target_column THEN move_horizontal(-1); exitif else new_col:=temp_col endif; endloop; else loop EXITIF current_offset = 0; EXITIF new_col <= sg$_target_column; move_horizontal(-1); new_col := get_info(buf,'offset_column'); endloop; endif; endif; sg$_prev_column := new_col; ENDPROCEDURE; !**************************************** PROCEDURE plus_line ! Move down one row, staying in the same column. Scroll if necessary. up_or_down(+1); ENDPROCEDURE; !**************************************** PROCEDURE plus_char IF mark(NONE) <> end_of(current_buffer) THEN IF current_offset <> length(current_line) THEN move_horizontal(+1); ELSE plus_line; move_horizontal(-current_offset); endif; endif; ENDPROCEDURE; !**************************************** PROCEDURE left_dangling LOCAL c; IF current_offset <> 0 THEN move_horizontal(-1); c := current_character; move_horizontal(1); RETURN (index(sg$lds, c) <> 0); else return 0; endif; ENDPROCEDURE; !**************************************** PROCEDURE right_dangling LOCAL c; IF current_offset <> length(current_line) THEN move_horizontal(1); c := current_character; move_horizontal(-1); RETURN (index(sg$rds, c) <> 0); ELSE return 0; endif; ENDPROCEDURE; !**************************************** PROCEDURE above_dangling LOCAL here, beg_line, c; ON_ERROR RETURN 0; ENDON_ERROR; here := mark(none); position(search(line_begin, reverse)); beg_line := mark(none); position(here); IF beg_line <> beginning_of(current_buffer) THEN cursor_vertical(-1); c := current_character; cursor_vertical(1); RETURN (index(sg$ads, c) <> 0); else return 0; endif; ENDPROCEDURE; !**************************************** PROCEDURE below_dangling LOCAL here, end_line, c; ON_ERROR RETURN 0; ENDON_ERROR; here := mark(none); position(search(line_end, forward)); end_line := mark(none); position(here); IF end_line <> end_of(current_buffer) THEN cursor_vertical(1); c := current_character; cursor_vertical(-1); RETURN (index(sg$bds, c) <> 0); else return 0; endif; ENDPROCEDURE; !**************************************** PROCEDURE down_vert LOCAL l_d, r_d, a_d; l_d := left_dangling; r_d := right_dangling; a_d := above_dangling; IF a_d THEN IF l_d THEN IF r_d THEN eve$copy_over(sg$cross); else eve$copy_over(sg$teeleft); endif; else IF r_d THEN eve$copy_over(sg$teeright); else eve$copy_over(sg$linevert); endif; endif; else IF l_d THEN IF r_d THEN eve$copy_over(sg$teedown); else eve$copy_over(sg$topright); endif; else IF r_d THEN eve$copy_over(sg$topleft); else eve$copy_over(sg$linevert); endif; endif; endif; ENDPROCEDURE; !**************************************** PROCEDURE up_vert LOCAL l_d, r_d, b_d; l_d := left_dangling; r_d := right_dangling; b_d := below_dangling; IF b_d THEN IF l_d THEN IF r_d THEN eve$copy_over(sg$cross); else eve$copy_over(sg$teeleft); endif; else IF r_d THEN eve$copy_over(sg$teeright); else eve$copy_over(sg$linevert); endif; endif; else IF l_d THEN IF r_d THEN eve$copy_over(sg$teeup); else eve$copy_over(sg$bottomright); endif; else IF r_d THEN eve$copy_over(sg$bottomleft); else eve$copy_over(sg$linevert); endif; endif; endif; ENDPROCEDURE; !**************************************** PROCEDURE left_horiz LOCAL r_d, a_d, b_d; r_d := right_dangling; a_d := above_dangling; b_d := below_dangling; IF r_d THEN IF a_d THEN IF b_d THEN eve$copy_over(sg$cross); else eve$copy_over(sg$teeup); endif; else IF b_d THEN eve$copy_over(sg$teedown); else eve$copy_over(sg$linehoriz); endif; endif; else IF a_d THEN IF b_d THEN eve$copy_over(sg$teeleft); else eve$copy_over(sg$bottomright); endif; else IF b_d THEN eve$copy_over(sg$topright); else eve$copy_over(sg$linehoriz); endif; endif; endif; ENDPROCEDURE; !**************************************** PROCEDURE right_horiz LOCAL l_d, a_d, b_d; l_d := left_dangling; a_d := above_dangling; b_d := below_dangling; IF l_d THEN IF a_d THEN IF b_d THEN eve$copy_over(sg$cross); else eve$copy_over(sg$teeup); endif; else IF b_d THEN eve$copy_over(sg$teedown); else eve$copy_over(sg$linehoriz); endif; endif; else IF a_d THEN IF b_d THEN eve$copy_over(sg$teeright); else eve$copy_over(sg$bottomleft); endif; else IF b_d THEN eve$copy_over(sg$topleft); else eve$copy_over(sg$linehoriz); endif; endif; endif; ENDPROCEDURE; !**************************************** PROCEDURE graph_char LOCAL vector; vector := 0; IF left_dangling THEN vector := vector + 8;ENDIF; IF right_dangling THEN vector := vector + 4;ENDIF; IF above_dangling THEN vector := vector + 2;ENDIF; IF below_dangling THEN vector := vector + 1;ENDIF; CASE vector from 0 to 15 [0] : plus_char; [1] : eve$copy_over(sg$teedown); [2] : eve$copy_over(sg$teeup); [3] : eve$copy_over(sg$linevert); [4] : eve$copy_over(sg$linehoriz); [5] : eve$copy_over(sg$topleft); [6] : eve$copy_over(sg$bottomleft); [7] : eve$copy_over(sg$teeright); [8] : eve$copy_over(sg$linehoriz); [9] : eve$copy_over(sg$topright); [10] : eve$copy_over(sg$bottomright); [11] : eve$copy_over(sg$teeleft); [12] : eve$copy_over(sg$linehoriz); [13] : eve$copy_over(sg$teedown); [14] : eve$copy_over(sg$teeup); [15] : eve$copy_over(sg$cross); EndCase; ENDPROCEDURE; !**************************************** PROCEDURE line_leftwards left_horiz; cursor_horizontal(-2); ENDPROCEDURE; !**************************************** PROCEDURE line_rightwards right_horiz; ENDPROCEDURE; !**************************************** PROCEDURE line_downwards IF mark(NONE) <> end_of(current_buffer) THEN IF get_info (current_window, "current_row") = get_info (current_window, "visible_bottom") THEN scroll (current_window, 1); cursor_vertical (-1); endif; down_vert; cursor_horizontal (-1); cursor_vertical (1); endif; ENDPROCEDURE; !**************************************** PROCEDURE line_upwards IF get_info (current_window, "current_row") = get_info (current_window, "visible_top") THEN scroll (current_window, -1); cursor_vertical (1); endif; up_vert; cursor_horizontal (-1); cursor_vertical (-1); ENDPROCEDURE; !**************************************** PROCEDURE sg_write_ln03_sequence if sg$ln03_write_sequence = "OFF" then copy_text(sg$select_1 + sg$select_2); message("Control code to switch on line graphics on a LN03"); sg$ln03_write_sequence := "ON"; else copy_text(sg$select_1 + sg$select_3); message("Control code to switch off line graphics on a LN03"); sg$ln03_write_sequence := "OFF"; endif; ENDPROCEDURE; !**************************************** PROCEDURE PCE_TOGGLE_LINEDRAW if (get_info (pce$linedraw_mode, "type") = UNSPECIFIED) then pce$linedraw_mode := "NORMAL"; endif; if pce$linedraw_mode = "LINEDRAW" then eve_set_nolinedrawing; else eve_set_linedrawing; endif; ENDPROCEDURE; !**************************************** PROCEDURE SCT_GFILE local g_mark; on_error return; endon_error; g_mark := mark (none); g_buffer := create_buffer ('g_file'); position (g_buffer); copy_text ("+0|"); ! esc + 0 esc | set (no_write, g_buffer, on); set (modified, g_buffer, off); set (system, g_buffer); position (g_mark); ENDPROCEDURE; !**************************************** PROCEDURE SCT_GSET local g_mark; g_mark := mark (none); set (screen_update, off); write_file (g_buffer, 'sys$output'); message (""); message (""); set (screen_update, on); position (g_mark); ENDPROCEDURE; !**************************************** PROCEDURE EVE$LINEDRAW_STATUS_FIELD (THE_LENGTH, THE_FORMAT) if pce$linedraw_mode = "LINEDRAW" then return (fao (the_format, "Line Draw")); else return ""; endif; ENDPROCEDURE; !**************************************** PROCEDURE SG$LINEDRAW_KEYS create_key_map ("sg$line_draw_keys"); define_key ("line_leftwards", left, "<-[", "sg$line_draw_keys"); define_key ("line_rightwards", right, "]->", "sg$line_draw_keys"); define_key ("line_downwards", down, "Down", "sg$line_draw_keys"); define_key ("line_upwards", up, "Up", "sg$line_draw_keys"); ENDPROCEDURE; sg$x_linedraw_keys := "sg$line_draw_keys"; sg$previous_mode := ""; sg$_prev_column := 1; sg$_target_column := 1; sg$uparrow := lookup_key (up, program); sg$downarrow := lookup_key (down, program); sg$leftarrow := lookup_key (left, program); sg$rightarrow := lookup_key (right, program); sg$select_1 := ascii(27) + ")0"; sg$select_2 := ascii(27) + "*0"; sg$select_3 := ascii(27) + "*<"; sg$line_drawing := "FALSE"; sg$linedraw_on := "FALSE"; sg$ln03_write_sequence := "OFF"; sg$bottomright := ascii (234); sg$topright := ascii (235); sg$topleft := ascii (236); sg$bottomleft := ascii (237); sg$cross := ascii (238); sg$linehoriz := ascii (241); sg$teeright := ascii (244); sg$teeleft := ascii (245); sg$teeup := ascii (246); sg$teedown := ascii (247); sg$linevert := ascii (248); sg$lds := sg$linehoriz + sg$teeright + sg$teeup + sg$teedown + sg$cross + sg$bottomleft + sg$topleft; sg$rds := sg$linehoriz + sg$teeleft + sg$teeup + sg$teedown + sg$cross + sg$bottomright + sg$topright; sg$ads := sg$linevert + sg$teedown + sg$teeleft + sg$teeright + sg$cross + sg$topleft + sg$topright; sg$bds := sg$linevert + sg$teeup + sg$teeleft + sg$teeright + sg$cross + sg$bottomleft + sg$bottomright; sct_gfile; ENDMODULE; sg$linedraw_keys; compile("procedure sg$linedraw_keys endprocedure"); define_key ("pce_toggle_linedraw", key_name ('d', shift_key), "TPUPLUS pce_toggle_linedraw (LineDrw)", eve$x_user_keys); define_key ("pce_toggle_linedraw", key_name ('d', shift_key), "TPUPLUS pce_toggle_linedraw (LineDrw)", eve$x_edt_keys);