Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Added a userdata parameter for event filters.
Browse files Browse the repository at this point in the history
Added a function to filter the existing queued events.
Added explicit support for relative mouse mode to the API.
  • Loading branch information
slouken committed Jun 30, 2006
1 parent 53a4ddf commit 819c7c0
Show file tree
Hide file tree
Showing 17 changed files with 574 additions and 36 deletions.
14 changes: 11 additions & 3 deletions include/SDL_events.h
Expand Up @@ -377,7 +377,7 @@ extern DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event * event);
The filter is protypted as:
*/
typedef int (SDLCALL * SDL_EventFilter) (SDL_Event * event);
typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event);
/*
If the filter returns 1, then the event will be added to the internal queue.
If it returns 0, then the event will be dropped from the queue, but the
Expand All @@ -394,13 +394,21 @@ typedef int (SDLCALL * SDL_EventFilter) (SDL_Event * event);
If the quit event is generated by an interrupt signal, it will bypass the
internal queue and be delivered to the application at the next event poll.
*/
extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter);
extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter,
void *userdata);

/*
Return the current event filter - can be used to "chain" filters.
If there is no event filter set, this function returns NULL.
*/
extern DECLSPEC SDL_EventFilter SDLCALL SDL_GetEventFilter(void);
extern DECLSPEC SDL_EventFilter SDLCALL SDL_GetEventFilter(void **userdata);

/*
Run the filter function on the current event queue, removing any
events for which the filter returns 0.
*/
extern DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter,
void *userdata);

/*
This function allows you to set the state of processing certain events.
Expand Down
33 changes: 31 additions & 2 deletions include/SDL_mouse.h
Expand Up @@ -74,10 +74,39 @@ extern DECLSPEC int SDLCALL SDL_SelectMouse(int index);
*/
extern DECLSPEC SDL_WindowID SDLCALL SDL_GetMouseFocusWindow(void);

/**
* \fn int SDL_SetRelativeMouseMode(SDL_bool enabled)
*
* \brief Set relative mouse mode for the currently selected mouse.
*
* \param enabled Whether or not to enable relative mode
*
* \return 0 on success, or -1 if relative mode is not supported.
*
* While the mouse is in relative mode, the cursor is hidden, and the
* driver will try to report continuous motion in the current window.
* Only relative motion events will be delivered, the mouse position
* will not change.
*
* \note This function will flush any pending mouse motion.
*
* \sa SDL_GetRelativeMouseMode()
*/
extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled);

/**
* \fn SDL_bool SDL_GetRelativeMouseMode()
*
* \brief Query whether relative mouse mode is enabled for the currently selected mouse.
*
* \sa SDL_SetRelativeMouseMode()
*/
extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode();

/**
* \fn Uint8 SDL_GetMouseState(int *x, int *y)
*
* \brief Retrieve the current state of the mouse.
* \brief Retrieve the current state of the currently selected mouse.
*
* The current button state is returned as a button bitmask, which can
* be tested using the SDL_BUTTON(X) macros, and x and y are set to the
Expand All @@ -89,7 +118,7 @@ extern DECLSPEC Uint8 SDLCALL SDL_GetMouseState(int *x, int *y);
/**
* \fn Uint8 SDL_GetRelativeMouseState(int *x, int *y)
*
* \brief Retrieve the current state of the mouse.
* \brief Retrieve the state of the currently selected mouse.
*
* The current button state is returned as a button bitmask, which can
* be tested using the SDL_BUTTON(X) macros, and x and y are set to the
Expand Down
4 changes: 2 additions & 2 deletions include/SDL_video.h
Expand Up @@ -120,8 +120,8 @@ typedef enum
SDL_WINDOW_SHOWN = 0x00000004, /**< window is visible */
SDL_WINDOW_BORDERLESS = 0x00000008, /**< no window decoration */
SDL_WINDOW_RESIZABLE = 0x00000010, /**< window can be resized */
SDL_WINDOW_MAXIMIZED = 0x00000020, /**< maximized */
SDL_WINDOW_MINIMIZED = 0x00000040, /**< minimized */
SDL_WINDOW_MINIMIZED = 0x00000020, /**< minimized */
SDL_WINDOW_MAXIMIZED = 0x00000040, /**< maximized */
SDL_WINDOW_INPUT_GRABBED = 0x00000100, /**< window has grabbed input focus */
SDL_WINDOW_KEYBOARD_FOCUS = 0x00000200, /**< window has keyboard focus */
SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */
Expand Down
15 changes: 9 additions & 6 deletions src/SDL_compat.c
Expand Up @@ -153,10 +153,11 @@ SDL_ListModes(SDL_PixelFormat * format, Uint32 flags)
return modes;
}

