src/video/riscos/SDL_wimppoll.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 Pumping of events and WIMP polling
slouken@630
    28
*/
slouken@630
    29
slouken@630
    30
#include "SDL.h"
slouken@630
    31
#include "SDL_syswm.h"
slouken@630
    32
#include "SDL_sysevents.h"
slouken@630
    33
#include "SDL_events_c.h"
slouken@630
    34
#include "SDL_riscosvideo.h"
slouken@630
    35
#include "SDL_riscosevents_c.h"
slouken@630
    36
#include "SDL_timer_c.h"
slouken@630
    37
slouken@630
    38
#include "memory.h"
slouken@630
    39
#include "stdlib.h"
slouken@630
    40
#include "ctype.h"
slouken@630
    41
slouken@630
    42
#include "kernel.h"
slouken@630
    43
#include "swis.h"
slouken@630
    44
#include "unixlib/os.h"
slouken@630
    45
slouken@630
    46
/* Local functions */
slouken@630
    47
void WIMP_Poll(_THIS, int waitTime);
slouken@630
    48
void WIMP_SetFocus(int win);
slouken@630
    49
slouken@630
    50
/* SDL_riscossprite functions */
slouken@630
    51
void WIMP_PlotSprite(_THIS, int x, int y);
slouken@630
    52
void WIMP_ModeChanged(_THIS);
slouken@630
    53
void WIMP_PaletteChanged(_THIS);
slouken@630
    54
slouken@630
    55
slouken@630
    56
extern void WIMP_PollMouse(_THIS);
slouken@630
    57
extern void RISCOS_PollKeyboard();
slouken@630
    58
slouken@630
    59
extern void DRenderer_FillBuffers();
slouken@630
    60
slouken@630
    61
/* Timer running function */
slouken@630
    62
extern void RISCOS_CheckTimer();
slouken@630
    63
slouken@630
    64
/* Mouse cursor handling */
slouken@630
    65
extern void WIMP_ReshowCursor(_THIS);
slouken@630
    66
slouken@630
    67
int hasFocus = 0;
slouken@630
    68
int mouseInWindow = 0;
slouken@630
    69
 
slouken@630
    70
/* Flag to ensure window is correct size after a mode change */
slouken@630
    71
static int resizeOnOpen = 0;
slouken@630
    72
slouken@630
    73
void WIMP_PumpEvents(_THIS)
slouken@630
    74
{
slouken@630
    75
	WIMP_Poll(this, 0);
slouken@630
    76
	if (hasFocus) RISCOS_PollKeyboard();
slouken@630
    77
	if (mouseInWindow) WIMP_PollMouse(this);
slouken@630
    78
	DRenderer_FillBuffers();
slouken@630
    79
	if (SDL_timer_running) RISCOS_CheckTimer();
slouken@630
    80
}
slouken@630
    81
slouken@630
    82
slouken@630
    83
