callback.pp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. {$ASMMODE ATT}
  2. {$MODE FPC}
  3. uses
  4. crt,
  5. go32;
  6. const
  7. mouseint = $33;
  8. var
  9. mouse_regs : trealregs; external name '___v2prt0_rmcb_regs';
  10. mouse_seginfo : tseginfo;
  11. var
  12. mouse_numbuttons : longint;
  13. mouse_action : word;
  14. mouse_x, mouse_y : Word;
  15. mouse_b : Word;
  16. userproc_installed : Longbool;
  17. userproc_length : Longint;
  18. userproc_proc : pointer;
  19. procedure callback_handler; assembler;
  20. asm
  21. pushw %ds
  22. pushl %eax
  23. movw %es, %ax
  24. movw %ax, %ds
  25. cmpl $1, USERPROC_INSTALLED
  26. jne .LNoCallback
  27. pushal
  28. movw DOSmemSELECTOR, %ax
  29. movw %ax, %fs
  30. call *USERPROC_PROC
  31. popal
  32. .LNoCallback:
  33. popl %eax
  34. popw %ds
  35. pushl %eax
  36. movl (%esi), %eax
  37. movl %eax, %es: 42(%edi)
  38. addw $4, %es:46(%edi)
  39. popl %eax
  40. iret
  41. end;
  42. procedure mouse_dummy; begin end;
  43. procedure textuserproc;
  44. begin
  45. mouse_b := mouse_regs.bx;
  46. mouse_x := (mouse_regs.cx shr 3) + 1;
  47. mouse_y := (mouse_regs.dx shr 3) + 1;
  48. end;
  49. procedure install_mouse(userproc : pointer; userproclen : longint);
  50. var r : trealregs;
  51. begin
  52. r.eax := $0; realintr(mouseint, r);
  53. if (r.eax <> $FFFF) then begin
  54. Writeln('No Microsoft compatible mouse found');
  55. Writeln('A Microsoft compatible mouse driver is necessary ',
  56. 'to run this example');
  57. halt;
  58. end;
  59. if (r.bx = $ffff) then mouse_numbuttons := 2
  60. else mouse_numbuttons := r.bx;
  61. Writeln(mouse_numbuttons, ' button Microsoft compatible mouse ',
  62. ' found.');
  63. if (userproc <> nil) then begin
  64. userproc_proc := userproc;
  65. userproc_installed := true;
  66. userproc_length := userproclen;
  67. lock_code(userproc_proc, userproc_length);
  68. end else begin
  69. userproc_proc := nil;
  70. userproc_length := 0;
  71. userproc_installed := false;
  72. end;
  73. lock_data(mouse_x, sizeof(mouse_x));
  74. lock_data(mouse_y, sizeof(mouse_y));
  75. lock_data(mouse_b, sizeof(mouse_b));
  76. lock_data(mouse_action, sizeof(mouse_action));
  77. lock_data(userproc_installed, sizeof(userproc_installed));
  78. lock_data(userproc_proc, sizeof(userproc_proc));
  79. lock_data(mouse_regs, sizeof(mouse_regs));
  80. lock_data(mouse_seginfo, sizeof(mouse_seginfo));
  81. lock_code(@callback_handler,
  82. longint(@mouse_dummy)-longint(@callback_handler));
  83. get_rm_callback(@callback_handler, mouse_regs, mouse_seginfo);
  84. r.eax := $0c; r.ecx := $7f;
  85. r.edx := longint(mouse_seginfo.offset);
  86. r.es := mouse_seginfo.segment;
  87. realintr(mouseint, r);
  88. r.eax := $01;
  89. realintr(mouseint, r);
  90. end;
  91. procedure remove_mouse;
  92. var
  93. r : trealregs;
  94. begin
  95. r.eax := $02; realintr(mouseint, r);
  96. r.eax := $0c; r.ecx := 0; r.edx := 0; r.es := 0;
  97. realintr(mouseint, r);
  98. free_rm_callback(mouse_seginfo);
  99. if (userproc_installed) then begin
  100. unlock_code(userproc_proc, userproc_length);
  101. userproc_proc := nil;
  102. userproc_length := 0;
  103. userproc_installed := false;
  104. end;
  105. unlock_data(mouse_x, sizeof(mouse_x));
  106. unlock_data(mouse_y, sizeof(mouse_y));
  107. unlock_data(mouse_b, sizeof(mouse_b));
  108. unlock_data(mouse_action, sizeof(mouse_action));
  109. unlock_data(userproc_proc, sizeof(userproc_proc));
  110. unlock_data(userproc_installed, sizeof(userproc_installed));
  111. unlock_data(mouse_regs, sizeof(mouse_regs));
  112. unlock_data(mouse_seginfo, sizeof(mouse_seginfo));
  113. unlock_code(@callback_handler,
  114. longint(@mouse_dummy)-longint(@callback_handler));
  115. fillchar(mouse_seginfo, sizeof(mouse_seginfo), 0);
  116. end;
  117. begin
  118. install_mouse(@textuserproc, 400);
  119. Writeln('Press any key to exit...');
  120. while (not keypressed) do begin
  121. gotoxy(1, wherey);
  122. write('MouseX : ', mouse_x:2, ' MouseY : ', mouse_y:2,
  123. ' Buttons : ', mouse_b:2);
  124. end;
  125. remove_mouse;
  126. end.