src/video/riscos/SDL_riscosmouse.c
author Cameron Cawley <ccawley2011@gmail.com>
Tue, 18 Jun 2019 23:55:01 +0100
branchSDL-1.2
changeset 12913 d07b4feae69c
parent 12786 4e73be7b4787
permissions -rw-r--r--
riscos: Improve error reporting
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
     File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
slouken@630
    26
	 27 March 2003
slouken@630
    27
slouken@630
    28
     Implements mouse cursor shape definitions and positioning
slouken@630
    29
*/
slouken@630
    30
slouken@630
    31
#include "SDL_mouse.h"
slouken@1361
    32
#include "../../events/SDL_events_c.h"
slouken@630
    33
slouken@630
    34
#include "SDL_riscosmouse_c.h"
slouken@630
    35
slouken@630
    36
#include "kernel.h"
slouken@630
    37
#include "swis.h"
slouken@630
    38
slouken@630
    39
static WMcursor *current_cursor = NULL;
slouken@1208
    40
static WMcursor *defined_cursor = NULL;
slouken@630
    41
slouken@1208
    42
/* Area to save cursor palette colours changed by SDL.
slouken@1208
    43
   Actual values will be read before we change to the SDL cursor */
slouken@1208
    44
static Uint8 wimp_cursor_palette[2][5] = {
slouken@1208
    45
  {1, 25, 255, 255, 255},
slouken@1208
    46
  {3, 25, 255, 255, 255}
slouken@1208
    47
};
slouken@1208
    48
slouken@1208
    49
static int cursor_palette_saved = 0;
slouken@1208
    50
me@12786
    51
static void WIMP_SaveCursorPalette();
me@12786
    52
static void WIMP_SetSDLCursorPalette();
slouken@1208
    53
slouken@1208
    54
slouken@630
    55
void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor)
slouken@630
    56
{
slouken@1336
    57
    SDL_free(cursor->data);
slouken@1336
    58
	SDL_free(cursor);
slouken@630
    59
}
slouken@630
    60
slouken@630
    61
