331 lines
8.6 KiB
C
331 lines
8.6 KiB
C
/*
|
|
SDL - Simple DirectMedia Layer
|
|
Copyright (C) 1997-2004 Sam Lantinga
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
License along with this library; if not, write to the Free
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
Sam Lantinga
|
|
slouken@libsdl.org
|
|
*/
|
|
#include "SDL_config.h"
|
|
|
|
/*
|
|
File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
|
|
27 March 2003
|
|
|
|
Implements Pumping of events and WIMP polling
|
|
*/
|
|
|
|
#include "SDL.h"
|
|
#include "SDL_syswm.h"
|
|
#include "../../events/SDL_sysevents.h"
|
|
#include "../../events/SDL_events_c.h"
|
|
#include "SDL_riscosvideo.h"
|
|
#include "SDL_riscosevents_c.h"
|
|
#include "SDL_riscosmouse_c.h"
|
|
#include "../../timer/SDL_timer_c.h"
|
|
|
|
#include "memory.h"
|
|
#include "stdlib.h"
|
|
#include "ctype.h"
|
|
|
|
#include "kernel.h"
|
|
#include "swis.h"
|
|
#include "unixlib/os.h"
|
|
|
|
#if !SDL_THREADS_DISABLED
|
|
#include <pthread.h>
|
|
#endif
|
|
|
|
/* Local functions */
|
|
void WIMP_Poll(_THIS, int waitTime);
|
|
void WIMP_SetFocus(int win);
|
|
|
|
/* SDL_riscossprite functions */
|
|
void WIMP_PlotSprite(_THIS, int x, int y);
|
|
void WIMP_ModeChanged(_THIS);
|
|
void WIMP_PaletteChanged(_THIS);
|
|
|
|
|
|
extern void WIMP_PollMouse(_THIS);
|
|
extern void RISCOS_PollKeyboard();
|
|
|
|
#if SDL_THREADS_DISABLED
|
|
/* Timer running function */
|
|
extern void RISCOS_CheckTimer();
|
|
#else
|
|
extern int riscos_using_threads;
|
|
#endif
|
|
|
|
/* Mouse cursor handling */
|
|
extern void WIMP_ReshowCursor(_THIS);
|
|
extern void WIMP_RestoreWimpCursor();
|
|
|
|
int hasFocus = 0;
|
|
int mouseInWindow = 0;
|
|
|
|
/* Flag to ensure window is correct size after a mode change */
|
|
static int resizeOnOpen = 0;
|
|
|
|
void WIMP_PumpEvents(_THIS)
|
|
{
|
|
WIMP_Poll(this, 0);
|
|
if (hasFocus) RISCOS_PollKeyboard();
|
|
if (mouseInWindow) WIMP_PollMouse(this);
|
|
#if SDL_THREADS_DISABLED
|
|
if (SDL_timer_running) RISCOS_CheckTimer();
|
|
#endif
|
|
}
|
|
|
|
|
|
void WIMP_Poll(_THIS, int waitTime)
|
|
{
|
|
_kernel_swi_regs regs;
|
|
int message[64];
|
|
unsigned int code;
|
|
int pollMask = 0;
|
|
int doPoll = 1;
|
|
int sysEvent;
|
|
int sdlWindow = this->hidden->window_handle;
|
|
|
|
if (this->PumpEvents != WIMP_PumpEvents) return;
|
|
|
|
if (waitTime > 0)
|
|
{
|
|
_kernel_swi(OS_ReadMonotonicTime, ®s, ®s);
|
|
waitTime += regs.r[0];
|
|
}
|
|
|
|
while (doPoll)
|
|
{
|
|
#if !SDL_THREADS_DISABLED
|
|
/* Stop thread callbacks while program is paged out */
|
|
if (riscos_using_threads) __pthread_stop_ticker();
|
|
#endif
|
|
|
|
if (waitTime <= 0)
|
|
{
|
|
regs.r[0] = pollMask; /* Poll Mask */
|
|
/* For no wait time mask out null event so we wait until something happens */
|
|
if (waitTime < 0) regs.r[0] |= 1;
|
|
regs.r[1] = (int)message;
|
|
_kernel_swi(Wimp_Poll, ®s, ®s);
|
|
} else
|
|
{
|
|
regs.r[0] = pollMask;
|
|
regs.r[1] = (int)message;
|
|
regs.r[2] = waitTime;
|
|
_kernel_swi(Wimp_PollIdle, ®s, ®s);
|
|
}
|
|
|
|
/* Flag to specify if we post a SDL_SysWMEvent */
|
|
sysEvent = 0;
|
|
|
|
code = (unsigned int)regs.r[0];
|
|
|
|
switch(code)
|
|
{
|
|
case 0: /* Null Event - drop out for standard processing*/
|
|
doPoll = 0;
|
|
break;
|
|
|
|
case 1: /* Redraw window */
|
|
_kernel_swi(Wimp_RedrawWindow, ®s,®s);
|
|
if (message[0] == sdlWindow)
|
|
{
|
|
while (regs.r[0])
|
|
{
|
|
WIMP_PlotSprite(this, message[1], message[2]);
|
|
_kernel_swi(Wimp_GetRectangle, ®s, ®s);
|
|
}
|
|
} else
|
|
{
|
|
/* TODO: Currently we just eat them - we may need to pass them on */
|
|
while (regs.r[0])
|
|
{
|
|
_kernel_swi(Wimp_GetRectangle, ®s, ®s);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 2: /* Open window */
|
|
if ( resizeOnOpen && message[0] == sdlWindow)
|
|
{
|
|
/* Ensure window is correct size */
|
|
resizeOnOpen = 0;
|
|
message[3] = message[1] + (this->screen->w << this->hidden->xeig);
|
|
message[4] = message[2] + (this->screen->h << this->hidden->yeig);
|
|
}
|
|
_kernel_swi(Wimp_OpenWindow, ®s, ®s);
|
|
break;
|
|
|
|
case 3: /* Close window */
|
|
if (message[0] == sdlWindow)
|
|
{
|
|
/* Documentation makes it looks as if the following line is correct:
|
|
** if (SDL_PrivateQuit() == 1) _kernel_swi(Wimp_CloseWindow, ®s, ®s);
|
|
** However some programs don't process this message and so sit there invisibly
|
|
** in the background so I just post the quit message and hope the application
|
|
** does the correct thing.
|
|
*/
|
|
SDL_PrivateQuit();
|
|
} else
|
|
sysEvent = 1;
|
|
doPoll = 0;
|
|
break;
|
|
|
|
case 4: /* Pointer_Leaving_Window */
|
|
if (message[0] == sdlWindow)
|
|
{
|
|
mouseInWindow = 0;
|
|
//TODO: Lose buttons / dragging
|
|
/* Reset to default pointer */
|
|
WIMP_RestoreWimpCursor();
|
|
SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
|
|
} else
|
|
sysEvent = 1;
|
|
break;
|
|
|
|
case 5: /* Pointer_Entering_Window */
|
|
if (message[0] == sdlWindow)
|
|
{
|
|
mouseInWindow = 1;
|
|
WIMP_ReshowCursor(this);
|
|
SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
|
|
} else sysEvent = 1;
|
|
break;
|
|
|
|
case 6: /* Mouse_Click */
|
|
if (hasFocus == 0)
|
|
{
|
|
/* First click gives focus if it's not a menu */
|
|
/* we only count non-menu clicks on a window that has the focus */
|
|
WIMP_SetFocus(message[3]);
|
|
} else
|
|
doPoll = 0; // So PollMouse gets a chance to pick it up
|
|
break;
|
|
|
|
case 7: /* User_Drag_Box - Used for mouse release */
|
|
//TODO: May need to implement this in the future
|
|
sysEvent = 1;
|
|
break;
|
|
|
|
case 8: /* Keypressed */
|
|
doPoll = 0; /* PollKeyboard should pick it up */
|
|
if (message[0] != sdlWindow) sysEvent = 1;
|
|
/*TODO: May want to always pass F12 etc to the wimp
|
|
{
|
|
regs.r[0] = message[6];
|
|
_kernel_swi(Wimp_ProcessKey, ®s, ®s);
|
|
}
|
|
*/
|
|
break;
|
|
|
|
case 11: /* Lose Caret */
|
|
hasFocus = 0;
|
|
if (message[0] == sdlWindow) SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
|
|
else sysEvent = 1;
|
|
break;
|
|
|
|
case 12: /* Gain Caret */
|
|
hasFocus = 1;
|
|
if (message[0] == sdlWindow) SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
|
|
else sysEvent = 1;
|
|
break;
|
|
|
|
case 17:
|
|
case 18:
|
|
sysEvent = 1; /* All messages are passed on */
|
|
|
|
switch(message[4])
|
|
{
|
|
case 0: /* Quit Event */
|
|
/* No choice - have to quit */
|
|
SDL_Quit();
|
|
exit(0);
|
|
break;
|
|
|
|
case 8: /* Pre Quit */
|
|
SDL_PrivateQuit();
|
|
break;
|
|
|
|
case 0x400c1: /* Mode change */
|
|
WIMP_ModeChanged(this);
|
|
resizeOnOpen = 1;
|
|
break;
|
|
|
|
case 9: /* Palette changed */
|
|
WIMP_PaletteChanged(this);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/* Pass unknown events on */
|
|
sysEvent = 1;
|
|
break;
|
|
}
|
|
|
|
if (sysEvent)
|
|
{
|
|
SDL_SysWMmsg wmmsg;
|
|
|
|
SDL_VERSION(&wmmsg.version);
|
|
wmmsg.eventCode = code;
|
|
SDL_memcpy(wmmsg.pollBlock, message, 64 * sizeof(int));
|
|
|
|
/* Fall out of polling loop if message is successfully posted */
|
|
if (SDL_PrivateSysWMEvent(&wmmsg)) doPoll = 0;
|
|
}
|
|
#if !SDL_THREADS_DISABLED
|
|
if (riscos_using_threads)
|
|
{
|
|
/* Restart ticker here so other thread can not interfere
|
|
with the Redraw processing */
|
|
if (riscos_using_threads) __pthread_start_ticker();
|
|
/* Give other threads a better chance of running */
|
|
pthread_yield();
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* Set focus to specified window */
|
|
void WIMP_SetFocus(int win)
|
|
{
|
|
_kernel_swi_regs regs;
|
|
|
|
regs.r[0] = win;
|
|
regs.r[1] = -1; /* Icon handle */
|
|
regs.r[2] = 0; /* X-offset we just put it at position 0 */
|
|
regs.r[3] = 0; /* Y-offset as above */
|
|
regs.r[4] = 1 << 25; /* Caret is invisible */
|
|
regs.r[5] = 0; /* index into string */
|
|
|
|
_kernel_swi(Wimp_SetCaretPosition, ®s, ®s);
|
|
}
|
|
|
|
/** Run background task while in a sleep command */
|
|
void RISCOS_BackgroundTasks(void)
|
|
{
|
|
if (current_video && current_video->hidden->window_handle)
|
|
{
|
|
WIMP_Poll(current_video, 0);
|
|
}
|
|
#if SDL_THREADS_DISABLED
|
|
if (SDL_timer_running) RISCOS_CheckTimer();
|
|
#endif
|
|
}
|