changeset 4661:03dcb795c583

Merged changes from the main SDL codebase
author Sam Lantinga <slouken@libsdl.org>
date Mon, 12 Jul 2010 21:09:23 -0700
parents b15e7017409b (diff) 6f8175ad0335 (current diff)
children 3c4e0130c9b1
files Makefile.in VisualC/SDL.sln VisualC/SDL/SDL.vcproj VisualC/SDL/SDL_VS2005.vcproj VisualC/SDL_VS2005.sln VisualC/SDLmain/SDLmain.vcproj VisualC/SDLmain/SDLmain_VS2005.vcproj VisualC/tests/automated/automated.vcproj VisualC/tests/checkkeys/checkkeys.vcproj VisualC/tests/graywin/graywin.vcproj VisualC/tests/loopwave/loopwave.vcproj VisualC/tests/testalpha/testalpha.vcproj VisualC/tests/testdraw2/testdraw2.vcproj VisualC/tests/testfile/testfile.vcproj VisualC/tests/testgamma/testgamma.vcproj VisualC/tests/testgl/testgl.vcproj VisualC/tests/testgl2/testgl2.vcproj VisualC/tests/testjoystick/testjoystick.vcproj VisualC/tests/testoverlay/testoverlay.vcproj VisualC/tests/testoverlay2/testoverlay2.vcproj VisualC/tests/testpalette/testpalette.vcproj VisualC/tests/testplatform/testplatform.vcproj VisualC/tests/testpower/testpower.vcproj VisualC/tests/testsprite/testsprite.vcproj VisualC/tests/testsprite2/testsprite2.vcproj VisualC/tests/testvidinfo/testvidinfo.vcproj VisualC/tests/testwin/testwin.vcproj VisualC/tests/testwm/testwm.vcproj include/SDL_events.h src/video/uikit/SDL_uikitview.h src/video/uikit/SDL_uikitview.m src/video/win32/SDL_win32events.c src/video/win32/SDL_win32video.h src/video/win32/SDL_win32window.c src/video/win32/wactab/pktdef.h src/video/win32/wactab/wintab.h src/video/win32/wactab/wintabx.h src/video/x11/SDL_x11events.c src/video/x11/SDL_x11video.c src/video/x11/SDL_x11video.h test/testmmousetablet.c
diffstat 45 files changed, 4804 insertions(+), 120 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.in	Mon Jul 12 01:20:57 2010 -0700
+++ b/Makefile.in	Mon Jul 12 21:09:23 2010 -0700
@@ -44,7 +44,7 @@
 
 DIST = acinclude autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS include INSTALL Makefile.minimal Makefile.in README* sdl-config.in sdl.m4 sdl.pc.in SDL.spec SDL.spec.in src test TODO VisualC.html VisualC VisualCE Watcom-Win32.zip WhatsNew Xcode Xcode-iPhoneOS
 
-HDRS = SDL.h SDL_assert.h SDL_atomic.h SDL_audio.h SDL_clipboard.h SDL_compat.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_haptic.h SDL_input.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_pixels.h SDL_platform.h SDL_power.h SDL_quit.h SDL_rect.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_stdinc.h SDL_surface.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h
+HDRS = SDL.h SDL_assert.h SDL_atomic.h SDL_audio.h SDL_clipboard.h SDL_compat.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_gesture.h SDL_haptic.h SDL_input.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_pixels.h SDL_platform.h SDL_power.h SDL_quit.h SDL_rect.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_stdinc.h SDL_surface.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_touch.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h
 
 LT_AGE      = @LT_AGE@
 LT_CURRENT  = @LT_CURRENT@
--- a/VisualC/SDL/SDL_VS2005.vcproj	Mon Jul 12 01:20:57 2010 -0700
+++ b/VisualC/SDL/SDL_VS2005.vcproj	Mon Jul 12 21:09:23 2010 -0700
@@ -1,10 +1,11 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8.00"
+	Version="9.00"
 	Name="SDL"
 	ProjectGUID="{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}"
 	RootNamespace="SDL"
+	TargetFrameworkVersion="131072"
 	>
 	<Platforms>
 		<Platform
@@ -76,16 +77,21 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalOptions="/MACHINE:I386"
+				AdditionalOptions="/MACHINE:I386&#x0D;&#x0A;msvcrt.lib"
 				AdditionalDependencies="msimg32.lib winmm.lib"
 				OutputFile=".\Debug/SDL.dll"
 				LinkIncremental="2"
 				SuppressStartupBanner="true"
-				IgnoreAllDefaultLibraries="true"
+				IgnoreAllDefaultLibraries="false"
+				IgnoreDefaultLibraryNames=""
 				GenerateDebugInformation="true"
 				ProgramDatabaseFile=".\Debug/SDL.pdb"
-				SubSystem="2"
+				SubSystem="0"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
 				ImportLibrary=".\Debug/SDL.lib"
+				Profile="true"
+				CLRThreadAttribute="0"
 				CLRUnmanagedCodeCheck="false"
 			/>
 			<Tool
@@ -107,9 +113,6 @@
 				Name="VCAppVerifierTool"
 			/>
 			<Tool
-				Name="VCWebDeploymentTool"
-			/>
-			<Tool
 				Name="VCPostBuildEventTool"
 			/>
 		</Configuration>
@@ -185,6 +188,8 @@
 				IgnoreAllDefaultLibraries="true"
 				ProgramDatabaseFile=".\Release/SDL.pdb"
 				SubSystem="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
 				ImportLibrary=".\Release/SDL.lib"
 			/>
 			<Tool
@@ -206,9 +211,6 @@
 				Name="VCAppVerifierTool"
 			/>
 			<Tool
-				Name="VCWebDeploymentTool"
-			/>
-			<Tool
 				Name="VCPostBuildEventTool"
 			/>
 		</Configuration>
@@ -941,6 +943,14 @@
 			>
 		</File>
 		<File
+			RelativePath="..\..\src\events\SDL_touch.c"
+			>
+		</File>
+		<File
+			RelativePath="..\..\src\events\SDL_touch_c.h"
+			>
+		</File>
+		<File
 			RelativePath="..\..\src\video\SDL_video.c"
 			>
 		</File>
--- a/VisualC/SDLmain/SDLmain_VS2005.vcproj	Mon Jul 12 01:20:57 2010 -0700
+++ b/VisualC/SDLmain/SDLmain_VS2005.vcproj	Mon Jul 12 21:09:23 2010 -0700
@@ -1,9 +1,10 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8.00"
+	Version="9.00"
 	Name="SDLmain"
 	ProjectGUID="{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}"
+	TargetFrameworkVersion="131072"
 	>
 	<Platforms>
 		<Platform
@@ -25,7 +26,7 @@
 			<Tool
 				Name="VCPreBuildEventTool"
 				Description="Making sure basic SDL headers are in place..."
-				CommandLine="if exist &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot; goto SDLCONFIGOKAY&#x0D;&#x0A;echo Copying SDL_config_win32.h to SDL_config.h...&#x0D;&#x0A;copy &quot;$(ProjectDir)\..\..\include\SDL_config_win32.h&quot; &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot;&#x0D;&#x0A;:SDLCONFIGOKAY&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot; goto SDLREVISIONOKAY&#x0D;&#x0A;echo Creating stub SDL_revision.h file...&#x0D;&#x0A;echo #define SDL_REVISION 0 &gt;&quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot;&#x0D;&#x0A;:SDLREVISIONOKAY"
+				CommandLine="if exist &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot; goto SDLCONFIGOKAY&#x0D;&#x0A;echo Copying SDL_config_win32.h to SDL_config.h...&#x0D;&#x0A;copy &quot;$(ProjectDir)\..\..\include\SDL_config_win32.h&quot; &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot;&#x0D;&#x0A;:SDLCONFIGOKAY&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot; goto SDLREVISIONOKAY&#x0D;&#x0A;echo Creating stub SDL_revision.h file...&#x0D;&#x0A;echo #define SDL_REVISION 0 &gt;&quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot;&#x0D;&#x0A;:SDLREVISIONOKAY&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
@@ -98,7 +99,7 @@
 			<Tool
 				Name="VCPreBuildEventTool"
 				Description="Making sure basic SDL headers are in place..."
-				CommandLine="if exist &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot; goto SDLCONFIGOKAY&#x0D;&#x0A;echo Copying SDL_config_win32.h to SDL_config.h...&#x0D;&#x0A;copy &quot;$(ProjectDir)\..\..\include\SDL_config_win32.h&quot; &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot;&#x0D;&#x0A;:SDLCONFIGOKAY&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot; goto SDLREVISIONOKAY&#x0D;&#x0A;echo Creating stub SDL_revision.h file...&#x0D;&#x0A;echo #define SDL_REVISION 0 &gt;&quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot;&#x0D;&#x0A;:SDLREVISIONOKAY"
+				CommandLine="if exist &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot; goto SDLCONFIGOKAY&#x0D;&#x0A;echo Copying SDL_config_win32.h to SDL_config.h...&#x0D;&#x0A;copy &quot;$(ProjectDir)\..\..\include\SDL_config_win32.h&quot; &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot;&#x0D;&#x0A;:SDLCONFIGOKAY&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot; goto SDLREVISIONOKAY&#x0D;&#x0A;echo Creating stub SDL_revision.h file...&#x0D;&#x0A;echo #define SDL_REVISION 0 &gt;&quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot;&#x0D;&#x0A;:SDLREVISIONOKAY&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
@@ -171,7 +172,7 @@
 			<Tool
 				Name="VCPreBuildEventTool"
 				Description="Making sure basic SDL headers are in place..."
-				CommandLine="if exist &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot; goto SDLCONFIGOKAY&#x0D;&#x0A;echo Copying SDL_config_win32.h to SDL_config.h...&#x0D;&#x0A;copy &quot;$(ProjectDir)\..\..\include\SDL_config_win32.h&quot; &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot;&#x0D;&#x0A;:SDLCONFIGOKAY&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot; goto SDLREVISIONOKAY&#x0D;&#x0A;echo Creating stub SDL_revision.h file...&#x0D;&#x0A;echo #define SDL_REVISION 0 &gt;&quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot;&#x0D;&#x0A;:SDLREVISIONOKAY"
+				CommandLine="if exist &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot; goto SDLCONFIGOKAY&#x0D;&#x0A;echo Copying SDL_config_win32.h to SDL_config.h...&#x0D;&#x0A;copy &quot;$(ProjectDir)\..\..\include\SDL_config_win32.h&quot; &quot;$(ProjectDir)\..\..\include\SDL_config.h&quot;&#x0D;&#x0A;:SDLCONFIGOKAY&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot; goto SDLREVISIONOKAY&#x0D;&#x0A;echo Creating stub SDL_revision.h file...&#x0D;&#x0A;echo #define SDL_REVISION 0 &gt;&quot;$(ProjectDir)\..\..\include\SDL_revision.h&quot;&#x0D;&#x0A;:SDLREVISIONOKAY&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
--- a/include/SDL_events.h	Mon Jul 12 01:20:57 2010 -0700
+++ b/include/SDL_events.h	Mon Jul 12 21:09:23 2010 -0700
@@ -36,6 +36,8 @@
 #include "SDL_mouse.h"
 #include "SDL_joystick.h"
 #include "SDL_quit.h"
+#include "SDL_gesture.h"
+#include "SDL_touch.h"
 
 #include "begin_code.h"
 /* Set up for C function definitions, even when using C++ */
@@ -90,14 +92,27 @@
     SDL_JOYBUTTONDOWN,          /**< Joystick button pressed */
     SDL_JOYBUTTONUP,            /**< Joystick button released */
 
+    /* Touch events */
+    SDL_FINGERDOWN      = 0x700,
+    SDL_FINGERUP,
+    SDL_FINGERMOTION,
+    SDL_TOUCHBUTTONDOWN,
+    SDL_TOUCHBUTTONUP,    
+
+    /* Gesture events */
+    SDL_DOLLARGESTURE   = 0x800,
+    SDL_DOLLARRECORD,
+    SDL_MULTIGESTURE,
+
     /* Clipboard events */
-    SDL_CLIPBOARDUPDATE = 0x700, /**< The clipboard changed */
+    SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard changed */
 
     /* Obsolete events */
     SDL_EVENT_COMPAT1 = 0x7000, /**< SDL 1.2 events for compatibility */
     SDL_EVENT_COMPAT2,
     SDL_EVENT_COMPAT3,
 
+
     /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use,
      *  and should be allocated with SDL_RegisterEvents()
      */
@@ -263,6 +278,79 @@
     Uint8 padding1;
 } SDL_JoyButtonEvent;
 
+
+/**
+ *  \brief Touch finger motion/finger event structure (event.tmotion.*)
+ */
+typedef struct SDL_TouchFingerEvent
+{
+    Uint32 type;        /**< ::SDL_FINGERMOTION OR 
+			   SDL_FINGERDOWN OR SDL_FINGERUP*/
+    Uint32 windowID;    /**< The window with mouse focus, if any */
+    Uint8 touchId;        /**< The touch device id */
+    Uint8 state;        /**< The current button state */
+    Uint8 fingerId;
+    Uint8 padding1;
+    int x;
+    int y;
+    int pressure;
+} SDL_TouchFingerEvent;
+
+
+/**
+ *  \brief Touch finger motion/finger event structure (event.tmotion.*)
+ */
+typedef struct SDL_TouchButtonEvent
+{
+    Uint32 type;        /**< ::SDL_TOUCHBUTTONUP OR SDL_TOUCHBUTTONDOWN */
+    Uint32 windowID;    /**< The window with mouse focus, if any */
+    Uint8 touchId;        /**< The touch device index */
+    Uint8 state;        /**< The current button state */
+    Uint8 button;        /**< The button changing state */
+    Uint8 padding1;
+
+} SDL_TouchButtonEvent;
+
+
+
+/**
+ *  \brief Multiple Finger Gesture Event
+ */
+typedef struct SDL_MultiGestureEvent
+{
+    Uint32 type;        /**< ::SDL_MULTIGESTURE */
+    Uint32 windowID;    /**< The window with mouse focus, if any */
+    Uint8 touchId;        /**< The touch device index */
+    Uint8 padding1;
+    Uint8 padding2;
+    Uint8 padding3;
+    float dTheta;
+    float dDist;
+    float x;  //currently 0...1. Change to screen coords?
+    float y;  
+
+} SDL_MultiGestureEvent;
+
+typedef struct SDL_DollarGestureEvent
+{
+    Uint32 type;        /**< ::SDL_DOLLARGESTURE */
+    Uint32 windowID;    /**< The window with mouse focus, if any */
+    Uint8 touchId;        /**< The touch device index */
+    Uint8 padding1;
+    Uint8 padding2;
+    Uint8 padding3;
+    unsigned long gestureId;
+    float error;
+  /*
+    //TODO: Enable to give location?
+    float x;  //currently 0...1. Change to screen coords?
+    float y;  
+  */
+} SDL_DollarGestureEvent;
+
+
+
+
 /**
  *  \brief The "quit requested" event
  */
@@ -345,6 +433,10 @@
     SDL_QuitEvent quit;             /**< Quit request event data */
     SDL_UserEvent user;             /**< Custom event data */
     SDL_SysWMEvent syswm;           /**< System dependent window event data */
+    SDL_TouchFingerEvent tfinger;   /**< Touch finger event data */
+    SDL_TouchButtonEvent tbutton;   /**< Touch button event data */
+    SDL_MultiGestureEvent mgesture; /**< Multi Finger Gesture data*/
+    SDL_DollarGestureEvent dgesture; /**< Multi Finger Gesture data*/
 
     /** Temporarily here for backwards compatibility */
     /*@{*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/SDL_gesture.h	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,90 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 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_gesture.h
+ *  
+ *  Include file for SDL gesture event handling.
+ */
+
+#ifndef _SDL_gesture_h
+#define _SDL_gesture_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_video.h"
+
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+
+/* Function prototypes */
+
+/**
+ *  \brief Begin Recording a gesture on the specified touch, or all touches (-1)
+ *
+ *
+ */
+  extern DECLSPEC int SDLCALL SDL_RecordGesture(int touchId);
+
+
+/**
+ *  \brief Save all currently loaded Dollar Gesture templates
+ *
+ *
+ */
+  extern DECLSPEC int SDLCALL SDL_SaveAllDollarTemplates(FILE *fp);
+
+/**
+ *  \brief Save a currently loaded Dollar Gesture template
+ *
+ *
+ */
+  extern DECLSPEC int 
+  SDLCALL SDL_SaveDollarTemplate(unsigned long gestureId,FILE *fp);
+
+
+/**
+ *  \brief Load Dollar Gesture templates from a file
+ *
+ *
+ */
+  extern DECLSPEC int SDLCALL SDL_LoadDollarTemplates(int touchId, FILE *fp);
+
+
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#include "close_code.h"
+
+#endif /* _SDL_gesture_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/SDL_touch.h	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,120 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 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_touch.h
+ *  
+ *  Include file for SDL touch event handling.
+ */
+
+#ifndef _SDL_touch_h
+#define _SDL_touch_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_video.h"
+
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+
+struct SDL_Finger {
+  int id;
+  int x;
+  int y;
+  int z;                      /* for future use */
+  int xdelta;
+  int ydelta;
+  int last_x, last_y,last_pressure;  /* the last reported coordinates */
+  SDL_bool down;
+  int pressure;
+};
+
+typedef struct SDL_Touch SDL_Touch;
+typedef struct SDL_Finger SDL_Finger;
+
+
+struct SDL_Touch {
+  
+  /* Free the touch when it's time */
+  void (*FreeTouch) (SDL_Touch * touch);
+  
+  /* data common for tablets */
+  int pressure_max, pressure_min;
+  int x_max,x_min;
+  int y_max,y_min;
+  int xres,yres,pressureres;
+  int tilt;                   /* for future use */
+  int rotation;               /* for future use */
+  
+  /* Data common to all touch */
+  int id;
+  SDL_Window *focus;
+  
+  char *name;
+  Uint8 buttonstate;
+  SDL_bool relative_mode;
+  SDL_bool flush_motion;
+
+  int num_fingers;
+  int max_fingers;
+  SDL_Finger** fingers;
+    
+  void *driverdata;
+};
+
+
+
+/* Function prototypes */
+
+/**
+ *  \brief Get the touch object at the given id.
+ *
+ *
+ */
+  extern DECLSPEC SDL_Touch* SDLCALL SDL_GetTouch(int id);
+
+
+
+/**
+ *  \brief Get the finger object of the given touch, at the given id.
+ *
+ *
+ */
+  extern DECLSPEC SDL_Finger* SDLCALL SDL_GetFinger(SDL_Touch *touch, int id);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#include "close_code.h"
+
+#endif /* _SDL_mouse_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/events/SDL_events.c	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/events/SDL_events.c	Mon Jul 12 21:09:23 2010 -0700
@@ -254,6 +254,7 @@
     retcode = 0;
     retcode += SDL_KeyboardInit();
     retcode += SDL_MouseInit();
+    retcode += SDL_TouchInit();
     retcode += SDL_QuitInit();
     if (retcode < 0) {
         /* We don't expect them to fail, but... */
@@ -492,6 +493,10 @@
     if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) {
         return -1;
     }
+
+    SDL_GestureProcessEvent(event);
+    
+
     return 1;
 }
 
--- a/src/events/SDL_events_c.h	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/events/SDL_events_c.h	Mon Jul 12 21:09:23 2010 -0700
@@ -26,8 +26,9 @@
 #include "SDL_thread.h"
 #include "SDL_mouse_c.h"
 #include "SDL_keyboard_c.h"
+#include "SDL_touch_c.h"
 #include "SDL_windowevents_c.h"
-
+#include "SDL_gesture_c.h"
 /* Start and stop the event processing loop */
 extern int SDL_StartEventLoop(Uint32 flags);
 extern void SDL_StopEventLoop(void);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/events/SDL_gesture.c	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,566 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 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    Founation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/* General mouse handling code for SDL */
