mouse.pp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  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. const
  19. MouseEventBufSize = 16;
  20. {$i mouseh.inc}
  21. implementation
  22. uses
  23. Unix,Video
  24. {$ifndef NOGPM}
  25. ,gpm
  26. {$endif ndef NOGPM}
  27. ;
  28. const
  29. mousecur : boolean = false;
  30. mousecurofs : longint = -1;
  31. var
  32. mousecurcell : TVideoCell;
  33. const
  34. gpm_fs : longint = -1;
  35. procedure PlaceMouseCur(ofs:longint);
  36. {$ifndef NOMOUSE}
  37. var
  38. upd : boolean;
  39. {$endif ndef NOMOUSE}
  40. begin
  41. {$ifndef NOMOUSE}
  42. if VideoBuf=nil then
  43. exit;
  44. upd:=false;
  45. if (MouseCurOfs<>-1) and (VideoBuf^[MouseCurOfs]=MouseCurCell) then
  46. begin
  47. VideoBuf^[MouseCurOfs]:=MouseCurCell xor $7f00;
  48. upd:=true;
  49. end;
  50. MouseCurOfs:=ofs;
  51. if (MouseCurOfs<>-1) then
  52. begin
  53. MouseCurCell:=VideoBuf^[MouseCurOfs] xor $7f00;
  54. VideoBuf^[MouseCurOfs]:=MouseCurCell;
  55. upd:=true;
  56. end;
  57. if upd then
  58. Updatescreen(false);
  59. {$endif ndef NOMOUSE}
  60. end;
  61. procedure InitMouse;
  62. {$ifndef NOGPM}
  63. var
  64. connect : TGPMConnect;
  65. {$endif ndef NOGPM}
  66. begin
  67. {$ifndef NOMOUSE}
  68. PendingMouseHead:=@PendingMouseEvent;
  69. PendingMouseTail:=@PendingMouseEvent;
  70. PendingMouseEvents:=0;
  71. FillChar(LastMouseEvent,sizeof(TMouseEvent),0);
  72. {$ifndef NOGPM}
  73. if gpm_fs=-1 then
  74. begin
  75. { open gpm }
  76. connect.EventMask:=GPM_MOVE or GPM_DRAG or GPM_DOWN or GPM_UP;
  77. connect.DefaultMask:=0;
  78. connect.MinMod:=0;
  79. connect.MaxMod:=0;
  80. gpm_fs:=Gpm_Open(connect,0);
  81. if (gpm_fs=-2) and (getenv('TERM')<>'xterm') then
  82. begin
  83. gpm_fs:=-1;
  84. Gpm_Close;
  85. end;
  86. end;
  87. { show mousepointer }
  88. if gpm_fs<>-1 then
  89. ShowMouse;
  90. {$else ifdef NOGPM}
  91. if (getenv('TERM')='xterm') then
  92. begin
  93. gpm_fs:=-2;
  94. Write(#27'[?1001s'); { save old hilit tracking }
  95. Write(#27'[?1000h'); { enable mouse tracking }
  96. end;
  97. {$endif NOGPM}
  98. {$endif ndef NOMOUSE}
  99. end;
  100. procedure DoneMouse;
  101. begin
  102. {$ifndef NOMOUSE}
  103. If gpm_fs<>-1 then
  104. begin
  105. HideMouse;
  106. {$ifndef NOGPM}
  107. Gpm_Close;
  108. {$else ifdef NOGPM}
  109. Write(#27'[?1000l'); { disable mouse tracking }
  110. Write(#27'[?1001r'); { Restore old hilit tracking }
  111. {$endif ifdef NOGPM}
  112. gpm_fs:=-1;
  113. end;
  114. {$endif ndef NOMOUSE}
  115. end;
  116. function DetectMouse:byte;
  117. {$ifndef NOGPM}
  118. var
  119. x : longint;
  120. e : TGPMEvent;
  121. connect : TGPMConnect;
  122. {$endif ndef NOGPM}
  123. begin
  124. {$ifdef NOMOUSE}
  125. DetectMouse:=0;
  126. {$else ndef NOMOUSE}
  127. {$ifndef NOGPM}
  128. if gpm_fs=-1 then
  129. begin
  130. connect.EventMask:=GPM_MOVE or GPM_DRAG or GPM_DOWN or GPM_UP;
  131. connect.DefaultMask:=0;
  132. connect.MinMod:=0;
  133. connect.MaxMod:=0;
  134. gpm_fs:=Gpm_Open(connect,0);
  135. if (gpm_fs=-2) and (getenv('TERM')<>'xterm') then
  136. begin
  137. Gpm_Close;
  138. gpm_fs:=-1;
  139. end;
  140. end;
  141. { always a mouse deamon present }
  142. if gpm_fs<>-1 then
  143. begin
  144. x:=Gpm_GetSnapshot(e);
  145. if x<>-1 then
  146. DetectMouse:=x
  147. else
  148. DetectMouse:=2;
  149. end
  150. else
  151. DetectMouse:=0;
  152. {$else ifdef NOGPM}
  153. if (getenv('TERM')='xterm') then
  154. DetectMouse:=2;
  155. {$endif NOGPM}
  156. {$endif ndef NOMOUSE}
  157. end;
  158. procedure ShowMouse;
  159. begin
  160. PlaceMouseCur(MouseCurOfs);
  161. mousecur:=true;
  162. end;
  163. procedure HideMouse;
  164. begin
  165. PlaceMouseCur(-1);
  166. mousecur:=false;
  167. end;
  168. function GetMouseX:word;
  169. {$ifndef NOGPM}
  170. var
  171. e : TGPMEvent;
  172. {$endif ndef NOGPM}
  173. begin
  174. {$ifdef NOMOUSE}
  175. GetMouseX:=0;
  176. {$else ndef NOMOUSE}
  177. if gpm_fs<0 then
  178. exit(0);
  179. {$ifndef NOGPM}
  180. Gpm_GetSnapshot(e);
  181. GetMouseX:=e.x-1;
  182. {$endif ndef NOGPM}
  183. {$endif ndef NOMOUSE}
  184. end;
  185. function GetMouseY:word;
  186. {$ifndef NOGPM}
  187. var
  188. e : TGPMEvent;
  189. {$endif ndef NOGPM}
  190. begin
  191. {$ifdef NOMOUSE}
  192. GetMouseY:=0;
  193. {$else ndef NOMOUSE}
  194. if gpm_fs<0 then
  195. exit(0);
  196. {$ifndef NOGPM}
  197. Gpm_GetSnapshot(e);
  198. if e.y>0 then
  199. GetMouseY:=e.y-1
  200. else
  201. GetMouseY:=0;
  202. {$endif ndef NOGPM}
  203. {$endif ndef NOMOUSE}
  204. end;
  205. function GetMouseButtons:word;
  206. {$ifndef NOGPM}
  207. var
  208. e : TGPMEvent;
  209. {$endif ndef NOGPM}
  210. begin
  211. {$ifdef NOMOUSE}
  212. GetMouseButtons:=0;
  213. {$else ndef NOMOUSE}
  214. if gpm_fs<0 then
  215. exit(0);
  216. {$ifndef NOGPM}
  217. Gpm_GetSnapshot(e);
  218. GetMouseButtons:=e.buttons;
  219. {$endif ndef NOGPM}
  220. {$endif ndef NOMOUSE}
  221. end;
  222. procedure SetMouseXY(x,y:word);
  223. begin
  224. end;
  225. procedure GetMouseEvent(var MouseEvent: TMouseEvent);
  226. {$ifndef NOGPM}
  227. var
  228. e : TGPMEvent;
  229. {$endif ndef NOGPM}
  230. begin
  231. {$ifdef NOMOUSE}
  232. fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  233. {$else ndef NOMOUSE}
  234. fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  235. if PendingMouseEvents>0 then
  236. begin
  237. MouseEvent:=PendingMouseHead^;
  238. inc(PendingMouseHead);
  239. if longint(PendingMouseHead)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
  240. PendingMouseHead:=@PendingMouseEvent;
  241. dec(PendingMouseEvents);
  242. if (LastMouseEvent.x<>MouseEvent.x) or (LastMouseEvent.y<>MouseEvent.y) then
  243. MouseEvent.Action:=MouseActionMove;
  244. if (LastMouseEvent.Buttons<>MouseEvent.Buttons) then
  245. begin
  246. if (LastMouseEvent.Buttons=0) then
  247. MouseEvent.Action:=MouseActionDown
  248. else
  249. MouseEvent.Action:=MouseActionUp;
  250. end;
  251. LastMouseEvent:=MouseEvent;
  252. exit;
  253. end;
  254. if gpm_fs<0 then
  255. exit;
  256. {$ifndef NOGPM}
  257. Gpm_GetEvent(e);
  258. if e.x>0 then
  259. MouseEvent.x:=e.x-1
  260. else
  261. MouseEvent.x:=0;
  262. if e.y>0 then
  263. MouseEvent.y:=e.y-1
  264. else
  265. MouseEvent.y:=0;
  266. MouseEvent.buttons:=0;
  267. if e.buttons and Gpm_b_left<>0 then
  268. inc(MouseEvent.buttons,1);
  269. if e.buttons and Gpm_b_right<>0 then
  270. inc(MouseEvent.buttons,2);
  271. if e.buttons and Gpm_b_middle<>0 then
  272. inc(MouseEvent.buttons,4);
  273. case (e.EventType and $f) of
  274. GPM_MOVE,
  275. GPM_DRAG : MouseEvent.Action:=MouseActionMove;
  276. GPM_DOWN : MouseEvent.Action:=MouseActionDown;
  277. GPM_UP : MouseEvent.Action:=MouseActionUp;
  278. else
  279. MouseEvent.Action:=0;
  280. end;
  281. LastMouseEvent:=MouseEvent;
  282. { update mouse cursor }
  283. if mousecur then
  284. PlaceMouseCur(MouseEvent.y*ScreenWidth+MouseEvent.x);
  285. {$endif ndef NOGPM}
  286. {$endif ndef NOMOUSE}
  287. end;
  288. procedure PutMouseEvent(const MouseEvent: TMouseEvent);
  289. begin
  290. {$ifndef NOMOUSE}
  291. if PendingMouseEvents<MouseEventBufSize then
  292. begin
  293. PendingMouseTail^:=MouseEvent;
  294. inc(PendingMouseTail);
  295. if longint(PendingMouseTail)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
  296. PendingMouseTail:=@PendingMouseEvent;
  297. { why isn't this done here ?
  298. so the win32 version do this by hand:}
  299. inc(PendingMouseEvents);
  300. end;
  301. {$endif ndef NOMOUSE}
  302. end;
  303. function PollMouseEvent(var MouseEvent: TMouseEvent):boolean;
  304. {$ifndef NOGPM}
  305. var
  306. e : TGPMEvent;
  307. fds : FDSet;
  308. {$endif ndef NOGPM}
  309. begin
  310. {$ifdef NOMOUSE}
  311. fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  312. exit(false);
  313. {$else ndef NOMOUSE}
  314. fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  315. if PendingMouseEvents>0 then
  316. begin
  317. MouseEvent:=PendingMouseHead^;
  318. PollMouseEvent:=true;
  319. exit;
  320. end
  321. else if gpm_fs<0 then
  322. exit(false);
  323. {$ifndef NOGPM}
  324. if gpm_fs>0 then
  325. begin
  326. FD_Zero(fds);
  327. FD_Set(gpm_fd,fds);
  328. end;
  329. if (gpm_fs=-2) or (Select(gpm_fs+1,@fds,nil,nil,1)>0) then
  330. begin
  331. Gpm_GetSnapshot(e);
  332. if e.x>0 then
  333. MouseEvent.x:=e.x-1
  334. else
  335. MouseEvent.x:=0;
  336. if e.y>0 then
  337. MouseEvent.y:=e.y-1
  338. else
  339. MouseEvent.y:=0;
  340. MouseEvent.buttons:=0;
  341. if e.buttons and Gpm_b_left<>0 then
  342. inc(MouseEvent.buttons,1);
  343. if e.buttons and Gpm_b_right<>0 then
  344. inc(MouseEvent.buttons,2);
  345. if e.buttons and Gpm_b_middle<>0 then
  346. inc(MouseEvent.buttons,4);
  347. case (e.EventType and $f) of
  348. GPM_MOVE,
  349. GPM_DRAG : MouseEvent.Action:=MouseActionMove;
  350. GPM_DOWN : MouseEvent.Action:=MouseActionDown;
  351. GPM_UP : MouseEvent.Action:=MouseActionUp;
  352. else
  353. MouseEvent.Action:=0;
  354. end;
  355. if (gpm_fs<>-2) or (MouseEvent.Action<>0) then
  356. PollMouseEvent:=true
  357. else
  358. PollMouseEvent:=false;
  359. end
  360. else
  361. PollMouseEvent:=false;
  362. {$endif ndef NOGPM}
  363. {$endif ndef NOMOUSE}
  364. end;
  365. end.
  366. {
  367. $Log$
  368. Revision 1.4 2001-09-17 21:36:31 peter
  369. * merged fixes
  370. Revision 1.3 2001/08/05 12:24:20 peter
  371. * m68k merges
  372. Revision 1.2 2001/01/21 20:21:40 marco
  373. * Rename fest II. Rtl OK
  374. Revision 1.1 2001/01/13 11:03:58 peter
  375. * API 2 RTL commit
  376. }