WMcursor *RISCOS_CreateWMCursor(_THIS,
slouken@630
    62
		Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
slouken@630
    63
{
slouken@630
    64
	WMcursor *cursor;
slouken@630
    65
	Uint8 *cursor_data;
slouken@630
    66
	Uint8 *ptr;
slouken@630
    67
	int i,j,k;
slouken@630
    68
	int data_byte, mask_byte;
slouken@630
    69
slouken@630
    70
	/* Check to make sure the cursor size is okay */
slouken@630
    71
	if ( (w > 32) || (h > 32) ) {
ccawley2011@12913
    72
		SDL_SetError("Only cursors with width and height <= 32 pixels are allowed");
slouken@630
    73
		return(NULL);
slouken@630
    74
	}
slouken@630
    75
slouken@630
    76
	/* Allocate the cursor */
slouken@1336
    77
	cursor = (WMcursor *)SDL_malloc(sizeof(*cursor));
slouken@630
    78
	if ( cursor == NULL ) {
ccawley2011@12913
    79
		SDL_OutOfMemory();
slouken@630
    80
		return(NULL);
slouken@630
    81
	}
slouken@630
    82
slouken@630
    83
	/* Note: SDL says width must be a multiple of 8 */
slouken@1336
    84
	cursor_data = SDL_malloc(w/4 * h);
slouken@630
    85
	if (cursor_data == NULL)
slouken@630
    86
	{
slouken@1336
    87
		SDL_free(cursor);
ccawley2011@12913
    88
		SDL_OutOfMemory();
slouken@630
    89
		return(NULL);
slouken@630
    90
	}
slouken@630
    91
slouken@630
    92
	cursor->w = w;
slouken@630
    93
	cursor->h = h;
slouken@630
    94
	cursor->hot_x = hot_x;
slouken@630
    95
	cursor->hot_y = hot_y;
slouken@630
    96
	cursor->data = cursor_data;
slouken@630
    97
slouken@630
    98
slouken@630
    99
/* Data / Mask Resulting pixel on screen 
slouken@630
   100
   0 / 1 White 
slouken@630
   101
   1 / 1 Black 
slouken@630
   102
   0 / 0 Transparent 
slouken@630
   103
   1 / 0 Inverted color if possible, black if not. 
slouken@630
   104
*/
slouken@630
   105
	ptr = cursor_data;
slouken@630
   106
slouken@630
   107
	for ( i=0; i<h; ++i )
slouken@630
   108
	{
slouken@630
   109
		for (j = 0; j < w/8; ++j)
slouken@630
   110
		{
slouken@630
   111
			data_byte = *data;
slouken@630
   112
			mask_byte = *mask;
slouken@630
   113
			*ptr++ = 0; /* Sets whole byte transparent */
slouken@630
   114
			*ptr = 0;
slouken@630
   115
			for (k = 0; k < 8; k++)
slouken@630
   116
			{
slouken@630
   117
				(*ptr) <<= 2;
slouken@630
   118
				if (data_byte & 1) *ptr |= 3; /* Black or inverted */
slouken@630
   119
				else if(mask_byte & 1) *ptr |= 1; /* White */
slouken@630
   120
				if ((k&3) == 3) ptr--;
slouken@630
   121
				data_byte >>= 1;
slouken@630
   122
				mask_byte >>= 1;
slouken@630
   123
			}
slouken@630
   124
slouken@630
   125
            ptr+=3;
slouken@630
   126
		    data++;
slouken@630
   127
		    mask++;
slouken@630
   128
		}
slouken@630
   129
	}
slouken@630
   130
slouken@630
   131
	return(cursor);
slouken@630
   132
}
slouken@630
   133
slouken@630
   134
int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor)
slouken@630
   135
{
slouken@1208
   136
	current_cursor = cursor;
slouken@1208
   137
slouken@630
   138
	if (cursor == NULL)
slouken@630
   139
	{
slouken@630
   140
		_kernel_osbyte(106,0,0);
slouken@1208
   141
		defined_cursor = NULL;
slouken@630
   142
	} else
slouken@630
   143
	{
slouken@1208
   144
        WMcursor *old_cursor = defined_cursor;
slouken@630
   145
slouken@1208
   146
		if (cursor != defined_cursor)
slouken@630
   147
		{
slouken@630
   148
			Uint8 cursor_def[10];
slouken@630
   149
slouken@630
   150
			cursor_def[0] = 0;
slouken@630
   151
			cursor_def[1] = 2; /* Use shape number 2 */
slouken@630
   152
			cursor_def[2] = cursor->w/4; /* Width in bytes */
slouken@630
   153
			cursor_def[3] = cursor->h; /* Height (h) in pixels */
slouken@630
   154
			cursor_def[4] = cursor->hot_x; /* ActiveX in pixels from left */
slouken@630
   155
			cursor_def[5] = cursor->hot_y; /* ActiveY in pixels from top */
slouken@630
   156
			cursor_def[6] = ((int)(cursor->data) & 0xFF);       /* Least significant byte of pointer to data */
slouken@630
   157
			cursor_def[7] = ((int)(cursor->data) >> 8) & 0xFF;  /* ... */
slouken@630
   158
			cursor_def[8] = ((int)(cursor->data) >> 16) & 0xFF; /* ... */
slouken@630
   159
			cursor_def[9] = ((int)(cursor->data) >> 24) & 0xFF; /* Most significant byte of pointer to data */
slouken@630
   160
slouken@1208
   161
			if (_kernel_osword(21, (int *)cursor_def) != 0)
slouken@630
   162
			{
ccawley2011@12913
   163
				SDL_SetError("RISC OS couldn't create the cursor to show");
slouken@630
   164
				return(0);
slouken@630
   165
			}
slouken@1208
   166
			defined_cursor = cursor;
slouken@630
   167
		}
slouken@630
   168
slouken@1208
   169
        if (old_cursor == NULL)
slouken@1208
   170
        {
slouken@1208
   171
            /* First time or reshow in window, so save/setup palette */
slouken@1208
   172
            if (!cursor_palette_saved)
slouken@1208
   173
            {
slouken@1208
   174
                WIMP_SaveCursorPalette();
slouken@1208
   175
            }
slouken@1208
   176
            WIMP_SetSDLCursorPalette();
slouken@1208
   177
        }
slouken@1208
   178
slouken@1208
   179
        _kernel_osbyte(106, 2, 0);        
slouken@630
   180
	}
slouken@630
   181
	
slouken@630
   182
	return(1);
slouken@630
   183
}
slouken@630
   184
slouken@630
   185
