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, &regs, &regs);
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, &regs, &regs);
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, &regs, &regs);
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, &regs, &regs);
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, &regs, &regs);
298 }
299
300 return mode;
301 }