drivers.pas 70 KB

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