void WIMP_Poll(_THIS, int waitTime)
slouken@630
    84
{
slouken@630
    85
	_kernel_swi_regs regs;
slouken@630
    86
	int message[64];
slouken@630
    87
	unsigned int code;
slouken@630
    88
	int pollMask = 0;
slouken@630
    89
	int doPoll = 1;
slouken@630
    90
	int sysEvent;
slouken@630
    91
	int sdlWindow = this->hidden->window_handle;
slouken@630
    92
slouken@630
    93
    if (this->PumpEvents != WIMP_PumpEvents) return;
slouken@630
    94
slouken@630
    95
    if (waitTime > 0)
slouken@630
    96
    {
slouken@630
    97
		_kernel_swi(OS_ReadMonotonicTime, &regs, &regs);
slouken@630
    98
		waitTime += regs.r[0];
slouken@630
    99
    }
slouken@630
   100
slouken@630
   101
    while (doPoll)
slouken@630
   102
    {
slouken@630
   103
        if (waitTime <= 0)
slouken@630
   104
        {
slouken@630
   105
        	regs.r[0] = pollMask; /* Poll Mask */
slouken@630
   106
        	 /* For no wait time mask out null event so we wait until something happens */
slouken@630
   107
        	if (waitTime < 0) regs.r[0] |= 1;
slouken@630
   108
        	regs.r[1] = (int)message;
slouken@630
   109
        	_kernel_swi(Wimp_Poll, &regs, &regs);
slouken@630
   110
        } else
slouken@630
   111
        {
slouken@630
   112
        	regs.r[0] = pollMask;
slouken@630
   113
        	regs.r[1] = (int)message;
slouken@630
   114
        	regs.r[2] = waitTime;
slouken@630
   115
        	_kernel_swi(Wimp_PollIdle, &regs, &regs);
slouken@630
   116
        }
slouken@630
   117
slouken@630
   118
		/* Flag to specify if we post a SDL_SysWMEvent */
slouken@630
   119
		sysEvent = 0;
slouken@630
   120
        
slouken@630
   121
        code = (unsigned int)regs.r[0];
slouken@630
   122
slouken@630
   123
		switch(code)
slouken@630
   124
		{
slouken@630
   125
		case 0:  /* Null Event - drop out for standard processing*/
slouken@630
   126
		   doPoll = 0;
slouken@630
   127
		   break;
slouken@630
   128
slouken@630
   129
		case 1:     /* Redraw window */
slouken@630
   130
        	_kernel_swi(Wimp_RedrawWindow, &regs,&regs);
slouken@630
   131
			if (message[0] == sdlWindow)
slouken@630
   132
			{
slouken@630
   133
        		while (regs.r[0])
slouken@630
   134
        		{
slouken@630
   135
        			WIMP_PlotSprite(this, message[1], message[2]);
slouken@630
   136
        			_kernel_swi(Wimp_GetRectangle, &regs, &regs);
slouken@630
   137
        		}
slouken@630
   138
			} else
slouken@630
   139
			{
slouken@630
   140
				/* TODO: Currently we just eat them - we may need to pass them on */
slouken@630
   141
        		while (regs.r[0])
slouken@630
   142
        		{
slouken@630
   143
        			_kernel_swi(Wimp_GetRectangle, &regs, &regs);
slouken@630
   144
        		}
slouken@630
   145
			}
slouken@630
   146
        	break;
slouken@630
   147
        	
slouken@630
   148
		case 2:		/* Open window */
slouken@630
   149
		   if ( resizeOnOpen && message[0] == sdlWindow)
slouken@630
   150
		   {
slouken@630
   151
		      /* Ensure window is correct size */
slouken@630
   152
		      resizeOnOpen = 0;
slouken@630
   153
		      message[3] = message[1] + (this->screen->w << this->hidden->xeig);
slouken@630
   154
		      message[4] = message[2] + (this->screen->h << this->hidden->yeig);       
slouken@630
   155
		   }
slouken@630
   156
        	_kernel_swi(Wimp_OpenWindow, &regs, &regs);
slouken@630
   157
       	    break;
slouken@630
   158
        	
slouken@630
   159
		case 3:		/* Close window */
slouken@630
   160
			if (message[0] == sdlWindow)
slouken@630
   161
			{
slouken@630
   162
				/* Documentation makes it looks as if the following line is correct:
slouken@630
   163
				**    if (SDL_PrivateQuit() == 1) _kernel_swi(Wimp_CloseWindow, &regs, &regs);
slouken@630
   164
				** However some programs don't process this message and so sit there invisibly
slouken@630
   165
				** in the background so I just post the quit message and hope the application
slouken@630
   166
				** does the correct thing.
slouken@630
   167
				*/
slouken@630
   168
				SDL_PrivateQuit();
slouken@630
   169
			} else
slouken@630
   170
				sysEvent = 1;
slouken@630
   171
        	doPoll = 0;
slouken@630
   172
        	break;
slouken@630
   173
slouken@630
   174
		case 4: /* Pointer_Leaving_Window */
slouken@630
   175
			if (message[0] == sdlWindow)
slouken@630
   176
			{
slouken@630
   177
				mouseInWindow = 0;
slouken@630
   178
				//TODO: Lose buttons / dragging
slouken@630
   179
				 /* Reset to default pointer */
slouken@630
   180
   				 regs.r[0] = 106;
slouken@630
   181
				 regs.r[1] = 1;
slouken@630
   182
				 regs.r[2] = 0;
slouken@630
   183
				 _kernel_swi(OS_Byte, &regs, &regs);
slouken@630
   184
				 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
slouken@630
   185
			} else
slouken@630
   186
				sysEvent = 1;
slouken@630
   187
			break;
slouken@630
   188
slouken@630
   189
		case 5: /* Pointer_Entering_Window */
slouken@630
   190
			if (message[0] == sdlWindow) 
slouken@630
   191
			{
slouken@630
   192
				mouseInWindow = 1;
slouken@630
   193
				WIMP_ReshowCursor(this);
slouken@630
   194
				SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
slouken@630
   195
			} else sysEvent = 1;
slouken@630
   196
			break;
slouken@630
   197
slouken@630
   198
		case 6:		/* Mouse_Click */
slouken@630
   199
			if (hasFocus == 0)
slouken@630
   200
			{
slouken@630
   201
			   /* First click gives focus if it's not a menu */
slouken@630
   202
			   /* we only count non-menu clicks on a window that has the focus */
slouken@630
   203
			   WIMP_SetFocus(message[3]);
slouken@630
   204
			} else
slouken@630
   205
				doPoll = 0; // So PollMouse gets a chance to pick it up
slouken@630
   206
		   break;
slouken@630
   207
slouken@630
   208
		case 7: /* User_Drag_Box - Used for mouse release */
slouken@630
   209
			//TODO: May need to implement this in the future
slouken@630
   210
			sysEvent = 1;
slouken@630
   211
			break;
slouken@630
   212
slouken@630
   213
		case 8: /* Keypressed */
slouken@630
   214
			doPoll = 0; /* PollKeyboard should pick it up */
slouken@630
   215
			if (message[0] != sdlWindow) sysEvent = 1;
slouken@630
   216
			/*TODO: May want to always pass F12 etc to the wimp
slouken@630
   217
			{
slouken@630
   218
				regs.r[0] = message[6];
slouken@630
   219
				_kernel_swi(Wimp_ProcessKey, &regs, &regs);
slouken@630
   220
			}
slouken@630
   221
			*/
slouken@630
   222
			break;
slouken@630
   223
slouken@630
   224
		case 11: /* Lose Caret */
slouken@630
   225
			 hasFocus = 0;
slouken@630
   226
			 if (message[0] == sdlWindow) SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
slouken@630
   227
			 else sysEvent = 1;
slouken@630
   228
			 break;
slouken@630
   229
slouken@630
   230
		case 12: /* Gain Caret */
slouken@630
   231
			 hasFocus = 1;
slouken@630
   232
			 if (message[0] == sdlWindow) SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
slouken@630
   233
			 else sysEvent = 1;
slouken@630
   234
			 break;
slouken@630
   235
        	
slouken@630
   236
		case 17:
slouken@630
   237
		case 18:
slouken@630
   238
			sysEvent = 1; /* All messages are passed on */
slouken@630
   239
slouken@630
   240
			switch(message[4])
slouken@630
   241
			{
slouken@630
   242
			case 0: /* Quit Event */
slouken@630
   243
				/* No choice - have to quit */
slouken@630
   244
			   SDL_Quit();
slouken@630
   245
        	   exit(0);
slouken@630
   246
			   break;
slouken@630
   247
slouken@630
   248
			case 8: /* Pre Quit */
slouken@630
   249
				SDL_PrivateQuit();
slouken@630
   250
				break;
slouken@630
   251
slouken@630
   252
			case 0x400c1: /* Mode change */
slouken@630
   253
				WIMP_ModeChanged(this);
slouken@630
   254
				resizeOnOpen = 1;
slouken@630
   255
				break;
slouken@630
   256
slouken@630
   257
			case 9:      /* Palette changed */
slouken@630
   258
				WIMP_PaletteChanged(this);
slouken@630
   259
				break;
slouken@630
   260
			}
slouken@630
   261
			break;
slouken@630
   262
slouken@630
   263
		default:
slouken@630
   264
			/* Pass unknown events on */
slouken@630
   265
			sysEvent = 1;
slouken@630
   266
			break;
slouken@630
   267
		}
slouken@630
   268
slouken@630
   269
		if (sysEvent)
slouken@630
   270
		{
slouken@630
   271
	        SDL_SysWMmsg wmmsg;
slouken@630
   272
slouken@630
   273
			SDL_VERSION(&wmmsg.version);
slouken@630
   274
			wmmsg.eventCode = code;
slouken@630
   275
			memcpy(wmmsg.pollBlock, message, 64 * sizeof(int));
slouken@630
   276
slouken@630
   277
			/* Fall out of polling loop if message is successfully posted */
slouken@630
   278
			if (SDL_PrivateSysWMEvent(&wmmsg)) doPoll = 0;
slouken@630
   279
		}
slouken@630
   280
slouken@630
   281
    }
slouken@630
   282
}
slouken@630
   283
