video.pp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. member of the Free Pascal development team
  5. Video unit for Win32
  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 Video;
  13. interface
  14. {$i videoh.inc}
  15. const
  16. useunicodefunctions : boolean = false;
  17. implementation
  18. uses
  19. windows,dos;
  20. {$i video.inc}
  21. type
  22. tunicodecharmappingflag = (umf_noinfo,umf_leadbyte,umf_undefined,
  23. umf_unused);
  24. punicodecharmapping = ^tunicodecharmapping;
  25. tunicodecharmapping = record
  26. unicode : word;
  27. flag : tunicodecharmappingflag;
  28. reserved : byte;
  29. end;
  30. const
  31. mapcp850 : array[0..255] of tunicodecharmapping = (
  32. (unicode : 0; flag : umf_noinfo; reserved : 0),
  33. (unicode : 1; flag : umf_noinfo; reserved : 0),
  34. (unicode : 2; flag : umf_noinfo; reserved : 0),
  35. (unicode : 3; flag : umf_noinfo; reserved : 0),
  36. (unicode : 4; flag : umf_noinfo; reserved : 0),
  37. (unicode : 5; flag : umf_noinfo; reserved : 0),
  38. (unicode : 6; flag : umf_noinfo; reserved : 0),
  39. (unicode : 7; flag : umf_noinfo; reserved : 0),
  40. (unicode : 8; flag : umf_noinfo; reserved : 0),
  41. (unicode : 9; flag : umf_noinfo; reserved : 0),
  42. (unicode : 10; flag : umf_noinfo; reserved : 0),
  43. (unicode : 11; flag : umf_noinfo; reserved : 0),
  44. (unicode : 12; flag : umf_noinfo; reserved : 0),
  45. (unicode : 13; flag : umf_noinfo; reserved : 0),
  46. (unicode : 14; flag : umf_noinfo; reserved : 0),
  47. (unicode : 15; flag : umf_noinfo; reserved : 0),
  48. (unicode : 16; flag : umf_noinfo; reserved : 0),
  49. (unicode : 17; flag : umf_noinfo; reserved : 0),
  50. (unicode : 18; flag : umf_noinfo; reserved : 0),
  51. (unicode : 19; flag : umf_noinfo; reserved : 0),
  52. (unicode : 20; flag : umf_noinfo; reserved : 0),
  53. (unicode : 21; flag : umf_noinfo; reserved : 0),
  54. (unicode : 22; flag : umf_noinfo; reserved : 0),
  55. (unicode : 23; flag : umf_noinfo; reserved : 0),
  56. (unicode : 24; flag : umf_noinfo; reserved : 0),
  57. (unicode : 25; flag : umf_noinfo; reserved : 0),
  58. (unicode : 26; flag : umf_noinfo; reserved : 0),
  59. (unicode : 27; flag : umf_noinfo; reserved : 0),
  60. (unicode : 28; flag : umf_noinfo; reserved : 0),
  61. (unicode : 29; flag : umf_noinfo; reserved : 0),
  62. (unicode : 30; flag : umf_noinfo; reserved : 0),
  63. (unicode : 31; flag : umf_noinfo; reserved : 0),
  64. (unicode : 32; flag : umf_noinfo; reserved : 0),
  65. (unicode : 33; flag : umf_noinfo; reserved : 0),
  66. (unicode : 34; flag : umf_noinfo; reserved : 0),
  67. (unicode : 35; flag : umf_noinfo; reserved : 0),
  68. (unicode : 36; flag : umf_noinfo; reserved : 0),
  69. (unicode : 37; flag : umf_noinfo; reserved : 0),
  70. (unicode : 38; flag : umf_noinfo; reserved : 0),
  71. (unicode : 39; flag : umf_noinfo; reserved : 0),
  72. (unicode : 40; flag : umf_noinfo; reserved : 0),
  73. (unicode : 41; flag : umf_noinfo; reserved : 0),
  74. (unicode : 42; flag : umf_noinfo; reserved : 0),
  75. (unicode : 43; flag : umf_noinfo; reserved : 0),
  76. (unicode : 44; flag : umf_noinfo; reserved : 0),
  77. (unicode : 45; flag : umf_noinfo; reserved : 0),
  78. (unicode : 46; flag : umf_noinfo; reserved : 0),
  79. (unicode : 47; flag : umf_noinfo; reserved : 0),
  80. (unicode : 48; flag : umf_noinfo; reserved : 0),
  81. (unicode : 49; flag : umf_noinfo; reserved : 0),
  82. (unicode : 50; flag : umf_noinfo; reserved : 0),
  83. (unicode : 51; flag : umf_noinfo; reserved : 0),
  84. (unicode : 52; flag : umf_noinfo; reserved : 0),
  85. (unicode : 53; flag : umf_noinfo; reserved : 0),
  86. (unicode : 54; flag : umf_noinfo; reserved : 0),
  87. (unicode : 55; flag : umf_noinfo; reserved : 0),
  88. (unicode : 56; flag : umf_noinfo; reserved : 0),
  89. (unicode : 57; flag : umf_noinfo; reserved : 0),
  90. (unicode : 58; flag : umf_noinfo; reserved : 0),
  91. (unicode : 59; flag : umf_noinfo; reserved : 0),
  92. (unicode : 60; flag : umf_noinfo; reserved : 0),
  93. (unicode : 61; flag : umf_noinfo; reserved : 0),
  94. (unicode : 62; flag : umf_noinfo; reserved : 0),
  95. (unicode : 63; flag : umf_noinfo; reserved : 0),
  96. (unicode : 64; flag : umf_noinfo; reserved : 0),
  97. (unicode : 65; flag : umf_noinfo; reserved : 0),
  98. (unicode : 66; flag : umf_noinfo; reserved : 0),
  99. (unicode : 67; flag : umf_noinfo; reserved : 0),
  100. (unicode : 68; flag : umf_noinfo; reserved : 0),
  101. (unicode : 69; flag : umf_noinfo; reserved : 0),
  102. (unicode : 70; flag : umf_noinfo; reserved : 0),
  103. (unicode : 71; flag : umf_noinfo; reserved : 0),
  104. (unicode : 72; flag : umf_noinfo; reserved : 0),
  105. (unicode : 73; flag : umf_noinfo; reserved : 0),
  106. (unicode : 74; flag : umf_noinfo; reserved : 0),
  107. (unicode : 75; flag : umf_noinfo; reserved : 0),
  108. (unicode : 76; flag : umf_noinfo; reserved : 0),
  109. (unicode : 77; flag : umf_noinfo; reserved : 0),
  110. (unicode : 78; flag : umf_noinfo; reserved : 0),
  111. (unicode : 79; flag : umf_noinfo; reserved : 0),
  112. (unicode : 80; flag : umf_noinfo; reserved : 0),
  113. (unicode : 81; flag : umf_noinfo; reserved : 0),
  114. (unicode : 82; flag : umf_noinfo; reserved : 0),
  115. (unicode : 83; flag : umf_noinfo; reserved : 0),
  116. (unicode : 84; flag : umf_noinfo; reserved : 0),
  117. (unicode : 85; flag : umf_noinfo; reserved : 0),
  118. (unicode : 86; flag : umf_noinfo; reserved : 0),
  119. (unicode : 87; flag : umf_noinfo; reserved : 0),
  120. (unicode : 88; flag : umf_noinfo; reserved : 0),
  121. (unicode : 89; flag : umf_noinfo; reserved : 0),
  122. (unicode : 90; flag : umf_noinfo; reserved : 0),
  123. (unicode : 91; flag : umf_noinfo; reserved : 0),
  124. (unicode : 92; flag : umf_noinfo; reserved : 0),
  125. (unicode : 93; flag : umf_noinfo; reserved : 0),
  126. (unicode : 94; flag : umf_noinfo; reserved : 0),
  127. (unicode : 95; flag : umf_noinfo; reserved : 0),
  128. (unicode : 96; flag : umf_noinfo; reserved : 0),
  129. (unicode : 97; flag : umf_noinfo; reserved : 0),
  130. (unicode : 98; flag : umf_noinfo; reserved : 0),
  131. (unicode : 99; flag : umf_noinfo; reserved : 0),
  132. (unicode : 100; flag : umf_noinfo; reserved : 0),
  133. (unicode : 101; flag : umf_noinfo; reserved : 0),
  134. (unicode : 102; flag : umf_noinfo; reserved : 0),
  135. (unicode : 103; flag : umf_noinfo; reserved : 0),
  136. (unicode : 104; flag : umf_noinfo; reserved : 0),
  137. (unicode : 105; flag : umf_noinfo; reserved : 0),
  138. (unicode : 106; flag : umf_noinfo; reserved : 0),
  139. (unicode : 107; flag : umf_noinfo; reserved : 0),
  140. (unicode : 108; flag : umf_noinfo; reserved : 0),
  141. (unicode : 109; flag : umf_noinfo; reserved : 0),
  142. (unicode : 110; flag : umf_noinfo; reserved : 0),
  143. (unicode : 111; flag : umf_noinfo; reserved : 0),
  144. (unicode : 112; flag : umf_noinfo; reserved : 0),
  145. (unicode : 113; flag : umf_noinfo; reserved : 0),
  146. (unicode : 114; flag : umf_noinfo; reserved : 0),
  147. (unicode : 115; flag : umf_noinfo; reserved : 0),
  148. (unicode : 116; flag : umf_noinfo; reserved : 0),
  149. (unicode : 117; flag : umf_noinfo; reserved : 0),
  150. (unicode : 118; flag : umf_noinfo; reserved : 0),
  151. (unicode : 119; flag : umf_noinfo; reserved : 0),
  152. (unicode : 120; flag : umf_noinfo; reserved : 0),
  153. (unicode : 121; flag : umf_noinfo; reserved : 0),
  154. (unicode : 122; flag : umf_noinfo; reserved : 0),
  155. (unicode : 123; flag : umf_noinfo; reserved : 0),
  156. (unicode : 124; flag : umf_noinfo; reserved : 0),
  157. (unicode : 125; flag : umf_noinfo; reserved : 0),
  158. (unicode : 126; flag : umf_noinfo; reserved : 0),
  159. (unicode : 127; flag : umf_noinfo; reserved : 0),
  160. (unicode : 199; flag : umf_noinfo; reserved : 0),
  161. (unicode : 252; flag : umf_noinfo; reserved : 0),
  162. (unicode : 233; flag : umf_noinfo; reserved : 0),
  163. (unicode : 226; flag : umf_noinfo; reserved : 0),
  164. (unicode : 228; flag : umf_noinfo; reserved : 0),
  165. (unicode : 224; flag : umf_noinfo; reserved : 0),
  166. (unicode : 229; flag : umf_noinfo; reserved : 0),
  167. (unicode : 231; flag : umf_noinfo; reserved : 0),
  168. (unicode : 234; flag : umf_noinfo; reserved : 0),
  169. (unicode : 235; flag : umf_noinfo; reserved : 0),
  170. (unicode : 232; flag : umf_noinfo; reserved : 0),
  171. (unicode : 239; flag : umf_noinfo; reserved : 0),
  172. (unicode : 238; flag : umf_noinfo; reserved : 0),
  173. (unicode : 236; flag : umf_noinfo; reserved : 0),
  174. (unicode : 196; flag : umf_noinfo; reserved : 0),
  175. (unicode : 197; flag : umf_noinfo; reserved : 0),
  176. (unicode : 201; flag : umf_noinfo; reserved : 0),
  177. (unicode : 230; flag : umf_noinfo; reserved : 0),
  178. (unicode : 198; flag : umf_noinfo; reserved : 0),
  179. (unicode : 244; flag : umf_noinfo; reserved : 0),
  180. (unicode : 246; flag : umf_noinfo; reserved : 0),
  181. (unicode : 242; flag : umf_noinfo; reserved : 0),
  182. (unicode : 251; flag : umf_noinfo; reserved : 0),
  183. (unicode : 249; flag : umf_noinfo; reserved : 0),
  184. (unicode : 255; flag : umf_noinfo; reserved : 0),
  185. (unicode : 214; flag : umf_noinfo; reserved : 0),
  186. (unicode : 220; flag : umf_noinfo; reserved : 0),
  187. (unicode : 248; flag : umf_noinfo; reserved : 0),
  188. (unicode : 163; flag : umf_noinfo; reserved : 0),
  189. (unicode : 216; flag : umf_noinfo; reserved : 0),
  190. (unicode : 215; flag : umf_noinfo; reserved : 0),
  191. (unicode : 402; flag : umf_noinfo; reserved : 0),
  192. (unicode : 225; flag : umf_noinfo; reserved : 0),
  193. (unicode : 237; flag : umf_noinfo; reserved : 0),
  194. (unicode : 243; flag : umf_noinfo; reserved : 0),
  195. (unicode : 250; flag : umf_noinfo; reserved : 0),
  196. (unicode : 241; flag : umf_noinfo; reserved : 0),
  197. (unicode : 209; flag : umf_noinfo; reserved : 0),
  198. (unicode : 170; flag : umf_noinfo; reserved : 0),
  199. (unicode : 186; flag : umf_noinfo; reserved : 0),
  200. (unicode : 191; flag : umf_noinfo; reserved : 0),
  201. (unicode : 174; flag : umf_noinfo; reserved : 0),
  202. (unicode : 172; flag : umf_noinfo; reserved : 0),
  203. (unicode : 189; flag : umf_noinfo; reserved : 0),
  204. (unicode : 188; flag : umf_noinfo; reserved : 0),
  205. (unicode : 161; flag : umf_noinfo; reserved : 0),
  206. (unicode : 171; flag : umf_noinfo; reserved : 0),
  207. (unicode : 187; flag : umf_noinfo; reserved : 0),
  208. (unicode : 9617; flag : umf_noinfo; reserved : 0),
  209. (unicode : 9618; flag : umf_noinfo; reserved : 0),
  210. (unicode : 9619; flag : umf_noinfo; reserved : 0),
  211. (unicode : 9474; flag : umf_noinfo; reserved : 0),
  212. (unicode : 9508; flag : umf_noinfo; reserved : 0),
  213. (unicode : 193; flag : umf_noinfo; reserved : 0),
  214. (unicode : 194; flag : umf_noinfo; reserved : 0),
  215. (unicode : 192; flag : umf_noinfo; reserved : 0),
  216. (unicode : 169; flag : umf_noinfo; reserved : 0),
  217. (unicode : 9571; flag : umf_noinfo; reserved : 0),
  218. (unicode : 9553; flag : umf_noinfo; reserved : 0),
  219. (unicode : 9559; flag : umf_noinfo; reserved : 0),
  220. (unicode : 9565; flag : umf_noinfo; reserved : 0),
  221. (unicode : 162; flag : umf_noinfo; reserved : 0),
  222. (unicode : 165; flag : umf_noinfo; reserved : 0),
  223. (unicode : 9488; flag : umf_noinfo; reserved : 0),
  224. (unicode : 9492; flag : umf_noinfo; reserved : 0),
  225. (unicode : 9524; flag : umf_noinfo; reserved : 0),
  226. (unicode : 9516; flag : umf_noinfo; reserved : 0),
  227. (unicode : 9500; flag : umf_noinfo; reserved : 0),
  228. (unicode : 9472; flag : umf_noinfo; reserved : 0),
  229. (unicode : 9532; flag : umf_noinfo; reserved : 0),
  230. (unicode : 227; flag : umf_noinfo; reserved : 0),
  231. (unicode : 195; flag : umf_noinfo; reserved : 0),
  232. (unicode : 9562; flag : umf_noinfo; reserved : 0),
  233. (unicode : 9556; flag : umf_noinfo; reserved : 0),
  234. (unicode : 9577; flag : umf_noinfo; reserved : 0),
  235. (unicode : 9574; flag : umf_noinfo; reserved : 0),
  236. (unicode : 9568; flag : umf_noinfo; reserved : 0),
  237. (unicode : 9552; flag : umf_noinfo; reserved : 0),
  238. (unicode : 9580; flag : umf_noinfo; reserved : 0),
  239. (unicode : 164; flag : umf_noinfo; reserved : 0),
  240. (unicode : 240; flag : umf_noinfo; reserved : 0),
  241. (unicode : 208; flag : umf_noinfo; reserved : 0),
  242. (unicode : 202; flag : umf_noinfo; reserved : 0),
  243. (unicode : 203; flag : umf_noinfo; reserved : 0),
  244. (unicode : 200; flag : umf_noinfo; reserved : 0),
  245. (unicode : 305; flag : umf_noinfo; reserved : 0),
  246. (unicode : 205; flag : umf_noinfo; reserved : 0),
  247. (unicode : 206; flag : umf_noinfo; reserved : 0),
  248. (unicode : 207; flag : umf_noinfo; reserved : 0),
  249. (unicode : 9496; flag : umf_noinfo; reserved : 0),
  250. (unicode : 9484; flag : umf_noinfo; reserved : 0),
  251. (unicode : 9608; flag : umf_noinfo; reserved : 0),
  252. (unicode : 9604; flag : umf_noinfo; reserved : 0),
  253. (unicode : 166; flag : umf_noinfo; reserved : 0),
  254. (unicode : 204; flag : umf_noinfo; reserved : 0),
  255. (unicode : 9600; flag : umf_noinfo; reserved : 0),
  256. (unicode : 211; flag : umf_noinfo; reserved : 0),
  257. (unicode : 223; flag : umf_noinfo; reserved : 0),
  258. (unicode : 212; flag : umf_noinfo; reserved : 0),
  259. (unicode : 210; flag : umf_noinfo; reserved : 0),
  260. (unicode : 245; flag : umf_noinfo; reserved : 0),
  261. (unicode : 213; flag : umf_noinfo; reserved : 0),
  262. (unicode : 181; flag : umf_noinfo; reserved : 0),
  263. (unicode : 254; flag : umf_noinfo; reserved : 0),
  264. (unicode : 222; flag : umf_noinfo; reserved : 0),
  265. (unicode : 218; flag : umf_noinfo; reserved : 0),
  266. (unicode : 219; flag : umf_noinfo; reserved : 0),
  267. (unicode : 217; flag : umf_noinfo; reserved : 0),
  268. (unicode : 253; flag : umf_noinfo; reserved : 0),
  269. (unicode : 221; flag : umf_noinfo; reserved : 0),
  270. (unicode : 175; flag : umf_noinfo; reserved : 0),
  271. (unicode : 180; flag : umf_noinfo; reserved : 0),
  272. (unicode : 173; flag : umf_noinfo; reserved : 0),
  273. (unicode : 177; flag : umf_noinfo; reserved : 0),
  274. (unicode : 8215; flag : umf_noinfo; reserved : 0),
  275. (unicode : 190; flag : umf_noinfo; reserved : 0),
  276. (unicode : 182; flag : umf_noinfo; reserved : 0),
  277. (unicode : 167; flag : umf_noinfo; reserved : 0),
  278. (unicode : 247; flag : umf_noinfo; reserved : 0),
  279. (unicode : 184; flag : umf_noinfo; reserved : 0),
  280. (unicode : 176; flag : umf_noinfo; reserved : 0),
  281. (unicode : 168; flag : umf_noinfo; reserved : 0),
  282. (unicode : 183; flag : umf_noinfo; reserved : 0),
  283. (unicode : 185; flag : umf_noinfo; reserved : 0),
  284. (unicode : 179; flag : umf_noinfo; reserved : 0),
  285. (unicode : 178; flag : umf_noinfo; reserved : 0),
  286. (unicode : 9632; flag : umf_noinfo; reserved : 0),
  287. (unicode : 160; flag : umf_noinfo; reserved : 0)
  288. );
  289. const
  290. LastCursorType: word = crUnderline;
  291. OrigScreen: PVideoBuf = nil;
  292. OrigScreenSize: cardinal = 0;
  293. var ConsoleInfo : TConsoleScreenBufferInfo;
  294. ConsoleCursorInfo : TConsoleCursorInfo;
  295. OrigCP: cardinal;
  296. OrigConsoleCursorInfo : TConsoleCursorInfo;
  297. OrigConsoleInfo : TConsoleScreenBufferInfo;
  298. procedure SysInitVideo;
  299. begin
  300. ScreenColor:=true;
  301. GetConsoleScreenBufferInfo(TextRec(Output).Handle, OrigConsoleInfo);
  302. GetConsoleCursorInfo(TextRec(Output).Handle, OrigConsoleCursorInfo);
  303. OrigCP := GetConsoleCP;
  304. ConsoleInfo:=OrigConsoleInfo;
  305. ConsoleCursorInfo:=OrigConsoleCursorInfo;
  306. {
  307. About the ConsoleCursorInfo record: There are 3 possible
  308. structures in it that can be regarded as the 'screen':
  309. - dwsize : contains the cols & row in current screen buffer.
  310. - srwindow : Coordinates (relative to buffer) of upper left
  311. & lower right corners of visible console.
  312. - dmMaximumWindowSize : Maximal size of Screen buffer.
  313. The first implementation of video used srWindow. After some
  314. bug-reports, this was switched to dwMaximumWindowSize.
  315. }
  316. with ConsoleInfo.dwMaximumWindowSize do
  317. begin
  318. ScreenWidth:=X;
  319. ScreenHeight:=Y;
  320. end;
  321. { TDrawBuffer only has FVMaxWidth elements
  322. larger values lead to crashes }
  323. if ScreenWidth> FVMaxWidth then
  324. ScreenWidth:=FVMaxWidth;
  325. CursorX:=ConsoleInfo.dwCursorPosition.x;
  326. CursorY:=ConsoleInfo.dwCursorPosition.y;
  327. if not ConsoleCursorInfo.bvisible then
  328. CursorLines:=0
  329. else
  330. CursorLines:=ConsoleCursorInfo.dwSize;
  331. end;
  332. procedure SysDoneVideo;
  333. begin
  334. SetConsoleScreenBufferSize (TextRec (Output).Handle, OrigConsoleInfo.dwSize);
  335. SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, OrigConsoleInfo.srWindow);
  336. SetConsoleCursorInfo(TextRec(Output).Handle, OrigConsoleCursorInfo);
  337. SetConsoleCP(OrigCP);
  338. end;
  339. function SysGetCapabilities: Word;
  340. begin
  341. SysGetCapabilities:=cpColor or cpChangeCursor;
  342. end;
  343. procedure SysSetCursorPos(NewCursorX, NewCursorY: Word);
  344. var
  345. pos : COORD;
  346. begin
  347. pos.x:=NewCursorX;
  348. pos.y:=NewCursorY;
  349. SetConsoleCursorPosition(TextRec(Output).Handle,pos);
  350. CursorX:=pos.x;
  351. CursorY:=pos.y;
  352. end;
  353. function SysGetCursorType: Word;
  354. begin
  355. GetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
  356. if not ConsoleCursorInfo.bvisible then
  357. SysGetCursorType:=crHidden
  358. else
  359. case ConsoleCursorInfo.dwSize of
  360. 1..30:
  361. SysGetCursorType:=crUnderline;
  362. 31..70:
  363. SysGetCursorType:=crHalfBlock;
  364. 71..100:
  365. SysGetCursorType:=crBlock;
  366. end;
  367. end;
  368. procedure SysSetCursorType(NewType: Word);
  369. begin
  370. GetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
  371. if newType=crHidden then
  372. ConsoleCursorInfo.bvisible:=false
  373. else
  374. begin
  375. ConsoleCursorInfo.bvisible:=true;
  376. case NewType of
  377. crUnderline:
  378. ConsoleCursorInfo.dwSize:=10;
  379. crHalfBlock:
  380. ConsoleCursorInfo.dwSize:=50;
  381. crBlock:
  382. ConsoleCursorInfo.dwSize:=99;
  383. end
  384. end;
  385. SetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
  386. end;
  387. function SysVideoModeSelector (const VideoMode: TVideoMode): boolean;
  388. var MI: Console_Screen_Buffer_Info;
  389. C: Coord;
  390. SR: Small_Rect;
  391. begin
  392. if not (GetConsoleScreenBufferInfo (TextRec (Output).Handle, MI)) then
  393. SysVideoModeSelector := false
  394. else
  395. begin
  396. with MI do
  397. begin
  398. C.X := VideoMode.Col;
  399. C.Y := VideoMode.Row;
  400. end;
  401. with SR do
  402. begin
  403. Top := 0;
  404. Left := 0;
  405. { First, we need to make sure we reach the minimum window size
  406. to always fit in the new buffer after changing buffer size. }
  407. Right := MI.srWindow.Right - MI.srWindow.Left;
  408. if VideoMode.Col <= Right then
  409. Right := Pred (VideoMode.Col);
  410. Bottom := MI.srWindow.Bottom - MI.srWindow.Top;
  411. if VideoMode.Row <= Bottom then
  412. Bottom := Pred (VideoMode.Row);
  413. end;
  414. if SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, SR) then
  415. if SetConsoleScreenBufferSize (TextRec (Output).Handle, C) then
  416. begin
  417. with SR do
  418. begin
  419. { Now, we can resize the window to the final size. }
  420. Right := Pred (VideoMode.Col);
  421. Bottom := Pred (VideoMode.Row);
  422. end;
  423. if SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, SR) then
  424. begin
  425. SysVideoModeSelector := true;
  426. SetCursorType (LastCursorType);
  427. ClearScreen;
  428. end
  429. else
  430. begin
  431. SysVideoModeSelector := false;
  432. SetConsoleScreenBufferSize (TextRec (Output).Handle, MI.dwSize);
  433. SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, MI.srWindow);
  434. SetCursorType (LastCursorType);
  435. end
  436. end
  437. else
  438. begin
  439. SysVideoModeSelector := false;
  440. SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, MI.srWindow);
  441. SetCursorType (LastCursorType);
  442. end
  443. else
  444. SysVideoModeSelector := false;
  445. end;
  446. end;
  447. Const
  448. SysVideoModeCount = 6;
  449. SysVMD : Array[0..SysVideoModeCount-1] of TVideoMode = (
  450. (Col: 40; Row: 25; Color: True),
  451. (Col: 80; Row: 25; Color: True),
  452. (Col: 80; Row: 30; Color: True),
  453. (Col: 80; Row: 43; Color: True),
  454. (Col: 80; Row: 50; Color: True),
  455. (Col: 80; Row: 25; Color: True) // Reserved for TargetEntry
  456. );
  457. Function SysSetVideoMode (Const Mode : TVideoMode) : Boolean;
  458. Var
  459. I : Integer;
  460. begin
  461. I:=SysVideoModeCount-1;
  462. SysSetVideoMode:=False;
  463. While (I>=0) and Not SysSetVideoMode do
  464. If (Mode.col=SysVMD[i].col) and
  465. (Mode.Row=SysVMD[i].Row) and
  466. (Mode.Color=SysVMD[i].Color) then
  467. SysSetVideoMode:=True
  468. else
  469. Dec(I);
  470. If SysSetVideoMode then
  471. begin
  472. if SysVideoModeSelector(Mode) then
  473. begin
  474. ScreenWidth:=SysVMD[I].Col;
  475. ScreenHeight:=SysVMD[I].Row;
  476. ScreenColor:=SysVMD[I].Color;
  477. end else SysSetVideoMode := false;
  478. end;
  479. end;
  480. Function SysGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean;
  481. begin
  482. SysGetVideoModeData:=(Index<=high(SysVMD));
  483. If SysGetVideoModeData then
  484. Data:=SysVMD[Index];
  485. end;
  486. Function SysGetVideoModeCount : Word;
  487. begin
  488. SysGetVideoModeCount:=SysVideoModeCount;
  489. end;
  490. procedure SysClearScreen;
  491. begin
  492. UpdateScreen(true);
  493. end;
  494. procedure SysUpdateScreen(Force: Boolean);
  495. type TmpRec = Array[0..(1024*32) - 1] of TCharInfo;
  496. type WordRec = record
  497. One, Two: Byte;
  498. end; { wordrec }
  499. var
  500. BufSize,
  501. BufCoord : COORD;
  502. WriteRegion : SMALL_RECT;
  503. LineBuf : ^TmpRec;
  504. BufCounter : Longint;
  505. LineCounter,
  506. ColCounter : Longint;
  507. smallforce : boolean;
  508. x1,y1,x2,y2 : longint;
  509. begin
  510. if force then
  511. smallforce:=true
  512. else
  513. begin
  514. asm
  515. pushl %esi
  516. pushl %edi
  517. movl VideoBuf,%esi
  518. movl OldVideoBuf,%edi
  519. movl VideoBufSize,%ecx
  520. shrl $2,%ecx
  521. repe
  522. cmpsl
  523. setne smallforce
  524. popl %edi
  525. popl %esi
  526. end;
  527. end;
  528. if SmallForce then
  529. begin
  530. BufSize.X := ScreenWidth;
  531. BufSize.Y := ScreenHeight;
  532. BufCoord.X := 0;
  533. BufCoord.Y := 0;
  534. with WriteRegion do
  535. begin
  536. Top :=0;
  537. Left :=0;
  538. Bottom := ScreenHeight-1;
  539. Right := ScreenWidth-1;
  540. end;
  541. New(LineBuf);
  542. BufCounter := 0;
  543. x1:=ScreenWidth+1;
  544. x2:=-1;
  545. y1:=ScreenHeight+1;
  546. y2:=-1;
  547. for LineCounter := 1 to ScreenHeight do
  548. begin
  549. for ColCounter := 1 to ScreenWidth do
  550. begin
  551. if (WordRec(VideoBuf^[BufCounter]).One<>WordRec(OldVideoBuf^[BufCounter]).One) or
  552. (WordRec(VideoBuf^[BufCounter]).Two<>WordRec(OldVideoBuf^[BufCounter]).Two) then
  553. begin
  554. if ColCounter<x1 then
  555. x1:=ColCounter;
  556. if ColCounter>x2 then
  557. x2:=ColCounter;
  558. if LineCounter<y1 then
  559. y1:=LineCounter;
  560. if LineCounter>y2 then
  561. y2:=LineCounter;
  562. end;
  563. if useunicodefunctions then
  564. LineBuf^[BufCounter].UniCodeChar := Widechar(mapcp850[WordRec(VideoBuf^[BufCounter]).One].unicode)
  565. else
  566. LineBuf^[BufCounter].UniCodeChar := Widechar(WordRec(VideoBuf^[BufCounter]).One);
  567. { If (WordRec(VideoBuf^[BufCounter]).Two and $80)<>0 then
  568. LineBuf^[BufCounter].Attributes := $100+WordRec(VideoBuf^[BufCounter]).Two
  569. else }
  570. LineBuf^[BufCounter].Attributes := WordRec(VideoBuf^[BufCounter]).Two;
  571. Inc(BufCounter);
  572. end; { for }
  573. end; { for }
  574. BufSize.X := ScreenWidth;
  575. BufSize.Y := ScreenHeight;
  576. with WriteRegion do
  577. begin
  578. if force then
  579. begin
  580. Top := 0;
  581. Left :=0;
  582. Bottom := ScreenHeight-1;
  583. Right := ScreenWidth-1;
  584. BufCoord.X := 0;
  585. BufCoord.Y := 0;
  586. end
  587. else
  588. begin
  589. Top := y1-1;
  590. Left :=x1-1;
  591. Bottom := y2-1;
  592. Right := x2-1;
  593. BufCoord.X := x1-1;
  594. BufCoord.Y := y1-1;
  595. end;
  596. end;
  597. {
  598. writeln('X1: ',x1);
  599. writeln('Y1: ',y1);
  600. writeln('X2: ',x2);
  601. writeln('Y2: ',y2);
  602. }
  603. if useunicodefunctions then
  604. WriteConsoleOutputW(TextRec(Output).Handle, LineBuf, BufSize, BufCoord, WriteRegion)
  605. else
  606. WriteConsoleOutput(TextRec(Output).Handle, LineBuf, BufSize, BufCoord, WriteRegion);
  607. Dispose(LineBuf);
  608. move(VideoBuf^,OldVideoBuf^,VideoBufSize);
  609. end;
  610. end;
  611. Const
  612. SysVideoDriver : TVideoDriver = (
  613. InitDriver : @SysInitVideo;
  614. DoneDriver : @SysDoneVideo;
  615. UpdateScreen : @SysUpdateScreen;
  616. ClearScreen : @SysClearScreen;
  617. SetVideoMode : @SysSetVideoMode;
  618. GetVideoModeCount : @SysGetVideoModeCount;
  619. GetVideoModeData : @SysGetVideoModeData;
  620. SetCursorPos : @SysSetCursorPos;
  621. GetCursorType : @SysGetCursorType;
  622. SetCursorType : @SysSetCursorType;
  623. GetCapabilities : @SysGetCapabilities
  624. );
  625. procedure TargetEntry;
  626. var
  627. C: Coord;
  628. SR: Small_Rect;
  629. VioMode: TConsoleScreenBufferInfo;
  630. begin
  631. GetConsoleScreenBufferInfo (TextRec (Output).Handle, VioMode);
  632. { Register the curent video mode in reserved slot in System Modes}
  633. with VioMode do
  634. begin
  635. {Assume we have at least 16 colours available in "colour" modes}
  636. SysVMD[SysVideoModeCount-1].Col:=dwMaximumWindowSize.X;
  637. SysVMD[SysVideoModeCount-1].Row:=dwMaximumWindowSize.Y;
  638. SysVMD[SysVideoModeCount-1].Color:=true;
  639. OrigScreenSize := max(dwMaximumWindowSize.X,dwSize.X) * max(dwMaximumWindowSize.Y,dwSize.Y) * SizeOf (Char_Info);
  640. end;
  641. GetMem (OrigScreen, OrigScreenSize);
  642. with C do
  643. begin
  644. X := 0;
  645. Y := 0;
  646. end;
  647. with SR do
  648. begin
  649. Top := 0;
  650. Left := 0;
  651. Right := Pred (VioMode.dwSize.X);
  652. Bottom := Pred (VioMode.dwSize.Y);
  653. end;
  654. if not (ReadConsoleOutput (TextRec (Output).Handle, OrigScreen, VioMode.dwSize, C, SR)) then
  655. begin
  656. FreeMem (OrigScreen, OrigScreenSize);
  657. OrigScreen := nil;
  658. OrigScreenSize := 0;
  659. end;
  660. end;
  661. initialization
  662. SetVideoDriver(SysVideoDriver);
  663. TargetEntry;
  664. end.