+
+#include "SDL_events.h"
+#include "SDL_events_c.h"
+#include "SDL_gesture_c.h"
+
+//TODO: Replace with malloc
+#define MAXFINGERS 3
+#define MAXTOUCHES 2
+#define MAXTEMPLATES 4
+#define MAXPATHSIZE 1024
+
+#define DOLLARNPOINTS 64
+#define DOLLARSIZE 256
+
+//PHI = ((sqrt(5)-1)/2)
+#define PHI 0.618033989 
+
+typedef struct {
+  float x,y;
+} Point;
+
+
+typedef struct {
+  Point p;
+  float pressure;
+  int id;
+} Finger;
+
+
+typedef struct {
+  float length;
+  
+  int numPoints;
+  Point p[MAXPATHSIZE];
+} DollarPath;
+
+
+typedef struct {
+  Finger f;
+  Point cv;
+  float dtheta,dDist;
+  DollarPath dollarPath;
+} TouchPoint;
+
+typedef struct {
+  Point path[DOLLARNPOINTS];
+  unsigned long hash;
+} DollarTemplate;
+
+typedef struct {
+  int id;
+  Point res;
+  Point centroid;
+  TouchPoint gestureLast[MAXFINGERS];
+  int numDownFingers;
+
+  int numDollarTemplates;
+  DollarTemplate dollarTemplate[MAXTEMPLATES];
+
+  SDL_bool recording;
+} GestureTouch;
+
+GestureTouch gestureTouch[MAXTOUCHES];
+int numGestureTouches = 0;
+SDL_bool recordAll;
+
+int SDL_RecordGesture(int touchId) {
+  int i;
+  if(touchId < 0) recordAll = SDL_TRUE;
+  for(i = 0;i < numGestureTouches; i++) {
+    if((touchId < 0) || (gestureTouch[i].id == touchId)) {
+      gestureTouch[i].recording = SDL_TRUE;
+      if(touchId >= 0)
+	return 1;
+    }      
+  }
+  return (touchId < 0);
+}
+
+unsigned long SDL_HashDollar(Point* points) {
+  unsigned long hash = 5381;
+  int i;
+  for(i = 0;i < DOLLARNPOINTS; i++) { 
+    hash = ((hash<<5) + hash) + points[i].x;
+    hash = ((hash<<5) + hash) + points[i].y;
+  }
+  return hash;
+}
+
+int SaveTemplate(DollarTemplate *templ, FILE *fp) {
+  int i;
+  fprintf(fp,"%lu ",templ->hash);
+  for(i = 0;i < DOLLARNPOINTS;i++) {
+    fprintf(fp,"%i %i ",(int)templ->path[i].x,(int)templ->path[i].y);
+  }
+  fprintf(fp,"\n");
+}
+
+
+int SDL_SaveAllDollarTemplates(FILE *fp) {  
+  int i,j,rtrn = 0;
+  for(i = 0; i < numGestureTouches; i++) {
+    GestureTouch* touch = &gestureTouch[i];
+    for(j = 0;j < touch->numDollarTemplates; j++) {
+	rtrn += SaveTemplate(&touch->dollarTemplate[i],fp);
+    }
+  }
+  return rtrn;  
+}
+
+int SDL_SaveDollarTemplate(unsigned long gestureId, FILE *fp) {
+  int i,j;
+  for(i = 0; i < numGestureTouches; i++) {
+    GestureTouch* touch = &gestureTouch[i];
+    for(j = 0;j < touch->numDollarTemplates; j++) {
+      if(touch->dollarTemplate[i].hash == gestureId) {
+	return SaveTemplate(&touch->dollarTemplate[i],fp);
+      }
+    }
+  }
+}
+
+int SDL_LoadDollarTemplates(int touchId, FILE *fp) {
+  int i,loaded = 0;
+  GestureTouch *touch = NULL;
+  if(touchId >= 0) {
+    for(i = 0;i < numGestureTouches; i++)
+      if(gestureTouch[i].id == touchId)
+	touch = &gestureTouch[i];
+    if(touch == NULL) return -1;
+  }
+
+  while(!feof(fp)) {
+    DollarTemplate templ;
+    fscanf(fp,"%lu ",&templ.hash);
+    for(i = 0;i < DOLLARNPOINTS; i++) {		
+      int x,y;
+      if(fscanf(fp,"%i %i ",&x,&y) != 2) break;
+      templ.path[i].x = x;
+      templ.path[i].y = y;
+    }
+    fscanf(fp,"\n");
+
+    if(touchId >= 0) {
+      if(SDL_AddDollarGesture(touch,templ)) loaded++;
+    }
+    else {
+      for(i = 0;i < numGestureTouches; i++) {
+	if(gestureTouch[i].id == touchId) {
+	  touch = &gestureTouch[i];
+	  SDL_AddDollarGesture(touch,templ);
+	}
+      }
+      loaded++;
+    }
+  }
+
+  return 1; 
+}
+
+
+//path is an already sampled set of points
+//Returns the index of the gesture on success, or -1
+int SDL_AddDollarGesture(GestureTouch* inTouch,Point* path) {
+  if(inTouch == NULL) {
+    if(numGestureTouches == 0) return -1;
+    int i = 0;
+    for(i = 0;i < numGestureTouches; i++) {
+      inTouch = &gestureTouch[i];
+      if(inTouch->numDollarTemplates < MAXTEMPLATES) {
+	DollarTemplate *templ = 
+	  &inTouch->dollarTemplate[inTouch->numDollarTemplates];
+	memcpy(templ->path,path,DOLLARNPOINTS*sizeof(Point));
+	templ->hash = SDL_HashDollar(templ->path);
+	inTouch->numDollarTemplates++;
+      }
+    }
+    return inTouch->numDollarTemplates - 1;
+  }else if(inTouch->numDollarTemplates < MAXTEMPLATES) {
+    DollarTemplate *templ = 
+      &inTouch->dollarTemplate[inTouch->numDollarTemplates];
+    memcpy(templ->path,path,DOLLARNPOINTS*sizeof(Point));
+    templ->hash = SDL_HashDollar(templ->path);
+    inTouch->numDollarTemplates++;
+    return inTouch->numDollarTemplates - 1;
+  }
+  return -1;
+}
+
+
+
+
+float dollarDifference(Point* points,Point* templ,float ang) {
+  //  Point p[DOLLARNPOINTS];
+  float dist = 0;
+  Point p;
+  int i;
+  for(i = 0; i < DOLLARNPOINTS; i++) {
+    p.x = points[i].x * cos(ang) - points[i].y * sin(ang);
+    p.y = points[i].x * sin(ang) + points[i].y * cos(ang);
+    dist += sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
+		 (p.y-templ[i].y)*(p.y-templ[i].y));
+  }
+  return dist/DOLLARNPOINTS;
+  
+}
+
+float bestDollarDifference(Point* points,Point* templ) {
+  //------------BEGIN DOLLAR BLACKBOX----------------//
+  //-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-//
+  //-"http://depts.washington.edu/aimgroup/proj/dollar/"-//
+  float ta = -M_PI/4;
+  float tb = M_PI/4;
+  float dt = M_PI/90;
+  float x1 = PHI*ta + (1-PHI)*tb;
+  float f1 = dollarDifference(points,templ,x1);
+  float x2 = (1-PHI)*ta + PHI*tb;
+  float f2 = dollarDifference(points,templ,x2);
+  while(abs(ta-tb) > dt) {
+    if(f1 < f2) {
+      tb = x2;
+      x2 = x1;
+      f2 = f1;
+      x1 = PHI*ta + (1-PHI)*tb;
+      f1 = dollarDifference(points,templ,x1);
+    }
+    else {
+      ta = x1;
+      x1 = x2;
+      f1 = f2;
+      x2 = (1-PHI)*ta + PHI*tb;
+      f2 = dollarDifference(points,templ,x2);
+    }
+  }
+  /*
+  if(f1 <= f2)
+    printf("Min angle (x1): %f\n",x1);
+  else if(f1 >  f2)
+    printf("Min angle (x2): %f\n",x2);
+  */
+  return SDL_min(f1,f2);  
+}
+
+float dollarRecognize(DollarPath path,int *bestTempl,GestureTouch* touch) {
+
+  Point points[DOLLARNPOINTS];
+  int numPoints = dollarNormalize(path,points);
+  int i;
+ 
+  int bestDiff = 10000;
+  *bestTempl = -1;
+  for(i = 0;i < touch->numDollarTemplates;i++) {
+    int diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
+    if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
+  }
+  return bestDiff;
+}
+
+//DollarPath contains raw points, plus (possibly) the calculated length
+int dollarNormalize(DollarPath path,Point *points) {
+  int i;
+  //Calculate length if it hasn't already been done
+  if(path.length <= 0) {
+    for(i=1;i<path.numPoints;i++) {
+      float dx = path.p[i  ].x - 
+	         path.p[i-1].x;
+      float dy = path.p[i  ].y - 
+	         path.p[i-1].y;
+      path.length += sqrt(dx*dx+dy*dy);
+    }
+  }
+
+
+  //Resample
+  float interval = path.length/(DOLLARNPOINTS - 1);
+  float dist = 0;
+
+  int numPoints = 0;
+  Point centroid; centroid.x = 0;centroid.y = 0;
+  //printf("(%f,%f)\n",path.p[path.numPoints-1].x,path.p[path.numPoints-1].y);
+  for(i = 1;i < path.numPoints;i++) {
+    float d = sqrt((path.p[i-1].x-path.p[i].x)*(path.p[i-1].x-path.p[i].x)+
+		   (path.p[i-1].y-path.p[i].y)*(path.p[i-1].y-path.p[i].y));
+    //printf("d = %f dist = %f/%f\n",d,dist,interval);
+    while(dist + d > interval) {
+      points[numPoints].x = path.p[i-1].x + 
+	((interval-dist)/d)*(path.p[i].x-path.p[i-1].x);
+      points[numPoints].y = path.p[i-1].y + 
+	((interval-dist)/d)*(path.p[i].y-path.p[i-1].y);
+      centroid.x += points[numPoints].x;
+      centroid.y += points[numPoints].y;
+      numPoints++;
+
+      dist -= interval;
+    }
+    dist += d;
+  }
+  if(numPoints < 1) return 0;
+  centroid.x /= numPoints;
+  centroid.y /= numPoints;
+ 
+  //printf("Centroid (%f,%f)",centroid.x,centroid.y);
+  //Rotate Points so point 0 is left of centroid and solve for the bounding box
+  float xmin,xmax,ymin,ymax;
+  xmin = centroid.x;
+  xmax = centroid.x;
+  ymin = centroid.y;
+  ymax = centroid.y;
+  
+  float ang = atan2(centroid.y - points[0].y,
+		    centroid.x - points[0].x);
+
+  for(i = 0;i<numPoints;i++) {					       
+    float px = points[i].x;
+    float py = points[i].y;
+    points[i].x = (px - centroid.x)*cos(ang) - 
+                  (py - centroid.y)*sin(ang) + centroid.x;
+    points[i].y = (px - centroid.x)*sin(ang) + 
+                  (py - centroid.y)*cos(ang) + centroid.y;
+
+
+    if(points[i].x < xmin) xmin = points[i].x;
+    if(points[i].x > xmax) xmax = points[i].x; 
+    if(points[i].y < ymin) ymin = points[i].y;
+    if(points[i].y > ymax) ymax = points[i].y;
+  }
+
+  //Scale points to DOLLARSIZE, and translate to the origin
+  float w = xmax-xmin;
+  float h = ymax-ymin;
+
+  for(i=0;i<numPoints;i++) {
+    points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
+    points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h;
+  }  
+  return numPoints;
+}
+
+int SDL_GestureAddTouch(SDL_Touch* touch) { 
+  if(numGestureTouches >= MAXTOUCHES) return -1;
+  
+  gestureTouch[numGestureTouches].res.x = touch->xres;
+  gestureTouch[numGestureTouches].res.y = touch->yres;
+  gestureTouch[numGestureTouches].numDownFingers = 0;
+
+  gestureTouch[numGestureTouches].res.x = touch->xres;
+  gestureTouch[numGestureTouches].id = touch->id;
+
+  gestureTouch[numGestureTouches].numDollarTemplates = 0;
+
+  gestureTouch[numGestureTouches].recording = SDL_FALSE;
+
+  numGestureTouches++;
+  return 0;
+}
+
+GestureTouch * SDL_GetGestureTouch(int id) {
+  int i;
+  for(i = 0;i < numGestureTouches; i++) {
+    //printf("%i ?= %i\n",gestureTouch[i].id,id);
+    if(gestureTouch[i].id == id) return &gestureTouch[i];
+  }
+  return NULL;
+}
+
+int SDL_SendGestureMulti(GestureTouch* touch,float dTheta,float dDist) {
+  SDL_Event event;
+  event.mgesture.type = SDL_MULTIGESTURE;
+  event.mgesture.touchId = touch->id;
+  event.mgesture.x = touch->centroid.x;
+  event.mgesture.y = touch->centroid.y;
+  event.mgesture.dTheta = dTheta;
+  event.mgesture.dDist = dDist;  
+  return SDL_PushEvent(&event) > 0;
+}
+
+int SDL_SendGestureDollar(GestureTouch* touch,int gestureId,float error) {
+  SDL_Event event;
+  event.dgesture.type = SDL_DOLLARGESTURE;
+  event.dgesture.touchId = touch->id;
+  /*
+    //TODO: Add this to give location of gesture?
+  event.mgesture.x = touch->centroid.x;
+  event.mgesture.y = touch->centroid.y;
+  */
+  event.dgesture.gestureId = gestureId;
+  event.dgesture.error = error;  
+  return SDL_PushEvent(&event) > 0;
+}
+
+
+int SDL_SendDollarRecord(GestureTouch* touch,int gestureId) {
+  SDL_Event event;
+  event.dgesture.type = SDL_DOLLARRECORD;
+  event.dgesture.touchId = touch->id;
+  event.dgesture.gestureId = gestureId;
+
+  return SDL_PushEvent(&event) > 0;
+}
+
+
+void SDL_GestureProcessEvent(SDL_Event* event)
+{
+  if(event->type == SDL_FINGERMOTION || 
+     event->type == SDL_FINGERDOWN ||
+     event->type == SDL_FINGERUP) {
+    GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
+
+    //Shouldn't be possible
+    if(inTouch == NULL) return;
+    
+    
+    float x = ((float)event->tfinger.x)/inTouch->res.x;
+    float y = ((float)event->tfinger.y)/inTouch->res.y;
+    int j,empty = -1;
+    
+    for(j = 0;j<inTouch->numDownFingers;j++) {
+      if(inTouch->gestureLast[j].f.id != event->tfinger.fingerId) continue;
+      //Finger Up
+      if(event->type == SDL_FINGERUP) {
+	inTouch->numDownFingers--;
+
+	if(inTouch->recording) {
+	  inTouch->recording = SDL_FALSE;
+	  Point path[DOLLARNPOINTS];
+	  dollarNormalize(inTouch->gestureLast[j].dollarPath,path);
+	  int index;
+	  if(recordAll) {
+	    index = SDL_AddDollarGesture(NULL,path);
+	    int i;
+	    for(i = 0;i < numGestureTouches; i++)
+	      gestureTouch[i].recording = SDL_FALSE;
+	  }
+	  else {
+	    index = SDL_AddDollarGesture(inTouch,path);
+	  }
+	  
+	  if(index >= 0) {
+	    SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
+	  }
+	  else {
+	    SDL_SendDollarRecord(inTouch,-1);
+	  }
+	}
+	else {	
+	  int bestTempl;
+	  float error;
+	  error = dollarRecognize(inTouch->gestureLast[j].dollarPath,
+				  &bestTempl,inTouch);
+	  if(bestTempl >= 0){
+	    //Send Event
+	    int gestureId = inTouch->dollarTemplate[bestTempl].hash;
+	    SDL_SendGestureDollar(inTouch,gestureId,error);
+	    printf("Dollar error: %f\n",error);
+	  }
+	} 
+	inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
+	break;
+      }
+      else {
+	float dx = x - inTouch->gestureLast[j].f.p.x;
+	float dy = y - inTouch->gestureLast[j].f.p.y;
+	DollarPath* path = &inTouch->gestureLast[j].dollarPath;
+	if(path->numPoints < MAXPATHSIZE) {
+	  path->p[path->numPoints].x = x;
+	  path->p[path->numPoints].y = y;
+	  path->length += sqrt(dx*dx + dy*dy);
+	  path->numPoints++;
+	}
+
+
+	inTouch->centroid.x += dx/inTouch->numDownFingers;
+	inTouch->centroid.y += dy/inTouch->numDownFingers;    
+	if(inTouch->numDownFingers > 1) {
+	  Point lv; //Vector from centroid to last x,y position
+	  Point v; //Vector from centroid to current x,y position
+	  lv = inTouch->gestureLast[j].cv;
+	  float lDist = sqrt(lv.x*lv.x + lv.y*lv.y);
+	  //printf("lDist = %f\n",lDist);
+	  v.x = x - inTouch->centroid.x;
+	  v.y = y - inTouch->centroid.y;
+	  inTouch->gestureLast[j].cv = v;
+	  float Dist = sqrt(v.x*v.x+v.y*v.y);
+	  // cos(dTheta) = (v . lv)/(|v| * |lv|)
+	  
+	  //Normalize Vectors to simplify angle calculation
+	  lv.x/=lDist;
+	  lv.y/=lDist;
+	  v.x/=Dist;
+	  v.y/=Dist;
+	  float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
+	  
+	  float dDist = (Dist - lDist);
+	  if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
+	  inTouch->gestureLast[j].dDist = dDist;
+	  inTouch->gestureLast[j].dtheta = dtheta;
+	  
+	  //printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
+	  //gdtheta = gdtheta*.9 + dtheta*.1;
+	  //gdDist  =  gdDist*.9 +  dDist*.1
+	  //knob.r += dDist/numDownFingers;
+	  //knob.ang += dtheta;
+	  //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
+	  //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
+	  SDL_SendGestureMulti(inTouch,dtheta,dDist);
+	}
+	else {
+	  inTouch->gestureLast[j].dDist = 0;
+	  inTouch->gestureLast[j].dtheta = 0;
+	  inTouch->gestureLast[j].cv.x = 0;
+	  inTouch->gestureLast[j].cv.y = 0;
+	}
+	inTouch->gestureLast[j].f.p.x = x;
+	inTouch->gestureLast[j].f.p.y = y;
+	break;
+	//pressure?
+      }      
+    }
+    
+    if(j == inTouch->numDownFingers) {
+      //printf("Finger Down!!!\n");
+      inTouch->numDownFingers++;
+      inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+ 
+			     x)/inTouch->numDownFingers;
+      inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
+			     y)/inTouch->numDownFingers;
+      
+      inTouch->gestureLast[j].f.id = event->tfinger.fingerId;
+      inTouch->gestureLast[j].f.p.x  = x;
+      inTouch->gestureLast[j].f.p.y  = y;	
+      inTouch->gestureLast[j].cv.x = 0;
+      inTouch->gestureLast[j].cv.y = 0;
+
+      inTouch->gestureLast[j].dollarPath.length = 0;
+      inTouch->gestureLast[j].dollarPath.p[0].x = x;
+      inTouch->gestureLast[j].dollarPath.p[0].y = y;
+      inTouch->gestureLast[j].dollarPath.numPoints = 1;
+    }
+  }
+}  
+  
+  /* vi: set ts=4 sw=4 expandtab: */
+  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/events/SDL_gesture_c.h	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,33 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 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"
+
+#ifndef _SDL_gesture_c_h
+#define _SDL_gesture_c_h
+
+extern void SDL_GestureProcessEvent(SDL_Event* event);
+
+extern int SDL_RecordGesture(int touchId);
+
+#endif /* _SDL_gesture_c_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/events/SDL_touch.c	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,514 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 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"
+
+/* General touch handling code for SDL */
+
+#include "SDL_events.h"
+#include "SDL_events_c.h"
+#include "../video/SDL_sysvideo.h"
+
+#include <stdio.h>
+
+
+static int SDL_num_touch = 0;
+static SDL_Touch **SDL_touchPads = NULL;
+
+
+/* Public functions */
+int
+SDL_TouchInit(void)
+{
+    
+    return (0);
+}
+
+SDL_Touch *
+SDL_GetTouch(int id)
+{
+    int index = SDL_GetTouchIndexId(id);
+    if (index < 0 || index >= SDL_num_touch) {
+        return NULL;
+    }
+    return SDL_touchPads[index];
+}
+
+SDL_Touch *
+SDL_GetTouchIndex(int index)
+{
+    if (index < 0 || index >= SDL_num_touch) {
+        return NULL;
+    }
+    return SDL_touchPads[index];
+}
+
+int
+SDL_GetFingerIndexId(SDL_Touch* touch,int fingerid)
+{
+    int i;
+    for(i = 0;i < touch->num_fingers;i++)
+	if(touch->fingers[i]->id == fingerid)
+	    return i;
+    return -1;
+}
+
+
+SDL_Finger *
+SDL_GetFinger(SDL_Touch* touch,int id)
+{
+    int index = SDL_GetFingerIndexId(touch,id);
+    if(index < 0 || index >= touch->num_fingers)
+	return NULL;
+    return touch->fingers[index];
+}
+
+
+int
+SDL_GetTouchIndexId(int id)
+{
+    int index;
+    SDL_Touch *touch;
+
+    for (index = 0; index < SDL_num_touch; ++index) {
+        touch = SDL_touchPads[index];
+        if (touch->id == id) {
+            return index;
+        }
+    }
+    return -1;
+}
+
+int
+SDL_AddTouch(const SDL_Touch * touch, char *name)
+{
+    SDL_Touch **touchPads;
+    int index,length;
+
+    if (SDL_GetTouchIndexId(touch->id) != -1) {
+        SDL_SetError("Touch ID already in use");
+    }
+
+    /* Add the touch to the list of touch */
+    touchPads = (SDL_Touch **) SDL_realloc(SDL_touchPads,
+                                      (SDL_num_touch + 1) * sizeof(*touch));
+    if (!touchPads) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+
+    SDL_touchPads = touchPads;
+    index = SDL_num_touch++;
+
+    SDL_touchPads[index] = (SDL_Touch *) SDL_malloc(sizeof(*SDL_touchPads[index]));
+    if (!SDL_touchPads[index]) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+    *SDL_touchPads[index] = *touch;
+
+    /* we're setting the touch properties */
+    length = 0;
+    length = SDL_strlen(name);
+    SDL_touchPads[index]->focus = 0;
+    SDL_touchPads[index]->name = SDL_malloc((length + 2) * sizeof(char));
+    SDL_strlcpy(SDL_touchPads[index]->name, name, length + 1);   
+
+    SDL_touchPads[index]->num_fingers = 0;
+    SDL_touchPads[index]->max_fingers = 1;
+    SDL_touchPads[index]->fingers = (SDL_Finger **) SDL_malloc(sizeof(SDL_Finger*));
+    SDL_touchPads[index]->fingers[0] = NULL;
+    SDL_touchPads[index]->buttonstate = 0;
+    SDL_touchPads[index]->relative_mode = SDL_FALSE;
+    SDL_touchPads[index]->flush_motion = SDL_FALSE;
+    
+    //Do I want this here? Probably
+    SDL_GestureAddTouch(SDL_touchPads[index]);
+
+    return index;
+}
+
+void
+SDL_DelTouch(int id)
+{
+    int index = SDL_GetTouchIndexId(id);
+    SDL_Touch *touch = SDL_GetTouch(id);
+
+    if (!touch) {
+        return;
+    }
+
+    
+    SDL_free(touch->name);
+ 
+    if (touch->FreeTouch) {
+        touch->FreeTouch(touch);
+    }
+    SDL_free(touch);
+
+    SDL_num_touch--;
+    SDL_touchPads[index] = SDL_touchPads[SDL_num_touch];
+}
+
+void
+SDL_TouchQuit(void)
+{
+    int i;
+
+    for (i = SDL_num_touch-1; i > 0 ; --i) {
+        SDL_DelTouch(i);
+    }
+    SDL_num_touch = 0;
+
+    if (SDL_touchPads) {
+        SDL_free(SDL_touchPads);
+        SDL_touchPads = NULL;
+    }
+}
+
+int
+SDL_GetNumTouch(void)
+{
+    return SDL_num_touch;
+}
+SDL_Window *
+SDL_GetTouchFocusWindow(int id)
+{
+    SDL_Touch *touch = SDL_GetTouch(id);
+
+    if (!touch) {
+        return 0;
+    }
+    return touch->focus;
+}
+
+void
+SDL_SetTouchFocus(int id, SDL_Window * window)
+{
+    int index = SDL_GetTouchIndexId(id);
+    SDL_Touch *touch = SDL_GetTouch(id);
+    int i;
+    SDL_bool focus;
+
+    if (!touch || (touch->focus == window)) {
+        return;
+    }
+
+    /* See if the current window has lost focus */
+    if (touch->focus) {
+        focus = SDL_FALSE;
+        for (i = 0; i < SDL_num_touch; ++i) {
+            SDL_Touch *check;
+            if (i != index) {
+                check = SDL_touchPads[i];
+                if (check && check->focus == touch->focus) {
+                    focus = SDL_TRUE;
+                    break;
+                }
+            }
+        }
+        if (!focus) {
+            SDL_SendWindowEvent(touch->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
+        }
+    }
+
+    touch->focus = window;
+
+    if (touch->focus) {
+        focus = SDL_FALSE;
+        for (i = 0; i < SDL_num_touch; ++i) {
+            SDL_Touch *check;
+            if (i != index) {
+                check = SDL_touchPads[i];
+                if (check && check->focus == touch->focus) {
+                    focus = SDL_TRUE;
+                    break;
+                }
+            }
+        }
+        if (!focus) {
+            SDL_SendWindowEvent(touch->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
+        }
+    }
+}
+
+int 
+SDL_AddFinger(SDL_Touch* touch,SDL_Finger* finger)
+{
+    int index;
+    SDL_Finger **fingers;
+    //printf("Adding Finger...\n");
+    if (SDL_GetFingerIndexId(touch,finger->id) != -1) {
+        SDL_SetError("Finger ID already in use");
+	}
+
+    /* Add the touch to the list of touch */
+    if(touch->num_fingers  >= touch->max_fingers){
+		//printf("Making room for it!\n");
+		fingers = (SDL_Finger **) SDL_realloc(touch->fingers,
+  						   (touch->num_fingers + 1) * sizeof(SDL_Finger *));
+		touch->max_fingers = touch->num_fingers+1;
+		if (!fingers) {
+			SDL_OutOfMemory();
+			return -1;
+		} else {
+			touch->max_fingers = touch->num_fingers+1;
+			touch->fingers = fingers;
+		}
+	}
+
+    index = touch->num_fingers;
+    //printf("Max_Fingers: %i Index: %i\n",touch->max_fingers,index);
+
+    touch->fingers[index] = (SDL_Finger *) SDL_malloc(sizeof(SDL_Finger));
+    if (!touch->fingers[index]) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+    *(touch->fingers[index]) = *finger;
+    touch->num_fingers++;
+
+    return index;
+}
+
+int
+SDL_DelFinger(SDL_Touch* touch,int fingerid)
+{
+    int index = SDL_GetFingerIndexId(touch,fingerid);
+    SDL_Finger* finger = SDL_GetFinger(touch,fingerid);
+
+    if (!finger) {
+        return -1;
+    }
+ 
+
+    SDL_free(finger);
+    touch->num_fingers--;
+    touch->fingers[index] = touch->fingers[touch->num_fingers];
+    return 0;
+}
+
+
+int
+SDL_SendFingerDown(int id, int fingerid, SDL_bool down, int x, int y, int pressure)
+{
+    int posted;
+    SDL_Touch* touch = SDL_GetTouch(id);
+
+    if(down) {
+	SDL_Finger *finger = SDL_GetFinger(touch,fingerid);
+	if(finger == NULL) {
+	    SDL_Finger nf;
+	    nf.id = fingerid;
+	    nf.x = x;
+	    nf.y = y;
+	    nf.pressure = pressure;
+	    nf.xdelta = 0;
+	    nf.ydelta = 0;
+	    nf.last_x = x;
+	    nf.last_y = y;
+	    nf.last_pressure = pressure;
+	    nf.down = SDL_FALSE;
+	    SDL_AddFinger(touch,&nf);
+	    finger = &nf;
+	}
+	else if(finger->down) return 0;
+	if(x < 0 || y < 0) return 0; //should defer if only a partial input
+	posted = 0;
+	if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
+	    SDL_Event event;
+	    event.tfinger.type = SDL_FINGERDOWN;
+	    event.tfinger.touchId = (Uint8) id;
+	    event.tfinger.x = x;
+	    event.tfinger.y = y;
+	    event.tfinger.state = touch->buttonstate;
+	    event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
+	    event.tfinger.fingerId = fingerid;
+	    posted = (SDL_PushEvent(&event) > 0);
+	}
+	if(posted) finger->down = SDL_TRUE;
+	return posted;
+    }
+    else {
+	if(SDL_DelFinger(touch,fingerid) < 0) return 0;
+	posted = 0;
+	if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
+	    SDL_Event event;
+	    event.tfinger.type = SDL_FINGERUP;
+	    event.tfinger.touchId = (Uint8) id;
+	    event.tfinger.state = touch->buttonstate;
+	    event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
+	    event.tfinger.fingerId = fingerid;
+	    posted = (SDL_PushEvent(&event) > 0);
+	}
+	return posted;
+    }
+}
+
+int
+SDL_SendTouchMotion(int id, int fingerid, int relative, 
+		    int x, int y, int pressure)
+{
+    int index = SDL_GetTouchIndexId(id);
+    SDL_Touch *touch = SDL_GetTouch(id);
+    SDL_Finger *finger = SDL_GetFinger(touch,fingerid);
+    int posted;
+    int xrel;
+    int yrel;
+    int x_max = 0, y_max = 0;
+    
+    if (!touch || touch->flush_motion) {
+	return 0;
+    }
+    
+    if(finger == NULL || !finger->down) {
+	return SDL_SendFingerDown(id,fingerid,SDL_TRUE,x,y,pressure);	
+    } else {
+	/* the relative motion is calculated regarding the last position */
+	if (relative) {
+	    xrel = x;
+	    yrel = y;
+	    x = (finger->last_x + x);
+	    y = (finger->last_y + y);
+	} else {
+	    if(x < 0) x = finger->last_x; /*If movement is only in one axis,*/
+	    if(y < 0) y = finger->last_y; /*The other is marked as -1*/
+	    if(pressure < 0) pressure = finger->last_pressure;
+	    xrel = x - finger->last_x;
+	    yrel = y - finger->last_y;
+	}
+	
+	/* Drop events that don't change state */
+	if (!xrel && !yrel) {
+#if 0
+	    printf("Touch event didn't change state - dropped!\n");
+#endif
+	    return 0;
+	}
+	
+	/* Update internal touch coordinates */
+	
+	finger->x = x;
+	finger->y = y;
+	
+	/*Should scale to window? Normalize? Maintain Aspect?*/
+	//SDL_GetWindowSize(touch->focus, &x_max, &y_max);
+	
+	/* make sure that the pointers find themselves inside the windows */
+	/* only check if touch->xmax is set ! */
+	/*
+	  if (x_max && touch->x > x_max) {
+	  touch->x = x_max;
+	  } else if (touch->x < 0) {
+	  touch->x = 0;
+	  }
+	  
+	  if (y_max && touch->y > y_max) {
+	  touch->y = y_max;
+	  } else if (touch->y < 0) {
+	  touch->y = 0;
+	  }
+	*/
+	finger->xdelta = xrel;
+	finger->ydelta = yrel;
+	finger->pressure = pressure;
+	
+	
+	
+	/* Post the event, if desired */
+	posted = 0;
+	if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
+	    SDL_Event event;
+	    event.tfinger.type = SDL_FINGERMOTION;
+	    event.tfinger.touchId = (Uint8) id;
+	    event.tfinger.fingerId = (Uint8) fingerid;
+	    event.tfinger.x = x;
+	    event.tfinger.y = y;
+	    event.tfinger.pressure = pressure;
+	    event.tfinger.state = touch->buttonstate;
+	    event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
+	    posted = (SDL_PushEvent(&event) > 0);
+	}
+	finger->last_x = finger->x;
+	finger->last_y = finger->y;
+	finger->last_pressure = finger->pressure;
+	return posted;
+    }
+}
+int
+SDL_SendTouchButton(int id, Uint8 state, Uint8 button)
+{
+    SDL_Touch *touch = SDL_GetTouch(id);
+    int posted;
+    Uint32 type;
+
+    if (!touch) {
+        return 0;
+    }
+
+    /* Figure out which event to perform */
+    switch (state) {
+    case SDL_PRESSED:
+        if (touch->buttonstate & SDL_BUTTON(button)) {
+            /* Ignore this event, no state change */
+            return 0;
+        }
+        type = SDL_TOUCHBUTTONDOWN;
+        touch->buttonstate |= SDL_BUTTON(button);
+        break;
+    case SDL_RELEASED:
+        if (!(touch->buttonstate & SDL_BUTTON(button))) {
+            /* Ignore this event, no state change */
+            return 0;
+        }
+        type = SDL_TOUCHBUTTONUP;
+        touch->buttonstate &= ~SDL_BUTTON(button);
+        break;
+    default:
+        /* Invalid state -- bail */
+        return 0;
+    }
+
+    /* Post the event, if desired */
+    posted = 0;
+    if (SDL_GetEventState(type) == SDL_ENABLE) {
+        SDL_Event event;
+        event.type = type;
+        event.tbutton.touchId = (Uint8) touch->id;
+        event.tbutton.state = state;
+        event.tbutton.button = button;
+        event.tbutton.windowID = touch->focus ? touch->focus->id : 0;
+        posted = (SDL_PushEvent(&event) > 0);
+    }
+    return posted;
+}
+
+char *
+SDL_GetTouchName(int id)
+{
+    SDL_Touch *touch = SDL_GetTouch(id);
+    if (!touch) {
+        return NULL;
+    }
+    return touch->name;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/events/SDL_touch_c.h	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,75 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 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"
+#include "../../include/SDL_touch.h"
+
+#ifndef _SDL_touch_c_h
+#define _SDL_touch_c_h
+
+
+
+/* Initialize the touch subsystem */
+extern int SDL_TouchInit(void);
+
+/*Get the touch at an index */
+extern SDL_Touch *SDL_GetTouchIndex(int index);
+
+/* Get the touch with id = id */
+extern SDL_Touch *SDL_GetTouch(int id);
+
+/*Get the finger at an index */
+extern SDL_Finger *SDL_GetFingerIndex(SDL_Touch *touch, int index);
+
+/* Get the finger with id = id */
+extern SDL_Finger *SDL_GetFinger(SDL_Touch *touch,int id);
+
+
+/* Add a touch, possibly reattaching at a particular index (or -1),
+   returning the index of the touch, or -1 if there was an error. */
+extern int SDL_AddTouch(const SDL_Touch * touch, char *name);
+                     
+
+/* Remove a touch at an index, clearing the slot for later */
+extern void SDL_DelTouch(int index);
+
+/* Set the touch focus window */
+extern void SDL_SetTouchFocus(int id, SDL_Window * window);
+
+/* Send a touch motion event for a touch */
+extern int SDL_SendTouchMotion(int id, int fingerid,
+			       int relative, int x, int y, int z);
+
+/* Send a touch button event for a touch */
+extern int SDL_SendTouchButton(int id, Uint8 state, Uint8 button);
+
+/* Shutdown the touch subsystem */
+extern void SDL_TouchQuit(void);
+
+/* Get the index of a touch device */
+extern int SDL_GetTouchIndexId(int id);
+
+
+
+
+#endif /* _SDL_touch_c_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/uikit/SDL_uikitview.h	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/video/uikit/SDL_uikitview.h	Mon Jul 12 21:09:23 2010 -0700
@@ -37,8 +37,8 @@
 @interface SDL_uikitview : UIView {
 #endif
 
-#if FIXME_MULTITOUCH
-	SDL_Mouse mice[MAX_SIMULTANEOUS_TOUCHES];
+#if FIXED_MULTITOUCH
+	int touchId;
 #endif
 
 #if SDL_IPHONE_KEYBOARD
--- a/src/video/uikit/SDL_uikitview.m	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/video/uikit/SDL_uikitview.m	Mon Jul 12 21:09:23 2010 -0700
@@ -48,16 +48,27 @@
 	[self initializeKeyboard];
 #endif	
 
-#if FIXME_MULTITOUCH
-	int i;
-	for (i=0; i<MAX_SIMULTANEOUS_TOUCHES; i++) {
-        mice[i].id = i;
-		mice[i].driverdata = NULL;
-		SDL_AddMouse(&mice[i], "Mouse", 0, 0, 1);
-	}
-	self.multipleTouchEnabled = YES;
+#if FIXED_MULTITOUCH
+	SDL_Touch touch;
+	touch.id = 0; //TODO: Should be -1?
+
+	//touch.driverdata = SDL_malloc(sizeof(EventTouchData));
+	//EventTouchData* data = (EventTouchData*)(touch.driverdata);
+	
+	touch.x_min = 0;
+	touch.x_max = frame.size.width;
+	touch.xres = touch.x_max - touch.x_min;
+	touch.y_min = 0;
+	touch.y_max = frame.size.height;
+	touch.yres = touch.y_max - touch.y_min;
+	touch.pressure_min = 0;
+	touch.pressure_max = 1;
+	touch.pressureres = touch.pressure_max - touch.pressure_min;
+
+
+	touchId = SDL_AddTouch(&touch, "IPHONE SCREEN");
 #endif
-			
+
 	return self;
 
 }
@@ -67,48 +78,6 @@
 	NSEnumerator *enumerator = [touches objectEnumerator];
 	UITouch *touch = (UITouch*)[enumerator nextObject];
 	
-#if FIXME_MULTITOUCH
-	/* associate touches with mice, so long as we have slots */
-	int i;
-	int found = 0;
-	for(i=0; touch && i < MAX_SIMULTANEOUS_TOUCHES; i++) {
-	
-		/* check if this mouse is already tracking a touch */
-		if (mice[i].driverdata != NULL) {
-			continue;
-		}
-		/*	
-			mouse not associated with anything right now,
-			associate the touch with this mouse
-		*/
-		found = 1;
-		
-		/* save old mouse so we can switch back */
-		int oldMouse = SDL_SelectMouse(-1);
-		
-		/* select this slot's mouse */
-		SDL_SelectMouse(i);
-		CGPoint locationInView = [touch locationInView: self];
-		
-		/* set driver data to touch object, we'll use touch object later */
-		mice[i].driverdata = [touch retain];
-		
-		/* send moved event */
-		SDL_SendMouseMotion(i, 0, locationInView.x, locationInView.y, 0);
-		
-		/* send mouse down event */
-		SDL_SendMouseButton(i, SDL_PRESSED, SDL_BUTTON_LEFT);
-		
-		/* re-calibrate relative mouse motion */
-		SDL_GetRelativeMouseState(i, NULL, NULL);
-		
-		/* switch back to our old mouse */
-		SDL_SelectMouse(oldMouse);
-		
-		/* grab next touch */
-		touch = (UITouch*)[enumerator nextObject]; 
-	}
-#else
 	if (touch) {
 		CGPoint locationInView = [touch locationInView: self];
 			
@@ -118,6 +87,16 @@
 		/* send mouse down event */
 		SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT);
 	}
