src/video/riscos/SDL_riscosmouse.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 05 Nov 2003 23:11:05 +0000
changeset 733 9557ac1857a3
parent 630 550bccdf04bd
child 769 b8d311d90021
permissions -rw-r--r--
Date: Mon, 13 Oct 2003 13:37:18 +0100
From: "alan buckley"
Subject: Modification for RISC OS SDL port (SDL_riscosevents.c)

This modification improves the key press to Unicode character translation.
slouken@630
     1
/*
slouken@630
     2
    SDL - Simple DirectMedia Layer
slouken@630
     3
    Copyright (C) 1997, 1998, 1999, 2000, 2001  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@630
    20
    slouken@devolution.com
slouken@630
    21
*/
slouken@630
    22
slouken@630
    23
/*
slouken@630
    24
     File added by Alan Buckley (alan_baa@hotmail.com) for RISCOS compatability
slouken@630
    25
	 27 March 2003
slouken@630
    26
slouken@630
    27
     Implements mouse cursor shape definitions and positioning
slouken@630
    28
*/
slouken@630
    29
slouken@630
    30
#include <stdio.h>
slouken@630
    31
#include <stdlib.h>
slouken@630
    32
slouken@630
    33
#include "SDL_error.h"
slouken@630
    34
#include "SDL_mouse.h"
slouken@630
    35
#include "SDL_events_c.h"
slouken@630
    36
slouken@630
    37
#include "SDL_riscosmouse_c.h"
slouken@630
    38
slouken@630
    39
#include "kernel.h"
slouken@630
    40
#include "swis.h"
slouken@630
    41
slouken@630
    42
static WMcursor *current_cursor = NULL;
slouken@630
    43
slouken@630
    44
extern int mouseInWindow;
slouken@630
    45
slouken@630
    46
void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor)
slouken@630
    47
{
slouken@630
    48
    free(cursor->data);
slouken@630
    49
	free(cursor);
slouken@630
    50
}
slouken@630
    51
slouken@630
    52
