mouse.pp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  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 NOMOUSE}
  25. ,gpm
  26. {$endif ndef NOMOUSE}
  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. {$ifndef NOGPM}
  69. PendingMouseHead:=@PendingMouseEvent;
  70. PendingMouseTail:=@PendingMouseEvent;
  71. PendingMouseEvents:=0;
  72. FillChar(LastMouseEvent,sizeof(TMouseEvent),0);
  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. GetMouseY:=e.y-1;
  199. {$endif ndef NOGPM}
  200. {$endif ndef NOMOUSE}
  201. end;
  202. function GetMouseButtons:word;
  203. {$ifndef NOGPM}
  204. var
  205. e : TGPMEvent;
  206. {$endif ndef NOGPM}
  207. begin
  208. {$ifdef NOMOUSE}
  209. GetMouseButtons:=0;
  210. {$else ndef NOMOUSE}
  211. if gpm_fs<0 then
  212. exit(0);
  213. {$ifndef NOGPM}
  214. Gpm_GetSnapshot(e);
  215. GetMouseButtons:=e.buttons;
  216. {$endif ndef NOGPM}
  217. {$endif ndef NOMOUSE}
  218. end;
  219. procedure SetMouseXY(x,y:word);
  220. begin
  221. end;
  222. procedure GetMouseEvent(var MouseEvent: TMouseEvent);
  223. {$ifndef NOGPM}
  224. var
  225. e : TGPMEvent;
  226. {$endif ndef NOGPM}
  227. begin
  228. {$ifdef NOMOUSE}
  229. fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  230. {$else ndef NOMOUSE}
  231. fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  232. if PendingMouseEvents>0 then
  233. begin
  234. MouseEvent:=PendingMouseHead^;
  235. inc(PendingMouseHead);
  236. if longint(PendingMouseHead)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
  237. PendingMouseHead:=@PendingMouseEvent;
  238. dec(PendingMouseEvents);
  239. if (LastMouseEvent.x<>MouseEvent.x) or (LastMouseEvent.y<>MouseEvent.y) then
  240. MouseEvent.Action:=MouseActionMove;
  241. if (LastMouseEvent.Buttons<>MouseEvent.Buttons) then
  242. begin
  243. if (LastMouseEvent.Buttons=0) then
  244. MouseEvent.Action:=MouseActionDown
  245. else
  246. MouseEvent.Action:=MouseActionUp;
  247. end;
  248. LastMouseEvent:=MouseEvent;
  249. exit;
  250. end;
  251. if gpm_fs<0 then
  252. exit;
  253. {$ifndef NOGPM}
  254. Gpm_GetEvent(e);
  255. MouseEvent.x:=e.x-1;
  256. MouseEvent.y:=e.y-1;
  257. MouseEvent.buttons:=0;
  258. if e.buttons and Gpm_b_left<>0 then
  259. inc(MouseEvent.buttons,1);
  260. if e.buttons and Gpm_b_right<>0 then
  261. inc(MouseEvent.buttons,2);
  262. if e.buttons and Gpm_b_middle<>0 then
  263. inc(MouseEvent.buttons,4);
  264. case (e.EventType and $f) of
  265. GPM_MOVE,
  266. GPM_DRAG : MouseEvent.Action:=MouseActionMove;
  267. GPM_DOWN : MouseEvent.Action:=MouseActionDown;
  268. GPM_UP : MouseEvent.Action:=MouseActionUp;
  269. else
  270. MouseEvent.Action:=0;
  271. end;
  272. LastMouseEvent:=MouseEvent;
  273. { update mouse cursor }
  274. if mousecur then
  275. PlaceMouseCur(MouseEvent.y*ScreenWidth+MouseEvent.x);
  276. {$endif ndef NOGPM}
  277. {$endif ndef NOMOUSE}
  278. end;
  279. procedure PutMouseEvent(const MouseEvent: TMouseEvent);
  280. begin
  281. {$ifndef NOMOUSE}
  282. if PendingMouseEvents<MouseEventBufSize then
  283. begin
  284. PendingMouseTail^:=MouseEvent;
  285. inc(PendingMouseTail);
  286. if longint(PendingMouseTail)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
  287. PendingMouseTail:=@PendingMouseEvent;
  288. { why isn't this done here ?
  289. so the win32 version do this by hand:}
  290. inc(PendingMouseEvents);
  291. end;
  292. {$endif ndef NOMOUSE}
  293. end;
  294. function PollMouseEvent(var MouseEvent: TMouseEvent):boolean;
  295. {$ifndef NOGPM}
  296. var
  297. e : TGPMEvent;
  298. fds : FDSet;
  299. {$endif ndef NOGPM}
  300. begin
  301. {$ifdef NOMOUSE}
  302. fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  303. exit(false);
  304. {$else ndef NOMOUSE}
  305. fillchar(MouseEvent,SizeOf(TMouseEvent),#0);
  306. if PendingMouseEvents>0 then
  307. begin
  308. MouseEvent:=PendingMouseHead^;
  309. PollMouseEvent:=true;
  310. exit;
  311. end
  312. else if gpm_fs<0 then
  313. exit(false);
  314. {$ifndef NOGPM}
  315. if gpm_fs>0 then
  316. begin
  317. FD_Zero(fds);
  318. FD_Set(gpm_fd,fds);
  319. end;
  320. if (gpm_fs=-2) or (Select(gpm_fs+1,@fds,nil,nil,1)>0) then
  321. begin
  322. Gpm_GetSnapshot(e);
  323. MouseEvent.x:=e.x-1;
  324. MouseEvent.y:=e.y-1;
  325. MouseEvent.buttons:=0;
  326. if e.buttons and Gpm_b_left<>0 then
  327. inc(MouseEvent.buttons,1);
  328. if e.buttons and Gpm_b_right<>0 then
  329. inc(MouseEvent.buttons,2);
  330. if e.buttons and Gpm_b_middle<>0 then
  331. inc(MouseEvent.buttons,4);
  332. case (e.EventType and $f) of
  333. GPM_MOVE,
  334. GPM_DRAG : MouseEvent.Action:=MouseActionMove;
  335. GPM_DOWN : MouseEvent.Action:=MouseActionDown;
  336. GPM_UP : MouseEvent.Action:=MouseActionUp;
  337. else
  338. MouseEvent.Action:=0;
  339. end;
  340. if (gpm_fs<>-2) or (MouseEvent.Action<>0) then
  341. PollMouseEvent:=true
  342. else
  343. PollMouseEvent:=false;
  344. end
  345. else
  346. PollMouseEvent:=false;
  347. {$endif ndef NOGPM}
  348. {$endif ndef NOMOUSE}
  349. end;
  350. end.
  351. {
  352. $Log$
  353. Revision 1.2 2001-01-21 20:21:40 marco
  354. * Rename fest II. Rtl OK
  355. Revision 1.1 2001/01/13 11:03:58 peter
  356. * API 2 RTL commit
  357. }