mouse.pp 9.0 KB

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