1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2004 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 23 March 2003
27
28 Implements RISC OS display device management.
29 Routines for full screen and wimp modes are split
30 into other source files.
31 */
32
33 #include "SDL_video.h"
34 #include "SDL_mouse.h"
35 #include "SDL_syswm.h"
36 #include "../SDL_sysvideo.h"
37 #include "../SDL_pixels_c.h"
38 #include "../../events/SDL_events_c.h"
39
40 #include "SDL_riscostask.h"
41 #include "SDL_riscosvideo.h"
42 #include "SDL_riscosevents_c.h"
43 #include "SDL_riscosmouse_c.h"
44
45 #include "kernel.h"
46 #include "swis.h"
47
48 #define RISCOSVID_DRIVER_NAME "riscos"
49
50 /* Initialization/Query functions */
51 static int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat);
52 static void RISCOS_VideoQuit(_THIS);
53
54 static SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
55 static SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
56
57 int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info);
58
59 int RISCOS_ToggleFullScreen(_THIS, int fullscreen);
60 /* Mouse checking */
61 void RISCOS_CheckMouseMode(_THIS);
62 extern SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode);
63
64 /* Fullscreen mode functions */
65 extern SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
66 extern void FULLSCREEN_BuildModeList(_THIS);
67 extern void FULLSCREEN_SetDeviceMode(_THIS);
68 extern int FULLSCREEN_ToggleFromWimp(_THIS);
69
70 /* Wimp mode functions */
71 extern SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
72 extern void WIMP_DeleteWindow(_THIS);
73 extern int WIMP_ToggleFromFullScreen(_THIS);
74
75 /* Hardware surface functions - common to WIMP and FULLSCREEN */
76 static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface);
77 static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface);
78 static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface);
79 static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface);
80
81 /* RISC OS driver bootstrap functions */
82
RISCOS_Available(void)83 static int RISCOS_Available(void)
84 {
85 return(1);
86 }
87
RISCOS_DeleteDevice(SDL_VideoDevice * device)88 static void RISCOS_DeleteDevice(SDL_VideoDevice *device)
89 {
90 SDL_free(device->hidden);
91 SDL_free(device);
92 }
93
RISCOS_CreateDevice(int devindex)94 static SDL_VideoDevice *RISCOS_CreateDevice(int devindex)
95 {
96 SDL_VideoDevice *device;
97
98 /* Initialize all variables that we clean on shutdown */
99 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
100 if ( device ) {
101 SDL_memset(device, 0, (sizeof *device));
102 device->hidden = (struct SDL_PrivateVideoData *)
103 SDL_malloc((sizeof *device->hidden));
104 }
105 if ( (device == NULL) || (device->hidden == NULL) ) {
106 SDL_OutOfMemory();
107 if ( device ) {
108 SDL_free(device);
109 }
110 return(0);
111 }
112 SDL_memset(device->hidden, 0, (sizeof *device->hidden));
113
114 /* Set the function pointers */
115 device->VideoInit = RISCOS_VideoInit;
116 device->VideoQuit = RISCOS_VideoQuit;
117
118 device->ListModes = RISCOS_ListModes;
119 device->SetVideoMode = RISCOS_SetVideoMode;
120 device->CreateYUVOverlay = NULL;
121 device->AllocHWSurface = RISCOS_AllocHWSurface;
122 device->CheckHWBlit = NULL;
123 device->FillHWRect = NULL;
124 device->SetHWColorKey = NULL;
125 device->SetHWAlpha = NULL;
126 device->LockHWSurface = RISCOS_LockHWSurface;
127 device->UnlockHWSurface = RISCOS_UnlockHWSurface;
128 device->FreeHWSurface = RISCOS_FreeHWSurface;
129
130 device->FreeWMCursor = RISCOS_FreeWMCursor;
131 device->CreateWMCursor = RISCOS_CreateWMCursor;
132 device->CheckMouseMode = RISCOS_CheckMouseMode;
133 device->GrabInput = RISCOS_GrabInput;
134
135 device->InitOSKeymap = RISCOS_InitOSKeymap;
136
137 device->GetWMInfo = RISCOS_GetWmInfo;
138
139 device->free = RISCOS_DeleteDevice;
140
141 /* Can't get Toggle screen to work if program starts up in Full screen mode so
142 disable it here and re-enable it when a wimp screen is chosen */
143 device->ToggleFullScreen = NULL; /*RISCOS_ToggleFullScreen;*/
144
145 /* Set other entries for fullscreen mode */
146 FULLSCREEN_SetDeviceMode(device);
147
148 /* Mouse pointer needs to use the WIMP ShowCursor version so
149 that it doesn't modify the pointer until the SDL Window is
150 entered or the application goes full screen */
151 device->ShowWMCursor = WIMP_ShowWMCursor;
152
153 return device;
154 }
155
156 VideoBootStrap RISCOS_bootstrap = {
157 RISCOSVID_DRIVER_NAME, "RISC OS video driver",
158 RISCOS_Available, RISCOS_CreateDevice
159 };
160
161
RISCOS_VideoInit(_THIS,SDL_PixelFormat * vformat)162 int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat)
163 {
164 _kernel_swi_regs regs;
165 int vars[4], vals[3];
166
167 if (RISCOS_InitTask() == 0)
168 {
169 SDL_SetError("Unable to start task");
170 return 0;
171 }
172
173 vars[0] = 9; /* Log base 2 bpp */
174 vars[1] = 11; /* XWndLimit - num x pixels -1 */
175 vars[2] = 12; /* YWndLimit - num y pixels -1 */
176 vars[3] = -1; /* Terminate list */
177 regs.r[0] = (int)vars;
178 regs.r[1] = (int)vals;
179
180 _kernel_swi(OS_ReadVduVariables, ®s, ®s);
181 vformat->BitsPerPixel = (1 << vals[0]);
182
183 /* Determine the current screen size */
184 this->info.current_w = vals[1] + 1;
185 this->info.current_h = vals[2] + 1;
186
187 /* Minimum bpp for SDL is 8 */
188 if (vformat->BitsPerPixel < 8) vformat->BitsPerPixel = 8;
189
190
191 switch (vformat->BitsPerPixel)
192 {
193 case 15:
194 case 16:
195 vformat->Bmask = 0x00007c00;
196 vformat->Gmask = 0x000003e0;
197 vformat->Rmask = 0x0000001f;
198 vformat->BitsPerPixel = 16; /* SDL wants actual number of bits used */
199 vformat->BytesPerPixel = 2;
200 break;
201
202 case 24:
203 case 32:
204 vformat->Bmask = 0x00ff0000;
205 vformat->Gmask = 0x0000ff00;
206 vformat->Rmask = 0x000000ff;
207 vformat->BytesPerPixel = 4;
208 break;
209
210 default:
211 vformat->Bmask = 0;
212 vformat->Gmask = 0;
213 vformat->Rmask = 0;
214 vformat->BytesPerPixel = 1;
215 break;
216 }
217
218 /* Fill in some window manager capabilities */
219 this->info.wm_available = 1;
220
221 /* We're done! */
222 return(0);
223 }
224
225 /* Note: If we are terminated, this could be called in the middle of
226 another SDL video routine -- notably UpdateRects.
227 */
RISCOS_VideoQuit(_THIS)228 void RISCOS_VideoQuit(_THIS)
229 {
230 RISCOS_ExitTask();
231
232 if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank);
233 this->hidden->alloc_bank = 0;
234 }
235
236
RISCOS_ListModes(_THIS,SDL_PixelFormat * format,Uint32 flags)237 SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
238 {
239 if (flags & SDL_FULLSCREEN)
240 {
241 /* Build mode list when first required. */
242 if (SDL_nummodes[0] == 0) FULLSCREEN_BuildModeList(this);
243
244 return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
245 } else
246 return (SDL_Rect **)-1;
247 }
248
249
250 /* Set up video mode */
RISCOS_SetVideoMode(_THIS,SDL_Surface * current,int width,int height,int bpp,Uint32 flags)251 SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current,
252 int width, int height, int bpp, Uint32 flags)
253 {
254 if (flags & SDL_FULLSCREEN)
255 {
256 RISCOS_StoreWimpMode();
257 /* Dump wimp window on switch to full screen */
258 if (this->hidden->window_handle) WIMP_DeleteWindow(this);
259
260 return FULLSCREEN_SetVideoMode(this, current, width, height, bpp, flags);
261 } else
262 {
263 RISCOS_RestoreWimpMode();
264 return WIMP_SetVideoMode(this, current, width, height, bpp, flags);
265 }
266 }
267
268
269 /* We don't actually allow hardware surfaces other than the main one */
RISCOS_AllocHWSurface(_THIS,SDL_Surface * surface)270 static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface)
271 {
272 return(-1);
273 }
RISCOS_FreeHWSurface(_THIS,SDL_Surface * surface)274 static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface)
275 {
276 return;
277 }
278
279 /* We need to wait for vertical retrace on page flipped displays */
RISCOS_LockHWSurface(_THIS,SDL_Surface * surface)280 static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface)
281 {
282 return(0);
283 }
284
RISCOS_UnlockHWSurface(_THIS,SDL_Surface * surface)285 static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface)
286 {
287 return;
288 }
289
290
RISCOS_GetWmInfo(_THIS,SDL_SysWMinfo * info)291 int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info)
292 {
293 SDL_VERSION(&(info->version));
294 info->wimpVersion = RISCOS_GetWimpVersion();
295 info->taskHandle = RISCOS_GetTaskHandle();
296 info->window = this->hidden->window_handle;
297
298 return 1;
299 }
300 /* Toggle full screen mode.
301 Returns 1 if successful otherwise 0
302 */
303
RISCOS_ToggleFullScreen(_THIS,int fullscreen)304 int RISCOS_ToggleFullScreen(_THIS, int fullscreen)
305 {
306 if (fullscreen)
307 {
308 return FULLSCREEN_ToggleFromWimp(this);
309 } else
310 {
311 return WIMP_ToggleFromFullScreen(this);
312 }
313
314 return 0;
315 }
316
317