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 (at) libsdl.org 21 */ 22 #include "SDL_config.h" 23 24 /* 25 File added by Alan Buckley (alan_baa (at) 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, ®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 */ 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 317