2001-04-26 16:45:43 +00:00
|
|
|
/*
|
|
|
|
SDL - Simple DirectMedia Layer
|
2008-12-08 00:27:32 +00:00
|
|
|
Copyright (C) 1997-2009 Sam Lantinga
|
2001-04-26 16:45:43 +00:00
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
2006-02-01 06:32:25 +00:00
|
|
|
modify it under the terms of the GNU Lesser General Public
|
2001-04-26 16:45:43 +00:00
|
|
|
License as published by the Free Software Foundation; either
|
2006-02-01 06:32:25 +00:00
|
|
|
version 2.1 of the License, or (at your option) any later version.
|
2001-04-26 16:45:43 +00:00
|
|
|
|
|
|
|
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
|
2006-02-01 06:32:25 +00:00
|
|
|
Lesser General Public License for more details.
|
2001-04-26 16:45:43 +00:00
|
|
|
|
2006-02-01 06:32:25 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with this library; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2001-04-26 16:45:43 +00:00
|
|
|
|
|
|
|
Sam Lantinga
|
2001-12-14 12:38:15 +00:00
|
|
|
slouken@libsdl.org
|
2001-04-26 16:45:43 +00:00
|
|
|
*/
|
2006-02-21 08:46:50 +00:00
|
|
|
#include "SDL_config.h"
|
2001-04-26 16:45:43 +00:00
|
|
|
|
|
|
|
/* General mouse handling code for SDL */
|
|
|
|
|
|
|
|
#include "SDL_events.h"
|
|
|
|
#include "SDL_events_c.h"
|
2006-07-10 21:04:37 +00:00
|
|
|
#include "default_cursor.h"
|
2001-04-26 16:45:43 +00:00
|
|
|
|
|
|
|
|
2008-08-25 06:33:00 +00:00
|
|
|
static int SDL_num_mice = 0;
|
|
|
|
static int SDL_current_mouse = -1;
|
|
|
|
static SDL_Mouse **SDL_mice = NULL;
|
2001-04-26 16:45:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Public functions */
|
2006-07-10 21:04:37 +00:00
|
|
|
int
|
|
|
|
SDL_MouseInit(void)
|
2001-04-26 16:45:43 +00:00
|
|
|
{
|
2006-07-10 21:04:37 +00:00
|
|
|
return (0);
|
2001-04-26 16:45:43 +00:00
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
SDL_Mouse *
|
|
|
|
SDL_GetMouse(int index)
|
|
|
|
{
|
|
|
|
if (index < 0 || index >= SDL_num_mice) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return SDL_mice[index];
|
|
|
|
}
|
|
|
|
|
2009-01-01 07:59:08 +00:00
|
|
|
static int
|
2008-08-25 08:50:37 +00:00
|
|
|
SDL_GetMouseIndexId(int id)
|
2008-08-25 06:33:00 +00:00
|
|
|
{
|
2009-01-01 07:59:08 +00:00
|
|
|
int index;
|
|
|
|
SDL_Mouse *mouse;
|
|
|
|
|
|
|
|
for (index = 0; index < SDL_num_mice; ++index) {
|
|
|
|
mouse = SDL_GetMouse(index);
|
|
|
|
if (mouse->id == id) {
|
|
|
|
return index;
|
|
|
|
}
|
2008-08-25 06:33:00 +00:00
|
|
|
}
|
2009-01-01 07:59:08 +00:00
|
|
|
return -1;
|
2008-08-25 06:33:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2009-01-01 07:59:08 +00:00
|
|
|
SDL_AddMouse(const SDL_Mouse * mouse, char *name, int pressure_max,
|
2008-08-25 06:33:00 +00:00
|
|
|
int pressure_min, int ends)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
|
|
|
SDL_Mouse **mice;
|
|
|
|
int selected_mouse;
|
2009-09-05 23:37:35 +00:00
|
|
|
int index;
|
|
|
|
size_t length;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2009-01-01 07:59:08 +00:00
|
|
|
if (SDL_GetMouseIndexId(mouse->id) != -1) {
|
|
|
|
SDL_SetError("Mouse ID already in use");
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2009-01-01 07:59:08 +00:00
|
|
|
/* Add the mouse to the list of mice */
|
|
|
|
mice = (SDL_Mouse **) SDL_realloc(SDL_mice,
|
|
|
|
(SDL_num_mice + 1) * sizeof(*mice));
|
|
|
|
if (!mice) {
|
|
|
|
SDL_OutOfMemory();
|
|
|
|
return -1;
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
2009-01-01 07:59:08 +00:00
|
|
|
|
|
|
|
SDL_mice = mice;
|
|
|
|
index = SDL_num_mice++;
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_mice[index] = (SDL_Mouse *) SDL_malloc(sizeof(*SDL_mice[index]));
|
|
|
|
if (!SDL_mice[index]) {
|
|
|
|
SDL_OutOfMemory();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*SDL_mice[index] = *mouse;
|
|
|
|
|
2008-08-25 06:33:00 +00:00
|
|
|
/* we're setting the mouse properties */
|
|
|
|
length = 0;
|
|
|
|
length = SDL_strlen(name);
|
2009-06-11 20:08:33 +00:00
|
|
|
SDL_mice[index]->focus = 0;
|
2008-08-25 18:02:14 +00:00
|
|
|
SDL_mice[index]->name = SDL_malloc((length + 2) * sizeof(char));
|
2008-08-26 05:57:41 +00:00
|
|
|
SDL_strlcpy(SDL_mice[index]->name, name, length + 1);
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_mice[index]->pressure_max = pressure_max;
|
|
|
|
SDL_mice[index]->pressure_min = pressure_min;
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_mice[index]->cursor_shown = SDL_TRUE;
|
|
|
|
selected_mouse = SDL_SelectMouse(index);
|
|
|
|
SDL_mice[index]->cur_cursor = NULL;
|
|
|
|
SDL_mice[index]->def_cursor =
|
|
|
|
SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH,
|
|
|
|
DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
|
|
|
|
SDL_SetCursor(SDL_mice[index]->def_cursor);
|
2008-08-25 06:33:00 +00:00
|
|
|
/* we're assuming that all mice are in the computer sensing zone */
|
|
|
|
SDL_mice[index]->proximity = SDL_TRUE;
|
|
|
|
/* we're assuming that all mice are working in the absolute position mode
|
|
|
|
thanx to that, the users that don't want to use many mice don't have to
|
|
|
|
worry about anything */
|
|
|
|
SDL_mice[index]->relative_mode = SDL_FALSE;
|
|
|
|
SDL_mice[index]->current_end = 0;
|
|
|
|
SDL_mice[index]->total_ends = ends;
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_SelectMouse(selected_mouse);
|
|
|
|
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SDL_DelMouse(int index)
|
|
|
|
{
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mouse->def_cursor = NULL;
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_free(mouse->name);
|
2006-07-10 21:04:37 +00:00
|
|
|
while (mouse->cursors) {
|
|
|
|
SDL_FreeCursor(mouse->cursors);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mouse->FreeMouse) {
|
|
|
|
mouse->FreeMouse(mouse);
|
|
|
|
}
|
|
|
|
SDL_free(mouse);
|
|
|
|
|
|
|
|
SDL_mice[index] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SDL_ResetMouse(int index)
|
|
|
|
{
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME */
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SDL_MouseQuit(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < SDL_num_mice; ++i) {
|
|
|
|
SDL_DelMouse(i);
|
|
|
|
}
|
|
|
|
SDL_num_mice = 0;
|
2008-10-04 06:46:59 +00:00
|
|
|
SDL_current_mouse = -1;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
if (SDL_mice) {
|
|
|
|
SDL_free(SDL_mice);
|
|
|
|
SDL_mice = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SDL_GetNumMice(void)
|
|
|
|
{
|
|
|
|
return SDL_num_mice;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SDL_SelectMouse(int index)
|
2005-08-21 06:18:54 +00:00
|
|
|
{
|
2006-07-10 21:04:37 +00:00
|
|
|
if (index >= 0 && index < SDL_num_mice) {
|
|
|
|
SDL_current_mouse = index;
|
|
|
|
}
|
|
|
|
return SDL_current_mouse;
|
2005-08-21 06:18:54 +00:00
|
|
|
}
|
2001-04-26 16:45:43 +00:00
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_WindowID
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_GetMouseFocusWindow(int index)
|
2002-08-20 06:01:20 +00:00
|
|
|
{
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return mouse->focus;
|
2002-08-20 06:01:20 +00:00
|
|
|
}
|
|
|
|
|
2006-10-17 09:15:21 +00:00
|
|
|
static int SDLCALL
|
2006-07-10 21:04:37 +00:00
|
|
|
FlushMouseMotion(void *param, SDL_Event * event)
|
2001-04-26 16:45:43 +00:00
|
|
|
{
|
2006-07-10 21:04:37 +00:00
|
|
|
if (event->type == SDL_MOUSEMOTION
|
|
|
|
&& event->motion.which == (Uint8) SDL_current_mouse) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return 1;
|
|
|
|
}
|
2001-04-26 16:45:43 +00:00
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
int
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_SetRelativeMouseMode(int index, SDL_bool enabled)
|
2001-04-26 16:45:43 +00:00
|
|
|
{
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
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;
|
2001-04-26 16:45:43 +00:00
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_bool
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_GetRelativeMouseMode(int index)
|
2001-04-26 16:45:43 +00:00
|
|
|
{
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return SDL_FALSE;
|
|
|
|
}
|
|
|
|
return mouse->relative_mode;
|
2001-04-26 16:45:43 +00:00
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
Uint8
|
2009-12-16 19:50:51 +00:00
|
|
|
SDL_GetMouseState(int *x, int *y)
|
2001-04-26 16:45:43 +00:00
|
|
|
{
|
2009-12-16 19:50:51 +00:00
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
if (x) {
|
|
|
|
*x = 0;
|
|
|
|
}
|
|
|
|
if (y) {
|
|
|
|
*y = 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x) {
|
|
|
|
*x = mouse->x;
|
|
|
|
}
|
|
|
|
if (y) {
|
|
|
|
*y = mouse->y;
|
|
|
|
}
|
|
|
|
return mouse->buttonstate;
|
|
|
|
}
|
|
|
|
|
|
|
|
Uint8
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_GetRelativeMouseState(int index, int *x, int *y)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
if (x) {
|
|
|
|
*x = 0;
|
|
|
|
}
|
|
|
|
if (y) {
|
|
|
|
*y = 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x) {
|
|
|
|
*x = mouse->xdelta;
|
|
|
|
}
|
|
|
|
if (y) {
|
|
|
|
*y = mouse->ydelta;
|
|
|
|
}
|
|
|
|
mouse->xdelta = 0;
|
|
|
|
mouse->ydelta = 0;
|
|
|
|
return mouse->buttonstate;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_SetMouseFocus(int id, SDL_WindowID windowID)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2008-08-25 08:50:37 +00:00
|
|
|
int index = SDL_GetMouseIndexId(id);
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
|
|
|
int i;
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_bool focus;
|
|
|
|
|
|
|
|
if (!mouse || (mouse->focus == windowID)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* See if the current window has lost focus */
|
|
|
|
if (mouse->focus) {
|
|
|
|
focus = SDL_FALSE;
|
|
|
|
for (i = 0; i < SDL_num_mice; ++i) {
|
|
|
|
SDL_Mouse *check;
|
|
|
|
if (i != index) {
|
|
|
|
check = SDL_GetMouse(i);
|
|
|
|
if (check && check->focus == mouse->focus) {
|
|
|
|
focus = SDL_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!focus) {
|
|
|
|
SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mouse->focus = windowID;
|
|
|
|
|
|
|
|
if (mouse->focus) {
|
|
|
|
focus = SDL_FALSE;
|
|
|
|
for (i = 0; i < SDL_num_mice; ++i) {
|
|
|
|
SDL_Mouse *check;
|
|
|
|
if (i != index) {
|
|
|
|
check = SDL_GetMouse(i);
|
|
|
|
if (check && check->focus == mouse->focus) {
|
|
|
|
focus = SDL_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!focus) {
|
|
|
|
SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_SendProximity(int id, int x, int y, int type)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2008-08-25 08:50:37 +00:00
|
|
|
int index = SDL_GetMouseIndexId(id);
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
2008-08-25 06:33:00 +00:00
|
|
|
int posted = 0;
|
2008-08-26 07:34:23 +00:00
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-08 00:52:12 +00:00
|
|
|
mouse->last_x = x;
|
|
|
|
mouse->last_y = y;
|
2008-08-25 06:33:00 +00:00
|
|
|
if (SDL_ProcessEvents[type] == SDL_ENABLE) {
|
|
|
|
SDL_Event event;
|
|
|
|
event.proximity.which = (Uint8) index;
|
|
|
|
event.proximity.x = x;
|
|
|
|
event.proximity.y = y;
|
|
|
|
event.proximity.cursor = mouse->current_end;
|
|
|
|
event.proximity.type = type;
|
2009-06-10 14:00:21 +00:00
|
|
|
/* FIXME: is this right? */
|
|
|
|
event.proximity.windowID = mouse->focus;
|
2008-08-25 06:33:00 +00:00
|
|
|
posted = (SDL_PushEvent(&event) > 0);
|
|
|
|
if (type == SDL_PROXIMITYIN) {
|
|
|
|
mouse->proximity = SDL_TRUE;
|
|
|
|
} else {
|
|
|
|
mouse->proximity = SDL_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return posted;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure)
|
|
|
|
{
|
2008-08-25 08:50:37 +00:00
|
|
|
int index = SDL_GetMouseIndexId(id);
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
2006-07-10 21:04:37 +00:00
|
|
|
int posted;
|
|
|
|
int xrel;
|
|
|
|
int yrel;
|
2008-12-08 00:52:12 +00:00
|
|
|
int x_max = 0, y_max = 0;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
if (!mouse || mouse->flush_motion) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-08-25 06:33:00 +00:00
|
|
|
/* if the mouse is out of proximity we don't to want to have any motion from it */
|
|
|
|
if (mouse->proximity == SDL_FALSE) {
|
2008-12-08 00:52:12 +00:00
|
|
|
mouse->last_x = x;
|
|
|
|
mouse->last_y = y;
|
2008-08-25 06:33:00 +00:00
|
|
|
return 0;
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
|
2008-08-25 06:33:00 +00:00
|
|
|
/* the relative motion is calculated regarding the system cursor last position */
|
2008-12-06 17:50:50 +00:00
|
|
|
if (relative) {
|
|
|
|
xrel = x;
|
|
|
|
yrel = y;
|
2008-12-08 00:52:12 +00:00
|
|
|
x = (mouse->last_x + x);
|
|
|
|
y = (mouse->last_y + y);
|
2008-12-06 17:50:50 +00:00
|
|
|
} else {
|
2008-12-08 00:52:12 +00:00
|
|
|
xrel = x - mouse->last_x;
|
|
|
|
yrel = y - mouse->last_y;
|
2008-12-06 17:50:50 +00:00
|
|
|
}
|
2008-08-25 06:33:00 +00:00
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
/* Drop events that don't change state */
|
|
|
|
if (!xrel && !yrel) {
|
2006-01-29 08:18:06 +00:00
|
|
|
#if 0
|
2006-07-10 21:04:37 +00:00
|
|
|
printf("Mouse event didn't change state - dropped!\n");
|
2006-01-29 08:18:06 +00:00
|
|
|
#endif
|
2006-07-10 21:04:37 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-08-25 06:33:00 +00:00
|
|
|
/* Update internal mouse coordinates */
|
|
|
|
if (mouse->relative_mode == SDL_FALSE) {
|
2006-07-10 21:04:37 +00:00
|
|
|
mouse->x = x;
|
|
|
|
mouse->y = y;
|
2008-08-25 06:33:00 +00:00
|
|
|
} else {
|
2008-12-08 00:52:12 +00:00
|
|
|
mouse->x += xrel;
|
|
|
|
mouse->y += yrel;
|
|
|
|
}
|
2008-12-07 21:53:28 +00:00
|
|
|
|
2008-12-08 00:52:12 +00:00
|
|
|
SDL_GetWindowSize(mouse->focus, &x_max, &y_max);
|
2008-12-07 21:53:28 +00:00
|
|
|
|
2008-12-08 00:52:12 +00:00
|
|
|
/* make sure that the pointers find themselves inside the windows */
|
|
|
|
/* only check if mouse->xmax is set ! */
|
|
|
|
if (x_max && mouse->x > x_max) {
|
|
|
|
mouse->x = x_max;
|
|
|
|
} else if (mouse->x < 0) {
|
|
|
|
mouse->x = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y_max && mouse->y > y_max) {
|
|
|
|
mouse->y = y_max;
|
|
|
|
} else if (mouse->y < 0) {
|
|
|
|
mouse->y = 0;
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
2008-12-08 00:52:12 +00:00
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
mouse->xdelta += xrel;
|
|
|
|
mouse->ydelta += yrel;
|
2008-08-25 06:33:00 +00:00
|
|
|
mouse->pressure = pressure;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
/* Move the mouse cursor, if needed */
|
|
|
|
if (mouse->cursor_shown && !mouse->relative_mode &&
|
|
|
|
mouse->MoveCursor && mouse->cur_cursor) {
|
|
|
|
mouse->MoveCursor(mouse->cur_cursor);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Post the event, if desired */
|
|
|
|
posted = 0;
|
2008-08-25 06:33:00 +00:00
|
|
|
if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE &&
|
|
|
|
mouse->proximity == SDL_TRUE) {
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_Event event;
|
|
|
|
event.motion.type = SDL_MOUSEMOTION;
|
|
|
|
event.motion.which = (Uint8) index;
|
|
|
|
event.motion.state = mouse->buttonstate;
|
|
|
|
event.motion.x = mouse->x;
|
|
|
|
event.motion.y = mouse->y;
|
2009-06-09 03:27:48 +00:00
|
|
|
event.motion.z = mouse->z;
|
2008-08-25 06:33:00 +00:00
|
|
|
event.motion.pressure = mouse->pressure;
|
|
|
|
event.motion.pressure_max = mouse->pressure_max;
|
|
|
|
event.motion.pressure_min = mouse->pressure_min;
|
2009-06-09 15:45:33 +00:00
|
|
|
event.motion.rotation = 0;
|
2009-12-16 00:44:53 +00:00
|
|
|
event.motion.tilt_x = 0;
|
|
|
|
event.motion.tilt_y = 0;
|
2008-08-25 06:33:00 +00:00
|
|
|
event.motion.cursor = mouse->current_end;
|
2009-06-09 15:45:33 +00:00
|
|
|
event.motion.xrel = xrel;
|
|
|
|
event.motion.yrel = yrel;
|
|
|
|
event.motion.windowID = mouse->focus;
|
2006-07-10 21:04:37 +00:00
|
|
|
posted = (SDL_PushEvent(&event) > 0);
|
|
|
|
}
|
2009-04-28 04:43:21 +00:00
|
|
|
mouse->last_x = mouse->x;
|
|
|
|
mouse->last_y = mouse->y;
|
2006-07-10 21:04:37 +00:00
|
|
|
return posted;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2008-08-25 08:50:37 +00:00
|
|
|
int index = SDL_GetMouseIndexId(id);
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
2006-07-10 21:04:37 +00:00
|
|
|
int posted;
|
|
|
|
Uint8 type;
|
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Figure out which event to perform */
|
|
|
|
switch (state) {
|
|
|
|
case SDL_PRESSED:
|
|
|
|
if (mouse->buttonstate & SDL_BUTTON(button)) {
|
|
|
|
/* Ignore this event, no state change */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
type = SDL_MOUSEBUTTONDOWN;
|
|
|
|
mouse->buttonstate |= SDL_BUTTON(button);
|
|
|
|
break;
|
|
|
|
case SDL_RELEASED:
|
2008-08-26 05:57:41 +00:00
|
|
|
if (!(mouse->buttonstate & SDL_BUTTON(button))) {
|
2008-08-25 18:02:14 +00:00
|
|
|
/* Ignore this event, no state change */
|
|
|
|
return 0;
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
type = SDL_MOUSEBUTTONUP;
|
|
|
|
mouse->buttonstate &= ~SDL_BUTTON(button);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Invalid state -- bail */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Post the event, if desired */
|
|
|
|
posted = 0;
|
|
|
|
if (SDL_ProcessEvents[type] == SDL_ENABLE) {
|
|
|
|
SDL_Event event;
|
|
|
|
event.type = type;
|
|
|
|
event.button.which = (Uint8) index;
|
|
|
|
event.button.state = state;
|
|
|
|
event.button.button = button;
|
|
|
|
event.button.x = mouse->x;
|
|
|
|
event.button.y = mouse->y;
|
|
|
|
event.button.windowID = mouse->focus;
|
|
|
|
posted = (SDL_PushEvent(&event) > 0);
|
|
|
|
}
|
|
|
|
return posted;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2007-07-06 09:22:18 +00:00
|
|
|
SDL_SendMouseWheel(int index, int x, int y)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
|
|
|
int posted;
|
|
|
|
|
2007-07-06 09:22:18 +00:00
|
|
|
if (!mouse || (!x && !y)) {
|
2006-07-10 21:04:37 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Post the event, if desired */
|
|
|
|
posted = 0;
|
|
|
|
if (SDL_ProcessEvents[SDL_MOUSEWHEEL] == SDL_ENABLE) {
|
|
|
|
SDL_Event event;
|
|
|
|
event.type = SDL_MOUSEWHEEL;
|
|
|
|
event.wheel.which = (Uint8) index;
|
2007-07-06 09:22:18 +00:00
|
|
|
event.wheel.x = x;
|
|
|
|
event.wheel.y = y;
|
2006-07-10 21:04:37 +00:00
|
|
|
event.wheel.windowID = mouse->focus;
|
|
|
|
posted = (SDL_PushEvent(&event) > 0);
|
|
|
|
}
|
|
|
|
return posted;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
|
|
|
|
{
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
|
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mouse->WarpMouse) {
|
|
|
|
mouse->WarpMouse(mouse, windowID, x, y);
|
|
|
|
} else {
|
|
|
|
SDL_SetMouseFocus(SDL_current_mouse, windowID);
|
2008-08-25 06:33:00 +00:00
|
|
|
SDL_SendMouseMotion(SDL_current_mouse, 0, x, y, 0);
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_Cursor *
|
|
|
|
SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
|
|
|
|
int w, int h, int hot_x, int hot_y)
|
|
|
|
{
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
|
|
|
|
SDL_Surface *surface;
|
|
|
|
SDL_Cursor *cursor;
|
|
|
|
int x, y;
|
|
|
|
Uint32 *pixel;
|
|
|
|
Uint8 datab, maskb;
|
|
|
|
const Uint32 black = 0xFF000000;
|
|
|
|
const Uint32 white = 0xFFFFFFFF;
|
|
|
|
const Uint32 transparent = 0x00000000;
|
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
SDL_SetError("No mice are initialized");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mouse->CreateCursor) {
|
|
|
|
SDL_SetError("Current mouse doesn't have cursor support");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Sanity check the hot spot */
|
|
|
|
if ((hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h)) {
|
|
|
|
SDL_SetError("Cursor hot spot doesn't lie within cursor");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure the width is a multiple of 8 */
|
|
|
|
w = ((w + 7) & ~7);
|
|
|
|
|
|
|
|
/* Create the surface from a bitmap */
|
|
|
|
surface =
|
|
|
|
SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
|
|
|
|
0xFF000000);
|
|
|
|
if (!surface) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
for (y = 0; y < h; ++y) {
|
|
|
|
pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
|
|
|
|
for (x = 0; x < w; ++x) {
|
|
|
|
if ((x % 8) == 0) {
|
|
|
|
datab = *data++;
|
|
|
|
maskb = *mask++;
|
|
|
|
}
|
|
|
|
if (maskb & 0x80) {
|
|
|
|
*pixel++ = (datab & 0x80) ? black : white;
|
|
|
|
} else {
|
|
|
|
*pixel++ = (datab & 0x80) ? black : transparent;
|
|
|
|
}
|
|
|
|
datab <<= 1;
|
|
|
|
maskb <<= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cursor = mouse->CreateCursor(surface, hot_x, hot_y);
|
|
|
|
if (cursor) {
|
|
|
|
cursor->mouse = mouse;
|
|
|
|
cursor->next = mouse->cursors;
|
|
|
|
mouse->cursors = cursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_FreeSurface(surface);
|
|
|
|
|
|
|
|
return cursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* SDL_SetCursor(NULL) can be used to force the cursor redraw,
|
|
|
|
if this is desired for any reason. This is used when setting
|
|
|
|
the video mode and when the SDL window gains the mouse focus.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
SDL_SetCursor(SDL_Cursor * cursor)
|
|
|
|
{
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
|
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
SDL_SetError("No mice are initialized");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the new cursor */
|
|
|
|
if (cursor) {
|
|
|
|
/* Make sure the cursor is still valid for this mouse */
|
|
|
|
SDL_Cursor *found;
|
|
|
|
for (found = mouse->cursors; found; found = found->next) {
|
|
|
|
if (found == cursor) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
SDL_SetError("Cursor not associated with the current mouse");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mouse->cur_cursor = cursor;
|
|
|
|
} else {
|
|
|
|
cursor = mouse->cur_cursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
|
|
|
|
if (mouse->ShowCursor) {
|
|
|
|
mouse->ShowCursor(cursor);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (mouse->ShowCursor) {
|
|
|
|
mouse->ShowCursor(NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_Cursor *
|
|
|
|
SDL_GetCursor(void)
|
|
|
|
{
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
|
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return mouse->cur_cursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SDL_FreeCursor(SDL_Cursor * cursor)
|
|
|
|
{
|
|
|
|
SDL_Mouse *mouse;
|
|
|
|
SDL_Cursor *curr, *prev;
|
|
|
|
|
|
|
|
if (!cursor) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mouse = cursor->mouse;
|
|
|
|
|
|
|
|
if (cursor == mouse->def_cursor) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (cursor == mouse->cur_cursor) {
|
|
|
|
SDL_SetCursor(mouse->def_cursor);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (prev = NULL, curr = mouse->cursors; curr;
|
|
|
|
prev = curr, curr = curr->next) {
|
|
|
|
if (curr == cursor) {
|
|
|
|
if (prev) {
|
|
|
|
prev->next = curr->next;
|
|
|
|
} else {
|
|
|
|
mouse->cursors = curr->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mouse->FreeCursor) {
|
|
|
|
mouse->FreeCursor(curr);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2001-04-26 16:45:43 +00:00
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
int
|
|
|
|
SDL_ShowCursor(int toggle)
|
2001-04-26 16:45:43 +00:00
|
|
|
{
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
|
|
|
|
SDL_bool shown;
|
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
shown = mouse->cursor_shown;
|
|
|
|
if (toggle >= 0) {
|
|
|
|
if (toggle) {
|
|
|
|
mouse->cursor_shown = SDL_TRUE;
|
|
|
|
} else {
|
|
|
|
mouse->cursor_shown = SDL_FALSE;
|
|
|
|
}
|
|
|
|
if (mouse->cursor_shown != shown) {
|
|
|
|
SDL_SetCursor(NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return shown;
|
2001-04-26 16:45:43 +00:00
|
|
|
}
|
|
|
|
|
2008-08-25 06:33:00 +00:00
|
|
|
char *
|
|
|
|
SDL_GetMouseName(int index)
|
|
|
|
{
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
|
|
|
if (!mouse) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return mouse->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SDL_ChangeEnd(int id, int end)
|
|
|
|
{
|
2008-08-25 08:50:37 +00:00
|
|
|
int index = SDL_GetMouseIndexId(id);
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
2008-08-25 06:33:00 +00:00
|
|
|
|
|
|
|
if (mouse) {
|
|
|
|
mouse->current_end = end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SDL_GetCursorsNumber(int index)
|
|
|
|
{
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return mouse->total_ends;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SDL_GetCurrentCursor(int index)
|
|
|
|
{
|
|
|
|
SDL_Mouse *mouse = SDL_GetMouse(index);
|
|
|
|
|
|
|
|
if (!mouse) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return mouse->current_end;
|
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
/* vi: set ts=4 sw=4 expandtab: */
|