src/video/riscos/SDL_riscosevents.c
changeset 630 550bccdf04bd
child 658 e71b7108d2d7
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/video/riscos/SDL_riscosevents.c	Thu May 29 04:44:13 2003 +0000
     1.3 @@ -0,0 +1,458 @@
     1.4 +/*
     1.5 +    SDL - Simple DirectMedia Layer
     1.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     1.7 +
     1.8 +    This library is free software; you can redistribute it and/or
     1.9 +    modify it under the terms of the GNU Library General Public
    1.10 +    License as published by the Free Software Foundation; either
    1.11 +    version 2 of the License, or (at your option) any later version.
    1.12 +
    1.13 +    This library is distributed in the hope that it will be useful,
    1.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.16 +    Library General Public License for more details.
    1.17 +
    1.18 +    You should have received a copy of the GNU Library General Public
    1.19 +    License along with this library; if not, write to the Free
    1.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.21 +
    1.22 +    Sam Lantinga
    1.23 +    slouken@devolution.com
    1.24 +*/
    1.25 +
    1.26 +/*
    1.27 +     File added by Alan Buckley (alan_baa@hotmail.com) for RISCOS compatability
    1.28 +	 27 March 2003
    1.29 +
    1.30 +     Implements keyboard setup, event pump and keyboard and mouse polling
    1.31 +*/
    1.32 +
    1.33 +
    1.34 +#include "SDL.h"
    1.35 +#include "SDL_sysevents.h"
    1.36 +#include "SDL_events_c.h"
    1.37 +#include "SDL_riscosvideo.h"
    1.38 +#include "SDL_riscosevents_c.h"
    1.39 +#include "SDL_timer_c.h"
    1.40 +#include "SDL_cursor_c.h"
    1.41 +
    1.42 +#include "memory.h"
    1.43 +#include "stdlib.h"
    1.44 +#include "ctype.h"
    1.45 +
    1.46 +#include "kernel.h"
    1.47 +#include "swis.h"
    1.48 +
    1.49 +/* The translation table from a RISCOS internal key numbers to a SDL keysym */
    1.50 +static SDLKey RO_keymap[SDLK_LAST];
    1.51 +
    1.52 +/* RISCOS Key codes */
    1.53 +#define ROKEY_SHIFT 0
    1.54 +#define ROKEY_CTRL  1
    1.55 +#define ROKEY_ALT   2
    1.56 +/* Left shift is first key we will check for */
    1.57 +#define ROKEY_LEFT_SHIFT 3
    1.58 +
    1.59 +/* Need to ignore mouse buttons as they are processed separately */
    1.60 +#define ROKEY_LEFT_MOUSE   9
    1.61 +#define ROKEY_CENTRE_MOUSE 10
    1.62 +#define ROKEY_RIGHT_MOUSE  11
    1.63 +
    1.64 +/* No key has been pressed return value*/
    1.65 +#define ROKEY_NONE 255
    1.66 +
    1.67 +/* Id of last key in keyboard */
    1.68 +#define ROKEY_LAST_KEY  124
    1.69 +
    1.70 +/* Size of array for all keys */
    1.71 +#define ROKEYBD_ARRAYSIZE 125
    1.72 +
    1.73 +static char RO_pressed[ROKEYBD_ARRAYSIZE];
    1.74 +
    1.75 +static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed);
    1.76 +
    1.77 +
    1.78 +void RISCOS_PollMouse(_THIS);
    1.79 +void RISCOS_PollKeyboard();
    1.80 +
    1.81 +void RISCOS_PollMouseHelper(_THIS, int fullscreen);
    1.82 +
    1.83 +extern void DRenderer_FillBuffers();
    1.84 +
    1.85 +/* Timer running function */
    1.86 +extern void RISCOS_CheckTimer();
    1.87 +
    1.88 +void FULLSCREEN_PumpEvents(_THIS)
    1.89 +{
    1.90 +    /* Current implementation requires keyboard and mouse polling */
    1.91 +	RISCOS_PollKeyboard();
    1.92 +	RISCOS_PollMouse(this);
    1.93 +	DRenderer_FillBuffers();
    1.94 +	if (SDL_timer_running) RISCOS_CheckTimer();
    1.95 +}
    1.96 +
    1.97 +
    1.98 +void RISCOS_InitOSKeymap(_THIS)
    1.99 +{
   1.100 +	int i;
   1.101 +
   1.102 +	/* Map the VK keysyms */
   1.103 +	for ( i=0; i<SDL_TABLESIZE(RO_keymap); ++i )
   1.104 +		RO_keymap[i] = SDLK_UNKNOWN;
   1.105 +
   1.106 +  RO_keymap[3] = SDLK_LSHIFT;
   1.107 +  RO_keymap[4] = SDLK_LCTRL;
   1.108 +  RO_keymap[5] = SDLK_LALT;
   1.109 +  RO_keymap[6] = SDLK_RSHIFT;
   1.110 +  RO_keymap[7] = SDLK_RCTRL;
   1.111 +  RO_keymap[8] = SDLK_RALT;
   1.112 +  RO_keymap[16] = SDLK_q;
   1.113 +  RO_keymap[17] = SDLK_3;
   1.114 +  RO_keymap[18] = SDLK_4;
   1.115 +  RO_keymap[19] = SDLK_5;
   1.116 +  RO_keymap[20] = SDLK_F4;
   1.117 +  RO_keymap[21] = SDLK_8;
   1.118 +  RO_keymap[22] = SDLK_F7;
   1.119 +  RO_keymap[23] = SDLK_MINUS,
   1.120 +  RO_keymap[25] = SDLK_LEFT;
   1.121 +  RO_keymap[26] = SDLK_KP6;
   1.122 +  RO_keymap[27] = SDLK_KP7;
   1.123 +  RO_keymap[28] = SDLK_F11;
   1.124 +  RO_keymap[29] = SDLK_F12;
   1.125 +  RO_keymap[30] = SDLK_F10;
   1.126 +  RO_keymap[31] = SDLK_SCROLLOCK;
   1.127 +  RO_keymap[32] = SDLK_PRINT;
   1.128 +  RO_keymap[33] = SDLK_w;
   1.129 +  RO_keymap[34] = SDLK_e;
   1.130 +  RO_keymap[35] = SDLK_t;
   1.131 +  RO_keymap[36] = SDLK_7;
   1.132 +  RO_keymap[37] = SDLK_i;
   1.133 +  RO_keymap[38] = SDLK_9;
   1.134 +  RO_keymap[39] = SDLK_0;
   1.135 +  RO_keymap[41] = SDLK_DOWN;
   1.136 +  RO_keymap[42] = SDLK_KP8;
   1.137 +  RO_keymap[43] = SDLK_KP9;
   1.138 +  RO_keymap[44] = SDLK_BREAK;
   1.139 +  RO_keymap[45] = SDLK_BACKQUOTE;
   1.140 +/*  RO_keymap[46] = SDLK_currency; TODO: Figure out if this has a value */
   1.141 +  RO_keymap[47] = SDLK_BACKSPACE;
   1.142 +  RO_keymap[48] = SDLK_1;
   1.143 +  RO_keymap[49] = SDLK_2;
   1.144 +  RO_keymap[50] = SDLK_d;
   1.145 +  RO_keymap[51] = SDLK_r;
   1.146 +  RO_keymap[52] = SDLK_6;
   1.147 +  RO_keymap[53] = SDLK_u;
   1.148 +  RO_keymap[54] = SDLK_o;
   1.149 +  RO_keymap[55] = SDLK_p;
   1.150 +  RO_keymap[56] = SDLK_LEFTPAREN;
   1.151 +  RO_keymap[57] = SDLK_UP;
   1.152 +  RO_keymap[58] = SDLK_KP_PLUS;
   1.153 +  RO_keymap[59] = SDLK_KP_MINUS;
   1.154 +  RO_keymap[60] = SDLK_KP_ENTER;
   1.155 +  RO_keymap[61] = SDLK_INSERT;
   1.156 +  RO_keymap[62] = SDLK_HOME;
   1.157 +  RO_keymap[63] = SDLK_PAGEUP;
   1.158 +  RO_keymap[64] = SDLK_CAPSLOCK;
   1.159 +  RO_keymap[65] = SDLK_a;
   1.160 +  RO_keymap[66] = SDLK_x;
   1.161 +  RO_keymap[67] = SDLK_f;
   1.162 +  RO_keymap[68] = SDLK_y;
   1.163 +  RO_keymap[69] = SDLK_j;
   1.164 +  RO_keymap[70] = SDLK_k;
   1.165 +  RO_keymap[72] = SDLK_SEMICOLON;
   1.166 +  RO_keymap[73] = SDLK_RETURN;
   1.167 +  RO_keymap[74] = SDLK_KP_DIVIDE;
   1.168 +  RO_keymap[76] = SDLK_KP_PERIOD;
   1.169 +  RO_keymap[77] = SDLK_NUMLOCK;
   1.170 +  RO_keymap[78] = SDLK_PAGEDOWN;
   1.171 +  RO_keymap[79] = SDLK_QUOTE;
   1.172 +  RO_keymap[81] = SDLK_s;
   1.173 +  RO_keymap[82] = SDLK_c;
   1.174 +  RO_keymap[83] = SDLK_g;
   1.175 +  RO_keymap[84] = SDLK_h;
   1.176 +  RO_keymap[85] = SDLK_n;
   1.177 +  RO_keymap[86] = SDLK_l;
   1.178 +  RO_keymap[87] = SDLK_SEMICOLON;
   1.179 +  RO_keymap[88] = SDLK_RIGHTPAREN;
   1.180 +  RO_keymap[89] = SDLK_DELETE;
   1.181 +  RO_keymap[90] = SDLK_KP_MINUS;
   1.182 +  RO_keymap[91] = SDLK_KP_MULTIPLY;
   1.183 +  RO_keymap[93] = SDLK_EQUALS;
   1.184 +  RO_keymap[94] = SDLK_BACKSLASH;
   1.185 +  RO_keymap[96] = SDLK_TAB;
   1.186 +  RO_keymap[97] = SDLK_z;
   1.187 +  RO_keymap[98] = SDLK_SPACE;
   1.188 +  RO_keymap[99] = SDLK_v;
   1.189 +  RO_keymap[100] = SDLK_b;
   1.190 +  RO_keymap[101] = SDLK_m;
   1.191 +  RO_keymap[102] = SDLK_COMMA;
   1.192 +  RO_keymap[103] = SDLK_PERIOD;
   1.193 +  RO_keymap[104] = SDLK_SLASH;
   1.194 +  RO_keymap[105] = SDLK_END;
   1.195 +  RO_keymap[106] = SDLK_KP0;
   1.196 +  RO_keymap[107] = SDLK_KP1;
   1.197 +  RO_keymap[108] = SDLK_KP3;
   1.198 +  RO_keymap[112] = SDLK_ESCAPE;
   1.199 +  RO_keymap[113] = SDLK_F1;
   1.200 +  RO_keymap[114] = SDLK_F2;
   1.201 +  RO_keymap[115] = SDLK_F3;
   1.202 +  RO_keymap[116] = SDLK_F5;
   1.203 +  RO_keymap[117] = SDLK_F6;
   1.204 +  RO_keymap[118] = SDLK_F8;
   1.205 +  RO_keymap[119] = SDLK_F9;
   1.206 +  RO_keymap[120] = SDLK_HASH;
   1.207 +  RO_keymap[121] = SDLK_RIGHT;
   1.208 +  RO_keymap[122] = SDLK_KP4;
   1.209 +  RO_keymap[123] = SDLK_KP5;
   1.210 +  RO_keymap[124] = SDLK_KP2;
   1.211 +
   1.212 +  memset(RO_pressed, 0, ROKEYBD_ARRAYSIZE);
   1.213 +}
   1.214 +
   1.215 +
   1.216 +/* Variable for mouse relative processing */
   1.217 +int mouse_relative = 0;
   1.218 +
   1.219 +/* Check to see if we need to enter or leave mouse relative mode */
   1.220 +
   1.221 +void RISCOS_CheckMouseMode(_THIS)
   1.222 +{
   1.223 +    /* If the mouse is hidden and input is grabbed, we use relative mode */
   1.224 +    if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
   1.225 +        (this->input_grab != SDL_GRAB_OFF) ) {
   1.226 +            mouse_relative = 1;
   1.227 +     } else {
   1.228 +            mouse_relative = 0;
   1.229 +     }
   1.230 +}
   1.231 +
   1.232 +
   1.233 +void RISCOS_PollMouse(_THIS)
   1.234 +{
   1.235 +   RISCOS_PollMouseHelper(this, 1);
   1.236 +}
   1.237 +
   1.238 +extern int mouseInWindow;
   1.239 +
   1.240 +void WIMP_PollMouse(_THIS)
   1.241 +{
   1.242 +   /* Only poll when mouse is over the window */
   1.243 +   if (!mouseInWindow) return;
   1.244 +
   1.245 +   RISCOS_PollMouseHelper(this, 0);
   1.246 +}
   1.247 +
   1.248 +/* Static variables so only changes are reported */
   1.249 +static Sint16 last_x = -1, last_y = -1;
   1.250 +static int last_buttons = 0;
   1.251 +
   1.252 +/* Share routine between WIMP and FULLSCREEN for polling mouse and
   1.253 +   passing on events */
   1.254 +void RISCOS_PollMouseHelper(_THIS, int fullscreen)
   1.255 +{
   1.256 +    _kernel_swi_regs regs;
   1.257 +    static int starting = 1;
   1.258 +
   1.259 +    if (_kernel_swi(OS_Mouse, &regs, &regs) == NULL)
   1.260 +    {
   1.261 +       Sint16 new_x = regs.r[0]; /* Initialy get as OS units */
   1.262 +       Sint16 new_y = regs.r[1];
   1.263 +
   1.264 +/* Discard mouse events until the let go of the mouse after starting */
   1.265 +       if (starting && regs.r[2] != 0) return;
   1.266 +       else starting = 0;
   1.267 +
   1.268 +       if (new_x != last_x || new_y != last_y || last_buttons != regs.r[2])
   1.269 +       {
   1.270 +          /* Something changed so generate appropriate events */
   1.271 +          int topLeftX, topLeftY;  /* Top left OS units */
   1.272 +          int x, y;                /* Mouse position in SDL pixels */
   1.273 +
   1.274 +          if (fullscreen)
   1.275 +          {
   1.276 +             topLeftX = 0;
   1.277 +             topLeftY = (this->hidden->height << this->hidden->yeig) - 1;
   1.278 +          } else
   1.279 +          {
   1.280 +             int window_state[9];
   1.281 +
   1.282 +	         /* Get current window state */
   1.283 +		     window_state[0] = this->hidden->window_handle;
   1.284 +		     regs.r[1] = (unsigned int)window_state;
   1.285 +		     _kernel_swi(Wimp_GetWindowState, &regs, &regs);
   1.286 +
   1.287 +             topLeftX = window_state[1];
   1.288 +             topLeftY = window_state[4];
   1.289 +          }
   1.290 +
   1.291 +		  /* Convert co-ordinates to workspace */
   1.292 +		  x = new_x - topLeftX;
   1.293 +          y = topLeftY - new_y; /* Y goes from top of window/screen */
   1.294 +
   1.295 +	 	  /* Convert OS units to pixels */
   1.296 +	      x >>= this->hidden->xeig;
   1.297 +		  y >>= this->hidden->yeig;
   1.298 +
   1.299 +          if (last_x != new_x || last_y != new_y)
   1.300 +          {
   1.301 +             if (mouse_relative)
   1.302 +             {
   1.303 +                int centre_x = SDL_VideoSurface->w/2;
   1.304 +                int centre_y = SDL_VideoSurface->h/2;
   1.305 +
   1.306 +                if (centre_x != x || centre_y != y)
   1.307 +                {
   1.308 +                   if (SDL_VideoSurface) SDL_PrivateMouseMotion(0,1,x - centre_x, y - centre_y);
   1.309 +                   last_x = topLeftX + (centre_x << this->hidden->xeig);
   1.310 +                   last_y = topLeftY - (centre_y << this->hidden->yeig);
   1.311 +
   1.312 +                   /* Re-centre the mouse pointer, so we still get relative
   1.313 +                      movement when the mouse is at the edge of the window
   1.314 +                      or screen.
   1.315 +                   */
   1.316 +                   {
   1.317 +                      unsigned char block[5];
   1.318 +
   1.319 +                      block[0] = 3; /* OSWORD move pointer sub-reason code */
   1.320 +                      block[1] = last_x & 0xFF;
   1.321 +                      block[2] = (last_x >> 8) & 0xFF;
   1.322 +                      block[3] = last_y & 0xFF;
   1.323 +                      block[4] = (last_y >> 8) & 0xFF;
   1.324 +                       
   1.325 +                      regs.r[0] = 21; /* OSWORD pointer stuff code */
   1.326 +                      regs.r[1] = (int)block;
   1.327 +                      _kernel_swi(OS_Word, &regs, &regs);
   1.328 +               	   }
   1.329 +                }
   1.330 +             } else
   1.331 +             {
   1.332 +                last_x = new_x;
   1.333 +                last_y = new_y;
   1.334 +                SDL_PrivateMouseMotion(0,0,x,y);
   1.335 +             }
   1.336 +          }
   1.337 +
   1.338 +          if (last_buttons != regs.r[2])
   1.339 +          {
   1.340 +             int changed = last_buttons ^ regs.r[2];
   1.341 +             last_buttons = regs.r[2];
   1.342 +             if (changed & 4) SDL_PrivateMouseButton((last_buttons & 4) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT, x, y);
   1.343 +             if (changed & 2) SDL_PrivateMouseButton((last_buttons & 2) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE, x, y);
   1.344 +             if (changed & 1) SDL_PrivateMouseButton((last_buttons & 1) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT, x, y);
   1.345 +          }
   1.346 +       }
   1.347 +    }
   1.348 +}
   1.349 +
   1.350 +void RISCOS_PollKeyboard()
   1.351 +{
   1.352 +	int which_key = ROKEY_LEFT_SHIFT;
   1.353 +	int j;
   1.354 +	int min_key, max_key;
   1.355 +	SDL_keysym key;
   1.356 +
   1.357 +	/* Scan the keyboard to see what is pressed */
   1.358 +	while (which_key <= ROKEY_LAST_KEY)
   1.359 +	{
   1.360 +		which_key = (_kernel_osbyte(121, which_key, 0) & 0xFF);
   1.361 +	    if (which_key != ROKEY_NONE)
   1.362 +		{
   1.363 +		    switch(which_key)
   1.364 +		    {
   1.365 +		    /* Skip over mouse keys */
   1.366 +		    case ROKEY_LEFT_MOUSE:
   1.367 +		    case ROKEY_CENTRE_MOUSE:
   1.368 +		    case ROKEY_RIGHT_MOUSE:
   1.369 +				which_key = ROKEY_RIGHT_MOUSE;
   1.370 +				break;
   1.371 +
   1.372 +            /* Ignore keys that cause 2 internal number to be generated */
   1.373 +			case 71: case 24: case 87: case 40:
   1.374 +			    break;
   1.375 +
   1.376 +			default:
   1.377 +				RO_pressed[which_key] += 2;
   1.378 +				break;
   1.379 +		    }
   1.380 +			which_key++;
   1.381 +		}
   1.382 +	}
   1.383 +
   1.384 +	/* Generate key released messages */
   1.385 +	min_key = ROKEY_LAST_KEY+1;
   1.386 +	max_key = ROKEY_LEFT_SHIFT;
   1.387 +
   1.388 +	for (j = ROKEY_LEFT_SHIFT; j <= ROKEY_LAST_KEY; j++)
   1.389 +	{
   1.390 +		if (RO_pressed[j])
   1.391 +		{
   1.392 +			if (RO_pressed[j] == 1)
   1.393 +			{
   1.394 +				RO_pressed[j] = 0;
   1.395 +				SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(j,&key,0));
   1.396 +			} else 
   1.397 +			{
   1.398 +				if (j < min_key) min_key = j;
   1.399 +				if (j > max_key) max_key = j;
   1.400 +			}
   1.401 +		}
   1.402 +	}
   1.403 +
   1.404 +	/* Generate key pressed messages */
   1.405 +	for (j = min_key; j <= max_key; j++)
   1.406 +	{
   1.407 +		if (RO_pressed[j])
   1.408 +		{
   1.409 +			if (RO_pressed[j] == 2)
   1.410 +			{
   1.411 +				SDL_PrivateKeyboard(SDL_PRESSED,TranslateKey(j,&key,1));
   1.412 +			}
   1.413 +			RO_pressed[j] = 1;
   1.414 +		}
   1.415 +	}
   1.416 +}
   1.417 +
   1.418 +static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed)
   1.419 +{
   1.420 +	/* Set the keysym information */
   1.421 +	keysym->scancode = (unsigned char) intkey;
   1.422 +	keysym->sym = RO_keymap[intkey];
   1.423 +	keysym->mod = KMOD_NONE;
   1.424 +	keysym->unicode = 0;
   1.425 +	if ( pressed && SDL_TranslateUNICODE )
   1.426 +	{
   1.427 +		int state;
   1.428 +		int ch;
   1.429 +
   1.430 +		state = (_kernel_osbyte(202, 0, 255) & 0xFF);
   1.431 +
   1.432 +		/*TODO: better key to char mapping */
   1.433 +
   1.434 +		ch = keysym->sym; /* This should handle most keys */
   1.435 +
   1.436 +        if (intkey < 9)
   1.437 +        {
   1.438 +           ch = 0;
   1.439 +
   1.440 +        } else if (state & 64) /* Control on */
   1.441 +		{
   1.442 +			ch = ch & 31;
   1.443 +
   1.444 +		} else if ((state & 16) == 0) /* Caps lock is on */
   1.445 +		{
   1.446 +			if ((state & 128) == 0) /* Shift Enable off */
   1.447 +			{
   1.448 +				ch = toupper(ch);
   1.449 +			}
   1.450 +		} else if (state & 8) /* Shift on */
   1.451 +		{
   1.452 +			ch = toupper(ch);
   1.453 +		}
   1.454 +				
   1.455 +		keysym->unicode = ch;
   1.456 +	}
   1.457 +	return(keysym);
   1.458 +}
   1.459 +
   1.460 +/* end of SDL_riscosevents.c ... */
   1.461 +