void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
slouken@630
   186
{
slouken@630
   187
	Uint8 move_block[5];
slouken@630
   188
	int os_x, os_y;
me@12783
   189
	int topLeftY;
slouken@630
   190
me@12783
   191
	topLeftY = (this->hidden->height << this->hidden->yeig) - 1; /* As per RISCOS_PollMouseHelper */
slouken@630
   192
me@12783
   193
	os_x = x << this->hidden->xeig;
me@12783
   194
	os_y = topLeftY - (y << this->hidden->yeig);
slouken@630
   195
slouken@630
   196
	move_block[0] = 3; /* Move cursor */
slouken@630
   197
	move_block[1] = os_x & 0xFF;
slouken@630
   198
	move_block[2] = (os_x >> 8) & 0xFF;
slouken@630
   199
	move_block[3] = os_y & 0xFF;
slouken@630
   200
	move_block[4] = (os_y >> 8) & 0xFF;
slouken@630
   201
slouken@630
   202
	_kernel_osword(21, (int *)move_block);
slouken@630
   203
	SDL_PrivateMouseMotion(0, 0, x, y);
slouken@630
   204
}
slouken@630
   205
slouken@630
   206
slouken@630
   207
/* Reshow cursor when mouse re-enters the window */
slouken@630
   208
void WIMP_ReshowCursor(_THIS)
slouken@630
   209
{
slouken@1208
   210
	defined_cursor = NULL;
slouken@1208
   211
    cursor_palette_saved = 0;
slouken@1208
   212
	RISCOS_ShowWMCursor(this, current_cursor);
slouken@630
   213
}
slouken@630
   214
slouken@630
   215
void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
slouken@630
   216
{
slouken@630
   217
	_kernel_swi_regs regs;
slouken@630
   218
	int window_state[9];
slouken@630
   219
	char block[5];
slouken@630
   220
	int osX, osY;
slouken@630
   221
slouken@630
   222
	window_state[0] = this->hidden->window_handle;
slouken@630
   223
	regs.r[1] = (unsigned int)window_state;
slouken@630
   224
	_kernel_swi(Wimp_GetWindowState, &regs, &regs);
slouken@630
   225
me@12783
   226
	/* 90 DPI mapping from SDL pixels to OS units */
me@12782
   227
	 osX = (x << 1) + window_state[1];
me@12782
   228
	 osY = window_state[4] - (y << 1);
slouken@630
   229
slouken@630
   230
	block[0] = 3;
slouken@630
   231
	block[1] = osX & 0xFF;
slouken@630
   232
	block[2] = (osX >> 8) & 0xFF;
slouken@630
   233
	block[3] = osY & 0xFF;
slouken@630
   234
	block[4] = (osY >> 8) & 0xFF;
slouken@630
   235
ccawley2011@12778
   236
	_kernel_osword(21, (int *)block);
slouken@630
   237
	SDL_PrivateMouseMotion(0, 0, x, y);
slouken@630
   238
}
slouken@630
   239
slouken@630
   240
int WIMP_ShowWMCursor(_THIS, WMcursor *cursor)
slouken@630
   241
{
slouken@630
   242
	if (mouseInWindow) return RISCOS_ShowWMCursor(this, cursor);
slouken@1208
   243
	else current_cursor = cursor;
slouken@1208
   244
slouken@630
   245
	return 1;
slouken@630
   246
}
slouken@630
   247
slouken@630
   248
SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode)
slouken@630
   249
{
slouken@630
   250
   /* In fullscreen mode we don't need to do anything */
slouken@630
   251
   if (mode < SDL_GRAB_FULLSCREEN)
slouken@630
   252
   {
slouken@630
   253
      _kernel_swi_regs regs;
slouken@630
   254
      unsigned char block[9];
slouken@630
   255
      block[0] = 1; /* Define mouse cursor bounding block */
slouken@630
   256
slouken@630
   257
      if ( mode == SDL_GRAB_OFF )
slouken@630
   258
      {
slouken@630
   259
         /* Clip to whole screen */
slouken@630
   260
slouken@630
   261
         int r = (this->hidden->screen_width << this->hidden->xeig) - 1;
slouken@630
   262
         int t = (this->hidden->screen_height << this->hidden->yeig) - 1;
slouken@630
   263
slouken@630
   264
	 block[1] = 0; block[2] = 0; /* Left*/
slouken@630
   265
         block[3] = 0; block[4] = 0; /* Bottom */
slouken@630
   266
         block[5] = r & 0xFF; block[6] = (r >> 8) & 0xFF; /* Right */
slouken@630
   267
         block[7] = t & 0xFF; block[8] = (t >> 8) & 0xFF; /* Top */
slouken@630
   268
      } else
slouken@630
   269
      {
slouken@630
   270
        /* Clip to window */
slouken@630
   271
       	unsigned char window_state[36];
slouken@630
   272
slouken@630
   273
	*((int *)window_state) = this->hidden->window_handle;
slouken@630
   274
	regs.r[1] = (unsigned int)window_state;
slouken@630
   275
	_kernel_swi(Wimp_GetWindowState, &regs, &regs);
slouken@630
   276
slouken@630
   277
        block[1] = window_state[4];
slouken@630
   278
        block[2] = window_state[5];
slouken@630
   279
        block[3] = window_state[8];
slouken@630
   280
        block[4] = window_state[9];
slouken@630
   281
        block[5] = window_state[12];
slouken@630
   282
        block[6] = window_state[13];
slouken@630
   283
        block[7] = window_state[16];
slouken@630
   284
        block[8] = window_state[17];
slouken@630
   285
slouken@630
   286
      }
slouken@630
   287
ccawley2011@12778
   288
      _kernel_osword(21, (int *)block);
slouken@630
   289
   }
slouken@630
   290
slouken@630
   291
   return mode;
slouken@630
   292
}
slouken@1208
   293
