1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Stuff for BeOS.
12 *
13 * By Jason Wilkins.
14 *
15 * Windowed mode modifications by Peter Wang.
16 *
17 * Cursor show/hide in windowed mode added by Angelo Mottola.
18 *
19 * See readme.txt for copyright information.
20 */
21
22 #include "bealleg.h"
23 #include "allegro/internal/aintern.h"
24 #include "allegro/platform/aintbeos.h"
25
26 #if !defined ALLEGRO_BEOS && !defined ALLEGRO_HAIKU
27 #error something is wrong with the makefile
28 #endif
29
30 #define MOUSE_THREAD_NAME "mouse driver"
31 #define MOUSE_THREAD_PRIORITY 60
32 #define MOUSE_THREAD_PERIOD 20000 // microseconds, 1/50th of a second
33
34
35
36 #define PREFIX_I "al-bmouse INFO: "
37 #define PREFIX_W "al-bmouse WARNING: "
38 #define PREFIX_E "al-bmouse ERROR: "
39
40 static thread_id mouse_thread_id = -1;
41 static volatile bool mouse_thread_running = false;
42
43 sem_id _be_mouse_view_attached = -1;
44 BWindow *_be_mouse_window = NULL;
45 BView *_be_mouse_view = NULL;
46 bool _be_mouse_window_mode = false;
47
48 static int be_mouse_x = 0;
49 static int be_mouse_y = 0;
50 static int be_mouse_b = 0;
51
52 static int be_mickey_x = 0;
53 static int be_mickey_y = 0;
54
55 static int limit_up = 0;
56 static int limit_down = 0;
57 static int limit_left = 0;
58 static int limit_right = 0;
59
60 static bool be_mouse_warped = false;
61
62
mouse_thread(void * mouse_started)63 int32 mouse_thread(void *mouse_started)
64 {
65 BPoint cursor(0, 0);
66 uint32 buttons;
67
68 if (!_be_mouse_window_mode) {
69 set_mouse_position(320, 240);
70 }
71
72 release_sem(*(sem_id *)mouse_started);
73
74 for (;;) {
75 acquire_sem(_be_mouse_view_attached);
76
77 if (mouse_thread_running == false) {
78 release_sem(_be_mouse_view_attached);
79 /* XXX commented out due to conflicting TRACE in Haiku
80 TRACE(PREFIX_I "mouse thread exited\n");
81 */
82
83 return 0;
84 }
85
86 if ((_be_focus_count > 0) && _be_mouse_window->Lock()) {
87 _be_mouse_view->GetMouse(&cursor, &buttons);
88 if (!_be_mouse_window_mode) {
89 int dx = (int)cursor.x - 320;
90 int dy = (int)cursor.y - 240;
91
92 if (be_mouse_warped) {
93 dx = 0;
94 dy = 0;
95 be_mouse_warped = false;
96 }
97 be_mickey_x = dx;
98 be_mickey_y = dy;
99 be_mouse_x += dx;
100 be_mouse_y += dy;
101
102 if (dx != 0 || dy != 0) {
103 set_mouse_position(320, 240);
104 }
105 }
106 else {
107 BRect bounds = _be_mouse_window->Bounds();
108
109 if (bounds.Contains(cursor)) {
110 int old_x = be_mouse_x;
111 int old_y = be_mouse_y;
112
113 _mouse_on = TRUE;
114 if (!be_app->IsCursorHidden()) {
115 be_app->HideCursor();
116 }
117
118 be_mouse_x = (int)(cursor.x - bounds.left);
119 be_mouse_y = (int)(cursor.y - bounds.top);
120 if (!be_mouse_warped) {
121 be_mickey_x += (be_mouse_x - old_x);
122 be_mickey_y += (be_mouse_y - old_y);
123 }
124 else {
125 be_mouse_warped = false;
126 be_mickey_x = 0;
127 be_mickey_y = 0;
128 }
129 }
130 else {
131 buttons = 0;
132 _mouse_on = FALSE;
133 if (be_app->IsCursorHidden()) {
134 be_app->ShowCursor();
135 }
136 }
137 }
138
139 _be_mouse_window->Unlock();
140
141 be_mouse_x = CLAMP(limit_left, be_mouse_x, limit_right);
142 be_mouse_y = CLAMP(limit_up, be_mouse_y, limit_down);
143
144 be_mouse_b = 0;
145 be_mouse_b |= (buttons & B_PRIMARY_MOUSE_BUTTON) ? 1 : 0;
146 be_mouse_b |= (buttons & B_SECONDARY_MOUSE_BUTTON) ? 2 : 0;
147 be_mouse_b |= (buttons & B_TERTIARY_MOUSE_BUTTON) ? 4 : 0;
148
149 _mouse_x = be_mouse_x;
150 _mouse_y = be_mouse_y;
151 _mouse_z = _be_mouse_z;
152 _mouse_b = be_mouse_b;
153 _handle_mouse_input();
154 }
155
156 release_sem(_be_mouse_view_attached);
157
158 snooze(MOUSE_THREAD_PERIOD);
159 }
160 }
161
162
163
be_mouse_init(void)164 extern "C" int be_mouse_init(void)
165 {
166 sem_id mouse_started;
167 int32 num_buttons;
168
169 mouse_started = create_sem(0, "starting mouse driver...");
170
171 if (mouse_started < 0) {
172 goto cleanup;
173 }
174
175 mouse_thread_id = spawn_thread(mouse_thread, MOUSE_THREAD_NAME,
176 MOUSE_THREAD_PRIORITY, &mouse_started);
177
178 if (mouse_thread_id < 0) {
179 goto cleanup;
180 }
181
182 mouse_thread_running = true;
183 resume_thread(mouse_thread_id);
184 acquire_sem(mouse_started);
185 delete_sem(mouse_started);
186
187 be_mickey_x = 0;
188 be_mickey_y = 0;
189
190 be_mouse_x = 0;
191 be_mouse_y = 0;
192 be_mouse_b = 0;
193
194 limit_up = 0;
195 limit_down = 0;
196 limit_left = 0;
197 limit_right = 0;
198
199 get_mouse_type(&num_buttons);
200
201 return num_buttons;
202
203 cleanup: {
204 if (mouse_started > 0) {
205 delete_sem(mouse_started);
206 }
207
208 be_mouse_exit();
209 return 0;
210 }
211 }
212
213
214
be_mouse_exit(void)215 extern "C" void be_mouse_exit(void)
216 {
217 be_mickey_x = 0;
218 be_mickey_y = 0;
219
220 be_mouse_x = 0;
221 be_mouse_y = 0;
222 be_mouse_b = 0;
223
224 limit_up = 0;
225 limit_down = 0;
226 limit_left = 0;
227 limit_right = 0;
228
229 mouse_thread_running = false;
230
231 if (mouse_thread_id > 0) {
232 release_sem(_be_mouse_view_attached);
233 wait_for_thread(mouse_thread_id, &ignore_result);
234 acquire_sem(_be_mouse_view_attached);
235 mouse_thread_id = -1;
236 }
237 }
238
239
240
be_mouse_position(int x,int y)241 extern "C" void be_mouse_position(int x, int y)
242 {
243 acquire_sem(_be_mouse_view_attached);
244 _mouse_x = be_mouse_x = CLAMP(limit_left, x, limit_right);
245 _mouse_y = be_mouse_y = CLAMP(limit_up, y, limit_down);
246 be_mouse_warped = true;
247 if (!_be_mouse_window_mode)
248 set_mouse_position(320, 240);
249 release_sem(_be_mouse_view_attached);
250 }
251
252
253
be_mouse_set_range(int x1,int y1,int x2,int y2)254 extern "C" void be_mouse_set_range(int x1, int y1, int x2, int y2)
255 {
256 acquire_sem(_be_mouse_view_attached);
257 limit_up = y1;
258 limit_down = y2;
259 limit_left = x1;
260 limit_right = x2;
261 release_sem(_be_mouse_view_attached);
262 }
263
264
265
be_mouse_set_speed(int xspeed,int yspeed)266 extern "C" void be_mouse_set_speed(int xspeed, int yspeed)
267 {
268 }
269
270
271
be_mouse_get_mickeys(int * mickeyx,int * mickeyy)272 extern "C" void be_mouse_get_mickeys(int *mickeyx, int *mickeyy)
273 {
274 acquire_sem(_be_mouse_view_attached);
275 if (mickeyx != NULL) {
276 *mickeyx = be_mickey_x;
277 }
278
279 if (mickeyy != NULL) {
280 *mickeyy = be_mickey_y;
281 }
282
283 be_mickey_x = 0;
284 be_mickey_y = 0;
285 release_sem(_be_mouse_view_attached);
286 }
287