From 7a8d9fca74ad62849de05c21f674eaffe4dbda46 Mon Sep 17 00:00:00 2001 From: Darren Alton Date: Mon, 23 Jun 2008 11:55:26 +0000 Subject: [PATCH] Started adding framework for Touchscreen API, based on and (consistent with) the existing Joystick API. --- Makefile.ds | 6 + include/SDL.h | 1 + include/SDL_config_nintendods.h | 4 + include/SDL_events.h | 25 ++ include/SDL_touchscreen.h | 152 +++++++ src/SDL.c | 25 ++ src/events/SDL_events.c | 15 + src/file/SDL_rwops.c | 9 +- src/touchscreen/SDL_systouchscreen.h | 78 ++++ src/touchscreen/SDL_touchscreen.c | 482 +++++++++++++++++++++ src/touchscreen/SDL_touchscreen_c.h | 42 ++ src/touchscreen/dummy/SDL_systouchscreen.c | 90 ++++ src/touchscreen/nds/SDL_systouchscreen.c | 115 +++++ 13 files changed, 1043 insertions(+), 1 deletion(-) create mode 100644 include/SDL_touchscreen.h create mode 100644 src/touchscreen/SDL_systouchscreen.h create mode 100644 src/touchscreen/SDL_touchscreen.c create mode 100644 src/touchscreen/SDL_touchscreen_c.h create mode 100644 src/touchscreen/dummy/SDL_systouchscreen.c create mode 100644 src/touchscreen/nds/SDL_systouchscreen.c diff --git a/Makefile.ds b/Makefile.ds index 96993f9af..2c3a4e9e6 100644 --- a/Makefile.ds +++ b/Makefile.ds @@ -51,6 +51,9 @@ src/events/SDL_windowevents.c \ src/file/SDL_rwops.c \ src/joystick/nds/SDL_sysjoystick.c \ src/joystick/SDL_joystick.c \ +src/touchscreen/nds/SDL_systouchscreen.c \ +src/touchscreen/dummy/SDL_systouchscreen.c \ +src/touchscreen/SDL_touchscreen.c \ src/stdlib/SDL_getenv.c \ src/stdlib/SDL_iconv.c \ src/stdlib/SDL_malloc.c \ @@ -67,6 +70,9 @@ src/timer/SDL_timer.c \ src/video/nds/SDL_ndsevents.c \ src/video/nds/SDL_ndsrender.c \ src/video/nds/SDL_ndsvideo.c \ +src/video/dummy/SDL_nullevents.c \ +src/video/dummy/SDL_nullrender.c \ +src/video/dummy/SDL_nullvideo.c \ src/video/SDL_blit_0.c \ src/video/SDL_blit_1.c \ src/video/SDL_blit_A.c \ diff --git a/include/SDL.h b/include/SDL.h index e079d2882..7c5fce48a 100644 --- a/include/SDL.h +++ b/include/SDL.h @@ -109,6 +109,7 @@ extern "C" { #define SDL_INIT_VIDEO 0x00000020 #define SDL_INIT_CDROM 0x00000100 #define SDL_INIT_JOYSTICK 0x00000200 +#define SDL_INIT_TOUCHSCREEN 0x00000400 #define SDL_INIT_NOPARACHUTE 0x00100000 /* Don't catch fatal signals */ #define SDL_INIT_EVENTTHREAD 0x01000000 /* Not supported on all OS's */ #define SDL_INIT_EVERYTHING 0x0000FFFF diff --git a/include/SDL_config_nintendods.h b/include/SDL_config_nintendods.h index 7d3cf35f6..5e1628396 100644 --- a/include/SDL_config_nintendods.h +++ b/include/SDL_config_nintendods.h @@ -99,6 +99,9 @@ typedef unsigned __PTRDIFF_TYPE__ uintptr_t; /* Enable various input drivers */ #define SDL_JOYSTICK_NDS 1 +/*#define SDL_JOYSTICK_DUMMY 1*/ +#define SDL_TOUCHSCREEN_NDS 1 +/*#define SDL_TOUCHSCREEN_DUMMY 1*/ /* DS has no dynamic linking afaik */ #define SDL_LOADSO_DISABLED 1 @@ -112,5 +115,6 @@ typedef unsigned __PTRDIFF_TYPE__ uintptr_t; /* Enable various video drivers */ #define SDL_VIDEO_DRIVER_NDS 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 #endif /* _SDL_config_nintendods_h */ diff --git a/include/SDL_events.h b/include/SDL_events.h index d26cf09d3..a84a53b5f 100644 --- a/include/SDL_events.h +++ b/include/SDL_events.h @@ -35,6 +35,7 @@ #include "SDL_keyboard.h" #include "SDL_mouse.h" #include "SDL_joystick.h" +#include "SDL_touchscreen.h" #include "SDL_quit.h" #include "begin_code.h" @@ -70,6 +71,9 @@ typedef enum SDL_JOYHATMOTION, /**< Joystick hat position change */ SDL_JOYBUTTONDOWN, /**< Joystick button pressed */ SDL_JOYBUTTONUP, /**< Joystick button released */ + SDL_TOUCHPRESSED, /**< Touchscreen pressed */ + SDL_TOUCHRELEASED, /**< Touchscreen no longer pressed */ + SDL_TOUCHMOTION, /**< Touchscreen point motion */ SDL_QUIT, /**< User-requested quit */ SDL_SYSWMEVENT, /**< System specific event */ SDL_EVENT_RESERVED1, /**< Reserved for future use... */ @@ -111,6 +115,11 @@ typedef enum SDL_EVENTMASK(SDL_JOYBALLMOTION) | SDL_EVENTMASK(SDL_JOYHATMOTION) | SDL_EVENTMASK(SDL_JOYBUTTONDOWN) | SDL_EVENTMASK(SDL_JOYBUTTONUP), + SDL_TOUCHPRESSEDMASK = SDL_EVENTMASK(SDL_TOUCHPRESSED), + SDL_TOUCHRELEASEDMASK = SDL_EVENTMASK(SDL_TOUCHRELEASED), + SDL_TOUCHMOTIONMASK = SDL_EVENTMASK(SDL_TOUCHMOTION), + SDL_TOUCHEVENTMASK = SDL_EVENTMASK(SDL_TOUCHPRESSED) | + SDL_EVENTMASK(SDL_TOUCHRELEASED) | SDL_EVENTMASK(SDL_TOUCHMOTION), SDL_QUITMASK = SDL_EVENTMASK(SDL_QUIT), SDL_SYSWMEVENTMASK = SDL_EVENTMASK(SDL_SYSWMEVENT) } SDL_EventMask; @@ -263,6 +272,21 @@ typedef struct SDL_JoyButtonEvent Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */ } SDL_JoyButtonEvent; +/** + * \struct SDL_TouchEvent + * + * \brief Touchscreen motion event structure (event.touch.*) + */ +typedef struct SDL_TouchEvent +{ + Uint8 type; /**< SDL_TOUCHMOTION, SDL_TOUCHPRESS, SDL_TOUCHRELEASED */ + Uint8 which; /**< The touchscreen device index */ + int point; /**< The touch point index, relevant for multitouch. */ + int xpos; /**< The X coordinate of the touch point. */ + int ypos; /**< The Y coordinate of the touch point. */ + int pressure; /**< The pressure of the touch */ +} SDL_TouchEvent; + /** * \struct SDL_QuitEvent * @@ -334,6 +358,7 @@ typedef union SDL_Event SDL_JoyBallEvent jball; /**< Joystick ball event data */ SDL_JoyHatEvent jhat; /**< Joystick hat event data */ SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ + SDL_TouchEvent touch; /**< Touchscreen event data */ SDL_QuitEvent quit; /**< Quit request event data */ SDL_UserEvent user; /**< Custom event data */ SDL_SysWMEvent syswm; /**< System dependent window event data */ diff --git a/include/SDL_touchscreen.h b/include/SDL_touchscreen.h new file mode 100644 index 000000000..6b14aa422 --- /dev/null +++ b/include/SDL_touchscreen.h @@ -0,0 +1,152 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ + +/** + * \file SDL_touchscreen.h + * + * Include file for SDL touchscreen event handling + */ + +#ifndef _SDL_touchscreen_h +#define _SDL_touchscreen_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* In order to use these functions, SDL_Init() must have been called + with the SDL_INIT_TOUCHSCREEN flag. This causes SDL to scan the system + for touchscreens, and load appropriate drivers. +*/ + +/* The touchscreen structure used to identify an SDL touchscreen */ +struct _SDL_Touchscreen; +typedef struct _SDL_Touchscreen SDL_Touchscreen; + + +/* Function prototypes */ +/* + * Count the number of touchscreens attached to the system + */ +extern DECLSPEC int SDLCALL SDL_NumTouchscreens(void); + +/* + * Get the implementation dependent name of a touchscreen. + * This can be called before any touchscreens are opened. + * If no name can be found, this function returns NULL. + */ +extern DECLSPEC const char *SDLCALL SDL_TouchscreenName(int device_index); + +/* + * Open a touchscreen for use - the index passed as an argument refers to + * the N'th touchscreen on the system. This index is the value which will + * identify this touchscreen in future touchscreen events. + * + * This function returns a touchscreen identifier, or NULL if an error occurred. + */ +extern DECLSPEC SDL_Touchscreen *SDLCALL SDL_TouchscreenOpen(int device_index); + +/* + * Returns 1 if the touchscreen has been opened, or 0 if it has not. + */ +extern DECLSPEC int SDLCALL SDL_TouchscreenOpened(int device_index); + +/* + * Get the device index of an opened touchscreen. + */ +extern DECLSPEC int SDLCALL SDL_TouchscreenIndex(SDL_Touchscreen * touchscreen); + +/* + * Get the number of points a touchscreen can register at a time + * (single or multi-touch.) + */ +extern DECLSPEC int SDLCALL SDL_TouchscreenMaxPoints(SDL_Touchscreen * touchscreen); + +/* + * Update the current state of the open touchscreens. + * This is called automatically by the event loop if any touchscreen + * events are enabled. + */ +extern DECLSPEC void SDLCALL SDL_TouchscreenUpdate(void); + +/* + * Enable/disable touchscreen event polling. + * If touchscreen events are disabled, you must call SDL_TouchscreenUpdate() + * yourself and check the state of the touchscreen when you want touchscreen + * information. + * The state can be one of SDL_QUERY, SDL_ENABLE or SDL_IGNORE. + */ +extern DECLSPEC int SDLCALL SDL_TouchscreenEventState(int state); + +/* + * Get the current X,Y position of the indicated point on the touchscreen. + * + * If not NULL, *x is set to an integer in the range [-32768,32767] + * where -32768 is the left edge, 0 is center, 32767 is right edge. + * Similarly with *y, for the top, center, and bottom, respectively. + * The returned value is an unsigned integer in the range [1,32767] + * that represents the pressure of the touch. + * If not being touched, 0 is returned and *x and *y are unmodified. + * + * The touch point indices start at index 0. + * If given a negative value for point, all the X,Y, and pressures + * for all the currently touched points on a multitouch device + * should be averaged and used for *x, *y, and the return value. + * If the value of point exceeds the number of points currently touched, + * 0 should be returned, and *x, *y should be left unmodified. + * + * On error, -1 is returned. + */ +extern DECLSPEC int SDLCALL SDL_TouchscreenGetXY(SDL_Touchscreen *touchscreen, + int point, int *x, int *y); + +/* + * Get the number of currently touched points on a touchscreen. + * This is either 0 or 1 for a single-touch device. + * On error, -1 is returned. + */ +extern DECLSPEC int SDLCALL SDL_TouchscreenGetPoints(SDL_Touchscreen * touchscreen); + +/* + * Close a touchscreen previously opened with SDL_TouchscreenOpen() + */ +extern DECLSPEC void SDLCALL SDL_TouchscreenClose(SDL_Touchscreen * touchscreen); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_touchscreen_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/SDL.c b/src/SDL.c index d2858673b..d20d7ac32 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -38,6 +38,10 @@ extern int SDL_JoystickInit(void); extern void SDL_JoystickQuit(void); #endif +#if !SDL_TOUCHSCREEN_DISABLED +extern int SDL_TouchscreenInit(void); +extern void SDL_TouchscreenQuit(void); +#endif #if !SDL_CDROM_DISABLED extern int SDL_CDROMInit(void); extern void SDL_CDROMQuit(void); @@ -123,6 +127,21 @@ SDL_InitSubSystem(Uint32 flags) } #endif +#if !SDL_TOUCHSCREEN_DISABLED + /* Initialize the touchscreen subsystem */ + if ((flags & SDL_INIT_TOUCHSCREEN) && !(SDL_initialized & SDL_INIT_TOUCHSCREEN)) { + if (SDL_TouchscreenInit() < 0) { + return (-1); + } + SDL_initialized |= SDL_INIT_TOUCHSCREEN; + } +#else + if (flags & SDL_INIT_TOUCHSCREEN) { + SDL_SetError("SDL not built with touchscreen support"); + return (-1); + } +#endif + #if !SDL_CDROM_DISABLED /* Initialize the CD-ROM subsystem */ if ((flags & SDL_INIT_CDROM) && !(SDL_initialized & SDL_INIT_CDROM)) { @@ -180,6 +199,12 @@ SDL_QuitSubSystem(Uint32 flags) SDL_initialized &= ~SDL_INIT_JOYSTICK; } #endif +#if !SDL_TOUCHSCREEN_DISABLED + if ((flags & SDL_initialized & SDL_INIT_TOUCHSCREEN)) { + SDL_TouchscreenQuit(); + SDL_initialized &= ~SDL_INIT_TOUCHSCREEN; + } +#endif #if !SDL_TIMERS_DISABLED if ((flags & SDL_initialized & SDL_INIT_TIMER)) { SDL_TimerQuit(); diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 364182eb3..4aa73cc54 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -31,6 +31,9 @@ #if !SDL_JOYSTICK_DISABLED #include "../joystick/SDL_joystick_c.h" #endif +#if !SDL_TOUCHSCREEN_DISABLED +#include "../touchscreen/SDL_touchscreen_c.h" +#endif /* Public data -- the event filter */ SDL_EventFilter SDL_EventOK = NULL; @@ -117,6 +120,12 @@ SDL_GobbleEvents(void *unused) SDL_JoystickUpdate(); } #endif +#if !SDL_TOUCHSCREEN_DISABLED + /* Similarly, check for touchscreen state change */ + if (SDL_numtouchscreens && (SDL_eventstate & SDL_TOUCHEVENTMASK)) { + SDL_TouchscreenUpdate(); + } +#endif /* Give up the CPU for the rest of our timeslice */ SDL_EventLock.safe = 1; @@ -387,6 +396,12 @@ SDL_PumpEvents(void) if (SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK)) { SDL_JoystickUpdate(); } +#endif +#if !SDL_TOUCHSCREEN_DISABLED + /* Check for touchscreen state change */ + if (SDL_numtouchscreens && (SDL_eventstate & SDL_TOUCHEVENTMASK)) { + SDL_TouchscreenUpdate(); + } #endif } } diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 22879cdba..c3ecfe8bb 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -28,6 +28,10 @@ #include "SDL_endian.h" #include "SDL_rwops.h" +#ifdef __NDS__ +/* include libfat headers for fatInitDefault(). */ +#include +#endif /* __NDS__ */ #ifdef __WIN32__ @@ -462,7 +466,10 @@ SDL_RWops * SDL_RWFromFP(FILE * fp, SDL_bool autoclose) { SDL_RWops *rwops = NULL; - +#ifdef __NDS__ + /* set it up so we can use stdio file function */ + fatInitDefault(); +#endif /* __NDS__ */ rwops = SDL_AllocRW(); if (rwops != NULL) { rwops->seek = stdio_seek; diff --git a/src/touchscreen/SDL_systouchscreen.h b/src/touchscreen/SDL_systouchscreen.h new file mode 100644 index 000000000..c5f3bba80 --- /dev/null +++ b/src/touchscreen/SDL_systouchscreen.h @@ -0,0 +1,78 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is SDL_free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* This is the system specific header for the SDL touchscreen API */ + +#include "SDL_touchscreen.h" + +/* The SDL touchscreen structure */ +struct _SDL_Touchscreen +{ + Uint8 index; /* Device index */ + const char *name; /* Touchscreen name - system dependent */ + + int maxpoints; /* Max # multi-touch points, -1 if unlimited. */ + int npoints; /* Number of points currently touched */ + struct touchpoint + { + int x; + int y; + int pressure; + } *points; /* Current ball motion deltas */ + + struct touchscreen_hwdata *hwdata; /* Driver dependent information */ + + int ref_count; /* Reference count for multiple opens */ +}; + +/* Function to scan the system for touchscreens. + * Touchscreen 0 should be the system default touchscreen. + * This function should return the number of available touchscreens, or -1 + * on an unrecoverable fatal error. + */ +extern int SDL_SYS_TouchscreenInit(void); + +/* Function to get the device-dependent name of a touchscreen */ +extern const char *SDL_SYS_TouchscreenName(int index); + +/* Function to open a touchscreen for use. + The touchscreen to open is specified by the index field of the touchscreen. + This should fill the maxpoints field of the touchscreen structure. + It returns 0, or -1 if there is an error. + */ +extern int SDL_SYS_TouchscreenOpen(SDL_Touchscreen * touchscreen); + +/* Function to update the state of a touchscreen - called as a device poll. + * This function shouldn't update the touchscreen structure directly, + * but instead should call SDL_PrivateTouchscreen*() to deliver events + * and update touchscreen device state. + */ +extern void SDL_SYS_TouchscreenUpdate(SDL_Touchscreen * touchscreen); + +/* Function to close a touchscreen after use */ +extern void SDL_SYS_TouchscreenClose(SDL_Touchscreen * touchscreen); + +/* Function to perform any system-specific touchscreen related cleanup */ +extern void SDL_SYS_TouchscreenQuit(void); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/touchscreen/SDL_touchscreen.c b/src/touchscreen/SDL_touchscreen.c new file mode 100644 index 000000000..d4e859909 --- /dev/null +++ b/src/touchscreen/SDL_touchscreen.c @@ -0,0 +1,482 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* This is the touchscreen API for Simple DirectMedia Layer */ + +#include "SDL_events.h" +#include "SDL_systouchscreen.h" +#include "SDL_touchscreen_c.h" +#if !SDL_EVENTS_DISABLED +#include "../events/SDL_events_c.h" +#endif + +/* This is used for Quake III Arena */ +#if SDL_EVENTS_DISABLED +#define SDL_Lock_EventThread() +#define SDL_Unlock_EventThread() +#endif + +Uint8 SDL_numtouchscreens = 0; +SDL_Touchscreen **SDL_touchscreens = NULL; +static SDL_Touchscreen *default_touchscreen = NULL; + +int +SDL_TouchscreenInit(void) +{ + int arraylen; + int status; + + SDL_numtouchscreens = 0; + status = SDL_SYS_TouchscreenInit(); + if (status >= 0) { + arraylen = (status + 1) * sizeof(*SDL_touchscreens); + SDL_touchscreens = (SDL_Touchscreen **) SDL_malloc(arraylen); + if (SDL_touchscreens == NULL) { + SDL_numtouchscreens = 0; + } else { + SDL_memset(SDL_touchscreens, 0, arraylen); + SDL_numtouchscreens = status; + } + status = 0; + } + default_touchscreen = NULL; + return (status); +} + +/* + * Count the number of touchscreens attached to the system + */ +int +SDL_NumTouchscreens(void) +{ + return SDL_numtouchscreens; +} + +/* + * Get the implementation dependent name of a touchscreen + */ +const char * +SDL_TouchscreenName(int device_index) +{ + if ((device_index < 0) || (device_index >= SDL_numtouchscreens)) { + SDL_SetError("There are %d touchscreens available", SDL_numtouchscreens); + return (NULL); + } + return (SDL_SYS_TouchscreenName(device_index)); +} + +/* + * Open a touchscreen for use - the index passed as an argument refers to + * the N'th touchscreen on the system. This index is the value which will + * identify this touchscreen in future touchscreen events. + * + * This function returns a touchscreen identifier, or NULL if an error occurred. + */ +SDL_Touchscreen * +SDL_TouchscreenOpen(int device_index) +{ + int i; + SDL_Touchscreen *touchscreen; + + if ((device_index < 0) || (device_index >= SDL_numtouchscreens)) { + SDL_SetError("There are %d touchscreens available", SDL_numtouchscreens); + return (NULL); + } + + /* If the touchscreen is already open, return it */ + for (i = 0; SDL_touchscreens[i]; ++i) { + if (device_index == SDL_touchscreens[i]->index) { + touchscreen = SDL_touchscreens[i]; + ++touchscreen->ref_count; + return (touchscreen); + } + } + + /* Create and initialize the touchscreen */ + touchscreen = (SDL_Touchscreen *) SDL_malloc((sizeof *touchscreen)); + if (touchscreen != NULL) { + SDL_memset(touchscreen, 0, (sizeof *touchscreen)); + touchscreen->index = device_index; + if (SDL_SYS_TouchscreenOpen(touchscreen) < 0) { + SDL_free(touchscreen); + touchscreen = NULL; + } else { + if (touchscreen->maxpoints > 0) { + touchscreen->points = (struct touchpoint *) SDL_malloc + (touchscreen->maxpoints * sizeof(*touchscreen->points)); + } + if ((touchscreen->maxpoints > 0) && !touchscreen->points) { + SDL_OutOfMemory(); + SDL_TouchscreenClose(touchscreen); + touchscreen = NULL; + } + if (touchscreen->points) { + SDL_memset(touchscreen->points, 0, + touchscreen->maxpoints * sizeof(*touchscreen->points)); + } + } + } + if (touchscreen) { + /* Add touchscreen to list */ + ++touchscreen->ref_count; + SDL_Lock_EventThread(); + for (i = 0; SDL_touchscreens[i]; ++i) + /* Skip to next touchscreen */ ; + SDL_touchscreens[i] = touchscreen; + SDL_Unlock_EventThread(); + } + return (touchscreen); +} + +/* + * Returns 1 if the touchscreen has been opened, or 0 if it has not. + */ +int +SDL_TouchscreenOpened(int device_index) +{ + int i, opened; + + opened = 0; + for (i = 0; SDL_touchscreens[i]; ++i) { + if (SDL_touchscreens[i]->index == (Uint8) device_index) { + opened = 1; + break; + } + } + return (opened); +} + +static int +ValidTouchscreen(SDL_Touchscreen ** touchscreen) +{ + int valid; + + if (*touchscreen == NULL) { + *touchscreen = default_touchscreen; + } + if (*touchscreen == NULL) { + SDL_SetError("Touchscreen hasn't been opened yet"); + valid = 0; + } else { + valid = 1; + } + return valid; +} + +/* + * Get the device index of an opened touchscreen. + */ +int +SDL_TouchscreenIndex(SDL_Touchscreen * touchscreen) +{ + if (!ValidTouchscreen(&touchscreen)) { + return (-1); + } + return (touchscreen->index); +} + +/* + * Get the max number of points on a multi-touch screen (or 1 on a single-touch) + */ +int +SDL_TouchscreenMaxPoints(SDL_Touchscreen * touchscreen) +{ + if (!ValidTouchscreen(&touchscreen)) { + return (-1); + } + return (touchscreen->maxpoints); +} + +/* + * Get the current X,Y position of the indicated point on the touchscreen + */ +int +SDL_TouchscreenGetXY(SDL_Touchscreen *touchscreen, int point, int *x, int *y) +{ + int retval; + + if (!ValidTouchscreen(&touchscreen)) { + return (-1); + } + + retval = 0; + if (point < 0) { + int i; long avg; + if(x) { + avg = 0; + for(i = 0; i < touchscreen->npoints; ++i) { + avg += touchscreen->points[i].x; + } + *x = avg; + } + if(y) { + avg = 0; + for(i = 0; i < touchscreen->npoints; ++i) { + avg += touchscreen->points[i].y; + } + *y = avg; + } + avg = 0; + for(i = 0; i < touchscreen->npoints; ++i) { + avg += touchscreen->points[i].pressure; + } + return (int)avg; + } else if (point < touchscreen->maxpoints) { + if (x) { + *x = touchscreen->points[point].x; + } + if (y) { + *y = touchscreen->points[point].y; + } + retval = touchscreen->points[point].pressure; + } else { + SDL_SetError("Touchscreen only can have %d points", touchscreen->maxpoints); + retval = -1; + } + return (retval); +} + +int +SDL_TouchscreenGetPoints(SDL_Touchscreen *touchscreen) { + if (!ValidTouchscreen(&touchscreen)) { + return (-1); + } + + return touchscreen->npoints; +} + +/* + * Close a touchscreen previously opened with SDL_TouchscreenOpen() + */ +void +SDL_TouchscreenClose(SDL_Touchscreen * touchscreen) +{ + int i; + + if (!ValidTouchscreen(&touchscreen)) { + return; + } + + /* First decrement ref count */ + if (--touchscreen->ref_count > 0) { + return; + } + + /* Lock the event queue - prevent touchscreen polling */ + SDL_Lock_EventThread(); + + if (touchscreen == default_touchscreen) { + default_touchscreen = NULL; + } + SDL_SYS_TouchscreenClose(touchscreen); + + /* Remove touchscreen from list */ + for (i = 0; SDL_touchscreens[i]; ++i) { + if (touchscreen == SDL_touchscreens[i]) { + SDL_memcpy(&SDL_touchscreens[i], &SDL_touchscreens[i + 1], + (SDL_numtouchscreens - i) * sizeof(touchscreen)); + break; + } + } + + /* Let the event thread keep running */ + SDL_Unlock_EventThread(); + + /* Free the data associated with this touchscreen */ + if (touchscreen->points) { + SDL_free(touchscreen->points); + } + SDL_free(touchscreen); +} + +void +SDL_TouchscreenQuit(void) +{ + /* Stop the event polling */ + SDL_Lock_EventThread(); + SDL_numtouchscreens = 0; + SDL_Unlock_EventThread(); + + /* Quit the touchscreen setup */ + SDL_SYS_TouchscreenQuit(); + if (SDL_touchscreens) { + SDL_free(SDL_touchscreens); + SDL_touchscreens = NULL; + } +} + + +/* These are global for SDL_systouchscreen.c and SDL_events.c */ +int +SDL_PrivateTouchPress(SDL_Touchscreen * touchscreen, int point, + int x, int y, int pressure) { + int posted; + int ev = SDL_TOUCHMOTION; + + if (!ValidTouchscreen(&touchscreen)) { + return -1; + } + + if(point >= touchscreen->maxpoints) { + SDL_SetError("Touchscreen only can have %d points", touchscreen->maxpoints); + return -1; + } + + /* on neg. point, set the given args as the *only* point. + so set the struct to have no points pressed, then continue as normal. */ + if(point < 0) { + point = 0; + touchscreen->npoints = 0; + SDL_memset(touchscreen->points, 0, + touchscreen->maxpoints * sizeof(touchscreen->points[0])); + } + + /* new touch point! that means a TOUCHPRESSED event is due. */ + if(point >= touchscreen->npoints) { + ev = SDL_TOUCHPRESSED; + point = touchscreen->npoints; + ++touchscreen->npoints; + } + + /* no motion, no change, don't report an event. */ + if(touchscreen->points[point].x == x && + touchscreen->points[point].y == y && + touchscreen->points[point].pressure == pressure) { + return 0; + } + + /* Update internal touchscreen point state */ + touchscreen->points[point].x = x; + touchscreen->points[point].y = y; + touchscreen->points[point].pressure = pressure; + + /* Post the event, if desired */ + posted = 0; +#if !SDL_EVENTS_DISABLED + if (SDL_ProcessEvents[ev] == SDL_ENABLE) { + SDL_Event event; + event.touch.type = ev; + event.touch.which = touchscreen->index; + event.touch.point = point; + event.touch.xpos = x; + event.touch.ypos = y; + event.touch.pressure = pressure; + if ((SDL_EventOK == NULL) + || (*SDL_EventOK) (SDL_EventOKParam, &event)) { + posted = 1; + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ + return (posted); +} + +int +SDL_PrivateTouchRelease(SDL_Touchscreen * touchscreen, int point) { + int posted; + + if (!ValidTouchscreen(&touchscreen)) { + return -1; + } + + if(point >= touchscreen->maxpoints) { + SDL_SetError("Touchscreen only can have %d points", touchscreen->maxpoints); + return -1; + } else if(point >= touchscreen->npoints) { + SDL_SetError("Point %d up when only %d were down", point, touchscreen->npoints); + return -1; + } + + /* on neg. point, clear all points. so set the struct to have one point + pressed, then continue as normal. */ + if(point < 0) { + point = 0; + touchscreen->npoints = 1; + SDL_memset(&(touchscreen->points[1]), 0, + (touchscreen->maxpoints-1) * sizeof(touchscreen->points[0])); + } + + /* Update internal touchscreen point state */ + touchscreen->points[point].pressure = 0; + if(touchscreen->npoints >= 0) --touchscreen->npoints; + + /* Post the event, if desired */ + posted = 0; +#if !SDL_EVENTS_DISABLED + if (SDL_ProcessEvents[SDL_TOUCHRELEASED] == SDL_ENABLE) { + SDL_Event event; + event.touch.type = SDL_TOUCHRELEASED; + event.touch.which = touchscreen->index; + event.touch.point = point; + if ((SDL_EventOK == NULL) + || (*SDL_EventOK) (SDL_EventOKParam, &event)) { + posted = 1; + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ + return (posted); +} + +void +SDL_TouchscreenUpdate(void) +{ + int i; + + for (i = 0; SDL_touchscreens[i]; ++i) { + SDL_SYS_TouchscreenUpdate(SDL_touchscreens[i]); + } +} + +int +SDL_TouchscreenEventState(int state) +{ +#if SDL_EVENTS_DISABLED + return SDL_IGNORE; +#else + const Uint8 event_list[] = { + SDL_TOUCHPRESSED, SDL_TOUCHRELEASED, SDL_TOUCHMOTION + }; + unsigned int i; + + switch (state) { + case SDL_QUERY: + state = SDL_IGNORE; + for (i = 0; i < SDL_arraysize(event_list); ++i) { + state = SDL_EventState(event_list[i], SDL_QUERY); + if (state == SDL_ENABLE) { + break; + } + } + break; + default: + for (i = 0; i < SDL_arraysize(event_list); ++i) { + SDL_EventState(event_list[i], state); + } + break; + } + return (state); +#endif /* SDL_EVENTS_DISABLED */ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/touchscreen/SDL_touchscreen_c.h b/src/touchscreen/SDL_touchscreen_c.h new file mode 100644 index 000000000..3e8ca1e16 --- /dev/null +++ b/src/touchscreen/SDL_touchscreen_c.h @@ -0,0 +1,42 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Useful functions and variables from SDL_touchscreen.c */ +#include "SDL_touchscreen.h" + +/* The number of available touchscreens on the system */ +extern Uint8 SDL_numtouchscreens; + +/* Internal event queueing functions */ + +/* the point index starts at 0 + * if point < 0, release all points and set this to be the first (only) point. + * if point >= touchscreen->maxpoints, error. + * otherwise, set or update the coordinates for the given point. + * return -1 if fatal error, 0 on success + */ +extern int SDL_PrivateTouchPress(SDL_Touchscreen * touchscreen, int point, + int x, int y, int pressure); +/* if point < 0, release all points. */ +extern int SDL_PrivateTouchRelease(SDL_Touchscreen * touchscreen, int point); +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/touchscreen/dummy/SDL_systouchscreen.c b/src/touchscreen/dummy/SDL_systouchscreen.c new file mode 100644 index 000000000..366302c13 --- /dev/null +++ b/src/touchscreen/dummy/SDL_systouchscreen.c @@ -0,0 +1,90 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#if defined(SDL_TOUCHSCREEN_DUMMY) || defined(SDL_TOUCHSCREEN_DISABLED) + +/* This is the system specific header for the SDL touchscreen API */ + +#include "SDL_touchscreen.h" +#include "../SDL_systouchscreen.h" +#include "../SDL_touchscreen_c.h" + +/* Function to scan the system for touchscreen. + * This function should set SDL_numtouchscreens to the number of available + * touchscreens. Touchscreen 0 should be the system default touchscreen. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +int +SDL_SYS_TouchscreenInit(void) +{ + SDL_numtouchscreens = 0; + return (0); +} + +/* Function to get the device-dependent name of a touchscreen */ +const char * +SDL_SYS_TouchscreenName(int index) +{ + SDL_SetError("Logic error: No touchscreens available"); + return (NULL); +} + +/* Function to open a touchscreen for use. + The touchscreen to open is specified by the index field of the touchscreen. + This should fill the maxpoints field of the touchscreen structure. + It returns 0, or -1 if there is an error. + */ +int +SDL_SYS_TouchscreenOpen(SDL_Touchscreen * touchscreen) +{ + SDL_SetError("Logic error: No touchscreens available"); + return (-1); +} + +/* Function to update the state of a touchscreen - called as a device poll. + * This function shouldn't update the touchscreen structure directly, + * but instead should call SDL_PrivateTouchscreen*() to deliver events + * and update touchscreen device state. + */ +void +SDL_SYS_TouchscreenUpdate(SDL_Touchscreen * touchscreen) +{ + return; +} + +/* Function to close a touchscreen after use */ +void +SDL_SYS_TouchscreenClose(SDL_Touchscreen * touchscreen) +{ + return; +} + +/* Function to perform any system-specific touchscreen related cleanup */ +void +SDL_SYS_TouchscreenQuit(void) +{ + return; +} + +#endif /* SDL_TOUCHSCREEN_DUMMY || SDL_TOUCHSCREEN_DISABLED */ +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/touchscreen/nds/SDL_systouchscreen.c b/src/touchscreen/nds/SDL_systouchscreen.c new file mode 100644 index 000000000..90846027b --- /dev/null +++ b/src/touchscreen/nds/SDL_systouchscreen.c @@ -0,0 +1,115 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com +*/ + +#include "SDL_config.h" + +#ifdef SDL_TOUCHSCREEN_NDS + +/* This is the system specific header for the SDL touchscreen API */ +#include +#include /* For the definition of NULL */ + +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_touchscreen.h" +#include "../SDL_systouchscreen.h" +#include "../SDL_touchscreen_c.h" + +#include "../../video/nds/SDL_ndsevents_c.h" + +/* Function to scan the system for touchscreen. + * This function should set SDL_numtouchscreens to the number of available + * touchscreen. Touchscreen 0 should be the system default touchscreen. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +int +SDL_SYS_TouchscreenInit(void) +{ + SDL_numtouchscreens = 1; + return (1); +} + +/* Function to get the device-dependent name of a touchscreen */ +const char * +SDL_SYS_TouchscreenName(int index) +{ + if (!index) + return "NDS builtin touchscreen"; + SDL_SetError("No touchscreen available with that index"); + return (NULL); +} + +/* Function to open a touchscreen for use. + The touchscreen to open is specified by the index field of the touchscreen. + This should fill the maxpoints field of the touchscreen structure. + It returns 0, or -1 if there is an error. + */ +int +SDL_SYS_TouchscreenOpen(SDL_Touchscreen * touchscreen) +{ + touchscreen->maxpoints = 1; + touchscreen->npoints = 0; + /* do I call SDL_TouchscreenOpen here? */ + return 0; +} + + +/* Function to update the state of a touchscreen - called as a device poll. + * This function shouldn't update the touchscreen structure directly, + * but instead should call SDL_PrivateTouch*() to deliver events + * and update touchscreen device state. + */ +void +SDL_SYS_TouchscreenUpdate(SDL_Touchscreen * touchscreen) +{ + u32 keysd, keysu, keysh; + int xpos, ypos, pressure = 16384; + touchPosition touch; + + scanKeys(); + keysd = keysDown(); + keysh = keysHeld(); + keysu = keysUp(); + touch=touchReadXY(); + xpos = (touch.px-128)*256; + ypos = (touch.py-96)*(65536/192); + + if (((keysd|keysh) & KEY_TOUCH)) { + SDL_PrivateTouchPress(touchscreen, 0, xpos, ypos, pressure); + } + if ((keysu & KEY_TOUCH)) { + SDL_PrivateTouchRelease(touchscreen, 0); + } } + +/* Function to close a touchscreen after use */ +void +SDL_SYS_TouchscreenClose(SDL_Touchscreen * touchscreen) +{ +} + +/* Function to perform any system-specific touchscreen related cleanup */ +void +SDL_SYS_TouchscreenQuit(void) +{ +} +#endif /* SDL_TOUCHSCREEN_NDS */ +