diff options
Diffstat (limited to 'apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c')
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c b/apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c new file mode 100644 index 0000000000..b4a0bffc94 --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c | |||
@@ -0,0 +1,371 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability | ||
26 | 27 March 2003 | ||
27 | |||
28 | Implements mouse cursor shape definitions and positioning | ||
29 | */ | ||
30 | |||
31 | #include "SDL_mouse.h" | ||
32 | #include "../../events/SDL_events_c.h" | ||
33 | |||
34 | #include "SDL_riscosmouse_c.h" | ||
35 | |||
36 | #include "kernel.h" | ||
37 | #include "swis.h" | ||
38 | |||
39 | static WMcursor *current_cursor = NULL; | ||
40 | static WMcursor *defined_cursor = NULL; | ||
41 | |||
42 | extern int mouseInWindow; | ||
43 | |||
44 | /* Area to save cursor palette colours changed by SDL. | ||
45 | Actual values will be read before we change to the SDL cursor */ | ||
46 | static Uint8 wimp_cursor_palette[2][5] = { | ||
47 | {1, 25, 255, 255, 255}, | ||
48 | {3, 25, 255, 255, 255} | ||
49 | }; | ||
50 | |||
51 | static int cursor_palette_saved = 0; | ||
52 | |||
53 | void WIMP_SaveCursorPalette(); | ||
54 | void WIMP_RestoreWimpCursor(); | ||
55 | void WIMP_SetSDLCursorPalette(); | ||
56 | |||
57 | |||
58 | void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor) | ||
59 | { | ||
60 | SDL_free(cursor->data); | ||
61 | SDL_free(cursor); | ||
62 | } | ||
63 | |||
64 | WMcursor *RISCOS_CreateWMCursor(_THIS, | ||
65 | Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) | ||
66 | { | ||
67 | WMcursor *cursor; | ||
68 | Uint8 *cursor_data; | ||
69 | Uint8 *ptr; | ||
70 | int i,j,k; | ||
71 | int data_byte, mask_byte; | ||
72 | |||
73 | /* Check to make sure the cursor size is okay */ | ||
74 | if ( (w > 32) || (h > 32) ) { | ||
75 | SDL_SetError("Only with width and height <= 32 pixels are allowed"); | ||
76 | return(NULL); | ||
77 | } | ||
78 | |||
79 | /* Allocate the cursor */ | ||
80 | cursor = (WMcursor *)SDL_malloc(sizeof(*cursor)); | ||
81 | if ( cursor == NULL ) { | ||
82 | SDL_SetError("Out of memory"); | ||
83 | return(NULL); | ||
84 | } | ||
85 | |||
86 | /* Note: SDL says width must be a multiple of 8 */ | ||
87 | cursor_data = SDL_malloc(w/4 * h); | ||
88 | if (cursor_data == NULL) | ||
89 | { | ||
90 | SDL_free(cursor); | ||
91 | SDL_SetError("Out of memory"); | ||
92 | return(NULL); | ||
93 | } | ||
94 | |||
95 | cursor->w = w; | ||
96 | cursor->h = h; | ||
97 | cursor->hot_x = hot_x; | ||
98 | cursor->hot_y = hot_y; | ||
99 | cursor->data = cursor_data; | ||
100 | |||
101 | |||
102 | /* Data / Mask Resulting pixel on screen | ||
103 | 0 / 1 White | ||
104 | 1 / 1 Black | ||
105 | 0 / 0 Transparent | ||
106 | 1 / 0 Inverted color if possible, black if not. | ||
107 | */ | ||
108 | ptr = cursor_data; | ||
109 | |||
110 | for ( i=0; i<h; ++i ) | ||
111 | { | ||
112 | for (j = 0; j < w/8; ++j) | ||
113 | { | ||
114 | data_byte = *data; | ||
115 | mask_byte = *mask; | ||
116 | *ptr++ = 0; /* Sets whole byte transparent */ | ||
117 | *ptr = 0; | ||
118 | for (k = 0; k < 8; k++) | ||
119 | { | ||
120 | (*ptr) <<= 2; | ||
121 | if (data_byte & 1) *ptr |= 3; /* Black or inverted */ | ||
122 | else if(mask_byte & 1) *ptr |= 1; /* White */ | ||
123 | if ((k&3) == 3) ptr--; | ||
124 | data_byte >>= 1; | ||
125 | mask_byte >>= 1; | ||
126 | } | ||
127 | |||
128 | ptr+=3; | ||
129 | data++; | ||
130 | mask++; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | return(cursor); | ||
135 | } | ||
136 | |||
137 | int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor) | ||
138 | { | ||
139 | current_cursor = cursor; | ||
140 | |||
141 | if (cursor == NULL) | ||
142 | { | ||
143 | _kernel_osbyte(106,0,0); | ||
144 | defined_cursor = NULL; | ||
145 | } else | ||
146 | { | ||
147 | WMcursor *old_cursor = defined_cursor; | ||
148 | |||
149 | if (cursor != defined_cursor) | ||
150 | { | ||
151 | Uint8 cursor_def[10]; | ||
152 | |||
153 | cursor_def[0] = 0; | ||
154 | cursor_def[1] = 2; /* Use shape number 2 */ | ||
155 | cursor_def[2] = cursor->w/4; /* Width in bytes */ | ||
156 | cursor_def[3] = cursor->h; /* Height (h) in pixels */ | ||
157 | cursor_def[4] = cursor->hot_x; /* ActiveX in pixels from left */ | ||
158 | cursor_def[5] = cursor->hot_y; /* ActiveY in pixels from top */ | ||
159 | cursor_def[6] = ((int)(cursor->data) & 0xFF); /* Least significant byte of pointer to data */ | ||
160 | cursor_def[7] = ((int)(cursor->data) >> 8) & 0xFF; /* ... */ | ||
161 | cursor_def[8] = ((int)(cursor->data) >> 16) & 0xFF; /* ... */ | ||
162 | cursor_def[9] = ((int)(cursor->data) >> 24) & 0xFF; /* Most significant byte of pointer to data */ | ||
163 | |||
164 | if (_kernel_osword(21, (int *)cursor_def) != 0) | ||
165 | { | ||
166 | SDL_SetError("RISCOS couldn't create the cursor to show"); | ||
167 | return(0); | ||
168 | } | ||
169 | defined_cursor = cursor; | ||
170 | } | ||
171 | |||
172 | if (old_cursor == NULL) | ||
173 | { | ||
174 | /* First time or reshow in window, so save/setup palette */ | ||
175 | if (!cursor_palette_saved) | ||
176 | { | ||
177 | WIMP_SaveCursorPalette(); | ||
178 | } | ||
179 | WIMP_SetSDLCursorPalette(); | ||
180 | } | ||
181 | |||
182 | _kernel_osbyte(106, 2, 0); | ||
183 | } | ||
184 | |||
185 | return(1); | ||
186 | } | ||
187 | |||
188 | void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y) | ||
189 | { | ||
190 | Uint8 move_block[5]; | ||
191 | int eig_block[3]; | ||
192 | _kernel_swi_regs regs; | ||
193 | int os_x, os_y; | ||
194 | |||
195 | eig_block[0] = 4; /* X eig factor */ | ||
196 | eig_block[1] = 5; /* Y eig factor */ | ||
197 | eig_block[2] = -1; /* End of list of variables to request */ | ||
198 | |||
199 | regs.r[0] = (int)eig_block; | ||
200 | regs.r[1] = (int)eig_block; | ||
201 | _kernel_swi(OS_ReadVduVariables, ®s, ®s); | ||
202 | |||
203 | os_x = x << eig_block[0]; | ||
204 | os_y = y << eig_block[1]; | ||
205 | |||
206 | move_block[0] = 3; /* Move cursor */ | ||
207 | move_block[1] = os_x & 0xFF; | ||
208 | move_block[2] = (os_x >> 8) & 0xFF; | ||
209 | move_block[3] = os_y & 0xFF; | ||
210 | move_block[4] = (os_y >> 8) & 0xFF; | ||
211 | |||
212 | _kernel_osword(21, (int *)move_block); | ||
213 | SDL_PrivateMouseMotion(0, 0, x, y); | ||
214 | } | ||
215 | |||
216 | |||
217 | /* Reshow cursor when mouse re-enters the window */ | ||
218 | void WIMP_ReshowCursor(_THIS) | ||
219 | { | ||
220 | defined_cursor = NULL; | ||
221 | cursor_palette_saved = 0; | ||
222 | RISCOS_ShowWMCursor(this, current_cursor); | ||
223 | } | ||
224 | |||
225 | void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y) | ||
226 | { | ||
227 | _kernel_swi_regs regs; | ||
228 | int window_state[9]; | ||
229 | char block[5]; | ||
230 | int osX, osY; | ||
231 | |||
232 | window_state[0] = this->hidden->window_handle; | ||
233 | regs.r[1] = (unsigned int)window_state; | ||
234 | _kernel_swi(Wimp_GetWindowState, ®s, ®s); | ||
235 | |||
236 | osX = (x << this->hidden->xeig) + window_state[1]; | ||
237 | osY = window_state[4] - (y << this->hidden->yeig); | ||
238 | |||
239 | block[0] = 3; | ||
240 | block[1] = osX & 0xFF; | ||
241 | block[2] = (osX >> 8) & 0xFF; | ||
242 | block[3] = osY & 0xFF; | ||
243 | block[4] = (osY >> 8) & 0xFF; | ||
244 | |||
245 | regs.r[0] = 21; | ||
246 | regs.r[1] = (int)block; | ||
247 | _kernel_swi(OS_Word, ®s, ®s); | ||
248 | SDL_PrivateMouseMotion(0, 0, x, y); | ||
249 | } | ||
250 | |||
251 | int WIMP_ShowWMCursor(_THIS, WMcursor *cursor) | ||
252 | { | ||
253 | if (mouseInWindow) return RISCOS_ShowWMCursor(this, cursor); | ||
254 | else current_cursor = cursor; | ||
255 | |||
256 | return 1; | ||
257 | } | ||
258 | |||
259 | SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode) | ||
260 | { | ||
261 | /* In fullscreen mode we don't need to do anything */ | ||
262 | if (mode < SDL_GRAB_FULLSCREEN) | ||
263 | { | ||
264 | _kernel_swi_regs regs; | ||
265 | unsigned char block[9]; | ||
266 | block[0] = 1; /* Define mouse cursor bounding block */ | ||
267 | |||
268 | if ( mode == SDL_GRAB_OFF ) | ||
269 | { | ||
270 | /* Clip to whole screen */ | ||
271 | |||
272 | int r = (this->hidden->screen_width << this->hidden->xeig) - 1; | ||
273 | int t = (this->hidden->screen_height << this->hidden->yeig) - 1; | ||
274 | |||
275 | block[1] = 0; block[2] = 0; /* Left*/ | ||
276 | block[3] = 0; block[4] = 0; /* Bottom */ | ||
277 | block[5] = r & 0xFF; block[6] = (r >> 8) & 0xFF; /* Right */ | ||
278 | block[7] = t & 0xFF; block[8] = (t >> 8) & 0xFF; /* Top */ | ||
279 | } else | ||
280 | { | ||
281 | /* Clip to window */ | ||
282 | unsigned char window_state[36]; | ||
283 | |||
284 | *((int *)window_state) = this->hidden->window_handle; | ||
285 | regs.r[1] = (unsigned int)window_state; | ||
286 | _kernel_swi(Wimp_GetWindowState, ®s, ®s); | ||
287 | |||
288 | block[1] = window_state[4]; | ||
289 | block[2] = window_state[5]; | ||
290 | block[3] = window_state[8]; | ||
291 | block[4] = window_state[9]; | ||
292 | block[5] = window_state[12]; | ||
293 | block[6] = window_state[13]; | ||
294 | block[7] = window_state[16]; | ||
295 | block[8] = window_state[17]; | ||
296 | |||
297 | } | ||
298 | |||
299 | regs.r[0] = 21; /* OS word code */ | ||
300 | regs.r[1] = (int)block; | ||
301 | _kernel_swi(OS_Word, ®s, ®s); | ||
302 | } | ||
303 | |||
304 | return mode; | ||
305 | } | ||
306 | |||
307 | /* Save mouse cursor palette to be restore when we are no longer | ||
308 | defining a cursor */ | ||
309 | |||
310 | void WIMP_SaveCursorPalette() | ||
311 | { | ||
312 | _kernel_swi_regs regs; | ||
313 | int colour; | ||
314 | |||
315 | for (colour = 0; colour < 2; colour++) | ||
316 | { | ||
317 | regs.r[0] = (int)wimp_cursor_palette[colour][0]; | ||
318 | regs.r[1] = 25; | ||
319 | /* Read settings with OS_ReadPalette */ | ||
320 | if (_kernel_swi(0x2f, ®s, ®s) == NULL) | ||
321 | { | ||
322 | wimp_cursor_palette[colour][2] = (unsigned char)((regs.r[2] >> 8) & 0xFF); | ||
323 | wimp_cursor_palette[colour][3] = (unsigned char)((regs.r[2] >> 16) & 0xFF); | ||
324 | wimp_cursor_palette[colour][4] = (unsigned char)((regs.r[2] >> 24) & 0xFF); | ||
325 | } | ||
326 | } | ||
327 | |||
328 | cursor_palette_saved = 1; | ||
329 | } | ||
330 | |||
331 | /* Restore the WIMP's cursor when we leave the SDL window */ | ||
332 | void WIMP_RestoreWimpCursor() | ||
333 | { | ||
334 | int colour; | ||
335 | |||
336 | /* Reset to pointer shape 1 */ | ||
337 | _kernel_osbyte(106, 1, 0); | ||
338 | |||
339 | /* Reset pointer colours */ | ||
340 | if (cursor_palette_saved) | ||
341 | { | ||
342 | for (colour = 0; colour < 2; colour++) | ||
343 | { | ||
344 | _kernel_osword(12, (int *)wimp_cursor_palette[colour]); | ||
345 | } | ||
346 | } | ||
347 | cursor_palette_saved = 0; | ||
348 | } | ||
349 | |||
350 | /* Set palette used for SDL mouse cursors */ | ||
351 | void WIMP_SetSDLCursorPalette() | ||
352 | { | ||
353 | /* First time set up the mouse colours */ | ||
354 | Uint8 block[5]; | ||
355 | |||
356 | /* Set up colour 1 as white */ | ||
357 | block[0] = 1; /* Colour to change 1 - 3 */ | ||
358 | block[1] = 25; /* Set pointer colour */ | ||
359 | block[2] = 255; /* red component*/ | ||
360 | block[3] = 255; /* green component */ | ||
361 | block[4] = 255; /* blue component*/ | ||
362 | _kernel_osword(12, (int *)block); | ||
363 | |||
364 | /* Set colour 3 to back */ | ||
365 | block[0] = 3; /* Colour to change 1 - 3 */ | ||
366 | block[1] = 25; /* Set pointer colour*/ | ||
367 | block[2] = 0; /* red component*/ | ||
368 | block[3] = 0; /* green component */ | ||
369 | block[4] = 0; /* blue component*/ | ||
370 | _kernel_osword(12, (int *)block); | ||
371 | } | ||