The code listing that follows demonstrates simple mouse event processing with the SDL event interface.
/* Example of simple mouse input with SDL. */
#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
SDL_Surface *screen;
SDL_Event event;
/* Initialize SDL's video system and check for errors. */
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
}
/* Make sure SDL_Quit gets called when the program exits! */
atexit(SDL_Quit);
/* Attempt to set a 256x256 hicolor (16-bit) video mode. */
screen = SDL_SetVideoMode(256, 256, 16, 0);
if (screen == NULL) {
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
/* Start the event loop. Keep reading events until there
is an error, or the user presses a mouse button. */
while (SDL_WaitEvent(&event) != 0) {
/* SDL_WaitEvent has filled in our event structure
with the next event. We check its type field to
find out what happened. */
switch (event.type) {
/* The next two event types deal
with mouse activity. */
case SDL_MOUSEMOTION:
printf("Mouse motion. ");
/* SDL provides the current position. */
printf("New position is (%i,%i). ",
event.motion.x, event.motion.y);
/* We can also get relative motion. */
printf("That is a (%i,%i) change.\n",
event.motion.xrel, event.motion.yrel);
break;
case SDL_MOUSEBUTTONDOWN:
printf("Mouse button pressed. ");
printf("Button %i at (%i,%i)\n",
event.button.button,
event.button.x, event.button.y);
break;
/* The SDL_QUIT event indicates that
the windows "Close" button has been
pressed. We can ignore this if we
need to, but that tends to make
users rather impatient. */
case SDL_QUIT:
printf("Quit event. Bye.\n");
exit(0);
}
}
return 0;
}
This program begins exactly as one of our early SDL video examples did. In fact, it is one of our early video examples, minus the drawing code. We need to open a window in order to receive events, but the window's contents are inconsequential. Once the window is open, the program kicks off the event loops and begins to monitor the mouse.
Suppose that the user quickly moves the mouse from the coordinates (10,10) to (25,30), relative to the position of the window. SDL would report this as an SDL_MOUSEMOTION event. The event structure's motion.x and motion.y fields would contain 25 and 30, respectively. The xrel and yrel fields would contain 15 and 20, since the mouse traveled 15 pixels to the right and 20 down. It is possible that this motion would be broken into two or more mouse events (depending on the speed at which the user moved the mouse, among other things), but this can be dealt with by averaging mouse motion over several animation frames.
SDL's event-processing model is sufficient in most cases, but sometimes a program simply needs to know the current position of the mouse, regardless of how it got there. Programs can bypass the event interface entirely with the SDL_GetMouseState function. Unfortunately, this function does not automatically read the mouse's current state; it simply reports the most recently read coordinates. If you choose to bypass the event system, you must call the SDL_PumpEvents function periodically to ensure that your program receives up-to-date input device information.
It's possible to have SDL set up a completely separate event-processing thread, but this is only partially implemented and generally unportable. Your best bet is to handle input processing in your game's main thread.