[wip] Retire move_image(), hide_image() and associated osdep routines; hide_image_reg...
[elinks/images.git] / src / osdep / unix / bsd.c
blobbac3a6cc438a22ccf2677798c9d6e2d4d63339e4
1 /* BSD mouse system-specific routines. */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include "osdep/system.h"
9 #ifdef CONFIG_SYSMOUSE
10 #ifdef HAVE_SYS_CONSIO_H
11 #include <sys/consio.h>
12 #include <sys/fbio.h>
13 #else
14 #include <machine/console.h>
15 #endif /* HAVE_SYS_CONSIO_H */
16 #endif /* CONFIG_SYSMOUSE */
18 #include "elinks.h"
20 #include "main/select.h"
21 #include "osdep/osdep.h"
22 #include "osdep/signals.h"
23 #include "terminal/event.h"
24 #include "terminal/mouse.h"
27 #if defined(CONFIG_SYSMOUSE) && defined(CONFIG_MOUSE)
29 struct sysmouse_spec {
30 void *itrm;
31 int cheight;
32 int cwidth;
33 void (*fn)(void *, unsigned char *, int);
36 static void
37 sysmouse_handler(void *data)
39 static struct interlink_event_mouse prev_mouse;
40 static int prev_buttons;
41 struct sysmouse_spec *sp = data;
42 void *itrm = sp->itrm;
43 int fd = get_output_handle();
44 int buttons, change;
45 int extended_button;
46 mouse_info_t mi;
47 struct interlink_event_mouse mouse;
48 struct interlink_event ev;
50 mi.operation = MOUSE_GETINFO;
51 if (ioctl(fd, CONS_MOUSECTL, &mi) == -1) return;
52 mouse.x = int_max(mi.u.data.x / sp->cwidth, 0);
53 mouse.y = int_max(mi.u.data.y / sp->cheight, 0);
55 /* for cosmetic bug in syscons.c on FreeBSD 3.3/3.4 */
56 #ifdef HAVE_MACHINE_CONSOLE_H
57 mi.operation = MOUSE_HIDE;
58 ioctl(fd, CONS_MOUSECTL, &mi);
59 mi.operation = MOUSE_SHOW;
60 ioctl(fd, CONS_MOUSECTL, &mi);
61 #endif
62 buttons = mi.u.data.buttons & 7;
63 change = (mouse.x != prev_mouse.x || mouse.y != prev_mouse.y);
64 prev_mouse = mouse;
65 /* It's horrible. */
66 switch (buttons) {
67 case 0:
68 switch (prev_buttons) {
69 case 0:
70 extended_button = mi.u.data.buttons & 24;
71 if (!extended_button) return;
72 if (extended_button & 8) mouse.button = B_WHEEL_UP;
73 else mouse.button = B_WHEEL_DOWN;
74 break;
75 case 1:
76 case 3:
77 case 5:
78 case 7:
79 mouse.button = B_LEFT | B_UP;
80 break;
81 case 2:
82 case 6:
83 mouse.button = B_MIDDLE | B_UP;
84 break;
85 case 4:
86 mouse.button = B_RIGHT | B_UP;
87 break;
89 break;
90 case 1:
91 case 3:
92 case 5:
93 case 7:
94 switch (prev_buttons) {
95 case 0:
96 case 2:
97 case 4:
98 case 6:
99 mouse.button = B_LEFT | B_DOWN;
100 break;
101 case 1:
102 case 3:
103 case 5:
104 case 7:
105 if (change)
106 mouse.button = B_LEFT | B_DRAG;
107 else mouse.button = B_LEFT | B_DOWN;
108 break;
110 break;
111 case 2:
112 case 6:
113 switch (prev_buttons) {
114 case 1:
115 case 3:
116 case 5:
117 case 7:
118 mouse.button = B_LEFT | B_UP;
119 break;
120 case 0:
121 case 4:
122 mouse.button = B_MIDDLE | B_DOWN;
123 break;
124 case 2:
125 case 6:
126 if (change)
127 mouse.button = B_MIDDLE | B_DRAG;
128 else mouse.button = B_MIDDLE | B_DOWN;
129 break;
131 break;
132 case 4:
133 switch (prev_buttons) {
134 case 1:
135 case 3:
136 case 5:
137 case 7:
138 mouse.button = B_LEFT | B_UP;
139 break;
140 case 2:
141 case 6:
142 mouse.button = B_MIDDLE | B_UP;
143 break;
144 case 0:
145 mouse.button = B_RIGHT | B_DOWN;
146 break;
147 case 4:
148 if (change)
149 mouse.button = B_RIGHT | B_DRAG;
150 else mouse.button = B_RIGHT | B_DOWN;
151 break;
153 break;
156 prev_buttons = buttons;
157 set_mouse_interlink_event(&ev, mouse.x, mouse.y, mouse.button);
158 sp->fn(itrm, (unsigned char *)&ev, sizeof(ev));
161 static void
162 sysmouse_signal_handler(void *data)
164 register_bottom_half(sysmouse_handler, data);
167 void *
168 handle_mouse(int cons, void (*fn)(void *, unsigned char *, int),
169 void *data)
171 static struct sysmouse_spec mouse_spec;
172 video_info_t vi;
173 mouse_info_t mi;
174 int fd = get_output_handle();
176 if (is_xterm()) return NULL;
177 mouse_spec.itrm = data;
178 mouse_spec.fn = fn;
180 if (ioctl(fd, FBIO_GETMODE, &vi.vi_mode) != -1 &&
181 ioctl(fd, FBIO_MODEINFO, &vi) != -1) {
182 mouse_spec.cwidth = vi.vi_cwidth;
183 mouse_spec.cheight = vi.vi_cheight;
184 } else {
185 return NULL;
188 install_signal_handler(SIGUSR2, NULL, NULL, 0);
189 mi.operation = MOUSE_MODE;
190 mi.u.mode.mode = 0;
191 mi.u.mode.signal = SIGUSR2;
192 if (ioctl(fd, CONS_MOUSECTL, &mi) != -1) {
193 install_signal_handler(SIGUSR2,
194 (void (*)(void *))sysmouse_signal_handler, &mouse_spec, 0);
195 mi.operation = MOUSE_SHOW;
196 ioctl(fd, CONS_MOUSECTL, &mi);
197 return &mouse_spec;
198 } else {
199 return NULL;
203 void
204 unhandle_mouse(void *data)
206 if (data) {
207 mouse_info_t mi;
208 int fd = get_output_handle();
210 mi.operation = MOUSE_MODE;
211 mi.u.mode.mode = 0;
212 mi.u.mode.signal = 0;
213 install_signal_handler(SIGUSR2, NULL, NULL, 0);
214 ioctl(fd, CONS_MOUSECTL, &mi);
218 void
219 suspend_mouse(void *data)
221 unhandle_mouse(data);
224 void
225 resume_mouse(void *data)
227 if (data) {
228 mouse_info_t mi;
229 int fd = get_output_handle();
231 mi.operation = MOUSE_MODE;
232 mi.u.mode.mode = 0;
233 mi.u.mode.signal = SIGUSR2;;
234 install_signal_handler(SIGUSR2,
235 (void (*)(void *))sysmouse_signal_handler, data, 0);
236 ioctl(fd, CONS_MOUSECTL, &mi);
240 #endif