WMcursor *RISCOS_CreateWMCursor(_THIS,
slouken@630
    53
		Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
slouken@630
    54
{
slouken@630
    55
	WMcursor *cursor;
slouken@630
    56
	Uint8 *cursor_data;
slouken@630
    57
	Uint8 *ptr;
slouken@630
    58
	int i,j,k;
slouken@630
    59
	int data_byte, mask_byte;
slouken@630
    60
slouken@630
    61
	/* Check to make sure the cursor size is okay */
slouken@630
    62
	if ( (w > 32) || (h > 32) ) {
slouken@630
    63
		SDL_SetError("Only with width and height <= 32 pixels are allowed");
slouken@630
    64
		return(NULL);
slouken@630
    65
	}
slouken@630
    66
slouken@630
    67
	/* Allocate the cursor */
slouken@630
    68
	cursor = (WMcursor *)malloc(sizeof(*cursor));
slouken@630
    69
	if ( cursor == NULL ) {
slouken@630
    70
		SDL_SetError("Out of memory");
slouken@630
    71
		return(NULL);
slouken@630
    72
	}
slouken@630
    73
slouken@630
    74
	/* Note: SDL says width must be a multiple of 8 */
slouken@630
    75
	cursor_data = malloc(w/4 * h);
slouken@630
    76
	if (cursor_data == NULL)
slouken@630
    77
	{
slouken@630
    78
		free(cursor);
slouken@630
    79
		SDL_SetError("Out of memory");
slouken@630
    80
		return(NULL);
slouken@630
    81
	}
slouken@630
    82
slouken@630
    83
	cursor->w = w;
slouken@630
    84
	cursor->h = h;
slouken@630
    85
	cursor->hot_x = hot_x;
slouken@630
    86
	cursor->hot_y = hot_y;
slouken@630
    87
	cursor->data = cursor_data;
slouken@630
    88
slouken@630
    89
slouken@630
    90
/* Data / Mask Resulting pixel on screen 
slouken@630
    91
   0 / 1 White 
slouken@630
    92
   1 / 1 Black 
slouken@630
    93
   0 / 0 Transparent 
slouken@630
    94
   1 / 0 Inverted color if possible, black if not. 
slouken@630
    95
*/
slouken@630
    96
	ptr = cursor_data;
slouken@630
    97
slouken@630
    98
	for ( i=0; i<h; ++i )
slouken@630
    99
	{
slouken@630
   100
		for (j = 0; j < w/8; ++j)
slouken@630
   101
		{
slouken@630
   102
			data_byte = *data;
slouken@630
   103
			mask_byte = *mask;
slouken@630
   104
			*ptr++ = 0; /* Sets whole byte transparent */
slouken@630
   105
			*ptr = 0;
slouken@630
   106
			for (k = 0; k < 8; k++)
slouken@630
   107
			{
slouken@630
   108
				(*ptr) <<= 2;
slouken@630
   109
				if (data_byte & 1) *ptr |= 3; /* Black or inverted */
slouken@630
   110
				else if(mask_byte & 1) *ptr |= 1; /* White */
slouken@630
   111
				if ((k&3) == 3) ptr--;
slouken@630
   112
				data_byte >>= 1;
slouken@630
   113
				mask_byte >>= 1;
slouken@630
   114
			}
slouken@630
   115
slouken@630
   116
            ptr+=3;
slouken@630
   117
		    data++;
slouken@630
   118
		    mask++;
slouken@630
   119
		}
slouken@630
   120
	}
slouken@630
   121
slouken@630
   122
	return(cursor);
slouken@630
   123
}
slouken@630
   124
slouken@630
   125
int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor)
slouken@630
   126
{
slouken@630
   127
	if (cursor == NULL)
slouken@630
   128
	{
slouken@630
   129
		_kernel_osbyte(106,0,0);
slouken@630
   130
		current_cursor = NULL;
slouken@630
   131
	} else
slouken@630
   132
	{
slouken@630
   133
		if (current_cursor == NULL)
slouken@630
   134
		{
slouken@630
   135
			/* First time set up the mouse colours */
slouken@630
   136
			Uint8 block[5];
slouken@630
   137
slouken@630
   138
			/* Set up colour 1 as white */
slouken@630
   139
			block[0] = 1;   /* Colour to change 1 - 3 */
slouken@630
   140
			block[1] = 25;  /* Set pointer colour */
slouken@630
   141
			block[2] = 255; /* red component*/
slouken@630
   142
			block[3] = 255; /* green component */
slouken@630
   143
			block[4] = 255; /* blue component*/
slouken@630
   144
			_kernel_osword(12, (int *)block);
slouken@630
   145
		
slouken@630
   146
			/* Set colour 3 to back */
slouken@630
   147
			block[0] = 3;   /* Colour to change 1 - 3 */
slouken@630
   148
			block[1] = 25;  /* Set pointer colour*/
slouken@630
   149
			block[2] = 0; /* red component*/
slouken@630
   150
			block[3] = 0; /* green component */
slouken@630
   151
			block[4] = 0; /* blue component*/
slouken@630
   152
			_kernel_osword(12, (int *)block);
slouken@630
   153
		}
slouken@630
   154
slouken@630
   155
		if (cursor != current_cursor)
slouken@630
   156
		{
slouken@630
   157
			Uint8 cursor_def[10];
slouken@630
   158
slouken@630
   159
			cursor_def[0] = 0;
slouken@630
   160
			cursor_def[1] = 2; /* Use shape number 2 */
slouken@630
   161
			cursor_def[2] = cursor->w/4; /* Width in bytes */
slouken@630
   162
			cursor_def[3] = cursor->h; /* Height (h) in pixels */
slouken@630
   163
			cursor_def[4] = cursor->hot_x; /* ActiveX in pixels from left */
slouken@630
   164
			cursor_def[5] = cursor->hot_y; /* ActiveY in pixels from top */
slouken@630
   165
			cursor_def[6] = ((int)(cursor->data) & 0xFF);       /* Least significant byte of pointer to data */
slouken@630
   166
			cursor_def[7] = ((int)(cursor->data) >> 8) & 0xFF;  /* ... */
slouken@630
   167
			cursor_def[8] = ((int)(cursor->data) >> 16) & 0xFF; /* ... */
slouken@630
   168
			cursor_def[9] = ((int)(cursor->data) >> 24) & 0xFF; /* Most significant byte of pointer to data */
slouken@630
   169
slouken@630
   170
			if (_kernel_osword(21, (int *)cursor_def) == 0)
slouken@630
   171
			{
slouken@630
   172
				SDL_SetError("RISCOS couldn't create the cursor to show");
slouken@630
   173
				return(0);
slouken@630
   174
			}
slouken@630
   175
			current_cursor = cursor;
slouken@630
   176
		}
slouken@630
   177
slouken@630
   178
		if ((this->screen->flags & SDL_FULLSCREEN) || mouseInWindow) _kernel_osbyte(106, 2, 0);
slouken@630
   179
	}
slouken@630
   180
	
slouken@630
   181
	return(1);
slouken@630
   182
}
slouken@630
   183