+
+#if FIXED_MULTITOUCH
+	while(touch) {
+	  CGPoint locationInView = [touch locationInView: self];
+	  SDL_SendFingerDown(touchId,(int)touch,
+			     SDL_TRUE,locationInView.x,locationInView.y,
+			     1);
+
+	  touch = (UITouch*)[enumerator nextObject]; 
+	}
 #endif
 }
 
@@ -126,30 +105,20 @@
 	NSEnumerator *enumerator = [touches objectEnumerator];
 	UITouch *touch = (UITouch*)[enumerator nextObject];
 	
-#if FIXME_MULTITOUCH
-	while(touch) {
-		/* search for the mouse slot associated with this touch */
-		int i, found = NO;
-		for (i=0; i<MAX_SIMULTANEOUS_TOUCHES && !found; i++) {
-			if (mice[i].driverdata == touch) {
-				/* found the mouse associate with the touch */
-				[(UITouch*)(mice[i].driverdata) release];
-				mice[i].driverdata = NULL;
-				/* send mouse up */
-				SDL_SendMouseButton(i, SDL_RELEASED, SDL_BUTTON_LEFT);
-				/* discontinue search for this touch */
-				found = YES;
-			}
-		}
-		
-		/* grab next touch */
-		touch = (UITouch*)[enumerator nextObject]; 
-	}
-#else
 	if (touch) {
 		/* send mouse up */
 		SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT);
 	}
