src/video/riscos/SDL_riscostask.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 29 May 2006 04:04:35 +0000
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
permissions -rw-r--r--
more tweaking indent options
     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
    68 dump_mode()
    69 {
    70     fprintf(stderr, "mode %d\n", stored_mode);
    71     if (stored_mode < -1 || stored_mode >= 256) {
    72         int blockSize = 0;
    73         int *storeBlock = (int *) stored_mode;
    74 
    75         while (blockSize < 5 || storeBlock[blockSize] != -1) {
    76             fprintf(stderr, "   %d\n", storeBlock[blockSize++]);
    77         }
    78     }
    79 }
    80 #endif
    81 
    82 /******************************************************************
    83 
    84  Initialise as RISC OS Wimp task
    85 
    86 *******************************************************************/
    87 
    88 int
    89 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)
    96         return 0;
    97 
    98     messages[0] = 9;            /* Palette changed */
    99     messages[1] = 0x400c1;      /* Mode changed */
   100     messages[2] = 8;            /* Pre quit */
   101     messages[2] = 0;
   102 
   103     regs.r[0] = (unsigned int) 360;     /* Minimum version 3.6 */
   104     regs.r[1] = (unsigned int) 0x4b534154;
   105     regs.r[2] = (unsigned int) task_name;
   106     regs.r[3] = (unsigned int) messages;
   107 
   108     if (_kernel_swi(Wimp_Initialise, &regs, &regs) == 0) {
   109         wimp_version = regs.r[0];
   110         task_handle = regs.r[1];
   111         return 1;
   112     }
   113 #if !SDL_THREADS_DISABLED
   114     main_thread = pthread_self();
   115 #endif
   116 
   117     return 0;
   118 }
   119 
   120 /*********************************************************************
   121 
   122   Close down application on exit.
   123 
   124 **********************************************************************/
   125 
   126 void
   127 RISCOS_ExitTask()
   128 {
   129     _kernel_swi_regs regs;
   130 
   131     if (stored_mode == -1) {
   132         /* Ensure cursor is put back to standard pointer shape if
   133            we have been running in a window */
   134         _kernel_osbyte(106, 1, 0);
   135     }
   136 
   137     /* Ensure we end up back in the wimp */
   138     RISCOS_RestoreWimpMode();
   139 
   140     /* Neatly exit the task */
   141     regs.r[0] = task_handle;
   142     regs.r[1] = (unsigned int) 0x4b534154;
   143     _kernel_swi(Wimp_CloseDown, &regs, &regs);
   144     task_handle = 0;
   145 }
   146 
   147 /**************************************************************************
   148 
   149   Get the name of the task for the desktop.
   150 
   151   Param:   task_name - name of task 32 characters.
   152 
   153   Returns: 1 is successful, otherwise 0
   154 
   155   Notes:   Works by getting using OS_GetEnv to get the command line
   156 		   used to run the program and then parsing a name from it
   157 		   as follows.
   158 
   159 		   1. Use name after final period if not !RunImage
   160 		   2. If name is !RunImage then process item before the period
   161 		      in front of !RunImage.
   162 		   3. If directory name use that
   163 		   4. if in form <XXX$Dir> use the XXX.
   164 
   165 		   Finally once this value has been retrieved use it unless
   166 		   there is a variable set up in the form SDL$<name>$TaskName
   167 		   in which case the value of this variable will be used.
   168 
   169 		   Now also gets other RISC OS configuration varibles
   170                 SDL$<name>$BackBuffer - set to 1 to use a system memory backbuffer in fullscreen mode
   171 						    so updates wait until a call to SDL_UpdateRects. (default 0)
   172 						    This is required for programmes where they have assumed this is
   173 						    always the case which is contrary to the documentation.
   174                SDL$<name>$CloseAction
   175                     0 Don't show close icon
   176                     1 Show close icon
   177 
   178 ***************************************************************************/
   179 
   180 int
   181 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         char *command_line = (char *) regs.r[0];
   190         size_t len = SDL_strlen(command_line) + 1;
   191         char *buffer = SDL_stack_alloc(char, len);
   192         char *env_var;
   193         char *p;
   194 
   195         SDL_strlcpy(buffer, command_line, len);
   196         p = SDL_strchr(buffer, ' ');
   197         if (p)
   198             *p = 0;
   199         p = SDL_strrchr(buffer, '.');
   200         if (p == 0)
   201             p = buffer;
   202         if (stricmp(p + 1, "!RunImage") == 0) {
   203             *p = 0;
   204             p = SDL_strrchr(buffer, '.');
   205             if (p == 0)
   206                 p = buffer;
   207         }
   208         if (*p == '.')
   209             p++;
   210         if (*p == '!')
   211             p++;                /* Skip "!" at beginning of application directories */
   212 
   213         if (*p == '<') {
   214             // Probably in the form <appname$Dir>
   215             char *q = SDL_strchr(p, '$');
   216             if (q == 0)
   217                 q = SDL_strchr(p, '>'); /* Use variable name if not */
   218             if (q)
   219                 *q = 0;
   220             p++;                /* Move over the < */
   221         }
   222 
   223         if (*p) {
   224             /* Read variables that effect the RISC OS SDL engine for this task */
   225             len = SDL_strlen(p) + 18;   /* 18 is larger than the biggest variable name */
   226             env_var = SDL_stack_alloc(char, len);
   227             if (env_var) {
   228                 char *env_val;
   229 
   230                 /* See if a variable of form SDL$<dirname>$TaskName exists */
   231 
   232                 SDL_strlcpy(env_var, "SDL$", len);
   233                 SDL_strlcat(env_var, p, len);
   234                 SDL_strlcat(env_var, "$TaskName", len);
   235 
   236                 env_val = SDL_getenv(env_var);
   237                 if (env_val)
   238                     SDL_strlcpy(task_name, env_val, maxlen);
   239 
   240                 SDL_strlcpy(env_var, "SDL$", len);
   241                 SDL_strlcat(env_var, p, len);
   242                 SDL_strlcat(env_var, "$BackBuffer", len);
   243 
   244                 env_val = SDL_getenv(env_var);
   245                 if (env_val)
   246                     riscos_backbuffer = atoi(env_val);
   247 
   248                 SDL_strlcpy(env_var, "SDL$", len);
   249                 SDL_strlcat(env_var, p, len);
   250                 SDL_strlcat(env_var, "$CloseAction", len);
   251 
   252                 env_val = SDL_getenv(env_var);
   253                 if (env_val && SDL_strcmp(env_val, "0") == 0)
   254                     riscos_closeaction = 0;
   255 
   256                 SDL_stack_free(env_var);
   257             }
   258 
   259             if (!*task_name)
   260                 SDL_strlcpy(task_name, p, maxlen);
   261         }
   262 
   263         SDL_stack_free(buffer);
   264     }
   265 
   266     if (task_name[0] == 0)
   267         SDL_strlcpy(task_name, "SDL Task", maxlen);
   268 
   269     return 1;
   270 }
   271 
   272 /*****************************************************************
   273 
   274   Store the current desktop screen mode if we are in the desktop.
   275 
   276 ******************************************************************/
   277 
   278 void
   279 RISCOS_StoreWimpMode()
   280 {
   281     _kernel_swi_regs regs;
   282 
   283     /* Don't store if in full screen mode */
   284     if (stored_mode != -1)
   285         return;
   286 
   287     regs.r[0] = 1;
   288     _kernel_swi(OS_ScreenMode, &regs, &regs);
   289     if (regs.r[1] >= 0 && regs.r[1] < 256)
   290         stored_mode = regs.r[1];
   291     else {
   292         int blockSize = 0;
   293         int *retBlock = (int *) regs.r[1];
   294         int *storeBlock;
   295         int j;
   296 
   297         while (blockSize < 5 || retBlock[blockSize] != -1)
   298             blockSize++;
   299         blockSize++;
   300         storeBlock = (int *) SDL_malloc(blockSize * sizeof(int));
   301         retBlock = (int *) regs.r[1];
   302         for (j = 0; j < blockSize; j++)
   303             storeBlock[j] = retBlock[j];
   304 
   305         stored_mode = (int) storeBlock;
   306     }
   307 #if DUMP_MODE
   308     fprintf(stderr, "Stored ");
   309     dump_mode();
   310 #endif
   311 }
   312 
   313 /*****************************************************************
   314 
   315   Restore desktop screen mode if we are in full screen mode.
   316 
   317 *****************************************************************/
   318 
   319 void
   320 RISCOS_RestoreWimpMode()
   321 {
   322     _kernel_swi_regs regs;
   323 
   324     /* Only need to restore if we are in full screen mode */
   325     if (stored_mode == -1)
   326         return;
   327 
   328 #if DUMP_MODE
   329     fprintf(stderr, "Restored");
   330     dump_mode();
   331 #endif
   332 
   333     regs.r[0] = stored_mode;
   334     _kernel_swi(Wimp_SetMode, &regs, &regs);
   335     if (stored_mode < 0 || stored_mode > 256) {
   336         SDL_free((int *) stored_mode);
   337     }
   338     stored_mode = -1;
   339 
   340     /* Flush keyboard buffer to dump the keystrokes we've already polled */
   341     regs.r[0] = 21;
   342     regs.r[1] = 0;              /* Keyboard buffer number */
   343     _kernel_swi(OS_Byte, &regs, &regs);
   344 
   345     mouseInWindow = 0;
   346 
   347 }
   348 
   349 /*********************************************************************
   350 
   351   Get version of Wimp running when task was initialised.
   352 
   353 *********************************************************************/
   354 
   355 int
   356 RISCOS_GetWimpVersion()
   357 {
   358     return wimp_version;
   359 }
   360 
   361 int
   362 RISCOS_GetTaskHandle()
   363 {
   364     return task_handle;
   365 }
   366 
   367 /* vi: set ts=4 sw=4 expandtab: */