slouken@630
   184
void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
slouken@630
   185
{
slouken@630
   186
	Uint8 move_block[5];
slouken@630
   187
	int eig_block[3];
slouken@630
   188
	_kernel_swi_regs regs;
slouken@630
   189
	int os_x, os_y;
slouken@630
   190
slouken@630
   191
	eig_block[0] = 4;  /* X eig factor */
slouken@630
   192
	eig_block[1] = 5;  /* Y eig factor */
slouken@630
   193
	eig_block[2] = -1;  /* End of list of variables to request */
slouken@630
   194
slouken@630
   195
    regs.r[0] = (int)eig_block;
slouken@630
   196
    regs.r[1] = (int)eig_block;
slouken@630
   197
    _kernel_swi(OS_ReadVduVariables, &regs, &regs);
slouken@630
   198
slouken@630
   199
	os_x = x << eig_block[0];
slouken@630
   200
	os_y = y << eig_block[1];
slouken@630
   201
slouken@630
   202
	move_block[0] = 3; /* Move cursor */
slouken@630
   203
	move_block[1] = os_x & 0xFF;
slouken@630
   204
	move_block[2] = (os_x >> 8) & 0xFF;
slouken@630
   205
	move_block[3] = os_y & 0xFF;
slouken@630
   206
	move_block[4] = (os_y >> 8) & 0xFF;
slouken@630
   207
slouken@630
   208
	_kernel_osword(21, (int *)move_block);
slouken@630
   209
	SDL_PrivateMouseMotion(0, 0, x, y);
slouken@630
   210
}
slouken@630
   211
slouken@630
   212
slouken@630
   213
/* Reshow cursor when mouse re-enters the window */
slouken@630
   214
void WIMP_ReshowCursor(_THIS)
slouken@630
   215
{
slouken@630
   216
	WMcursor *cursor = current_cursor;
slouken@630
   217
	current_cursor = NULL;
slouken@630
   218
	RISCOS_ShowWMCursor(this, cursor);
slouken@630
   219
}
slouken@630
   220
slouken@630
   221
extern int mouseInWindow;
slouken@630
   222
slouken@630
   223
