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