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