• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RISCOS_FreeWMCursor(_THIS,WMcursor * cursor)58 void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor)
59 {
60     SDL_free(cursor->data);
61 	SDL_free(cursor);
62 }
63 
RISCOS_CreateWMCursor(_THIS,Uint8 * data,Uint8 * mask,int w,int h,int hot_x,int hot_y)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 
RISCOS_ShowWMCursor(_THIS,WMcursor * cursor)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 
FULLSCREEN_WarpWMCursor(_THIS,Uint16 x,Uint16 y)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, &regs, &regs);
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 */
WIMP_ReshowCursor(_THIS)218 void WIMP_ReshowCursor(_THIS)
219 {
220 	defined_cursor = NULL;
221     cursor_palette_saved = 0;
222 	RISCOS_ShowWMCursor(this, current_cursor);
223 }
224 
WIMP_WarpWMCursor(_THIS,Uint16 x,Uint16 y)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, &regs, &regs);
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, &regs, &regs);
248 	SDL_PrivateMouseMotion(0, 0, x, y);
249 }
250 
WIMP_ShowWMCursor(_THIS,WMcursor * cursor)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 
RISCOS_GrabInput(_THIS,SDL_GrabMode mode)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, &regs, &regs);
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, &regs, &regs);
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 
WIMP_SaveCursorPalette()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, &regs, &regs) == 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 */
WIMP_RestoreWimpCursor()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 */
WIMP_SetSDLCursorPalette()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 }
372