FreeBASIC  0.91.0
io_mouse.c
Go to the documentation of this file.
1 /* console mode mouse functions */
2 
3 #include "../fb.h"
4 
5 #ifdef DISABLE_GPM
6 
7 int fb_ConsoleGetMouse( int *x, int *y, int *z, int *buttons, int *clip )
8 {
10 }
11 
12 #else
13 
14 #include "../unix/fb_private_console.h"
15 #include "../fb_private_hdynload.h"
16 #include <sys/select.h>
17 #include <gpm.h>
18 
19 typedef int (*GPM_OPEN)(Gpm_Connect *, int);
20 typedef int (*GPM_CLOSE)(void);
21 typedef int (*GPM_GETEVENT)(Gpm_Event *);
22 
23 typedef struct {
27  int *fd;
28 } GPM_FUNCS;
29 
31 static GPM_FUNCS gpm = { NULL };
32 static Gpm_Connect conn;
33 static int has_focus = TRUE;
34 static int mouse_x = 0, mouse_y = 0, mouse_z = 0, mouse_buttons = 0;
35 
36 static void mouse_update(int cb, int cx, int cy)
37 {
38  if (has_focus) {
39  cb &= ~0x1C;
40  if (cb >= 0x60) {
41  if (cb - 0x60)
42  mouse_z--;
43  else
44  mouse_z++;
45  } else {
46  if (cb >= 0x40)
47  cb -= 0x20;
48  switch (cb) {
49  case 0x20: mouse_buttons |= 0x1; break;
50  case 0x21: mouse_buttons |= 0x4; break;
51  case 0x22: mouse_buttons |= 0x2; break;
52  case 0x23: mouse_buttons = 0; break;
53  }
54  }
55  mouse_x = cx - 0x21;
56  mouse_y = cy - 0x21;
57  }
58 }
59 
60 static void mouse_handler(void)
61 {
62  Gpm_Event event;
63  fd_set set;
64  struct timeval tv = { 0, 0 };
65  int count = 0;
66 
67 #ifndef DISABLE_X11
68  if (__fb_con.inited == INIT_X11) {
69  if (fb_hXTermHasFocus()) {
70  if (!has_focus)
71  mouse_buttons = 0;
72  has_focus = TRUE;
73  } else {
74  if (has_focus) {
75  mouse_x = -1;
76  mouse_y = -1;
77  mouse_buttons = -1;
78  }
79  has_focus = FALSE;
80  }
81  return;
82  }
83 #endif
84 
85  FD_ZERO(&set);
86  FD_SET(*gpm.fd, &set);
87 
88  while ((select(FD_SETSIZE, &set, NULL, NULL, &tv) > 0) && (count < 16)) {
89  if (gpm.GetEvent(&event) > 0) {
90  mouse_x += event.dx;
91  mouse_y += event.dy;
92 
94  if (mouse_x < 0) mouse_x = 0;
95  if (mouse_x >= __fb_con.w) mouse_x = __fb_con.w - 1;
96  if (mouse_y < 0) mouse_y = 0;
97  if (mouse_y >= __fb_con.h) mouse_y = __fb_con.h - 1;
98 
99  mouse_z += event.wdy;
100 
101  if (event.type & GPM_DOWN)
102  mouse_buttons |= ((event.buttons & 0x4) >> 2) | ((event.buttons & 0x2) << 1) | ((event.buttons & 0x1) << 1);
103  else if (event.type & GPM_UP)
104  mouse_buttons &= ~(((event.buttons & 0x4) >> 2) | ((event.buttons & 0x2) << 1) | ((event.buttons & 0x1) << 1));
105  }
106  count++;
107  }
108 }
109 
110 static int mouse_init(void)
111 {
112  const char *funcs[] = { "Gpm_Open", "Gpm_Close", "Gpm_GetEvent", "gpm_fd", NULL };
113 
114  if (__fb_con.inited == INIT_CONSOLE) {
115  gpm_lib = fb_hDynLoad("libgpm.so.1", funcs, (void **)&gpm);
116  if (!gpm_lib)
117  return -1;
118 
119  conn.eventMask = ~0;
120  conn.defaultMask = ~GPM_HARD;
121  conn.maxMod = ~0;
122  conn.minMod = 0;
123  if (gpm.Open(&conn, 0) < 0) {
125  return -1;
126  }
127  }
128  else {
129  fb_hTermOut(SEQ_INIT_XMOUSE, 0, 0);
130  __fb_con.mouse_update = mouse_update;
131 #ifndef DISABLE_X11
133 #endif
134  }
135  return 0;
136 }
137 
138 static void mouse_exit(void)
139 {
140  if (__fb_con.inited == INIT_CONSOLE) {
141  gpm.Close();
143  }
144  else {
145  fb_hTermOut(SEQ_EXIT_XMOUSE, 0, 0);
146 #ifndef DISABLE_X11
148 #endif
149  __fb_con.mouse_update = NULL;
150  }
151  __fb_con.mouse_handler = NULL;
152  __fb_con.mouse_exit = NULL;
153 }
154 
155 int fb_ConsoleGetMouse(int *x, int *y, int *z, int *buttons, int *clip)
156 {
157  int temp_z, temp_buttons;
158 
159  if (!__fb_con.inited)
161 
162  if (!z)
163  z = &temp_z;
164  if (!buttons)
165  buttons = &temp_buttons;
166 
167  BG_LOCK();
168 
170 
171  if (!__fb_con.mouse_handler) {
172  if (!mouse_init()) {
173  __fb_con.mouse_init = mouse_init;
174  __fb_con.mouse_exit = mouse_exit;
175  __fb_con.mouse_handler = mouse_handler;
176  } else {
177  *x = *y = *z = *buttons = -1;
178  BG_UNLOCK();
180  }
181  }
182 
183  if (__fb_con.inited != INIT_CONSOLE)
184  fb_hGetCh(FALSE);
185 
186  *x = mouse_x;
187  *y = mouse_y;
188  *z = mouse_z;
189  *buttons = mouse_buttons;
190  *clip = 0;
191 
192  BG_UNLOCK();
193 
194  return FB_RTERROR_OK;
195 }
196 
197 #endif /* ndef DISABLE_GPM */
198 
199 int fb_ConsoleSetMouse( int x, int y, int cursor, int clip )
200 {
202 }