SDL-1.2.14
[sdl_omap.git] / src / video / riscos / SDL_riscosvideo.c
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2009 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
83 static int RISCOS_Available(void)
84 {
85         return(1);
86 }
87
88 static void RISCOS_DeleteDevice(SDL_VideoDevice *device)
89 {
90         SDL_free(device->hidden);
91         SDL_free(device);
92 }
93
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
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, &regs, &regs);
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 */
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
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 */
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 */
270 static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface)
271 {
272         return(-1);
273 }
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 */
280 static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface)
281 {
282         return(0);
283 }
284
285 static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface)
286 {
287         return;
288 }
289
290
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
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