Started adding framework for Touchscreen API, based on and (consistent with) the existing Joystick API. gsoc2008_nds
authorDarren Alton <dalton@stevens.edu>
Mon, 23 Jun 2008 11:55:26 +0000
branchgsoc2008_nds
changeset 2674 f1d07ba2e275
parent 2673 24a6b3588eac
child 2675 5e4274591163
Started adding framework for Touchscreen API, based on and (consistent with) the existing Joystick API.
Makefile.ds
include/SDL.h
include/SDL_config_nintendods.h
include/SDL_events.h
include/SDL_touchscreen.h
src/SDL.c
src/events/SDL_events.c
src/file/SDL_rwops.c
src/touchscreen/SDL_systouchscreen.h
src/touchscreen/SDL_touchscreen.c
src/touchscreen/SDL_touchscreen_c.h
src/touchscreen/dummy/SDL_systouchscreen.c
src/touchscreen/nds/SDL_systouchscreen.c
--- a/Makefile.ds	Thu Jun 19 07:11:35 2008 +0000
+++ b/Makefile.ds	Mon Jun 23 11:55:26 2008 +0000
@@ -51,6 +51,9 @@
 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/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 \
--- a/include/SDL.h	Thu Jun 19 07:11:35 2008 +0000
+++ b/include/SDL.h	Mon Jun 23 11:55:26 2008 +0000
@@ -109,6 +109,7 @@
 #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
--- a/include/SDL_config_nintendods.h	Thu Jun 19 07:11:35 2008 +0000
+++ b/include/SDL_config_nintendods.h	Mon Jun 23 11:55:26 2008 +0000
@@ -99,6 +99,9 @@
 
 /* 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 @@
 
 /* Enable various video drivers */
 #define SDL_VIDEO_DRIVER_NDS	1
+#define SDL_VIDEO_DRIVER_DUMMY	1
 
 #endif /* _SDL_config_nintendods_h */
--- a/include/SDL_events.h	Thu Jun 19 07:11:35 2008 +0000
+++ b/include/SDL_events.h	Mon Jun 23 11:55:26 2008 +0000
@@ -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 @@
     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 @@
         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;
@@ -264,6 +273,21 @@
 } 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
  *
  * \brief The "quit requested" event
@@ -334,6 +358,7 @@
     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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/SDL_touchscreen.h	Mon Jun 23 11:55:26 2008 +0000
@@ -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: */
--- a/src/SDL.c	Thu Jun 19 07:11:35 2008 +0000
+++ b/src/SDL.c	Mon Jun 23 11:55:26 2008 +0000
@@ -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 @@
     }
 #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_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();
--- a/src/events/SDL_events.c	Thu Jun 19 07:11:35 2008 +0000
+++ b/src/events/SDL_events.c	Mon Jun 23 11:55:26 2008 +0000
@@ -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_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;
@@ -388,6 +397,12 @@
             SDL_JoystickUpdate();
         }
 #endif
+#if !SDL_TOUCHSCREEN_DISABLED
+        /* Check for touchscreen state change */
+        if (SDL_numtouchscreens && (SDL_eventstate & SDL_TOUCHEVENTMASK)) {
+            SDL_TouchscreenUpdate();
+        }
+#endif
     }
 }
 
--- a/src/file/SDL_rwops.c	Thu Jun 19 07:11:35 2008 +0000
+++ b/src/file/SDL_rwops.c	Mon Jun 23 11:55:26 2008 +0000
@@ -28,6 +28,10 @@
 #include "SDL_endian.h"
 #include "SDL_rwops.h"
 
+#ifdef __NDS__
+/* include libfat headers for fatInitDefault(). */
+#include <fat.h>
+#endif /* __NDS__ */
 
 #ifdef __WIN32__
 
@@ -462,7 +466,10 @@
 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;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/touchscreen/SDL_systouchscreen.h	Mon Jun 23 11:55:26 2008 +0000
@@ -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: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/touchscreen/SDL_touchscreen.c	Mon Jun 23 11:55:26 2008 +0000
@@ -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: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/touchscreen/SDL_touchscreen_c.h	Mon Jun 23 11:55:26 2008 +0000
@@ -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: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/touchscreen/dummy/SDL_systouchscreen.c	Mon Jun 23 11:55:26 2008 +0000
@@ -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: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/touchscreen/nds/SDL_systouchscreen.c	Mon Jun 23 11:55:26 2008 +0000
@@ -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 <nds.h>
+#include <stdio.h>              /* 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 */
+