symbian-qemu-0.9.1-12/libsdl-trunk/src/video/riscos/SDL_riscostask.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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     This file added by Alan Buckley (alan_baa@hotmail.com) to support RISC OS 
       
    26 	26 March 2003
       
    27 
       
    28 	File includes routines for:
       
    29 	  Setting up as a WIMP Task
       
    30 	  Reading information about the current desktop
       
    31 	  Storing information before a switch to full screen
       
    32 	  Restoring desktop after switching to full screen
       
    33 */
       
    34 
       
    35 #include "kernel.h"
       
    36 #include "swis.h"
       
    37 
       
    38 #include "SDL_stdinc.h"
       
    39 #include "SDL_riscostask.h"
       
    40 
       
    41 #if !SDL_THREADS_DISABLED
       
    42 #include <pthread.h>
       
    43 pthread_t main_thread;
       
    44 #endif
       
    45 
       
    46 /* RISC OS variables */
       
    47 
       
    48 static int task_handle = 0;
       
    49 static int wimp_version = 0;
       
    50 
       
    51 /* RISC OS variables to help compatability with certain programs */
       
    52 int riscos_backbuffer = 0; /* Create a back buffer in system memory for full screen mode */
       
    53 int riscos_closeaction = 1; /* Close icon action */
       
    54 
       
    55 static int stored_mode = -1; /* -1 when in desktop, mode number or pointer when full screen */
       
    56 
       
    57 extern int mouseInWindow; /* Mouse is in WIMP window */
       
    58 
       
    59 /* Local function */
       
    60 
       
    61 static int RISCOS_GetTaskName(char *task_name, size_t maxlen);
       
    62 
       
    63 /* Uncomment next line to copy mode changes/restores to stderr */
       
    64 /* #define DUMP_MODE */
       
    65 #ifdef DUMP_MODE
       
    66 #include "stdio.h"
       
    67 static void dump_mode()
       
    68 {
       
    69     fprintf(stderr, "mode %d\n", stored_mode);
       
    70     if (stored_mode < -1 || stored_mode >= 256)
       
    71     {
       
    72         int blockSize = 0;
       
    73 		int *storeBlock = (int *)stored_mode;
       
    74 
       
    75         while(blockSize < 5 || storeBlock[blockSize] != -1)
       
    76         {
       
    77            fprintf(stderr, "   %d\n", storeBlock[blockSize++]);
       
    78         }
       
    79     }
       
    80 }
       
    81 #endif
       
    82 
       
    83 /******************************************************************
       
    84 
       
    85  Initialise as RISC OS Wimp task
       
    86 
       
    87 *******************************************************************/
       
    88 
       
    89 int RISCOS_InitTask()
       
    90 {
       
    91    char task_name[32];
       
    92    _kernel_swi_regs regs;
       
    93    int messages[4];
       
    94 
       
    95    if (RISCOS_GetTaskName(task_name, SDL_arraysize(task_name)) == 0) return 0;
       
    96 
       
    97    messages[0] = 9;       /* Palette changed */
       
    98    messages[1] = 0x400c1; /* Mode changed */
       
    99    messages[2] = 8;       /* Pre quit */
       
   100    messages[2] = 0;
       
   101    
       
   102 	regs.r[0] = (unsigned int)360; /* Minimum version 3.6 */
       
   103 	regs.r[1] = (unsigned int)0x4b534154;
       
   104 	regs.r[2] = (unsigned int)task_name;
       
   105 	regs.r[3] = (unsigned int)messages;
       
   106 
       
   107    if (_kernel_swi(Wimp_Initialise, &regs, &regs) == 0)
       
   108    {
       
   109 	   wimp_version = regs.r[0];
       
   110 	   task_handle = regs.r[1];
       
   111 	   return 1;
       
   112    }
       
   113 
       
   114 #if !SDL_THREADS_DISABLED
       
   115    main_thread = pthread_self();
       
   116 #endif
       
   117 
       
   118    return 0;
       
   119 }
       
   120 
       
   121 /*********************************************************************
       
   122 
       
   123   Close down application on exit.
       
   124 
       
   125 **********************************************************************/
       
   126 
       
   127 void RISCOS_ExitTask()
       
   128 {
       
   129 	_kernel_swi_regs regs;
       
   130 
       
   131     if (stored_mode == -1)
       
   132     {
       
   133        /* Ensure cursor is put back to standard pointer shape if
       
   134           we have been running in a window */
       
   135        _kernel_osbyte(106,1,0);
       
   136     }
       
   137 
       
   138 	/* Ensure we end up back in the wimp */
       
   139 	RISCOS_RestoreWimpMode();
       
   140 
       
   141 	/* Neatly exit the task */
       
   142    	regs.r[0] = task_handle;
       
   143    	regs.r[1] = (unsigned int)0x4b534154;
       
   144    	_kernel_swi(Wimp_CloseDown, &regs, &regs);
       
   145 	task_handle = 0;
       
   146 }
       
   147 
       
   148 /**************************************************************************
       
   149 
       
   150   Get the name of the task for the desktop.
       
   151 
       
   152   Param:   task_name - name of task 32 characters.
       
   153 
       
   154   Returns: 1 is successful, otherwise 0
       
   155 
       
   156   Notes:   Works by getting using OS_GetEnv to get the command line
       
   157 		   used to run the program and then parsing a name from it
       
   158 		   as follows.
       
   159 
       
   160 		   1. Use name after final period if not !RunImage
       
   161 		   2. If name is !RunImage then process item before the period
       
   162 		      in front of !RunImage.
       
   163 		   3. If directory name use that
       
   164 		   4. if in form <XXX$Dir> use the XXX.
       
   165 
       
   166 		   Finally once this value has been retrieved use it unless
       
   167 		   there is a variable set up in the form SDL$<name>$TaskName
       
   168 		   in which case the value of this variable will be used.
       
   169 
       
   170 		   Now also gets other RISC OS configuration varibles
       
   171                 SDL$<name>$BackBuffer - set to 1 to use a system memory backbuffer in fullscreen mode
       
   172 						    so updates wait until a call to SDL_UpdateRects. (default 0)
       
   173 						    This is required for programmes where they have assumed this is
       
   174 						    always the case which is contrary to the documentation.
       
   175                SDL$<name>$CloseAction
       
   176                     0 Don't show close icon
       
   177                     1 Show close icon
       
   178 
       
   179 ***************************************************************************/
       
   180 
       
   181 int RISCOS_GetTaskName(char *task_name, size_t maxlen)
       
   182 {
       
   183 	_kernel_swi_regs regs;
       
   184 
       
   185    task_name[0] = 0;
       
   186 
       
   187    /* Figure out a sensible task name */
       
   188    if (_kernel_swi(OS_GetEnv, &regs, &regs) == 0)
       
   189    {
       
   190 	   char *command_line = (char *)regs.r[0];
       
   191 	   size_t len = SDL_strlen(command_line)+1;
       
   192 	   char *buffer = SDL_stack_alloc(char, len);
       
   193 	   char *env_var;
       
   194 	   char *p;
       
   195 
       
   196 	   SDL_strlcpy(buffer, command_line, len);
       
   197 	   p = SDL_strchr(buffer, ' ');
       
   198 	   if (p) *p = 0;
       
   199 	   p = SDL_strrchr(buffer, '.');
       
   200 	   if (p == 0) p = buffer;
       
   201 	   if (stricmp(p+1,"!RunImage") == 0)
       
   202 	   {
       
   203 		   *p = 0;
       
   204 	   	   p = SDL_strrchr(buffer, '.');
       
   205 		   if (p == 0) p = buffer;
       
   206 	   }
       
   207 	   if (*p == '.') p++;
       
   208 	   if (*p == '!') p++; /* Skip "!" at beginning of application directories */
       
   209 
       
   210        if (*p == '<')
       
   211        {
       
   212           // Probably in the form <appname$Dir>
       
   213           char *q = SDL_strchr(p, '$');
       
   214           if (q == 0) q = SDL_strchr(p,'>'); /* Use variable name if not */
       
   215           if (q) *q = 0;
       
   216           p++; /* Move over the < */
       
   217        }
       
   218 
       
   219 	   if (*p)
       
   220 	   {
       
   221 		   /* Read variables that effect the RISC OS SDL engine for this task */
       
   222 		   len = SDL_strlen(p) + 18; /* 18 is larger than the biggest variable name */
       
   223 		   env_var = SDL_stack_alloc(char, len);
       
   224 		   if (env_var)
       
   225 		   {
       
   226 			   char *env_val;
       
   227 
       
   228 			   /* See if a variable of form SDL$<dirname>$TaskName exists */
       
   229 
       
   230 			   SDL_strlcpy(env_var, "SDL$", len);
       
   231 			   SDL_strlcat(env_var, p, len);
       
   232 			   SDL_strlcat(env_var, "$TaskName", len);
       
   233 
       
   234 			   env_val = SDL_getenv(env_var);
       
   235 			   if (env_val) SDL_strlcpy(task_name, env_val, maxlen);
       
   236 
       
   237 			   SDL_strlcpy(env_var, "SDL$", len);
       
   238 			   SDL_strlcat(env_var, p, len);
       
   239 			   SDL_strlcat(env_var, "$BackBuffer", len);
       
   240 
       
   241 			   env_val = SDL_getenv(env_var);
       
   242 			   if (env_val) riscos_backbuffer = atoi(env_val);
       
   243 
       
   244 			   SDL_strlcpy(env_var, "SDL$", len);
       
   245 			   SDL_strlcat(env_var, p, len);
       
   246 			   SDL_strlcat(env_var, "$CloseAction", len);
       
   247 
       
   248 			   env_val = SDL_getenv(env_var);
       
   249 			   if (env_val && SDL_strcmp(env_val,"0") == 0) riscos_closeaction = 0;
       
   250 
       
   251 			   SDL_stack_free(env_var);
       
   252 		   }
       
   253 		   
       
   254 		   if (!*task_name) SDL_strlcpy(task_name, p, maxlen);
       
   255 	   }
       
   256 
       
   257 	   SDL_stack_free(buffer);
       
   258    }
       
   259 
       
   260    if (task_name[0] == 0) SDL_strlcpy(task_name, "SDL Task", maxlen);
       
   261 
       
   262    return 1;
       
   263 }
       
   264 
       
   265 /*****************************************************************
       
   266 
       
   267   Store the current desktop screen mode if we are in the desktop.
       
   268 
       
   269 ******************************************************************/
       
   270 
       
   271 void RISCOS_StoreWimpMode()
       
   272 {
       
   273      _kernel_swi_regs regs;
       
   274 
       
   275 	/* Don't store if in full screen mode */
       
   276 	if (stored_mode != -1) return;
       
   277 
       
   278     regs.r[0] = 1;
       
   279     _kernel_swi(OS_ScreenMode, &regs, &regs);
       
   280     if (regs.r[1] >= 0 && regs.r[1] < 256) stored_mode = regs.r[1];
       
   281     else
       
   282     {
       
   283         int blockSize = 0;
       
   284         int *retBlock = (int *)regs.r[1];
       
   285 		int *storeBlock;
       
   286         int j;
       
   287 
       
   288         while(blockSize < 5 || retBlock[blockSize] != -1) blockSize++;
       
   289         blockSize++;
       
   290         storeBlock = (int *)SDL_malloc(blockSize * sizeof(int));
       
   291         retBlock = (int *)regs.r[1];
       
   292         for ( j = 0; j < blockSize; j++)
       
   293            storeBlock[j] = retBlock[j];
       
   294 
       
   295 		stored_mode = (int)storeBlock;
       
   296      }
       
   297 #if DUMP_MODE
       
   298     fprintf(stderr, "Stored "); dump_mode();
       
   299 #endif
       
   300 }
       
   301 
       
   302 /*****************************************************************
       
   303 
       
   304   Restore desktop screen mode if we are in full screen mode.
       
   305 
       
   306 *****************************************************************/
       
   307 
       
   308 void RISCOS_RestoreWimpMode()
       
   309 {
       
   310     _kernel_swi_regs regs;
       
   311 
       
   312 	/* Only need to restore if we are in full screen mode */
       
   313 	if (stored_mode == -1) return;
       
   314 
       
   315 #if DUMP_MODE
       
   316    fprintf(stderr, "Restored"); dump_mode();
       
   317 #endif
       
   318 
       
   319     regs.r[0] = stored_mode;
       
   320     _kernel_swi(Wimp_SetMode, &regs, &regs);
       
   321     if (stored_mode < 0 || stored_mode > 256)
       
   322     {
       
   323        SDL_free((int *)stored_mode);
       
   324     }
       
   325     stored_mode = -1;
       
   326 
       
   327     /* Flush keyboard buffer to dump the keystrokes we've already polled */
       
   328     regs.r[0] = 21;
       
   329     regs.r[1] = 0; /* Keyboard buffer number */
       
   330     _kernel_swi(OS_Byte, &regs, &regs);
       
   331 
       
   332     mouseInWindow = 0;
       
   333 
       
   334 }
       
   335 
       
   336 /*********************************************************************
       
   337 
       
   338   Get version of Wimp running when task was initialised.
       
   339 
       
   340 *********************************************************************/
       
   341 
       
   342 int RISCOS_GetWimpVersion()
       
   343 {
       
   344 	return wimp_version;
       
   345 }
       
   346 
       
   347 int RISCOS_GetTaskHandle()
       
   348 {
       
   349 	return task_handle;
       
   350 }