Mercurial > sdl-ios-xcode
comparison src/video/riscos/SDL_riscosmouse.c @ 630:550bccdf04bd
Added initial support for RISC OS (thanks Peter Naulls!)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 29 May 2003 04:44:13 +0000 |
parents | |
children | b8d311d90021 |
comparison
equal
deleted
inserted
replaced
629:3fa401bb4bb5 | 630:550bccdf04bd |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com | |
21 */ | |
22 | |
23 /* | |
24 File added by Alan Buckley (alan_baa@hotmail.com) for RISCOS compatability | |
25 27 March 2003 | |
26 | |
27 Implements mouse cursor shape definitions and positioning | |
28 */ | |
29 | |
30 #include <stdio.h> | |
31 #include <stdlib.h> | |
32 | |
33 #include "SDL_error.h" | |
34 #include "SDL_mouse.h" | |
35 #include "SDL_events_c.h" | |
36 | |
37 #include "SDL_riscosmouse_c.h" | |
38 | |
39 #include "kernel.h" | |
40 #include "swis.h" | |
41 | |
42 static WMcursor *current_cursor = NULL; | |
43 | |
44 extern int mouseInWindow; | |
45 | |
46 void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor) | |
47 { | |
48 free(cursor->data); | |
49 free(cursor); | |
50 } | |
51 | |
52 WMcursor *RISCOS_CreateWMCursor(_THIS, | |
53 Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) | |
54 { | |
55 WMcursor *cursor; | |
56 Uint8 *cursor_data; | |
57 Uint8 *ptr; | |
58 int i,j,k; | |
59 int data_byte, mask_byte; | |
60 | |
61 /* Check to make sure the cursor size is okay */ | |
62 if ( (w > 32) || (h > 32) ) { | |
63 SDL_SetError("Only with width and height <= 32 pixels are allowed"); | |
64 return(NULL); | |
65 } | |
66 | |
67 /* Allocate the cursor */ | |
68 cursor = (WMcursor *)malloc(sizeof(*cursor)); | |
69 if ( cursor == NULL ) { | |
70 SDL_SetError("Out of memory"); | |
71 return(NULL); | |
72 } | |
73 | |
74 /* Note: SDL says width must be a multiple of 8 */ | |
75 cursor_data = malloc(w/4 * h); | |
76 if (cursor_data == NULL) | |
77 { | |
78 free(cursor); | |
79 SDL_SetError("Out of memory"); | |
80 return(NULL); | |
81 } | |
82 | |
83 cursor->w = w; | |
84 cursor->h = h; | |
85 cursor->hot_x = hot_x; | |
86 cursor->hot_y = hot_y; | |
87 cursor->data = cursor_data; | |
88 | |
89 | |
90 /* Data / Mask Resulting pixel on screen | |
91 0 / 1 White | |
92 1 / 1 Black | |
93 0 / 0 Transparent | |
94 1 / 0 Inverted color if possible, black if not. | |
95 */ | |
96 ptr = cursor_data; | |
97 | |
98 for ( i=0; i<h; ++i ) | |
99 { | |
100 for (j = 0; j < w/8; ++j) | |
101 { | |
102 data_byte = *data; | |
103 mask_byte = *mask; | |
104 *ptr++ = 0; /* Sets whole byte transparent */ | |
105 *ptr = 0; | |
106 for (k = 0; k < 8; k++) | |
107 { | |
108 (*ptr) <<= 2; | |
109 if (data_byte & 1) *ptr |= 3; /* Black or inverted */ | |
110 else if(mask_byte & 1) *ptr |= 1; /* White */ | |
111 if ((k&3) == 3) ptr--; | |
112 data_byte >>= 1; | |
113 mask_byte >>= 1; | |
114 } | |
115 | |
116 ptr+=3; | |
117 data++; | |
118 mask++; | |
119 } | |
120 } | |
121 | |
122 return(cursor); | |
123 } | |
124 | |
125 int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor) | |
126 { | |
127 if (cursor == NULL) | |
128 { | |
129 _kernel_osbyte(106,0,0); | |
130 current_cursor = NULL; | |
131 } else | |
132 { | |
133 if (current_cursor == NULL) | |
134 { | |
135 /* First time set up the mouse colours */ | |
136 Uint8 block[5]; | |
137 | |
138 /* Set up colour 1 as white */ | |
139 block[0] = 1; /* Colour to change 1 - 3 */ | |
140 block[1] = 25; /* Set pointer colour */ | |
141 block[2] = 255; /* red component*/ | |
142 block[3] = 255; /* green component */ | |
143 block[4] = 255; /* blue component*/ | |
144 _kernel_osword(12, (int *)block); | |
145 | |
146 /* Set colour 3 to back */ | |
147 block[0] = 3; /* Colour to change 1 - 3 */ | |
148 block[1] = 25; /* Set pointer colour*/ | |
149 block[2] = 0; /* red component*/ | |
150 block[3] = 0; /* green component */ | |
151 block[4] = 0; /* blue component*/ | |
152 _kernel_osword(12, (int *)block); | |
153 } | |
154 | |
155 if (cursor != current_cursor) | |
156 { | |
157 Uint8 cursor_def[10]; | |
158 | |
159 cursor_def[0] = 0; | |
160 cursor_def[1] = 2; /* Use shape number 2 */ | |
161 cursor_def[2] = cursor->w/4; /* Width in bytes */ | |
162 cursor_def[3] = cursor->h; /* Height (h) in pixels */ | |
163 cursor_def[4] = cursor->hot_x; /* ActiveX in pixels from left */ | |
164 cursor_def[5] = cursor->hot_y; /* ActiveY in pixels from top */ | |
165 cursor_def[6] = ((int)(cursor->data) & 0xFF); /* Least significant byte of pointer to data */ | |
166 cursor_def[7] = ((int)(cursor->data) >> 8) & 0xFF; /* ... */ | |
167 cursor_def[8] = ((int)(cursor->data) >> 16) & 0xFF; /* ... */ | |
168 cursor_def[9] = ((int)(cursor->data) >> 24) & 0xFF; /* Most significant byte of pointer to data */ | |
169 | |
170 if (_kernel_osword(21, (int *)cursor_def) == 0) | |
171 { | |
172 SDL_SetError("RISCOS couldn't create the cursor to show"); | |
173 return(0); | |
174 } | |
175 current_cursor = cursor; | |
176 } | |
177 | |
178 if ((this->screen->flags & SDL_FULLSCREEN) || mouseInWindow) _kernel_osbyte(106, 2, 0); | |
179 } | |
180 | |
181 return(1); | |
182 } | |
183 | |
184 void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y) | |
185 { | |
186 Uint8 move_block[5]; | |
187 int eig_block[3]; | |
188 _kernel_swi_regs regs; | |
189 int os_x, os_y; | |
190 | |
191 eig_block[0] = 4; /* X eig factor */ | |
192 eig_block[1] = 5; /* Y eig factor */ | |
193 eig_block[2] = -1; /* End of list of variables to request */ | |
194 | |
195 regs.r[0] = (int)eig_block; | |
196 regs.r[1] = (int)eig_block; | |
197 _kernel_swi(OS_ReadVduVariables, ®s, ®s); | |
198 | |
199 os_x = x << eig_block[0]; | |
200 os_y = y << eig_block[1]; | |
201 | |
202 move_block[0] = 3; /* Move cursor */ | |
203 move_block[1] = os_x & 0xFF; | |
204 move_block[2] = (os_x >> 8) & 0xFF; | |
205 move_block[3] = os_y & 0xFF; | |
206 move_block[4] = (os_y >> 8) & 0xFF; | |
207 | |
208 _kernel_osword(21, (int *)move_block); | |
209 SDL_PrivateMouseMotion(0, 0, x, y); | |
210 } | |
211 | |
212 | |
213 /* Reshow cursor when mouse re-enters the window */ | |
214 void WIMP_ReshowCursor(_THIS) | |
215 { | |
216 WMcursor *cursor = current_cursor; | |
217 current_cursor = NULL; | |
218 RISCOS_ShowWMCursor(this, cursor); | |
219 } | |
220 | |
221 extern int mouseInWindow; | |
222 | |
223 void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y) | |
224 { | |
225 _kernel_swi_regs regs; | |
226 int window_state[9]; | |
227 char block[5]; | |
228 int osX, osY; | |
229 | |
230 window_state[0] = this->hidden->window_handle; | |
231 regs.r[1] = (unsigned int)window_state; | |
232 _kernel_swi(Wimp_GetWindowState, ®s, ®s); | |
233 | |
234 osX = (x << this->hidden->xeig) + window_state[1]; | |
235 osY = window_state[4] - (y << this->hidden->yeig); | |
236 | |
237 block[0] = 3; | |
238 block[1] = osX & 0xFF; | |
239 block[2] = (osX >> 8) & 0xFF; | |
240 block[3] = osY & 0xFF; | |
241 block[4] = (osY >> 8) & 0xFF; | |
242 | |
243 regs.r[0] = 21; | |
244 regs.r[1] = (int)block; | |
245 _kernel_swi(OS_Word, ®s, ®s); | |
246 SDL_PrivateMouseMotion(0, 0, x, y); | |
247 } | |
248 | |
249 int WIMP_ShowWMCursor(_THIS, WMcursor *cursor) | |
250 { | |
251 if (mouseInWindow) return RISCOS_ShowWMCursor(this, cursor); | |
252 return 1; | |
253 } | |
254 | |
255 SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode) | |
256 { | |
257 /* In fullscreen mode we don't need to do anything */ | |
258 if (mode < SDL_GRAB_FULLSCREEN) | |
259 { | |
260 _kernel_swi_regs regs; | |
261 unsigned char block[9]; | |
262 block[0] = 1; /* Define mouse cursor bounding block */ | |
263 | |
264 if ( mode == SDL_GRAB_OFF ) | |
265 { | |
266 /* Clip to whole screen */ | |
267 | |
268 int r = (this->hidden->screen_width << this->hidden->xeig) - 1; | |
269 int t = (this->hidden->screen_height << this->hidden->yeig) - 1; | |
270 | |
271 block[1] = 0; block[2] = 0; /* Left*/ | |
272 block[3] = 0; block[4] = 0; /* Bottom */ | |
273 block[5] = r & 0xFF; block[6] = (r >> 8) & 0xFF; /* Right */ | |
274 block[7] = t & 0xFF; block[8] = (t >> 8) & 0xFF; /* Top */ | |
275 } else | |
276 { | |
277 /* Clip to window */ | |
278 unsigned char window_state[36]; | |
279 | |
280 *((int *)window_state) = this->hidden->window_handle; | |
281 regs.r[1] = (unsigned int)window_state; | |
282 _kernel_swi(Wimp_GetWindowState, ®s, ®s); | |
283 | |
284 block[1] = window_state[4]; | |
285 block[2] = window_state[5]; | |
286 block[3] = window_state[8]; | |
287 block[4] = window_state[9]; | |
288 block[5] = window_state[12]; | |
289 block[6] = window_state[13]; | |
290 block[7] = window_state[16]; | |
291 block[8] = window_state[17]; | |
292 | |
293 } | |
294 | |
295 regs.r[0] = 21; /* OS word code */ | |
296 regs.r[1] = (int)block; | |
297 _kernel_swi(OS_Word, ®s, ®s); | |
298 } | |
299 | |
300 return mode; | |
301 } |