video.pp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  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 WordRec = record
  496. One, Two: Byte;
  497. end; { wordrec }
  498. var
  499. BufSize,
  500. BufCoord : COORD;
  501. WriteRegion : SMALL_RECT;
  502. LineBuf : Array[0..(1024*32) - 1] of TCharInfo;
  503. BufCounter : Longint;
  504. LineCounter,
  505. ColCounter : Longint;
  506. smallforce : boolean;
  507. x1,y1,x2,y2 : longint;
  508. begin
  509. if force then
  510. smallforce:=true
  511. else
  512. begin
  513. asm
  514. pushl %esi
  515. pushl %edi
  516. movl VideoBuf,%esi
  517. movl OldVideoBuf,%edi
  518. movl VideoBufSize,%ecx
  519. shrl $2,%ecx
  520. repe
  521. cmpsl
  522. setne smallforce
  523. popl %edi
  524. popl %esi
  525. end;
  526. end;
  527. if SmallForce then
  528. begin
  529. BufSize.X := ScreenWidth;
  530. BufSize.Y := ScreenHeight;
  531. BufCoord.X := 0;
  532. BufCoord.Y := 0;
  533. with WriteRegion do
  534. begin
  535. Top :=0;
  536. Left :=0;
  537. Bottom := ScreenHeight-1;
  538. Right := ScreenWidth-1;
  539. end;
  540. BufCounter := 0;
  541. x1:=ScreenWidth+1;
  542. x2:=-1;
  543. y1:=ScreenHeight+1;
  544. y2:=-1;
  545. for LineCounter := 1 to ScreenHeight do
  546. begin
  547. for ColCounter := 1 to ScreenWidth do
  548. begin
  549. if (WordRec(VideoBuf^[BufCounter]).One<>WordRec(OldVideoBuf^[BufCounter]).One) or
  550. (WordRec(VideoBuf^[BufCounter]).Two<>WordRec(OldVideoBuf^[BufCounter]).Two) then
  551. begin
  552. if ColCounter<x1 then
  553. x1:=ColCounter;
  554. if ColCounter>x2 then
  555. x2:=ColCounter;
  556. if LineCounter<y1 then
  557. y1:=LineCounter;
  558. if LineCounter>y2 then
  559. y2:=LineCounter;
  560. end;
  561. if useunicodefunctions then
  562. LineBuf[BufCounter].UniCodeChar := Widechar(mapcp850[WordRec(VideoBuf^[BufCounter]).One].unicode)
  563. else
  564. LineBuf[BufCounter].UniCodeChar := Widechar(WordRec(VideoBuf^[BufCounter]).One);
  565. { If (WordRec(VideoBuf^[BufCounter]).Two and $80)<>0 then
  566. LineBuf^[BufCounter].Attributes := $100+WordRec(VideoBuf^[BufCounter]).Two
  567. else }
  568. LineBuf[BufCounter].Attributes := WordRec(VideoBuf^[BufCounter]).Two;
  569. Inc(BufCounter);
  570. end; { for }
  571. end; { for }
  572. BufSize.X := ScreenWidth;
  573. BufSize.Y := ScreenHeight;
  574. with WriteRegion do
  575. begin
  576. if force then
  577. begin
  578. Top := 0;
  579. Left :=0;
  580. Bottom := ScreenHeight-1;
  581. Right := ScreenWidth-1;
  582. BufCoord.X := 0;
  583. BufCoord.Y := 0;
  584. end
  585. else
  586. begin
  587. Top := y1-1;
  588. Left :=x1-1;
  589. Bottom := y2-1;
  590. Right := x2-1;
  591. BufCoord.X := x1-1;
  592. BufCoord.Y := y1-1;
  593. end;
  594. end;
  595. {
  596. writeln('X1: ',x1);
  597. writeln('Y1: ',y1);
  598. writeln('X2: ',x2);
  599. writeln('Y2: ',y2);
  600. }
  601. if useunicodefunctions then
  602. WriteConsoleOutputW(TextRec(Output).Handle, @LineBuf, BufSize, BufCoord, WriteRegion)
  603. else
  604. WriteConsoleOutput(TextRec(Output).Handle, @LineBuf, BufSize, BufCoord, WriteRegion);
  605. move(VideoBuf^,OldVideoBuf^,VideoBufSize);
  606. end;
  607. end;
  608. Const
  609. SysVideoDriver : TVideoDriver = (
  610. InitDriver : @SysInitVideo;
  611. DoneDriver : @SysDoneVideo;
  612. UpdateScreen : @SysUpdateScreen;
  613. ClearScreen : @SysClearScreen;
  614. SetVideoMode : @SysSetVideoMode;
  615. GetVideoModeCount : @SysGetVideoModeCount;
  616. GetVideoModeData : @SysGetVideoModeData;
  617. SetCursorPos : @SysSetCursorPos;
  618. GetCursorType : @SysGetCursorType;
  619. SetCursorType : @SysSetCursorType;
  620. GetCapabilities : @SysGetCapabilities
  621. );
  622. procedure TargetEntry;
  623. var
  624. C: Coord;
  625. SR: Small_Rect;
  626. VioMode: TConsoleScreenBufferInfo;
  627. begin
  628. GetConsoleScreenBufferInfo (TextRec (Output).Handle, VioMode);
  629. { Register the curent video mode in reserved slot in System Modes}
  630. with VioMode do
  631. begin
  632. {Assume we have at least 16 colours available in "colour" modes}
  633. SysVMD[SysVideoModeCount-1].Col:=dwMaximumWindowSize.X;
  634. SysVMD[SysVideoModeCount-1].Row:=dwMaximumWindowSize.Y;
  635. SysVMD[SysVideoModeCount-1].Color:=true;
  636. OrigScreenSize := max(dwMaximumWindowSize.X,dwSize.X) * max(dwMaximumWindowSize.Y,dwSize.Y) * SizeOf (Char_Info);
  637. end;
  638. GetMem (OrigScreen, OrigScreenSize);
  639. with C do
  640. begin
  641. X := 0;
  642. Y := 0;
  643. end;
  644. with SR do
  645. begin
  646. Top := 0;
  647. Left := 0;
  648. Right := Pred (VioMode.dwSize.X);
  649. Bottom := Pred (VioMode.dwSize.Y);
  650. end;
  651. if not (ReadConsoleOutput (TextRec (Output).Handle, OrigScreen, VioMode.dwSize, C, SR)) then
  652. begin
  653. FreeMem (OrigScreen, OrigScreenSize);
  654. OrigScreen := nil;
  655. OrigScreenSize := 0;
  656. end;
  657. end;
  658. initialization
  659. SetVideoDriver(SysVideoDriver);
  660. TargetEntry;
  661. end.