+
+#if FIXED_MULTITOUCH
+	while(touch) {
+	  CGPoint locationInView = [touch locationInView: self];
+	  SDL_SendFingerDown(touchId,(int)touch,
+			     SDL_FALSE,locationInView.x,locationInView.y,
+			     1);
+
+	  touch = (UITouch*)[enumerator nextObject]; 
+	}
 #endif
 }
 
@@ -167,31 +136,22 @@
 	NSEnumerator *enumerator = [touches objectEnumerator];
 	UITouch *touch = (UITouch*)[enumerator nextObject];
 	
-#if FIXME_MULTITOUCH
-	while(touch) {
-		/* try to find the mouse associated with this touch */
-		int i, found = NO;
-		for (i=0; i<MAX_SIMULTANEOUS_TOUCHES && !found; i++) {
-			if (mice[i].driverdata == touch) {
-				/* found proper mouse */
-				CGPoint locationInView = [touch locationInView: self];
-				/* send moved event */
-				SDL_SendMouseMotion(i, 0, locationInView.x, locationInView.y, 0);
-				/* discontinue search */
-				found = YES;
-			}
-		}
-		
-		/* grab next touch */
-		touch = (UITouch*)[enumerator nextObject]; 
-	}
-#else
 	if (touch) {
 		CGPoint locationInView = [touch locationInView: self];
 
 		/* send moved event */
 		SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y);
 	}
+
+#if FIXED_MULTITOUCH
+	while(touch) {
+	  CGPoint locationInView = [touch locationInView: self];
+	  SDL_SendTouchMotion(touchId,(int)touch,
+			     SDL_FALSE,locationInView.x,locationInView.y,
+			     1);
+
+	  touch = (UITouch*)[enumerator nextObject]; 
+	}
 #endif
 }
 
--- a/src/video/win32/SDL_win32events.c	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/video/win32/SDL_win32events.c	Mon Jul 12 21:09:23 2010 -0700
@@ -20,9 +20,9 @@
     slouken@libsdl.org
 */
 
-#if (_WIN32_WINNT < 0x0501)
+#if (_WIN32_WINNT < 0x601)
 #undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
+#define _WIN32_WINNT 0x601
 #endif
 
 #include "SDL_config.h"
@@ -32,11 +32,14 @@
 #include "SDL_vkeys.h"
 #include "../../events/SDL_events_c.h"
 
-/*#define WMMSG_DEBUG*/
+
+
+#define WMMSG_DEBUG
 #ifdef WMMSG_DEBUG
-#include <stdio.h>
+#include <stdio.h>	
 #include "wmmsg.h"
 #endif
+//#include <stdio.h>
 
 /* Masks for processing the windows KEYDOWN and KEYUP messages */
 #define REPEATED_KEYMASK    (1<<30)
@@ -117,9 +120,10 @@
     if (!data) {
         return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
     }
+
 #ifdef WMMSG_DEBUG
-    {
-        FILE *log = fopen("wmmsg.txt", "a");
+    {		
+        FILE *log = fopen("wmmsg.txt", "a");		
         fprintf(log, "Received windows message: %p ", hwnd);
         if (msg > MAX_WMMSG) {
             fprintf(log, "%d", msg);
@@ -495,7 +499,39 @@
         }
         returnCode = 0;
         break;
-    }
+	case WM_TOUCH:
+		{
+			//printf("Got Touch Event!\n");
+    
+			FILE *log = fopen("wmmsg.txt", "a");
+			fprintf(log, "Received Touch Message: %p ", hwnd);
+			if (msg > MAX_WMMSG) {
+				fprintf(log, "%d", msg);
+			} else {
+				fprintf(log, "%s", wmtab[msg]);
+			}
+			fprintf(log, "WM_TOUCH = %d -- 0x%X, 0x%X\n",msg, wParam, lParam);
+			fclose(log);
+    
+		}
+		break;
+	case WM_GESTURE:
+		{
+			//printf("Got Touch Event!\n");
+    
+			FILE *log = fopen("wmmsg.txt", "a");
+			fprintf(log, "Received Gesture Message: %p ", hwnd);
+			if (msg > MAX_WMMSG) {
+				fprintf(log, "%d", msg);
+			} else {
+				fprintf(log, "%s", wmtab[msg]);
+			}
+			fprintf(log, "WM_GESTURE = %d -- 0x%X, 0x%X\n",msg, wParam, lParam);
+			fclose(log);
+    
+		}
+		break;		
+	}
 
     /* If there's a window proc, assume it's going to handle messages */
     if (data->wndproc) {
--- a/src/video/win32/SDL_win32video.h	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/video/win32/SDL_win32video.h	Mon Jul 12 21:09:23 2010 -0700
@@ -30,7 +30,14 @@
 #define STRICT
 #define UNICODE
 #undef WINVER
-#define WINVER  0x500           /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */
+//#define WINVER  0x500           /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */
+#define WINVER 0x601  /* Need 0x600 (_WIN32_WINNT_WIN7) for WM_Touch */
+#if (_WIN32_WINNT < 0x601)
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x601
+#endif
+
+
 #include <windows.h>
 
 #if SDL_VIDEO_RENDER_D3D
--- a/src/video/win32/SDL_win32window.c	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/video/win32/SDL_win32window.c	Mon Jul 12 21:09:23 2010 -0700
@@ -250,6 +250,7 @@
         WIN_SetError("Couldn't create window");
         return -1;
     }
+	//RegisterTouchWindow(hwnd, 0);
 
     WIN_PumpEvents(_this);
 
--- a/src/video/win32/wmmsg.h	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/video/win32/wmmsg.h	Mon Jul 12 21:09:23 2010 -0700
@@ -283,7 +283,7 @@
     "WM_INITMENU",
     "WM_INITMENUPOPUP",
     "UNKNOWN (280)",
-    "UNKNOWN (281)",
+    "WM_GESTURE",
     "UNKNOWN (282)",
     "UNKNOWN (283)",
     "UNKNOWN (284)",
@@ -578,7 +578,7 @@
     "UNKNOWN (573)",
     "UNKNOWN (574)",
     "UNKNOWN (575)",
-    "UNKNOWN (576)",
+    "WM_TOUCH",
     "UNKNOWN (577)",
     "UNKNOWN (578)",
     "UNKNOWN (579)",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/x11/SDL_eventtouch.c	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,120 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 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"
+#include "SDL_x11video.h"
+#include "SDL_eventtouch.h"
+#include "../../events/SDL_touch_c.h"
+
+#include <linux/input.h>
+#include <fcntl.h>
+
+void
+X11_InitTouch(_THIS)
+{
+  printf("Initializing touch...\n");
+
+  FILE *fd;
+  fd = fopen("/proc/bus/input/devices","r");
+  
+  char c;
+  int i = 0;
+  char line[256];
+  char tstr[256];
+  int vendor = -1,product = -1,event = -1;
+  while(!feof(fd)) {
+    if(fgets(line,256,fd) <=0) continue;
+    //printf("%s",line);
+    if(line[0] == '\n') {
+      if(vendor == 1386){
+	printf("Wacom... Assuming it is a touch device\n");
+	sprintf(tstr,"/dev/input/event%i",event);
+	printf("At location: %s\n",tstr);
+
+	SDL_Touch touch;
+	touch.pressure_max = 0;
+	touch.pressure_min = 0;
+	touch.id = event; 
+
+	
+
+	
+
+	touch.driverdata = SDL_malloc(sizeof(EventTouchData));
+	EventTouchData* data = (EventTouchData*)(touch.driverdata);
+	printf("Opening device...\n");
+	//printf("New Touch - DataPtr: %i\n",data);
+	data->eventStream = open(tstr, 
+				 O_RDONLY | O_NONBLOCK);
+	ioctl (data->eventStream, EVIOCGNAME (sizeof (tstr)), tstr);
+	printf ("Reading From : %s\n", tstr);
+
+
+
+	int abs[5];
+	ioctl(data->eventStream,EVIOCGABS(0),abs);	
+	touch.x_min = abs[1];
+	touch.x_max = abs[2];
+	touch.xres = touch.x_max - touch.x_min;
+	ioctl(data->eventStream,EVIOCGABS(ABS_Y),abs);	
+	touch.y_min = abs[1];
+	touch.y_max = abs[2];
+	touch.yres = touch.y_max - touch.y_min;
+	ioctl(data->eventStream,EVIOCGABS(ABS_PRESSURE),abs);	
+	touch.pressure_min = abs[1];
+	touch.pressure_max = abs[2];
+	touch.pressureres = touch.pressure_max - touch.pressure_min;
+
+
+	SDL_AddTouch(&touch, tstr);
+
+      }
+      vendor = -1;
+      product = -1;
+      event = -1;      
+    }
+    else if(line[0] == 'I') {
+      i = 1;
+      while(line[i]) {
+	sscanf(&line[i],"Vendor=%x",&vendor);
+	sscanf(&line[i],"Product=%x",&product);
+	i++;
+      }
+    }
+    else if(line[0] == 'H') {
+      i = 1;
+      while(line[i]) {
+	sscanf(&line[i],"event%d",&event);
+	i++;
+      }
+    }
+  }
+  
+  close(fd);
+}
+
+void
+X11_QuitTouch(_THIS)
+{
+    SDL_TouchQuit();
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/x11/SDL_eventtouch.h	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,43 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 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"
+
+#ifndef _SDL_eventtouch_h
+#define _SDL_eventtouch_h
+
+
+//What should this be?
+#if SDL_VIDEO_DRIVER_X11_XINPUT
+typedef struct EventTouchData
+{
+    int x,y,pressure,finger; //Temporary Variables until sync
+    int eventStream;
+    SDL_bool up;
+} EventTouchData;
+#endif
+
+extern void X11_InitTouch(_THIS);
+extern void X11_QuitTouch(_THIS);
+
+#endif /* _SDL_eventtouch_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/x11/SDL_x11events.c	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/video/x11/SDL_x11events.c	Mon Jul 12 21:09:23 2010 -0700
@@ -30,10 +30,17 @@
 #include "SDL_x11video.h"
 #include "../../events/SDL_events_c.h"
 #include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_touch_c.h"
 
 #include "SDL_timer.h"
 #include "SDL_syswm.h"
 
+#include <stdio.h>
+
+//Touch Input/event* includes
+#include <linux/input.h>
+#include <fcntl.h>
+
 /*#define DEBUG_XEVENTS*/
 
 static void
@@ -101,7 +108,6 @@
             SDL_SetMouseFocus(data->window);
         }
         break;
-
         /* Losing mouse coverage? */
     case LeaveNotify:{
 #ifdef DEBUG_XEVENTS
@@ -394,6 +400,78 @@
     while (X11_Pending(data->display)) {
         X11_DispatchEvent(_this);
     }
+
+
+    /* Process Touch events - TODO When X gets touch support, use that instead*/
+    int i = 0,rd;
+    char name[256];
+    struct input_event ev[64];
+    int size = sizeof (struct input_event);
+
+    for(i = 0;i < SDL_GetNumTouch();++i) {
+	SDL_Touch* touch = SDL_GetTouchIndex(i);
+	if(!touch) printf("Touch %i/%i DNE\n",i,SDL_GetNumTouch());
+	EventTouchData* data;
+	data = (EventTouchData*)(touch->driverdata);
+	if(data == NULL) {
+	  printf("No driver data\n");
+	  continue;
+	}
+	if(data->eventStream <= 0) 
+	    printf("Error: Couldn't open stream\n");
+	rd = read(data->eventStream, ev, size * 64);
+	//printf("Got %i/%i bytes\n",rd,size);
+	if(rd >= size) {
+	    for (i = 0; i < rd / sizeof(struct input_event); i++) {
+		switch (ev[i].type) {
+		case EV_ABS:
+		    //printf("Got position x: %i!\n",data->x);
+		    switch (ev[i].code) {
+			case ABS_X:
+			    data->x = ev[i].value;
+			    break;
+			case ABS_Y:
+			    data->y = ev[i].value;
+			    break;
+			case ABS_PRESSURE:
+			    data->pressure = ev[i].value;
+			    if(data->pressure < 0) data->pressure = 0;
+			    break;
+			case ABS_MISC:
+			    data->up = SDL_TRUE;
+			    data->finger = ev[i].value;
+			    break;
+			}
+		    break;
+		case EV_MSC:
+		    if(ev[i].code == MSC_SERIAL)
+			data->finger = ev[i].value;
+		    break;
+		case EV_SYN:
+		  //printf("Id: %i\n",touch->id); 
+		  if(data->up) {
+		      SDL_SendFingerDown(touch->id,data->finger,
+			  	       SDL_FALSE,data->x,data->y,
+				       data->pressure);
+		  }
+		  else if(data->x >= 0 || data->y >= 0)
+		      SDL_SendTouchMotion(touch->id,data->finger, 
+					SDL_FALSE,data->x,data->y,
+					    data->pressure);
+		  
+		    //printf("Synched: %i tx: %i, ty: %i\n",
+		    //	   data->finger,data->x,data->y);
+		    data->x = -1;
+		    data->y = -1;
+		    data->pressure = -1;
+		    data->finger = 0;
+		    data->up = SDL_FALSE;
+		    
+		    break;		
+		}
+	    }
+	}
+    }
 }
 
 /* This is so wrong it hurts */
--- a/src/video/x11/SDL_x11video.c	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/video/x11/SDL_x11video.c	Mon Jul 12 21:09:23 2010 -0700
@@ -25,6 +25,7 @@
 
 #include "SDL_video.h"
 #include "SDL_mouse.h"
+#include "SDL_eventtouch.h" 
 #include "../SDL_sysvideo.h"
 #include "../SDL_pixels_c.h"
 
@@ -275,6 +276,7 @@
     }
     X11_InitMouse(_this);
 
+    X11_InitTouch(_this);
     return 0;
 }
 
@@ -295,6 +297,7 @@
     X11_QuitModes(_this);
     X11_QuitKeyboard(_this);
     X11_QuitMouse(_this);
+    X11_QuitTouch(_this);
 }
 
 SDL_bool
--- a/src/video/x11/SDL_x11video.h	Mon Jul 12 01:20:57 2010 -0700
+++ b/src/video/x11/SDL_x11video.h	Mon Jul 12 21:09:23 2010 -0700
@@ -54,6 +54,7 @@
 #include "SDL_x11keyboard.h"
 #include "SDL_x11modes.h"
 #include "SDL_x11mouse.h"