void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
slouken@630
   224
{
slouken@630
   225
	_kernel_swi_regs regs;
slouken@630
   226
	int window_state[9];
slouken@630
   227
	char block[5];
slouken@630
   228
	int osX, osY;
slouken@630
   229
slouken@630
   230
	window_state[0] = this->hidden->window_handle;
slouken@630
   231
	regs.r[1] = (unsigned int)window_state;
slouken@630
   232
	_kernel_swi(Wimp_GetWindowState, &regs, &regs);
slouken@630
   233
slouken@630
   234
	 osX = (x << this->hidden->xeig) + window_state[1];
slouken@630
   235
	 osY = window_state[4] - (y << this->hidden->yeig);
slouken@630
   236
slouken@630
   237
	block[0] = 3;
slouken@630
   238
	block[1] = osX & 0xFF;
slouken@630
   239
	block[2] = (osX >> 8) & 0xFF;
slouken@630
   240
	block[3] = osY & 0xFF;
slouken@630
   241
	block[4] = (osY >> 8) & 0xFF;
slouken@630
   242
slouken@630
   243
	regs.r[0] = 21;
slouken@630
   244
	regs.r[1] = (int)block;
slouken@630
   245
	_kernel_swi(OS_Word, &regs, &regs);
slouken@630
   246
	SDL_PrivateMouseMotion(0, 0, x, y);
slouken@630
   247
}
slouken@630
   248
slouken@630
   249
int WIMP_ShowWMCursor(_THIS, WMcursor *cursor)
slouken@630
   250
{
slouken@630
   251
	if (mouseInWindow) return RISCOS_ShowWMCursor(this, cursor);
slouken@630
   252
	return 1;
slouken@630
   253
}
slouken@630
   254
slouken@630
   255
SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode)
slouken@630
   256
{
slouken@630
   257
   /* In fullscreen mode we don't need to do anything */
slouken@630
   258
   if (mode < SDL_GRAB_FULLSCREEN)
slouken@630
   259
   {
slouken@630
   260
      _kernel_swi_regs regs;
slouken@630
   261
      unsigned char block[9];
slouken@630
   262
      block[0] = 1; /* Define mouse cursor bounding block */
slouken@630
   263
slouken@630
   264
      if ( mode == SDL_GRAB_OFF )
slouken@630
   265
      {
slouken@630
   266
         /* Clip to whole screen */
slouken@630
   267
slouken@630
   268
         int r = (this->hidden->screen_width << this->hidden->xeig) - 1;
slouken@630
   269
         int t = (this->hidden->screen_height << this->hidden->yeig) - 1;
slouken@630
   270
slouken@630
   271
	 block[1] = 0; block[2] = 0; /* Left*/
slouken@630
   272
         block[3] = 0; block[4] = 0; /* Bottom */
slouken@630
   273
         block[5] = r & 0xFF; block[6] = (r >> 8) & 0xFF; /* Right */
slouken@630
   274
         block[7] = t & 0xFF; block[8] = (t >> 8) & 0xFF; /* Top */
slouken@630
   275
      } else
slouken@630
   276
      {
slouken@630
   277
        /* Clip to window */
slouken@630
   278
       	unsigned char window_state[36];
slouken@630
   279
slouken@630
   280
	*((int *)window_state) = this->hidden->window_handle;
slouken@630
   281
	regs.r[1] = (unsigned int)window_state;
slouken@630
   282
	_kernel_swi(Wimp_GetWindowState, &regs, &regs);
slouken@630
   283
slouken@630
   284
        block[1] = window_state[4];
slouken@630
   285
        block[2] = window_state[5];
slouken@630
   286
        block[3] = window_state[8];
slouken@630
   287
        block[4] = window_state[9];
slouken@630
   288
        block[5] = window_state[12];
slouken@630
   289
        block[6] = window_state[13];
slouken@630
   290
        block[7] = window_state[16];
slouken@630
   291
        block[8] = window_state[17];
slouken@630
   292
slouken@630
   293
      }
slouken@630
   294
slouken@630
   295
      regs.r[0] = 21; /* OS word code */
slouken@630
   296
      regs.r[1] = (int)block;
slouken@630
   297
      _kernel_swi(OS_Word, &regs, &regs);
slouken@630
   298
   }
slouken@630
   299
slouken@630
   300
   return mode;
slouken@630
   301
}