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