consoleio.pas 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. {
  2. This file is part of the Free Pascal run time library.
  3. A file in Amiga system run time library.
  4. Copyright (c) 1998-2003 by Nils Sjoholm
  5. member of the Amiga RTL development team.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit consoleio;
  13. {
  14. History:
  15. First version of ConsoleIO.
  16. This is an translation of consoleio from PCQ Pascal.
  17. Just AttachConsole to a window and you have your
  18. own console.
  19. 12 Sep 2000.
  20. Added the define use_amiga_smartlink.
  21. 13 Jan 2003.
  22. Changed integer > smallint.
  23. 10 Feb 2003.
  24. [email protected]
  25. }
  26. {$I useamigasmartlink.inc}
  27. {$ifdef use_amiga_smartlink}
  28. {$smartlink on}
  29. {$endif use_amiga_smartlink}
  30. interface
  31. uses exec, intuition, console, amigalib, conunit;
  32. TYPE
  33. tConsoleSet = record
  34. WritePort,
  35. ReadPort : pMsgPort;
  36. WriteRequest,
  37. ReadRequest : pIOStdReq;
  38. Window : pWindow; { not yet used }
  39. Buffer : Char;
  40. end;
  41. pConsoleSet = ^tConsoleSet;
  42. {
  43. ConsoleIO.p
  44. This file implements all the normal console.device stuff for
  45. dealing with windows. They are pulled from the ROM Kernel Manual.
  46. See ConsoleTest.p for an example of using these routines.
  47. }
  48. Procedure ConPutChar(Request : pIOStdReq; Character : Char);
  49. Procedure ConWrite(Request : pIOStdReq; Str : pchar; length : longint);
  50. Procedure ConPutStr(Request : pIOStdReq; Str : pchar);
  51. Procedure QueueRead(Request : pIOStdReq; Where : pchar);
  52. Function ConGetChar(consolePort : pMsgPort; Request : pIOStdReq;
  53. WhereTo : pchar) : Char;
  54. Procedure CleanSet(con : pConsoleSet);
  55. Function AttachConsole(w : pWindow) : pConsoleSet;
  56. Function ReadKey(con : pConsoleSet) : Char;
  57. Function KeyPressed(con : pConsoleSet) : Boolean;
  58. Procedure WriteString(con : pConsoleSet; Str : Pchar);
  59. Procedure WriteString(con : pConsoleSet; Str : string);
  60. Function MaxX(con : pConsoleSet) : smallint;
  61. Function MaxY(con : pConsoleSet) : smallint;
  62. Function WhereX(con : pConsoleSet) : smallint;
  63. Function WhereY(con : pConsoleSet) : smallint;
  64. Procedure TextColor(con : pConsoleSet; pen : Byte);
  65. Procedure TextBackground(con : pConsoleSet; pen : Byte);
  66. Procedure DetachConsole(con : pConsoleSet);
  67. Procedure ClrEOL(con : pConsoleSet);
  68. Procedure ClrScr(con : pConsoleSet);
  69. Procedure CursOff(con : pConsoleSet);
  70. Procedure CursOn(con : pConsoleSet);
  71. Procedure DelLine(con : pConsoleSet);
  72. Function LongToStr (I : smallint) : String;
  73. Procedure GotoXY(con : pConsoleSet; x,y : smallint);
  74. Procedure InsLine(con : pConsoleSet);
  75. Procedure OpenConsoleDevice;
  76. Procedure CloseConsoleDevice;
  77. implementation
  78. Procedure ConPutChar(Request : pIOStdReq; Character : Char);
  79. var
  80. Error : longint;
  81. begin
  82. Request^.io_Command := CMD_WRITE;
  83. Request^.io_Data := Addr(Character);
  84. Request^.io_Length := 1;
  85. Error := DoIO(pIORequest(Request));
  86. end;
  87. Procedure ConWrite(Request : pIOStdReq; Str : pchar; length : longint);
  88. var
  89. Error : longint;
  90. begin
  91. Request^.io_Command := CMD_WRITE;
  92. Request^.io_Data := Str;
  93. Request^.io_Length := Length;
  94. Error := DoIO(pIORequest(Request));
  95. end;
  96. Procedure ConPutStr(Request : pIOStdReq; Str : pchar);
  97. var
  98. Error : longint;
  99. begin
  100. Request^.io_Command := CMD_WRITE;
  101. Request^.io_Data := Str;
  102. Request^.io_Length := -1;
  103. Error := DoIO(pIORequest(Request));
  104. end;
  105. Procedure QueueRead(Request : pIOStdReq; Where : pchar);
  106. begin
  107. Request^.io_Command := CMD_READ;
  108. Request^.io_Data := Where;
  109. Request^.io_Length := 1;
  110. SendIO(pIORequest(Request));
  111. end;
  112. Function ConGetChar(consolePort : pMsgPort; Request : pIOStdReq;
  113. WhereTo : pchar) : Char;
  114. var
  115. Temp : Char;
  116. TempMsg : pMessage;
  117. begin
  118. if GetMsg(consolePort) = Nil then begin
  119. TempMsg := WaitPort(consolePort);
  120. TempMsg := GetMsg(consolePort);
  121. end;
  122. Temp := WhereTo^;
  123. QueueRead(Request, WhereTo);
  124. ConGetChar := Temp;
  125. end;
  126. Procedure CleanSet(con : pConsoleSet);
  127. begin
  128. with con^ do begin
  129. if ReadRequest <> Nil then
  130. DeleteStdIO(ReadRequest);
  131. if WriteRequest <> Nil then
  132. DeleteStdIO(WriteRequest);
  133. if ReadPort <> Nil then
  134. DeletePort(ReadPort);
  135. if WritePort <> Nil then
  136. DeletePort(WritePort);
  137. end;
  138. end;
  139. Function AttachConsole(w : pWindow) : pConsoleSet;
  140. var
  141. con : pConsoleSet;
  142. Error : Boolean;
  143. begin
  144. New(con);
  145. if con = Nil then
  146. AttachConsole := Nil;
  147. with Con^ do begin
  148. WritePort := CreatePort(Nil, 0);
  149. Error := WritePort = Nil;
  150. ReadPort := CreatePort(Nil, 0);
  151. Error := Error or (ReadPort = Nil);
  152. if not Error then begin
  153. WriteRequest := CreateStdIO(WritePort);
  154. Error := Error or (WriteRequest = Nil);
  155. ReadRequest := CreateStdIO(ReadPort);
  156. Error := Error or (ReadRequest = Nil);
  157. end;
  158. if Error then begin
  159. CleanSet(con);
  160. Dispose(con);
  161. AttachConsole := Nil;
  162. end;
  163. Window := w;
  164. end;
  165. with con^.WriteRequest^ do begin
  166. io_Data := pointer(w);
  167. io_Length := SizeOf(tWindow);
  168. end;
  169. Error := OpenDevice('console.device', 0,
  170. pIORequest(con^.WriteRequest), 0) <> 0;
  171. if Error then begin
  172. CleanSet(con);
  173. Dispose(con);
  174. AttachConsole := Nil;
  175. end;
  176. with con^ do begin
  177. ReadRequest^.io_Device := WriteRequest^.io_Device;
  178. ReadRequest^.io_Unit := WriteRequest^.io_Unit;
  179. end;
  180. QueueRead(con^.ReadRequest, Addr(con^.Buffer));
  181. AttachConsole := Con;
  182. end;
  183. Function ReadKey(con : pConsoleSet) : Char;
  184. begin
  185. with con^ do
  186. ReadKey := ConGetChar(ReadPort, ReadRequest, Addr(Buffer));
  187. end;
  188. Function KeyPressed(con : pConsoleSet) : Boolean;
  189. begin
  190. with con^ do
  191. KeyPressed := CheckIO(pIORequest(ReadRequest)) <> Nil;
  192. end;
  193. Procedure WriteString(con : pConsoleSet; Str : Pchar);
  194. begin
  195. ConPutStr(con^.WriteRequest, Str);
  196. end;
  197. Procedure WriteString(con : pConsoleSet; Str : string);
  198. var
  199. temp : string;
  200. begin
  201. temp := Str;
  202. temp := temp + #0;
  203. ConPutStr(con^.WriteRequest, @temp[1]);
  204. end;
  205. Function MaxX(con : pConsoleSet) : smallint;
  206. var
  207. CU : pConUnit;
  208. begin
  209. CU := pConUnit(con^.WriteRequest^.io_Unit);
  210. MaxX := CU^.cu_XMax;
  211. end;
  212. Function MaxY(con : pConsoleSet) : smallint;
  213. var
  214. CU : pConUnit;
  215. begin
  216. CU := pConUnit(con^.WriteRequest^.io_Unit);
  217. MaxY := CU^.cu_YMax;
  218. end;
  219. Function WhereX(con : pConsoleSet) : smallint;
  220. var
  221. CU : pConUnit;
  222. begin
  223. CU := pConUnit(con^.WriteRequest^.io_Unit);
  224. WhereX := CU^.cu_XCP;
  225. end;
  226. Function WhereY(con : pConsoleSet) : smallint;
  227. var
  228. CU : pConUnit;
  229. begin
  230. CU := pConUnit(con^.WriteRequest^.io_Unit);
  231. WhereY := CU^.cu_YCP;
  232. end;
  233. Procedure TextColor(con : pConsoleSet; pen : Byte);
  234. var
  235. CU : pConUnit;
  236. begin
  237. CU := pConUnit(con^.WriteRequest^.io_Unit);
  238. CU^.cu_FgPen := pen;
  239. end;
  240. Procedure TextBackground(con : pConsoleSet; pen : Byte);
  241. var
  242. CU : pConUnit;
  243. begin
  244. CU := pConUnit(con^.WriteRequest^.io_Unit);
  245. CU^.cu_BgPen := pen;
  246. end;
  247. Procedure DetachConsole(con : pConsoleSet);
  248. var
  249. TempMsg : pMessage;
  250. begin
  251. with con^ do begin
  252. Forbid;
  253. if CheckIO(pIORequest(ReadRequest)) = Nil then begin
  254. AbortIO(pIORequest(ReadRequest));
  255. Permit;
  256. TempMsg := WaitPort(ReadPort);
  257. TempMsg := GetMsg(ReadPort);
  258. end else
  259. Permit;
  260. CloseDevice(pIORequest(WriteRequest));
  261. end;
  262. CleanSet(con);
  263. Dispose(con);
  264. end;
  265. const
  266. CSI = #27 + '[';
  267. Procedure ClrEOL(con : pConsoleSet);
  268. {
  269. Clear to the end of the line
  270. }
  271. begin
  272. WriteString(con, CSI + 'K');
  273. end;
  274. Procedure ClrScr(con : pConsoleSet);
  275. {
  276. Clear the text area of the window
  277. }
  278. begin
  279. WriteString(con, CSI + '1;1H\cJ');
  280. end;
  281. Procedure CursOff(con : pConsoleSet);
  282. {
  283. Turn the console device's text cursor off
  284. }
  285. begin
  286. WriteString(con, CSI + '0 p');
  287. end;
  288. Procedure CursOn(con : pConsoleSet);
  289. {
  290. Turn the text cursor on
  291. }
  292. begin
  293. WriteString(con, CSI + ' p');
  294. end;
  295. { Delete the current line, moving all the lines below it }
  296. { up one. The bottom line is cleared. }
  297. Procedure DelLine(con : pConsoleSet);
  298. begin
  299. WriteString(con, CSI + 'M');
  300. end;
  301. Function LongToStr (I : smallint) : String;
  302. Var
  303. S : String;
  304. begin
  305. Str (I,S);
  306. LongToStr:=S;
  307. end;
  308. Procedure GotoXY(con : pConsoleSet; x,y : smallint);
  309. {
  310. Move the text cursor to the x,y position. This routine uses
  311. the ANSI CUP command.
  312. }
  313. var
  314. XRep : string[7];
  315. YRep : string[7];
  316. begin
  317. XRep := LongToStr(x);
  318. YRep := LongToStr(y);
  319. WriteString(con,CSI);
  320. WriteString(con,(YRep));
  321. WriteString(con,string(';'));
  322. WriteString(con,(XRep));
  323. WriteString(con,string('H'));
  324. end;
  325. { Insert a line at the current text position. The current line and }
  326. { all those below it are moved down one. }
  327. Procedure InsLine(con : pConsoleSet);
  328. begin
  329. WriteString(con, CSI + 'L');
  330. end;
  331. {
  332. These routines just open and close the Console device without
  333. attaching it to any window. They update ConsoleBase, and are thus required
  334. for RawKeyConvert and DeadKeyConvert.
  335. }
  336. var
  337. ConsoleRequest : tIOStdReq;
  338. Procedure OpenConsoleDevice;
  339. {
  340. This procedure initializes ConsoleDevice, which is required for
  341. CDInputHandler and RawKeyConvert.
  342. }
  343. var
  344. Error : longint;
  345. begin
  346. Error := OpenDevice('console.device', -1, Addr(ConsoleRequest), 0);
  347. ConsoleDevice := ConsoleRequest.io_Device;
  348. end;
  349. Procedure CloseConsoleDevice;
  350. begin
  351. CloseDevice(Addr(ConsoleRequest));
  352. end;
  353. end.