static int (*orig_eventfilter) (SDL_Event * event);
static SDL_EventFilter orig_eventfilter;
static void *orig_eventfilterparam;

static int
SDL_CompatEventFilter(SDL_Event * event)
SDL_CompatEventFilter(void *userdata, SDL_Event * event)
{
SDL_Event fake;

Expand Down Expand Up @@ -227,7 +228,7 @@ SDL_CompatEventFilter(SDL_Event * event)
}
}
if (orig_eventfilter) {
return orig_eventfilter(event);
return orig_eventfilter(orig_eventfilterparam, event);
} else {
return 1;
}
Expand All @@ -251,7 +252,8 @@ SDL_VideoPaletteChanged(void *userdata, SDL_Palette * palette)
SDL_Surface *
SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
{
int (*filter) (SDL_Event * event);
SDL_EventFilter filter;
void *filterparam;
const SDL_DisplayMode *desktop_mode;
SDL_DisplayMode mode;
Uint32 window_flags;
Expand Down Expand Up @@ -280,11 +282,12 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
SDL_DestroyWindow(SDL_VideoWindow);

/* Set up the event filter */
filter = SDL_GetEventFilter();
filter = SDL_GetEventFilter(&filterparam);
if (filter != SDL_CompatEventFilter) {
orig_eventfilter = filter;
orig_eventfilterparam = filterparam;
}
SDL_SetEventFilter(SDL_CompatEventFilter);
SDL_SetEventFilter(SDL_CompatEventFilter, NULL);

/* Create a new window */
window_flags = SDL_WINDOW_SHOWN;
Expand Down
2 changes: 2 additions & 0 deletions src/audio/SDL_mixer_MMX_VC.c
Expand Up @@ -184,3 +184,5 @@ SDL_MixAudio_MMX_S8_VC(char *dst, char *src, unsigned int nSize, int volume)
}

#endif /* SDL_ASSEMBLY_ROUTINES */

/* vi: set ts=4 sw=4 expandtab: */
30 changes: 27 additions & 3 deletions src/events/SDL_events.c
Expand Up @@ -34,6 +34,7 @@

/* Public data -- the event filter */
SDL_EventFilter SDL_EventOK = NULL;
void *SDL_EventOKParam;
Uint8 SDL_ProcessEvents[SDL_NUMEVENTS];
static Uint32 SDL_eventstate = 0;

Expand Down Expand Up @@ -434,21 +435,43 @@ SDL_PushEvent(SDL_Event * event)
}

void
SDL_SetEventFilter(SDL_EventFilter filter)
SDL_SetEventFilter(SDL_EventFilter filter, void *userdata)
{
SDL_Event bitbucket;

/* Set filter and discard pending events */
SDL_EventOK = filter;
SDL_EventOKParam = userdata;
while (SDL_PollEvent(&bitbucket) > 0);
}

SDL_EventFilter
SDL_GetEventFilter(void)
SDL_GetEventFilter(void **userdata)
{
if (userdata) {
*userdata = SDL_EventOKParam;
}
return (SDL_EventOK);
}

void
SDL_FilterEvents(SDL_EventFilter filter, void *userdata)
{
if (SDL_mutexP(SDL_EventQ.lock) == 0) {
int spot;

spot = SDL_EventQ.head;
while (spot != SDL_EventQ.tail) {
if (filter(userdata, &SDL_EventQ.event[spot])) {
spot = (spot + 1) % MAXEVENTS;
} else {
spot = SDL_CutEvent(spot);
}
}
}
SDL_mutexV(SDL_EventQ.lock);
}

Uint8
SDL_EventState(Uint8 type, int state)
{
Expand Down Expand Up @@ -507,7 +530,8 @@ SDL_PrivateSysWMEvent(SDL_SysWMmsg * message)
SDL_memset(&event, 0, sizeof(event));
event.type = SDL_SYSWMEVENT;
event.syswm.msg = message;
if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) {
if ((SDL_EventOK == NULL)
|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
posted = 1;
SDL_PushEvent(&event);
}
Expand Down
1 change: 1 addition & 0 deletions src/events/SDL_events_c.h
Expand Up @@ -41,6 +41,7 @@ extern void SDL_QuitQuit(void);

/* The event filter function */
extern SDL_EventFilter SDL_EventOK;
extern void *SDL_EventOKParam;

/* The array of event processing states */
extern Uint8 SDL_ProcessEvents[SDL_NUMEVENTS];
Expand Down
5 changes: 3 additions & 2 deletions src/events/SDL_keyboard.c
Expand Up @@ -632,7 +632,7 @@ SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state,
keyboard->repeat.firsttime = 1;
keyboard->repeat.timestamp = 1;
}
if ((SDL_EventOK == NULL) || SDL_EventOK(&event)) {
if ((SDL_EventOK == NULL) || SDL_EventOK(SDL_EventOKParam, &event)) {
posted = 1;
SDL_PushEvent(&event);
}
Expand Down Expand Up @@ -669,7 +669,8 @@ SDL_CheckKeyRepeat(void)
if (interval > (Uint32) keyboard->repeat.interval) {
keyboard->repeat.timestamp = now;
if ((SDL_EventOK == NULL)
|| SDL_EventOK(&keyboard->repeat.evt)) {
|| SDL_EventOK(SDL_EventOKParam,
&keyboard->repeat.evt)) {
SDL_PushEvent(&keyboard->repeat.evt);
}
}
Expand Down
69 changes: 62 additions & 7 deletions src/events/SDL_mouse.c
Expand Up @@ -165,6 +165,56 @@ SDL_GetMouseFocusWindow()
return mouse->focus;
}