slouken@1208
   294
/* Save mouse cursor palette to be restore when we are no longer
slouken@1208
   295
   defining a cursor */
slouken@1208
   296
slouken@1208
   297
void WIMP_SaveCursorPalette()
slouken@1208
   298
{
slouken@1208
   299
    _kernel_swi_regs regs;
slouken@1208
   300
    int colour;
slouken@1208
   301
slouken@1208
   302
    for (colour = 0; colour < 2; colour++)
slouken@1208
   303
    {
slouken@1208
   304
      regs.r[0] = (int)wimp_cursor_palette[colour][0];
slouken@1208
   305
      regs.r[1] = 25;
slouken@1208
   306
      /* Read settings with OS_ReadPalette */
ccawley2011@12778
   307
      if (_kernel_swi(OS_ReadPalette, &regs, &regs) == NULL)
slouken@1208
   308
      {
slouken@1208
   309
        wimp_cursor_palette[colour][2] = (unsigned char)((regs.r[2] >> 8) & 0xFF);
slouken@1208
   310
        wimp_cursor_palette[colour][3] = (unsigned char)((regs.r[2] >> 16) & 0xFF);
slouken@1208
   311
        wimp_cursor_palette[colour][4] = (unsigned char)((regs.r[2] >> 24) & 0xFF);
slouken@1208
   312
      }
slouken@1208
   313
    }
slouken@1208
   314
slouken@1208
   315
    cursor_palette_saved = 1;
slouken@1208
   316
}
slouken@1208
   317
slouken@1208
   318
/* Restore the WIMP's cursor when we leave the SDL window */
slouken@1208
   319
void WIMP_RestoreWimpCursor()
slouken@1208
   320
{
slouken@1208
   321
    int colour;
slouken@1208
   322
slouken@1208
   323
    /* Reset to pointer shape 1 */
slouken@1208
   324
    _kernel_osbyte(106, 1, 0);
slouken@1208
   325
slouken@1208
   326
    /* Reset pointer colours */
slouken@1208
   327
    if (cursor_palette_saved)
slouken@1208
   328
    {
slouken@1208
   329
      for (colour = 0; colour < 2; colour++)
slouken@1208
   330
      {
slouken@1208
   331
        _kernel_osword(12, (int *)wimp_cursor_palette[colour]);
slouken@1208
   332
      }
slouken@1208
   333
    }
slouken@1208
   334
    cursor_palette_saved = 0;
slouken@1208
   335
}
slouken@1208
   336
slouken@1208
   337
/* Set palette used for SDL mouse cursors */
slouken@1208
   338
void WIMP_SetSDLCursorPalette()
slouken@1208
   339
{
slouken@1208
   340
  /* First time set up the mouse colours */
slouken@1208
   341
  Uint8 block[5];
slouken@1208
   342
slouken@1208
   343
  /* Set up colour 1 as white */
slouken@1208
   344
  block[0] = 1;   /* Colour to change 1 - 3 */
slouken@1208
   345
  block[1] = 25;  /* Set pointer colour */
slouken@1208
   346
  block[2] = 255; /* red component*/
slouken@1208
   347
  block[3] = 255; /* green component */
slouken@1208
   348
  block[4] = 255; /* blue component*/
slouken@1208
   349
 _kernel_osword(12, (int *)block);
slouken@1208
   350
		
slouken@1208
   351
 /* Set colour 3 to back */
slouken@1208
   352
 block[0] = 3;   /* Colour to change 1 - 3 */
slouken@1208
   353
 block[1] = 25;  /* Set pointer colour*/
slouken@1208
   354
 block[2] = 0; /* red component*/
slouken@1208
   355
 block[3] = 0; /* green component */
slouken@1208
   356
 block[4] = 0; /* blue component*/
slouken@1208
   357
 _kernel_osword(12, (int *)block);
slouken@1208
   358
}