2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 Sam Lantinga
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.
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.
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
22 #include "SDL_config.h"
25 File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
28 Implements mouse cursor shape definitions and positioning
31 #include "SDL_mouse.h"
32 #include "../../events/SDL_events_c.h"
34 #include "SDL_riscosmouse_c.h"
39 static WMcursor *current_cursor = NULL;
40 static WMcursor *defined_cursor = NULL;
42 extern int mouseInWindow;
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}
51 static int cursor_palette_saved = 0;
53 void WIMP_SaveCursorPalette();
54 void WIMP_RestoreWimpCursor();
55 void WIMP_SetSDLCursorPalette();
58 void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor)
60 SDL_free(cursor->data);
64 WMcursor *RISCOS_CreateWMCursor(_THIS,
65 Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
71 int data_byte, mask_byte;
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");
79 /* Allocate the cursor */
80 cursor = (WMcursor *)SDL_malloc(sizeof(*cursor));
81 if ( cursor == NULL ) {
82 SDL_SetError("Out of memory");
86 /* Note: SDL says width must be a multiple of 8 */
87 cursor_data = SDL_malloc(w/4 * h);
88 if (cursor_data == NULL)
91 SDL_SetError("Out of memory");
97 cursor->hot_x = hot_x;
98 cursor->hot_y = hot_y;
99 cursor->data = cursor_data;
102 /* Data / Mask Resulting pixel on screen
106 1 / 0 Inverted color if possible, black if not.
110 for ( i=0; i<h; ++i )
112 for (j = 0; j < w/8; ++j)
116 *ptr++ = 0; /* Sets whole byte transparent */
118 for (k = 0; k < 8; k++)
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--;
137 int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor)
139 current_cursor = cursor;
143 _kernel_osbyte(106,0,0);
144 defined_cursor = NULL;
147 WMcursor *old_cursor = defined_cursor;
149 if (cursor != defined_cursor)
151 Uint8 cursor_def[10];
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 */
164 if (_kernel_osword(21, (int *)cursor_def) != 0)
166 SDL_SetError("RISCOS couldn't create the cursor to show");
169 defined_cursor = cursor;
172 if (old_cursor == NULL)
174 /* First time or reshow in window, so save/setup palette */
175 if (!cursor_palette_saved)
177 WIMP_SaveCursorPalette();
179 WIMP_SetSDLCursorPalette();
182 _kernel_osbyte(106, 2, 0);
188 void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
192 _kernel_swi_regs regs;
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 */
199 regs.r[0] = (int)eig_block;
200 regs.r[1] = (int)eig_block;
201 _kernel_swi(OS_ReadVduVariables, ®s, ®s);
203 os_x = x << eig_block[0];
204 os_y = y << eig_block[1];
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;
212 _kernel_osword(21, (int *)move_block);
213 SDL_PrivateMouseMotion(0, 0, x, y);
217 /* Reshow cursor when mouse re-enters the window */
218 void WIMP_ReshowCursor(_THIS)
220 defined_cursor = NULL;
221 cursor_palette_saved = 0;
222 RISCOS_ShowWMCursor(this, current_cursor);
225 void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
227 _kernel_swi_regs regs;
232 window_state[0] = this->hidden->window_handle;
233 regs.r[1] = (unsigned int)window_state;
234 _kernel_swi(Wimp_GetWindowState, ®s, ®s);
236 osX = (x << this->hidden->xeig) + window_state[1];
237 osY = window_state[4] - (y << this->hidden->yeig);
240 block[1] = osX & 0xFF;
241 block[2] = (osX >> 8) & 0xFF;
242 block[3] = osY & 0xFF;
243 block[4] = (osY >> 8) & 0xFF;
246 regs.r[1] = (int)block;
247 _kernel_swi(OS_Word, ®s, ®s);
248 SDL_PrivateMouseMotion(0, 0, x, y);
251 int WIMP_ShowWMCursor(_THIS, WMcursor *cursor)
253 if (mouseInWindow) return RISCOS_ShowWMCursor(this, cursor);
254 else current_cursor = cursor;
259 SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode)
261 /* In fullscreen mode we don't need to do anything */
262 if (mode < SDL_GRAB_FULLSCREEN)
264 _kernel_swi_regs regs;
265 unsigned char block[9];
266 block[0] = 1; /* Define mouse cursor bounding block */
268 if ( mode == SDL_GRAB_OFF )
270 /* Clip to whole screen */
272 int r = (this->hidden->screen_width << this->hidden->xeig) - 1;
273 int t = (this->hidden->screen_height << this->hidden->yeig) - 1;
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 */
282 unsigned char window_state[36];
284 *((int *)window_state) = this->hidden->window_handle;
285 regs.r[1] = (unsigned int)window_state;
286 _kernel_swi(Wimp_GetWindowState, ®s, ®s);
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];
299 regs.r[0] = 21; /* OS word code */
300 regs.r[1] = (int)block;
301 _kernel_swi(OS_Word, ®s, ®s);
307 /* Save mouse cursor palette to be restore when we are no longer
310 void WIMP_SaveCursorPalette()
312 _kernel_swi_regs regs;
315 for (colour = 0; colour < 2; colour++)
317 regs.r[0] = (int)wimp_cursor_palette[colour][0];
319 /* Read settings with OS_ReadPalette */
320 if (_kernel_swi(0x2f, ®s, ®s) == NULL)
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);
328 cursor_palette_saved = 1;
331 /* Restore the WIMP's cursor when we leave the SDL window */
332 void WIMP_RestoreWimpCursor()
336 /* Reset to pointer shape 1 */
337 _kernel_osbyte(106, 1, 0);
339 /* Reset pointer colours */
340 if (cursor_palette_saved)
342 for (colour = 0; colour < 2; colour++)
344 _kernel_osword(12, (int *)wimp_cursor_palette[colour]);
347 cursor_palette_saved = 0;
350 /* Set palette used for SDL mouse cursors */
351 void WIMP_SetSDLCursorPalette()
353 /* First time set up the mouse colours */
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);
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);