files
SDK/Lib/KoW/CRT.inc

251 lines
6.4 KiB
PHP

(*
KolibriOS on Windows (KoW) CRT unit
Copyright (c) 2021 Delphi SDK for KolibriOS team
*)
type
TConsoleFontInfo = packed record
Number: LongWord;
Size: TCoord;
end;
var
// Console.obj defaults
ScrSize: TCoord = (X: 80; Y: 300);
WndPos: TPoint = (X: 200; Y: 50);
WndSize: TPoint = (X: 80; Y: 25);
SaveInputCP, SaveOutputCP: Word;
const
msvcrt = 'msvcrt.dll';
function GetCurrentConsoleFont(hConsole: THandle; MaximumWindow: LongBool; var Info: TConsoleFontInfo): LongBool; stdcall;
external kernel32 name 'GetCurrentConsoleFont';
function GetConsoleWindow: THandle; stdcall;
external kernel32 name 'GetConsoleWindow';
function _cgets_s(Buffer: PKolibriChar; Count: Cardinal; var Read: Cardinal): PKolibriChar; cdecl;
external msvcrt name '_cgets_s';
function _cputs(Str: PKolibriChar): Integer; cdecl;
external msvcrt name '_cputs';
function _getch: KolibriChar; cdecl;
external msvcrt name '_getch';
function gets: PKolibriChar; cdecl;
external msvcrt name 'gets';
function _kbhit: Integer; cdecl;
external msvcrt name '_kbhit';
function _cprintf(Fmt: PKolibriChar): Integer; cdecl varargs;
external msvcrt name '_cprintf';
procedure con_set_cursor_pos(X, Y: Integer); stdcall; forward; // call local proc from con_cls
procedure con_cls; stdcall;
var
Info: TConsoleScreenBufferInfo;
Point: TCoord;
Written: LongWord;
begin
if GetConsoleScreenBufferInfo(TTextRec(Output).Handle, Info) then
begin
Point.X := 0;
Point.Y := 0;
with Info.dwSize do
FillConsoleOutputCharacter(TTextRec(Output).Handle, ' ', X * Y, Point, Written);
end;
con_set_cursor_pos(0, 0);
end;
procedure con_exit(CloseWindow: Boolean); stdcall;
begin
if not CloseWindow then
begin
CursorOff;
_getch;
end;
SetConsoleCP(SaveInputCP);
SetConsoleOutputCP(SaveOutputCP);
TTextRec(Input).Handle := 0;
TTextRec(Output).Handle := 0;
end;
procedure con_init(WndWidth, WndHeight, ScrWidth, ScrHeight: LongWord; Title: PKolibriChar); stdcall;
{$IFDEF Debug}
var
Font: TConsoleFontInfo;
R: TSmallRect;
{$ENDIF}
begin
{$IFDEF Debug}
if not IsConsole then
AllocConsole;
{$ENDIF}
TTextRec(Input).Handle := System.GetStdHandle(STD_INPUT_HANDLE);
TTextRec(Output).Handle := System.GetStdHandle(STD_OUTPUT_HANDLE);
{$IFDEF Debug}
SaveInputCP := GetConsoleCP;
SetConsoleCP(CP_KOLIBRIOS);
SaveOutputCP := GetConsoleOutputCP;
SetConsoleOutputCP(CP_KOLIBRIOS);
SetConsoleTitleA(Title);
if WndWidth <> LongWord(-1) then
WndSize.X := WndWidth;
if WndHeight <> LongWord(-1) then
WndSize.Y := WndHeight;
MainWindow := GetConsoleWindow;
GetCurrentConsoleFont(TTextRec(Output).Handle, False, Font);
SetWindowPos(MainWindow, 0, WndPos.X, WndPos.Y,
Font.Size.X * WndSize.X + GetSystemMetrics(SM_CXVSCROLL), Font.Size.Y * WndSize.Y + GetSystemMetrics(SM_CYHSCROLL), 0);
if ScrWidth <> LongWord(-1) then
ScrSize.X := ScrWidth;
if ScrHeight <> LongWord(-1) then
ScrSize.Y := ScrHeight;
SetConsoleScreenBufferSize(TTextRec(Output).Handle, ScrSize);
with R do
begin
Left := 0;
Top := 0;
Right := ScrSize.X - 1;
Bottom := ScrSize.Y - 1;
end;
SetConsoleWindowInfo(TTextRec(Output).Handle, True, R);
{$ENDIF}
end;
function con_get_cursor_height: Integer; stdcall;
var
Info: TConsoleCursorInfo;
begin
GetConsoleCursorInfo(TTextRec(Output).Handle, Info);
Result := Info.dwSize;
end;
procedure con_get_cursor_pos(var X, Y: Integer); stdcall;
var
Info: TConsoleScreenBufferInfo;
begin
GetConsoleScreenBufferInfo(TTextRec(Output).Handle, Info);
with Info do
begin
X := dwCursorPosition.X;
Y := dwCursorPosition.Y;
end;
end;
function con_get_flags: LongWord; stdcall
var
Info: TConsoleScreenBufferInfo;
begin
GetConsoleScreenBufferInfo(TTextRec(Output).Handle, Info);
Result := Info.wAttributes;
end;
function con_get_font_height: Integer; stdcall;
var
Font: TConsoleFontInfo;
begin
GetCurrentConsoleFont(TTextRec(Output).Handle, False, Font);
Result := Font.Size.Y;
end;
function con_getch: KolibriChar; stdcall;
begin
Result := _getch;
end;
function con_gets(Str: PKolibriChar; Length: Integer): PKolibriChar; stdcall;
var
LF: KolibriChar;
Read: Cardinal;
begin
_cgets_s(Str, Length, Read);
_cgets_s(@LF, SizeOf(LF), Read);
Result := Str;
end;
function con_gets2(Callback: con_gets2_callback; Str: PKolibriChar; Length: Integer): PKolibriChar; stdcall;
begin
Result := con_gets(Str, Length);
end;
function con_kbhit: Boolean; stdcall;
begin
Result := _kbhit <> 0;
end;
function con_set_cursor_height(Height: Integer): Integer; stdcall;
var
Info: TConsoleCursorInfo;
begin
GetConsoleCursorInfo(TTextRec(Output).Handle, Info);
Result := Info.dwSize;
if Height <> 0 then
Info.dwSize := Height;
Info.bVisible := Height <> 0;
SetConsoleCursorInfo (TTextRec(Output).Handle, Info);
end;
procedure con_set_cursor_pos(X, Y: Integer); stdcall;
var
Coord: TCoord;
begin
Coord.X := X;
Coord.Y := Y;
SetConsoleCursorPosition(TTextRec(Output).Handle, Coord);
end;
function con_set_flags(Flags: LongWord): LongWord; stdcall;
begin
Result := con_get_flags;
SetConsoleTextAttribute(TTextRec(Output).Handle, Flags and $FF);
end;
procedure con_write_string(Str: PKolibriChar; Length: LongWord); stdcall;
var
Written: Cardinal;
begin
System.WriteFile(TTextRec(Output).Handle, Str^, Length, Written, nil);
end;
procedure con_write_asciiz(Str: PKolibriChar); stdcall;
begin
_cputs(Str);
end;
procedure Delay(Milliseconds: LongWord);
begin
Sleep(Milliseconds);
end;
procedure InitKoW;
begin
Pointer(@System.con_cls) := @con_cls;
Pointer(@System.con_exit) := @con_exit;
Pointer(@System.con_init) := @con_init;
Pointer(@System.con_getch) := @con_getch;
Pointer(@System.con_get_flags) := @con_get_flags;
Pointer(@System.con_get_cursor_height) := @con_get_cursor_height;
Pointer(@System.con_get_cursor_pos) := @con_get_cursor_pos;
Pointer(@System.con_get_font_height) := @con_get_font_height;
Pointer(@System.con_gets) := @con_gets;
Pointer(@System.con_gets2) := @con_gets2;
Pointer(@System.con_kbhit) := @con_kbhit;
Pointer(@System.con_printf) := @_cprintf;
Pointer(@System.con_set_cursor_height) := @con_set_cursor_height;
Pointer(@System.con_set_cursor_pos) := @con_set_cursor_pos;
Pointer(@System.con_set_flags) := @con_set_flags;
Pointer(@System.con_set_title) := @Windows.SetConsoleTitleA;
Pointer(@System.con_write_asciiz) := @con_write_asciiz;
Pointer(@System.con_write_string) := @con_write_string;
end;