mouse.pp 9.1 KB

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