slouken@630
   284
/* Set focus to specified window */
slouken@630
   285
void WIMP_SetFocus(int win)
slouken@630
   286
{
slouken@630
   287
	_kernel_swi_regs regs;
slouken@630
   288
slouken@630
   289
	regs.r[0] = win;
slouken@630
   290
	regs.r[1] = -1; /* Icon handle */
slouken@630
   291
	regs.r[2] = 0;  /* X-offset we just put it at position 0 */
slouken@630
   292
	regs.r[3] = 0;  /* Y-offset as above */
slouken@630
   293
	regs.r[4] = 1 << 25; /* Caret is invisible */
slouken@630
   294
	regs.r[5] = 0;  /* index into string */
slouken@630
   295
slouken@630
   296
	_kernel_swi(Wimp_SetCaretPosition, &regs, &regs);
slouken@630
   297
}
slouken@630
   298
slouken@630
   299
/** Run background task while in a sleep command */
slouken@630
   300
void RISCOS_BackgroundTasks(void)
slouken@630
   301
{
slouken@630
   302
	if (current_video && current_video->hidden->window_handle)
slouken@630
   303
	{
slouken@630
   304
		WIMP_Poll(current_video, 0);
slouken@630
   305
	}
slouken@630
   306
	/* Keep sound buffers running */
slouken@630
   307
	DRenderer_FillBuffers();
slouken@630
   308
	if (SDL_timer_running) RISCOS_CheckTimer();
slouken@630
   309
}