From 12ab8e4227046b36d31c4eecc150ec84e0197be3 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 18 Apr 2006 06:37:16 +0000 Subject: [PATCH] Merged revisions 3102-3103,3128,3183,3211 via svnmerge from http://peter@svn.freepascal.org/svn/fpc/trunk ........ r3102 | daniel | 2006-04-01 10:21:11 +0200 (Sat, 01 Apr 2006) | 2 lines * Fix xterm detection ........ r3103 | daniel | 2006-04-01 12:24:22 +0200 (Sat, 01 Apr 2006) | 2 lines * More video improvements ........ r3128 | marco | 2006-04-02 22:25:36 +0200 (Sun, 02 Apr 2006) | 1 line * FIO constants ........ r3183 | jonas | 2006-04-09 20:21:35 +0200 (Sun, 09 Apr 2006) | 3 lines * changed record typecast into shift to avoid q3 becoming not regable in FPC_MUL_INT64 ........ r3211 | daniel | 2006-04-15 15:49:51 +0200 (Sat, 15 Apr 2006) | 2 lines * Add a group of console ioctl commands. ........ git-svn-id: branches/fixes_2_0@3265 - --- rtl/freebsd/termios.inc | 17 ++- rtl/inc/int64.inc | 2 +- rtl/linux/linux.pp | 53 +++++++++ rtl/unix/keyboard.pp | 4 +- rtl/unix/video.pp | 252 +++++++++++++++++----------------------- 5 files changed, 178 insertions(+), 150 deletions(-) diff --git a/rtl/freebsd/termios.inc b/rtl/freebsd/termios.inc index 3956732e43..9fa121f132 100644 --- a/rtl/freebsd/termios.inc +++ b/rtl/freebsd/termios.inc @@ -309,11 +309,20 @@ struct winsize { TIOCSDRAINWAIT =IOCTLWRITE+$47400+ 87; { set ttywait timeout } TIOCGDRAINWAIT =IOCTLREAD+$47400+ 86; { get ttywait timeout } - TTYDISC =0; { termios tty line discipline } - SLIPDISC =4; { serial IP discipline } - PPPDISC =5; { PPP discipline } - NETGRAPHDISC =6; { Netgraph tty node discipline } + TTYDISC = 0; { termios tty line discipline } + SLIPDISC = 4; { serial IP discipline } + PPPDISC = 5; { PPP discipline } + NETGRAPHDISC = 6; { Netgraph tty node discipline } + FIOCLEX = IOCTLVOID +$6600+ 1; { set close on exec on fd } + FIONCLEX = IOCTLVOID +$6600+ 2; { remove close on exec } + FIONREAD = IOCTLREAD +$46600+127; { get # bytes to read } + FIONBIO = IOCTLWRITE+$46600+126; { set/clear non-blocking i/o } + FIOASYNC = IOCTLWRITE+$46600+125; { set/clear async i/o } + FIOSETOWN = IOCTLWRITE+$46600+124; { set owner } + FIOGETOWN = IOCTLREAD +$46600+123; { get owner } + FIODTYPE = IOCTLREAD +$46600+122; { get d_flags type part } + FIOGETLBA = IOCTLREAD +$46600+121; { get start blk # } { * Defaults on "first" open. diff --git a/rtl/inc/int64.inc b/rtl/inc/int64.inc index 715e84537b..68b1332cb8 100644 --- a/rtl/inc/int64.inc +++ b/rtl/inc/int64.inc @@ -348,7 +348,7 @@ ((q1>q3) or (q2>q3) or { the bit 63 can be only set if we have $80000000 00000000 } { and sign is true } - ((tqwordrec(q3).high and dword($80000000))<>0) and + (q3 shr 63<>0) and ((q3<>(qword(1) shl 63)) or not(sign)) ) then HandleErrorFrame(215,get_frame); diff --git a/rtl/linux/linux.pp b/rtl/linux/linux.pp index c2422c9386..8b9269b6eb 100644 --- a/rtl/linux/linux.pp +++ b/rtl/linux/linux.pp @@ -61,6 +61,59 @@ Const EPOLL_CTL_MOD = 2; EPOLL_CTL_DEL = 3; + {Some console iotcl's.} + GIO_FONT = $4B60; {gets font in expanded form} + PIO_FONT = $4B61; {use font in expanded form} + GIO_FONTX = $4B6B; {get font using struct consolefontdesc} + PIO_FONTX = $4B6C; {set font using struct consolefontdesc} + PIO_FONTRESET = $4B6D; {reset to default font} + GIO_CMAP = $4B70; {gets colour palette on VGA+} + PIO_CMAP = $4B71; {sets colour palette on VGA+} + KIOCSOUND = $4B2F; {start sound generation (0 for off)} + KDMKTONE = $4B30; {generate tone} + KDGETLED = $4B31; {return current led state} + KDSETLED = $4B32; {set led state [lights, not flags]} + KDGKBTYPE = $4B33; {get keyboard type} + KDADDIO = $4B34; {add i/o port as valid} + KDDELIO = $4B35; {del i/o port as valid} + KDENABIO = $4B36; {enable i/o to video board} + KDDISABIO = $4B37; {disable i/o to video board} + KDSETMODE = $4B3A; {set text/graphics mode} + KDGETMODE = $4B3B; {get current mode} + KDMAPDISP = $4B3C; {map display into address space} + KDUNMAPDISP = $4B3D; {unmap display from address space} + GIO_SCRNMAP = $4B40; {get screen mapping from kernel} + PIO_SCRNMAP = $4B41; {put screen mapping table in kernel} + GIO_UNISCRNMAP = $4B69; {get full Unicode screen mapping} + PIO_UNISCRNMAP = $4B6A; {set full Unicode screen mapping} + GIO_UNIMAP = $4B66; {get unicode-to-font mapping from kernel} + PIO_UNIMAP = $4B67; {put unicode-to-font mapping in kernel} + PIO_UNIMAPCLR = $4B68; {clear table, possibly advise hash algorithm} + KDGKBDIACR = $4B4A; {read kernel accent table} + KDSKBDIACR = $4B4B; {write kernel accent table} + KDGETKEYCODE = $4B4C; {read kernel keycode table entry} + KDSETKEYCODE = $4B4D; {write kernel keycode table entry} + KDSIGACCEPT = $4B4E; {accept kbd generated signals} + KDFONTOP = $4B72; {font operations} + + {Keyboard types (for KDGKBTYPE)} + KB_84 = 1; + KB_101 = 2; {Normal PC keyboard.} + KB_OTHER = 3; + + {Keyboard LED constants.} + LED_SCR = 1; {scroll lock led} + LED_NUM = 2; {num lock led} + LED_CAP = 4; {caps lock led} + + {Tty modes. (for KDSETMODE)} + KD_TEXT = 0; + KD_GRAPHICS = 1; + KD_TEXT0 = 2; {obsolete} + KD_TEXT1 = 3; {obsolete} + + + type TCloneFunc=function(args:pointer):longint;cdecl; diff --git a/rtl/unix/keyboard.pp b/rtl/unix/keyboard.pp index 14752d9db6..dad9625430 100644 --- a/rtl/unix/keyboard.pp +++ b/rtl/unix/keyboard.pp @@ -1247,7 +1247,7 @@ begin { default for Ctrl Prefix is ^W } if CtrlPrefix=0 then CtrlPrefix:=23; - if copy(fpgetenv('TERM'),1,4)='xterm' then + if copy(fpgetenv('TERM'),1,5)='xterm' then {The alt key should generate an escape prefix. Save the old setting make make it send that escape prefix.} write(#27'[?1036s'#27'[?1036h'); @@ -1265,7 +1265,7 @@ begin unpatchkeyboard; {$endif linux} - if copy(fpgetenv('TERM'),1,4)='xterm' then + if copy(fpgetenv('TERM'),1,5)='xterm' then {Restore the old alt key behaviour.} write(#27'[?1036r'); diff --git a/rtl/unix/video.pp b/rtl/unix/video.pp index e3bcf62c43..85573e65f7 100644 --- a/rtl/unix/video.pp +++ b/rtl/unix/video.pp @@ -34,12 +34,15 @@ uses baseunix,termio,strings {$i video.inc} -Type TConsoleType = (ttyNetwork +type Tconsole_type=(ttyNetwork {$ifdef linux},ttyLinux{$endif} ,ttyFreeBSD ,ttyNetBSD); -type Ttermcode=( + Tconversion=(cv_none, + cv_vga_to_acs); + + Ttermcode=( enter_alt_charset_mode, exit_alt_charset_mode, clear_screen, @@ -55,7 +58,7 @@ type Ttermcode=( Ttermcodes=array[Ttermcode] of Pchar; Ptermcodes=^Ttermcodes; -const term_codes_ansi:Ttermcodes= {Linux escape sequences are equal to ansi sequences} +const term_codes_ansi:Ttermcodes= (#$1B#$5B#$31#$31#$6D, {enter_alt_charset_mode} #$1B#$5B#$31#$30#$6D, {exit_alt_charset_mode} #$1B#$5B#$48#$1B#$5B#$4A, {clear_screen} @@ -155,10 +158,12 @@ const terminal_names:array[0..8] of string[7]=( @term_codes_vt220, @term_codes_xterm); +const convert:Tconversion=cv_none; + var LastCursorType : byte; TtyFd: Longint; - Console: TConsoleType; + Console: Tconsole_type; cur_term_strings:Ptermcodes; {$ifdef logging} f: file; @@ -178,95 +183,61 @@ const { can_delete_term : boolean = false;} ACSIn : string = ''; ACSOut : string = ''; - InACS : boolean =false; + in_ACS : boolean =false; + +function convert_vga_to_acs(ch:char):word; + +{Ch contains a character in the VGA character set (i.e. codepage 437). + This routine tries to convert some VGA symbols as well as possible to the + xterm alternate character set. + + Return type is word to allow expanding to UCS-2 characters in the + future.} -function IsACS(var ch,ACSchar : char): boolean; begin - IsACS:=false; case ch of + #18: + convert_vga_to_acs:=word('|'); #24, #30: {} - ch:='^'; + convert_vga_to_acs:=word('^'); #25, #31: {} - ch:='v'; + convert_vga_to_acs:=word('v'); #26, #16: {Never introduce a ctrl-Z ... } - ch:='>'; - {#27,needed in Escape sequences} #17: {} - ch:='<'; + convert_vga_to_acs:=word('>'); + {#27,} #17: {} + convert_vga_to_acs:=word('<'); #176, #177, #178: {°±²} - begin - IsACS:=true; - ACSChar:='a'; - end; + convert_vga_to_acs:=$f800+word('a'); #180, #181, #182, #185: {´µ¶¹} - begin - IsACS:=true; - ACSChar:='u'; - end; + convert_vga_to_acs:=$f800+word('u'); #183, #184, #187, #191: {·¸»¿} - begin - IsACS:=true; - ACSChar:='k'; - end; + convert_vga_to_acs:=$f800+word('k'); #188, #189, #190, #217: {¼½¾Ù} - begin - IsACS:=true; - ACSChar:='j'; - end; + convert_vga_to_acs:=$f800+word('j'); #192, #200, #211, #212: {ÀÈÓÔ} - begin - IsACS:=true; - ACSChar:='m'; - end; + convert_vga_to_acs:=$f800+word('m'); #193, #202, #207, #208: {ÁÊÏÐ} - begin - IsACS:=true; - ACSChar:='v'; - end; + convert_vga_to_acs:=$f800+word('v'); #194, #203, #209, #210: {ÂËÑÒ} - begin - IsACS:=true; - ACSChar:='w'; - end; + convert_vga_to_acs:=$f800+word('w'); #195, #198, #199, #204: {ÃÆÇÌ} - begin - IsACS:=true; - ACSChar:='t'; - end; + convert_vga_to_acs:=$f800+word('t'); #196, #205: {ÄÍ} - begin - IsACS:=true; - ACSChar:='q'; - end; + convert_vga_to_acs:=$f800+word('q'); #179, #186: {³º} - begin - IsACS:=true; - ACSChar:='x'; - end; + convert_vga_to_acs:=$f800+word('x'); #197, #206, #215, #216: {ÅÎר} - begin - IsACS:=true; - ACSChar:='n'; - end; + convert_vga_to_acs:=$f800+word('n'); #201, #213, #214, #218: {ÉÕÖÚ} - begin - IsACS:=true; - ACSChar:='l'; - end; + convert_vga_to_acs:=$f800+word('l'); #254: { þ } - begin - ch:='*'; - end; + convert_vga_to_acs:=word('*'); { Shadows for Buttons } - #220: { Ü } - begin - IsACS:=true; - ACSChar:='a'; - end; + #220 { Ü }, #223: { ß } - begin - IsACS:=true; - ACSChar:='a'; - end; + convert_vga_to_acs:=$f800+word('a'); + else + convert_vga_to_acs:=word(ch); end; end; @@ -298,12 +269,10 @@ begin end; -Function IntStr(l:longint):string; -var - s : string; +function IntStr(l:longint):string; + begin - Str(l,s); - IntStr:=s; + Str(l,intstr); end; @@ -315,7 +284,18 @@ Function XY2Ansi(x,y,ox,oy:longint):String; is (1, 1)), while SetCursorPos parameters and CursorX and CursorY are 0-based (top-left corner of the screen is (0, 0)). } -Begin + +var delta:longint; + direction:char; + movement:string[32]; + +begin + if ((x=1) and (oy+1=y)) and (console<>ttyfreebsd) then + begin + XY2Ansi:=#13#10; + exit; + end; + direction:='H'; if y=oy then begin if x=ox then @@ -328,40 +308,27 @@ Begin XY2Ansi:=#13; exit; end; - if x>ox then - begin - XY2Ansi:=#27'['+IntStr(x-ox)+'C'; - exit; - end - else - begin - XY2Ansi:=#27'['+IntStr(ox-x)+'D'; - exit; - end; + delta:=ox-x; + direction:=char(byte('C')+byte(x<=ox)); end; if x=ox then begin - if y>oy then - begin - XY2Ansi:=#27'['+IntStr(y-oy)+'B'; - exit; - end - else - begin - XY2Ansi:=#27'['+IntStr(oy-y)+'A'; - exit; - end; + delta:=oy-y; + direction:=char(byte('A')+byte(y>oy)); end; - if ((x=1) and (oy+1=y)) and (console<>ttyfreebsd) then - XY2Ansi:=#13#10 + + if direction='H' then + movement:=intstr(y)+';'+intstr(x) else - XY2Ansi:=#27'['+IntStr(y)+';'+IntStr(x)+'H'; -End; + movement:=intstr(abs(delta)); + + xy2ansi:=#27'['+movement+direction; +end; -const - AnsiTbl : string[8]='04261537'; +const ansitbl:array[0..7] of char='04261537'; + Function Attr2Ansi(Attr,OAttr:longint):string; { Convert Attr to an Ansi String, the Optimal code is calculate @@ -408,12 +375,12 @@ begin if (Fg<>OFg) then begin AddSep('3'); - hstr:=hstr+AnsiTbl[(Fg and 7)+1]; + hstr:=hstr+AnsiTbl[fg and 7]; end; if (Bg<>OBg) then begin AddSep('4'); - hstr:=hstr+AnsiTbl[(Bg and 7)+1]; + hstr:=hstr+AnsiTbl[bg and 7]; end; if hstr='0' then hstr:=''; @@ -445,37 +412,38 @@ var p,pold : pvideocell; LastLineWidth : Longint; -procedure TransformUsingACS(var st : string); -var - res : string; - i : longint; - ch,ACSch : char; -begin - res:=''; - for i:=1 to length(st) do - begin - ch:=st[i]; - if IsACS(ch,ACSch) then - begin - if not InACS then - begin - res:=res+ACSIn; - InACS:=true; - end; - res:=res+ACSch; - end - else - begin - if InACS then + procedure transform_using_acs(var st:string); + + var res:string; + i:byte; + c:char; + converted:word; + + begin + res:=''; + for i:=1 to length(st) do + begin + c:=st[i]; + converted:=convert_vga_to_acs(c); + if converted and $ff00=$f800 then + begin + if not in_ACS then + begin + res:=res+ACSIn; + in_ACS:=true; + end; + c:=char(converted and $ff); + end + else + if in_ACS then begin res:=res+ACSOut+Attr2Ansi(LastAttr,0); - InACS:=false; + in_ACS:=false; end; - res:=res+ch; - end; - end; - st:=res; -end; + res:=res+c; + end; + st:=res; + end; @@ -488,8 +456,8 @@ end; hstr:=#13#10+hstr; dec(eol); end; - if NoExtendedFrame and (ACSIn<>'') and (ACSOut<>'') then - TransformUsingACS(Hstr); + if (convert=cv_vga_to_acs) and (ACSIn<>'') and (ACSOut<>'') then + transform_using_acs(Hstr); move(hstr[1],outbuf[outptr],length(hstr)); inc(outptr,length(hstr)); if outptr>=1024 then @@ -527,6 +495,7 @@ end; Spaces:=0; end; +(* function GetTermString(ndx:Ttermcode):String; var P{,pdelay}: PChar; @@ -545,6 +514,7 @@ begin pdelay^:='$';} end; end; +*) begin OutPtr:=0; @@ -657,7 +627,7 @@ begin blockwrite(f,nl,1); {$endif logging} fpWrite(stdoutputhandle,outbuf,outptr); - if InACS then + if in_ACS then SendEscapeSeqNdx(exit_alt_charset_mode); {turn autowrap on} // SendEscapeSeq(#27'[?7h'); @@ -803,9 +773,6 @@ const font_vga:array[0..6] of char=#15#27'%@'#27'(U'; font_custom:array[0..2] of char=#27'(K'; begin -{$ifndef CPUI386} - LowAscii:=false; -{$endif CPUI386} { check for tty } if (IsATTY(stdinputhandle)=1) then begin @@ -863,7 +830,6 @@ begin {No VGA font :( } fpwrite(stdoutputhandle,font_custom,3); { running on a remote terminal, no error with /dev/vcsa } - LowAscii:=false; {$ifdef linux} end; {$endif} @@ -908,7 +874,7 @@ begin if pos('$<',ACSOut)>0 then ACSOut:=Copy(ACSOut,1,Pos('$<',ACSOut)-1);} If fpGetEnv('TERM')='xterm' then - NoExtendedFrame := true; {use of acs for xterm is ok} + convert:=cv_vga_to_acs; {use of acs for xterm is ok} end else begin @@ -932,6 +898,7 @@ var font_custom:array[0..2] of char=#27'(K'; begin prepareDoneVideo; + SetCursorType(crUnderLine); {$ifdef linux} if Console=ttylinux then SetCursorPos(0,0) @@ -942,7 +909,6 @@ begin SendEscapeSeqNdx(cursor_home); SendEscapeSeqNdx(cursor_normal); SendEscapeSeqNdx(cursor_visible); - SetCursorType(crUnderLine); SendEscapeSeq(#27'[H'); if cur_term_strings=@term_codes_linux then begin