static int
FlushMouseMotion(void *param, SDL_Event * event)
{
if (event->type == SDL_MOUSEMOTION
&& event->motion.which == (Uint8) SDL_current_mouse) {
return 0;
} else {
return 1;
}
}

int
SDL_SetRelativeMouseMode(SDL_bool enabled)
{
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);

if (!mouse) {
return -1;
}

/* Flush pending mouse motion */
mouse->flush_motion = SDL_TRUE;
SDL_PumpEvents();
mouse->flush_motion = SDL_FALSE;
SDL_FilterEvents(FlushMouseMotion, mouse);

/* Set the relative mode */
mouse->relative_mode = enabled;

/* Update cursor visibility */
SDL_SetCursor(NULL);

if (!enabled) {
/* Restore the expected mouse position */
SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
}
return 0;
}

SDL_bool
SDL_GetRelativeMouseMode()
{
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);

if (!mouse) {
return SDL_FALSE;
}
return mouse->relative_mode;
}

Uint8
SDL_GetMouseState(int *x, int *y)
{
Expand Down Expand Up @@ -224,7 +274,7 @@ SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative, int x,
int xrel;
int yrel;

if (!mouse) {
if (!mouse || mouse->flush_motion) {
return 0;
}

Expand Down Expand Up @@ -252,13 +302,16 @@ SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative, int x,
}

/* Update internal mouse state */
mouse->x = x;
mouse->y = y;
if (!mouse->relative_mode) {
mouse->x = x;
mouse->y = y;
}
mouse->xdelta += xrel;
mouse->ydelta += yrel;

/* Move the mouse cursor, if needed */
if (mouse->MoveCursor && mouse->cur_cursor) {
if (mouse->cursor_shown && !mouse->relative_mode &&
mouse->MoveCursor && mouse->cur_cursor) {
mouse->MoveCursor(mouse->cur_cursor);
}

Expand All @@ -274,7 +327,8 @@ SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative, int x,
event.motion.xrel = xrel;
event.motion.yrel = yrel;
event.motion.windowID = mouse->focus;
if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) {
if ((SDL_EventOK == NULL)
|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
posted = 1;
SDL_PushEvent(&event);
}
Expand Down Expand Up @@ -332,7 +386,8 @@ SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state,
event.button.x = mouse->x;
event.button.y = mouse->y;
event.button.windowID = mouse->focus;
if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) {
if ((SDL_EventOK == NULL)
|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
posted = 1;
SDL_PushEvent(&event);
}
Expand Down Expand Up @@ -457,7 +512,7 @@ SDL_SetCursor(SDL_Cursor * cursor)
cursor = mouse->cur_cursor;
}

if (cursor && mouse->cursor_shown) {
if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
if (mouse->ShowCursor) {
mouse->ShowCursor(cursor);
}
Expand Down
2 changes: 2 additions & 0 deletions src/events/SDL_mouse_c.h
Expand Up @@ -63,6 +63,8 @@ struct SDL_Mouse
int xdelta;
int ydelta;
Uint8 buttonstate;
SDL_bool relative_mode;
SDL_bool flush_motion;

SDL_Cursor *cursors;
SDL_Cursor *def_cursor;
Expand Down
3 changes: 2 additions & 1 deletion src/events/SDL_quit.c
Expand Up @@ -88,7 +88,8 @@ SDL_SendQuit(void)
if (SDL_ProcessEvents[SDL_QUIT] == SDL_ENABLE) {
SDL_Event event;
event.type = SDL_QUIT;
if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) {
if ((SDL_EventOK == NULL)
|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
posted = 1;
SDL_PushEvent(&event);
}
Expand Down

0 comments on commit 819c7c0

Please sign in to comment.