mouse.pp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  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 linux
  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. {$ifdef NOMOUSE}
  16. {$DEFINE NOGPM}
  17. {$ENDIF}
  18. {$i mouseh.inc}
  19. implementation
  20. uses
  21. BaseUnix,Video
  22. {$ifndef NOGPM}
  23. ,gpm
  24. {$endif ndef NOGPM}
  25. ;
  26. {$i mouse.inc}
  27. {$ifndef NOMOUSE}
  28. const
  29. WaitMouseMove : boolean = false;
  30. PrintMouseCur : boolean = false;
  31. mousecurofs : longint = -1;
  32. var
  33. mousecurcell : TVideoCell;
  34. SysLastMouseEvent : TMouseEvent;
  35. const
  36. gpm_fs : longint = -1;
  37. {$ifndef NOGPM}
  38. procedure GPMEvent2MouseEvent(const e:TGPMEvent;var mouseevent:tmouseevent);
  39. var
  40. PrevButtons : byte;
  41. begin
  42. PrevButtons:=SysLastMouseEvent.Buttons;
  43. if e.x>0 then
  44. mouseevent.x:=e.x-1
  45. else
  46. MouseEvent.x:=0;
  47. if e.y>0 then
  48. MouseEvent.y:=e.y-1
  49. else
  50. MouseEvent.y:=0;
  51. MouseEvent.buttons:=0;
  52. if e.buttons and Gpm_b_left<>0 then
  53. inc(MouseEvent.buttons,1);
  54. if e.buttons and Gpm_b_right<>0 then
  55. inc(MouseEvent.buttons,2);
  56. if e.buttons and Gpm_b_middle<>0 then
  57. inc(MouseEvent.buttons,4);
  58. case (e.EventType and $f) of
  59. GPM_MOVE,
  60. GPM_DRAG :
  61. begin
  62. MouseEvent.Action:=MouseActionMove;
  63. WaitMouseMove:=false;
  64. end;
  65. GPM_DOWN :
  66. begin
  67. MouseEvent.Action:=MouseActionDown;
  68. WaitMouseMove:=false;
  69. end;
  70. GPM_UP :
  71. begin
  72. { gpm apparently sends the button that is left up
  73. while mouse unit expects the button state after
  74. the button was released PM }
  75. if MouseEvent.Buttons<>0 then
  76. begin
  77. MouseEvent.Buttons:=MouseEvent.Buttons xor PrevButtons;
  78. MouseEvent.Action:=MouseActionUp;
  79. end
  80. { this does probably never happen...
  81. but its just a security PM }
  82. else
  83. MouseEvent.Action:=MouseActionMove;
  84. WaitMouseMove:=false;
  85. end;
  86. else
  87. MouseEvent.Action:=0;
  88. end;
  89. end;
  90. {$ENDIF}
  91. procedure PlaceMouseCur(ofs:longint);
  92. var
  93. upd : boolean;
  94. begin
  95. if (VideoBuf=nil) or (MouseCurOfs=Ofs) then
  96. exit;
  97. upd:=false;
  98. if (MouseCurOfs<>-1) and (VideoBuf^[MouseCurOfs]=MouseCurCell) then
  99. begin
  100. VideoBuf^[MouseCurOfs]:=MouseCurCell xor $7f00;
  101. upd:=true;
  102. end;
  103. MouseCurOfs:=ofs;
  104. if (MouseCurOfs<>-1) then
  105. begin
  106. MouseCurCell:=VideoBuf^[MouseCurOfs] xor $7f00;
  107. VideoBuf^[MouseCurOfs]:=MouseCurCell;
  108. upd:=true;
  109. end;
  110. if upd then
  111. Updatescreen(false);
  112. end;
  113. procedure SysInitMouse;
  114. {$ifndef NOGPM}
  115. var
  116. connect : TGPMConnect;
  117. E : TGPMEvent;
  118. {$endif ndef NOGPM}
  119. begin
  120. {$ifndef NOGPM}
  121. if gpm_fs=-1 then
  122. begin
  123. { open gpm }
  124. connect.EventMask:=GPM_MOVE or GPM_DRAG or GPM_DOWN or GPM_UP;
  125. connect.DefaultMask:=0;
  126. connect.MinMod:=0;
  127. connect.MaxMod:=0;
  128. gpm_fs:=Gpm_Open(connect,0);
  129. if (gpm_fs=-2) and (fpgetenv('TERM')<>'xterm') then
  130. begin
  131. gpm_fs:=-1;
  132. Gpm_Close;
  133. end;
  134. { initialize SysLastMouseEvent }
  135. if gpm_fs<>-1 then
  136. begin
  137. Gpm_GetSnapshot(e);
  138. GPMEvent2MouseEvent(e,SysLastMouseEvent);
  139. end;
  140. end;
  141. { show mousepointer }
  142. if gpm_fs<>-1 then
  143. ShowMouse;
  144. {$else ifdef NOGPM}
  145. if (fpgetenv('TERM')='xterm') then
  146. begin
  147. gpm_fs:=-2;
  148. Write(#27'[?1001s'); { save old hilit tracking }
  149. Write(#27'[?1000h'); { enable mouse tracking }
  150. end;
  151. {$endif NOGPM}
  152. end;
  153. procedure SysDoneMouse;
  154. begin
  155. If gpm_fs<>-1 then
  156. begin
  157. HideMouse;
  158. {$ifndef NOGPM}
  159. Gpm_Close;
  160. {$else ifdef NOGPM}
  161. Write(#27'[?1000l'); { disable mouse tracking }
  162. Write(#27'[?1001r'); { Restore old hilit tracking }
  163. {$endif ifdef NOGPM}
  164. gpm_fs:=-1;
  165. end;
  166. end;
  167. function SysDetectMouse:byte;
  168. {$ifndef NOGPM}
  169. var
  170. connect : TGPMConnect;
  171. {$endif ndef NOGPM}
  172. begin
  173. {$ifndef NOGPM}
  174. if gpm_fs=-1 then
  175. begin
  176. connect.EventMask:=GPM_MOVE or GPM_DRAG or GPM_DOWN or GPM_UP;
  177. connect.DefaultMask:=0;
  178. connect.MinMod:=0;
  179. connect.MaxMod:=0;
  180. gpm_fs:=Gpm_Open(connect,0);
  181. if (gpm_fs=-2) and (fpgetenv('TERM')<>'xterm') then
  182. begin
  183. Gpm_Close;
  184. gpm_fs:=-1;
  185. end;
  186. end;
  187. { always a mouse deamon present }
  188. if gpm_fs<>-1 then
  189. SysDetectMouse:=Gpm_GetSnapshot(nil)
  190. else
  191. SysDetectMouse:=0;
  192. {$else ifdef NOGPM}
  193. if (fpgetenv('TERM')='xterm') then
  194. SysDetectMouse:=2;
  195. {$endif NOGPM}
  196. end;
  197. procedure SysGetMouseEvent(var MouseEvent: TMouseEvent);
  198. {$ifndef NOGPM}
  199. var
  200. e : TGPMEvent;
  201. {$endif ndef NOGPM}
  202. begin
  203. fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  204. if gpm_fs<0 then
  205. exit;
  206. {$ifndef NOGPM}
  207. Gpm_GetEvent(e);
  208. GPMEvent2MouseEvent(e,MouseEvent);
  209. SysLastMouseEvent:=MouseEvent;
  210. { update mouse cursor }
  211. if PrintMouseCur then
  212. PlaceMouseCur(MouseEvent.y*ScreenWidth+MouseEvent.x);
  213. {$endif ndef NOGPM}
  214. end;
  215. function SysPollMouseEvent(var MouseEvent: TMouseEvent):boolean;
  216. {$ifndef NOGPM}
  217. var
  218. e : TGPMEvent;
  219. fds : tFDSet;
  220. {$endif ndef NOGPM}
  221. begin
  222. fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  223. {$ifndef NOGPM}
  224. if gpm_fs<0 then
  225. exit(false);
  226. if gpm_fs>0 then
  227. begin
  228. fpFD_ZERO(fds);
  229. fpFD_SET(gpm_fs,fds);
  230. end;
  231. if (fpSelect(gpm_fs+1,@fds,nil,nil,1)>0) then
  232. begin
  233. FillChar(e,SizeOf(e),#0);
  234. { Gpm_snapshot does not work here PM }
  235. Gpm_GetEvent(e);
  236. GPMEvent2MouseEvent(e,MouseEvent);
  237. SysLastMouseEvent:=MouseEvent;
  238. if (MouseEvent.Action<>0) then
  239. begin
  240. { As we now use Gpm_GetEvent, we need to put in
  241. in the MouseEvent queue PM }
  242. PutMouseEvent(MouseEvent);
  243. SysPollMouseEvent:=true;
  244. { update mouse cursor is also required here
  245. as next call will read MouseEvent from queue }
  246. if PrintMouseCur then
  247. PlaceMouseCur(MouseEvent.y*ScreenWidth+MouseEvent.x);
  248. end
  249. else
  250. SysPollMouseEvent:=false;
  251. end
  252. else
  253. {$endif NOGPM}
  254. SysPollMouseEvent:=false;
  255. end;
  256. function SysGetMouseX:word;
  257. {$ifndef NOGPM}
  258. var
  259. me : TMouseEvent;
  260. {$endif ndef NOGPM}
  261. begin
  262. if gpm_fs<0 then
  263. exit(0);
  264. {$ifndef NOGPM}
  265. if PollMouseEvent(ME) then
  266. begin
  267. { Remove mouse event, we are only interrested in
  268. the X,Y so all other events can be thrown away }
  269. GetMouseEvent(ME);
  270. SysGetMouseX:=ME.X
  271. end
  272. else
  273. begin
  274. SysGetMouseX:=SysLastMouseEvent.x;
  275. end;
  276. {$endif ndef NOGPM}
  277. end;
  278. function SysGetMouseY:word;
  279. {$ifndef NOGPM}
  280. var
  281. me : TMouseEvent;
  282. {$endif ndef NOGPM}
  283. begin
  284. if gpm_fs<0 then
  285. exit(0);
  286. {$ifndef NOGPM}
  287. if PollMouseEvent(ME) then
  288. begin
  289. { Remove mouse event, we are only interrested in
  290. the X,Y so all other events can be thrown away }
  291. GetMouseEvent(ME);
  292. SysGetMouseY:=ME.Y
  293. end
  294. else
  295. begin
  296. SysGetMouseY:=SysLastMouseEvent.y;
  297. end;
  298. {$endif ndef NOGPM}
  299. end;
  300. procedure SysShowMouse;
  301. var
  302. x,y : word;
  303. begin
  304. PrintMouseCur:=true;
  305. { Wait with showing the cursor until the mouse has moved. Else the
  306. cursor updates will be to quickly }
  307. if WaitMouseMove then
  308. exit;
  309. if (MouseCurOfs>=0) or (gpm_fs=-1) then
  310. PlaceMouseCur(MouseCurOfs)
  311. else
  312. begin
  313. x:=SysGetMouseX;
  314. y:=SysGetMouseY;
  315. if (x<=ScreenWidth) and (y<=ScreenHeight) then
  316. PlaceMouseCur(Y*ScreenWidth+X)
  317. else
  318. PlaceMouseCur(MouseCurOfs);
  319. end;
  320. end;
  321. procedure SysHideMouse;
  322. begin
  323. if (MouseCurOfs>=0) then
  324. PlaceMouseCur(-1);
  325. WaitMouseMove:=true;
  326. PrintMouseCur:=false;
  327. end;
  328. function SysGetMouseButtons:word;
  329. {$ifndef NOGPM}
  330. var
  331. me : TMouseEvent;
  332. {$endif ndef NOGPM}
  333. begin
  334. if gpm_fs<0 then
  335. exit(0);
  336. {$ifndef NOGPM}
  337. if PollMouseEvent(ME) then
  338. begin
  339. { Remove mouse event, we are only interrested in
  340. the buttons so all other events can be thrown away }
  341. GetMouseEvent(ME);
  342. SysGetMouseButtons:=ME.Buttons;
  343. end
  344. else
  345. begin
  346. SysGetMouseButtons:=SysLastMouseEvent.buttons;
  347. end;
  348. {$endif ndef NOGPM}
  349. end;
  350. Const
  351. SysMouseDriver : TMouseDriver = (
  352. UseDefaultQueue : true;
  353. InitDriver : @SysInitMouse;
  354. DoneDriver : @SysDoneMouse;
  355. DetectMouse : @SysDetectMouse;
  356. ShowMouse : @SysShowMouse;
  357. HideMouse : @SysHideMouse;
  358. GetMouseX : @SysGetMouseX;
  359. GetMouseY : @SysGetMouseY;
  360. GetMouseButtons : @SysGetMouseButtons;
  361. SetMouseXY : Nil;
  362. GetMouseEvent : @SysGetMouseEvent;
  363. PollMouseEvent : @SysPollMouseEvent;
  364. PutMouseEvent : Nil;
  365. );
  366. {$else ifndef NOMOUSE}
  367. Const
  368. SysMouseDriver : TMouseDriver = (
  369. UseDefaultQueue : true;
  370. InitDriver : Nil;
  371. DoneDriver : Nil;
  372. DetectMouse : Nil;
  373. ShowMouse : Nil;
  374. HideMouse : Nil;
  375. GetMouseX : Nil;
  376. GetMouseY : Nil;
  377. GetMouseButtons : Nil;
  378. SetMouseXY : Nil;
  379. GetMouseEvent : Nil;
  380. PollMouseEvent : Nil;
  381. PutMouseEvent : Nil;
  382. );
  383. {$endif}
  384. Begin
  385. SetMouseDriver(SysMouseDriver);
  386. end.
  387. {
  388. $Log$
  389. Revision 1.14 2004-11-06 20:06:19 peter
  390. * mouse works again
  391. Revision 1.13 2004/11/03 16:51:05 peter
  392. * fixed valgrind issues
  393. Revision 1.12 2003/10/24 18:09:56 marco
  394. * 1.0.x fixes merged
  395. Revision 1.11 2003/09/16 16:13:56 marco
  396. * fdset functions renamed to fp<posix name>
  397. Revision 1.10 2003/09/14 20:15:01 marco
  398. * Unix reform stage two. Remove all calls from Unix that exist in Baseunix.
  399. Revision 1.9 2002/10/14 18:37:15 peter
  400. * use Unix unit
  401. Revision 1.8 2002/09/15 17:52:30 peter
  402. * Updates from the fixes branch
  403. Revision 1.2.2.9 2002/09/11 06:49:59 pierre
  404. * use gpm_fs in FD_SET
  405. Revision 1.2.2.8 2002/09/02 13:48:48 pierre
  406. * mouse event for consoles hopefully fixed
  407. }