mouse.inc 21 KB

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