mouse.pp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. Mouse unit for Go32v2
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit Mouse;
  14. interface
  15. {$i mouseh.inc}
  16. { tells the mouse unit to draw the mouse cursor itself }
  17. procedure DoCustomMouse(b : boolean);
  18. implementation
  19. uses
  20. video,go32;
  21. {$i mouse.inc}
  22. var
  23. RealSeg : Word; { Real mode segment }
  24. RealOfs : Word; { Real mode offset }
  25. CurrentMask : word;
  26. MouseCallback : Pointer; { Mouse call back ptr }
  27. UnderNT: boolean;
  28. {$ifdef DEBUG}
  29. EntryEDI,EntryESI : longint;
  30. EntryDS,EntryES : word;
  31. {$endif DEBUG}
  32. { Real mode registers in text segment below $ffff limit
  33. for Windows NT
  34. NOTE this might cause problem if someone want to
  35. protect text section against writing (would be possible
  36. with CWSDPMI under raw dos, not implemented yet !) }
  37. ActionRegs : TRealRegs;external name '___v2prt0_rmcb_regs';
  38. v2prt0_ds_alias : word;external name '___v2prt0_ds_alias';
  39. const
  40. MousePresent : boolean = false;
  41. {$ifdef DEBUG}
  42. MouseError : longint = 0;
  43. CallCounter : longint = 0;
  44. {$endif DEBUG}
  45. drawmousecursor : boolean = false;
  46. mouseisvisible : boolean = false;
  47. { position where the mouse was drawn the last time }
  48. oldmousex : longint = -1;
  49. oldmousey : longint = -1;
  50. mouselock : boolean = false;
  51. { if the cursor is drawn by this the unit, we must be careful }
  52. { when drawing while the interrupt handler is called }
  53. procedure lockmouse;assembler;
  54. asm
  55. .Ltrylockagain:
  56. movb $1,%al
  57. xchgb mouselock,%al
  58. orb %al,%al
  59. jne .Ltrylockagain
  60. end;
  61. procedure unlockmouse;
  62. begin
  63. mouselock:=false;
  64. end;
  65. {$ASMMODE ATT}
  66. procedure MouseInt;assembler;
  67. asm
  68. movb %bl,mousebuttons
  69. movw %cx,mousewherex
  70. movw %dx,mousewherey
  71. shrw $3,%cx
  72. shrw $3,%dx
  73. { should we draw the mouse cursor? }
  74. cmpb $0,drawmousecursor
  75. je .Lmouse_nocursor
  76. cmpb $0,mouseisvisible
  77. je .Lmouse_nocursor
  78. pushw %fs
  79. pushl %eax
  80. pushl %edi
  81. { check lock }
  82. movb $1,%al
  83. xchgb mouselock,%al
  84. orb %al,%al
  85. { don't update the cursor yet, because hide/showcursor is called }
  86. jne .Ldont_draw
  87. { load start of video buffer }
  88. movzwl videoseg,%edi
  89. shll $4,%edi
  90. movw dosmemselector,%fs
  91. { calculate address of old mouse cursor }
  92. movl oldmousey,%eax
  93. imulw screenwidth,%ax
  94. addl oldmousex,%eax
  95. leal 1(%edi,%eax,2),%eax
  96. { remove old cursor }
  97. xorb $0x7f,%fs:(%eax)
  98. { store position of old cursor }
  99. movzwl %cx,%ecx
  100. movl %ecx,oldmousex
  101. movzwl %dx,%edx
  102. movl %edx,oldmousey
  103. { calculate address of new cursor }
  104. movl %edx,%eax
  105. imulw screenwidth,%ax
  106. addl %ecx,%eax
  107. leal 1(%edi,%eax,2),%eax
  108. { draw new cursor }
  109. xorb $0x7f,%fs:(%eax)
  110. { unlock mouse }
  111. movb $0,mouselock
  112. .Ldont_draw:
  113. popl %edi
  114. popl %eax
  115. popw %fs
  116. .Lmouse_nocursor:
  117. cmpb MouseEventBufSize,PendingMouseEvents
  118. je .Lmouse_exit
  119. movl PendingMouseTail,%edi
  120. movw %bx,(%edi)
  121. movw %cx,2(%edi)
  122. movw %dx,4(%edi)
  123. movw $0,6(%edi)
  124. addl $8,%edi
  125. leal PendingMouseEvent,%eax
  126. addl MouseEventBufSize*8,%eax
  127. cmpl %eax,%edi
  128. jne .Lmouse_nowrap
  129. leal PendingMouseEvent,%edi
  130. .Lmouse_nowrap:
  131. movl %edi,PendingMouseTail
  132. incb PendingMouseEvents
  133. .Lmouse_exit:
  134. end;
  135. PROCEDURE Mouse_Trap; ASSEMBLER;
  136. ASM
  137. PUSH %ES; { Save ES register }
  138. PUSH %DS; { Save DS register }
  139. PUSHL %EDI; { Save register }
  140. PUSHL %ESI; { Save register }
  141. { ; caution : ds is not the selector for our data !! }
  142. {$ifdef DEBUG}
  143. MOVL %EDI,%ES:EntryEDI
  144. MOVL %ESI,%ES:EntryESI
  145. MOVW %DS,%AX
  146. MOVW %AX,%ES:EntryDS
  147. MOVW %ES,%AX
  148. MOVW %AX,%ES:EntryES
  149. {$endif DEBUG}
  150. { movw %cs:v2prt0_ds_alias,%ax v2prt0 is not locked !!
  151. movw %ax,%ds
  152. movw %ax,%es }
  153. PUSH %ES; { Push data seg }
  154. POP %DS; { Load data seg }
  155. {$ifdef DEBUG}
  156. incl callcounter
  157. CMPL $ACTIONREGS,%edi
  158. JE .L_ActionRegsOK
  159. INCL MouseError
  160. JMP .L_NoCallBack
  161. .L_ActionRegsOK:
  162. {$endif DEBUG}
  163. MOVL MOUSECALLBACK, %EAX; { Fetch callback addr }
  164. CMPL $0, %EAX; { Check for nil ptr }
  165. JZ .L_NoCallBack; { Ignore if nil }
  166. MOVL %EDI,%EAX; { %EAX = @actionregs }
  167. MOVL (%EAX), %EDI; { EDI from actionregs }
  168. MOVL 4(%EAX), %ESI; { ESI from actionregs }
  169. MOVL 16(%EAX), %EBX; { EBX from actionregs }
  170. MOVL 20(%EAX), %EDX; { EDX from actionregs }
  171. MOVL 24(%EAX), %ECX; { ECX from actionregs }
  172. MOVL 28(%EAX), %EAX; { EAX from actionregs }
  173. CALL *MOUSECALLBACK; { Call callback proc }
  174. .L_NoCallBack:
  175. POPL %ESI; { Recover register }
  176. POPL %EDI; { Recover register }
  177. POP %DS; { Restore DS register }
  178. POP %ES; { Restore ES register }
  179. { This works for WinNT
  180. movzwl %si,%eax
  181. but CWSDPMI need this }
  182. movl %esi,%eax
  183. MOVL %ds:(%Eax), %EAX;
  184. MOVL %EAX, %ES:42(%EDI); { Set as return addr }
  185. ADDW $4, %ES:46(%EDI); { adjust stack }
  186. IRET; { Interrupt return }
  187. END;
  188. PROCEDURE Mouse_Trap_NT; ASSEMBLER;
  189. ASM
  190. PUSH %ES; { Save ES register }
  191. PUSH %DS; { Save DS register }
  192. PUSHL %EDI; { Save register }
  193. PUSHL %ESI; { Save register }
  194. { ; caution : ds is not the selector for our data !! }
  195. {$ifdef DEBUG}
  196. MOVL %EDI,%ES:EntryEDI
  197. MOVL %ESI,%ES:EntryESI
  198. MOVW %DS,%AX
  199. MOVW %AX,%ES:EntryDS
  200. MOVW %ES,%AX
  201. MOVW %AX,%ES:EntryES
  202. {$endif DEBUG}
  203. { movw %cs:v2prt0_ds_alias,%ax v2prt0 is not locked !!
  204. movw %ax,%ds
  205. movw %ax,%es }
  206. PUSH %ES; { Push data seg }
  207. POP %DS; { Load data seg }
  208. {$ifdef DEBUG}
  209. incl callcounter
  210. CMPL $ACTIONREGS,%edi
  211. JE .L_ActionRegsOK
  212. INCL MouseError
  213. JMP .L_NoCallBack
  214. .L_ActionRegsOK:
  215. {$endif DEBUG}
  216. MOVL MOUSECALLBACK, %EAX; { Fetch callback addr }
  217. CMPL $0, %EAX; { Check for nil ptr }
  218. JZ .L_NoCallBack; { Ignore if nil }
  219. MOVL %EDI,%EAX; { %EAX = @actionregs }
  220. MOVL (%EAX), %EDI; { EDI from actionregs }
  221. MOVL 4(%EAX), %ESI; { ESI from actionregs }
  222. MOVL 16(%EAX), %EBX; { EBX from actionregs }
  223. MOVL 20(%EAX), %EDX; { EDX from actionregs }
  224. MOVL 24(%EAX), %ECX; { ECX from actionregs }
  225. MOVL 28(%EAX), %EAX; { EAX from actionregs }
  226. CALL *MOUSECALLBACK; { Call callback proc }
  227. .L_NoCallBack:
  228. POPL %ESI; { Recover register }
  229. POPL %EDI; { Recover register }
  230. POP %DS; { Restore DS register }
  231. POP %ES; { Restore ES register }
  232. movzwl %si,%eax
  233. MOVL %ds:(%Eax), %EAX;
  234. MOVL %EAX, %ES:42(%EDI); { Set as return addr }
  235. ADDW $4, %ES:46(%EDI); { adjust stack }
  236. IRET; { Interrupt return }
  237. END;
  238. Function Allocate_mouse_bridge : boolean;
  239. var
  240. error : word;
  241. begin
  242. ASM
  243. LEAL ACTIONREGS, %EDI; { Addr of actionregs }
  244. LEAL MOUSE_TRAP, %ESI; { Procedure address }
  245. CMPB $0, UnderNT
  246. JZ .LGo32
  247. LEAL MOUSE_TRAP_NT, %ESI; { Procedure address }
  248. .LGo32:
  249. PUSH %DS; { Save DS segment }
  250. PUSH %ES; { Save ES segment }
  251. MOVW v2prt0_ds_alias,%ES; { ES now has dataseg alias that is never invalid }
  252. PUSH %CS;
  253. POP %DS; { DS now has codeseg }
  254. MOVW $0x303, %AX; { Function id }
  255. INT $0x31; { Call DPMI bridge }
  256. JNC .L_call_ok; { Branch if ok }
  257. POP %ES; { Restore ES segment }
  258. POP %DS; { Restore DS segment }
  259. MOVW $0,REALSEG;
  260. MOVW $0,REALOFS;
  261. JMP .L_exit
  262. .L_call_ok:
  263. POP %ES; { Restore ES segment }
  264. POP %DS; { Restore DS segment }
  265. MOVW %CX,REALSEG; { Transfer real seg }
  266. MOVW %DX,REALOFS; { Transfer real ofs }
  267. MOVW $0, %AX; { Force error to zero }
  268. .L_exit:
  269. MOVW %AX, ERROR; { Return error state }
  270. END;
  271. Allocate_mouse_bridge:=error=0;
  272. end;
  273. Procedure Release_mouse_bridge;
  274. begin
  275. ASM
  276. MOVW $0x304, %AX; { Set function id }
  277. MOVW REALSEG, %CX; { Bridged real seg }
  278. MOVW REALOFS, %DX; { Bridged real ofs }
  279. INT $0x31; { Release bridge }
  280. MOVW $0,REALSEG;
  281. MOVW $0,REALOFS;
  282. END;
  283. end;
  284. PROCEDURE Mouse_Action (Mask : Word; P : Pointer);
  285. VAR
  286. Error : Word;
  287. Rg : TRealRegs;
  288. BEGIN
  289. Error := 0; { Preset no error }
  290. If (P <> MouseCallBack) or (Mask<>CurrentMask) Then { Check func different }
  291. Begin
  292. { Remove old calback }
  293. If (CurrentMask <> 0) Then
  294. Begin
  295. Rg.AX := 12; { Function id }
  296. Rg.CX := 0; { Zero mask register }
  297. Rg.ES := 0; { Zero proc seg }
  298. Rg.DX := 0; { Zero proc ofs }
  299. RealIntr($33, Rg); { Stop INT 33 callback }
  300. End;
  301. if RealSeg=0 then
  302. error:=1;
  303. { test addresses for Windows NT }
  304. if (longint(@actionregs)>$ffff) {or
  305. (longint(@mouse_trap)>$ffff)} then
  306. begin
  307. error:=1;
  308. end
  309. else If (P = Nil) Then
  310. Begin
  311. Mask := 0; { Zero mask register }
  312. End;
  313. If (Error = 0) Then
  314. Begin
  315. MouseCallback := P; { Set call back addr }
  316. if Mask<>0 then
  317. begin
  318. Rg.AX := 12; { Set function id }
  319. Rg.CX := Mask; { Set mask register }
  320. If Mask<>0 then
  321. begin
  322. Rg.ES := RealSeg; { Real mode segment }
  323. Rg.DX := RealOfs; { Real mode offset }
  324. end
  325. else
  326. begin
  327. Rg.ES:=0;
  328. Rg.DX:=0;
  329. end;
  330. RealIntr($33, Rg); { Set interrupt 33 }
  331. end;
  332. CurrentMask:=Mask;
  333. End;
  334. End;
  335. If (Error <> 0) Then
  336. Begin
  337. Writeln('GO32V2 mouse handler set failed !!');
  338. ReadLn; { Wait for user to see }
  339. End;
  340. END;
  341. { We need to remove the mouse callback before exiting !! PM }
  342. const StoredExit : Pointer = Nil;
  343. FirstMouseInitDone : boolean = false;
  344. procedure MouseSafeExit;
  345. begin
  346. ExitProc:=StoredExit;
  347. if MouseCallBack<>Nil then
  348. Mouse_Action(0, Nil);
  349. if not FirstMouseInitDone then
  350. exit;
  351. FirstMouseInitDone:=false;
  352. Unlock_Code(Pointer(@Mouse_Trap), 400); { Release trap code }
  353. Unlock_Code(Pointer(@Mouse_Trap_NT), 400); { Release trap code }
  354. Unlock_Code(Pointer(@MouseInt), 400); { Lock MouseInt code }
  355. Unlock_Data(ActionRegs, SizeOf(TRealRegs)); { Release registers }
  356. UnLock_Data(MouseCallBack,SizeOf(Pointer));
  357. { unlock Mouse Queue and related stuff ! }
  358. Unlock_Data(PendingMouseEvent,
  359. MouseEventBufSize*Sizeof(TMouseEvent));
  360. Unlock_Data(PendingMouseTail,SizeOf(longint));
  361. Unlock_Data(PendingMouseEvents,sizeof(byte));
  362. Unlock_Data(MouseButtons,SizeOf(byte));
  363. Unlock_Data(MouseWhereX,SizeOf(word));
  364. Unlock_Data(MouseWhereY,SizeOf(word));
  365. Unlock_Data(drawmousecursor,SizeOf(boolean));
  366. Unlock_Data(mouseisvisible,SizeOf(boolean));
  367. Unlock_Data(mouselock,SizeOf(boolean));
  368. Unlock_Data(videoseg,SizeOf(word));
  369. Unlock_Data(dosmemselector,SizeOf(word));
  370. Unlock_Data(screenwidth,SizeOf(word));
  371. Unlock_Data(OldMouseX,SizeOf(longint));
  372. Unlock_Data(OldMouseY,SizeOf(longint));
  373. {$ifdef DEBUG}
  374. Unlock_Data(EntryEDI, SizeOf(longint));
  375. Unlock_Data(EntryESI, SizeOf(longint));
  376. Unlock_Data(EntryDS, SizeOf(word));
  377. Unlock_Data(EntryES, SizeOf(word));
  378. Unlock_Data(MouseError, SizeOf(longint));
  379. Unlock_Data(callcounter, SizeOf(longint));
  380. {$endif DEBUG}
  381. Release_mouse_bridge;
  382. end;
  383. function RunningUnderWINNT: boolean;
  384. var r: trealregs;
  385. begin
  386. fillchar(r,sizeof(r),0);
  387. r.ax:=$3306;
  388. realintr($21,r);
  389. RunningUnderWINNT:=(r.bx=$3205);
  390. end;
  391. procedure SysInitMouse;
  392. begin
  393. UnderNT:=RunningUnderWINNT;
  394. if not MousePresent then
  395. begin
  396. if DetectMouse=0 then
  397. begin
  398. Writeln('No mouse driver found ');
  399. exit;
  400. end
  401. else
  402. MousePresent:=true;
  403. end;
  404. { don't do this twice !! PM }
  405. If not FirstMouseInitDone then
  406. begin
  407. StoredExit:=ExitProc;
  408. ExitProc:=@MouseSafeExit;
  409. Lock_Code(Pointer(@Mouse_Trap), 400); { Lock trap code }
  410. Lock_Code(Pointer(@Mouse_Trap_NT), 400); { Lock trap code }
  411. Lock_Code(Pointer(@MouseInt), 400); { Lock MouseInt code }
  412. Lock_Data(ActionRegs, SizeOf(TRealRegs)); { Lock registers }
  413. Lock_Data(MouseCallBack, SizeOf(pointer));
  414. { lock Mouse Queue and related stuff ! }
  415. Lock_Data(PendingMouseEvent,
  416. MouseEventBufSize*Sizeof(TMouseEvent));
  417. Lock_Data(PendingMouseTail,SizeOf(longint));
  418. Lock_Data(PendingMouseEvents,sizeof(byte));
  419. Lock_Data(MouseButtons,SizeOf(byte));
  420. Lock_Data(MouseWhereX,SizeOf(word));
  421. Lock_Data(MouseWhereY,SizeOf(word));
  422. Lock_Data(drawmousecursor,SizeOf(boolean));
  423. Lock_Data(mouseisvisible,SizeOf(boolean));
  424. Lock_Data(mouselock,SizeOf(boolean));
  425. Lock_Data(videoseg,SizeOf(word));
  426. Lock_Data(dosmemselector,SizeOf(word));
  427. Lock_Data(screenwidth,SizeOf(word));
  428. Lock_Data(OldMouseX,SizeOf(longint));
  429. Lock_Data(OldMouseY,SizeOf(longint));
  430. {$ifdef DEBUG}
  431. Lock_Data(EntryEDI, SizeOf(longint));
  432. Lock_Data(EntryESI, SizeOf(longint));
  433. Lock_Data(EntryDS, SizeOf(word));
  434. Lock_Data(EntryES, SizeOf(word));
  435. Lock_Data(MouseError, SizeOf(longint));
  436. Lock_Data(callcounter, SizeOf(longint));
  437. {$endif DEBUG}
  438. Allocate_mouse_bridge;
  439. FirstMouseInitDone:=true;
  440. end;
  441. If MouseCallBack=Nil then
  442. Mouse_Action($ffff, @MouseInt); { Set masks/interrupt }
  443. drawmousecursor:=false;
  444. mouseisvisible:=false;
  445. if (screenwidth>80) or (screenheight>50) then
  446. DoCustomMouse(true);
  447. ShowMouse;
  448. end;
  449. procedure SysDoneMouse;
  450. begin
  451. HideMouse;
  452. If (MouseCallBack <> Nil) Then
  453. Mouse_Action(0, Nil); { Clear mask/interrupt }
  454. end;
  455. function SysDetectMouse:byte;assembler;
  456. asm
  457. movl $0x200,%eax
  458. movl $0x33,%ebx
  459. int $0x31
  460. movw %cx,%ax
  461. orw %ax,%dx
  462. jz .Lno_mouse
  463. xorl %eax,%eax
  464. pushl %ebp
  465. int $0x33
  466. popl %ebp
  467. orw %ax,%ax
  468. jz .Lno_mouse
  469. movl %ebx,%eax
  470. .Lno_mouse:
  471. end;
  472. procedure SysShowMouse;
  473. begin
  474. if drawmousecursor then
  475. begin
  476. lockmouse;
  477. if not(mouseisvisible) then
  478. begin
  479. oldmousex:=getmousex-1;
  480. oldmousey:=getmousey-1;
  481. mem[videoseg:(((screenwidth*oldmousey)+oldmousex)*2)+1]:=
  482. mem[videoseg:(((screenwidth*oldmousey)+oldmousex)*2)+1] xor $7f;
  483. mouseisvisible:=true;
  484. end;
  485. unlockmouse;
  486. end
  487. else
  488. asm
  489. cmpb $1,MousePresent
  490. jne .LShowMouseExit
  491. movl $1,%eax
  492. pushl %ebp
  493. int $0x33
  494. popl %ebp
  495. .LShowMouseExit:
  496. end;
  497. end;
  498. procedure SysHideMouse;
  499. begin
  500. if drawmousecursor then
  501. begin
  502. lockmouse;
  503. if mouseisvisible then
  504. begin
  505. mouseisvisible:=false;
  506. mem[videoseg:(((screenwidth*oldmousey)+oldmousex)*2)+1]:=
  507. mem[videoseg:(((screenwidth*oldmousey)+oldmousex)*2)+1] xor $7f;
  508. oldmousex:=-1;
  509. oldmousey:=-1;
  510. end;
  511. unlockmouse;
  512. end
  513. else
  514. asm
  515. cmpb $1,MousePresent
  516. jne .LHideMouseExit
  517. movl $2,%eax
  518. pushl %ebp
  519. int $0x33
  520. popl %ebp
  521. .LHideMouseExit:
  522. end;
  523. end;
  524. function SysGetMouseX:word;assembler;
  525. asm
  526. cmpb $1,MousePresent
  527. jne .LGetMouseXError
  528. movl $3,%eax
  529. pushl %ebp
  530. int $0x33
  531. popl %ebp
  532. movzwl %cx,%eax
  533. shrl $3,%eax
  534. incl %eax
  535. ret
  536. .LGetMouseXError:
  537. xorl %eax,%eax
  538. end;
  539. function SysGetMouseY:word;assembler;
  540. asm
  541. cmpb $1,MousePresent
  542. jne .LGetMouseYError
  543. movl $3,%eax
  544. pushl %ebp
  545. int $0x33
  546. popl %ebp
  547. movzwl %dx,%eax
  548. shrl $3,%eax
  549. incl %eax
  550. ret
  551. .LGetMouseYError:
  552. xorl %eax,%eax
  553. end;
  554. function SysGetMouseButtons:word;assembler;
  555. asm
  556. cmpb $1,MousePresent
  557. jne .LGetMouseButtonsError
  558. movl $3,%eax
  559. pushl %ebp
  560. int $0x33
  561. popl %ebp
  562. movw %bx,%ax
  563. ret
  564. .LGetMouseButtonsError:
  565. xorl %eax,%eax
  566. end;
  567. procedure SysSetMouseXY(x,y:word);assembler;
  568. asm
  569. cmpb $1,MousePresent
  570. jne .LSetMouseXYExit
  571. movw x,%cx
  572. movw y,%dx
  573. movl $4,%eax
  574. pushl %ebp
  575. int $0x33
  576. popl %ebp
  577. .LSetMouseXYExit:
  578. end;
  579. Procedure SetMouseXRange (Min,Max:Longint);
  580. begin
  581. If Not(MousePresent) Then Exit;
  582. asm
  583. movl $7,%eax
  584. movl min,%ecx
  585. movl max,%edx
  586. pushl %ebp
  587. int $0x33
  588. popl %ebp
  589. end;
  590. end;
  591. Procedure SetMouseYRange (min,max:Longint);
  592. begin
  593. If Not(MousePresent) Then Exit;
  594. asm
  595. movl $8,%eax
  596. movl min,%ecx
  597. movl max,%edx
  598. pushl %ebp
  599. int $0x33
  600. popl %ebp
  601. end;
  602. end;
  603. procedure DoCustomMouse(b : boolean);
  604. begin
  605. HideMouse;
  606. lockmouse;
  607. oldmousex:=-1;
  608. oldmousey:=-1;
  609. SetMouseXRange(0,(screenwidth-1)*8);
  610. SetMouseYRange(0,(screenheight-1)*8);
  611. if b then
  612. begin
  613. mouseisvisible:=false;
  614. drawmousecursor:=true;
  615. end
  616. else
  617. drawmousecursor:=false;
  618. unlockmouse;
  619. end;
  620. const
  621. LastCallcounter : longint = 0;
  622. procedure SysGetMouseEvent(var MouseEvent: TMouseEvent);
  623. begin
  624. if not MousePresent then
  625. begin
  626. Fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  627. end;
  628. {$ifdef DEBUG}
  629. if mouseError>0 then
  630. Writeln('Errors in mouse Handler ',MouseError);
  631. {$ifdef EXTMOUSEDEBUG}
  632. if callcounter>LastCallcounter then
  633. Writeln('Number of calls in mouse Handler ',Callcounter);
  634. {$endif EXTMOUSEDEBUG}
  635. LastCallcounter:=Callcounter;
  636. {$endif DEBUG}
  637. repeat until PendingMouseEvents>0;
  638. MouseEvent:=PendingMouseHead^;
  639. inc(PendingMouseHead);
  640. if longint(PendingMouseHead)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
  641. PendingMouseHead:=@PendingMouseEvent;
  642. dec(PendingMouseEvents);
  643. if (LastMouseEvent.x<>MouseEvent.x) or (LastMouseEvent.y<>MouseEvent.y) then
  644. MouseEvent.Action:=MouseActionMove;
  645. if (LastMouseEvent.Buttons<>MouseEvent.Buttons) then
  646. begin
  647. if (LastMouseEvent.Buttons=0) then
  648. MouseEvent.Action:=MouseActionDown
  649. else
  650. MouseEvent.Action:=MouseActionUp;
  651. end;
  652. LastMouseEvent:=MouseEvent;
  653. end;
  654. Const
  655. SysMouseDriver : TMouseDriver = (
  656. useDefaultQueue : true;
  657. InitDriver : @SysInitMouse;
  658. DoneDriver : @SysDoneMouse;
  659. DetectMouse : @SysDetectMouse;
  660. ShowMouse : @SysShowMouse;
  661. HideMouse : @SysHideMouse;
  662. GetMouseX : @SysGetMouseX;
  663. GetMouseY : @SysGetMouseY;
  664. GetMouseButtons : @SysGetMouseButtons;
  665. SetMouseXY : @SysSetMouseXY;
  666. GetMouseEvent : @SysGetMouseEvent;
  667. PollMouseEvent : Nil;
  668. PutMouseEvent : Nil;
  669. );
  670. Begin
  671. SetMouseDriver(SysMouseDriver);
  672. end.
  673. {
  674. $Log$
  675. Revision 1.2 2001-09-22 00:01:42 michael
  676. + Merged driver support for mouse from fixbranch
  677. Revision 1.1.2.2 2001/09/21 23:53:48 michael
  678. + Added mouse driver support.
  679. Revision 1.1.2.1 2001/01/30 21:52:01 peter
  680. * moved api utils to rtl
  681. Revision 1.1 2001/01/13 11:03:58 peter
  682. * API 2 RTL commit
  683. }