drivers.pas 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551
  1. { $Id$ }
  2. {********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
  3. { }
  4. { System independent clone of DRIVERS.PAS }
  5. { }
  6. { Interface Copyright (c) 1992 Borland International }
  7. { }
  8. { Copyright (c) 1996, 1997, 1998, 1999, 2000 }
  9. { by Leon de Boer }
  10. { [email protected] - primary e-mail addr }
  11. { [email protected] - backup e-mail addr }
  12. { }
  13. { Original FormatStr kindly donated by Marco Schmidt }
  14. { }
  15. { Mouse callback hook under FPC with kind assistance of }
  16. { Pierre Muller, Gertjan Schouten & Florian Klaempfl. }
  17. { }
  18. {****************[ THIS CODE IS FREEWARE ]*****************}
  19. { }
  20. { This sourcecode is released for the purpose to }
  21. { promote the pascal language on all platforms. You may }
  22. { redistribute it and/or modify with the following }
  23. { DISCLAIMER. }
  24. { }
  25. { This SOURCE CODE is distributed "AS IS" WITHOUT }
  26. { WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
  27. { ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
  28. { }
  29. {*****************[ SUPPORTED PLATFORMS ]******************}
  30. { }
  31. { Only Free Pascal Compiler supported }
  32. { }
  33. {**********************************************************}
  34. UNIT Drivers;
  35. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  36. INTERFACE
  37. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  38. {====Include file to sort compiler platform out =====================}
  39. {$I Platform.inc}
  40. {====================================================================}
  41. {==== Compiler directives ===========================================}
  42. {$X+} { Extended syntax is ok }
  43. {$R-} { Disable range checking }
  44. {$IFNDEF OS_LINUX}
  45. {$S-} { Disable Stack Checking }
  46. {$ENDIF}
  47. {$I-} { Disable IO Checking }
  48. {$Q-} { Disable Overflow Checking }
  49. {$V-} { Turn off strict VAR strings }
  50. {====================================================================}
  51. USES
  52. {$IFDEF OS_WINDOWS} { WIN/NT CODE }
  53. Windows, { Standard unit }
  54. {$ENDIF}
  55. {$IFDEF OS_OS2} { OS2 CODE }
  56. {$IFDEF PPC_Virtual} { VIRTUAL PASCAL UNITS }
  57. OS2Def, OS2Base, OS2PMAPI, { Standard units }
  58. {$ENDIF}
  59. {$IFDEF PPC_Speed} { SPEED PASCAL UNITS }
  60. BseDos, Os2Def, { Standard units }
  61. {$ENDIF}
  62. {$ENDIF}
  63. {$IFDEF OS_LINUX}
  64. {$ifdef VER1_0}
  65. linux,
  66. {$else}
  67. unix,
  68. {$endif}
  69. {$ENDIF}
  70. video,
  71. {$IFDEF GRAPH_API} { GRAPH CODE }
  72. Graph, { Standard unit }
  73. {$ENDIF}
  74. GFVGraph, { GFV graphics unit }
  75. FVCommon, Objects; { GFV standard units }
  76. {***************************************************************************}
  77. { PUBLIC CONSTANTS }
  78. {***************************************************************************}
  79. {---------------------------------------------------------------------------}
  80. { EVENT TYPE MASKS }
  81. {---------------------------------------------------------------------------}
  82. CONST
  83. evMouseDown = $0001; { Mouse down event }
  84. evMouseUp = $0002; { Mouse up event }
  85. evMouseMove = $0004; { Mouse move event }
  86. evMouseAuto = $0008; { Mouse auto event }
  87. evKeyDown = $0010; { Key down event }
  88. evCommand = $0100; { Command event }
  89. evBroadcast = $0200; { Broadcast event }
  90. {---------------------------------------------------------------------------}
  91. { EVENT CODE MASKS }
  92. {---------------------------------------------------------------------------}
  93. CONST
  94. evNothing = $0000; { Empty event }
  95. evMouse = $000F; { Mouse event }
  96. evKeyboard = $0010; { Keyboard event }
  97. evMessage = $FF00; { Message event }
  98. {---------------------------------------------------------------------------}
  99. { EXTENDED KEY CODES }
  100. {---------------------------------------------------------------------------}
  101. CONST
  102. kbNoKey = $0000; kbAltEsc = $0100; kbEsc = $011B;
  103. kbAltSpace = $0200; kbCtrlIns = $0400; kbShiftIns = $0500;
  104. kbCtrlDel = $0600; kbShiftDel = $0700; kbAltBack = $0800;
  105. kbAltShiftBack= $0900; kbBack = $0E08; kbCtrlBack = $0E7F;
  106. kbShiftTab = $0F00; kbTab = $0F09; kbAltQ = $1000;
  107. kbCtrlQ = $1011; kbAltW = $1100; kbCtrlW = $1117;
  108. kbAltE = $1200; kbCtrlE = $1205; kbAltR = $1300;
  109. kbCtrlR = $1312; kbAltT = $1400; kbCtrlT = $1414;
  110. kbAltY = $1500; kbCtrlY = $1519; kbAltU = $1600;
  111. kbCtrlU = $1615; kbAltI = $1700; kbCtrlI = $1709;
  112. kbAltO = $1800; kbCtrlO = $180F; kbAltP = $1900;
  113. kbCtrlP = $1910; kbAltLftBrack = $1A00; kbAltRgtBrack = $1B00;
  114. kbCtrlEnter = $1C0A; kbEnter = $1C0D; kbAltA = $1E00;
  115. kbCtrlA = $1E01; kbAltS = $1F00; kbCtrlS = $1F13;
  116. kbAltD = $2000; kbCtrlD = $2004; kbAltF = $2100;
  117. kbCtrlF = $2106; kbAltG = $2200; kbCtrlG = $2207;
  118. kbAltH = $2300; kbCtrlH = $2308; kbAltJ = $2400;
  119. kbCtrlJ = $240A; kbAltK = $2500; kbCtrlK = $250B;
  120. kbAltL = $2600; kbCtrlL = $260C; kbAltSemiCol = $2700;
  121. kbAltQuote = $2800; kbAltOpQuote = $2900; kbAltBkSlash = $2B00;
  122. kbAltZ = $2C00; kbCtrlZ = $2C1A; kbAltX = $2D00;
  123. kbCtrlX = $2D18; kbAltC = $2E00; kbCtrlC = $2E03;
  124. kbAltV = $2F00; kbCtrlV = $2F16; kbAltB = $3000;
  125. kbCtrlB = $3002; kbAltN = $3100; kbCtrlN = $310E;
  126. kbAltM = $3200; kbCtrlM = $320D; kbAltComma = $3300;
  127. kbAltPeriod = $3400; kbAltSlash = $3500; kbAltGreyAst = $3700;
  128. kbSpaceBar = $3920; kbF1 = $3B00; kbF2 = $3C00;
  129. kbF3 = $3D00; kbF4 = $3E00; kbF5 = $3F00;
  130. kbF6 = $4000; kbF7 = $4100; kbF8 = $4200;
  131. kbF9 = $4300; kbF10 = $4400; kbHome = $4700;
  132. kbUp = $4800; kbPgUp = $4900; kbGrayMinus = $4A2D;
  133. kbLeft = $4B00; kbCenter = $4C00; kbRight = $4D00;
  134. kbAltGrayPlus = $4E00; kbGrayPlus = $4E2B; kbEnd = $4F00;
  135. kbDown = $5000; kbPgDn = $5100; kbIns = $5200;
  136. kbDel = $5300; kbShiftF1 = $5400; kbShiftF2 = $5500;
  137. kbShiftF3 = $5600; kbShiftF4 = $5700; kbShiftF5 = $5800;
  138. kbShiftF6 = $5900; kbShiftF7 = $5A00; kbShiftF8 = $5B00;
  139. kbShiftF9 = $5C00; kbShiftF10 = $5D00; kbCtrlF1 = $5E00;
  140. kbCtrlF2 = $5F00; kbCtrlF3 = $6000; kbCtrlF4 = $6100;
  141. kbCtrlF5 = $6200; kbCtrlF6 = $6300; kbCtrlF7 = $6400;
  142. kbCtrlF8 = $6500; kbCtrlF9 = $6600; kbCtrlF10 = $6700;
  143. kbAltF1 = $6800; kbAltF2 = $6900; kbAltF3 = $6A00;
  144. kbAltF4 = $6B00; kbAltF5 = $6C00; kbAltF6 = $6D00;
  145. kbAltF7 = $6E00; kbAltF8 = $6F00; kbAltF9 = $7000;
  146. kbAltF10 = $7100; kbCtrlPrtSc = $7200; kbCtrlLeft = $7300;
  147. kbCtrlRight = $7400; kbCtrlEnd = $7500; kbCtrlPgDn = $7600;
  148. kbCtrlHome = $7700; kbAlt1 = $7800; kbAlt2 = $7900;
  149. kbAlt3 = $7A00; kbAlt4 = $7B00; kbAlt5 = $7C00;
  150. kbAlt6 = $7D00; kbAlt7 = $7E00; kbAlt8 = $7F00;
  151. kbAlt9 = $8000; kbAlt0 = $8100; kbAltMinus = $8200;
  152. kbAltEqual = $8300; kbCtrlPgUp = $8400; kbF11 = $8500;
  153. kbF12 = $8600; kbShiftF11 = $8700; kbShiftF12 = $8800;
  154. kbCtrlF11 = $8900; kbCtrlF12 = $8A00; kbAltF11 = $8B00;
  155. kbAltF12 = $8C00; kbCtrlUp = $8D00; kbCtrlMinus = $8E00;
  156. kbCtrlCenter = $8F00; kbCtrlGreyPlus= $9000; kbCtrlDown = $9100;
  157. kbCtrlTab = $9400; kbAltHome = $9700; kbAltUp = $9800;
  158. kbAltPgUp = $9900; kbAltLeft = $9B00; kbAltRight = $9D00;
  159. kbAltEnd = $9F00; kbAltDown = $A000; kbAltPgDn = $A100;
  160. kbAltIns = $A200; kbAltDel = $A300; kbAltTab = $A500;
  161. { ------------------------------- REMARK ------------------------------ }
  162. { New keys not initially defined by Borland in their unit interface. }
  163. { ------------------------------ END REMARK --- Leon de Boer, 15May96 - }
  164. kbFullStop = $342E; kbComma = $332C; kbBackSlash = $352F;
  165. kbApostrophe = $2827; kbSemiColon = $273B; kbEqual = $0D3D;
  166. kbGreaterThan = $343E; kbLessThan = $333C; kbQuestion = $353F;
  167. kbQuote = $2822; kbColon = $273A; kbPlus = $0D2B;
  168. kbPipe = $2B7C; kbSlash = $2B5C; kbExclaim = $0221;
  169. kbAt = $0340; kbNumber = $0423; kbPercent = $0625;
  170. kbCaret = $075E; kbAmpersand = $0826; kbAsterix = $092A;
  171. kbLeftBracket = $0A28; kbRightBracket= $0B29; kbApprox = $2960;
  172. kbTilde = $297E; kbDollar = $0524; kbMinus = $0C2D;
  173. kbUnderline = $0C5F; kbLeftSqBr = $1A5B; kbRightSqBr = $1B5D;
  174. kbLeftCurlyBr = $1A7B; kbRightCurlyBr= $1B7D;
  175. {---------------------------------------------------------------------------}
  176. { KEYBOARD STATE AND SHIFT MASKS }
  177. {---------------------------------------------------------------------------}
  178. CONST
  179. kbRightShift = $0001; { Right shift key }
  180. kbLeftShift = $0002; { Left shift key }
  181. kbCtrlShift = $0004; { Control key down }
  182. kbAltShift = $0008; { Alt key down }
  183. kbScrollState = $0010; { Scroll lock on }
  184. kbNumState = $0020; { Number lock on }
  185. kbCapsState = $0040; { Caps lock on }
  186. kbInsState = $0080; { Insert mode on }
  187. kbBothShifts = kbRightShift + kbLeftShift; { Right & Left shifts }
  188. {---------------------------------------------------------------------------}
  189. { MOUSE BUTTON STATE MASKS }
  190. {---------------------------------------------------------------------------}
  191. CONST
  192. mbLeftButton = $01; { Left mouse button }
  193. mbRightButton = $02; { Right mouse button }
  194. mbMiddleButton = $04; { Middle mouse button }
  195. {---------------------------------------------------------------------------}
  196. { SCREEN CRT MODE CONSTANTS }
  197. {---------------------------------------------------------------------------}
  198. CONST
  199. smBW80 = $0002; { Black and white }
  200. smCO80 = $0003; { Colour mode }
  201. smMono = $0007; { Monochrome mode }
  202. smFont8x8 = $0100; { 8x8 font mode }
  203. {***************************************************************************}
  204. { PUBLIC TYPE DEFINITIONS }
  205. {***************************************************************************}
  206. { ******************************* REMARK ****************************** }
  207. { The TEvent definition is completely compatable with all existing }
  208. { code but adds two new fields ID and Data into the message record }
  209. { which helps with WIN/NT and OS2 message processing. }
  210. { ****************************** END REMARK *** Leon de Boer, 11Sep97 * }
  211. {---------------------------------------------------------------------------}
  212. { EVENT RECORD DEFINITION }
  213. {---------------------------------------------------------------------------}
  214. TYPE
  215. TEvent = PACKED RECORD
  216. What: Sw_Word; { Event type }
  217. Case Sw_Word Of
  218. evNothing: (); { ** NO EVENT ** }
  219. evMouse: (
  220. Buttons: Byte; { Mouse buttons }
  221. Double: Boolean; { Double click state }
  222. Where: TPoint); { Mouse position }
  223. evKeyDown: ( { ** KEY EVENT ** }
  224. Case Sw_Integer Of
  225. 0: (KeyCode: Word); { Full key code }
  226. 1: (CharCode: Char; { Char code }
  227. ScanCode: Byte; { Scan code }
  228. KeyShift: byte)); { Shift states }
  229. evMessage: ( { ** MESSAGE EVENT ** }
  230. Command: Sw_Word; { Message command }
  231. Id : Sw_Word; { Message id }
  232. Data : Real; { Message data }
  233. Case Sw_Word Of
  234. 0: (InfoPtr: Pointer); { Message pointer }
  235. 1: (InfoLong: Longint); { Message longint }
  236. 2: (InfoWord: Word); { Message Sw_Word }
  237. 3: (InfoInt: Integer); { Message Sw_Integer }
  238. 4: (InfoByte: Byte); { Message byte }
  239. 5: (InfoChar: Char)); { Message character }
  240. END;
  241. PEvent = ^TEvent;
  242. {$ifdef USE_VIDEO_API}
  243. TVideoMode = Video.TVideoMode; { Screen mode }
  244. {$else not USE_VIDEO_API}
  245. TVideoMode = Sw_Word; { Screen mode }
  246. {$endif USE_VIDEO_API}
  247. {---------------------------------------------------------------------------}
  248. { ERROR HANDLER FUNCTION DEFINITION }
  249. {---------------------------------------------------------------------------}
  250. TYPE
  251. TSysErrorFunc = FUNCTION (ErrorCode: Sw_Integer; Drive: Byte): Sw_Integer;
  252. {***************************************************************************}
  253. { INTERFACE ROUTINES }
  254. {***************************************************************************}
  255. { Get Dos counter ticks }
  256. Function GetDosTicks:longint; { returns ticks at 18.2 Hz, just like DOS }
  257. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  258. { BUFFER MOVE ROUTINES }
  259. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  260. {-CStrLen------------------------------------------------------------
  261. Returns the length of string S, where S is a control string using tilde
  262. characters ('~') to designate shortcut characters. The tildes are
  263. excluded from the length of the string, as they will not appear on
  264. the screen. For example, given the string '~B~roccoli' as its
  265. parameter, CStrLen returns 8.
  266. 25May96 LdB
  267. ---------------------------------------------------------------------}
  268. FUNCTION CStrLen (Const S: String): Sw_Integer;
  269. {-MoveStr------------------------------------------------------------
  270. Moves a string into a buffer for use with a view's WriteBuf or WriteLine.
  271. Dest must be a TDrawBuffer (or an equivalent array of Sw_Words). The
  272. characters in Str are moved into the low bytes of corresponding Sw_Words
  273. in Dest. The high bytes of the Sw_Words are set to Attr, or remain
  274. unchanged if Attr is zero.
  275. 25May96 LdB
  276. ---------------------------------------------------------------------}
  277. PROCEDURE MoveStr (Var Dest; Const Str: String; Attr: Byte);
  278. {-MoveCStr-----------------------------------------------------------
  279. The characters in Str are moved into the low bytes of corresponding
  280. Sw_Words in Dest. The high bytes of the Sw_Words are set to Lo(Attr) or
  281. Hi(Attr). Tilde characters (~) in the string toggle between the two
  282. attribute bytes passed in the Attr Sw_Word.
  283. 25May96 LdB
  284. ---------------------------------------------------------------------}
  285. PROCEDURE MoveCStr (Var Dest; Const Str: String; Attrs: Word);
  286. {-MoveBuf------------------------------------------------------------
  287. Count bytes are moved from Source into the low bytes of corresponding
  288. Sw_Words in Dest. The high bytes of the Sw_Words in Dest are set to Attr,
  289. or remain unchanged if Attr is zero.
  290. 25May96 LdB
  291. ---------------------------------------------------------------------}
  292. PROCEDURE MoveBuf (Var Dest, Source; Attr: Byte; Count: Sw_Word);
  293. {-MoveChar------------------------------------------------------------
  294. Moves characters into a buffer for use with a view's WriteBuf or
  295. WriteLine. Dest must be a TDrawBuffer (or an equivalent array of Sw_Words).
  296. The low bytes of the first Count Sw_Words of Dest are set to C, or
  297. remain unchanged if Ord(C) is zero. The high bytes of the Sw_Words are
  298. set to Attr, or remain unchanged if Attr is zero.
  299. 25May96 LdB
  300. ---------------------------------------------------------------------}
  301. PROCEDURE MoveChar (Var Dest; C: Char; Attr: Byte; Count: Sw_Word);
  302. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  303. { KEYBOARD SUPPORT ROUTINES }
  304. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  305. {-GetAltCode---------------------------------------------------------
  306. Returns the scancode corresponding to Alt+Ch key that is given.
  307. 25May96 LdB
  308. ---------------------------------------------------------------------}
  309. FUNCTION GetAltCode (Ch: Char): Word;
  310. {-GetCtrlCode--------------------------------------------------------
  311. Returns the scancode corresponding to Alt+Ch key that is given.
  312. 25May96 LdB
  313. ---------------------------------------------------------------------}
  314. FUNCTION GetCtrlCode (Ch: Char): Word;
  315. {-GetAltChar---------------------------------------------------------
  316. Returns the ascii character for the Alt+Key scancode that was given.
  317. 25May96 LdB
  318. ---------------------------------------------------------------------}
  319. FUNCTION GetAltChar (KeyCode: Word): Char;
  320. {-GetCtrlChar--------------------------------------------------------
  321. Returns the ascii character for the Ctrl+Key scancode that was given.
  322. 25May96 LdB
  323. ---------------------------------------------------------------------}
  324. FUNCTION GetCtrlChar (KeyCode: Word): Char;
  325. {-CtrlToArrow--------------------------------------------------------
  326. Converts a WordStar-compatible control key code to the corresponding
  327. cursor key code.
  328. 25May96 LdB
  329. ---------------------------------------------------------------------}
  330. FUNCTION CtrlToArrow (KeyCode: Word): Word;
  331. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  332. { KEYBOARD CONTROL ROUTINES }
  333. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  334. {-GetShiftState------------------------------------------------------
  335. Returns a byte containing the current Shift key state. The return
  336. value contains a combination of the kbXXXX constants for shift states.
  337. 08Jul96 LdB
  338. ---------------------------------------------------------------------}
  339. FUNCTION GetShiftState: Byte;
  340. {-GetKeyEvent--------------------------------------------------------
  341. Checks whether a keyboard event is available. If a key has been pressed,
  342. Event.What is set to evKeyDown and Event.KeyCode is set to the scan
  343. code of the key. Otherwise, Event.What is set to evNothing.
  344. 19May98 LdB
  345. ---------------------------------------------------------------------}
  346. PROCEDURE GetKeyEvent (Var Event: TEvent);
  347. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  348. { MOUSE CONTROL ROUTINES }
  349. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  350. {-ShowMouse----------------------------------------------------------
  351. Decrements the hide counter and if zero the mouse is shown on screen.
  352. 30Jun98 LdB
  353. ---------------------------------------------------------------------}
  354. PROCEDURE ShowMouse;
  355. {-HideMouse----------------------------------------------------------
  356. If mouse hide counter is zero it removes the cursor from the screen.
  357. The hide counter is then incremented by one count.
  358. 30Jun98 LdB
  359. ---------------------------------------------------------------------}
  360. PROCEDURE HideMouse;
  361. {-GetMouseEvent------------------------------------------------------
  362. Checks whether a mouse event is available. If a mouse event has occurred,
  363. Event.What is set to evMouseDown, evMouseUp, evMouseMove, or evMouseAuto
  364. and the button and double click variables are set appropriately.
  365. 06Jan97 LdB
  366. ---------------------------------------------------------------------}
  367. PROCEDURE GetMouseEvent (Var Event: TEvent);
  368. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  369. { EVENT HANDLER CONTROL ROUTINES }
  370. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  371. {-InitEvents---------------------------------------------------------
  372. Initializes the event manager, enabling the mouse handler routine and
  373. under DOS/DPMI shows the mouse on screen. It is called automatically
  374. by TApplication.Init.
  375. 02May98 LdB
  376. ---------------------------------------------------------------------}
  377. PROCEDURE InitEvents;
  378. {-DoneEvents---------------------------------------------------------
  379. Terminates event manager and disables the mouse and under DOS hides
  380. the mouse. It is called automatically by TApplication.Done.
  381. 02May98 LdB
  382. ---------------------------------------------------------------------}
  383. PROCEDURE DoneEvents;
  384. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  385. { VIDEO CONTROL ROUTINES }
  386. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  387. {-InitVideo---------------------------------------------------------
  388. Initializes the video manager, Saves the current screen mode in
  389. StartupMode, and switches to the mode indicated by ScreenMode.
  390. 19May98 LdB
  391. ---------------------------------------------------------------------}
  392. PROCEDURE InitVideo;
  393. {-DoneVideo---------------------------------------------------------
  394. Terminates the video manager by restoring the initial screen mode
  395. (given by StartupMode), clearing the screen, and restoring the cursor.
  396. Called automatically by TApplication.Done.
  397. 03Jan97 LdB
  398. ---------------------------------------------------------------------}
  399. PROCEDURE DoneVideo;
  400. {-ClearScreen--------------------------------------------------------
  401. Does nothing provided for compatability purposes only.
  402. 04Jan97 LdB
  403. ---------------------------------------------------------------------}
  404. PROCEDURE ClearScreen;
  405. {-SetVideoMode-------------------------------------------------------
  406. Does nothing provided for compatability purposes only.
  407. 04Jan97 LdB
  408. ---------------------------------------------------------------------}
  409. PROCEDURE SetVideoMode (Mode: Sw_Word);
  410. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  411. { ERROR CONTROL ROUTINES }
  412. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  413. {-InitSysError-------------------------------------------------------
  414. Error handling is not yet implemented so this simply sets
  415. SysErrActive=True (ie it lies) and exits.
  416. 20May98 LdB
  417. ---------------------------------------------------------------------}
  418. PROCEDURE InitSysError;
  419. {-DoneSysError-------------------------------------------------------
  420. Error handling is not yet implemented so this simply sets
  421. SysErrActive=False and exits.
  422. 20May98 LdB
  423. ---------------------------------------------------------------------}
  424. PROCEDURE DoneSysError;
  425. {-SystemError---------------------------------------------------------
  426. Error handling is not yet implemented so this simply drops through.
  427. 20May98 LdB
  428. ---------------------------------------------------------------------}
  429. FUNCTION SystemError (ErrorCode: Sw_Integer; Drive: Byte): Sw_Integer;
  430. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  431. { STRING FORMAT ROUTINES }
  432. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  433. {-PrintStr-----------------------------------------------------------
  434. Does nothing provided for compatability purposes only.
  435. 30Jun98 LdB
  436. ---------------------------------------------------------------------}
  437. PROCEDURE PrintStr (CONST S: String);
  438. {-FormatStr----------------------------------------------------------
  439. A string formatting routine that given a string that includes format
  440. specifiers and a list of parameters in Params, FormatStr produces a
  441. formatted output string in Result.
  442. 18Feb99 LdB
  443. ---------------------------------------------------------------------}
  444. PROCEDURE FormatStr (Var Result: String; CONST Format: String; Var Params);
  445. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  446. { >> NEW QUEUED EVENT HANDLER ROUTINES << }
  447. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  448. {-PutEventInQueue-----------------------------------------------------
  449. If there is room in the queue the event is placed in the next vacant
  450. position in the queue manager.
  451. 17Mar98 LdB
  452. ---------------------------------------------------------------------}
  453. FUNCTION PutEventInQueue (Var Event: TEvent): Boolean;
  454. {-NextQueuedEvent----------------------------------------------------
  455. If there are queued events the next event is loaded into event else
  456. evNothing is returned.
  457. 17Mar98 LdB
  458. ---------------------------------------------------------------------}
  459. PROCEDURE NextQueuedEvent(Var Event: TEvent);
  460. {***************************************************************************}
  461. { INITIALIZED PUBLIC VARIABLES }
  462. {***************************************************************************}
  463. PROCEDURE HideMouseCursor;
  464. PROCEDURE ShowMouseCursor;
  465. {---------------------------------------------------------------------------}
  466. { INITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
  467. {---------------------------------------------------------------------------}
  468. CONST
  469. CheckSnow : Boolean = False; { Compatability only }
  470. MouseEvents : Boolean = False; { Mouse event state }
  471. MouseReverse : Boolean = False; { Mouse reversed }
  472. HiResScreen : Boolean = False; { Compatability only }
  473. CtrlBreakHit : Boolean = False; { Compatability only }
  474. SaveCtrlBreak: Boolean = False; { Compatability only }
  475. SysErrActive : Boolean = False; { Compatability only }
  476. FailSysErrors: Boolean = False; { Compatability only }
  477. ButtonCount : Byte = 0; { Mouse button count }
  478. DoubleDelay : Sw_Word = 8; { Double click delay }
  479. RepeatDelay : Sw_Word = 8; { Auto mouse delay }
  480. SysColorAttr : Sw_Word = $4E4F; { System colour attr }
  481. SysMonoAttr : Sw_Word = $7070; { System mono attr }
  482. StartupMode : Sw_Word = $FFFF; { Compatability only }
  483. CursorLines : Sw_Word = $FFFF; { Compatability only }
  484. ScreenBuffer : Pointer = Nil; { Compatability only }
  485. SaveInt09 : Pointer = Nil; { Compatability only }
  486. SysErrorFunc : TSysErrorFunc = {$ifdef FPC}@{$endif}SystemError; { System error ptr }
  487. {---------------------------------------------------------------------------}
  488. { >>> NEW INITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES <<< }
  489. {---------------------------------------------------------------------------}
  490. CONST
  491. TextModeGFV : Boolean = False; { DOS/DPMI textmode op }
  492. DefLineNum : Sw_Integer = 25; { Default line number }
  493. DefFontHeight : Sw_Integer = 0; { Default font height }
  494. SysFontWidth : Sw_Integer = 8; { System font width }
  495. SysFontHeight : Sw_Integer = 16; { System font height }
  496. {***************************************************************************}
  497. { UNINITIALIZED PUBLIC VARIABLES }
  498. {***************************************************************************}
  499. {---------------------------------------------------------------------------}
  500. { UNINITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
  501. {---------------------------------------------------------------------------}
  502. VAR
  503. MouseIntFlag: Byte; { Mouse in int flag }
  504. MouseButtons: Byte; { Mouse button state }
  505. ScreenWidth : Byte; { Screen text width }
  506. ScreenHeight: Byte; { Screen text height }
  507. {$ifdef GRAPH_API}
  508. ScreenMode : Sw_Word; { Screen mode }
  509. {$else not GRAPH_API}
  510. ScreenMode : TVideoMode; { Screen mode }
  511. {$endif GRAPH_API}
  512. MouseWhere : TPoint; { Mouse position }
  513. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  514. IMPLEMENTATION
  515. {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
  516. { API Units }
  517. USES
  518. Keyboard,Mouse;
  519. {***************************************************************************}
  520. { PRIVATE INTERNAL CONSTANTS }
  521. {***************************************************************************}
  522. {---------------------------------------------------------------------------}
  523. { DOS/DPMI MOUSE INTERRUPT EVENT QUEUE SIZE }
  524. {---------------------------------------------------------------------------}
  525. CONST EventQSize = 16; { Default int bufsize }
  526. {---------------------------------------------------------------------------}
  527. { DOS/DPMI/WIN/NT/OS2 NEW EVENT QUEUE MAX SIZE }
  528. {---------------------------------------------------------------------------}
  529. CONST QueueMax = 64; { Max new queue size }
  530. {***************************************************************************}
  531. { PRIVATE INTERNAL TYPES }
  532. {***************************************************************************}
  533. {***************************************************************************}
  534. { PRIVATE INTERNAL INITIALIZED VARIABLES }
  535. {***************************************************************************}
  536. {---------------------------------------------------------------------------}
  537. { DOS/DPMI/WIN/NT/OS2 ALT KEY SCANCODES FROM KEYS (0-127) }
  538. {---------------------------------------------------------------------------}
  539. CONST AltCodes: Array [0..127] Of Byte = (
  540. $00, $00, $00, $00, $00, $00, $00, $00, { $00 - $07 }
  541. $00, $00, $00, $00, $00, $00, $00, $00, { $08 - $0F }
  542. $00, $00, $00, $00, $00, $00, $00, $00, { $10 - $17 }
  543. $00, $00, $00, $00, $00, $00, $00, $00, { $18 - $1F }
  544. $00, $00, $00, $00, $00, $00, $00, $00, { $20 - $27 }
  545. $00, $00, $00, $00, $00, $82, $00, $00, { $28 - $2F }
  546. $81, $78, $79, $7A, $7B, $7C, $7D, $7E, { $30 - $37 }
  547. $7F, $80, $00, $00, $00, $83, $00, $00, { $38 - $3F }
  548. $00, $1E, $30, $2E, $20, $12, $21, $22, { $40 - $47 }
  549. $23, $17, $24, $25, $26, $32, $31, $18, { $48 - $4F }
  550. $19, $10, $13, $1F, $14, $16, $2F, $11, { $50 - $57 }
  551. $2D, $15, $2C, $00, $00, $00, $00, $00, { $58 - $5F }
  552. $00, $00, $00, $00, $00, $00, $00, $00, { $60 - $67 }
  553. $00, $00, $00, $00, $00, $00, $00, $00, { $68 - $6F }
  554. $00, $00, $00, $00, $00, $00, $00, $00, { $70 - $77 }
  555. $00, $00, $00, $00, $00, $00, $00, $00); { $78 - $7F }
  556. {***************************************************************************}
  557. { PRIVATE INTERNAL INITIALIZED VARIABLES }
  558. {***************************************************************************}
  559. {---------------------------------------------------------------------------}
  560. { NEW CONTROL VARIABLES }
  561. {---------------------------------------------------------------------------}
  562. CONST
  563. HideCount : Sw_Integer = 0; { Cursor hide count }
  564. QueueCount: Sw_Word = 0; { Queued message count }
  565. QueueHead : Sw_Word = 0; { Queue head pointer }
  566. QueueTail : Sw_Word = 0; { Queue tail pointer }
  567. {***************************************************************************}
  568. { PRIVATE INTERNAL UNINITIALIZED VARIABLES }
  569. {***************************************************************************}
  570. {---------------------------------------------------------------------------}
  571. { UNINITIALIZED DOS/DPMI/API VARIABLES }
  572. {---------------------------------------------------------------------------}
  573. VAR
  574. LastDouble : Boolean; { Last double buttons }
  575. LastButtons: Byte; { Last button state }
  576. DownButtons: Byte; { Last down buttons }
  577. EventCount : Sw_Word; { Events in queue }
  578. AutoDelay : Sw_Word; { Delay time count }
  579. DownTicks : Sw_Word; { Down key tick count }
  580. AutoTicks : Sw_Word; { Held key tick count }
  581. LastWhereX : Sw_Word; { Last x position }
  582. LastWhereY : Sw_Word; { Last y position }
  583. DownWhereX : Sw_Word; { Last x position }
  584. DownWhereY : Sw_Word; { Last y position }
  585. LastWhere : TPoint; { Last mouse position }
  586. DownWhere : TPoint; { Last down position }
  587. EventQHead : Pointer; { Head of queue }
  588. EventQTail : Pointer; { Tail of queue }
  589. EventQueue : Array [0..EventQSize - 1] Of TEvent; { Event queue }
  590. EventQLast : RECORD END; { Simple end marker }
  591. {---------------------------------------------------------------------------}
  592. { GetDosTicks (18.2 Hz) }
  593. {---------------------------------------------------------------------------}
  594. Function GetDosTicks:longint; { returns ticks at 18.2 Hz, just like DOS }
  595. {$IFDEF OS_OS2}
  596. const
  597. QSV_MS_COUNT = 14;
  598. var
  599. L: longint;
  600. begin
  601. DosQuerySysInfo (QSV_MS_COUNT, QSV_MS_COUNT, L, 4);
  602. GetDosTicks := L div 55;
  603. end;
  604. {$ENDIF}
  605. {$IFDEF OS_LINUX}
  606. var
  607. tv : TimeVal;
  608. { tz : TimeZone;}
  609. begin
  610. GetTimeOfDay(tv{,tz});
  611. GetDosTicks:=((tv.Sec mod 86400) div 60)*1092+((tv.Sec mod 60)*1000000+tv.USec) div 54945;
  612. end;
  613. {$ENDIF OS_LINUX}
  614. {$IFDEF OS_WINDOWS}
  615. begin
  616. GetDosTicks:=GetTickCount div 55;
  617. end;
  618. {$ENDIF OS_WINDOWS}
  619. {$IFDEF OS_DOS}
  620. begin
  621. GetDosTicks:=MemL[$40:$6c];
  622. end;
  623. {$ENDIF OS_DOS}
  624. {---------------------------------------------------------------------------}
  625. { UNINITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
  626. {---------------------------------------------------------------------------}
  627. VAR
  628. SaveExit: Pointer; { Saved exit pointer }
  629. Queue : Array [0..QueueMax-1] Of TEvent; { New message queue }
  630. {***************************************************************************}
  631. { PRIVATE INTERNAL ROUTINES }
  632. {***************************************************************************}
  633. PROCEDURE ShowMouseCursor;
  634. BEGIN
  635. ShowMouse;
  636. END;
  637. PROCEDURE HideMouseCursor;
  638. BEGIN
  639. HideMouse;
  640. END;
  641. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  642. { DOS/DPMI/WIN/NT/OS2 PRIVATE INTERNAL ROUTINES }
  643. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  644. {---------------------------------------------------------------------------}
  645. { ExitDrivers -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jun98 LdB }
  646. {---------------------------------------------------------------------------}
  647. PROCEDURE ExitDrivers; {$IFNDEF OS_LINUX} FAR; {$ENDIF}
  648. BEGIN
  649. DoneSysError; { Relase error trap }
  650. DoneEvents; { Close event driver }
  651. DoneKeyboard;
  652. DoneVideo;
  653. ExitProc := SaveExit; { Restore old exit }
  654. END;
  655. {---------------------------------------------------------------------------}
  656. { DetectVideo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
  657. {---------------------------------------------------------------------------}
  658. {$IFDEF Use_Video_API}
  659. procedure DetectVideo;
  660. VAR
  661. CurrMode : TVideoMode;
  662. begin
  663. Video.InitVideo;
  664. GetVideoMode(CurrMode);
  665. ScreenMode:=CurrMode;
  666. end;
  667. {$else not Use_Video_API}
  668. PROCEDURE DetectVideo;
  669. {$IFDEF OS_DOS} { DOS/DPMI CODE }
  670. ASSEMBLER;
  671. {$IFDEF ASM_BP} { BP COMPATABLE ASM }
  672. ASM
  673. MOV AH, $0F; { Set function id }
  674. PUSH BP; { Safety!! save reg }
  675. INT $10; { Get current crt mode }
  676. POP BP; { Restore register }
  677. PUSH AX; { Hold result }
  678. MOV AX, $1130; { Set function id }
  679. MOV BH, 0; { Zero register }
  680. MOV DL, 0; { Zero register }
  681. PUSH BP; { Safety!! save reg }
  682. INT $10; { Get ext-video mode }
  683. POP BP; { Restore register }
  684. POP AX; { Recover held value }
  685. MOV DH, AH; { Transfer high mode }
  686. CMP DL, 25; { Check screen ht }
  687. SBB AH, AH; { Subtract borrow }
  688. INC AH; { Make #1 if in high }
  689. MOV CL, 1; { Preset value of 1 }
  690. OR DL, DL; { Test for zero }
  691. JNZ @@1; { Branch if not zero }
  692. MOV CL, 0 { Set value to zero }
  693. MOV DL, 24; { Zero = 24 lines }
  694. @@1:
  695. INC DL; { Add one line }
  696. MOV ScreenWidth, DH; { Hold screen width }
  697. MOV ScreenHeight, DL; { Hold screen height }
  698. MOV HiResScreen, CL; { Set hires mask }
  699. CMP AL, smMono; { Is screen mono }
  700. JZ @@Exit1; { Exit of mono }
  701. CMP AL, smBW80; { Is screen B&W }
  702. JZ @@Exit1; { Exit if B&W }
  703. MOV AX, smCO80; { Else set to colour }
  704. @@Exit1:
  705. MOV ScreenMode, AX; { Hold screen mode }
  706. END;
  707. {$ENDIF}
  708. {$IFDEF ASM_FPC} { FPC COMPATABLE ASM }
  709. ASM
  710. MOVB $0x0F, %AH; { Set function id }
  711. PUSHL %EBP; { Save register }
  712. INT $0x10; { Get current crt mode }
  713. POPL %EBP; { Restore register }
  714. PUSHL %EAX; { Hold result }
  715. MOVW $0x1130, %AX; { Set function id }
  716. MOVB $0, %BH; { Zero register }
  717. MOVB $0, %DL; { Zero register }
  718. PUSHL %EBP; { Safety!! save reg }
  719. INT $0x10; { Get ext-video mode }
  720. POPL %EBP; { Restore register }
  721. POPL %EAX; { Recover held value }
  722. MOVB %AH, %DH; { Transfer high mode }
  723. CMPB $25, %DL; { Check screen ht }
  724. SBB %AH, %AH; { Subtract borrow }
  725. INCB %AH; { Make #1 if in high }
  726. MOVB $1, %CL; { Preset value of 1 }
  727. ORB %DL, %DL; { Test for zero }
  728. JNZ .L_JMP1; { Branch if not zero }
  729. MOVB $0, %CL; { Set value to zero }
  730. MOVB $24, %DL; { Zero = 24 lines }
  731. .L_JMP1:
  732. INCB %DL; { Add one line }
  733. MOVB %DH, SCREENWIDTH; { Hold screen width }
  734. MOVB %DL, SCREENHEIGHT; { Hold screen height }
  735. MOVB %CL, HIRESSCREEN; { Set hires mask }
  736. CMPB $07, %AL; { Is screen mono }
  737. JZ .L_Exit1; { Exit of mono }
  738. CMPB $02, %AL; { Is screen B&W }
  739. JZ .L_Exit1; { Exit if B&W }
  740. MOVW $03, %AX; { Else set to colour }
  741. .L_Exit1:
  742. MOVW %AX, SCREENMODE; { Hold screen mode }
  743. END;
  744. {$ENDIF}
  745. {$ENDIF}
  746. {$IFDEF OS_WINDOWS} { WIN/NT CODE }
  747. VAR Dc: HDC;
  748. BEGIN
  749. Dc := GetDc(0); { Get screen context }
  750. If ((GetDeviceCaps(Dc, BitsPixel) > 1) OR { Colour capacity }
  751. (GetDeviceCaps(Dc, Planes) > 1)) Then { Colour capacity }
  752. ScreenMode := smCO80 Else ScreenMode := smMono; { Screen mode }
  753. ReleaseDc(0, Dc); { Release context }
  754. END;
  755. {$ENDIF}
  756. {$IFDEF OS_OS2} { OS2 CODE }
  757. VAR Ps: Hps; Dc: Hdc; Colours: LongInt;
  758. BEGIN
  759. Ps := WinGetPS(HWND_Desktop); { Get desktop PS }
  760. Dc := GpiQueryDevice(Ps); { Get gpi context }
  761. DevQueryCaps(Dc, Caps_Phys_Colors, 1, Colours); { Colour capacity }
  762. If (Colours> 2) Then ScreenMode := smCO80 { Colour screen }
  763. Else ScreenMode := smMono; { Mono screen }
  764. WinReleasePS(Ps); { Release desktop PS }
  765. END;
  766. {$ENDIF}
  767. {$endif not Use_Video_API}
  768. {---------------------------------------------------------------------------}
  769. { DetectMouse -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
  770. FUNCTION DetectMouse: Byte;
  771. begin
  772. DetectMouse:=Mouse.DetectMouse;
  773. end;
  774. {***************************************************************************}
  775. { INTERFACE ROUTINES }
  776. {***************************************************************************}
  777. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  778. { BUFFER MOVE ROUTINES }
  779. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  780. {---------------------------------------------------------------------------}
  781. { CStrLen -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
  782. {---------------------------------------------------------------------------}
  783. FUNCTION CStrLen (Const S: String): Sw_Integer;
  784. VAR I, J: Sw_Integer;
  785. BEGIN
  786. J := 0; { Set result to zero }
  787. For I := 1 To Length(S) Do
  788. If (S[I] <> '~') Then Inc(J); { Inc count if not ~ }
  789. CStrLen := J; { Return length }
  790. END;
  791. {---------------------------------------------------------------------------}
  792. { MoveStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Jul99 LdB }
  793. {---------------------------------------------------------------------------}
  794. PROCEDURE MoveStr (Var Dest; Const Str: String; Attr: Byte);
  795. VAR I: Word; P: PWord;
  796. BEGIN
  797. For I := 1 To Length(Str) Do Begin { For each character }
  798. P := @TWordArray(Dest)[I-1]; { Pointer to Sw_Word }
  799. If (Attr <> 0) Then WordRec(P^).Hi := Attr; { Copy attribute }
  800. WordRec(P^).Lo := Byte(Str[I]); { Copy string char }
  801. End;
  802. END;
  803. {---------------------------------------------------------------------------}
  804. { MoveCStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Jul99 LdB }
  805. {---------------------------------------------------------------------------}
  806. PROCEDURE MoveCStr (Var Dest; Const Str: String; Attrs: Word);
  807. VAR B: Byte; I, J: Sw_Word; P: PWord;
  808. BEGIN
  809. J := 0; { Start position }
  810. For I := 1 To Length(Str) Do Begin { For each character }
  811. If (Str[I] <> '~') Then Begin { Not tilde character }
  812. P := @TWordArray(Dest)[J]; { Pointer to Sw_Word }
  813. If (Lo(Attrs) <> 0) Then
  814. WordRec(P^).Hi := Lo(Attrs); { Copy attribute }
  815. WordRec(P^).Lo := Byte(Str[I]); { Copy string char }
  816. Inc(J); { Next position }
  817. End Else Begin
  818. B := Hi(Attrs); { Hold attribute }
  819. WordRec(Attrs).Hi := Lo(Attrs); { Copy low to high }
  820. WordRec(Attrs).Lo := B; { Complete exchange }
  821. End;
  822. End;
  823. END;
  824. {---------------------------------------------------------------------------}
  825. { MoveBuf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Jul99 LdB }
  826. {---------------------------------------------------------------------------}
  827. PROCEDURE MoveBuf (Var Dest, Source; Attr: Byte; Count: Sw_Word);
  828. VAR I: Word; P: PWord;
  829. BEGIN
  830. For I := 1 To Count Do Begin
  831. P := @TWordArray(Dest)[I-1]; { Pointer to Sw_Word }
  832. If (Attr <> 0) Then WordRec(P^).Hi := Attr; { Copy attribute }
  833. WordRec(P^).Lo := TByteArray(Source)[I-1]; { Copy source data }
  834. End;
  835. END;
  836. {---------------------------------------------------------------------------}
  837. { MoveChar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Jul99 LdB }
  838. {---------------------------------------------------------------------------}
  839. PROCEDURE MoveChar (Var Dest; C: Char; Attr: Byte; Count: Sw_Word);
  840. VAR I: Word; P: PWord;
  841. BEGIN
  842. For I := 1 To Count Do Begin
  843. P := @TWordArray(Dest)[I-1]; { Pointer to Sw_Word }
  844. If (Attr <> 0) Then WordRec(P^).Hi := Attr; { Copy attribute }
  845. If (Ord(C) <> 0) Then WordRec(P^).Lo := Byte(C); { Copy character }
  846. End;
  847. END;
  848. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  849. { KEYBOARD SUPPORT ROUTINES }
  850. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  851. {---------------------------------------------------------------------------}
  852. { GetAltCode -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
  853. {---------------------------------------------------------------------------}
  854. FUNCTION GetAltCode (Ch: Char): Word;
  855. BEGIN
  856. GetAltCode := 0; { Preset zero return }
  857. Ch := UpCase(Ch); { Convert upper case }
  858. If (Ch < #128) Then
  859. GetAltCode := AltCodes[Ord(Ch)] SHL 8 { Return code }
  860. Else If (Ch = #240) Then GetAltCode := $0200 { Return code }
  861. Else GetAltCode := 0; { Return zero }
  862. END;
  863. {---------------------------------------------------------------------------}
  864. { GetCtrlCode -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
  865. {---------------------------------------------------------------------------}
  866. FUNCTION GetCtrlCode (Ch: Char): Word;
  867. BEGIN
  868. GetCtrlCode := GetAltCode(Ch) OR (Ord(Ch) - $40); { Ctrl+key code }
  869. END;
  870. {---------------------------------------------------------------------------}
  871. { GetAltChar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
  872. {---------------------------------------------------------------------------}
  873. FUNCTION GetAltChar (KeyCode: Word): Char;
  874. VAR I: Sw_Integer;
  875. BEGIN
  876. GetAltChar := #0; { Preset fail return }
  877. If (Lo(KeyCode) = 0) Then Begin { Extended key }
  878. If (Hi(KeyCode) < 128) Then Begin { Key between 0-127 }
  879. I := 0; { Start at first }
  880. While (I < 128) AND (Hi(KeyCode) <> AltCodes[I])
  881. Do Inc(I); { Search for match }
  882. If (I < 128) Then GetAltChar := Chr(I); { Return character }
  883. End Else
  884. If (Hi(KeyCode)=$02) Then GetAltChar := #240; { Return char }
  885. End;
  886. END;
  887. {---------------------------------------------------------------------------}
  888. { GetCtrlChar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
  889. {---------------------------------------------------------------------------}
  890. FUNCTION GetCtrlChar (KeyCode: Word): Char;
  891. VAR C: Char;
  892. BEGIN
  893. C := #0; { Preset #0 return }
  894. If (Lo(KeyCode) > 0) AND (Lo(KeyCode) <= 26) Then { Between 1-26 }
  895. C := Chr(Lo(KeyCode) + $40); { Return char A-Z }
  896. GetCtrlChar := C; { Return result }
  897. END;
  898. {---------------------------------------------------------------------------}
  899. { CtrlToArrow -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
  900. {---------------------------------------------------------------------------}
  901. FUNCTION CtrlToArrow (KeyCode: Word): Word;
  902. CONST NumCodes = 11;
  903. CtrlCodes : Array [0..NumCodes-1] Of Char =
  904. (#19, #4, #5, #24, #1, #6, #7, #22, #18, #3, #8);
  905. ArrowCodes: Array [0..NumCodes-1] Of Sw_Word =
  906. (kbLeft, kbRight, kbUp, kbDown, kbHome, kbEnd, kbDel, kbIns,
  907. kbPgUp, kbPgDn, kbBack);
  908. VAR I: Sw_Integer;
  909. BEGIN
  910. CtrlToArrow := KeyCode; { Preset key return }
  911. For I := 0 To NumCodes - 1 Do
  912. If WordRec(KeyCode).Lo = Byte(CtrlCodes[I]) { Matches a code }
  913. Then Begin
  914. CtrlToArrow := ArrowCodes[I]; { Return key stroke }
  915. Exit; { Now exit }
  916. End;
  917. END;
  918. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  919. { KEYBOARD CONTROL ROUTINES }
  920. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  921. {---------------------------------------------------------------------------}
  922. { GetShiftState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jul96 LdB }
  923. {---------------------------------------------------------------------------}
  924. FUNCTION GetShiftState: Byte;
  925. begin
  926. GetShiftState:=Keyboard.GetKeyEventShiftState(Keyboard.PollShiftStateEvent);
  927. end;
  928. {---------------------------------------------------------------------------}
  929. { GetKeyEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
  930. {---------------------------------------------------------------------------}
  931. procedure GetKeyEvent (Var Event: TEvent);
  932. var
  933. key : TKeyEvent;
  934. keycode : Word;
  935. keyshift : byte;
  936. begin
  937. if Keyboard.PollKeyEvent<>0 then
  938. begin
  939. key:=Keyboard.GetKeyEvent;
  940. keycode:=Keyboard.GetKeyEventCode(key);
  941. keyshift:=KeyBoard.GetKeyEventShiftState(key);
  942. { fixup shift-keys }
  943. if keyshift and kbShift<>0 then
  944. begin
  945. case keycode of
  946. $5200 : keycode:=kbShiftIns;
  947. $5300 : keycode:=kbShiftDel;
  948. $8500 : keycode:=kbShiftF1;
  949. $8600 : keycode:=kbShiftF2;
  950. end;
  951. end
  952. { fixup ctrl-keys }
  953. else if keyshift and kbCtrl<>0 then
  954. begin
  955. case keycode of
  956. $5200,
  957. $9200 : keycode:=kbCtrlIns;
  958. $5300,
  959. $9300 : keycode:=kbCtrlDel;
  960. end;
  961. end
  962. { fixup alt-keys }
  963. else if keyshift and kbAlt<>0 then
  964. begin
  965. case keycode of
  966. $0e08,
  967. $0e00 : keycode:=kbAltBack;
  968. end;
  969. end
  970. { fixup normal keys }
  971. else
  972. begin
  973. case keycode of
  974. $e00d : keycode:=kbEnter;
  975. end;
  976. end;
  977. Event.What:=evKeyDown;
  978. Event.KeyCode:=keycode;
  979. Event.KeyShift:=keyshift;
  980. end
  981. else
  982. Event.What:=evNothing;
  983. end;
  984. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  985. { MOUSE CONTROL ROUTINES }
  986. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  987. {---------------------------------------------------------------------------}
  988. { HideMouse -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun98 LdB }
  989. {---------------------------------------------------------------------------}
  990. procedure HideMouse;
  991. begin
  992. { Is mouse hidden yet?
  993. If (HideCount = 0) Then}
  994. Mouse.HideMouse;
  995. { Inc(HideCount);}
  996. end;
  997. {---------------------------------------------------------------------------}
  998. { ShowMouse -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun98 LdB }
  999. {---------------------------------------------------------------------------}
  1000. procedure ShowMouse;
  1001. begin
  1002. { if HideCount>0 then
  1003. dec(HideCount);
  1004. if (HideCount=0) then}
  1005. Mouse.ShowMouse;
  1006. end;
  1007. {---------------------------------------------------------------------------}
  1008. { GetMouseEvent -> Platforms DOS/DPMI/WINDOWS/OS2 - Updated 30Jun98 LdB }
  1009. {---------------------------------------------------------------------------}
  1010. procedure GetMouseEvent (Var Event: TEvent);
  1011. var
  1012. e : Mouse.TMouseEvent;
  1013. begin
  1014. if Mouse.PollMouseEvent(e) then
  1015. begin
  1016. Mouse.GetMouseEvent(e);
  1017. MouseWhere.X:=e.x * SysFontWidth;
  1018. MouseWhere.Y:=e.y * SysFontHeight;
  1019. Event.Double:=false;
  1020. case e.Action of
  1021. MouseActionMove :
  1022. Event.What:=evMouseMove;
  1023. MouseActionDown :
  1024. begin
  1025. Event.What:=evMouseDown;
  1026. if (DownButtons=e.Buttons) and
  1027. (LastWhere.X=MouseWhere.X) and
  1028. (LastWhere.Y=MouseWhere.Y) and
  1029. (GetDosTicks-DownTicks<=DoubleDelay) then
  1030. Event.Double:=true;
  1031. DownButtons:=e.Buttons;
  1032. DownWhere.X:=MouseWhere.X;
  1033. DownWhere.Y:=MouseWhere.Y;
  1034. DownTicks:=GetDosTicks;
  1035. AutoTicks:=GetDosTicks;
  1036. AutoDelay:=RepeatDelay;
  1037. end;
  1038. MouseActionUp :
  1039. begin
  1040. Event.What:=evMouseUp;
  1041. end;
  1042. else
  1043. begin
  1044. if GetDosTicks-AutoTicks>=AutoDelay then
  1045. begin
  1046. Event.What:=evMouseAuto;
  1047. AutoTicks:=GetDosTicks;
  1048. AutoDelay:=1;
  1049. end;
  1050. end;
  1051. end;
  1052. Event.Buttons:=e.Buttons;
  1053. Event.Where.X:=MouseWhere.X;
  1054. Event.Where.Y:=MouseWhere.Y;
  1055. LastButtons:=Event.Buttons;
  1056. LastWhere.x:=Event.Where.x;
  1057. LastWhere.y:=Event.Where.y;
  1058. end
  1059. else
  1060. FillChar(Event,sizeof(TEvent),0);
  1061. end;
  1062. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1063. { EVENT HANDLER CONTROL ROUTINES }
  1064. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1065. {---------------------------------------------------------------------------}
  1066. { InitEvents -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 07Sep99 LdB }
  1067. {---------------------------------------------------------------------------}
  1068. PROCEDURE InitEvents;
  1069. BEGIN
  1070. If (ButtonCount <> 0) Then
  1071. begin { Mouse is available }
  1072. Mouse.InitMouse; { Hook the mouse }
  1073. { this is required by the use of HideCount variable }
  1074. Mouse.ShowMouse; { visible by default }
  1075. { HideCount:=0; }
  1076. LastButtons := 0; { Clear last buttons }
  1077. DownButtons := 0; { Clear down buttons }
  1078. MouseWhere.X:=Mouse.GetMouseX;
  1079. MouseWhere.Y:=Mouse.GetMouseY; { Get mouse position }
  1080. LastWhere.x:=MouseWhere.x;
  1081. LastWhereX:=MouseWhere.x;
  1082. LastWhere.y:=MouseWhere.y;
  1083. LastWhereY:=MouseWhere.y;
  1084. MouseEvents := True; { Set initialized flag }
  1085. end;
  1086. END;
  1087. {---------------------------------------------------------------------------}
  1088. { DoneEvents -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
  1089. {---------------------------------------------------------------------------}
  1090. PROCEDURE DoneEvents;
  1091. BEGIN
  1092. END;
  1093. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1094. { VIDEO CONTROL ROUTINES }
  1095. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1096. {---------------------------------------------------------------------------}
  1097. { InitVideo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Nov99 LdB }
  1098. {---------------------------------------------------------------------------}
  1099. PROCEDURE InitVideo;
  1100. VAR {$ifdef Use_Video_API}I, J: Sw_Integer;
  1101. {$else not Use_Video_API}
  1102. {$IFDEF OS_DOS} I, J: Integer;Ts: TextSettingsType;{$ENDIF}
  1103. {$IFDEF OS_WINDOWS} Dc, Mem: HDc; TempFont: TLogFont; Tm: TTextmetric; {$ENDIF}
  1104. {$IFDEF OS_OS2} Ts, Fs: Sw_Integer; Ps: HPs; Tm: FontMetrics; {$ENDIF}
  1105. {$ENDIF}
  1106. BEGIN
  1107. {$ifdef GRAPH_API}
  1108. I := Detect; { Detect video card }
  1109. J := 0; { Zero select mode }
  1110. InitGraph(I, J, ''); { Initialize graphics }
  1111. I := Graph.GetMaxX; { Fetch max x size }
  1112. J := Graph.GetMaxY; { Fetch max y size }
  1113. If (DefFontHeight = 0) Then { Font height not set }
  1114. J := (Graph.GetMaxY+1) DIV DefLineNum { Approx font height }
  1115. Else J := DefFontHeight; { Use set font height }
  1116. I := J DIV (TextHeight('H')+4); { Approx magnification }
  1117. If (I < 1) Then I := 1; { Must be 1 or above }
  1118. GetTextSettings(Ts); { Get text style }
  1119. SetTextStyle(Ts.Font, Ts.Direction, I); { Set new font settings }
  1120. SysFontWidth := TextWidth('H'); { Transfer font width }
  1121. SysFontHeight := TextHeight('H')+4; { Transfer font height }
  1122. ScreenWidth := (SysScreenWidth+1) DIV
  1123. SysFontWidth; { Calc screen width }
  1124. ScreenHeight := (SysScreenHeight+1) DIV
  1125. SysFontHeight; { Calc screen height }
  1126. {$else not GRAPH_API}
  1127. Video.InitVideo;
  1128. ScreenWidth:=Video.ScreenWidth;
  1129. ScreenHeight:=Video.ScreenHeight;
  1130. SetViewPort(0,0,ScreenWidth,ScreenHeight,true,true);
  1131. GetVideoMode(ScreenMode);
  1132. I := ScreenWidth*8 -1; { Mouse width }
  1133. J := ScreenHeight*8 -1; { Mouse height }
  1134. SysScreenWidth := I + 1;
  1135. SysScreenHeight := J + 1;
  1136. SysFontWidth := 8; { Font width }
  1137. SysFontHeight := 8; { Font height }
  1138. {$endif not GRAPH_API}
  1139. END;
  1140. {---------------------------------------------------------------------------}
  1141. { DoneVideo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
  1142. {---------------------------------------------------------------------------}
  1143. PROCEDURE DoneVideo;
  1144. BEGIN
  1145. {$ifdef GRAPH_API}
  1146. CloseGraph;
  1147. {$else not GRAPH_API}
  1148. {$ifdef USE_video_api}
  1149. Video.DoneVideo;
  1150. {$endif USE_video_api}
  1151. {$endif not GRAPH_API}
  1152. END;
  1153. {---------------------------------------------------------------------------}
  1154. { ClearScreen -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Jan97 LdB }
  1155. {---------------------------------------------------------------------------}
  1156. PROCEDURE ClearScreen;
  1157. BEGIN
  1158. {$ifndef GRAPH_API}
  1159. Video.ClearScreen;
  1160. {$endif GRAPH_API}
  1161. END;
  1162. {---------------------------------------------------------------------------}
  1163. { SetVideoMode -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Nov99 LdB }
  1164. {---------------------------------------------------------------------------}
  1165. PROCEDURE SetVideoMode (Mode: Sw_Word);
  1166. BEGIN
  1167. If (Mode > $100) Then DefLineNum := 50 { 50 line mode request }
  1168. Else DefLineNum := 24; { Normal 24 line mode }
  1169. END;
  1170. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1171. { ERROR CONTROL ROUTINES }
  1172. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1173. {---------------------------------------------------------------------------}
  1174. { InitSysError -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20May98 LdB }
  1175. {---------------------------------------------------------------------------}
  1176. PROCEDURE InitSysError;
  1177. BEGIN
  1178. SysErrActive := True; { Set active flag }
  1179. END;
  1180. {---------------------------------------------------------------------------}
  1181. { DoneSysError -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20May98 LdB }
  1182. {---------------------------------------------------------------------------}
  1183. PROCEDURE DoneSysError;
  1184. BEGIN
  1185. SysErrActive := False; { Clear active flag }
  1186. END;
  1187. {---------------------------------------------------------------------------}
  1188. { SystemError -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20May98 LdB }
  1189. {---------------------------------------------------------------------------}
  1190. FUNCTION SystemError (ErrorCode: Sw_Integer; Drive: Byte): Sw_Integer;
  1191. BEGIN
  1192. If (FailSysErrors = False) Then Begin { Check error ignore }
  1193. End Else SystemError := 1; { Return 1 for ignored }
  1194. END;
  1195. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1196. { STRING FORMAT ROUTINES }
  1197. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1198. {---------------------------------------------------------------------------}
  1199. { PrintStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Feb99 LdB }
  1200. {---------------------------------------------------------------------------}
  1201. PROCEDURE PrintStr (CONST S: String);
  1202. BEGIN
  1203. Write(S); { Write to screen }
  1204. END;
  1205. {---------------------------------------------------------------------------}
  1206. { FormatStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 13Jul99 LdB }
  1207. {---------------------------------------------------------------------------}
  1208. PROCEDURE FormatStr (Var Result: String; CONST Format: String; Var Params);
  1209. TYPE TLongArray = Array[0..0] Of LongInt;
  1210. VAR ResultLength, FormatIndex, Justify, Wth: Byte; Fill: Char; S: String;
  1211. FUNCTION LongToStr (L: Longint; Radix: Byte): String;
  1212. CONST HexChars: Array[0..15] Of Char =
  1213. ('0', '1', '2', '3', '4', '5', '6', '7',
  1214. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
  1215. VAR I: LongInt; S: String; Sign: String[1];
  1216. BEGIN
  1217. LongToStr := ''; { Preset empty return }
  1218. If (L < 0) Then Begin { If L is negative }
  1219. Sign := '-'; { Sign is negative }
  1220. L := Abs(L); { Convert to positive }
  1221. End Else Sign := ''; { Sign is empty }
  1222. S := ''; { Preset empty string }
  1223. Repeat
  1224. I := L MOD Radix; { Radix mod of value }
  1225. S := HexChars[I] + S; { Add char to string }
  1226. L := L DIV Radix; { Divid by radix }
  1227. Until (L = 0); { Until no remainder }
  1228. LongToStr := Sign + S; { Return result }
  1229. END;
  1230. PROCEDURE HandleParameter (I : LongInt);
  1231. BEGIN
  1232. While (FormatIndex <= Length(Format)) Do Begin { While length valid }
  1233. While (Format[FormatIndex] <> '%') AND { Param char not found }
  1234. (FormatIndex <= Length(Format)) Do Begin { Length still valid }
  1235. Result[ResultLength+1] := Format[FormatIndex]; { Transfer character }
  1236. Inc(ResultLength); { One character added }
  1237. Inc(FormatIndex); { Next param char }
  1238. End;
  1239. If (FormatIndex < Length(Format)) AND { Not last char and }
  1240. (Format[FormatIndex] = '%') Then Begin { '%' char found }
  1241. Fill := ' '; { Default fill char }
  1242. Justify := 0; { Default justify }
  1243. Wth := 0; { Default 0=no width }
  1244. Inc(FormatIndex); { Next character }
  1245. If (Format[FormatIndex] = '0') Then
  1246. Fill := '0'; { Fill char to zero }
  1247. If (Format[FormatIndex] = '-') Then Begin { Optional just char }
  1248. Justify := 1; { Right justify }
  1249. Inc(FormatIndex); { Next character }
  1250. End;
  1251. While ((FormatIndex <= Length(Format)) AND { Length still valid }
  1252. (Format[FormatIndex] >= '0') AND
  1253. (Format[FormatIndex] <= '9')) Do Begin { Numeric character }
  1254. Wth := Wth * 10; { Multiply x10 }
  1255. Wth := Wth + Ord(Format[FormatIndex])-$30; { Add numeric value }
  1256. Inc(FormatIndex); { Next character }
  1257. End;
  1258. If ((FormatIndex <= Length(Format)) AND { Length still valid }
  1259. (Format[FormatIndex] = '#')) Then Begin { Parameter marker }
  1260. Inc(FormatIndex); { Next character }
  1261. HandleParameter(Wth); { Width is param idx }
  1262. End;
  1263. If (FormatIndex <= Length(Format)) Then Begin{ Length still valid }
  1264. Case Format[FormatIndex] Of
  1265. 'c': S := Char(TLongArray(Params)[I]); { Character parameter }
  1266. 'd': S := LongToStr(TLongArray(Params)[I],
  1267. 10); { Decimal parameter }
  1268. 's': S := PString(TLongArray(Params)[I])^;{ String parameter }
  1269. 'x': S := LongToStr(TLongArray(Params)[I],
  1270. 16); { Hex parameter }
  1271. '%': Begin { Literal % }
  1272. S := '%'; { Set string }
  1273. Inc(FormatIndex); { Next character }
  1274. Move(S[1], Result[ResultLength+1], 1); { '%' char to result }
  1275. Inc(ResultLength, Length(S)); { Inc result length }
  1276. Continue; { Now continue }
  1277. End;
  1278. End;
  1279. Inc(I); { Next parameter }
  1280. Inc(FormatIndex); { Next character }
  1281. If (Wth > 0) Then Begin { Width control active }
  1282. If (Length(S) > Wth) Then Begin { We must shorten S }
  1283. If (Justify=1) Then { Check right justify }
  1284. S := Copy(S, Length(S)-Wth+1, Wth) { Take right side data }
  1285. Else S := Copy(S, 1, Wth); { Take left side data }
  1286. End Else Begin { We must pad out S }
  1287. If (Justify=1) Then { Right justify }
  1288. While (Length(S) < Wth) Do
  1289. S := S+Fill Else { Right justify fill }
  1290. While (Length(S) < Wth) Do
  1291. S := Fill + S; { Left justify fill }
  1292. End;
  1293. End;
  1294. Move(S[1], Result[ResultLength+1],
  1295. Length(S)); { Move data to result }
  1296. ResultLength := ResultLength + Length(S); { Adj result length }
  1297. End;
  1298. End;
  1299. End;
  1300. END;
  1301. BEGIN
  1302. ResultLength := 0; { Zero result length }
  1303. FormatIndex := 1; { Format index to 1 }
  1304. HandleParameter(0); { Handle parameter }
  1305. SetLength(Result, ResultLength); { Set string length }
  1306. END;
  1307. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1308. { NEW QUEUED EVENT HANDLER ROUTINES }
  1309. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  1310. {---------------------------------------------------------------------------}
  1311. { PutEventInQueue -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Mar98 LdB }
  1312. {---------------------------------------------------------------------------}
  1313. FUNCTION PutEventInQueue (Var Event: TEvent): Boolean;
  1314. BEGIN
  1315. If (QueueCount < QueueMax) Then Begin { Check room in queue }
  1316. Queue[QueueHead] := Event; { Store event }
  1317. Inc(QueueHead); { Inc head position }
  1318. If (QueueHead = QueueMax) Then QueueHead := 0; { Roll to start check }
  1319. Inc(QueueCount); { Inc queue count }
  1320. PutEventInQueue := True; { Return successful }
  1321. End Else PutEventInQueue := False; { Return failure }
  1322. END;
  1323. {---------------------------------------------------------------------------}
  1324. { NextQueuedEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Mar98 LdB }
  1325. {---------------------------------------------------------------------------}
  1326. PROCEDURE NextQueuedEvent(Var Event: TEvent);
  1327. BEGIN
  1328. If (QueueCount > 0) Then Begin { Check queued event }
  1329. Event := Queue[QueueTail]; { Fetch next event }
  1330. Inc(QueueTail); { Inc tail position }
  1331. If (QueueTail = QueueMax) Then QueueTail := 0; { Roll to start check }
  1332. Dec(QueueCount); { Dec queue count }
  1333. End Else Event.What := evNothing; { Return empty event }
  1334. END;
  1335. {***************************************************************************}
  1336. { UNIT INITIALIZATION ROUTINE }
  1337. {***************************************************************************}
  1338. BEGIN
  1339. ButtonCount := DetectMouse; { Detect mouse }
  1340. DetectVideo; { Detect video }
  1341. { text mode is the default mode }
  1342. TextModeGFV:=True;
  1343. InitKeyboard;
  1344. {$ifdef Graph_API}
  1345. TextModeGFV:=false;
  1346. {$endif Graph_API}
  1347. SaveExit := ExitProc; { Save old exit }
  1348. ExitProc := @ExitDrivers; { Set new exit }
  1349. END.
  1350. {
  1351. $Log$
  1352. Revision 1.13 2001-10-02 16:35:50 pierre
  1353. * fix several problems, try to get the graph version to compile
  1354. Revision 1.12 2001/08/05 02:03:13 peter
  1355. * view redrawing and small cursor updates
  1356. * merged some more FV extensions
  1357. Revision 1.11 2001/08/04 19:14:33 peter
  1358. * Added Makefiles
  1359. * added FV specific units and objects from old FV
  1360. Revision 1.10 2001/05/10 16:46:27 pierre
  1361. + some improovements made
  1362. Revision 1.9 2001/05/07 22:22:03 pierre
  1363. * removed NO_WINDOW cond, added GRAPH_API
  1364. Revision 1.8 2001/05/04 15:43:45 pierre
  1365. * several more fixes
  1366. Revision 1.7 2001/05/04 10:46:02 pierre
  1367. * various fixes for win32 api mode
  1368. Revision 1.6 2001/05/04 08:42:55 pierre
  1369. * some corrections for linux
  1370. Revision 1.5 2001/05/03 22:32:52 pierre
  1371. new bunch of changes, displays something for dos at least
  1372. Revision 1.4 2001/04/10 21:57:55 pierre
  1373. + first adds for Use_API define
  1374. Revision 1.3 2001/04/10 21:29:55 pierre
  1375. * import of Leon de Boer's files
  1376. Revision 1.2 2000/08/24 12:00:21 marco
  1377. * CVS log and ID tags
  1378. }
  1379. {******************[ REVISION HISTORY ]********************}
  1380. { Version Date Fix }
  1381. { ------- --------- --------------------------------- }
  1382. { 1.00 26 Jul 96 First DOS/DPMI platform release }
  1383. { 1.10 18 Nov 97 Windows conversion added. }
  1384. { 1.20 29 Aug 97 Platform.inc sort added. }
  1385. { 1.30 10 Jun 98 Virtual pascal 2.0 code added. }
  1386. { 1.40 13 Jul 98 Added FormatStr by Marco Schmidt. }
  1387. { 1.50 14 Jul 98 Fixed width = 0 in FormatStr. }
  1388. { 1.60 13 Aug 98 Complete rewrite of FormatStr. }
  1389. { 1.70 10 Sep 98 Added mouse int hook for FPC. }
  1390. { 1.80 10 Sep 98 Checks run & commenting added. }
  1391. { 1.90 15 Oct 98 Fixed for FPC version 0.998 }
  1392. { 1.91 18 Feb 99 Added PrintStr functions }
  1393. { 1.92 18 Feb 99 FormatStr literal '%' fix added }
  1394. { 1.93 10 Jul 99 Sybil 2.0 code added }
  1395. { 1.94 15 Jul 99 Fixed for FPC 0.9912 release }
  1396. { 1.95 26 Jul 99 Windows..Scales to GFV system font }
  1397. { 1.96 30 Jul 99 Fixed Ctrl+F1..F10 in GetKeyEvent }
  1398. { 1.97 07 Sep 99 InitEvent, DoneEvent fixed for OS2 }
  1399. { 1.98 09 Sep 99 GetMouseEvent fixed for OS2. }
  1400. { 1.99 03 Nov 99 FPC windows support added. }
  1401. { 2.00 26 Nov 99 Graphics stuff moved to GFVGraph }
  1402. { 2.01 21 May 00 DOS fixed to use std GRAPH unit }
  1403. {**********************************************************}