src/video/riscos/SDL_riscostask.c
author Ozkan Sezer <sezeroz@gmail.com>
Sat, 14 Sep 2019 17:00:50 +0300
branchSDL-1.2
changeset 13077 cd46eb772bee
parent 13055 2641390846e1
permissions -rw-r--r--
make SDL_qsort.c to actually link (missing SDL_stdinc.h include)

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