问题描述
在Pascal中,有一个GotoXY函数,可将光标定位在当前窗口的坐标(X,Y)上。 Linux上的Ada是否有类似的功能?我为Win32找到了一个名为NT_console的文件,但没有为Linux找到一个文件。更一般而言,是否有任何包装与pascal上的crt单元相似?谢谢。
解决方法
有ncurses(或者,如果您需要Windows解决方案,则为JEWL)。不过,我从未用过它们。
,不是这样。
但是,这是我移植一个进行一些交互式文本编辑的Pascal程序时放在一起的“终端”程序包,最初是在Windows CMD窗口上……实际上可能是在DOS上。
不完整,但作为起点可能有用。 GotoXY在这里是Set_Cursor。请注意,Clear_Scrn等上的“ atr”参数将被忽略:这对我来说已经足够了:可以删除它们(进一步简化库),但保留它们与原始项目的兼容性。
可在Debian Linux“ Gnome Terminal”控制台上工作,但可以使用转义序列轻松修改为其他终端类型。
terminal.ads ...
PACKAGE Terminal IS
TYPE WORD IS MOD 2**16;
-- returned by Read_Special which reads the keyboard. Parse these
-- if you need to interactively move round the screen,and get_cursor
-- and set_cursor accordingly. Or if between space and tilde,-- call LOBYTE to extract the (Ada.Characters.Latin_1) character.
up_arrow : CONSTANT WORD := 16#5B41#;
dn_arrow : CONSTANT WORD := 16#5B42#;
lf_arrow : CONSTANT WORD := 16#5B44#;
rt_arrow : CONSTANT WORD := 16#5B43#;
pgup : CONSTANT WORD := 16#357E#;
pgdn : CONSTANT WORD := 16#367E#;
F2 : CONSTANT WORD := 16#4F51#;
F3 : CONSTANT WORD := 16#4F52#;
F4 : CONSTANT WORD := 16#4F53#;
ins : CONSTANT WORD := 16#327E#;
Esc : CONSTANT WORD := 16#001B#;
cr : CONSTANT WORD := 16#000D#;
lf : CONSTANT WORD := 16#000A#; -- accept cr or lf for Linux too
plus : CONSTANT WORD := 16#002B#;
minus : CONSTANT WORD := 16#002D#;
period : CONSTANT WORD := 16#002E#;
naught : CONSTANT WORD := 16#0030#;
nine : CONSTANT WORD := 16#0039#;
bcksp : CONSTANT WORD := 16#007F#; -- Gnome terminal "profile preferences" ...
-- backspace generates ASCII DEL (vs ctrl-H 0008)
space : CONSTANT WORD := 16#0020#; -- {first printable character}
tilda : CONSTANT WORD := 16#007E#; -- {last printable character}
FUNCTION LOBYTE(Data : WORD) RETURN CHARACTER;
PROCEDURE read_special(incode: OUT WORD); -- EXTERN;
-- {Reads special keyboard characters; LOBYTE(incode)= ASCII
-- HIBYTE(incode) = special code;}
PROCEDURE set_cursor(row,col: INTEGER); -- EXTERN;
-- {Sets screen cursor at line = row,column = col}
PROCEDURE get_cursor(row,col: OUT INTEGER); -- EXTERN;
-- {Gets current cursor position: line = row,column = col}
PROCEDURE backspace;
PROCEDURE clear_scrn(atr: INTEGER); -- EXTERN;
-- {Clears active display screen,sets display attribute}
PROCEDURE clear_ln(row,atr: INTEGER); -- EXTERN;
-- {Clears single line row on active display screen,sets display attribute;
PROCEDURE scrlup_scrn(topln,botln,atr: INTEGER); -- EXTERN;
PROCEDURE scrldn_scrn(topln,atr: INTEGER); -- EXTERN;
-- {Scroll active display screen up or down one line in window defined by
-- topln and botln; sets display attribute of blank line; }
END Terminal;
terminal.adb
WITH Ada.Unchecked_Conversion;
WITH Ada.Text_IO; USE Ada.Text_IO;
WITH Ada.Integer_Text_IO; USE Ada.Integer_Text_IO;
WITH Ada.Characters.Latin_1;
PACKAGE BODY Terminal IS
FUNCTION LOBYTE(Data : WORD) RETURN CHARACTER IS
TYPE BYTE IS MOD 2**8;
FUNCTION Byte_To_Char IS NEW Ada.Unchecked_Conversion(BYTE,CHARACTER);
Temp : BYTE := BYTE(Data MOD 2**8);
BEGIN
RETURN Byte_To_Char(Temp);
END LOBYTE;
PROCEDURE read_special(incode: OUT WORD) IS
-- {Reads special keyboard characters; LOBYTE(incode)= ASCII
-- HIBYTE(incode) = special code;
temp1,temp2,tempx : CHARACTER := Ada.Characters.Latin_1.NUL;
avail : BOOLEAN;
BEGIN
get_immediate(Standard_Input,temp1); -- block until input
incode := Word(Character'pos(temp1));
get_immediate(Standard_Input,avail); -- check for sequences
IF avail THEN
LOOP
get_immediate(Standard_Input,tempx,avail);
EXIT WHEN NOT avail;
temp1 := temp2;
temp2 := tempx;
END LOOP; -- keep the last 2 characters of the sequence
incode := Word(Character'pos(temp1) * 256 + Character'pos(temp2));
END IF;
END read_special;
PROCEDURE set_cursor(row,col: INTEGER) IS
-- {Sets screen cursor at line = row,column = col; }
r0,r1,r2,c0,c1 : CHARACTER;
BEGIN
r0 := Character'val( Character'pos('0') + (row + 1) MOD 10);
r1 := Character'val( Character'pos('0') + ((row + 1) / 10) MOD 10);
r2 := Character'val( Character'pos('0') + ((row + 1) / 100) MOD 10);
c0 := Character'val( Character'pos('0') + (col + 1) MOD 10);
c1 := Character'val( Character'pos('0') + ((col + 1) / 10) MOD 10);
Put(Ada.Characters.Latin_1.ESC & '[' & r2 & r1 & r0 & ';' & c1 & c0 & 'H');
END set_cursor;
PROCEDURE get_cursor(row,col: OUT INTEGER) IS
-- {Gets current cursor position: line = row,column = col}
BEGIN
row := INTEGER(Ada.Text_IO.Line) - 1;
col := INTEGER(Ada.Text_IO.Col) - 1;
END get_cursor;
PROCEDURE backspace IS
BEGIN
Put(Ada.Characters.Latin_1.ESC & '[' & 'D'); -- Backspace
END backspace;
PROCEDURE clear_scrn(atr: INTEGER) IS
-- {Clears active display screen,sets display attribute}
-- row,col : INTEGER;
BEGIN
Put(Ada.Characters.Latin_1.ESC & '[' & '2' & 'J');
END clear_scrn;
PROCEDURE clear_ln(row,atr: INTEGER) IS
-- {Clears single line row on active display screen,sets display attribute;
BEGIN
set_cursor(row,0);
Put(Ada.Characters.Latin_1.ESC & '[' & '2' & 'K');
END clear_ln;
PROCEDURE scrlup_scrn(topln,atr: INTEGER) IS
-- {Scroll active display screen up or down one line in window defined by
-- topln and botln; sets display attribute of blank line}
BEGIN
Put(Ada.Characters.Latin_1.ESC & '[' & '1' & 'S');
END scrlup_scrn;
PROCEDURE scrldn_scrn(topln,atr: INTEGER) IS
BEGIN
Put(Ada.Characters.Latin_1.ESC & '[' & '1' & 'T');
END scrldn_scrn;
END Terminal;
here for example记录的终端转义序列