+#include "SDL_eventtouch.h"
 #include "SDL_x11opengl.h"
 #include "SDL_x11window.h"
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/TODO	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,1 @@
+Pressure is sometimes negative
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/gestureSDLTest.c	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,423 @@
+#include <stdio.h>
+#include <SDL.h>
+#include <math.h>
+#include <SDL_touch.h>
+#include <SDL_gesture.h>
+
+#define PI 3.1415926535897
+#define PHI ((sqrt(5)-1)/2)
+#define WIDTH 640
+#define HEIGHT 480
+#define BPP 4
+#define DEPTH 32
+
+#define MAXFINGERS 3
+
+#define DOLLARNPOINTS 64
+#define DOLLARSIZE 256
+
+//MUST BE A POWER OF 2!
+#define EVENT_BUF_SIZE 256
+
+SDL_Event events[EVENT_BUF_SIZE];
+int eventWrite;
+
+int mousx,mousy;
+int keystat[512];
+int bstatus;
+
+int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
+
+int index2fingerid[MAXFINGERS];
+int fingersDown;
+
+typedef struct {
+  float x,y;
+} Point;
+
+typedef struct {
+  Point p;
+  float pressure;
+  int id;
+} Finger;
+
+typedef struct {
+  Finger f;
+  Point cv;
+  float dtheta,dDist;
+} TouchPoint;
+
+ 
+typedef struct { //dt + s
+  Point d,s; //direction, start
+  int points;
+} Line;
+
+
+typedef struct {
+  float length;
+  
+  int numPoints;
+  Point p[EVENT_BUF_SIZE]; //To be safe
+} DollarPath;
+
+typedef struct {
+  float ang,r;
+  Point p;
+} Knob;
+
+Knob knob;
+
+Finger finger[MAXFINGERS];
+
+
+DollarPath dollarPath[MAXFINGERS];
+
+#define MAXTEMPLATES 4
+
+Point dollarTemplate[MAXTEMPLATES][DOLLARNPOINTS];
+int numDollarTemplates = 0;
+#ifdef DRAW_VECTOR_EST
+Line gestureLine[MAXFINGERS];
+#endif
+
+void handler (int sig)
+{
+  printf ("\exiting...(%d)\n", sig);
+  exit (0);
+}
+
+void perror_exit (char *error)
+{
+  perror (error);
+  handler (9);
+}
+
+
+void setpix(SDL_Surface *screen, int x, int y, unsigned int col)
+{
+  Uint32 *pixmem32;
+  Uint32 colour;
+  
+  if((unsigned)x > screen->w) return;
+  if((unsigned)y > screen->h) return;
+
+  pixmem32 = (Uint32*) screen->pixels  + y*screen->pitch/BPP + x;
+  
+  Uint8 r,g,b;
+  float a;
+  
+  memcpy(&colour,pixmem32,screen->format->BytesPerPixel);
+
+  SDL_GetRGB(colour,screen->format,&r,&g,&b); //Always returns 0xFFFFFF?
+  //r = 0;g = 0; b = 0;
+  a = (col>>24)&0xFF;
+  if(a == 0) a = 0xFF; //Hack, to make things easier.
+  a /= 0xFF;
+  r = r*(1-a) + ((col>>16)&0xFF)*(a);
+  g = g*(1-a) + ((col>> 8)&0xFF)*(a);
+  b = b*(1-a) + ((col>> 0)&0xFF)*(a);
+  colour = SDL_MapRGB( screen->format,r, g, b);
+  
+
+  *pixmem32 = colour;
+}
+
+void drawLine(SDL_Surface *screen,int x0,int y0,int x1,int y1,unsigned int col) {
+  float t;
+  for(t=0;t<1;t+=1.f/SDL_max(abs(x0-x1),abs(y0-y1)))
+    setpix(screen,x1+t*(x0-x1),y1+t*(y0-y1),col);
+}
+void drawCircle(SDL_Surface* screen,int x,int y,int r,unsigned int c)
+{
+
+  float a;
+  int tx;
+  
+  int ty;
+  float xr;
+  for(ty = -abs(r);ty <= abs(r);ty++) {
+    xr = sqrt(r*r - ty*ty);
+    if(r > 0) { //r > 0 ==> filled circle
+      for(tx=-xr+.5;tx<=xr-.5;tx++) {
+	setpix(screen,x+tx,y+ty,c);
+      }
+    }
+    else {
+      setpix(screen,x-xr+.5,y+ty,c);
+      setpix(screen,x+xr-.5,y+ty,c);
+    }
+  }
+}
+
+void drawKnob(SDL_Surface* screen,Knob k) {
+  //printf("Knob: x = %f, y = %f, r = %f, a = %f\n",k.p.x,k.p.y,k.r,k.ang);
+ 
+  drawCircle(screen,k.p.x*screen->w,k.p.y*screen->h,k.r*screen->w,0xFFFFFF);
+  
+  drawCircle(screen,(k.p.x+k.r/2*cos(k.ang))*screen->w,
+  	            (k.p.y+k.r/2*sin(k.ang))*screen->h,k.r/4*screen->w,0);
+  
+}
+
+void DrawScreen(SDL_Surface* screen, int h)
+{
+  int x, y, xm,ym,c;
+  if(SDL_MUSTLOCK(screen))
+    {                                              
+      if(SDL_LockSurface(screen) < 0) return;
+    }
+  for(y = 0; y < screen->h; y++ )
+    {
+      for( x = 0; x < screen->w; x++ )
+        {
+	  //setpixel(screen, x, y, (x*x)/256+3*y+h, (y*y)/256+x+h, h);
+	  //xm = (x+h)%screen->w;
+	  //ym = (y+h)%screen->w;
+	  //c = sin(h/256*2*PI)*x*y/screen->w/screen->h;
+	  //setpix(screen,x,y,255*sin(xm/screen->w*2*PI),sin(h/255*2*PI)*255*y/screen->h,c);
+	  setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
+	  //setpix(screen,x,y,0); //Inefficient, but that's okay...
+        }
+    }
+  drawCircle(screen,mousx,mousy,-30,0xFFFFFF);
+  drawLine(screen,0,0,screen->w,screen->h,0xFFFFFF);
+
+  int i;
+//draw Touch History
+  TouchPoint gestureLast[MAXFINGERS];
+  //printf("------------------Start History------------------\n");
+  for(i = 0;i < MAXFINGERS;i++) {
+    gestureLast[i].f.id = -1;
+  }
+  int numDownFingers = 0;
+  Point centroid;
+  float gdtheta,gdDist;
+
+
+  for(i = SDL_max(0,eventWrite - EVENT_BUF_SIZE);i < eventWrite;i++) {
+    SDL_Event event = events[i&(EVENT_BUF_SIZE-1)];
+    int age = eventWrite - i - 1;
+    if(event.type == SDL_FINGERMOTION || 
+       event.type == SDL_FINGERDOWN ||
+       event.type == SDL_FINGERUP) {
+      SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
+      //SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId);
+	    
+      float x = ((float)event.tfinger.x)/inTouch->xres;
+      float y = ((float)event.tfinger.y)/inTouch->yres;      
+      
+      //draw the touch:
+      
+      unsigned int c = colors[event.tfinger.touchId%7]; 
+      unsigned int col = 
+	((unsigned int)(c*(.1+.85))) |
+	((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24;
+
+      if(event.type == SDL_FINGERMOTION)
+	drawCircle(screen,x*screen->w,y*screen->h,5,col);
+      else if(event.type == SDL_FINGERDOWN)
+	drawCircle(screen,x*screen->w,y*screen->h,-10,col);     
+      /*      
+      //if there is a centroid, draw it
+      if(numDownFingers > 1) {
+	unsigned int col = 
+	  ((unsigned int)(0xFFFFFF)) |
+	  ((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24;
+	drawCircle(screen,centroid.x*screen->w,centroid.y*screen->h,5,col);
+      }
+      */
+    }
+  }
+  
+
+  for(i=0;i<MAXFINGERS;i++)
+    if(finger[i].p.x >= 0 && finger[i].p.y >= 0)
+      if(finger[i].pressure > 0)
+	drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h
+		   ,20,0xFF*finger[i].pressure);
+      else
+	drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h
+		   ,20,0xFF);
+
+
+  
+  keystat[32] = 0;
+  
+  if(knob.p.x > 0)
+    drawKnob(screen,knob);
+  
+  if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
+  
+  SDL_Flip(screen);
+}
+
+SDL_Surface* initScreen(int width,int height)
+{
+  return SDL_SetVideoMode(width, height, DEPTH,
+			  SDL_HWSURFACE | SDL_RESIZABLE);
+}
+
+int main(int argc, char* argv[])
+{  
+  SDL_Surface *screen;
+  SDL_Event event;
+  
+  int keypress = 0;
+  int h=0,s=1,i,j;
+
+  //gesture variables
+  int numDownFingers = 0;
+  float gdtheta = 0,gdDist = 0;
+  Point centroid;
+  knob.r = .1;
+  knob.ang = 0;
+  TouchPoint gestureLast[MAXFINGERS];
+  
+
+
+  memset(keystat,0,512*sizeof(keystat[0]));
+  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
+  
+  if (!(screen = initScreen(WIDTH,HEIGHT)))
+    {
+      SDL_Quit();
+      return 1;
+    }
+
+  while(!keystat[27]) {
+    //Poll SDL
+    while(SDL_PollEvent(&event)) 
+      {
+	//Record _all_ events
+	events[eventWrite & (EVENT_BUF_SIZE-1)] = event;
+	eventWrite++;
+	
+	switch (event.type) 
+	  {
+	  case SDL_QUIT:
+	    keystat[27] = 1;
+	    break;
+	  case SDL_KEYDOWN:
+	    //printf("%i\n",event.key.keysym.sym);
+	    keystat[event.key.keysym.sym] = 1;
+	    if(event.key.keysym.sym == 32) {
+	      SDL_RecordGesture(-1);
+	    }
+	    else if(event.key.keysym.sym == 115) {
+	      FILE *fp;
+	      fp = fopen("gestureSave","w");
+	      SDL_SaveAllDollarTemplates(fp);
+	      fclose(fp);
+	    }
+	    else if(event.key.keysym.sym == 108) {
+	      FILE *fp;
+	      fp = fopen("gestureSave","r");
+	      printf("Loaded: %i\n",SDL_LoadDollarTemplates(-1,fp));
+	      fclose(fp);
+	    }
+	    
+	    //keypress = 1;
+	    break;
+	  case SDL_KEYUP:
+	      //printf("%i\n",event.key.keysym.sym);
+	    keystat[event.key.keysym.sym] = 0;
+	    //keypress = 1;
+	    break;
+	  case SDL_VIDEORESIZE:
+	    if (!(screen = initScreen(event.resize.w,
+				      event.resize.h)))
+	      {
+		SDL_Quit();
+		return 1;
+	      }
+	    break;
+	  case SDL_MOUSEMOTION:
+	    mousx = event.motion.x;
+	    mousy = event.motion.y; 
+	    break;
+	  case SDL_MOUSEBUTTONDOWN:
+	    bstatus |=  (1<<(event.button.button-1));
+	    break;
+	  case SDL_MOUSEBUTTONUP:
+	    bstatus &= ~(1<<(event.button.button-1));
+	    break;
+	  case SDL_FINGERMOTION:    
+	    ;
+	    //printf("Finger: %i,x: %i, y: %i\n",event.tfinger.fingerId,
+	    //	   event.tfinger.x,event.tfinger.y);
+	    SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
+	    SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId);
+
+	    for(i = 0;i<MAXFINGERS;i++) 
+	      if(index2fingerid[i] == event.tfinger.fingerId) 	      
+		break;
+	    if(i == MAXFINGERS) break;  
+	    if(inTouch > 0) {
+	      finger[i].p.x = ((float)event.tfinger.x)/
+		inTouch->xres;
+	      finger[i].p.y = ((float)event.tfinger.y)/
+		inTouch->yres;
+	      
+	      finger[i].pressure = 
+		((float)event.tfinger.pressure)/inTouch->pressureres;
+	      /*
+	      printf("Finger: %i, Pressure: %f Pressureres: %i\n",
+		     event.tfinger.fingerId,
+		     finger[i].pressure,
+		     inTouch->pressureres);
+	      */
+	      //printf("Finger: %i, pressure: %f\n",event.tfinger.fingerId,
+	      //   finger[event.tfinger.fingerId].pressure);
+	    }
+	    
+	    break;	    
+	  case SDL_FINGERDOWN:
+	    printf("Finger: %i down - x: %i, y: %i\n",event.tfinger.fingerId,
+		   event.tfinger.x,event.tfinger.y);
+
+	    for(i = 0;i<MAXFINGERS;i++) 
+	      if(index2fingerid[i] == -1) {
+		index2fingerid[i] = event.tfinger.fingerId;
+		break;
+	      }
+	    finger[i].p.x = event.tfinger.x;
+	    finger[i].p.y = event.tfinger.y;
+	    break;
+	  case SDL_FINGERUP:
+	    printf("Figner: %i up - x: %i, y: %i\n",event.tfinger.fingerId,
+	           event.tfinger.x,event.tfinger.y);
+	    for(i = 0;i<MAXFINGERS;i++) 
+	      if(index2fingerid[i] == event.tfinger.fingerId) {
+		index2fingerid[i] = -1;
+		break;
+	      }
+	    finger[i].p.x = -1;
+	    finger[i].p.y = -1;
+	    break;
+	  case SDL_MULTIGESTURE:
+	    knob.p.x = event.mgesture.x;
+	    knob.p.y = event.mgesture.y;
+	    knob.ang += event.mgesture.dTheta;
+	    knob.r += event.mgesture.dDist;
+	    break;
+	  case SDL_DOLLARGESTURE:
+	    printf("Gesture %lu performed, error: %f\n",
+		   event.dgesture.gestureId,
+		   event.dgesture.error);
+	    break;
+	  case SDL_DOLLARRECORD:
+	    printf("Recorded gesture: %lu\n",event.dgesture.gestureId);
+	    break;
+	  }
+      }
+    DrawScreen(screen,h);    
+    for(i = 0; i < 256; i++) 
+      if(keystat[i]) 
+	printf("Key %i down\n",i);
+  }  
+  SDL_Quit();
+  
+  return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/gestureTest.c	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,773 @@
+#include <stdio.h>
+#include <SDL.h>
+#include <math.h>
+#include <SDL_touch.h>
+
+#define PI 3.1415926535897
+#define PHI ((sqrt(5)-1)/2)
+#define WIDTH 640
+#define HEIGHT 480
+#define BPP 4
+#define DEPTH 32
+
+#define MAXFINGERS 3
+
+#define DOLLARNPOINTS 64
+#define DOLLARSIZE 256
+
+//MUST BE A POWER OF 2!
+#define EVENT_BUF_SIZE 256
+
+SDL_Event events[EVENT_BUF_SIZE];
+int eventWrite;
+
+int mousx,mousy;
+int keystat[512];
+int bstatus;
+
+int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
+
+int index2fingerid[MAXFINGERS];
+int fingersDown;
+
+typedef struct {
+  float x,y;
+} Point;
+
+typedef struct {
+  Point p;
+  float pressure;
+  int id;
+} Finger;
+
+typedef struct {
+  Finger f;
+  Point cv;
+  float dtheta,dDist;
+} TouchPoint;
+ 
+typedef struct { //dt + s
+  Point d,s; //direction, start
+  int points;
+} Line;
+
+
+typedef struct {
+  float length;
+  
+  int numPoints;
+  Point p[EVENT_BUF_SIZE]; //To be safe
+} DollarPath;
+
+typedef struct {
+  float ang,r;
+  Point p;
+} Knob;
+
+Knob knob;
+
+Finger finger[MAXFINGERS];
+
+
+DollarPath dollarPath[MAXFINGERS];
+
+#define MAXTEMPLATES 4
+
+Point dollarTemplate[MAXTEMPLATES][DOLLARNPOINTS];
+int numDollarTemplates = 0;
+#ifdef DRAW_VECTOR_EST
+Line gestureLine[MAXFINGERS];
+#endif
+
+void handler (int sig)
+{
+  printf ("\exiting...(%d)\n", sig);
+  exit (0);
+}
+
+void perror_exit (char *error)
+{
+  perror (error);
+  handler (9);
+}
+
+
+void setpix(SDL_Surface *screen, int x, int y, unsigned int col)
+{
+  Uint32 *pixmem32;
+  Uint32 colour;
+  
+  if((unsigned)x > screen->w) return;
+  if((unsigned)y > screen->h) return;
+
+  pixmem32 = (Uint32*) screen->pixels  + y*screen->pitch/BPP + x;
+  
+  Uint8 r,g,b;
+  float a;
+  
+  memcpy(&colour,pixmem32,screen->format->BytesPerPixel);
+
+  SDL_GetRGB(colour,screen->format,&r,&g,&b); //Always returns 0xFFFFFF?
+  //r = 0;g = 0; b = 0;
+  a = (col>>24)&0xFF;
+  if(a == 0) a = 0xFF; //Hack, to make things easier.
+  a /= 0xFF;
+  r = r*(1-a) + ((col>>16)&0xFF)*(a);
+  g = g*(1-a) + ((col>> 8)&0xFF)*(a);
+  b = b*(1-a) + ((col>> 0)&0xFF)*(a);
+  colour = SDL_MapRGB( screen->format,r, g, b);
+  
+
+  *pixmem32 = colour;
+}
+
+void drawLine(SDL_Surface *screen,int x0,int y0,int x1,int y1,unsigned int col) {
+  float t;
+  for(t=0;t<1;t+=1.f/SDL_max(abs(x0-x1),abs(y0-y1)))
+    setpix(screen,x1+t*(x0-x1),y1+t*(y0-y1),col);
+}
+void drawCircle(SDL_Surface* screen,int x,int y,int r,unsigned int c)
+{
+
+  float a;
+  int tx;
+  
+  int ty;
+  float xr;
+  for(ty = -abs(r);ty <= abs(r);ty++) {
+    xr = sqrt(r*r - ty*ty);
+    if(r > 0) { //r > 0 ==> filled circle
+      for(tx=-xr+.5;tx<=xr-.5;tx++) {
+	setpix(screen,x+tx,y+ty,c);
+      }
+    }
+    else {
+      setpix(screen,x-xr+.5,y+ty,c);
+      setpix(screen,x+xr-.5,y+ty,c);
+    }
+  }
+}
+
+void drawKnob(SDL_Surface* screen,Knob k) {
+  printf("Knob: x = %f, y = %f, r = %f, a = %f\n",k.p.x,k.p.y,k.r,k.ang);
+ 
+  drawCircle(screen,k.p.x*screen->w,k.p.y*screen->h,k.r*screen->w,0xFFFFFF);
+  
+  drawCircle(screen,(k.p.x+k.r/2*cos(k.ang))*screen->w,
+  	            (k.p.y+k.r/2*sin(k.ang))*screen->h,k.r/4*screen->w,0);
+  
+}
+
+void drawDollarPath(SDL_Surface* screen,Point* points,int numPoints,
+		    int rad,unsigned int col){
+  int i;
+  for(i=0;i<numPoints;i++) {
+    drawCircle(screen,points[i].x+screen->w/2,
+	       points[i].y+screen->h/2,
+	       rad,col);
+  }
+}
+
+float dollarDifference(Point* points,Point* templ,float ang) {
+  //  Point p[DOLLARNPOINTS];
+  float dist = 0;
+  Point p;
+  int i;
+  for(i = 0; i < DOLLARNPOINTS; i++) {
+    p.x = points[i].x * cos(ang) - points[i].y * sin(ang);
+    p.y = points[i].x * sin(ang) + points[i].y * cos(ang);
+    dist += sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
+		 (p.y-templ[i].y)*(p.y-templ[i].y));
+  }
+  return dist/DOLLARNPOINTS;
+  
+}
+
+float bestDollarDifference(Point* points,Point* templ) {
+  //------------BEGIN DOLLAR BLACKBOX----------------//
+  //-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-//
+  //-"http://depts.washington.edu/aimgroup/proj/dollar/"-//
+  float ta = -PI/4;
+  float tb = PI/4;
+  float dt = PI/90;
+  float x1 = PHI*ta + (1-PHI)*tb;
+  float f1 = dollarDifference(points,templ,x1);
+  float x2 = (1-PHI)*ta + PHI*tb;
+  float f2 = dollarDifference(points,templ,x2);
+  while(abs(ta-tb) > dt) {
+    if(f1 < f2) {
+      tb = x2;
+      x2 = x1;
+      f2 = f1;
+      x1 = PHI*ta + (1-PHI)*tb;
+      f1 = dollarDifference(points,templ,x1);
+    }
+    else {
+      ta = x1;
+      x1 = x2;
+      f1 = f2;
+      x2 = (1-PHI)*ta + PHI*tb;
+      f2 = dollarDifference(points,templ,x2);
+    }
+  }
+  /*
+  if(f1 <= f2)
+    printf("Min angle (x1): %f\n",x1);
+  else if(f1 >  f2)
+    printf("Min angle (x2): %f\n",x2);
+  */
+  return SDL_min(f1,f2);  
+}
+
+float dollarRecognize(SDL_Surface* screen, DollarPath path,int *bestTempl) {
+
+  Point points[DOLLARNPOINTS];
+  int numPoints = dollarNormalize(path,points);
+  int i;
+  
+  int k;
+  /*
+  for(k = 0;k<DOLLARNPOINTS;k++) {
+    printf("(%f,%f)\n",points[k].x,
+	   points[k].y);
+  }
+  */
+  drawDollarPath(screen,points,numPoints,-15,0xFF6600);
+
+  int bestDiff = 10000;
+  *bestTempl = -1;
+  for(i = 0;i < numDollarTemplates;i++) {
+    int diff = bestDollarDifference(points,dollarTemplate[i]);
+    if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
+  }
+  return bestDiff;
+}
+
+//DollarPath contains raw points, plus (possibly) the calculated length
+int dollarNormalize(DollarPath path,Point *points) {
+  int i;
+  //Calculate length if it hasn't already been done
+  if(path.length <= 0) {
+    for(i=1;i<path.numPoints;i++) {
+      float dx = path.p[i  ].x - 
+	         path.p[i-1].x;
+      float dy = path.p[i  ].y - 
+	         path.p[i-1].y;
+      path.length += sqrt(dx*dx+dy*dy);
+    }
+  }
+
+
+  //Resample
+  float interval = path.length/(DOLLARNPOINTS - 1);
+  float dist = 0;
+
+  int numPoints = 0;
+  Point centroid; centroid.x = 0;centroid.y = 0;
+  //printf("(%f,%f)\n",path.p[path.numPoints-1].x,path.p[path.numPoints-1].y);
+  for(i = 1;i < path.numPoints;i++) {
+    float d = sqrt((path.p[i-1].x-path.p[i].x)*(path.p[i-1].x-path.p[i].x)+
+		   (path.p[i-1].y-path.p[i].y)*(path.p[i-1].y-path.p[i].y));
+    //printf("d = %f dist = %f/%f\n",d,dist,interval);
+    while(dist + d > interval) {
+      points[numPoints].x = path.p[i-1].x + 
+	((interval-dist)/d)*(path.p[i].x-path.p[i-1].x);
+      points[numPoints].y = path.p[i-1].y + 
+	((interval-dist)/d)*(path.p[i].y-path.p[i-1].y);
+      centroid.x += points[numPoints].x;
+      centroid.y += points[numPoints].y;
+      numPoints++;
+
+      dist -= interval;
+    }
+    dist += d;
+  }
+  if(numPoints < 1) return 0;
+  centroid.x /= numPoints;
+  centroid.y /= numPoints;
+ 
+  //printf("Centroid (%f,%f)",centroid.x,centroid.y);
+  //Rotate Points so point 0 is left of centroid and solve for the bounding box
+  float xmin,xmax,ymin,ymax;
+  xmin = centroid.x;
+  xmax = centroid.x;
+  ymin = centroid.y;
+  ymax = centroid.y;
+  
+  float ang = atan2(centroid.y - points[0].y,
+		    centroid.x - points[0].x);
+
+  for(i = 0;i<numPoints;i++) {					       
+    float px = points[i].x;
+    float py = points[i].y;
+    points[i].x = (px - centroid.x)*cos(ang) - 
+                  (py - centroid.y)*sin(ang) + centroid.x;
+    points[i].y = (px - centroid.x)*sin(ang) + 
+                  (py - centroid.y)*cos(ang) + centroid.y;
+
+
+    if(points[i].x < xmin) xmin = points[i].x;
+    if(points[i].x > xmax) xmax = points[i].x; 
+    if(points[i].y < ymin) ymin = points[i].y;
+    if(points[i].y > ymax) ymax = points[i].y;
+  }
+
+  //Scale points to DOLLARSIZE, and translate to the origin
+  float w = xmax-xmin;
+  float h = ymax-ymin;
+
+  for(i=0;i<numPoints;i++) {
+    points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
+    points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h;
+  }  
+  return numPoints;
+}
+
+void DrawScreen(SDL_Surface* screen, int h)
+{
+  int x, y, xm,ym,c;
+  if(SDL_MUSTLOCK(screen))
+    {                                              
+      if(SDL_LockSurface(screen) < 0) return;
+    }
+  for(y = 0; y < screen->h; y++ )
+    {
+      for( x = 0; x < screen->w; x++ )
+        {
+	  //setpixel(screen, x, y, (x*x)/256+3*y+h, (y*y)/256+x+h, h);
+	  //xm = (x+h)%screen->w;
+	  //ym = (y+h)%screen->w;
+	  //c = sin(h/256*2*PI)*x*y/screen->w/screen->h;
+	  //setpix(screen,x,y,255*sin(xm/screen->w*2*PI),sin(h/255*2*PI)*255*y/screen->h,c);
+	  setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
+	  //setpix(screen,x,y,0); //Inefficient, but that's okay...
+        }
+    }
+  drawCircle(screen,mousx,mousy,-30,0xFFFFFF);
+  drawLine(screen,0,0,screen->w,screen->h,0xFFFFFF);
+
+  int i;
+//draw Touch History
+  TouchPoint gestureLast[MAXFINGERS];
+  //printf("------------------Start History------------------\n");
+  for(i = 0;i < MAXFINGERS;i++) {
+    gestureLast[i].f.id = -1;
+  }
+  int numDownFingers = 0;
+  Point centroid;
+  float gdtheta,gdDist;
+
+
+  for(i = SDL_max(0,eventWrite - EVENT_BUF_SIZE);i < eventWrite;i++) {
+    SDL_Event event = events[i&(EVENT_BUF_SIZE-1)];
+    int age = eventWrite - i - 1;
+    if(event.type == SDL_FINGERMOTION || 
+       event.type == SDL_FINGERDOWN ||
+       event.type == SDL_FINGERUP) {
+      SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
+      //SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId);
+	    
+      float x = ((float)event.tfinger.x)/inTouch->xres;
+      float y = ((float)event.tfinger.y)/inTouch->yres;
+      int j,empty = -1;
+      
+      for(j = 0;j<MAXFINGERS;j++) {
+	if(gestureLast[j].f.id == event.tfinger.fingerId) {
+	  if(event.type == SDL_FINGERUP) {
+	    numDownFingers--;
+	    if(numDownFingers <= 1) {
+	      gdtheta = 0;
+	      gdDist = 0;
+	    }
+	    if(!keystat[32]){ //spacebar
+	      int bestTempl;
+	      float error = dollarRecognize(screen,dollarPath[j],&bestTempl);
+	      if(bestTempl >= 0){
+		drawDollarPath(screen,dollarTemplate[bestTempl]
+			       ,DOLLARNPOINTS,-15,0x0066FF);		
+		printf("Dollar error: %f\n",error);
+	      }
+	      
+	    }
+	    else if(numDollarTemplates < MAXTEMPLATES) {
+	      
+	      dollarNormalize(dollarPath[j],
+			      dollarTemplate[numDollarTemplates]);
+	      /*
+	      int k;	      
+	      for(k = 0;k<DOLLARNPOINTS;k++) {
+		printf("(%f,%f)\n",dollarTemplate[numDollarTemplates][i].x,
+		       dollarTemplate[numDollarTemplates][i].y);
+		       }*/
+	      numDollarTemplates++;	      
+	    }
+
+	    gestureLast[j].f.id = -1;
+	    break;
+	  }
+	  else {
+	    dollarPath[j].p[dollarPath[j].numPoints].x = x;
+	    dollarPath[j].p[dollarPath[j].numPoints].y = y;
+	    float dx = (dollarPath[j].p[dollarPath[j].numPoints  ].x-
+			dollarPath[j].p[dollarPath[j].numPoints-1].x);
+	    float dy = (dollarPath[j].p[dollarPath[j].numPoints  ].y-
+			dollarPath[j].p[dollarPath[j].numPoints-1].y);
+	    dollarPath[j].length += sqrt(dx*dx + dy*dy);
+
+	    dollarPath[j].numPoints++;
+
+	    centroid.x = centroid.x + dx/numDownFingers;
+	    centroid.y = centroid.y + dy/numDownFingers;    
+	    if(numDownFingers > 1) {
+	      Point lv; //Vector from centroid to last x,y position
+	      Point v; //Vector from centroid to current x,y position
+	      lv.x = gestureLast[j].cv.x;
+	      lv.y = gestureLast[j].cv.y;
+	      float lDist = sqrt(lv.x*lv.x + lv.y*lv.y);
+	      
+	      v.x = x - centroid.x;
+	      v.y = y - centroid.y;
+	      gestureLast[j].cv = v;
+	      float Dist = sqrt(v.x*v.x+v.y*v.y);
+	      // cos(dTheta) = (v . lv)/(|v| * |lv|)
+	      
+	      lv.x/=lDist;
+	      lv.y/=lDist;
+	      v.x/=Dist;
+	      v.y/=Dist;
+	      float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
+	      
+	      float dDist = (lDist - Dist);	      
+	      
+	      gestureLast[j].dDist = dDist;
+	      gestureLast[j].dtheta = dtheta;
+
+	      //gdtheta = gdtheta*.9 + dtheta*.1;
+	      //gdDist  =  gdDist*.9 +  dDist*.1
+	      gdtheta += dtheta;
+	      gdDist += dDist;
+
+	      //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
+	      //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
+	    }
+	    else {
+	      gestureLast[j].dDist = 0;
+	      gestureLast[j].dtheta = 0;
+	      gestureLast[j].cv.x = 0;
+	      gestureLast[j].cv.y = 0;
+	    }
+	    gestureLast[j].f.p.x = x;
+	    gestureLast[j].f.p.y = y;
+	    break;
+	    //pressure?
+	  }	  
+	}
+	else if(gestureLast[j].f.id == -1 && empty == -1) {
+	  empty = j;
+	}
+      }
+      
+      if(j >= MAXFINGERS && empty >= 0) {
+	//	printf("Finger Down!!!\n");
+	numDownFingers++;
+	centroid.x = (centroid.x*(numDownFingers - 1) + x)/numDownFingers;
+	centroid.y = (centroid.y*(numDownFingers - 1) + y)/numDownFingers;
+	
+	j = empty;
+	gestureLast[j].f.id = event.tfinger.fingerId;
+	gestureLast[j].f.p.x  = x;
+	gestureLast[j].f.p.y  = y;
+	
+	
+	dollarPath[j].length = 0;
+	dollarPath[j].p[0].x = x;
+	dollarPath[j].p[0].y = y;
+	dollarPath[j].numPoints = 1;
+      }
+      
+      //draw the touch:
+      
+      if(gestureLast[j].f.id < 0) continue; //Finger up. Or some error...
+      
+      unsigned int c = colors[gestureLast[j].f.id%7]; 
+      unsigned int col = 
+	((unsigned int)(c*(.1+.85))) |
+	((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24;
+      x = gestureLast[j].f.p.x;
+      y = gestureLast[j].f.p.y;
+      if(event.type == SDL_FINGERMOTION)
+	drawCircle(screen,x*screen->w,y*screen->h,5,col);
+      else if(event.type == SDL_FINGERDOWN)
+	drawCircle(screen,x*screen->w,y*screen->h,-10,col);     
+      
+      //if there is a centroid, draw it
+      if(numDownFingers > 1) {
+	unsigned int col = 
+	  ((unsigned int)(0xFFFFFF)) |
+	  ((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24;
+	drawCircle(screen,centroid.x*screen->w,centroid.y*screen->h,5,col);
+      }
+    }
+  }
+  
+
+  for(i=0;i<MAXFINGERS;i++)
+    if(finger[i].p.x >= 0 && finger[i].p.y >= 0)
+      if(finger[i].pressure > 0)
+	drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h
+		   ,20,0xFF*finger[i].pressure);
+      else
+	drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h
+		   ,20,0xFF);
+
+
+  
+  keystat[32] = 0;
+  
+  if(knob.p.x > 0)
+    drawKnob(screen,knob);
+  
+  if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
+  
+  SDL_Flip(screen);
+}
+
+SDL_Surface* initScreen(int width,int height)
+{
+  return SDL_SetVideoMode(width, height, DEPTH,
+			  SDL_HWSURFACE | SDL_RESIZABLE);
+}
+
+int main(int argc, char* argv[])
+{  
+  SDL_Surface *screen;
+  SDL_Event event;
+  
+  int keypress = 0;
+  int h=0,s=1,i,j;
+
+  //gesture variables
+  int numDownFingers = 0;
+  float gdtheta = 0,gdDist = 0;
+  Point centroid;
+  knob.r = .1;
+  knob.ang = 0;
+  TouchPoint gestureLast[MAXFINGERS];
+  for(i = 0;i < MAXFINGERS;i++)
+    gestureLast[i].f.id = -1;
+
+
+  memset(keystat,0,512*sizeof(keystat[0]));
+  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
+  
+  if (!(screen = initScreen(WIDTH,HEIGHT)))
+    {
+      SDL_Quit();
+      return 1;
+    }
+
+  while(!keystat[27]) {
+    //Poll SDL
+    while(SDL_PollEvent(&event)) 
+      {
+	//Record _all_ events
+	events[eventWrite & (EVENT_BUF_SIZE-1)] = event;
+	eventWrite++;
+	
+	switch (event.type) 
+	  {
+	  case SDL_QUIT:
+	    keystat[27] = 1;
+	    break;
+	  case SDL_KEYDOWN:
+	    //printf("%i\n",event.key.keysym.sym);
+	    keystat[event.key.keysym.sym] = 1;
+	    //keypress = 1;
+	    break;
+	  case SDL_KEYUP:
+	      //printf("%i\n",event.key.keysym.sym);
+	    keystat[event.key.keysym.sym] = 0;
+	    //keypress = 1;
+	    break;
+	  case SDL_VIDEORESIZE:
+	    if (!(screen = initScreen(event.resize.w,
+				      event.resize.h)))
+	      {
+		SDL_Quit();
+		return 1;
+	      }
+	    break;
+	  case SDL_MOUSEMOTION:
+	    mousx = event.motion.x;
+	    mousy = event.motion.y; 
+	    break;
+	  case SDL_MOUSEBUTTONDOWN:
+	    bstatus |=  (1<<(event.button.button-1));
+	    break;
+	  case SDL_MOUSEBUTTONUP:
+	    bstatus &= ~(1<<(event.button.button-1));
+	    break;
+	  case SDL_FINGERMOTION:    
+	    ;
+	    //printf("Finger: %i,x: %i, y: %i\n",event.tfinger.fingerId,
+	    //	   event.tfinger.x,event.tfinger.y);
+	    SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
+	    SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId);
+
+	    for(i = 0;i<MAXFINGERS;i++) 
+	      if(index2fingerid[i] == event.tfinger.fingerId) 	      
+		break;
+	    if(i == MAXFINGERS) break;  
+	    if(inTouch > 0) {
+	      finger[i].p.x = ((float)event.tfinger.x)/
+		inTouch->xres;
+	      finger[i].p.y = ((float)event.tfinger.y)/
+		inTouch->yres;
+	      
+	      finger[i].pressure = 
+		((float)event.tfinger.pressure)/inTouch->pressureres;
+	      /*
+	      printf("Finger: %i, Pressure: %f Pressureres: %i\n",
+		     event.tfinger.fingerId,
+		     finger[i].pressure,
+		     inTouch->pressureres);
+	      */
+	      //printf("Finger: %i, pressure: %f\n",event.tfinger.fingerId,
+	      //   finger[event.tfinger.fingerId].pressure);
+	    }
+	    
+	    break;	    
+	  case SDL_FINGERDOWN:
+	    printf("Finger: %i down - x: %i, y: %i\n",event.tfinger.fingerId,
+		   event.tfinger.x,event.tfinger.y);
+
+	    for(i = 0;i<MAXFINGERS;i++) 
+	      if(index2fingerid[i] == -1) {
+		index2fingerid[i] = event.tfinger.fingerId;
+		break;
+	      }
+	    finger[i].p.x = event.tfinger.x;
+	    finger[i].p.y = event.tfinger.y;
+	    break;
+	  case SDL_FINGERUP:
+	    printf("Figner: %i up - x: %i, y: %i\n",event.tfinger.fingerId,
+	           event.tfinger.x,event.tfinger.y);
+	    for(i = 0;i<MAXFINGERS;i++) 
+	      if(index2fingerid[i] == event.tfinger.fingerId) {
+		index2fingerid[i] = -1;
+		break;
+	      }
+	    finger[i].p.x = -1;
+	    finger[i].p.y = -1;
+	    break;
+	  }
+      
+    
+	if(event.type == SDL_FINGERMOTION || 
+	   event.type == SDL_FINGERDOWN ||
+	   event.type == SDL_FINGERUP) {
+	  SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
+	  //SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId);
+	  
+	  float x = ((float)event.tfinger.x)/inTouch->xres;
+	  float y = ((float)event.tfinger.y)/inTouch->yres;
+	  int j,empty = -1;
+	  
+	  for(j = 0;j<MAXFINGERS;j++) {
+	    if(gestureLast[j].f.id == event.tfinger.fingerId) {
+	      if(event.type == SDL_FINGERUP) {
+		numDownFingers--;
+		if(numDownFingers <= 1) {
+		  gdtheta = 0;
+		  gdDist = 0;
+		}
+		gestureLast[j].f.id = -1;
+		break;
+	      }
+	      else {	    
+		float dx = x - gestureLast[j].f.p.x;
+		float dy = y - gestureLast[j].f.p.y;
+		centroid.x = centroid.x + dx/numDownFingers;
+		centroid.y = centroid.y + dy/numDownFingers;    
+		if(numDownFingers > 1) {
+		  Point lv; //Vector from centroid to last x,y position
+		  Point v; //Vector from centroid to current x,y position
+		  lv = gestureLast[j].cv;
+		  float lDist = sqrt(lv.x*lv.x + lv.y*lv.y);
+		  printf("lDist = %f\n",lDist);
+		  v.x = x - centroid.x;
+		  v.y = y - centroid.y;
+		  gestureLast[j].cv = v;
+		  float Dist = sqrt(v.x*v.x+v.y*v.y);
+		  // cos(dTheta) = (v . lv)/(|v| * |lv|)
+		  
+		  lv.x/=lDist;
+		  lv.y/=lDist;
+		  v.x/=Dist;
+		  v.y/=Dist;
+		  float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
+		  
+		  float dDist = (Dist - lDist);	      
+		  if(lDist == 0) {dDist = 0;dtheta = 0;}
+		  gestureLast[j].dDist = dDist;
+		  gestureLast[j].dtheta = dtheta;
+		  
+		  printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
+		  //gdtheta = gdtheta*.9 + dtheta*.1;
+		  //gdDist  =  gdDist*.9 +  dDist*.1
+		  knob.r += dDist/numDownFingers;
+		  knob.ang += dtheta;
+		  //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
+		  //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
+		}
+		else {
+		  gestureLast[j].dDist = 0;
+		  gestureLast[j].dtheta = 0;
+		  gestureLast[j].cv.x = 0;
+		  gestureLast[j].cv.y = 0;
+		}
+		gestureLast[j].f.p.x = x;
+		gestureLast[j].f.p.y = y;
+		break;
+		//pressure?
+	      }	  
+	    }
+	    else if(gestureLast[j].f.id == -1 && empty == -1) {
+	      empty = j;
+	    }
+	  }
+	  
+	  if(j >= MAXFINGERS && empty >= 0) {
+	    printf("Finger Down!!!\n");
+	    numDownFingers++;
+	    centroid.x = (centroid.x*(numDownFingers - 1) + x)/numDownFingers;
+	    centroid.y = (centroid.y*(numDownFingers - 1) + y)/numDownFingers;
+	    
+	    j = empty;
+	    gestureLast[j].f.id = event.tfinger.fingerId;
+	    gestureLast[j].f.p.x  = x;
+	    gestureLast[j].f.p.y  = y;	
+	    gestureLast[j].cv.x = 0;
+	    gestureLast[j].cv.y = 0;
+	  }
+	  
+	  //draw the touch:
+	}
+	//And draw
+	if(numDownFingers > 1)
+	  knob.p = centroid;
+	else
+	  knob.p.x = -1;
+      }
+    DrawScreen(screen,h);
+    //printf("c: (%f,%f)\n",centroid.x,centroid.y);
+    //printf("numDownFingers: %i\n",numDownFingers);
+    //for(i=0;i<512;i++) 
+    // if(keystat[i]) printf("%i\n",i);
+    
+    
+  }  
+  SDL_Quit();
+  
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/makefile	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,9 @@
+SDLTest : touchSimp.c touchPong.c
+	gcc gestureSDLTest.c -o gestureSDLTest `sdl-config --cflags --libs` -g
+	gcc gestureTest.c -o gestureTest `sdl-config --cflags --libs` -g
+	gcc touchTest.c -o touchTest `sdl-config --cflags --libs` -g		
+	gcc touchSimp.c -o touchSimp `sdl-config --cflags --libs` -g
+	gcc touchPong.c -o touchPong `sdl-config --cflags --libs` -g
+	gcc parseDevicesTest.c -o parseDevicesTest -g
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/makefile~	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,3 @@
+SDLTest : touchSimp.c touchPong.c
+	gcc touchSimp.c -o touchSimp `sdl-config --cflags --libs` -gSDLTest : 
+	gcc touchPong.c -o touchPong `sdl-config --cflags --libs` -g
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/parseDevicesTest.c	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/input.h>
+#include <fcntl.h>
+
+
+int main(int agrc,char **argv)
+{
+  FILE *fd;
+  fd = fopen("/proc/bus/input/devices","r");
+  
+  char c;
+  int i = 0;
+  char line[256];
+  char tstr[256];
+  int vendor = -1,product = -1,event = -1;
+  while(!feof(fd)) {
+    fgets(line,256,fd);
+    //printf("%s",line);
+    if(line[0] == '\n') {
+      if(vendor == 1386){
+	printf("Wacom... Assuming it is a touch device\n");
+	sprintf(tstr,"/dev/input/event%i",event);
+	printf("At location: %s\n",tstr);
+		
+	int inFile = open(tstr,O_RDONLY);
+	
+	unsigned long bits[4];
+	int abs[5];
+	ioctl(inFile,EVIOCGABS(ABS_X),abs);	
+	int minx,maxx,miny,maxy,minp,maxp;
+	minx = abs[1];
+	maxx = abs[2];
+	ioctl(inFile,EVIOCGABS(ABS_Y),abs);	
+	miny = abs[1];
+	maxy = abs[2];
+	ioctl(inFile,EVIOCGABS(ABS_PRESSURE),abs);	
+	minp = abs[1];
+	maxp = abs[2];
+	
+
+	close(inFile);
+      }
+      vendor = -1;
+      product = -1;
+      event = -1;      
+    }
+    else if(line[0] == 'I') {
+      i = 1;
+      while(line[i]) {
+	sscanf(&line[i],"Vendor=%x",&vendor);
+	sscanf(&line[i],"Product=%x",&product);
+	i++;
+      }
+    }
+    else if(line[0] == 'H') {
+      i = 1;
+      while(line[i]) {
+	sscanf(&line[i],"event%d",&event);
+	i++;
+      }
+    }
+  }
+  
+  close(fd);
+  return 0;
+}
Binary file touchTest/testIn has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/testIn.c	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <termios.h>
+#include <signal.h>
+
+void handler (int sig)
+{
+  printf ("\nexiting...(%d)\n", sig);
+  exit (0);
+}
+
+void perror_exit (char *error)
+{
+  perror (error);
+  handler (9);
+}
+
+int main (int argc, char *argv[])
+{
+  struct input_event ev[64];
+  int fd, rd, value, size = sizeof (struct input_event);
+  char name[256] = "Unknown";
+  char *device = NULL;
+
+  //Setup check
+  if (argv[1] == NULL){
+      printf("Please specify (on the command line) the path to the dev event interface device\n");
+      exit (0);
+    }
+
+  if ((getuid ()) != 0)
+    printf ("You are not root! This may not work...\n");
+
+  if (argc > 1)
+    device = argv[1];
+
+  //Open Device
+  if ((fd = open (device, O_RDONLY)) == -1)
+    printf ("%s is not a vaild device.\n", device);
+
+  //Print Device Name
+  ioctl (fd, EVIOCGNAME (sizeof (name)), name);
+  printf ("Reading From : %s (%s)\n", device, name);
+
+  while (1){
+      
+    if ((rd = read (fd, ev, size * 64)) < size)
+      perror_exit ("read()");          
+    printf("time: %i\n type: %X\n code: %X\n value: %i\n ",ev[0].time,ev[0].type,ev[0].value,ev[0].value);
+
+      value = ev[0].value;
+
+      if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){ // Only read the key press event
+	   printf ("Code[%d]\n", (ev[1].code));
+      }
+  }
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/testIn.c~	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <termios.h>
+#include <signal.h>
+
+void handler (int sig)
+{
+  printf ("\nexiting...(%d)\n", sig);
+  exit (0);
+}
+
+void perror_exit (char *error)
+{
+  perror (error);
+  handler (9);
+}
+
+int main (int argc, char *argv[])
+{
+  struct input_event ev[64];
+  int fd, rd, value, size = sizeof (struct input_event);
+  char name[256] = "Unknown";
+  char *device = NULL;
+
+  //Setup check
+  if (argv[1] == NULL){
+      printf("Please specify (on the command line) the path to the dev event interface device\n");
+      exit (0);
+    }
+
+  if ((getuid ()) != 0)
+    printf ("You are not root! This may not work...\n");
+
+  if (argc > 1)
+    device = argv[1];
+
+  //Open Device
+  if ((fd = open (device, O_RDONLY)) == -1)
+    printf ("%s is not a vaild device.\n", device);
+
+  //Print Device Name
+  ioctl (fd, EVIOCGNAME (sizeof (name)), name);
+  printf ("Reading From : %s (%s)\n", device, name);
+
+  while (1){
+      
+    if ((rd = read (fd, ev, size * 64)) < size)
+      perror_exit ("read()");          
+    printf("time: %i\n type: %X\n code: %X\n value: %i\n ",ev[0].time,ev[0].type,ev[0].value,ev[0].value);
+
+      value = ev[0].value;
+
+      if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){ // Only read the key press event
+	   printf ("Code[%d]\n", (ev[1].code));
+      }
+  }
+
+  return 0;
+}
Binary file touchTest/touchPong has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/touchPong.c	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,272 @@
+#include <stdio.h>
+#include <SDL.h>
+#include <math.h>
+#include <linux/input.h>
+#include <fcntl.h>
+
+
+#define PI 3.1415926535897
+#define WIDTH 640
+#define HEIGHT 480
+#define BPP 4
+#define DEPTH 32
+
+
+#define MAX_FINGERS 2
+
+int mousx,mousy;
+int keystat[512];
+int bstatus;
+
+
+
+typedef struct {
+  int x,y;
+} Point;
+
+Point finger[MAX_FINGERS];
+
+//Pong Code
+Point ball,ballv;
+
+
+void handler (int sig)
+{
+  printf ("\nexiting...(%d)\n", sig);
+  exit (0);
+}
+
+void perror_exit (char *error)
+{
+  perror (error);
+  handler (9);
+}
+
+
+void setpix(SDL_Surface *screen, int x, int y, int col)
+{
+  Uint32 *pixmem32;
+  Uint32 colour;
+  
+  if((unsigned)x > screen->w) return;
+  if((unsigned)y > screen->h) return;
+
+  colour = SDL_MapRGB( screen->format, (col>>16)&0xFF, (col>>8)&0xFF, col&0xFF);
+  
+  pixmem32 = (Uint32*) screen->pixels  + y*screen->pitch/BPP + x;
+  *pixmem32 = colour;
+}
+
+void drawCircle(SDL_Surface* screen,int x,int y,int r,int c)
+{
+
+  float a;
+  for(a=0;a<2*PI;a+=1.f/(float)r)
+  {
+    setpix(screen,(int)(x+r*cos(a)),(int)(y+r*sin(a)),c);
+  }
+}
+
+void DrawScreen(SDL_Surface* screen, int h)
+{
+  int x, y, xm,ym,c;
+  if(SDL_MUSTLOCK(screen))
+    {                                              
+      if(SDL_LockSurface(screen) < 0) return;
+    }
+  for(y = 0; y < screen->h; y++ )
+    {
+      for( x = 0; x < screen->w; x++ )
+        {
+	  //setpixel(screen, x, y, (x*x)/256+3*y+h, (y*y)/256+x+h, h);
+	  //xm = (x+h)%screen->w;
+	  //ym = (y+h)%screen->w;
+	  //c = sin(h/256*2*PI)*x*y/screen->w/screen->h;
+	  //setpix(screen,x,y,255*sin(xm/screen->w*2*PI),sin(h/255*2*PI)*255*y/screen->h,c);
+	  setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
+        }
+    }
+  drawCircle(screen,mousx,mousy,30,0xFFFFFF);
+  int i;
+  for(i=0;i<MAX_FINGERS;i++)
+    drawCircle(screen,finger[i].x,finger[i].y,30,0xFFFFFF);
+  
+  drawCircle(screen,ball.x,ball.y,30,0xFF00FF);
+
+  if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
+  
+  SDL_Flip(screen);
+}
+
+SDL_Surface* initScreen(int width,int height)
+{
+  return SDL_SetVideoMode(width, height, DEPTH,
+			  SDL_HWSURFACE | SDL_RESIZABLE);
+}
+
+int main(int argc, char* argv[])
+{
+  struct input_event ev[64];
+  int fd, rd, value, size = sizeof (struct input_event);
+  char name[256] = "Unknown";
+  char *device = NULL;
+
+  
+  
+  //Setup check
+  if (argv[1] == NULL){
+    printf("Please specify (on the command line) the path to the dev event interface device\n");
+    exit (0);
+  }
+  
+  if ((getuid ()) != 0)
+    printf ("You are not root! This may not work...\n");
+  
+  if (argc > 1)
+    device = argv[1];
+  
+  //Open Device
+  if ((fd = open (device, O_RDONLY)) == -1)
+    printf ("%s is not a vaild device.\n", device);
+  
+  //Print Device Name
+  ioctl (fd, EVIOCGNAME (sizeof (name)), name);
+  printf ("Reading From : %s (%s)\n", device, name);
+  
+  
+  
+  
+  
+  SDL_Surface *screen;
+  SDL_Event event;
+  
+  int keypress = 0;
+  int h=0,s=1,i,j;
+  int tx,ty,curf=0;
+
+
+
+  memset(keystat,0,512*sizeof(keystat[0]));
+  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
+  
+  if (!(screen = initScreen(WIDTH,HEIGHT)))
+    {
+      SDL_Quit();
+      return 1;
+    }
+  ball.x = screen->w/2;
+  ball.y = screen->h/2;
+  ballv.x = -3;
+  ballv.y = 1;
+  while(!keystat[27]) 
+    {
+      //Poll SDL
+      while(SDL_PollEvent(&event)) 
+	{
+	  switch (event.type) 
+	    {
+	    case SDL_QUIT:
+	      keystat[27] = 1;
+	      break;
+	    case SDL_KEYDOWN:
+	      //printf("%i\n",event.key.keysym.sym);
+	      keystat[event.key.keysym.sym] = 1;
+	      //keypress = 1;
+	      break;
+	    case SDL_KEYUP:
+	      //printf("%i\n",event.key.keysym.sym);
+	      keystat[event.key.keysym.sym] = 0;
+	      //keypress = 1;
+	      break;
+	    case SDL_VIDEORESIZE:
+	      if (!(screen = initScreen(event.resize.w,
+					event.resize.h)))
+	      {
+		SDL_Quit();
+		return 1;
+	      }
+	      break;
+	    case SDL_MOUSEMOTION:
+	      mousx = event.motion.x;
+	      mousy = event.motion.y; 
+	      break;
+	    case SDL_MOUSEBUTTONDOWN:
+	      bstatus |=  (1<<(event.button.button-1));
+	      break;
+	    case SDL_MOUSEBUTTONUP:
+	      bstatus &= ~(1<<(event.button.button-1));
+	      break;
+	    }
+	}
+
+      //poll for Touch <- Goal: make this a case:      
+      if ((rd = read (fd, ev, size * 64)) < size)
+	perror_exit ("read()");          
+      //printf("time: %i\n type: %X\n code: %X\n value: %i\n ",
+      //     ev->time,ev->type,ev->code,ev->value);
+      for (i = 0; i < rd / sizeof(struct input_event); i++)
+	switch (ev[i].type)	
+	  {
+	  case EV_ABS:
+	    if(ev[i].code == ABS_X)
+	      tx = ev[i].value;
+	    else if (ev[i].code == ABS_Y)
+	      ty = ev[i].value;
+	    else if (ev[i].code == ABS_MISC)
+	      {	     
+		//printf("Misc:type: %X\n     code: %X\n     value: %i\n ",
+		//      ev[i].type,ev[i].code,ev[i].value);
+	      }
+	    break;
+	  case EV_MSC:
+	    if(ev[i].code == MSC_SERIAL)
+	      curf = ev[i].value;
+	    break;
+	  case EV_SYN:
+	    curf -= 1;
+	    if(tx >= 0)
+	      finger[curf].x = tx;
+	    if(ty >= 0)
+	      finger[curf].y = ty;
+
+	    //printf("Synched: %i tx: %i, ty: %i\n",curf,finger[curf].x,finger[curf].y);
+	    tx = -1;
+	    ty = -1;
+	    break;    
+
+	}
+
+      //Pong code
+      ball.x += ballv.x;
+      ball.y += ballv.y;
+      for(i=0;i<MAX_FINGERS;i++)
+	{
+
+	  if(finger[i].x > 0 || finger[i].y > 0)
+	    {
+	      int d2 = (finger[i].x-ball.x)*(finger[i].x-ball.x) + 
+		(finger[i].y-ball.y)*(finger[i].y-ball.y);
+	      ballv.x += (50*(ball.x-finger[i].x))/d2;
+	      ballv.y += (30*(ball.y-finger[i].y))/d2;
+	    }
+	}
+      if((unsigned int)ball.x > screen->w){
+	ball.x = screen->w/2;
+	ball.y = screen->h/2;
+	ballv.x = -3;
+	ballv.y = 1;
+      }
+      if((unsigned int)ball.y > screen->h) ballv.y *= -1;
+      printf("(%i,%i)\n",ball.x,ball.y);
+      //And draw
+      DrawScreen(screen,h);
+      /*
+      for(i=0;i<512;i++) 
+	if(keystat[i]) printf("%i\n",i);
+      printf("Buttons:%i\n",bstatus);
+      */
+    }  
+  SDL_Quit();
+  
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/touchPong.c~	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,243 @@
+#include <stdio.h>
+#include <SDL.h>
+#include <math.h>
+#include <linux/input.h>
+#include <fcntl.h>
+
+
+#define PI 3.1415926535897
+#define WIDTH 640
+#define HEIGHT 480
+#define BPP 4
+#define DEPTH 32
+
+
+#define MAX_FINGERS 2
+
+int mousx,mousy;
+int keystat[512];
+int bstatus;
+
+
+//Pong Code
+Point ball,ballv;
+
+typedef struct {
+  int x,y;
+} Point;
+
+Point finger[MAX_FINGERS];
+
+void handler (int sig)
+{
+  printf ("\nexiting...(%d)\n", sig);
+  exit (0);
+}
+
+void perror_exit (char *error)
+{
+  perror (error);
+  handler (9);
+}
+
+
+void setpix(SDL_Surface *screen, int x, int y, int col)
+{
+  Uint32 *pixmem32;
+  Uint32 colour;
+  
+  if((unsigned)x > screen->w) return;
+  if((unsigned)y > screen->h) return;
+
+  colour = SDL_MapRGB( screen->format, (col>>16)&0xFF, (col>>8)&0xFF, col&0xFF);
+  
+  pixmem32 = (Uint32*) screen->pixels  + y*screen->pitch/BPP + x;
+  *pixmem32 = colour;
+}
+
+void drawCircle(SDL_Surface* screen,int x,int y,int r,int c)
+{
+
+  float a;
+  for(a=0;a<2*PI;a+=1.f/(float)r)
+  {
+    setpix(screen,(int)(x+r*cos(a)),(int)(y+r*sin(a)),c);
+  }
+}
+
+void DrawScreen(SDL_Surface* screen, int h)
+{
+  int x, y, xm,ym,c;
+  if(SDL_MUSTLOCK(screen))
+    {                                              
+      if(SDL_LockSurface(screen) < 0) return;
+    }
+  for(y = 0; y < screen->h; y++ )
+    {
+      for( x = 0; x < screen->w; x++ )
+        {
+	  //setpixel(screen, x, y, (x*x)/256+3*y+h, (y*y)/256+x+h, h);
+	  //xm = (x+h)%screen->w;
+	  //ym = (y+h)%screen->w;
+	  //c = sin(h/256*2*PI)*x*y/screen->w/screen->h;
+	  //setpix(screen,x,y,255*sin(xm/screen->w*2*PI),sin(h/255*2*PI)*255*y/screen->h,c);
+	  setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
+        }
+    }
+  drawCircle(screen,mousx,mousy,30,0xFFFFFF);
+  int i;
+  for(i=0;i<MAX_FINGERS;i++)
+    drawCircle(screen,finger[i].x,finger[i].y,30,0xFFFFFF);
+  
+  if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
+  
+  SDL_Flip(screen);
+}
+
+SDL_Surface* initScreen(int width,int height)
+{
+  return SDL_SetVideoMode(width, height, DEPTH,
+			  SDL_HWSURFACE | SDL_RESIZABLE);
+}
+
+int main(int argc, char* argv[])
+{
+  struct input_event ev[64];
+  int fd, rd, value, size = sizeof (struct input_event);
+  char name[256] = "Unknown";
+  char *device = NULL;
+
+  
+  
+  //Setup check
+  if (argv[1] == NULL){
+    printf("Please specify (on the command line) the path to the dev event interface device\n");
+    exit (0);
+  }
+  
+  if ((getuid ()) != 0)
+    printf ("You are not root! This may not work...\n");
+  
+  if (argc > 1)
+    device = argv[1];
+  
+  //Open Device
+  if ((fd = open (device, O_RDONLY)) == -1)
+    printf ("%s is not a vaild device.\n", device);
+  
+  //Print Device Name
+  ioctl (fd, EVIOCGNAME (sizeof (name)), name);
+  printf ("Reading From : %s (%s)\n", device, name);
+  
+  
+  
+  
+  
+  SDL_Surface *screen;
+  SDL_Event event;
+  
+  int keypress = 0;
+  int h=0,s=1,i,j;
+  int tx,ty,curf=0;
+
+
+
+  memset(keystat,0,512*sizeof(keystat[0]));
+  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
+  
+  if (!(screen = initScreen(WIDTH,HEIGHT)))
+    {
+      SDL_Quit();
+      return 1;
+    }
+  ball.x = screen->width()/2;
+  ball.y = screen->height()/2;
+  while(!keystat[27]) 
+    {
+      //Poll SDL
+      while(SDL_PollEvent(&event)) 
+	{
+	  switch (event.type) 
+	    {
+	    case SDL_QUIT:
+	      keystat[27] = 1;
+	      break;
+	    case SDL_KEYDOWN:
+	      //printf("%i\n",event.key.keysym.sym);
+	      keystat[event.key.keysym.sym] = 1;
+	      //keypress = 1;
+	      break;
+	    case SDL_KEYUP:
+	      //printf("%i\n",event.key.keysym.sym);
+	      keystat[event.key.keysym.sym] = 0;
+	      //keypress = 1;
+	      break;
+	    case SDL_VIDEORESIZE:
+	      if (!(screen = initScreen(event.resize.w,
+					event.resize.h)))
+	      {
+		SDL_Quit();
+		return 1;
+	      }
+	      break;
+	    case SDL_MOUSEMOTION:
+	      mousx = event.motion.x;
+	      mousy = event.motion.y; 
+	      break;
+	    case SDL_MOUSEBUTTONDOWN:
+	      bstatus |=  (1<<(event.button.button-1));
+	      break;
+	    case SDL_MOUSEBUTTONUP:
+	      bstatus &= ~(1<<(event.button.button-1));
+	      break;
+	    }
+	}
+
+      //poll for Touch <- Goal: make this a case:      
+      if ((rd = read (fd, ev, size * 64)) < size)
+	perror_exit ("read()");          
+      //printf("time: %i\n type: %X\n code: %X\n value: %i\n ",
+      //     ev->time,ev->type,ev->code,ev->value);
+      for (i = 0; i < rd / sizeof(struct input_event); i++)
+	switch (ev[i].type)	
+	  {
+	  case EV_ABS:
+	    if(ev[i].code == ABS_X)
+	      tx = ev[i].value;
+	    else if (ev[i].code == ABS_Y)
+	      ty = ev[i].value;
+	    else if (ev[i].code == ABS_MISC)
+	      {	     
+		//printf("Misc:type: %X\n     code: %X\n     value: %i\n ",
+		//      ev[i].type,ev[i].code,ev[i].value);
+	      }
+	    break;
+	  case EV_MSC:
+	    if(ev[i].code == MSC_SERIAL)
+	      curf = ev[i].value;
+	    break;
+	  case EV_SYN:
+	    curf -= 1;
+	    if(tx >= 0)
+	      finger[curf].x = tx;
+	    if(ty >= 0)
+	      finger[curf].y = ty;
+
+	    //printf("Synched: %i tx: %i, ty: %i\n",curf,finger[curf].x,finger[curf].y);
+	    tx = -1;
+	    ty = -1;
+	    break;    
+
+	}
+      //And draw
+      DrawScreen(screen,h);
+      /*
+      for(i=0;i<512;i++) 
+	if(keystat[i]) printf("%i\n",i);
+      printf("Buttons:%i\n",bstatus);
+      */
+    }  
+  SDL_Quit();
+  
+  return 0;
+}
Binary file touchTest/touchSimp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/touchSimp.c	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,246 @@
+#include <stdio.h>
+#include <SDL.h>
+#include <math.h>
+#include <linux/input.h>
+#include <fcntl.h>
+
+
+#define PI 3.1415926535897
+#define WIDTH 640
+#define HEIGHT 480
+#define BPP 4
+#define DEPTH 32
+
+
+#define MAX_FINGERS 2
+
+int mousx,mousy;
+int keystat[512];
+int bstatus;
+
+
+
+
+typedef struct {
+  int x,y;
+} Point;
+
+Point finger[MAX_FINGERS];
+
+void handler (int sig)
+{
+  printf ("\nexiting...(%d)\n", sig);
+  exit (0);
+}
+
+void perror_exit (char *error)
+{
+  perror (error);
+  handler (9);
+}
+
+
+void setpix(SDL_Surface *screen, int x, int y, int col)
+{
+  Uint32 *pixmem32;
+  Uint32 colour;
+  
+  if((unsigned)x > screen->w) return;
+  if((unsigned)y > screen->h) return;
+
+  colour = SDL_MapRGB( screen->format, (col>>16)&0xFF, (col>>8)&0xFF, col&0xFF);
+  
+  pixmem32 = (Uint32*) screen->pixels  + y*screen->pitch/BPP + x;
+  *pixmem32 = colour;
+}
+
+void drawCircle(SDL_Surface* screen,int x,int y,int r,int c)
+{
+
+  float a;
+  for(a=0;a<2*PI;a+=1.f/(float)r)
+  {
+    setpix(screen,(int)(x+r*cos(a)),(int)(y+r*sin(a)),c);
+  }
+}
+
+void DrawScreen(SDL_Surface* screen, int h)
+{
+  int x, y, xm,ym,c;
+  if(SDL_MUSTLOCK(screen))
+    {                                              
+      if(SDL_LockSurface(screen) < 0) return;
+    }
+  for(y = 0; y < screen->h; y++ )
+    {
+      for( x = 0; x < screen->w; x++ )
+        {
+	  //setpixel(screen, x, y, (x*x)/256+3*y+h, (y*y)/256+x+h, h);
+	  //xm = (x+h)%screen->w;
+	  //ym = (y+h)%screen->w;
+	  //c = sin(h/256*2*PI)*x*y/screen->w/screen->h;
+	  //setpix(screen,x,y,255*sin(xm/screen->w*2*PI),sin(h/255*2*PI)*255*y/screen->h,c);
+	  setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
+        }
+    }
+  drawCircle(screen,mousx,mousy,30,0xFFFFFF);
+  int i;
+  for(i=0;i<MAX_FINGERS;i++)
+    drawCircle(screen,finger[i].x,finger[i].y,30,0xFFFFFF);
+  
+  if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
+  
+  SDL_Flip(screen);
+}
+
+SDL_Surface* initScreen(int width,int height)
+{
+  return SDL_SetVideoMode(width, height, DEPTH,
+			  SDL_HWSURFACE | SDL_RESIZABLE);
+}
+
+int main(int argc, char* argv[])
+{
+  struct input_event ev[64];
+  int fd, rd, value, size = sizeof (struct input_event);
+  char name[256] = "Unknown";
+  char *device = NULL;
+
+  
+  
+  //Setup check
+  if (argv[1] == NULL){
+    printf("Please specify (on the command line) the path to the dev event interface device\n");
+    exit (0);
+  }
+  
+  if ((getuid ()) != 0)
+    printf ("You are not root! This may not work...\n");
+  
+  if (argc > 1)
+    device = argv[1];
+  
+  //Open Device
+  if ((fd = open (device, O_RDONLY | O_NONBLOCK)) == -1)
+    printf ("%s is not a vaild device.\n", device);
+  
+  //Print Device Name
+  ioctl (fd, EVIOCGNAME (sizeof (name)), name);
+  printf ("Reading From : %s (%s)\n", device, name);
+  
+  
+  
+  
+  
+  SDL_Surface *screen;
+  SDL_Event event;
+  
+  int keypress = 0;
+  int h=0,s=1,i,j;
+  int tx,ty,curf=0;
+
+  memset(keystat,0,512*sizeof(keystat[0]));
+  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
+  
+  if (!(screen = initScreen(WIDTH,HEIGHT)))
+    {
+      SDL_Quit();
+      return 1;
+    }
+
+  while(!keystat[27]) 
+    {
+      //Poll SDL
+      while(SDL_PollEvent(&event)) 
+	{
+	  switch (event.type) 
+	    {
+	    case SDL_QUIT:
+	      keystat[27] = 1;
+	      break;
+	    case SDL_KEYDOWN:
+	      //printf("%i\n",event.key.keysym.sym);
+	      keystat[event.key.keysym.sym] = 1;
+	      //keypress = 1;
+	      break;
+	    case SDL_KEYUP:
+	      //printf("%i\n",event.key.keysym.sym);
+	      keystat[event.key.keysym.sym] = 0;
+	      //keypress = 1;
+	      break;
+	    case SDL_VIDEORESIZE:
+	      if (!(screen = initScreen(event.resize.w,
+					event.resize.h)))
+	      {
+		SDL_Quit();
+		return 1;
+	      }
+	      break;
+	    case SDL_MOUSEMOTION:
+	      mousx = event.motion.x;
+	      mousy = event.motion.y; 
+	      break;
+	    case SDL_MOUSEBUTTONDOWN:
+	      bstatus |=  (1<<(event.button.button-1));
+	      break;
+	    case SDL_MOUSEBUTTONUP:
+	      bstatus &= ~(1<<(event.button.button-1));
+	      break;
+	    case SDL_FINGERMOTION:
+	      printf("Holy SH!T\n");
+	      break;
+		     
+	    }
+	}
+
+      //poll for Touch <- Goal: make this a case:      
+      
+
+      /*if ((rd = read (fd, ev, size * 64)) < size)
+	perror_exit ("read()");          */
+      //printf("time: %i\n type: %X\n code: %X\n value: %i\n ",
+      //     ev->time,ev->type,ev->code,ev->value);
+      if((rd = read (fd, ev, size * 64)) >= size)
+	 for (i = 0; i < rd / sizeof(struct input_event); i++)
+	   switch (ev[i].type)	
+	     {
+	     case EV_ABS:
+	       if(ev[i].code == ABS_X)
+		 tx = ev[i].value;
+	       else if (ev[i].code == ABS_Y)
+		 ty = ev[i].value;
+	       else if (ev[i].code == ABS_MISC)
+		 {	     
+		   //printf("Misc:type: %X\n     code: %X\n     value: %i\n ",
+		   //      ev[i].type,ev[i].code,ev[i].value);
+		 }
+	       break;
+	     case EV_MSC:
+	       if(ev[i].code == MSC_SERIAL)
+		 curf = ev[i].value;
+	       break;
+	     case EV_SYN:
+	       curf -= 1;
+	       if(tx >= 0)
+		 finger[curf].x = tx;
+	       if(ty >= 0)
+		 finger[curf].y = ty;
+	       
+	       //printf("Synched: %i tx: %i, ty: %i\n",curf,finger[curf].x,finger[curf].y);
+	       tx = -1;
+	       ty = -1;
+	       break;    
+	       
+	     }
+	 //And draw
+     DrawScreen(screen,h);
+	 /*
+	   for(i=0;i<512;i++) 
+	   if(keystat[i]) printf("%i\n",i);
+	   printf("Buttons:%i\n",bstatus);
+	 */
+     }  
+     SDL_Quit();
+      
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/touchSimp.c~	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,241 @@
+#include <stdio.h>
+#include <SDL.h>
+#include <math.h>
+#include <linux/input.h>
+#include <fcntl.h>
+
+
+#define PI 3.1415926535897
+#define WIDTH 640
+#define HEIGHT 480
+#define BPP 4
+#define DEPTH 32
+
+
+#define MAX_FINGERS 2
+
+int mousx,mousy;
+int keystat[512];
+int bstatus;
+
+
+
+typedef struct {
+  int x,y;
+} Point;
+
+Point finger[MAX_FINGERS];
+
+void handler (int sig)
+{
+  printf ("\nexiting...(%d)\n", sig);
+  exit (0);
+}
+
+void perror_exit (char *error)
+{
+  perror (error);
+  handler (9);
+}
+
+
+void setpix(SDL_Surface *screen, int x, int y, int col)
+{
+  Uint32 *pixmem32;
+  Uint32 colour;
+  
+  if((unsigned)x > screen->w) return;
+  if((unsigned)y > screen->h) return;
+
+  colour = SDL_MapRGB( screen->format, (col>>16)&0xFF, (col>>8)&0xFF, col&0xFF);
+  
+  pixmem32 = (Uint32*) screen->pixels  + y*screen->pitch/BPP + x;
+  *pixmem32 = colour;
+}
+
+void drawCircle(SDL_Surface* screen,int x,int y,int r,int c)
+{
+
+  float a;
+  for(a=0;a<2*PI;a+=1.f/(float)r)
+  {
+    setpix(screen,(int)(x+r*cos(a)),(int)(y+r*sin(a)),c);
+  }
+}
+
+void DrawScreen(SDL_Surface* screen, int h)
+{
+  int x, y, xm,ym,c;
+  if(SDL_MUSTLOCK(screen))
+    {                                              
+      if(SDL_LockSurface(screen) < 0) return;
+    }
+  for(y = 0; y < screen->h; y++ )
+    {
+      for( x = 0; x < screen->w; x++ )
+        {
+	  //setpixel(screen, x, y, (x*x)/256+3*y+h, (y*y)/256+x+h, h);
+	  //xm = (x+h)%screen->w;
+	  //ym = (y+h)%screen->w;
+	  //c = sin(h/256*2*PI)*x*y/screen->w/screen->h;
+	  //setpix(screen,x,y,255*sin(xm/screen->w*2*PI),sin(h/255*2*PI)*255*y/screen->h,c);
+	  setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
+        }
+    }
+  drawCircle(screen,mousx,mousy,30,0xFFFFFF);
+  int i;
+  for(i=0;i<MAX_FINGERS;i++)
+    drawCircle(screen,finger[i].x,finger[i].y,30,0xFFFFFF);
+  
+  if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
+  
+  SDL_Flip(screen);
+}
+
+SDL_Surface* initScreen(int width,int height)
+{
+  return SDL_SetVideoMode(width, height, DEPTH,
+			  SDL_HWSURFACE | SDL_RESIZABLE);
+}
+
+int main(int argc, char* argv[])
+{
+  struct input_event ev[64];
+  int fd, rd, value, size = sizeof (struct input_event);
+  char name[256] = "Unknown";
+  char *device = NULL;
+
+  
+  
+  //Setup check
+  if (argv[1] == NULL){
+    printf("Please specify (on the command line) the path to the dev event interface device\n");
+    exit (0);
+  }
+  
+  if ((getuid ()) != 0)
+    printf ("You are not root! This may not work...\n");
+  
+  if (argc > 1)
+    device = argv[1];
+  
+  //Open Device
+  if ((fd = open (device, O_RDONLY)) == -1)
+    printf ("%s is not a vaild device.\n", device);
+  
+  //Print Device Name
+  ioctl (fd, EVIOCGNAME (sizeof (name)), name);
+  printf ("Reading From : %s (%s)\n", device, name);
+  
+  
+  
+  
+  
+  SDL_Surface *screen;
+  SDL_Event event;
+  
+  int keypress = 0;
+  int h=0,s=1,i,j;
+  int tx,ty,curf=0;
+
+  Point ball,ballv;
+
+  memset(keystat,0,512*sizeof(keystat[0]));
+  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
+  
+  if (!(screen = initScreen(WIDTH,HEIGHT)))
+    {
+      SDL_Quit();
+      return 1;
+    }
+  ball.x = screen->width()/2;
+  ball.y = screen->height()/2;
+  while(!keystat[27]) 
+    {
+      //Poll SDL
+      while(SDL_PollEvent(&event)) 
+	{
+	  switch (event.type) 
+	    {
+	    case SDL_QUIT:
+	      keystat[27] = 1;
+	      break;
+	    case SDL_KEYDOWN:
+	      //printf("%i\n",event.key.keysym.sym);
+	      keystat[event.key.keysym.sym] = 1;
+	      //keypress = 1;
+	      break;
+	    case SDL_KEYUP:
+	      //printf("%i\n",event.key.keysym.sym);
+	      keystat[event.key.keysym.sym] = 0;
+	      //keypress = 1;
+	      break;
+	    case SDL_VIDEORESIZE:
+	      if (!(screen = initScreen(event.resize.w,
+					event.resize.h)))
+	      {
+		SDL_Quit();
+		return 1;
+	      }
+	      break;
+	    case SDL_MOUSEMOTION:
+	      mousx = event.motion.x;
+	      mousy = event.motion.y; 
+	      break;
+	    case SDL_MOUSEBUTTONDOWN:
+	      bstatus |=  (1<<(event.button.button-1));
+	      break;
+	    case SDL_MOUSEBUTTONUP:
+	      bstatus &= ~(1<<(event.button.button-1));
+	      break;
+	    }
+	}
+
+      //poll for Touch <- Goal: make this a case:      
+      if ((rd = read (fd, ev, size * 64)) < size)
+	perror_exit ("read()");          
+      //printf("time: %i\n type: %X\n code: %X\n value: %i\n ",
+      //     ev->time,ev->type,ev->code,ev->value);
+      for (i = 0; i < rd / sizeof(struct input_event); i++)
+	switch (ev[i].type)	
+	  {
+	  case EV_ABS:
+	    if(ev[i].code == ABS_X)
+	      tx = ev[i].value;
+	    else if (ev[i].code == ABS_Y)
+	      ty = ev[i].value;
+	    else if (ev[i].code == ABS_MISC)
+	      {	     
+		//printf("Misc:type: %X\n     code: %X\n     value: %i\n ",
+		//      ev[i].type,ev[i].code,ev[i].value);
+	      }
+	    break;
+	  case EV_MSC:
+	    if(ev[i].code == MSC_SERIAL)
+	      curf = ev[i].value;
+	    break;
+	  case EV_SYN:
+	    curf -= 1;
+	    if(tx >= 0)
+	      finger[curf].x = tx;
+	    if(ty >= 0)
+	      finger[curf].y = ty;
+
+	    //printf("Synched: %i tx: %i, ty: %i\n",curf,finger[curf].x,finger[curf].y);
+	    tx = -1;
+	    ty = -1;
+	    break;    
+
+	}
+      //And draw
+      DrawScreen(screen,h);
+      /*
+      for(i=0;i<512;i++) 
+	if(keystat[i]) printf("%i\n",i);
+      printf("Buttons:%i\n",bstatus);
+      */
+    }  
+  SDL_Quit();
+  
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/touchTest.c	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,232 @@
+#include <stdio.h>
+#include <SDL.h>
+#include <math.h>
+#include <SDL_touch.h>
+
+
+
+#define PI 3.1415926535897
+#define WIDTH 640
+#define HEIGHT 480
+#define BPP 4
+#define DEPTH 32
+
+#define MAXFINGERS 3
+
+int mousx,mousy;
+int keystat[512];
+int bstatus;
+
+
+
+
+typedef struct {
+  float x,y;
+} Point;
+
+typedef struct {
+  Point p;
+  float pressure;
+} Finger;
+
+
+Finger finger[MAXFINGERS];
+
+void handler (int sig)
+{
+  printf ("exiting...(%d)\n", sig);
+  exit (0);
+}
+
+void perror_exit (char *error)
+{
+  perror (error);
+  handler (9);
+}
+
+
+void setpix(SDL_Surface *screen, int x, int y, int col)
+{
+  Uint32 *pixmem32;
+  Uint32 colour;
+  
+  if((unsigned)x > screen->w) return;
+  if((unsigned)y > screen->h) return;
+
+  colour = SDL_MapRGB( screen->format, (col>>16)&0xFF, (col>>8)&0xFF, col&0xFF);
+  
+  pixmem32 = (Uint32*) screen->pixels  + y*screen->pitch/screen->format->BytesPerPixel + x; //TODO : Check this. May cause crash.
+  *pixmem32 = colour;
+}
+
+void drawCircle(SDL_Surface* screen,int x,int y,int r,int c)
+{
+
+  float a;
+  int tx;
+  for(a=0;a<PI/2;a+=1.f/(float)abs(r))
+  {
+    if(r > 0) { //r<0 ==> unfilled circle
+      for(tx=x-r*cos(a);tx<x+r*cos(a);tx++) {
+	setpix(screen,tx,(int)(y+r*sin(a)),c);
+	setpix(screen,tx,(int)(y-r*sin(a)),c);
+      }
+    }
+    
+    //Always Draw Outline
+    setpix(screen,(int)(x+r*cos(a)),(int)(y+r*sin(a)),c);
+    setpix(screen,(int)(x-r*cos(a)),(int)(y+r*sin(a)),c);
+    setpix(screen,(int)(x+r*cos(a)),(int)(y-r*sin(a)),c);
+    setpix(screen,(int)(x-r*cos(a)),(int)(y-r*sin(a)),c);
+  }
+}
+
+void DrawScreen(SDL_Surface* screen, int h)
+{
+  int x, y, xm,ym,c,i;
+  if(SDL_MUSTLOCK(screen))
+    {                                              
+      if(SDL_LockSurface(screen) < 0) return;
+    }
+  for(y = 0; y < screen->h; y++ )
+    {
+      for( x = 0; x < screen->w; x++ )
+        {
+	  //setpixel(screen, x, y, (x*x)/256+3*y+h, (y*y)/256+x+h, h);
+	  //xm = (x+h)%screen->w;
+	  //ym = (y+h)%screen->w;
+	  //c = sin(h/256*2*PI)*x*y/screen->w/screen->h;
+	  //setpix(screen,x,y,255*sin(xm/screen->w*2*PI),sin(h/255*2*PI)*255*y/screen->h,c);
+	  setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
+        }
+    }
+
+  drawCircle(screen,mousx,mousy,-30,0xFFFFFF);
+  
+  
+  for(i=0;i<MAXFINGERS;i++)
+    if(finger[i].p.x >= 0 && finger[i].p.y >= 0)
+      if(finger[i].pressure > 0)
+	drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h
+		   ,20,0xFF*finger[i].pressure);
+      else
+	drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h
+		   ,20,0xFF);
+  
+  if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
+  
+  SDL_Flip(screen);
+}
+
+SDL_Surface* initScreen(int width,int height)
+{
+  return SDL_SetVideoMode(width, height, DEPTH,
+			  SDL_HWSURFACE | SDL_RESIZABLE);
+}
+
+int main(int argc, char* argv[])
+{  
+  SDL_Surface *screen;
+  SDL_Event event;
+  
+  int keypress = 0;
+  int h=0,s=1,i,j;
+
+  memset(keystat,0,512*sizeof(keystat[0]));
+  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
+  screen = initScreen(WIDTH,HEIGHT);
+  if (!screen)
+    {
+      SDL_Quit();
+      return 1;
+    }
+
+  while(!keystat[27]) {
+    //Poll SDL
+    while(SDL_PollEvent(&event)) 
+      {
+	switch (event.type) 
+	  {
+	  case SDL_QUIT:
+	    keystat[27] = 1;
+	    break;
+	  case SDL_KEYDOWN:
+	    //printf("%i\n",event.key.keysym.sym);
+	    keystat[event.key.keysym.sym] = 1;
+	    //keypress = 1;
+	    break;
+	  case SDL_KEYUP:
+	      //printf("%i\n",event.key.keysym.sym);
+	    keystat[event.key.keysym.sym] = 0;
+	    //keypress = 1;
+	    break;
+	  case SDL_VIDEORESIZE:
+	    if (!(screen = initScreen(event.resize.w,
+				      event.resize.h)))
+	      {
+		SDL_Quit();
+		return 1;
+	      }
+	    break;
+	  case SDL_MOUSEMOTION:
+	    mousx = event.motion.x;
+	    mousy = event.motion.y; 
+	    break;
+	  case SDL_MOUSEBUTTONDOWN:
+	    bstatus |=  (1<<(event.button.button-1));
+	    break;
+	  case SDL_MOUSEBUTTONUP:
+	    bstatus &= ~(1<<(event.button.button-1));
+	    break;
+	  case SDL_FINGERMOTION:    
+	    ;
+	    //printf("Finger: %i,x: %i, y: %i\n",event.tfinger.fingerId,
+	    //	   event.tfinger.x,event.tfinger.y);
+	    //SDL_Touch *inTouch = SDL_GetTouch(event.tfinger.touchId);
+	    //SDL_Finger *inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId);
+	    /*
+	    finger[event.tfinger.fingerId].p.x = ((float)event.tfinger.x)/
+	      inTouch->xres;
+	    finger[event.tfinger.fingerId].p.y = ((float)event.tfinger.y)/
+	      inTouch->yres;
+
+	    finger[event.tfinger.fingerId].pressure = 
+	      ((float)event.tfinger.pressure)/inTouch->pressureres;*/
+		/*
+	    printf("Finger: %i, Pressure: %f Pressureres: %i\n",
+		   event.tfinger.fingerId,
+		   finger[event.tfinger.fingerId].pressure,
+		   inTouch->pressureres);
+		   */
+	    //printf("Finger: %i, pressure: %f\n",event.tfinger.fingerId,
+	    //   finger[event.tfinger.fingerId].pressure);
+
+	    
+	    break;	    
+	  case SDL_FINGERDOWN:
+	    printf("Figner: %i down - x: %i, y: %i\n",event.tfinger.fingerId,
+		   event.tfinger.x,event.tfinger.y);
+	    finger[event.tfinger.fingerId].p.x = event.tfinger.x;
+	    finger[event.tfinger.fingerId].p.y = event.tfinger.y;
+	    break;
+	  case SDL_FINGERUP:
+	    printf("Figner: %i up - x: %i, y: %i\n",event.tfinger.fingerId,
+		   event.tfinger.x,event.tfinger.y);
+	    finger[event.tfinger.fingerId].p.x = -1;
+	    finger[event.tfinger.fingerId].p.y = -1;
+	    break;
+	  }
+      }
+    //And draw
+    DrawScreen(screen,h);
+	printf("Things\n");
+    /*
+      for(i=0;i<512;i++) 
+      if(keystat[i]) printf("%i\n",i);
+      printf("Buttons:%i\n",bstatus);
+    */
+  }  
+  SDL_Quit();
+      
+  return 0;
+}
Binary file touchTest/touchTest2/touchTest2.ncb has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/touchTest2/touchTest2.sln	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "touchTest2", "touchTest2\touchTest2.vcproj", "{42BC83F1-CF20-4CEC-AC81-12EA804639E2}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{42BC83F1-CF20-4CEC-AC81-12EA804639E2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{42BC83F1-CF20-4CEC-AC81-12EA804639E2}.Debug|Win32.Build.0 = Debug|Win32
+		{42BC83F1-CF20-4CEC-AC81-12EA804639E2}.Release|Win32.ActiveCfg = Release|Win32
+		{42BC83F1-CF20-4CEC-AC81-12EA804639E2}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Binary file touchTest/touchTest2/touchTest2.suo has changed
Binary file touchTest/touchTest2/touchTest2/SDL.dll has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/touchTest2/touchTest2/touchTest2.vcproj	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="touchTest2"
+	ProjectGUID="{42BC83F1-CF20-4CEC-AC81-12EA804639E2}"
+	RootNamespace="touchTest2"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="C:\programs\gsoc10\VisualC\SDL\Debug\SDL.lib&#x0D;&#x0A;C:\programs\gsoc10\VisualC\SDLmain\Debug\SDLmain.lib&#x0D;&#x0A;msvcrt.lib&#x0D;&#x0A;"
+				IgnoreAllDefaultLibraries="true"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				GenerateDebugInformation="true"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\..\touchTest.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+			<File
+				RelativePath=".\SDL.dll"
+				>
+			</File>
+			<File
+				RelativePath=".\wmmsg.txt"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touchTest/touchTest2/touchTest2/touchTest2.vcproj.jgran-virtualPC.jgran.user	Mon Jul 12 21:09:23 2010 -0700
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="9.00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory=""
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="JGRAN-VIRTUALPC"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor=""
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory=""
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="JGRAN-VIRTUALPC"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor=""
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>