Merged Jim's Google Summer of Code work from SDL-gsoc2010_gesture
authorSam Lantinga <slouken@libsdl.org>
Sun, 22 Aug 2010 12:07:55 -0700
changeset 4694c24ba2cc9583
parent 4638 08d22c54a21f
parent 4693 2ede56a19f2f
child 4729 1f7ad083fd3c
Merged Jim's Google Summer of Code work from SDL-gsoc2010_gesture
configure.in
include/SDL_events.h
src/video/cocoa/SDL_cocoakeyboard.m
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/x11/SDL_x11events.c
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
     1.1 --- a/.hgignore	Sun Aug 22 11:56:07 2010 -0700
     1.2 +++ b/.hgignore	Sun Aug 22 12:07:55 2010 -0700
     1.3 @@ -90,5 +90,6 @@
     1.4  test/testatomic
     1.5  test/testspriteminimal
     1.6  test/testfill
     1.7 +test/testgesture
     1.8  test/*.exe
     1.9  test/*.dSYM
     2.1 --- a/Makefile.in	Sun Aug 22 11:56:07 2010 -0700
     2.2 +++ b/Makefile.in	Sun Aug 22 12:07:55 2010 -0700
     2.3 @@ -44,7 +44,7 @@
     2.4  
     2.5  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
     2.6  
     2.7 -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
     2.8 +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
     2.9  
    2.10  LT_AGE      = @LT_AGE@
    2.11  LT_CURRENT  = @LT_CURRENT@
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/README.gesture	Sun Aug 22 12:07:55 2010 -0700
     3.3 @@ -0,0 +1,72 @@
     3.4 +===========================================================================
     3.5 +Dollar Gestures
     3.6 +===========================================================================
     3.7 +SDL Provides an implementation of the $1 gesture recognition system. This allows for recording, saving, loading, and performing single stroke gestures.
     3.8 +
     3.9 +Gestures can be performed with any number of fingers (the centroid of the fingers must follow the path of the gesture), but the number of fingers must be constant (a finger cannot go down in the middle of a gesture). The path of a gesture is considered the path from the time when the final finger went down, to the first time any finger comes up. 
    3.10 +
    3.11 +Dollar gestures are assigned an Id based on a hash function. This is guaranteed to remain constant for a given gesture. There is a (small) chance that two different gestures will be assigned the same ID. In this case, simply re-recording one of the gestures should result in a different ID.
    3.12 +
    3.13 +Recording:
    3.14 +----------
    3.15 +To begin recording on a touch device call:
    3.16 +SDL_RecordGesture(SDL_TouchID touchId), where touchId is the id of the touch device you wish to record on, or -1 to record on all connected devices.
    3.17 +
    3.18 +Recording terminates as soon as a finger comes up. Recording is acknowledged by an SDL_DOLLARRECORD event.
    3.19 +A SDL_DOLLARRECORD event is a dgesture with the following fields:
    3.20 +
    3.21 +event.dgesture.touchId   - the Id of the touch used to record the gesture.
    3.22 +event.dgesture.gestureId - the unique id of the recoreded gesture.
    3.23 +
    3.24 +
    3.25 +Performing:
    3.26 +-----------
    3.27 +As long as there is a dollar gesture assigned to a touch, every finger-up event will also cause an SDL_DOLLARGESTURE event with the following fields:
    3.28 +
    3.29 +event.dgesture.touchId    - the Id of the touch which performed the gesture.
    3.30 +event.dgesture.gestureId  - the unique id of the closest gesture to the performed stroke.
    3.31 +event.dgesture.error      - the difference between the gesture template and the actual performed gesture. Lower error is a better match.
    3.32 +event.dgesture.numFingers - the number of fingers used to draw the stroke.
    3.33 +
    3.34 +Most programs will want to define an appropriate error threshold and check to be sure taht the error of a gesture is not abnormally high (an indicator that no gesture was performed). 
    3.35 +
    3.36 +
    3.37 +
    3.38 +Saving:
    3.39 +-------
    3.40 +To save a template, call SDL_SaveDollarTemplate(gestureId, src) where gestureId is the id of the gesture you want to save, and src is an SDL_RWops pointer to the file where the gesture will be stored.
    3.41 +
    3.42 +To save all currently loaded templates, call SDL_SaveAllDollarTemplates(src) where source is an SDL_RWops pointer to the file where the gesture will be stored.
    3.43 +
    3.44 +Both functions return the number of gestures sucessfully saved.
    3.45 +
    3.46 +
    3.47 +Loading:
    3.48 +--------
    3.49 +To load templates from a file, call SDL_LoadDollarTemplates(touchId,src) where touchId is the id of the touch to load to (or -1 to load to all touch devices), and src is an SDL_RWops pointer to a gesture save file. 
    3.50 +
    3.51 +SDL_LoadDollarTemplates returns the number of templates sucessfully loaded. 
    3.52 +
    3.53 +
    3.54 +
    3.55 +===========================================================================
    3.56 +Multi Gestures
    3.57 +===========================================================================
    3.58 +SDL provides simple support for pinch/rotate/swipe gestures. 
    3.59 +Every time a finger is moved an SDL_MULTIGESTURE event is sent with the following fields:
    3.60 +
    3.61 +event.mgesture.touchId - the Id of the touch on which the gesture was performed.
    3.62 +event.mgesture.x       - the normalized x cooridinate of the gesture. (0..1)
    3.63 +event.mgesture.y       - the normalized y cooridinate of the gesture. (0..1)
    3.64 +event.mgesture.dTheta  - the amount that the fingers rotated during this motion.
    3.65 +event.mgesture.dDist   - the amount that the fingers pinched during this motion.
    3.66 +event.mgesture.numFingers - the number of fingers used in the gesture.
    3.67 +
    3.68 +
    3.69 +===========================================================================
    3.70 +Notes
    3.71 +===========================================================================
    3.72 +For a complete example see test/testgesture.c
    3.73 +
    3.74 +Please direct questions/comments to:
    3.75 +   jim.tla+sdl_touch@gmail.com
     4.1 --- a/README.iphoneos	Sun Aug 22 11:56:07 2010 -0700
     4.2 +++ b/README.iphoneos	Sun Aug 22 12:07:55 2010 -0700
     4.3 @@ -34,14 +34,6 @@
     4.4  5.  Delete the contents of main.m and program your app as a regular SDL program instead.  You may replace main.m with your own main.c, but you must tell XCode not to use the project prefix file, as it includes Objective-C code.
     4.5  
     4.6  ==============================================================================
     4.7 -Notes -- Touch Input
     4.8 -==============================================================================
     4.9 -
    4.10 -Touch input in SDL for iPhone OS is presently exposed through SDL's mouse input API.  Multi-touch input is reported as multiple mice, with each touch associated with a specific mouse.  This association stays coherent from the time the touch starts to the time a touch ends.
    4.11 -
    4.12 -By default, multi-touch is turned ON.  This requires some care, because if you simply respond to mouse events without checking which mouse caused the event, you may end up fetching data from the wrong mouse, ie, from an incorrect or invalid touch.  To turn multi-touch OFF, you can recompile SDL for iPhone with the macro SDL_IPHONE_MULTIPLE_MICE (found in SDL_config_iphoneos.h) set to 0.
    4.13 -
    4.14 -==============================================================================
    4.15  Notes -- Accelerometer as Joystick
    4.16  ==============================================================================
    4.17  
    4.18 @@ -55,7 +47,7 @@
    4.19  
    4.20  Your SDL application for iPhone uses OpenGL ES for video by default.
    4.21  
    4.22 -OpenGL ES for iPhone supports two display pixel formats, RGBA8 and RGB565, which provide a 32 bit and 16 bit color buffer respectively.  By default, the implementation uses RGB565, but you may use RGBA8 by setting each color component to 8 bits in SDL_GL_SetAttribute.
    4.23 +OpenGL ES for iPhone supports several display pixel formats, such as RGBA8 and RGB565, which provide a 32 bit and 16 bit color buffer respectively.  By default, the implementation uses RGB565, but you may use RGBA8 by setting each color component to 8 bits in SDL_GL_SetAttribute.
    4.24  
    4.25  If your application doesn't use OpenGL's depth buffer, you may find significant performance improvement by setting SDL_GL_DEPTH_SIZE to 0.
    4.26  
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/README.touch	Sun Aug 22 12:07:55 2010 -0700
     5.3 @@ -0,0 +1,101 @@
     5.4 +===========================================================================
     5.5 +System Specific Notes
     5.6 +===========================================================================
     5.7 +Linux:
     5.8 +The linux touch system is currently based off event streams, and proc/bus/devices. The active user must be given permissions to read /dev/input/TOUCHDEVICE, where TOUCHDEVICE is the event stream for your device. Currently only Wacom tablets are supported. If you have an unsupported tablet contact me at jim.tla+sdl_touch@gmail.com and I will help you get support for it.
     5.9 +
    5.10 +Mac: 
    5.11 +The Mac and Iphone API's are pretty. If your touch device supports them then you'll be fine. If it doesn't, then there isn't much we can do.
    5.12 +
    5.13 +iPhone: 
    5.14 +Works out of box.
    5.15 +
    5.16 +Windows:
    5.17 +Unfortunately there is no windows support as of yet. Support for Windows 7 is planned, but we currently have no way to test. If you have a Windows 7 WM_TOUCH supported device, and are willing to help test please contact me at jim.tla+sdl_touch@gmail.com
    5.18 +
    5.19 +===========================================================================
    5.20 +Events
    5.21 +===========================================================================
    5.22 +SDL_FINGERDOWN:
    5.23 +Sent when a finger (or stylus) is placed on a touch device.
    5.24 +Fields:
    5.25 +event.tfinger.touchId  - the Id of the touch device.
    5.26 +event.tfinger.fingerId - the Id of the finger which just went down.
    5.27 +event.tfinger.x        - the x coordinate of the touch (0..touch.xres)
    5.28 +event.tfinger.y        - the y coordinate of the touch (0..touch.yres)
    5.29 +event.tfinger.pressure - the pressure of the touch (0..touch.pressureres)
    5.30 +
    5.31 +SDL_FINGERMOTION:
    5.32 +Sent when a finger (or stylus) is moved on the touch device.
    5.33 +Fields:
    5.34 +Same as FINGERDOWN but with additional:
    5.35 +event.tfginer.dx       - change in x coordinate during this motion event.
    5.36 +event.tfginer.dy       - change in y coordinate during this motion event.
    5.37 +
    5.38 +SDL_FINGERMOTION:
    5.39 +Sent when a finger (or stylus) is lifted from the touch device.
    5.40 +Fields:
    5.41 +Same as FINGERDOWN.
    5.42 +
    5.43 +
    5.44 +===========================================================================
    5.45 +Functions
    5.46 +===========================================================================
    5.47 +SDL provides the ability to access the underlying Touch and Finger structures.
    5.48 +These structures should _never_ be modified.
    5.49 +
    5.50 +The following functions are included from SDL_Touch.h
    5.51 +
    5.52 +To get a SDL_Touch device call SDL_GetTouch(touchId). 
    5.53 +This returns an SDL_Touch*. 
    5.54 +IMPORTANT: If the touch has been removed, or there is no touch with the given ID, SDL_GetTouch will return null. Be sure to check for this!
    5.55 +
    5.56 +An SDL_Touch has the following fields:
    5.57 +>xres,yres,pressures:
    5.58 +	The resolution at which x,y, and pressure values are reported. Currently these will always be equal to 2^15, but this may not always be the case. 
    5.59 +
    5.60 +>pressure_max, pressure_min, x_max, x_min, y_max, y_min
    5.61 +	Which give, respectively, the maximum and minumum values that the touch digitizer can return for pressure, x coordiniate, and y coordinate AS REPORTED BY THE OPERATING SYSTEM.
    5.62 +On Mac/iPhone systems _max will always be 0, and _min will always be 1. 
    5.63 +
    5.64 +>native_xres,native_yres,native_pressureres:
    5.65 +	The native resolution of the touch device AS REPORTED BY THE OPERATING SYSTEM.
    5.66 +On Mac/iPhone systems these will always be 1.
    5.67 +
    5.68 +>num_fingers:
    5.69 +	The number of fingers currently down on the device.
    5.70 +
    5.71 +>fingers:
    5.72 +	An array of pointers to the fingers which are on the device.
    5.73 +
    5.74 +
    5.75 +The most common reason to access a touch device is to normalize inputs. This would be accomplished by code like the following:
    5.76 +
    5.77 +      SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
    5.78 +      if(inTouch == NULL) continue; //The touch has been removed
    5.79 +
    5.80 +      float x = ((float)event.tfinger.x)/inTouch->xres;
    5.81 +      float y = ((float)event.tfinger.y)/inTouch->yres;
    5.82 +
    5.83 +
    5.84 +
    5.85 +To get an SDL_Finger, call SDL_GetFinger(touch,fingerId), where touch is a pointer to an SDL_Touch device, and fingerId is the id of the requested finger.
    5.86 +This returns an SDL_Finger*, or null if the finger does not exist, or has been removed.
    5.87 +An SDL_Finger is guaranteed to be persistent for the duration of a touch, but it will be de-allocated as soon as the finger is removed. This occurs when the SDL_FINGERUP event is _added_ to the event queue, and thus _before_ the FINGERUP event is polled. 
    5.88 +As a result, be very careful to check for null return values.
    5.89 +
    5.90 +An SDL_Finger has the following fields:
    5.91 +>x,y,pressure:
    5.92 +	The current coordinates of the touch.
    5.93 +>xdelta,ydelta: 
    5.94 +	The change in position resulting from the last finger motion.
    5.95 +>last_x, last_y, last_pressure:
    5.96 +	 The previous coordinates of the touch.
    5.97 +
    5.98 +===========================================================================
    5.99 +Notes
   5.100 +===========================================================================
   5.101 +For a complete example see test/testgesture.c
   5.102 +
   5.103 +Please direct questions/comments to:
   5.104 +   jim.tla+sdl_touch@gmail.com
     6.1 --- a/VisualC/SDL/SDL_VS2005.vcproj	Sun Aug 22 11:56:07 2010 -0700
     6.2 +++ b/VisualC/SDL/SDL_VS2005.vcproj	Sun Aug 22 12:07:55 2010 -0700
     6.3 @@ -1,10 +1,18 @@
     6.4  <?xml version="1.0" encoding="Windows-1252"?>
     6.5  <VisualStudioProject
     6.6  	ProjectType="Visual C++"
     6.7 +<<<<<<< local
     6.8  	Version="8.00"
     6.9 +=======
    6.10 +	Version="9.00"
    6.11 +>>>>>>> other
    6.12  	Name="SDL"
    6.13  	ProjectGUID="{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}"
    6.14  	RootNamespace="SDL"
    6.15 +<<<<<<< local
    6.16 +=======
    6.17 +	TargetFrameworkVersion="131072"
    6.18 +>>>>>>> other
    6.19  	>
    6.20  	<Platforms>
    6.21  		<Platform
    6.22 @@ -76,16 +84,36 @@
    6.23  			/>
    6.24  			<Tool
    6.25  				Name="VCLinkerTool"
    6.26 +<<<<<<< local
    6.27  				AdditionalOptions="/MACHINE:I386"
    6.28 +=======
    6.29 +				AdditionalOptions="/MACHINE:I386&#x0D;&#x0A;msvcrt.lib"
    6.30 +>>>>>>> other
    6.31  				AdditionalDependencies="msimg32.lib winmm.lib"
    6.32  				OutputFile=".\Debug/SDL.dll"
    6.33  				LinkIncremental="2"
    6.34  				SuppressStartupBanner="true"
    6.35 +<<<<<<< local
    6.36  				IgnoreAllDefaultLibraries="true"
    6.37 +=======
    6.38 +				IgnoreAllDefaultLibraries="false"
    6.39 +				IgnoreDefaultLibraryNames=""
    6.40 +>>>>>>> other
    6.41  				GenerateDebugInformation="true"
    6.42  				ProgramDatabaseFile=".\Debug/SDL.pdb"
    6.43 +<<<<<<< local
    6.44  				SubSystem="2"
    6.45 +=======
    6.46 +				SubSystem="0"
    6.47 +				RandomizedBaseAddress="1"
    6.48 +				DataExecutionPrevention="0"
    6.49 +>>>>>>> other
    6.50  				ImportLibrary=".\Debug/SDL.lib"
    6.51 +<<<<<<< local
    6.52 +=======
    6.53 +				Profile="true"
    6.54 +				CLRThreadAttribute="0"
    6.55 +>>>>>>> other
    6.56  				CLRUnmanagedCodeCheck="false"
    6.57  			/>
    6.58  			<Tool
    6.59 @@ -107,9 +135,12 @@
    6.60  				Name="VCAppVerifierTool"
    6.61  			/>
    6.62  			<Tool
    6.63 +<<<<<<< local
    6.64  				Name="VCWebDeploymentTool"
    6.65  			/>
    6.66  			<Tool
    6.67 +=======
    6.68 +>>>>>>> other
    6.69  				Name="VCPostBuildEventTool"
    6.70  			/>
    6.71  		</Configuration>
    6.72 @@ -185,6 +216,11 @@
    6.73  				IgnoreAllDefaultLibraries="true"
    6.74  				ProgramDatabaseFile=".\Release/SDL.pdb"
    6.75  				SubSystem="2"
    6.76 +<<<<<<< local
    6.77 +=======
    6.78 +				RandomizedBaseAddress="1"
    6.79 +				DataExecutionPrevention="0"
    6.80 +>>>>>>> other
    6.81  				ImportLibrary=".\Release/SDL.lib"
    6.82  			/>
    6.83  			<Tool
    6.84 @@ -206,9 +242,12 @@
    6.85  				Name="VCAppVerifierTool"
    6.86  			/>
    6.87  			<Tool
    6.88 +<<<<<<< local
    6.89  				Name="VCWebDeploymentTool"
    6.90  			/>
    6.91  			<Tool
    6.92 +=======
    6.93 +>>>>>>> other
    6.94  				Name="VCPostBuildEventTool"
    6.95  			/>
    6.96  		</Configuration>
    6.97 @@ -941,6 +980,17 @@
    6.98  			>
    6.99  		</File>
   6.100  		<File
   6.101 +<<<<<<< local
   6.102 +=======
   6.103 +			RelativePath="..\..\src\events\SDL_touch.c"
   6.104 +			>
   6.105 +		</File>
   6.106 +		<File
   6.107 +			RelativePath="..\..\src\events\SDL_touch_c.h"
   6.108 +			>
   6.109 +		</File>
   6.110 +		<File
   6.111 +>>>>>>> other
   6.112  			RelativePath="..\..\src\video\SDL_video.c"
   6.113  			>
   6.114  		</File>
     7.1 --- a/VisualC/SDLmain/SDLmain_VS2005.vcproj	Sun Aug 22 11:56:07 2010 -0700
     7.2 +++ b/VisualC/SDLmain/SDLmain_VS2005.vcproj	Sun Aug 22 12:07:55 2010 -0700
     7.3 @@ -1,9 +1,17 @@
     7.4  <?xml version="1.0" encoding="Windows-1252"?>
     7.5  <VisualStudioProject
     7.6  	ProjectType="Visual C++"
     7.7 +<<<<<<< local
     7.8  	Version="8.00"
     7.9 +=======
    7.10 +	Version="9.00"
    7.11 +>>>>>>> other
    7.12  	Name="SDLmain"
    7.13  	ProjectGUID="{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}"
    7.14 +<<<<<<< local
    7.15 +=======
    7.16 +	TargetFrameworkVersion="131072"
    7.17 +>>>>>>> other
    7.18  	>
    7.19  	<Platforms>
    7.20  		<Platform
    7.21 @@ -25,7 +33,11 @@
    7.22  			<Tool
    7.23  				Name="VCPreBuildEventTool"
    7.24  				Description="Making sure basic SDL headers are in place..."
    7.25 +<<<<<<< local
    7.26  				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"
    7.27 +=======
    7.28 +				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;"
    7.29 +>>>>>>> other
    7.30  			/>
    7.31  			<Tool
    7.32  				Name="VCCustomBuildTool"
    7.33 @@ -98,7 +110,11 @@
    7.34  			<Tool
    7.35  				Name="VCPreBuildEventTool"
    7.36  				Description="Making sure basic SDL headers are in place..."
    7.37 +<<<<<<< local
    7.38  				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"
    7.39 +=======
    7.40 +				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;"
    7.41 +>>>>>>> other
    7.42  			/>
    7.43  			<Tool
    7.44  				Name="VCCustomBuildTool"
    7.45 @@ -171,7 +187,11 @@
    7.46  			<Tool
    7.47  				Name="VCPreBuildEventTool"
    7.48  				Description="Making sure basic SDL headers are in place..."
    7.49 +<<<<<<< local
    7.50  				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"
    7.51 +=======
    7.52 +				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;"
    7.53 +>>>>>>> other
    7.54  			/>
    7.55  			<Tool
    7.56  				Name="VCCustomBuildTool"
     8.1 --- a/Xcode-iPhoneOS/Demos/DemosiPhoneOS.xcodeproj/project.pbxproj	Sun Aug 22 11:56:07 2010 -0700
     8.2 +++ b/Xcode-iPhoneOS/Demos/DemosiPhoneOS.xcodeproj/project.pbxproj	Sun Aug 22 12:07:55 2010 -0700
     8.3 @@ -109,7 +109,7 @@
     8.4  			isa = PBXContainerItemProxy;
     8.5  			containerPortal = FD1B48920E313154007AB34E /* SDLiPhoneOS.xcodeproj */;
     8.6  			proxyType = 2;
     8.7 -			remoteGlobalIDString = 006E982211955059001DE610 /* testsdl.app */;
     8.8 +			remoteGlobalIDString = 006E982211955059001DE610;
     8.9  			remoteInfo = testsdl;
    8.10  		};
    8.11  		FD1B489D0E313154007AB34E /* PBXContainerItemProxy */ = {
     9.1 --- a/Xcode-iPhoneOS/SDL/SDLiPhoneOS.xcodeproj/project.pbxproj	Sun Aug 22 11:56:07 2010 -0700
     9.2 +++ b/Xcode-iPhoneOS/SDL/SDLiPhoneOS.xcodeproj/project.pbxproj	Sun Aug 22 12:07:55 2010 -0700
     9.3 @@ -95,6 +95,12 @@
     9.4  		04B2ECEE1025CE4800F9BC5F /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B2ECE81025CE4800F9BC5F /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; };
     9.5  		04B2ECFF1025CEB900F9BC5F /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04B2ECF11025CEB900F9BC5F /* SDL_atomic.c */; };
     9.6  		04B2ED081025CF9E00F9BC5F /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B2ED061025CF9E00F9BC5F /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; };
     9.7 +		04BA9D6311EF474A00B60E01 /* SDL_gesture_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BA9D5F11EF474A00B60E01 /* SDL_gesture_c.h */; };
     9.8 +		04BA9D6411EF474A00B60E01 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BA9D6011EF474A00B60E01 /* SDL_gesture.c */; };
     9.9 +		04BA9D6511EF474A00B60E01 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BA9D6111EF474A00B60E01 /* SDL_touch_c.h */; };
    9.10 +		04BA9D6611EF474A00B60E01 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BA9D6211EF474A00B60E01 /* SDL_touch.c */; };
    9.11 +		04BA9D7D11EF497E00B60E01 /* SDL_gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BA9D7B11EF497E00B60E01 /* SDL_gesture.h */; };
    9.12 +		04BA9D7E11EF497E00B60E01 /* SDL_touch.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BA9D7C11EF497E00B60E01 /* SDL_touch.h */; };
    9.13  		04EC8B521025D12900431D42 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = 04EC8B501025D12900431D42 /* SDL_config_iphoneos.h */; };
    9.14  		04F2AF541104ABC300D6DDF7 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F2AF531104ABC300D6DDF7 /* SDL_assert.h */; };
    9.15  		04F2AF561104ABD200D6DDF7 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F2AF551104ABD200D6DDF7 /* SDL_assert.c */; };
    9.16 @@ -346,6 +352,12 @@
    9.17  		04B2ECE81025CE4800F9BC5F /* SDL_revision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_revision.h; path = ../../include/SDL_revision.h; sourceTree = SOURCE_ROOT; };
    9.18  		04B2ECF11025CEB900F9BC5F /* SDL_atomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_atomic.c; sourceTree = "<group>"; };
    9.19  		04B2ED061025CF9E00F9BC5F /* SDL_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_config.h; path = ../../include/SDL_config.h; sourceTree = SOURCE_ROOT; };
    9.20 +		04BA9D5F11EF474A00B60E01 /* SDL_gesture_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gesture_c.h; sourceTree = "<group>"; };
    9.21 +		04BA9D6011EF474A00B60E01 /* SDL_gesture.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gesture.c; sourceTree = "<group>"; };
    9.22 +		04BA9D6111EF474A00B60E01 /* SDL_touch_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_touch_c.h; sourceTree = "<group>"; };
    9.23 +		04BA9D6211EF474A00B60E01 /* SDL_touch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_touch.c; sourceTree = "<group>"; };
    9.24 +		04BA9D7B11EF497E00B60E01 /* SDL_gesture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_gesture.h; path = ../../include/SDL_gesture.h; sourceTree = SOURCE_ROOT; };
    9.25 +		04BA9D7C11EF497E00B60E01 /* SDL_touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_touch.h; path = ../../include/SDL_touch.h; sourceTree = SOURCE_ROOT; };
    9.26  		04EC8B501025D12900431D42 /* SDL_config_iphoneos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_config_iphoneos.h; path = ../../include/SDL_config_iphoneos.h; sourceTree = SOURCE_ROOT; };
    9.27  		04F2AF531104ABC300D6DDF7 /* SDL_assert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_assert.h; path = ../../include/SDL_assert.h; sourceTree = SOURCE_ROOT; };
    9.28  		04F2AF551104ABD200D6DDF7 /* SDL_assert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_assert.c; path = ../../src/SDL_assert.c; sourceTree = SOURCE_ROOT; };
    9.29 @@ -851,6 +863,7 @@
    9.30  				FD99B8F60DD52EB400FB1D6B /* SDL_endian.h */,
    9.31  				FD99B8DC0DD52EB400FB1D6B /* SDL_error.h */,
    9.32  				FD99B8DD0DD52EB400FB1D6B /* SDL_events.h */,
    9.33 +				04BA9D7B11EF497E00B60E01 /* SDL_gesture.h */,
    9.34  				04461DED0EA76BA3006C462D /* SDL_haptic.h */,
    9.35  				044E5FB411E6069F0076F181 /* SDL_input.h */,
    9.36  				FD99B8DE0DD52EB400FB1D6B /* SDL_joystick.h */,
    9.37 @@ -876,6 +889,7 @@
    9.38  				FD99B8EF0DD52EB400FB1D6B /* SDL_syswm.h */,
    9.39  				FD99B8F00DD52EB400FB1D6B /* SDL_thread.h */,
    9.40  				FD99B8F10DD52EB400FB1D6B /* SDL_timer.h */,
    9.41 +				04BA9D7C11EF497E00B60E01 /* SDL_touch.h */,
    9.42  				FD99B8F20DD52EB400FB1D6B /* SDL_types.h */,
    9.43  				FD99B8F30DD52EB400FB1D6B /* SDL_version.h */,
    9.44  				FD99B8F40DD52EB400FB1D6B /* SDL_video.h */,
    9.45 @@ -956,6 +970,10 @@
    9.46  		FD99B98C0DD52EDC00FB1D6B /* events */ = {
    9.47  			isa = PBXGroup;
    9.48  			children = (
    9.49 +				04BA9D5F11EF474A00B60E01 /* SDL_gesture_c.h */,
    9.50 +				04BA9D6011EF474A00B60E01 /* SDL_gesture.c */,
    9.51 +				04BA9D6111EF474A00B60E01 /* SDL_touch_c.h */,
    9.52 +				04BA9D6211EF474A00B60E01 /* SDL_touch.c */,
    9.53  				FD99B98D0DD52EDC00FB1D6B /* blank_cursor.h */,
    9.54  				FD99B98E0DD52EDC00FB1D6B /* default_cursor.h */,
    9.55  				FD99B98F0DD52EDC00FB1D6B /* scancodes_darwin.h */,
    9.56 @@ -1191,6 +1209,10 @@
    9.57  				044E5FB511E6069F0076F181 /* SDL_clipboard.h in Headers */,
    9.58  				044E5FB611E6069F0076F181 /* SDL_input.h in Headers */,
    9.59  				0420497011E6F03D007E7EC9 /* SDL_clipboardevents_c.h in Headers */,
    9.60 +				04BA9D6311EF474A00B60E01 /* SDL_gesture_c.h in Headers */,
    9.61 +				04BA9D6511EF474A00B60E01 /* SDL_touch_c.h in Headers */,
    9.62 +				04BA9D7D11EF497E00B60E01 /* SDL_gesture.h in Headers */,
    9.63 +				04BA9D7E11EF497E00B60E01 /* SDL_touch.h in Headers */,
    9.64  			);
    9.65  			runOnlyForDeploymentPostprocessing = 0;
    9.66  		};
    9.67 @@ -1431,6 +1453,8 @@
    9.68  				006E9889119552DD001DE610 /* SDL_rwopsbundlesupport.m in Sources */,
    9.69  				044E5FB811E606EB0076F181 /* SDL_clipboard.c in Sources */,
    9.70  				0420497111E6F03D007E7EC9 /* SDL_clipboardevents.c in Sources */,
    9.71 +				04BA9D6411EF474A00B60E01 /* SDL_gesture.c in Sources */,
    9.72 +				04BA9D6611EF474A00B60E01 /* SDL_touch.c in Sources */,
    9.73  			);
    9.74  			runOnlyForDeploymentPostprocessing = 0;
    9.75  		};
    10.1 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj	Sun Aug 22 11:56:07 2010 -0700
    10.2 +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj	Sun Aug 22 12:07:55 2010 -0700
    10.3 @@ -476,6 +476,16 @@
    10.4  		04F2AF671104AC0800D6DDF7 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F2AF651104AC0800D6DDF7 /* SDL_assert.c */; };
    10.5  		04F2AF691104AC4500D6DDF7 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F2AF681104AC4500D6DDF7 /* SDL_assert.h */; settings = {ATTRIBUTES = (Public, ); }; };
    10.6  		04F2AF6A1104AC4500D6DDF7 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F2AF681104AC4500D6DDF7 /* SDL_assert.h */; };
    10.7 +		8CB0A76C11F6A84800CBA2DE /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CB0A76A11F6A84800CBA2DE /* SDL_x11clipboard.c */; };
    10.8 +		8CB0A76D11F6A84800CBA2DE /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CB0A76B11F6A84800CBA2DE /* SDL_x11clipboard.h */; };
    10.9 +		8CB0A77811F6A87F00CBA2DE /* SDL_gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CB0A77611F6A87F00CBA2DE /* SDL_gesture.h */; };
   10.10 +		8CB0A77911F6A87F00CBA2DE /* SDL_touch.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CB0A77711F6A87F00CBA2DE /* SDL_touch.h */; };
   10.11 +		8CB0A77E11F6A8E700CBA2DE /* SDL_gesture_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CB0A77A11F6A8E700CBA2DE /* SDL_gesture_c.h */; };
   10.12 +		8CB0A77F11F6A8E700CBA2DE /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CB0A77B11F6A8E700CBA2DE /* SDL_gesture.c */; };
   10.13 +		8CB0A78011F6A8E700CBA2DE /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CB0A77C11F6A8E700CBA2DE /* SDL_touch_c.h */; };
   10.14 +		8CB0A78111F6A8E700CBA2DE /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CB0A77D11F6A8E700CBA2DE /* SDL_touch.c */; };
   10.15 +		8CB0A78711F6A90B00CBA2DE /* SDL_eventtouch.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CB0A78511F6A90B00CBA2DE /* SDL_eventtouch.c */; };
   10.16 +		8CB0A78811F6A90B00CBA2DE /* SDL_eventtouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CB0A78611F6A90B00CBA2DE /* SDL_eventtouch.h */; };
   10.17  		BECDF62E0761BA81005FE872 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 01538330006D78D67F000001 /* SDL_audio.c */; };
   10.18  		BECDF62F0761BA81005FE872 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 01538331006D78D67F000001 /* SDL_audiocvt.c */; };
   10.19  		BECDF6300761BA81005FE872 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = 01538332006D78D67F000001 /* SDL_audiodev.c */; };
   10.20 @@ -864,6 +874,17 @@
   10.21  		0C5AF5FD01191D2B7F000001 /* SDL_version.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_version.h; path = ../../include/SDL_version.h; sourceTree = SOURCE_ROOT; };
   10.22  		0C5AF5FE01191D2B7F000001 /* SDL_video.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_video.h; path = ../../include/SDL_video.h; sourceTree = SOURCE_ROOT; };
   10.23  		0C5AF5FF01191D2B7F000001 /* SDL.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL.h; path = ../../include/SDL.h; sourceTree = SOURCE_ROOT; };
   10.24 +		8C93F0EA11F803710014F54D /* gestureSDLTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "gestureSDLTest-Info.plist"; sourceTree = "<group>"; };
   10.25 +		8CB0A76A11F6A84800CBA2DE /* SDL_x11clipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11clipboard.c; sourceTree = "<group>"; };
   10.26 +		8CB0A76B11F6A84800CBA2DE /* SDL_x11clipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11clipboard.h; sourceTree = "<group>"; };
   10.27 +		8CB0A77611F6A87F00CBA2DE /* SDL_gesture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_gesture.h; path = ../../include/SDL_gesture.h; sourceTree = SOURCE_ROOT; };
   10.28 +		8CB0A77711F6A87F00CBA2DE /* SDL_touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_touch.h; path = ../../include/SDL_touch.h; sourceTree = SOURCE_ROOT; };
   10.29 +		8CB0A77A11F6A8E700CBA2DE /* SDL_gesture_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gesture_c.h; sourceTree = "<group>"; };
   10.30 +		8CB0A77B11F6A8E700CBA2DE /* SDL_gesture.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gesture.c; sourceTree = "<group>"; };
   10.31 +		8CB0A77C11F6A8E700CBA2DE /* SDL_touch_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_touch_c.h; sourceTree = "<group>"; };
   10.32 +		8CB0A77D11F6A8E700CBA2DE /* SDL_touch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_touch.c; sourceTree = "<group>"; };
   10.33 +		8CB0A78511F6A90B00CBA2DE /* SDL_eventtouch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_eventtouch.c; sourceTree = "<group>"; };
   10.34 +		8CB0A78611F6A90B00CBA2DE /* SDL_eventtouch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_eventtouch.h; sourceTree = "<group>"; };
   10.35  		B24DA50405A88D52006B9F1C /* SDL_cpuinfo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SDL_cpuinfo.c; sourceTree = "<group>"; };
   10.36  		B29A290D04E5B28700A80002 /* SDL_loadso.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_loadso.h; path = ../../include/SDL_loadso.h; sourceTree = "<group>"; };
   10.37  		B2CF8DC405C444E400E5DC7F /* SDL_cpuinfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_cpuinfo.h; path = ../../include/SDL_cpuinfo.h; sourceTree = SOURCE_ROOT; };
   10.38 @@ -1108,6 +1129,10 @@
   10.39  		00CFA719106B498B00758660 /* x11 */ = {
   10.40  			isa = PBXGroup;
   10.41  			children = (
   10.42 +				8CB0A78511F6A90B00CBA2DE /* SDL_eventtouch.c */,
   10.43 +				8CB0A78611F6A90B00CBA2DE /* SDL_eventtouch.h */,
   10.44 +				8CB0A76A11F6A84800CBA2DE /* SDL_x11clipboard.c */,
   10.45 +				8CB0A76B11F6A84800CBA2DE /* SDL_x11clipboard.h */,
   10.46  				00CFA71A106B498B00758660 /* imKStoUCS.c */,
   10.47  				00CFA71B106B498B00758660 /* imKStoUCS.h */,
   10.48  				00CFA71C106B498B00758660 /* SDL_x11dyn.c */,
   10.49 @@ -1353,6 +1378,10 @@
   10.50  		01538367006D79147F000001 /* events */ = {
   10.51  			isa = PBXGroup;
   10.52  			children = (
   10.53 +				8CB0A77A11F6A8E700CBA2DE /* SDL_gesture_c.h */,
   10.54 +				8CB0A77B11F6A8E700CBA2DE /* SDL_gesture.c */,
   10.55 +				8CB0A77C11F6A8E700CBA2DE /* SDL_touch_c.h */,
   10.56 +				8CB0A77D11F6A8E700CBA2DE /* SDL_touch.c */,
   10.57  				0420497411E6F052007E7EC9 /* blank_cursor.h */,
   10.58  				0420497511E6F052007E7EC9 /* default_cursor.h */,
   10.59  				0420497611E6F052007E7EC9 /* scancodes_darwin.h */,
   10.60 @@ -1470,6 +1499,8 @@
   10.61  		0153844A006D81B07F000001 /* Public Headers */ = {
   10.62  			isa = PBXGroup;
   10.63  			children = (
   10.64 +				8CB0A77611F6A87F00CBA2DE /* SDL_gesture.h */,
   10.65 +				8CB0A77711F6A87F00CBA2DE /* SDL_touch.h */,
   10.66  				0C5AF5E501191D2B7F000001 /* begin_code.h */,
   10.67  				0C5AF5E601191D2B7F000001 /* close_code.h */,
   10.68  				0C5AF5FF01191D2B7F000001 /* SDL.h */,
   10.69 @@ -1561,6 +1592,7 @@
   10.70  				BECDF66B0761BA81005FE872 /* Info-Framework.plist */,
   10.71  				BEC562FE0761C0E800A33029 /* Linked Frameworks */,
   10.72  				00D8D9F11195090700638393 /* testsdl-Info.plist */,
   10.73 +				8C93F0EA11F803710014F54D /* gestureSDLTest-Info.plist */,
   10.74  			);
   10.75  			comments = "To build Universal Binaries, we have experimented with a variety of different options.\nThe complication is that we must retain compatibility with at least 10.2. \nThe Universal Binary defaults only work for > 10.3.9\n\nSo far, we have found:\ngcc 4.0.0 with Xcode 2.1 always links against libgcc_s. gcc 4.0.1 from Xcode 2.2 fixes this problem.\n\nBut gcc 4.0 will not work with < 10.3.9 because we continue to get an undefined symbol to _fprintf$LDBL128.\nSo we must use gcc 3.3 on PPC to accomplish 10.2 support. (But 4.0 is required for i386.)\n\nSetting the deployment target to 10.4 will disable prebinding, so for PPC, we set it less than 10.4 to preserve prebinding for legacy support.\n\nSetting the PPC SDKROOT to /Developers/SDKs/MacOSX10.2.8.sdk will link to 63.0.0 libSystem.B.dylib. Leaving it at current or 10.4u links to 88.1.2. However, as long as we are using gcc 3.3, it doesn't seem to matter as testing has demonstrated both will run. We have decided not to invoke the 10.2.8 SDK because it is not a default installed component with Xcode which will probably cause most people problems. However, rather than deleting the SDKROOT_ppc entry entirely, we have mapped it to 10.4u in case we decide we need to change this setting.\n\nTo use Altivec or SSE, we needed architecture specific flags:\nOTHER_CFLAGS_ppc\nOTHER_CFLAGS_i386\nOTHER_CFLAGS=$(OTHER_CFLAGS_($CURRENT_ARCH))\n\nThe general OTHER_CFLAGS needed to be manually mapped to architecture specific options because Xcode didn't do this automatically for us.\n\n\n";
   10.76  			name = SDLFramework;
   10.77 @@ -1805,6 +1837,12 @@
   10.78  				0420497D11E6F052007E7EC9 /* scancodes_linux.h in Headers */,
   10.79  				0420497E11E6F052007E7EC9 /* scancodes_win32.h in Headers */,
   10.80  				0420497F11E6F052007E7EC9 /* scancodes_xfree86.h in Headers */,
   10.81 +				8CB0A76D11F6A84800CBA2DE /* SDL_x11clipboard.h in Headers */,
   10.82 +				8CB0A77811F6A87F00CBA2DE /* SDL_gesture.h in Headers */,
   10.83 +				8CB0A77911F6A87F00CBA2DE /* SDL_touch.h in Headers */,
   10.84 +				8CB0A77E11F6A8E700CBA2DE /* SDL_gesture_c.h in Headers */,
   10.85 +				8CB0A78011F6A8E700CBA2DE /* SDL_touch_c.h in Headers */,
   10.86 +				8CB0A78811F6A90B00CBA2DE /* SDL_eventtouch.h in Headers */,
   10.87  			);
   10.88  			runOnlyForDeploymentPostprocessing = 0;
   10.89  		};
   10.90 @@ -2277,6 +2315,10 @@
   10.91  				04DEA57511E6009000386CAC /* SDL_clipboard.c in Sources */,
   10.92  				04DEA57A11E600A600386CAC /* SDL_cocoaclipboard.m in Sources */,
   10.93  				0420496211E6EFD3007E7EC9 /* SDL_clipboardevents.c in Sources */,
   10.94 +				8CB0A76C11F6A84800CBA2DE /* SDL_x11clipboard.c in Sources */,
   10.95 +				8CB0A77F11F6A8E700CBA2DE /* SDL_gesture.c in Sources */,
   10.96 +				8CB0A78111F6A8E700CBA2DE /* SDL_touch.c in Sources */,
   10.97 +				8CB0A78711F6A90B00CBA2DE /* SDL_eventtouch.c in Sources */,
   10.98  			);
   10.99  			runOnlyForDeploymentPostprocessing = 0;
  10.100  		};
    11.1 --- a/configure.in	Sun Aug 22 11:56:07 2010 -0700
    11.2 +++ b/configure.in	Sun Aug 22 12:07:55 2010 -0700
    11.3 @@ -1005,6 +1005,8 @@
    11.4  dnl Find the X11 include and library directories
    11.5  CheckX11()
    11.6  {
    11.7 +
    11.8 +
    11.9      AC_ARG_ENABLE(video-x11,
   11.10  AC_HELP_STRING([--enable-video-x11], [use X11 video driver [[default=yes]]]),
   11.11                    , enable_video_x11=yes)
    12.1 --- a/include/SDL_events.h	Sun Aug 22 11:56:07 2010 -0700
    12.2 +++ b/include/SDL_events.h	Sun Aug 22 12:07:55 2010 -0700
    12.3 @@ -36,6 +36,8 @@
    12.4  #include "SDL_mouse.h"
    12.5  #include "SDL_joystick.h"
    12.6  #include "SDL_quit.h"
    12.7 +#include "SDL_gesture.h"
    12.8 +#include "SDL_touch.h"
    12.9  
   12.10  #include "begin_code.h"
   12.11  /* Set up for C function definitions, even when using C++ */
   12.12 @@ -90,14 +92,28 @@
   12.13      SDL_JOYBUTTONDOWN,          /**< Joystick button pressed */
   12.14      SDL_JOYBUTTONUP,            /**< Joystick button released */
   12.15  
   12.16 +    /* Touch events */
   12.17 +    SDL_FINGERDOWN      = 0x700,
   12.18 +    SDL_FINGERUP,
   12.19 +    SDL_FINGERMOTION,
   12.20 +    SDL_TOUCHBUTTONDOWN,
   12.21 +    SDL_TOUCHBUTTONUP,    
   12.22 +
   12.23 +    /* Gesture events */
   12.24 +    SDL_DOLLARGESTURE   = 0x800,
   12.25 +    SDL_DOLLARRECORD,
   12.26 +    SDL_MULTIGESTURE,
   12.27 +
   12.28      /* Clipboard events */
   12.29 -    SDL_CLIPBOARDUPDATE = 0x700, /**< The clipboard changed */
   12.30 +
   12.31 +    SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard changed */
   12.32  
   12.33      /* Obsolete events */
   12.34      SDL_EVENT_COMPAT1 = 0x7000, /**< SDL 1.2 events for compatibility */
   12.35      SDL_EVENT_COMPAT2,
   12.36      SDL_EVENT_COMPAT3,
   12.37  
   12.38 +
   12.39      /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use,
   12.40       *  and should be allocated with SDL_RegisterEvents()
   12.41       */
   12.42 @@ -263,6 +279,79 @@
   12.43      Uint8 padding1;
   12.44  } SDL_JoyButtonEvent;
   12.45  
   12.46 +
   12.47 +/**
   12.48 + *  \brief Touch finger motion/finger event structure (event.tmotion.*)
   12.49 + */
   12.50 +typedef struct SDL_TouchFingerEvent
   12.51 +{
   12.52 +    Uint32 type;        /**< ::SDL_FINGERMOTION OR 
   12.53 +			   SDL_FINGERDOWN OR SDL_FINGERUP*/
   12.54 +    Uint32 windowID;    /**< The window with mouse focus, if any */
   12.55 +    SDL_TouchID touchId;        /**< The touch device id */
   12.56 +    SDL_FingerID fingerId;
   12.57 +    Uint8 state;        /**< The current button state */
   12.58 +    Uint8 padding1;
   12.59 +    Uint8 padding2;
   12.60 +    Uint8 padding3;
   12.61 +    Uint16 x;
   12.62 +    Uint16 y;
   12.63 +    Sint16 dx;
   12.64 +    Sint16 dy;
   12.65 +    Uint16 pressure;
   12.66 +} SDL_TouchFingerEvent;
   12.67 +
   12.68 +
   12.69 +/**
   12.70 + *  \brief Touch finger motion/finger event structure (event.tmotion.*)
   12.71 + */
   12.72 +typedef struct SDL_TouchButtonEvent
   12.73 +{
   12.74 +    Uint32 type;        /**< ::SDL_TOUCHBUTTONUP OR SDL_TOUCHBUTTONDOWN */
   12.75 +    Uint32 windowID;    /**< The window with mouse focus, if any */
   12.76 +    SDL_TouchID touchId;        /**< The touch device index */
   12.77 +    Uint8 state;        /**< The current button state */
   12.78 +    Uint8 button;        /**< The button changing state */
   12.79 +    Uint8 padding1;
   12.80 +    Uint8 padding2;
   12.81 +} SDL_TouchButtonEvent;
   12.82 +
   12.83 +
   12.84 +
   12.85 +/**
   12.86 + *  \brief Multiple Finger Gesture Event
   12.87 + */
   12.88 +typedef struct SDL_MultiGestureEvent
   12.89 +{
   12.90 +    Uint32 type;        /**< ::SDL_MULTIGESTURE */
   12.91 +    Uint32 windowID;    /**< The window with mouse focus, if any */
   12.92 +    SDL_TouchID touchId;        /**< The touch device index */
   12.93 +    float dTheta;
   12.94 +    float dDist;
   12.95 +    float x;  //currently 0...1. Change to screen coords?
   12.96 +    float y;  
   12.97 +    Uint16 numFingers;
   12.98 +    Uint16 padding;
   12.99 +} SDL_MultiGestureEvent;
  12.100 +
  12.101 +typedef struct SDL_DollarGestureEvent
  12.102 +{
  12.103 +    Uint32 type;        /**< ::SDL_DOLLARGESTURE */
  12.104 +    Uint32 windowID;    /**< The window with mouse focus, if any */
  12.105 +    SDL_TouchID touchId;        /**< The touch device index */
  12.106 +    SDL_GestureID gestureId;
  12.107 +    Uint32 numFingers;
  12.108 +    float error;
  12.109 +  /*
  12.110 +    //TODO: Enable to give location?
  12.111 +    float x;  //currently 0...1. Change to screen coords?
  12.112 +    float y;  
  12.113 +  */
  12.114 +} SDL_DollarGestureEvent;
  12.115 +
  12.116 +
  12.117 +
  12.118 +
  12.119  /**
  12.120   *  \brief The "quit requested" event
  12.121   */
  12.122 @@ -345,6 +434,10 @@
  12.123      SDL_QuitEvent quit;             /**< Quit request event data */
  12.124      SDL_UserEvent user;             /**< Custom event data */
  12.125      SDL_SysWMEvent syswm;           /**< System dependent window event data */
  12.126 +    SDL_TouchFingerEvent tfinger;   /**< Touch finger event data */
  12.127 +    SDL_TouchButtonEvent tbutton;   /**< Touch button event data */
  12.128 +    SDL_MultiGestureEvent mgesture; /**< Multi Finger Gesture data*/
  12.129 +    SDL_DollarGestureEvent dgesture; /**< Multi Finger Gesture data*/
  12.130  
  12.131      /** Temporarily here for backwards compatibility */
  12.132      /*@{*/
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/include/SDL_gesture.h	Sun Aug 22 12:07:55 2010 -0700
    13.3 @@ -0,0 +1,92 @@
    13.4 +/*
    13.5 +    SDL - Simple DirectMedia Layer
    13.6 +    Copyright (C) 1997-2010 Sam Lantinga
    13.7 +
    13.8 +    This library is free software; you can redistribute it and/or
    13.9 +    modify it under the terms of the GNU Lesser General Public
   13.10 +    License as published by the Free Software Foundation; either
   13.11 +    version 2.1 of the License, or (at your option) any later version.
   13.12 +
   13.13 +    This library is distributed in the hope that it will be useful,
   13.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13.16 +    Lesser General Public License for more details.
   13.17 +
   13.18 +    You should have received a copy of the GNU Lesser General Public
   13.19 +    License along with this library; if not, write to the Free Software
   13.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   13.21 +
   13.22 +    Sam Lantinga
   13.23 +    slouken@libsdl.org
   13.24 +*/
   13.25 +
   13.26 +/**
   13.27 + *  \file SDL_gesture.h
   13.28 + *  
   13.29 + *  Include file for SDL gesture event handling.
   13.30 + */
   13.31 +
   13.32 +#ifndef _SDL_gesture_h
   13.33 +#define _SDL_gesture_h
   13.34 +
   13.35 +#include "SDL_stdinc.h"
   13.36 +#include "SDL_error.h"
   13.37 +#include "SDL_video.h"
   13.38 +
   13.39 +#include "SDL_touch.h"
   13.40 +
   13.41 +
   13.42 +#include "begin_code.h"
   13.43 +/* Set up for C function definitions, even when using C++ */
   13.44 +#ifdef __cplusplus
   13.45 +/* *INDENT-OFF* */
   13.46 +extern "C" {
   13.47 +/* *INDENT-ON* */
   13.48 +#endif
   13.49 +
   13.50 +typedef Sint64 SDL_GestureID;
   13.51 +
   13.52 +/* Function prototypes */
   13.53 +
   13.54 +/**
   13.55 + *  \brief Begin Recording a gesture on the specified touch, or all touches (-1)
   13.56 + *
   13.57 + *
   13.58 + */
   13.59 +extern DECLSPEC int SDLCALL SDL_RecordGesture(SDL_TouchID touchId);
   13.60 +
   13.61 +
   13.62 +/**
   13.63 + *  \brief Save all currently loaded Dollar Gesture templates
   13.64 + *
   13.65 + *
   13.66 + */
   13.67 +extern DECLSPEC int SDLCALL SDL_SaveAllDollarTemplates(SDL_RWops *src);
   13.68 +
   13.69 +/**
   13.70 + *  \brief Save a currently loaded Dollar Gesture template
   13.71 + *
   13.72 + *
   13.73 + */
   13.74 +extern DECLSPEC int SDLCALL SDL_SaveDollarTemplate(SDL_GestureID gestureId,SDL_RWops *src);
   13.75 +
   13.76 +
   13.77 +/**
   13.78 + *  \brief Load Dollar Gesture templates from a file
   13.79 + *
   13.80 + *
   13.81 + */
   13.82 +extern DECLSPEC int SDLCALL SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src);
   13.83 +
   13.84 +
   13.85 +/* Ends C function definitions when using C++ */
   13.86 +#ifdef __cplusplus
   13.87 +/* *INDENT-OFF* */
   13.88 +}
   13.89 +/* *INDENT-ON* */
   13.90 +#endif
   13.91 +#include "close_code.h"
   13.92 +
   13.93 +#endif /* _SDL_gesture_h */
   13.94 +
   13.95 +/* vi: set ts=4 sw=4 expandtab: */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/include/SDL_touch.h	Sun Aug 22 12:07:55 2010 -0700
    14.3 @@ -0,0 +1,125 @@
    14.4 +/*
    14.5 +    SDL - Simple DirectMedia Layer
    14.6 +    Copyright (C) 1997-2010 Sam Lantinga
    14.7 +
    14.8 +    This library is free software; you can redistribute it and/or
    14.9 +    modify it under the terms of the GNU Lesser General Public
   14.10 +    License as published by the Free Software Foundation; either
   14.11 +    version 2.1 of the License, or (at your option) any later version.
   14.12 +
   14.13 +    This library is distributed in the hope that it will be useful,
   14.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14.16 +    Lesser General Public License for more details.
   14.17 +
   14.18 +    You should have received a copy of the GNU Lesser General Public
   14.19 +    License along with this library; if not, write to the Free Software
   14.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   14.21 +
   14.22 +    Sam Lantinga
   14.23 +    slouken@libsdl.org
   14.24 +*/
   14.25 +
   14.26 +/**
   14.27 + *  \file SDL_touch.h
   14.28 + *  
   14.29 + *  Include file for SDL touch event handling.
   14.30 + */
   14.31 +
   14.32 +#ifndef _SDL_touch_h
   14.33 +#define _SDL_touch_h
   14.34 +
   14.35 +#include "SDL_stdinc.h"
   14.36 +#include "SDL_error.h"
   14.37 +#include "SDL_video.h"
   14.38 +
   14.39 +#include "begin_code.h"
   14.40 +/* Set up for C function definitions, even when using C++ */
   14.41 +#ifdef __cplusplus
   14.42 +/* *INDENT-OFF* */
   14.43 +extern "C" {
   14.44 +/* *INDENT-ON* */
   14.45 +#endif
   14.46 +
   14.47 +
   14.48 +typedef Sint64 SDL_TouchID;
   14.49 +typedef Sint64 SDL_FingerID;
   14.50 +
   14.51 +
   14.52 +struct SDL_Finger {
   14.53 +  SDL_FingerID id;
   14.54 +  Uint16 x;
   14.55 +  Uint16 y;
   14.56 +  Uint16 pressure;
   14.57 +  Uint16 xdelta;
   14.58 +  Uint16 ydelta;
   14.59 +  Uint16 last_x, last_y,last_pressure;  /* the last reported coordinates */
   14.60 +  SDL_bool down;
   14.61 +};
   14.62 +
   14.63 +typedef struct SDL_Touch SDL_Touch;
   14.64 +typedef struct SDL_Finger SDL_Finger;
   14.65 +
   14.66 +
   14.67 +struct SDL_Touch {
   14.68 +  
   14.69 +  /* Free the touch when it's time */
   14.70 +  void (*FreeTouch) (SDL_Touch * touch);
   14.71 +  
   14.72 +  /* data common for tablets */
   14.73 +  float pressure_max, pressure_min;
   14.74 +  float x_max,x_min;
   14.75 +  float y_max,y_min;
   14.76 +  Uint16 xres,yres,pressureres;
   14.77 +  float native_xres,native_yres,native_pressureres;
   14.78 +  float tilt;                   /* for future use */
   14.79 +  float rotation;               /* for future use */
   14.80 +  
   14.81 +  /* Data common to all touch */
   14.82 +  SDL_TouchID id;
   14.83 +  SDL_Window *focus;
   14.84 +  
   14.85 +  char *name;
   14.86 +  Uint8 buttonstate;
   14.87 +  SDL_bool relative_mode;
   14.88 +  SDL_bool flush_motion;
   14.89 +
   14.90 +  int num_fingers;
   14.91 +  int max_fingers;
   14.92 +  SDL_Finger** fingers;
   14.93 +    
   14.94 +  void *driverdata;
   14.95 +};
   14.96 +
   14.97 +
   14.98 +
   14.99 +/* Function prototypes */
  14.100 +
  14.101 +/**
  14.102 + *  \brief Get the touch object at the given id.
  14.103 + *
  14.104 + *
  14.105 + */
  14.106 +  extern DECLSPEC SDL_Touch* SDLCALL SDL_GetTouch(SDL_TouchID id);
  14.107 +
  14.108 +
  14.109 +
  14.110 +/**
  14.111 + *  \brief Get the finger object of the given touch, at the given id.
  14.112 + *
  14.113 + *
  14.114 + */
  14.115 +  extern 
  14.116 +  DECLSPEC SDL_Finger* SDLCALL SDL_GetFinger(SDL_Touch *touch, SDL_FingerID id);
  14.117 +
  14.118 +/* Ends C function definitions when using C++ */
  14.119 +#ifdef __cplusplus
  14.120 +/* *INDENT-OFF* */
  14.121 +}
  14.122 +/* *INDENT-ON* */
  14.123 +#endif
  14.124 +#include "close_code.h"
  14.125 +
  14.126 +#endif /* _SDL_mouse_h */
  14.127 +
  14.128 +/* vi: set ts=4 sw=4 expandtab: */
    15.1 --- a/src/events/SDL_events.c	Sun Aug 22 11:56:07 2010 -0700
    15.2 +++ b/src/events/SDL_events.c	Sun Aug 22 12:07:55 2010 -0700
    15.3 @@ -254,6 +254,7 @@
    15.4      retcode = 0;
    15.5      retcode += SDL_KeyboardInit();
    15.6      retcode += SDL_MouseInit();
    15.7 +    retcode += SDL_TouchInit();
    15.8      retcode += SDL_QuitInit();
    15.9      if (retcode < 0) {
   15.10          /* We don't expect them to fail, but... */
   15.11 @@ -492,6 +493,10 @@
   15.12      if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) {
   15.13          return -1;
   15.14      }
   15.15 +
   15.16 +    SDL_GestureProcessEvent(event);
   15.17 +    
   15.18 +
   15.19      return 1;
   15.20  }
   15.21  
    16.1 --- a/src/events/SDL_events_c.h	Sun Aug 22 11:56:07 2010 -0700
    16.2 +++ b/src/events/SDL_events_c.h	Sun Aug 22 12:07:55 2010 -0700
    16.3 @@ -26,8 +26,9 @@
    16.4  #include "SDL_thread.h"
    16.5  #include "SDL_mouse_c.h"
    16.6  #include "SDL_keyboard_c.h"
    16.7 +#include "SDL_touch_c.h"
    16.8  #include "SDL_windowevents_c.h"
    16.9 -
   16.10 +#include "SDL_gesture_c.h"
   16.11  /* Start and stop the event processing loop */
   16.12  extern int SDL_StartEventLoop(Uint32 flags);
   16.13  extern void SDL_StopEventLoop(void);
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/events/SDL_gesture.c	Sun Aug 22 12:07:55 2010 -0700
    17.3 @@ -0,0 +1,643 @@
    17.4 +/*
    17.5 +    SDL - Simple DirectMedia Layer
    17.6 +    Copyright (C) 1997-2010 Sam Lantinga
    17.7 +
    17.8 +    This library is free software; you can redistribute it and/or
    17.9 +    modify it under the terms of the GNU Lesser General Public
   17.10 +    License as published by the Free Software Foundation; either
   17.11 +    version 2.1 of the License, or (at your option) any later version.
   17.12 +
   17.13 +    This library is distributed in the hope that it will be useful,
   17.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   17.16 +    Lesser General Public License for more details.
   17.17 +
   17.18 +    You should have received a copy of the GNU Lesser General Public
   17.19 +    License along with this library; if not, write to the Free Software    Founation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   17.20 +
   17.21 +    Sam Lantinga
   17.22 +    slouken@libsdl.org
   17.23 +*/
   17.24 +#include "SDL_config.h"
   17.25 +
   17.26 +/* General mouse handling code for SDL */
   17.27 +
   17.28 +#include "SDL_events.h"
   17.29 +#include "SDL_events_c.h"
   17.30 +#include "SDL_gesture_c.h"
   17.31 +
   17.32 +//TODO: Replace with malloc
   17.33 +
   17.34 +#define MAXPATHSIZE 1024
   17.35 +
   17.36 + 
   17.37 +
   17.38 +
   17.39 +#define DOLLARNPOINTS 64
   17.40 +#define DOLLARSIZE 256
   17.41 +
   17.42 +#define ENABLE_DOLLAR
   17.43 +
   17.44 +//PHI = ((sqrt(5)-1)/2)
   17.45 +#define PHI 0.618033989 
   17.46 +
   17.47 +typedef struct {
   17.48 +  float x,y;
   17.49 +} SDL_FloatPoint;
   17.50 +
   17.51 +typedef struct {
   17.52 +  float length;
   17.53 +  
   17.54 +  int numPoints;
   17.55 +  SDL_FloatPoint p[MAXPATHSIZE];
   17.56 +} SDL_DollarPath;
   17.57 +
   17.58 +typedef struct {
   17.59 +  SDL_FloatPoint path[DOLLARNPOINTS];
   17.60 +  unsigned long hash;
   17.61 +} SDL_DollarTemplate;
   17.62 +
   17.63 +typedef struct {
   17.64 +  SDL_GestureID id;
   17.65 +  SDL_FloatPoint res;
   17.66 +  SDL_FloatPoint centroid;
   17.67 +  SDL_DollarPath dollarPath;
   17.68 +  Uint16 numDownFingers;
   17.69 +
   17.70 +  int numDollarTemplates;
   17.71 +  SDL_DollarTemplate *dollarTemplate;
   17.72 +
   17.73 +  SDL_bool recording;
   17.74 +} SDL_GestureTouch;
   17.75 +
   17.76 +SDL_GestureTouch *SDL_gestureTouch;
   17.77 +int SDL_numGestureTouches = 0;
   17.78 +SDL_bool recordAll;
   17.79 +
   17.80 +void SDL_PrintPath(SDL_FloatPoint *path) {
   17.81 +  int i;
   17.82 +  printf("Path:");
   17.83 +  for(i=0;i<DOLLARNPOINTS;i++) {
   17.84 +    printf(" (%f,%f)",path[i].x,path[i].y);
   17.85 +  }
   17.86 +  printf("\n");
   17.87 +}
   17.88 +
   17.89 +int SDL_RecordGesture(SDL_TouchID touchId) {
   17.90 +  int i;
   17.91 +  if(touchId < 0) recordAll = SDL_TRUE;
   17.92 +  for(i = 0;i < SDL_numGestureTouches; i++) {
   17.93 +    if((touchId < 0) || (SDL_gestureTouch[i].id == touchId)) {
   17.94 +      SDL_gestureTouch[i].recording = SDL_TRUE;
   17.95 +      if(touchId >= 0)
   17.96 +	return 1;
   17.97 +    }      
   17.98 +  }
   17.99 +  return (touchId < 0);
  17.100 +}
  17.101 +
  17.102 +unsigned long SDL_HashDollar(SDL_FloatPoint* points) {
  17.103 +  unsigned long hash = 5381;
  17.104 +  int i;
  17.105 +  for(i = 0;i < DOLLARNPOINTS; i++) { 
  17.106 +    hash = ((hash<<5) + hash) + points[i].x;
  17.107 +    hash = ((hash<<5) + hash) + points[i].y;
  17.108 +  }
  17.109 +  return hash;
  17.110 +}
  17.111 +
  17.112 +
  17.113 +static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops * src) {
  17.114 +  if(src == NULL) return 0;
  17.115 +
  17.116 +  int i;
  17.117 +  
  17.118 +  //No Longer storing the Hash, rehash on load
  17.119 +  //if(SDL_RWops.write(src,&(templ->hash),sizeof(templ->hash),1) != 1) return 0;
  17.120 +  
  17.121 +  if(SDL_RWwrite(src,templ->path,
  17.122 +		 sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) 
  17.123 +    return 0;
  17.124 +
  17.125 +  return 1;
  17.126 +}
  17.127 +
  17.128 +
  17.129 +int SDL_SaveAllDollarTemplates(SDL_RWops *src) {  
  17.130 +  int i,j,rtrn = 0;
  17.131 +  for(i = 0; i < SDL_numGestureTouches; i++) {
  17.132 +    SDL_GestureTouch* touch = &SDL_gestureTouch[i];
  17.133 +    for(j = 0;j < touch->numDollarTemplates; j++) {
  17.134 +	rtrn += SaveTemplate(&touch->dollarTemplate[i],src);
  17.135 +    }
  17.136 +  }
  17.137 +  return rtrn;  
  17.138 +}
  17.139 +
  17.140 +int SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *src) {
  17.141 +  int i,j;
  17.142 +  for(i = 0; i < SDL_numGestureTouches; i++) {
  17.143 +    SDL_GestureTouch* touch = &SDL_gestureTouch[i];
  17.144 +    for(j = 0;j < touch->numDollarTemplates; j++) {
  17.145 +      if(touch->dollarTemplate[i].hash == gestureId) {
  17.146 +	return SaveTemplate(&touch->dollarTemplate[i],src);
  17.147 +      }
  17.148 +    }
  17.149 +  }
  17.150 +  SDL_SetError("Unknown gestureId");
  17.151 +  return -1;
  17.152 +}
  17.153 +
  17.154 +//path is an already sampled set of points
  17.155 +//Returns the index of the gesture on success, or -1
  17.156 +static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch,SDL_FloatPoint* path) {
  17.157 +  if(inTouch == NULL) {
  17.158 +    if(SDL_numGestureTouches == 0) return -1;
  17.159 +    int i = 0;
  17.160 +    for(i = 0;i < SDL_numGestureTouches; i++) {
  17.161 +      inTouch = &SDL_gestureTouch[i];
  17.162 +
  17.163 +      SDL_DollarTemplate* dollarTemplate = 
  17.164 +	SDL_realloc(inTouch->dollarTemplate,
  17.165 +		    (inTouch->numDollarTemplates + 1) * 
  17.166 +		    sizeof(SDL_DollarTemplate));
  17.167 +      if(!dollarTemplate) {
  17.168 +	SDL_OutOfMemory();
  17.169 +	return -1;
  17.170 +      }
  17.171 +	
  17.172 +      inTouch->dollarTemplate = dollarTemplate;
  17.173 +
  17.174 +      SDL_DollarTemplate *templ = 
  17.175 +	&inTouch->dollarTemplate[inTouch->numDollarTemplates];
  17.176 +      memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
  17.177 +      templ->hash = SDL_HashDollar(templ->path);
  17.178 +      inTouch->numDollarTemplates++;    
  17.179 +    }
  17.180 +    return inTouch->numDollarTemplates - 1;
  17.181 +  } else {
  17.182 +    SDL_DollarTemplate* dollarTemplate = 
  17.183 +      SDL_realloc(inTouch->dollarTemplate,
  17.184 +		  (inTouch->numDollarTemplates + 1) * 
  17.185 +		  sizeof(SDL_DollarTemplate));
  17.186 +    if(!dollarTemplate) {
  17.187 +      SDL_OutOfMemory();
  17.188 +      return -1;
  17.189 +    }
  17.190 +    
  17.191 +    inTouch->dollarTemplate = dollarTemplate;
  17.192 +
  17.193 +    SDL_DollarTemplate *templ = 
  17.194 +      &inTouch->dollarTemplate[inTouch->numDollarTemplates];
  17.195 +    memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
  17.196 +    templ->hash = SDL_HashDollar(templ->path);
  17.197 +    inTouch->numDollarTemplates++;
  17.198 +    return inTouch->numDollarTemplates - 1;
  17.199 +  }
  17.200 +  return -1;
  17.201 +}
  17.202 +
  17.203 +int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) {
  17.204 +  if(src == NULL) return 0;
  17.205 +  int i,loaded = 0;
  17.206 +  SDL_GestureTouch *touch = NULL;
  17.207 +  if(touchId >= 0) {
  17.208 +    for(i = 0;i < SDL_numGestureTouches; i++)
  17.209 +      if(SDL_gestureTouch[i].id == touchId)
  17.210 +	touch = &SDL_gestureTouch[i];
  17.211 +    if(touch == NULL) return -1;
  17.212 +  }
  17.213 +
  17.214 +  while(1) {
  17.215 +    SDL_DollarTemplate templ;
  17.216 +
  17.217 +    if(SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < 
  17.218 +       DOLLARNPOINTS) break;
  17.219 +
  17.220 +    if(touchId >= 0) {
  17.221 +      printf("Adding loaded gesture to 1 touch\n");
  17.222 +      if(SDL_AddDollarGesture(touch,templ.path)) loaded++;
  17.223 +    }
  17.224 +    else {
  17.225 +      printf("Adding to: %i touches\n",SDL_numGestureTouches);
  17.226 +      for(i = 0;i < SDL_numGestureTouches; i++) {
  17.227 +	touch = &SDL_gestureTouch[i];
  17.228 +	printf("Adding loaded gesture to + touches\n");
  17.229 +	//TODO: What if this fails?
  17.230 +	SDL_AddDollarGesture(touch,templ.path);	
  17.231 +      }
  17.232 +      loaded++;
  17.233 +    }
  17.234 +  }
  17.235 +
  17.236 +  return loaded; 
  17.237 +}
  17.238 +
  17.239 +
  17.240 +float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang) {
  17.241 +  //  SDL_FloatPoint p[DOLLARNPOINTS];
  17.242 +  float dist = 0;
  17.243 +  SDL_FloatPoint p;
  17.244 +  int i;
  17.245 +  for(i = 0; i < DOLLARNPOINTS; i++) {
  17.246 +    p.x = points[i].x * cos(ang) - points[i].y * sin(ang);
  17.247 +    p.y = points[i].x * sin(ang) + points[i].y * cos(ang);
  17.248 +    dist += sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
  17.249 +		 (p.y-templ[i].y)*(p.y-templ[i].y));
  17.250 +  }
  17.251 +  return dist/DOLLARNPOINTS;
  17.252 +  
  17.253 +}
  17.254 +
  17.255 +float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ) {
  17.256 +  //------------BEGIN DOLLAR BLACKBOX----------------//
  17.257 +  //-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-//
  17.258 +  //-"http://depts.washington.edu/aimgroup/proj/dollar/"-//
  17.259 +  float ta = -M_PI/4;
  17.260 +  float tb = M_PI/4;
  17.261 +  float dt = M_PI/90;
  17.262 +  float x1 = PHI*ta + (1-PHI)*tb;
  17.263 +  float f1 = dollarDifference(points,templ,x1);
  17.264 +  float x2 = (1-PHI)*ta + PHI*tb;
  17.265 +  float f2 = dollarDifference(points,templ,x2);
  17.266 +  while(abs(ta-tb) > dt) {
  17.267 +    if(f1 < f2) {
  17.268 +      tb = x2;
  17.269 +      x2 = x1;
  17.270 +      f2 = f1;
  17.271 +      x1 = PHI*ta + (1-PHI)*tb;
  17.272 +      f1 = dollarDifference(points,templ,x1);
  17.273 +    }
  17.274 +    else {
  17.275 +      ta = x1;
  17.276 +      x1 = x2;
  17.277 +      f1 = f2;
  17.278 +      x2 = (1-PHI)*ta + PHI*tb;
  17.279 +      f2 = dollarDifference(points,templ,x2);
  17.280 +    }
  17.281 +  }
  17.282 +  /*
  17.283 +  if(f1 <= f2)
  17.284 +    printf("Min angle (x1): %f\n",x1);
  17.285 +  else if(f1 >  f2)
  17.286 +    printf("Min angle (x2): %f\n",x2);
  17.287 +  */
  17.288 +  return SDL_min(f1,f2);  
  17.289 +}
  17.290 +
  17.291 +//DollarPath contains raw points, plus (possibly) the calculated length
  17.292 +int dollarNormalize(SDL_DollarPath path,SDL_FloatPoint *points) {
  17.293 +  int i;
  17.294 +  //Calculate length if it hasn't already been done
  17.295 +  if(path.length <= 0) {
  17.296 +    for(i=1;i<path.numPoints;i++) {
  17.297 +      float dx = path.p[i  ].x - 
  17.298 +	         path.p[i-1].x;
  17.299 +      float dy = path.p[i  ].y - 
  17.300 +	         path.p[i-1].y;
  17.301 +      path.length += sqrt(dx*dx+dy*dy);
  17.302 +    }
  17.303 +  }
  17.304 +
  17.305 +  //Resample
  17.306 +  float interval = path.length/(DOLLARNPOINTS - 1);
  17.307 +  float dist = interval;
  17.308 +
  17.309 +  int numPoints = 0;
  17.310 +  SDL_FloatPoint centroid; 
  17.311 +  centroid.x = 0;centroid.y = 0;
  17.312 +  
  17.313 +  //printf("(%f,%f)\n",path.p[path.numPoints-1].x,path.p[path.numPoints-1].y);
  17.314 +  for(i = 1;i < path.numPoints;i++) {
  17.315 +    float d = sqrt((path.p[i-1].x-path.p[i].x)*(path.p[i-1].x-path.p[i].x)+
  17.316 +		   (path.p[i-1].y-path.p[i].y)*(path.p[i-1].y-path.p[i].y));
  17.317 +    //printf("d = %f dist = %f/%f\n",d,dist,interval);
  17.318 +    while(dist + d > interval) {
  17.319 +      points[numPoints].x = path.p[i-1].x + 
  17.320 +	((interval-dist)/d)*(path.p[i].x-path.p[i-1].x);
  17.321 +      points[numPoints].y = path.p[i-1].y + 
  17.322 +	((interval-dist)/d)*(path.p[i].y-path.p[i-1].y);
  17.323 +      centroid.x += points[numPoints].x;
  17.324 +      centroid.y += points[numPoints].y;
  17.325 +      numPoints++;
  17.326 +
  17.327 +      dist -= interval;
  17.328 +    }
  17.329 +    dist += d;
  17.330 +  }
  17.331 +  if(numPoints < DOLLARNPOINTS-1) {
  17.332 +    printf("ERROR: NumPoints = %i\n",numPoints); 
  17.333 +    return 0;
  17.334 +  }
  17.335 +  //copy the last point
  17.336 +  points[DOLLARNPOINTS-1] = path.p[path.numPoints-1];
  17.337 +  numPoints = DOLLARNPOINTS;
  17.338 +
  17.339 +  centroid.x /= numPoints;
  17.340 +  centroid.y /= numPoints;
  17.341 + 
  17.342 +  //printf("Centroid (%f,%f)",centroid.x,centroid.y);
  17.343 +  //Rotate Points so point 0 is left of centroid and solve for the bounding box
  17.344 +  float xmin,xmax,ymin,ymax;
  17.345 +  xmin = centroid.x;
  17.346 +  xmax = centroid.x;
  17.347 +  ymin = centroid.y;
  17.348 +  ymax = centroid.y;
  17.349 +  
  17.350 +  float ang = atan2(centroid.y - points[0].y,
  17.351 +		    centroid.x - points[0].x);
  17.352 +
  17.353 +  for(i = 0;i<numPoints;i++) {					       
  17.354 +    float px = points[i].x;
  17.355 +    float py = points[i].y;
  17.356 +    points[i].x = (px - centroid.x)*cos(ang) - 
  17.357 +                  (py - centroid.y)*sin(ang) + centroid.x;
  17.358 +    points[i].y = (px - centroid.x)*sin(ang) + 
  17.359 +                  (py - centroid.y)*cos(ang) + centroid.y;
  17.360 +
  17.361 +
  17.362 +    if(points[i].x < xmin) xmin = points[i].x;
  17.363 +    if(points[i].x > xmax) xmax = points[i].x; 
  17.364 +    if(points[i].y < ymin) ymin = points[i].y;
  17.365 +    if(points[i].y > ymax) ymax = points[i].y;
  17.366 +  }
  17.367 +
  17.368 +  //Scale points to DOLLARSIZE, and translate to the origin
  17.369 +  float w = xmax-xmin;
  17.370 +  float h = ymax-ymin;
  17.371 +
  17.372 +  for(i=0;i<numPoints;i++) {
  17.373 +    points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
  17.374 +    points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h;
  17.375 +  }  
  17.376 +  return numPoints;
  17.377 +}
  17.378 +
  17.379 +float dollarRecognize(SDL_DollarPath path,int *bestTempl,SDL_GestureTouch* touch) {
  17.380 +	
  17.381 +	SDL_FloatPoint points[DOLLARNPOINTS];
  17.382 +	int numPoints = dollarNormalize(path,points);
  17.383 +	//SDL_PrintPath(points);
  17.384 +	int i;
  17.385 +	
  17.386 +	int bestDiff = 10000;
  17.387 +	*bestTempl = -1;
  17.388 +	for(i = 0;i < touch->numDollarTemplates;i++) {
  17.389 +		int diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
  17.390 +		if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
  17.391 +	}
  17.392 +	return bestDiff;
  17.393 +}
  17.394 +
  17.395 +int SDL_GestureAddTouch(SDL_Touch* touch) {  
  17.396 +  SDL_GestureTouch *gestureTouch = SDL_realloc(SDL_gestureTouch,
  17.397 +					       (SDL_numGestureTouches + 1) *
  17.398 +					       sizeof(SDL_GestureTouch));
  17.399 +
  17.400 +  if(!gestureTouch) {
  17.401 +    SDL_OutOfMemory();
  17.402 +    return -1;
  17.403 +  }
  17.404 +
  17.405 +  SDL_gestureTouch = gestureTouch;
  17.406 +
  17.407 +  SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
  17.408 +  SDL_gestureTouch[SDL_numGestureTouches].res.y = touch->yres;
  17.409 +  SDL_gestureTouch[SDL_numGestureTouches].numDownFingers = 0;
  17.410 +
  17.411 +  SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
  17.412 +  SDL_gestureTouch[SDL_numGestureTouches].id = touch->id;
  17.413 +
  17.414 +  SDL_gestureTouch[SDL_numGestureTouches].numDollarTemplates = 0;
  17.415 +
  17.416 +  SDL_gestureTouch[SDL_numGestureTouches].recording = SDL_FALSE;
  17.417 +
  17.418 +  SDL_numGestureTouches++;
  17.419 +  return 0;
  17.420 +}
  17.421 +
  17.422 +int SDL_GestureRemoveTouch(SDL_TouchID id) {
  17.423 +  int i;
  17.424 +  for(i = 0;i < SDL_numGestureTouches; i++) {
  17.425 +    if(SDL_gestureTouch[i].id == id) {
  17.426 +      SDL_numGestureTouches--;
  17.427 +      SDL_gestureTouch[i] = SDL_gestureTouch[SDL_numGestureTouches];
  17.428 +      return 1;
  17.429 +    }
  17.430 +  }
  17.431 +  return -1;
  17.432 +}
  17.433 +
  17.434 +
  17.435 +SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id) {
  17.436 +  int i;
  17.437 +  for(i = 0;i < SDL_numGestureTouches; i++) {
  17.438 +    //printf("%i ?= %i\n",SDL_gestureTouch[i].id,id);
  17.439 +    if(SDL_gestureTouch[i].id == id) return &SDL_gestureTouch[i];
  17.440 +  }
  17.441 +  return NULL;
  17.442 +}
  17.443 +
  17.444 +int SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist) {
  17.445 +  SDL_Event event;
  17.446 +  event.mgesture.type = SDL_MULTIGESTURE;
  17.447 +  event.mgesture.touchId = touch->id;
  17.448 +  event.mgesture.x = touch->centroid.x;
  17.449 +  event.mgesture.y = touch->centroid.y;
  17.450 +  event.mgesture.dTheta = dTheta;
  17.451 +  event.mgesture.dDist = dDist;  
  17.452 +  event.mgesture.numFingers = touch->numDownFingers;
  17.453 +  return SDL_PushEvent(&event) > 0;
  17.454 +}
  17.455 +
  17.456 +int SDL_SendGestureDollar(SDL_GestureTouch* touch,
  17.457 +			  SDL_GestureID gestureId,float error) {
  17.458 +  SDL_Event event;
  17.459 +  event.dgesture.type = SDL_DOLLARGESTURE;
  17.460 +  event.dgesture.touchId = touch->id;
  17.461 +  /*
  17.462 +    //TODO: Add this to give location of gesture?
  17.463 +  event.mgesture.x = touch->centroid.x;
  17.464 +  event.mgesture.y = touch->centroid.y;
  17.465 +  */
  17.466 +  event.dgesture.gestureId = gestureId;
  17.467 +  event.dgesture.error = error;  
  17.468 +  //A finger came up to trigger this event.
  17.469 +  event.dgesture.numFingers = touch->numDownFingers + 1; 
  17.470 +  return SDL_PushEvent(&event) > 0;
  17.471 +}
  17.472 +
  17.473 +
  17.474 +int SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId) {
  17.475 +  SDL_Event event;
  17.476 +  event.dgesture.type = SDL_DOLLARRECORD;
  17.477 +  event.dgesture.touchId = touch->id;
  17.478 +  event.dgesture.gestureId = gestureId;
  17.479 +  return SDL_PushEvent(&event) > 0;
  17.480 +}
  17.481 +
  17.482 +
  17.483 +void SDL_GestureProcessEvent(SDL_Event* event)
  17.484 +{
  17.485 +  if(event->type == SDL_FINGERMOTION || 
  17.486 +     event->type == SDL_FINGERDOWN ||
  17.487 +     event->type == SDL_FINGERUP) {
  17.488 +    SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
  17.489 +    
  17.490 +    //Shouldn't be possible
  17.491 +    if(inTouch == NULL) return;
  17.492 +    
  17.493 +    //printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x,
  17.494 +    //	   (int)event->tfinger.y,
  17.495 +    //   (int)inTouch->res.x,(int)inTouch->res.y);
  17.496 +
  17.497 +    
  17.498 +    float x = ((float)event->tfinger.x)/(float)inTouch->res.x;
  17.499 +    float y = ((float)event->tfinger.y)/(float)inTouch->res.y;   
  17.500 +
  17.501 +
  17.502 +    //Finger Up
  17.503 +    if(event->type == SDL_FINGERUP) {
  17.504 +      inTouch->numDownFingers--;
  17.505 +      
  17.506 +#ifdef ENABLE_DOLLAR
  17.507 +      if(inTouch->recording) {
  17.508 +	inTouch->recording = SDL_FALSE;
  17.509 +	SDL_FloatPoint path[DOLLARNPOINTS];
  17.510 +	dollarNormalize(inTouch->dollarPath,path);
  17.511 +	//SDL_PrintPath(path);
  17.512 +	int index;
  17.513 +	if(recordAll) {
  17.514 +	  index = SDL_AddDollarGesture(NULL,path);
  17.515 +	  int i;
  17.516 +	  for(i = 0;i < SDL_numGestureTouches; i++)
  17.517 +	    SDL_gestureTouch[i].recording = SDL_FALSE;
  17.518 +	}
  17.519 +	else {
  17.520 +	  index = SDL_AddDollarGesture(inTouch,path);
  17.521 +	}
  17.522 +	
  17.523 +	if(index >= 0) {
  17.524 +	  SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
  17.525 +	}
  17.526 +	else {
  17.527 +	  SDL_SendDollarRecord(inTouch,-1);
  17.528 +	}
  17.529 +      }
  17.530 +      else {	
  17.531 +	int bestTempl;
  17.532 +	float error;
  17.533 +	error = dollarRecognize(inTouch->dollarPath,
  17.534 +				&bestTempl,inTouch);
  17.535 +	if(bestTempl >= 0){
  17.536 +	  //Send Event
  17.537 +	  unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
  17.538 +	  SDL_SendGestureDollar(inTouch,gestureId,error);
  17.539 +	  //printf ("%s\n",);("Dollar error: %f\n",error);
  17.540 +	}
  17.541 +      }
  17.542 +#endif 
  17.543 +      //inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
  17.544 +      if(inTouch->numDownFingers > 0) {
  17.545 +	inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
  17.546 +			       x)/inTouch->numDownFingers;
  17.547 +	inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
  17.548 +			       y)/inTouch->numDownFingers;
  17.549 +      }
  17.550 +    }
  17.551 +    else if(event->type == SDL_FINGERMOTION) {
  17.552 +      float dx = ((float)event->tfinger.dx)/(float)inTouch->res.x;
  17.553 +      float dy = ((float)event->tfinger.dy)/(float)inTouch->res.y;
  17.554 +      //printf("dx,dy: (%f,%f)\n",dx,dy); 
  17.555 +#ifdef ENABLE_DOLLAR
  17.556 +      SDL_DollarPath* path = &inTouch->dollarPath;
  17.557 +      if(path->numPoints < MAXPATHSIZE) {
  17.558 +	path->p[path->numPoints].x = inTouch->centroid.x;
  17.559 +	path->p[path->numPoints].y = inTouch->centroid.y;
  17.560 +	float pathDx = 
  17.561 +	  (path->p[path->numPoints].x-path->p[path->numPoints-1].x);
  17.562 +	float pathDy = 
  17.563 +	  (path->p[path->numPoints].y-path->p[path->numPoints-1].y);
  17.564 +	path->length += sqrt(pathDx*pathDx + pathDy*pathDy);
  17.565 +	path->numPoints++;
  17.566 +      }
  17.567 +#endif
  17.568 +      SDL_FloatPoint lastP;
  17.569 +      lastP.x = x - dx;
  17.570 +      lastP.y = y - dy;
  17.571 +      SDL_FloatPoint lastCentroid;
  17.572 +      lastCentroid = inTouch->centroid;
  17.573 +      
  17.574 +      inTouch->centroid.x += dx/inTouch->numDownFingers;
  17.575 +      inTouch->centroid.y += dy/inTouch->numDownFingers;
  17.576 +      //printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y);
  17.577 +      if(inTouch->numDownFingers > 1) {
  17.578 +	SDL_FloatPoint lv; //Vector from centroid to last x,y position
  17.579 +	SDL_FloatPoint v; //Vector from centroid to current x,y position
  17.580 +	//lv = inTouch->gestureLast[j].cv;
  17.581 +	lv.x = lastP.x - lastCentroid.x;
  17.582 +	lv.y = lastP.y - lastCentroid.y;
  17.583 +	float lDist = sqrt(lv.x*lv.x + lv.y*lv.y);
  17.584 +	//printf("lDist = %f\n",lDist);
  17.585 +	v.x = x - inTouch->centroid.x;
  17.586 +	v.y = y - inTouch->centroid.y;
  17.587 +	//inTouch->gestureLast[j].cv = v;
  17.588 +	float Dist = sqrt(v.x*v.x+v.y*v.y);
  17.589 +	// cos(dTheta) = (v . lv)/(|v| * |lv|)
  17.590 +	
  17.591 +	//Normalize Vectors to simplify angle calculation
  17.592 +	lv.x/=lDist;
  17.593 +	lv.y/=lDist;
  17.594 +	v.x/=Dist;
  17.595 +	v.y/=Dist;
  17.596 +	float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
  17.597 +	
  17.598 +	float dDist = (Dist - lDist);
  17.599 +	if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
  17.600 +	
  17.601 +	//inTouch->gestureLast[j].dDist = dDist;
  17.602 +	//inTouch->gestureLast[j].dtheta = dtheta;
  17.603 +	
  17.604 +	//printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
  17.605 +	//gdtheta = gdtheta*.9 + dtheta*.1;
  17.606 +	//gdDist  =  gdDist*.9 +  dDist*.1
  17.607 +	//knob.r += dDist/numDownFingers;
  17.608 +	//knob.ang += dtheta;
  17.609 +	//printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
  17.610 +	//printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
  17.611 +	SDL_SendGestureMulti(inTouch,dtheta,dDist);
  17.612 +      }
  17.613 +      else {
  17.614 +	//inTouch->gestureLast[j].dDist = 0;
  17.615 +	//inTouch->gestureLast[j].dtheta = 0;
  17.616 +	//inTouch->gestureLast[j].cv.x = 0;
  17.617 +	//inTouch->gestureLast[j].cv.y = 0;
  17.618 +      }
  17.619 +      //inTouch->gestureLast[j].f.p.x = x;
  17.620 +      //inTouch->gestureLast[j].f.p.y = y;
  17.621 +      //break;
  17.622 +      //pressure?
  17.623 +    }
  17.624 +    
  17.625 +    if(event->type == SDL_FINGERDOWN) {
  17.626 +
  17.627 +      inTouch->numDownFingers++;
  17.628 +      inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+ 
  17.629 +			     x)/inTouch->numDownFingers;
  17.630 +      inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
  17.631 +			     y)/inTouch->numDownFingers;
  17.632 +      //printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
  17.633 +      //     inTouch->centroid.x,inTouch->centroid.y);
  17.634 +
  17.635 +#ifdef ENABLE_DOLLAR
  17.636 +      inTouch->dollarPath.length = 0;
  17.637 +      inTouch->dollarPath.p[0].x = x;
  17.638 +      inTouch->dollarPath.p[0].y = y;
  17.639 +      inTouch->dollarPath.numPoints = 1;
  17.640 +#endif
  17.641 +    }
  17.642 +  }
  17.643 +}
  17.644 +
  17.645 +  /* vi: set ts=4 sw=4 expandtab: */
  17.646 +  
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/events/SDL_gesture_c.h	Sun Aug 22 12:07:55 2010 -0700
    18.3 @@ -0,0 +1,35 @@
    18.4 +/*
    18.5 +    SDL - Simple DirectMedia Layer
    18.6 +    Copyright (C) 1997-2010 Sam Lantinga
    18.7 +
    18.8 +    This library is free software; you can redistribute it and/or
    18.9 +    modify it under the terms of the GNU Lesser General Public
   18.10 +    License as published by the Free Software Foundation; either
   18.11 +    version 2.1 of the License, or (at your option) any later version.
   18.12 +
   18.13 +    This library is distributed in the hope that it will be useful,
   18.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18.16 +    Lesser General Public License for more details.
   18.17 +
   18.18 +    You should have received a copy of the GNU Lesser General Public
   18.19 +    License along with this library; if not, write to the Free Software
   18.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   18.21 +
   18.22 +    Sam Lantinga
   18.23 +    slouken@libsdl.org
   18.24 +*/
   18.25 +#include "SDL_config.h"
   18.26 +
   18.27 +#ifndef _SDL_gesture_c_h
   18.28 +#define _SDL_gesture_c_h
   18.29 +
   18.30 +extern void SDL_GestureProcessEvent(SDL_Event* event);
   18.31 +
   18.32 +extern int SDL_RecordGesture(SDL_TouchID touchId);
   18.33 +
   18.34 +extern int SDL_GestureAddTouch(SDL_Touch* touch);
   18.35 +
   18.36 +#endif /* _SDL_gesture_c_h */
   18.37 +
   18.38 +/* vi: set ts=4 sw=4 expandtab: */
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/events/SDL_touch.c	Sun Aug 22 12:07:55 2010 -0700
    19.3 @@ -0,0 +1,555 @@
    19.4 +/*
    19.5 +    SDL - Simple DirectMedia Layer
    19.6 +    Copyright (C) 1997-2010 Sam Lantinga
    19.7 +
    19.8 +    This library is free software; you can redistribute it and/or
    19.9 +    modify it under the terms of the GNU Lesser General Public
   19.10 +    License as published by the Free Software Foundation; either
   19.11 +    version 2.1 of the License, or (at your option) any later version.
   19.12 +
   19.13 +    This library is distributed in the hope that it will be useful,
   19.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   19.16 +    Lesser General Public License for more details.
   19.17 +
   19.18 +    You should have received a copy of the GNU Lesser General Public
   19.19 +    License along with this library; if not, write to the Free Software
   19.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   19.21 +
   19.22 +    Sam Lantinga
   19.23 +    slouken@libsdl.org
   19.24 +*/
   19.25 +#include "SDL_config.h"
   19.26 +
   19.27 +/* General touch handling code for SDL */
   19.28 +
   19.29 +#include "SDL_events.h"
   19.30 +#include "SDL_events_c.h"
   19.31 +#include "../video/SDL_sysvideo.h"
   19.32 +
   19.33 +#include <stdio.h>
   19.34 +
   19.35 +
   19.36 +static int SDL_num_touch = 0;
   19.37 +static SDL_Touch **SDL_touchPads = NULL;
   19.38 +
   19.39 +
   19.40 +/* Public functions */
   19.41 +int
   19.42 +SDL_TouchInit(void)
   19.43 +{
   19.44 +  return (0);
   19.45 +}
   19.46 +
   19.47 +SDL_Touch *
   19.48 +SDL_GetTouch(SDL_TouchID id)
   19.49 +{
   19.50 +    int index = SDL_GetTouchIndexId(id);
   19.51 +    if (index < 0 || index >= SDL_num_touch) {
   19.52 +        return NULL;
   19.53 +    }
   19.54 +    return SDL_touchPads[index];
   19.55 +}
   19.56 +
   19.57 +SDL_Touch *
   19.58 +SDL_GetTouchIndex(int index)
   19.59 +{
   19.60 +    if (index < 0 || index >= SDL_num_touch) {
   19.61 +        return NULL;
   19.62 +    }
   19.63 +    return SDL_touchPads[index];
   19.64 +}
   19.65 +
   19.66 +int
   19.67 +SDL_GetFingerIndexId(SDL_Touch* touch,SDL_FingerID fingerid)
   19.68 +{
   19.69 +    int i;
   19.70 +    for(i = 0;i < touch->num_fingers;i++)
   19.71 +	if(touch->fingers[i]->id == fingerid)
   19.72 +	    return i;
   19.73 +    return -1;
   19.74 +}
   19.75 +
   19.76 +
   19.77 +SDL_Finger *
   19.78 +SDL_GetFinger(SDL_Touch* touch,SDL_FingerID id)
   19.79 +{
   19.80 +    int index = SDL_GetFingerIndexId(touch,id);
   19.81 +    if(index < 0 || index >= touch->num_fingers)
   19.82 +	return NULL;
   19.83 +    return touch->fingers[index];
   19.84 +}
   19.85 +
   19.86 +
   19.87 +int
   19.88 +SDL_GetTouchIndexId(SDL_TouchID id)
   19.89 +{
   19.90 +    int index;
   19.91 +    SDL_Touch *touch;
   19.92 +
   19.93 +    for (index = 0; index < SDL_num_touch; ++index) {
   19.94 +        touch = SDL_touchPads[index];
   19.95 +        if (touch->id == id) {
   19.96 +            return index;
   19.97 +        }
   19.98 +    }
   19.99 +    return -1;
  19.100 +}
  19.101 +
  19.102 +int
  19.103 +SDL_AddTouch(const SDL_Touch * touch, char *name)
  19.104 +{
  19.105 +    SDL_Touch **touchPads;
  19.106 +    int index,length;
  19.107 +
  19.108 +    if (SDL_GetTouchIndexId(touch->id) != -1) {
  19.109 +        SDL_SetError("Touch ID already in use");
  19.110 +    }
  19.111 +
  19.112 +    /* Add the touch to the list of touch */
  19.113 +    touchPads = (SDL_Touch **) SDL_realloc(SDL_touchPads,
  19.114 +                                      (SDL_num_touch + 1) * sizeof(*touch));
  19.115 +    if (!touchPads) {
  19.116 +        SDL_OutOfMemory();
  19.117 +        return -1;
  19.118 +    }
  19.119 +
  19.120 +    SDL_touchPads = touchPads;
  19.121 +    index = SDL_num_touch++;
  19.122 +
  19.123 +    SDL_touchPads[index] = (SDL_Touch *) SDL_malloc(sizeof(*SDL_touchPads[index]));
  19.124 +    if (!SDL_touchPads[index]) {
  19.125 +        SDL_OutOfMemory();
  19.126 +        return -1;
  19.127 +    }
  19.128 +    *SDL_touchPads[index] = *touch;
  19.129 +
  19.130 +    /* we're setting the touch properties */
  19.131 +    length = 0;
  19.132 +    length = SDL_strlen(name);
  19.133 +    SDL_touchPads[index]->focus = 0;
  19.134 +    SDL_touchPads[index]->name = SDL_malloc((length + 2) * sizeof(char));
  19.135 +    SDL_strlcpy(SDL_touchPads[index]->name, name, length + 1);   
  19.136 +
  19.137 +    SDL_touchPads[index]->num_fingers = 0;
  19.138 +    SDL_touchPads[index]->max_fingers = 1;
  19.139 +    SDL_touchPads[index]->fingers = (SDL_Finger **) SDL_malloc(sizeof(SDL_Finger*));
  19.140 +    SDL_touchPads[index]->fingers[0] = NULL;
  19.141 +    SDL_touchPads[index]->buttonstate = 0;
  19.142 +    SDL_touchPads[index]->relative_mode = SDL_FALSE;
  19.143 +    SDL_touchPads[index]->flush_motion = SDL_FALSE;
  19.144 +    
  19.145 +    SDL_touchPads[index]->xres = (1<<(16-1));
  19.146 +    SDL_touchPads[index]->yres = (1<<(16-1));
  19.147 +    //Do I want this here? Probably
  19.148 +    SDL_GestureAddTouch(SDL_touchPads[index]);
  19.149 +
  19.150 +    return index;
  19.151 +}
  19.152 +
  19.153 +void
  19.154 +SDL_DelTouch(SDL_TouchID id)
  19.155 +{
  19.156 +    int index = SDL_GetTouchIndexId(id);
  19.157 +    SDL_Touch *touch = SDL_GetTouch(id);
  19.158 +
  19.159 +    if (!touch) {
  19.160 +        return;
  19.161 +    }
  19.162 +
  19.163 +    
  19.164 +    SDL_free(touch->name);
  19.165 + 
  19.166 +    if (touch->FreeTouch) {
  19.167 +        touch->FreeTouch(touch);
  19.168 +    }
  19.169 +    SDL_free(touch);
  19.170 +
  19.171 +    SDL_num_touch--;
  19.172 +    SDL_touchPads[index] = SDL_touchPads[SDL_num_touch];
  19.173 +}
  19.174 +
  19.175 +void
  19.176 +SDL_TouchQuit(void)
  19.177 +{
  19.178 +    int i;
  19.179 +
  19.180 +    for (i = SDL_num_touch-1; i > 0 ; --i) {
  19.181 +        SDL_DelTouch(i);
  19.182 +    }
  19.183 +    SDL_num_touch = 0;
  19.184 +
  19.185 +    if (SDL_touchPads) {
  19.186 +        SDL_free(SDL_touchPads);
  19.187 +        SDL_touchPads = NULL;
  19.188 +    }
  19.189 +}
  19.190 +
  19.191 +int
  19.192 +SDL_GetNumTouch(void)
  19.193 +{
  19.194 +    return SDL_num_touch;
  19.195 +}
  19.196 +SDL_Window *
  19.197 +SDL_GetTouchFocusWindow(SDL_TouchID id)
  19.198 +{
  19.199 +    SDL_Touch *touch = SDL_GetTouch(id);
  19.200 +
  19.201 +    if (!touch) {
  19.202 +        return 0;
  19.203 +    }
  19.204 +    return touch->focus;
  19.205 +}
  19.206 +
  19.207 +void
  19.208 +SDL_SetTouchFocus(SDL_TouchID id, SDL_Window * window)
  19.209 +{
  19.210 +    int index = SDL_GetTouchIndexId(id);
  19.211 +    SDL_Touch *touch = SDL_GetTouch(id);
  19.212 +    int i;
  19.213 +    SDL_bool focus;
  19.214 +
  19.215 +    if (!touch || (touch->focus == window)) {
  19.216 +        return;
  19.217 +    }
  19.218 +
  19.219 +    /* See if the current window has lost focus */
  19.220 +    if (touch->focus) {
  19.221 +        focus = SDL_FALSE;
  19.222 +        for (i = 0; i < SDL_num_touch; ++i) {
  19.223 +            SDL_Touch *check;
  19.224 +            if (i != index) {
  19.225 +                check = SDL_touchPads[i];
  19.226 +                if (check && check->focus == touch->focus) {
  19.227 +                    focus = SDL_TRUE;
  19.228 +                    break;
  19.229 +                }
  19.230 +            }
  19.231 +        }
  19.232 +        if (!focus) {
  19.233 +            SDL_SendWindowEvent(touch->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
  19.234 +        }
  19.235 +    }
  19.236 +
  19.237 +    touch->focus = window;
  19.238 +
  19.239 +    if (touch->focus) {
  19.240 +        focus = SDL_FALSE;
  19.241 +        for (i = 0; i < SDL_num_touch; ++i) {
  19.242 +            SDL_Touch *check;
  19.243 +            if (i != index) {
  19.244 +                check = SDL_touchPads[i];
  19.245 +                if (check && check->focus == touch->focus) {
  19.246 +                    focus = SDL_TRUE;
  19.247 +                    break;
  19.248 +                }
  19.249 +            }
  19.250 +        }
  19.251 +        if (!focus) {
  19.252 +            SDL_SendWindowEvent(touch->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
  19.253 +        }
  19.254 +    }
  19.255 +}
  19.256 +
  19.257 +int 
  19.258 +SDL_AddFinger(SDL_Touch* touch,SDL_Finger *finger)
  19.259 +{
  19.260 +    int index;
  19.261 +    SDL_Finger **fingers;
  19.262 +    //printf("Adding Finger...\n");
  19.263 +    if (SDL_GetFingerIndexId(touch,finger->id) != -1) {
  19.264 +        SDL_SetError("Finger ID already in use");
  19.265 +	}
  19.266 +
  19.267 +    /* Add the touch to the list of touch */
  19.268 +    if(touch->num_fingers  >= touch->max_fingers){
  19.269 +		//printf("Making room for it!\n");
  19.270 +		fingers = (SDL_Finger **) SDL_realloc(touch->fingers,
  19.271 +  						   (touch->num_fingers + 1) * sizeof(SDL_Finger *));
  19.272 +		touch->max_fingers = touch->num_fingers+1;
  19.273 +		if (!fingers) {
  19.274 +			SDL_OutOfMemory();
  19.275 +			return -1;
  19.276 +		} else {
  19.277 +			touch->max_fingers = touch->num_fingers+1;
  19.278 +			touch->fingers = fingers;
  19.279 +		}
  19.280 +	}
  19.281 +
  19.282 +    index = touch->num_fingers;
  19.283 +    //printf("Max_Fingers: %i Index: %i\n",touch->max_fingers,index);
  19.284 +
  19.285 +    touch->fingers[index] = (SDL_Finger *) SDL_malloc(sizeof(SDL_Finger));
  19.286 +    if (!touch->fingers[index]) {
  19.287 +        SDL_OutOfMemory();
  19.288 +        return -1;
  19.289 +    }
  19.290 +    *(touch->fingers[index]) = *finger;
  19.291 +    touch->num_fingers++;
  19.292 +
  19.293 +    return index;
  19.294 +}
  19.295 +
  19.296 +int
  19.297 +SDL_DelFinger(SDL_Touch* touch,SDL_FingerID fingerid)
  19.298 +{
  19.299 +    int index = SDL_GetFingerIndexId(touch,fingerid);
  19.300 +    SDL_Finger* finger = SDL_GetFinger(touch,fingerid);
  19.301 +
  19.302 +    if (!finger) {
  19.303 +        return -1;
  19.304 +    }
  19.305 + 
  19.306 +
  19.307 +    SDL_free(finger);
  19.308 +    touch->num_fingers--;
  19.309 +    touch->fingers[index] = touch->fingers[touch->num_fingers];
  19.310 +    return 0;
  19.311 +}
  19.312 +
  19.313 +
  19.314 +int
  19.315 +SDL_SendFingerDown(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, 
  19.316 +		   float xin, float yin, float pressurein)
  19.317 +{
  19.318 +    int posted;
  19.319 +    SDL_Touch* touch = SDL_GetTouch(id);
  19.320 +
  19.321 +    if(!touch) {
  19.322 +      return SDL_TouchNotFoundError(id);
  19.323 +    }
  19.324 +
  19.325 +    
  19.326 +    //scale to Integer coordinates
  19.327 +    Uint16 x = (xin+touch->x_min)*(touch->xres)/(touch->native_xres);
  19.328 +    Uint16 y = (yin+touch->y_min)*(touch->yres)/(touch->native_yres);
  19.329 +    Uint16 pressure = (yin+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres);
  19.330 +    
  19.331 +    SDL_Finger *finger = SDL_GetFinger(touch,fingerid);
  19.332 +    if(down) {
  19.333 +	if(finger == NULL) {
  19.334 +	    SDL_Finger nf;
  19.335 +	    nf.id = fingerid;
  19.336 +	    nf.x = x;
  19.337 +	    nf.y = y;
  19.338 +	    nf.pressure = pressure;
  19.339 +	    nf.xdelta = 0;
  19.340 +	    nf.ydelta = 0;
  19.341 +	    nf.last_x = x;
  19.342 +	    nf.last_y = y;
  19.343 +	    nf.last_pressure = pressure;
  19.344 +	    nf.down = SDL_FALSE;
  19.345 +	    if(SDL_AddFinger(touch,&nf) < 0) return 0;
  19.346 +	    finger = SDL_GetFinger(touch,fingerid);
  19.347 +	}
  19.348 +	else if(finger->down) return 0;
  19.349 +	if(xin < touch->x_min || yin < touch->y_min) return 0; //should defer if only a partial input
  19.350 +	posted = 0;
  19.351 +	if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
  19.352 +	    SDL_Event event;
  19.353 +	    event.tfinger.type = SDL_FINGERDOWN;
  19.354 +	    event.tfinger.touchId = id;
  19.355 +	    event.tfinger.x = x;
  19.356 +	    event.tfinger.y = y;
  19.357 +	    event.tfinger.pressure = pressure;
  19.358 +	    event.tfinger.state = touch->buttonstate;
  19.359 +	    event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
  19.360 +	    event.tfinger.fingerId = fingerid;
  19.361 +	    posted = (SDL_PushEvent(&event) > 0);
  19.362 +	}
  19.363 +	if(posted) finger->down = SDL_TRUE;
  19.364 +	return posted;
  19.365 +    }
  19.366 +    else {
  19.367 +        if(finger == NULL) {printf("Finger not found...\n");return 0;}      
  19.368 +	posted = 0;
  19.369 +	if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
  19.370 +	    SDL_Event event;
  19.371 +	    event.tfinger.type = SDL_FINGERUP;
  19.372 +	    event.tfinger.touchId =  id;
  19.373 +	    event.tfinger.state = touch->buttonstate;
  19.374 +	    event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
  19.375 +	    event.tfinger.fingerId = fingerid;
  19.376 +	    //I don't trust the coordinates passed on fingerUp
  19.377 +	    event.tfinger.x = finger->x; 
  19.378 +	    event.tfinger.y = finger->y;
  19.379 +	    event.tfinger.dx = 0;
  19.380 +	    event.tfinger.dy = 0;
  19.381 +
  19.382 +	    if(SDL_DelFinger(touch,fingerid) < 0) return 0;
  19.383 +	    posted = (SDL_PushEvent(&event) > 0);
  19.384 +	}	
  19.385 +	return posted;
  19.386 +    }
  19.387 +}
  19.388 +
  19.389 +int
  19.390 +SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, int relative, 
  19.391 +		    float xin, float yin, float pressurein)
  19.392 +{
  19.393 +    int index = SDL_GetTouchIndexId(id);
  19.394 +    SDL_Touch *touch = SDL_GetTouch(id);
  19.395 +    SDL_Finger *finger = SDL_GetFinger(touch,fingerid);
  19.396 +    int posted;
  19.397 +    Sint16 xrel, yrel;
  19.398 +    float x_max = 0, y_max = 0;
  19.399 +    
  19.400 +    if (!touch) {
  19.401 +      return SDL_TouchNotFoundError(id);
  19.402 +    }
  19.403 +
  19.404 +    //scale to Integer coordinates
  19.405 +    Uint16 x = (xin+touch->x_min)*(touch->xres)/(touch->native_xres);
  19.406 +    Uint16 y = (yin+touch->y_min)*(touch->yres)/(touch->native_yres);
  19.407 +    Uint16 pressure = (yin+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres);
  19.408 +    if(touch->flush_motion) {
  19.409 +	return 0;
  19.410 +    }
  19.411 +    
  19.412 +    if(finger == NULL || !finger->down) {
  19.413 +	return SDL_SendFingerDown(id,fingerid,SDL_TRUE,xin,yin,pressurein);	
  19.414 +    } else {
  19.415 +	/* the relative motion is calculated regarding the last position */
  19.416 +	if (relative) {
  19.417 +	    xrel = x;
  19.418 +	    yrel = y;
  19.419 +	    x = (finger->last_x + x);
  19.420 +	    y = (finger->last_y + y);
  19.421 +	} else {
  19.422 +	    if(xin < touch->x_min) x = finger->last_x; /*If movement is only in one axis,*/
  19.423 +	    if(yin < touch->y_min) y = finger->last_y; /*The other is marked as -1*/
  19.424 +	    if(pressurein < touch->pressure_min) pressure = finger->last_pressure;
  19.425 +	    xrel = x - finger->last_x;
  19.426 +	    yrel = y - finger->last_y;
  19.427 +	    //printf("xrel,yrel (%i,%i)\n",(int)xrel,(int)yrel);
  19.428 +	}
  19.429 +	
  19.430 +	/* Drop events that don't change state */
  19.431 +	if (!xrel && !yrel) {
  19.432 +#if 0
  19.433 +	    printf("Touch event didn't change state - dropped!\n");
  19.434 +#endif
  19.435 +	    return 0;
  19.436 +	}
  19.437 +	
  19.438 +	/* Update internal touch coordinates */
  19.439 +	
  19.440 +	finger->x = x;
  19.441 +	finger->y = y;
  19.442 +	
  19.443 +	/*Should scale to window? Normalize? Maintain Aspect?*/
  19.444 +	//SDL_GetWindowSize(touch->focus, &x_max, &y_max);
  19.445 +	
  19.446 +	/* make sure that the pointers find themselves inside the windows */
  19.447 +	/* only check if touch->xmax is set ! */
  19.448 +	/*
  19.449 +	  if (x_max && touch->x > x_max) {
  19.450 +	  touch->x = x_max;
  19.451 +	  } else if (touch->x < 0) {
  19.452 +	  touch->x = 0;
  19.453 +	  }
  19.454 +	  
  19.455 +	  if (y_max && touch->y > y_max) {
  19.456 +	  touch->y = y_max;
  19.457 +	  } else if (touch->y < 0) {
  19.458 +	  touch->y = 0;
  19.459 +	  }
  19.460 +	*/
  19.461 +	finger->xdelta = xrel;
  19.462 +	finger->ydelta = yrel;
  19.463 +	finger->pressure = pressure;
  19.464 +	
  19.465 +	
  19.466 +	
  19.467 +	/* Post the event, if desired */
  19.468 +	posted = 0;
  19.469 +	if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
  19.470 +	    SDL_Event event;
  19.471 +	    event.tfinger.type = SDL_FINGERMOTION;
  19.472 +	    event.tfinger.touchId = id;
  19.473 +	    event.tfinger.fingerId = fingerid;
  19.474 +	    event.tfinger.x = x;
  19.475 +	    event.tfinger.y = y;
  19.476 +	    event.tfinger.dx = xrel;
  19.477 +	    event.tfinger.dy = yrel;	    
  19.478 +		
  19.479 +	    event.tfinger.pressure = pressure;
  19.480 +	    event.tfinger.state = touch->buttonstate;
  19.481 +	    event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
  19.482 +	    posted = (SDL_PushEvent(&event) > 0);
  19.483 +	}
  19.484 +	finger->last_x = finger->x;
  19.485 +	finger->last_y = finger->y;
  19.486 +	finger->last_pressure = finger->pressure;
  19.487 +	return posted;
  19.488 +    }
  19.489 +}
  19.490 +int
  19.491 +SDL_SendTouchButton(SDL_TouchID id, Uint8 state, Uint8 button)
  19.492 +{
  19.493 +    SDL_Touch *touch = SDL_GetTouch(id);
  19.494 +    int posted;
  19.495 +    Uint32 type;
  19.496 +
  19.497 +    
  19.498 +    if (!touch) {
  19.499 +      return SDL_TouchNotFoundError(id);
  19.500 +    }
  19.501 +
  19.502 +    /* Figure out which event to perform */
  19.503 +    switch (state) {
  19.504 +    case SDL_PRESSED:
  19.505 +        if (touch->buttonstate & SDL_BUTTON(button)) {
  19.506 +            /* Ignore this event, no state change */
  19.507 +            return 0;
  19.508 +        }
  19.509 +        type = SDL_TOUCHBUTTONDOWN;
  19.510 +        touch->buttonstate |= SDL_BUTTON(button);
  19.511 +        break;
  19.512 +    case SDL_RELEASED:
  19.513 +        if (!(touch->buttonstate & SDL_BUTTON(button))) {
  19.514 +            /* Ignore this event, no state change */
  19.515 +            return 0;
  19.516 +        }
  19.517 +        type = SDL_TOUCHBUTTONUP;
  19.518 +        touch->buttonstate &= ~SDL_BUTTON(button);
  19.519 +        break;
  19.520 +    default:
  19.521 +        /* Invalid state -- bail */
  19.522 +        return 0;
  19.523 +    }
  19.524 +
  19.525 +    /* Post the event, if desired */
  19.526 +    posted = 0;
  19.527 +    if (SDL_GetEventState(type) == SDL_ENABLE) {
  19.528 +        SDL_Event event;
  19.529 +        event.type = type;
  19.530 +        event.tbutton.touchId = touch->id;
  19.531 +        event.tbutton.state = state;
  19.532 +        event.tbutton.button = button;
  19.533 +        event.tbutton.windowID = touch->focus ? touch->focus->id : 0;
  19.534 +        posted = (SDL_PushEvent(&event) > 0);
  19.535 +    }
  19.536 +    return posted;
  19.537 +}
  19.538 +
  19.539 +char *
  19.540 +SDL_GetTouchName(SDL_TouchID id)
  19.541 +{
  19.542 +    SDL_Touch *touch = SDL_GetTouch(id);
  19.543 +    if (!touch) {
  19.544 +        return NULL;
  19.545 +    }
  19.546 +    return touch->name;
  19.547 +}
  19.548 +
  19.549 +int SDL_TouchNotFoundError(SDL_TouchID id) {
  19.550 +  printf("ERROR: Cannot send touch on non-existent device with id: %li make sure SDL_AddTouch has been called\n",id);
  19.551 +  printf("ERROR: There are %i touches installed with Id's:\n",SDL_num_touch);
  19.552 +  int i;
  19.553 +  for(i=0;i < SDL_num_touch;i++) {
  19.554 +    printf("ERROR: %li\n",SDL_touchPads[i]->id);
  19.555 +  }
  19.556 +  return 0;
  19.557 +}
  19.558 +/* vi: set ts=4 sw=4 expandtab: */
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/events/SDL_touch_c.h	Sun Aug 22 12:07:55 2010 -0700
    20.3 @@ -0,0 +1,79 @@
    20.4 +/*
    20.5 +    SDL - Simple DirectMedia Layer
    20.6 +    Copyright (C) 1997-2010 Sam Lantinga
    20.7 +
    20.8 +    This library is free software; you can redistribute it and/or
    20.9 +    modify it under the terms of the GNU Lesser General Public
   20.10 +    License as published by the Free Software Foundation; either
   20.11 +    version 2.1 of the License, or (at your option) any later version.
   20.12 +
   20.13 +    This library is distributed in the hope that it will be useful,
   20.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   20.16 +    Lesser General Public License for more details.
   20.17 +
   20.18 +    You should have received a copy of the GNU Lesser General Public
   20.19 +    License along with this library; if not, write to the Free Software
   20.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   20.21 +
   20.22 +    Sam Lantinga
   20.23 +    slouken@libsdl.org
   20.24 +*/
   20.25 +#include "SDL_config.h"
   20.26 +#include "../../include/SDL_touch.h"
   20.27 +
   20.28 +#ifndef _SDL_touch_c_h
   20.29 +#define _SDL_touch_c_h
   20.30 +
   20.31 +
   20.32 +
   20.33 +/* Initialize the touch subsystem */
   20.34 +extern int SDL_TouchInit(void);
   20.35 +
   20.36 +/*Get the touch at an index */
   20.37 +extern SDL_Touch *SDL_GetTouchIndex(int index);
   20.38 +
   20.39 +/* Get the touch with id = id */
   20.40 +extern SDL_Touch *SDL_GetTouch(SDL_TouchID id);
   20.41 +
   20.42 +/*Get the finger at an index */
   20.43 +extern SDL_Finger *SDL_GetFingerIndex(SDL_Touch *touch, int index);
   20.44 +
   20.45 +/* Get the finger with id = id */
   20.46 +extern SDL_Finger *SDL_GetFinger(SDL_Touch *touch,SDL_FingerID id);
   20.47 +
   20.48 +
   20.49 +/* Add a touch, possibly reattaching at a particular index (or -1),
   20.50 +   returning the index of the touch, or -1 if there was an error. */
   20.51 +extern int SDL_AddTouch(const SDL_Touch * touch, char *name);
   20.52 +                     
   20.53 +
   20.54 +/* Remove a touch at an index, clearing the slot for later */
   20.55 +extern void SDL_DelTouch(SDL_TouchID id);
   20.56 +
   20.57 +/* Set the touch focus window */
   20.58 +extern void SDL_SetTouchFocus(SDL_TouchID id, SDL_Window * window);
   20.59 +
   20.60 +/* Send a touch motion event for a touch */
   20.61 +extern int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
   20.62 +			       int relative, float x, float y, float z);
   20.63 +
   20.64 +/* Send a touch down/up event for a touch */
   20.65 +extern int SDL_SendFingerDown(SDL_TouchID id, SDL_FingerID fingerid, 
   20.66 +			      SDL_bool down, float x, float y, float pressure);
   20.67 +
   20.68 +/* Send a touch button event for a touch */
   20.69 +extern int SDL_SendTouchButton(SDL_TouchID id, Uint8 state, Uint8 button);
   20.70 +
   20.71 +/* Shutdown the touch subsystem */
   20.72 +extern void SDL_TouchQuit(void);
   20.73 +
   20.74 +/* Get the index of a touch device */
   20.75 +extern int SDL_GetTouchIndexId(SDL_TouchID id);
   20.76 +
   20.77 +/* Print a debug message for a nonexistent touch */
   20.78 +extern int SDL_TouchNotFoundError(SDL_TouchID id);
   20.79 +
   20.80 +#endif /* _SDL_touch_c_h */
   20.81 +
   20.82 +/* vi: set ts=4 sw=4 expandtab: */
    21.1 --- a/src/video/cocoa/SDL_cocoaevents.m	Sun Aug 22 11:56:07 2010 -0700
    21.2 +++ b/src/video/cocoa/SDL_cocoaevents.m	Sun Aug 22 12:07:55 2010 -0700
    21.3 @@ -192,6 +192,9 @@
    21.4          if ( event == nil ) {
    21.5              break;
    21.6          }
    21.7 +		
    21.8 +	//printf("Type: %i, Subtype: %i\n",[event type],[event subtype]);
    21.9 +		
   21.10          switch ([event type]) {
   21.11          case NSLeftMouseDown:
   21.12          case NSOtherMouseDown:
   21.13 @@ -203,6 +206,7 @@
   21.14          case NSRightMouseDragged:
   21.15          case NSOtherMouseDragged: /* usually middle mouse dragged */
   21.16          case NSMouseMoved:
   21.17 +	  printf("Mouse Type: %i, Subtype: %i\n",[event type],[event subtype]);
   21.18              Cocoa_HandleMouseEvent(_this, event);
   21.19              /* Pass through to NSApp to make sure everything stays in sync */
   21.20              [NSApp sendEvent:event];
   21.21 @@ -217,6 +221,8 @@
   21.22              if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged)
   21.23                 [NSApp sendEvent: event];
   21.24              break;
   21.25 +	case NSTabletPoint:
   21.26 +	  printf("Tablet Event Received\n");
   21.27          default:
   21.28              [NSApp sendEvent:event];
   21.29              break;
    22.1 --- a/src/video/cocoa/SDL_cocoawindow.h	Sun Aug 22 11:56:07 2010 -0700
    22.2 +++ b/src/video/cocoa/SDL_cocoawindow.h	Sun Aug 22 12:07:55 2010 -0700
    22.3 @@ -64,6 +64,20 @@
    22.4  -(void) rightMouseDragged:(NSEvent *) theEvent;
    22.5  -(void) otherMouseDragged:(NSEvent *) theEvent;
    22.6  -(void) scrollWheel:(NSEvent *) theEvent;
    22.7 +-(void) touchesBeganWithEvent:(NSEvent *) theEvent;
    22.8 +-(void) touchesMovedWithEvent:(NSEvent *) theEvent;
    22.9 +-(void) touchesEndedWithEvent:(NSEvent *) theEvent;
   22.10 +-(void) touchesCancelledWithEvent:(NSEvent *) theEvent;
   22.11 +
   22.12 +/* Touch event handling */
   22.13 +typedef enum {
   22.14 +    COCOA_TOUCH_DOWN,
   22.15 +    COCOA_TOUCH_UP,
   22.16 +    COCOA_TOUCH_MOVE,
   22.17 +    COCOA_TOUCH_CANCELLED
   22.18 +} cocoaTouchType;
   22.19 +-(void) handleTouches:(cocoaTouchType)type withEvent:(NSEvent*) event;
   22.20 +
   22.21  @end
   22.22  /* *INDENT-ON* */
   22.23  
    23.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Sun Aug 22 11:56:07 2010 -0700
    23.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Sun Aug 22 12:07:55 2010 -0700
    23.3 @@ -25,8 +25,8 @@
    23.4  #include "../SDL_sysvideo.h"
    23.5  #include "../../events/SDL_keyboard_c.h"
    23.6  #include "../../events/SDL_mouse_c.h"
    23.7 +#include "../../events/SDL_touch_c.h"
    23.8  #include "../../events/SDL_windowevents_c.h"
    23.9 -
   23.10  #include "SDL_cocoavideo.h"
   23.11  
   23.12  static __inline__ void ConvertNSRect(NSRect *r)
   23.13 @@ -60,6 +60,7 @@
   23.14      [center addObserver:self selector:@selector(windowDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp];
   23.15  
   23.16      [_data->nswindow setAcceptsMouseMovedEvents:YES];
   23.17 +    [[_data->nswindow contentView] setAcceptsTouchEvents:YES];
   23.18  }
   23.19  
   23.20  - (void)close
   23.21 @@ -268,6 +269,91 @@
   23.22      SDL_SendMouseWheel(_data->window, (int)x, (int)y);
   23.23  }
   23.24  
   23.25 +- (void)touchesBeganWithEvent:(NSEvent *) theEvent
   23.26 +{
   23.27 +    [self handleTouches:COCOA_TOUCH_DOWN withEvent:theEvent];
   23.28 +}
   23.29 +
   23.30 +- (void)touchesMovedWithEvent:(NSEvent *) theEvent
   23.31 +{
   23.32 +    [self handleTouches:COCOA_TOUCH_MOVE withEvent:theEvent];
   23.33 +}
   23.34 +
   23.35 +- (void)touchesEndedWithEvent:(NSEvent *) theEvent
   23.36 +{
   23.37 +    [self handleTouches:COCOA_TOUCH_UP withEvent:theEvent];
   23.38 +}
   23.39 +
   23.40 +- (void)touchesCancelledWithEvent:(NSEvent *) theEvent
   23.41 +{
   23.42 +    [self handleTouches:COCOA_TOUCH_CANCELLED withEvent:theEvent];
   23.43 +}
   23.44 +
   23.45 +- (void)handleTouches:(cocoaTouchType)type withEvent:(NSEvent *)event
   23.46 +{
   23.47 +    NSSet *touches = 0;
   23.48 +    NSEnumerator *enumerator;
   23.49 +    NSTouch *touch;
   23.50 +
   23.51 +    switch (type) {
   23.52 +        case COCOA_TOUCH_DOWN:
   23.53 +            touches = [event touchesMatchingPhase:NSTouchPhaseBegan inView:nil];
   23.54 +            break;
   23.55 +        case COCOA_TOUCH_UP:
   23.56 +        case COCOA_TOUCH_CANCELLED:
   23.57 +            touches = [event touchesMatchingPhase:NSTouchPhaseEnded inView:nil];
   23.58 +            break;
   23.59 +        case COCOA_TOUCH_MOVE:
   23.60 +            touches = [event touchesMatchingPhase:NSTouchPhaseMoved inView:nil];
   23.61 +            break;
   23.62 +    }
   23.63 +
   23.64 +    enumerator = [touches objectEnumerator];
   23.65 +    touch = (NSTouch*)[enumerator nextObject];
   23.66 +    while (touch) {
   23.67 +        SDL_TouchID touchId = (SDL_TouchID)[touch device];
   23.68 +        if (!SDL_GetTouch(touchId)) {
   23.69 +            SDL_Touch touch;
   23.70 +
   23.71 +            touch.id = touchId;
   23.72 +            touch.x_min = 0;
   23.73 +            touch.x_max = 1;
   23.74 +            touch.native_xres = touch.x_max - touch.x_min;
   23.75 +            touch.y_min = 0;
   23.76 +            touch.y_max = 1;
   23.77 +            touch.native_yres = touch.y_max - touch.y_min;
   23.78 +            touch.pressure_min = 0;
   23.79 +            touch.pressure_max = 1;
   23.80 +            touch.native_pressureres = touch.pressure_max - touch.pressure_min;
   23.81 +            
   23.82 +            if (SDL_AddTouch(&touch, "") < 0) {
   23.83 +                return;
   23.84 +            }
   23.85 +        } 
   23.86 +
   23.87 +        SDL_FingerID fingerId = (SDL_FingerID)[touch identity];
   23.88 +        float x = [touch normalizedPosition].x;
   23.89 +        float y = [touch normalizedPosition].y;
   23.90 +	/* Make the origin the upper left instead of the lower left */
   23.91 +	y = 1.0f - y;
   23.92 +
   23.93 +        switch (type) {
   23.94 +        case COCOA_TOUCH_DOWN:
   23.95 +            SDL_SendFingerDown(touchId, fingerId, SDL_TRUE, x, y, 1);
   23.96 +            break;
   23.97 +        case COCOA_TOUCH_UP:
   23.98 +        case COCOA_TOUCH_CANCELLED:
   23.99 +            SDL_SendFingerDown(touchId, fingerId, SDL_FALSE, x, y, 1);
  23.100 +            break;
  23.101 +        case COCOA_TOUCH_MOVE:
  23.102 +            SDL_SendTouchMotion(touchId, fingerId, SDL_FALSE, x, y, 1);
  23.103 +            break;
  23.104 +        }
  23.105 +        
  23.106 +        touch = (NSTouch*)[enumerator nextObject];
  23.107 +    }
  23.108 +}
  23.109 +
  23.110  @end
  23.111  
  23.112  @interface SDLWindow : NSWindow
    24.1 --- a/src/video/uikit/SDL_uikitview.h	Sun Aug 22 11:56:07 2010 -0700
    24.2 +++ b/src/video/uikit/SDL_uikitview.h	Sun Aug 22 12:07:55 2010 -0700
    24.3 @@ -13,8 +13,7 @@
    24.4      Lesser General Public License for more details.
    24.5  
    24.6      You should have received a copy of the GNU Lesser General Public
    24.7 -    License along with this library; if not, write to the Free Software
    24.8 -    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    24.9 +    License along with this library; if not, write to the Free Software    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   24.10  
   24.11      Sam Lantinga
   24.12      slouken@libsdl.org
   24.13 @@ -24,10 +23,11 @@
   24.14  #include "SDL_stdinc.h"
   24.15  #include "SDL_events.h"
   24.16  
   24.17 -#if SDL_IPHONE_MULTIPLE_MICE
   24.18 +#define IPHONE_TOUCH_EFFICIENT_DANGEROUS
   24.19 +#define FIXED_MULTITOUCH
   24.20 +
   24.21 +#ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS
   24.22  #define MAX_SIMULTANEOUS_TOUCHES 5
   24.23 -#else
   24.24 -#define MAX_SIMULTANEOUS_TOUCHES 1
   24.25  #endif
   24.26  
   24.27  /* *INDENT-OFF* */
   24.28 @@ -37,8 +37,11 @@
   24.29  @interface SDL_uikitview : UIView {
   24.30  #endif
   24.31  
   24.32 -#if FIXME_MULTITOUCH
   24.33 -	SDL_Mouse mice[MAX_SIMULTANEOUS_TOUCHES];
   24.34 +#ifdef FIXED_MULTITOUCH
   24.35 +	long touchId;
   24.36 +#ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS
   24.37 +	UITouch *finger[MAX_SIMULTANEOUS_TOUCHES];
   24.38 +#endif
   24.39  #endif
   24.40  
   24.41  #if SDL_IPHONE_KEYBOARD
    25.1 --- a/src/video/uikit/SDL_uikitview.m	Sun Aug 22 11:56:07 2010 -0700
    25.2 +++ b/src/video/uikit/SDL_uikitview.m	Sun Aug 22 12:07:55 2010 -0700
    25.3 @@ -24,6 +24,7 @@
    25.4  
    25.5  #include "../../events/SDL_keyboard_c.h"
    25.6  #include "../../events/SDL_mouse_c.h"
    25.7 +#include "../../events/SDL_touch_c.h"
    25.8  
    25.9  #if SDL_IPHONE_KEYBOARD
   25.10  #import "keyinfotable.h"
   25.11 @@ -48,16 +49,27 @@
   25.12  	[self initializeKeyboard];
   25.13  #endif	
   25.14  
   25.15 -#if FIXME_MULTITOUCH
   25.16 -	int i;
   25.17 -	for (i=0; i<MAX_SIMULTANEOUS_TOUCHES; i++) {
   25.18 -        mice[i].id = i;
   25.19 -		mice[i].driverdata = NULL;
   25.20 -		SDL_AddMouse(&mice[i], "Mouse", 0, 0, 1);
   25.21 -	}
   25.22 -	self.multipleTouchEnabled = YES;
   25.23 +#ifdef FIXED_MULTITOUCH
   25.24 +	SDL_Touch touch;
   25.25 +	touch.id = 0; //TODO: Should be -1?
   25.26 +
   25.27 +	//touch.driverdata = SDL_malloc(sizeof(EventTouchData));
   25.28 +	//EventTouchData* data = (EventTouchData*)(touch.driverdata);
   25.29 +	
   25.30 +	touch.x_min = 0;
   25.31 +	touch.x_max = frame.size.width;
   25.32 +	touch.native_xres = touch.x_max - touch.x_min;
   25.33 +	touch.y_min = 0;
   25.34 +	touch.y_max = frame.size.height;
   25.35 +	touch.native_yres = touch.y_max - touch.y_min;
   25.36 +	touch.pressure_min = 0;
   25.37 +	touch.pressure_max = 1;
   25.38 +	touch.native_pressureres = touch.pressure_max - touch.pressure_min;
   25.39 +
   25.40 +
   25.41 +	touchId = SDL_AddTouch(&touch, "IPHONE SCREEN");
   25.42  #endif
   25.43 -			
   25.44 +
   25.45  	return self;
   25.46  
   25.47  }
   25.48 @@ -67,48 +79,8 @@
   25.49  	NSEnumerator *enumerator = [touches objectEnumerator];
   25.50  	UITouch *touch = (UITouch*)[enumerator nextObject];
   25.51  	
   25.52 -#if FIXME_MULTITOUCH
   25.53 -	/* associate touches with mice, so long as we have slots */
   25.54 -	int i;
   25.55 -	int found = 0;
   25.56 -	for(i=0; touch && i < MAX_SIMULTANEOUS_TOUCHES; i++) {
   25.57 +	//NSLog("Click");
   25.58  	
   25.59 -		/* check if this mouse is already tracking a touch */
   25.60 -		if (mice[i].driverdata != NULL) {
   25.61 -			continue;
   25.62 -		}
   25.63 -		/*	
   25.64 -			mouse not associated with anything right now,
   25.65 -			associate the touch with this mouse
   25.66 -		*/
   25.67 -		found = 1;
   25.68 -		
   25.69 -		/* save old mouse so we can switch back */
   25.70 -		int oldMouse = SDL_SelectMouse(-1);
   25.71 -		
   25.72 -		/* select this slot's mouse */
   25.73 -		SDL_SelectMouse(i);
   25.74 -		CGPoint locationInView = [touch locationInView: self];
   25.75 -		
   25.76 -		/* set driver data to touch object, we'll use touch object later */
   25.77 -		mice[i].driverdata = [touch retain];
   25.78 -		
   25.79 -		/* send moved event */
   25.80 -		SDL_SendMouseMotion(i, 0, locationInView.x, locationInView.y, 0);
   25.81 -		
   25.82 -		/* send mouse down event */
   25.83 -		SDL_SendMouseButton(i, SDL_PRESSED, SDL_BUTTON_LEFT);
   25.84 -		
   25.85 -		/* re-calibrate relative mouse motion */
   25.86 -		SDL_GetRelativeMouseState(i, NULL, NULL);
   25.87 -		
   25.88 -		/* switch back to our old mouse */
   25.89 -		SDL_SelectMouse(oldMouse);
   25.90 -		
   25.91 -		/* grab next touch */
   25.92 -		touch = (UITouch*)[enumerator nextObject]; 
   25.93 -	}
   25.94 -#else
   25.95  	if (touch) {
   25.96  		CGPoint locationInView = [touch locationInView: self];
   25.97  			
   25.98 @@ -118,6 +90,37 @@
   25.99  		/* send mouse down event */
  25.100  		SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT);
  25.101  	}
  25.102 +
  25.103 +#ifdef FIXED_MULTITOUCH
  25.104 +	while(touch) {
  25.105 +	  CGPoint locationInView = [touch locationInView: self];
  25.106 +
  25.107 +
  25.108 +#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
  25.109 +	  //FIXME: TODO: Using touch as the fingerId is potentially dangerous
  25.110 +	  //It is also much more efficient than storing the UITouch pointer
  25.111 +	  //and comparing it to the incoming event.
  25.112 +	  SDL_SendFingerDown(touchId,(long)touch,
  25.113 +			     SDL_TRUE,locationInView.x,locationInView.y,
  25.114 +			     1);
  25.115 +#else
  25.116 +	  int i;
  25.117 +	  for(i = 0;i < MAX_SIMULTANEOUS_TOUCHES;i++) {
  25.118 +	    if(finger[i] == NULL) {
  25.119 +	      finger[i] = touch;
  25.120 +	      SDL_SendFingerDown(touchId,i,
  25.121 +				 SDL_TRUE,locationInView.x,locationInView.y,
  25.122 +				 1);
  25.123 +	      break;
  25.124 +	    }
  25.125 +	  }
  25.126 +#endif
  25.127 +	  
  25.128 +
  25.129 +	  
  25.130 +
  25.131 +	  touch = (UITouch*)[enumerator nextObject]; 
  25.132 +	}
  25.133  #endif
  25.134  }
  25.135  
  25.136 @@ -126,30 +129,34 @@
  25.137  	NSEnumerator *enumerator = [touches objectEnumerator];
  25.138  	UITouch *touch = (UITouch*)[enumerator nextObject];
  25.139  	
  25.140 -#if FIXME_MULTITOUCH
  25.141 -	while(touch) {
  25.142 -		/* search for the mouse slot associated with this touch */
  25.143 -		int i, found = NO;
  25.144 -		for (i=0; i<MAX_SIMULTANEOUS_TOUCHES && !found; i++) {
  25.145 -			if (mice[i].driverdata == touch) {
  25.146 -				/* found the mouse associate with the touch */
  25.147 -				[(UITouch*)(mice[i].driverdata) release];
  25.148 -				mice[i].driverdata = NULL;
  25.149 -				/* send mouse up */
  25.150 -				SDL_SendMouseButton(i, SDL_RELEASED, SDL_BUTTON_LEFT);
  25.151 -				/* discontinue search for this touch */
  25.152 -				found = YES;
  25.153 -			}
  25.154 -		}
  25.155 -		
  25.156 -		/* grab next touch */
  25.157 -		touch = (UITouch*)[enumerator nextObject]; 
  25.158 -	}
  25.159 -#else
  25.160  	if (touch) {
  25.161  		/* send mouse up */
  25.162  		SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT);
  25.163  	}
  25.164 +
  25.165 +#ifdef FIXED_MULTITOUCH
  25.166 +	while(touch) {
  25.167 +	  CGPoint locationInView = [touch locationInView: self];
  25.168 +	  
  25.169 +
  25.170 +#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
  25.171 +	  SDL_SendFingerDown(touchId,(long)touch,
  25.172 +			     SDL_FALSE,locationInView.x,locationInView.y,
  25.173 +			     1);
  25.174 +#else
  25.175 +	  int i;
  25.176 +	  for(i = 0;i < MAX_SIMULTANEOUS_TOUCHES;i++) {
  25.177 +	    if(finger[i] == touch) {
  25.178 +	      SDL_SendFingerDown(touchId,i,
  25.179 +				 SDL_FALSE,locationInView.x,locationInView.y,
  25.180 +				 1);
  25.181 +	      break;
  25.182 +	    }
  25.183 +	  }
  25.184 +#endif
  25.185 +
  25.186 +	  touch = (UITouch*)[enumerator nextObject]; 
  25.187 +	}
  25.188  #endif
  25.189  }
  25.190  
  25.191 @@ -167,31 +174,36 @@
  25.192  	NSEnumerator *enumerator = [touches objectEnumerator];
  25.193  	UITouch *touch = (UITouch*)[enumerator nextObject];
  25.194  	
  25.195 -#if FIXME_MULTITOUCH
  25.196 -	while(touch) {
  25.197 -		/* try to find the mouse associated with this touch */
  25.198 -		int i, found = NO;
  25.199 -		for (i=0; i<MAX_SIMULTANEOUS_TOUCHES && !found; i++) {
  25.200 -			if (mice[i].driverdata == touch) {
  25.201 -				/* found proper mouse */
  25.202 -				CGPoint locationInView = [touch locationInView: self];
  25.203 -				/* send moved event */
  25.204 -				SDL_SendMouseMotion(i, 0, locationInView.x, locationInView.y, 0);
  25.205 -				/* discontinue search */
  25.206 -				found = YES;
  25.207 -			}
  25.208 -		}
  25.209 -		
  25.210 -		/* grab next touch */
  25.211 -		touch = (UITouch*)[enumerator nextObject]; 
  25.212 -	}
  25.213 -#else
  25.214  	if (touch) {
  25.215  		CGPoint locationInView = [touch locationInView: self];
  25.216  
  25.217  		/* send moved event */
  25.218  		SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y);
  25.219  	}
  25.220 +
  25.221 +#ifdef FIXED_MULTITOUCH
  25.222 +	while(touch) {
  25.223 +	  CGPoint locationInView = [touch locationInView: self];
  25.224 +	  
  25.225 +
  25.226 +#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
  25.227 +	  SDL_SendTouchMotion(touchId,(long)touch,
  25.228 +			      SDL_FALSE,locationInView.x,locationInView.y,
  25.229 +			      1);
  25.230 +#else
  25.231 +	  int i;
  25.232 +	  for(i = 0;i < MAX_SIMULTANEOUS_TOUCHES;i++) {
  25.233 +	    if(finger[i] == touch) {
  25.234 +	      SDL_SendTouchMotion(touchId,i,
  25.235 +				  SDL_FALSE,locationInView.x,locationInView.y,
  25.236 +				  1);
  25.237 +	      break;
  25.238 +	    }
  25.239 +	  }
  25.240 +#endif
  25.241 +
  25.242 +	  touch = (UITouch*)[enumerator nextObject]; 
  25.243 +	}
  25.244  #endif
  25.245  }
  25.246  
    26.1 --- a/src/video/win32/SDL_win32events.c	Sun Aug 22 11:56:07 2010 -0700
    26.2 +++ b/src/video/win32/SDL_win32events.c	Sun Aug 22 12:07:55 2010 -0700
    26.3 @@ -20,9 +20,9 @@
    26.4      slouken@libsdl.org
    26.5  */
    26.6  
    26.7 -#if (_WIN32_WINNT < 0x0501)
    26.8 +#if (_WIN32_WINNT < 0x601)
    26.9  #undef _WIN32_WINNT
   26.10 -#define _WIN32_WINNT 0x0501
   26.11 +#define _WIN32_WINNT 0x601
   26.12  #endif
   26.13  
   26.14  #include "SDL_config.h"
   26.15 @@ -32,11 +32,14 @@
   26.16  #include "SDL_vkeys.h"
   26.17  #include "../../events/SDL_events_c.h"
   26.18  
   26.19 -/*#define WMMSG_DEBUG*/
   26.20 +
   26.21 +
   26.22 +#define WMMSG_DEBUG
   26.23  #ifdef WMMSG_DEBUG
   26.24 -#include <stdio.h>
   26.25 +#include <stdio.h>	
   26.26  #include "wmmsg.h"
   26.27  #endif
   26.28 +//#include <stdio.h>
   26.29  
   26.30  /* Masks for processing the windows KEYDOWN and KEYUP messages */
   26.31  #define REPEATED_KEYMASK    (1<<30)
   26.32 @@ -121,9 +124,10 @@
   26.33      if (!data) {
   26.34          return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
   26.35      }
   26.36 +
   26.37  #ifdef WMMSG_DEBUG
   26.38 -    {
   26.39 -        FILE *log = fopen("wmmsg.txt", "a");
   26.40 +    {		
   26.41 +        FILE *log = fopen("wmmsg.txt", "a");		
   26.42          fprintf(log, "Received windows message: %p ", hwnd);
   26.43          if (msg > MAX_WMMSG) {
   26.44              fprintf(log, "%d", msg);
   26.45 @@ -509,7 +513,39 @@
   26.46          }
   26.47          returnCode = 0;
   26.48          break;
   26.49 -    }
   26.50 +	case WM_TOUCH:
   26.51 +		{
   26.52 +			//printf("Got Touch Event!\n");
   26.53 +    
   26.54 +			FILE *log = fopen("wmmsg.txt", "a");
   26.55 +			fprintf(log, "Received Touch Message: %p ", hwnd);
   26.56 +			if (msg > MAX_WMMSG) {
   26.57 +				fprintf(log, "%d", msg);
   26.58 +			} else {
   26.59 +				fprintf(log, "%s", wmtab[msg]);
   26.60 +			}
   26.61 +			fprintf(log, "WM_TOUCH = %d -- 0x%X, 0x%X\n",msg, wParam, lParam);
   26.62 +			fclose(log);
   26.63 +    
   26.64 +		}
   26.65 +		break;
   26.66 +	case WM_GESTURE:
   26.67 +		{
   26.68 +			//printf("Got Touch Event!\n");
   26.69 +    
   26.70 +			FILE *log = fopen("wmmsg.txt", "a");
   26.71 +			fprintf(log, "Received Gesture Message: %p ", hwnd);
   26.72 +			if (msg > MAX_WMMSG) {
   26.73 +				fprintf(log, "%d", msg);
   26.74 +			} else {
   26.75 +				fprintf(log, "%s", wmtab[msg]);
   26.76 +			}
   26.77 +			fprintf(log, "WM_GESTURE = %d -- 0x%X, 0x%X\n",msg, wParam, lParam);
   26.78 +			fclose(log);
   26.79 +    
   26.80 +		}
   26.81 +		break;		
   26.82 +	}
   26.83  
   26.84      /* If there's a window proc, assume it's going to handle messages */
   26.85      if (data->wndproc) {
    27.1 --- a/src/video/win32/SDL_win32video.h	Sun Aug 22 11:56:07 2010 -0700
    27.2 +++ b/src/video/win32/SDL_win32video.h	Sun Aug 22 12:07:55 2010 -0700
    27.3 @@ -32,7 +32,14 @@
    27.4  #define UNICODE
    27.5  #endif
    27.6  #undef WINVER
    27.7 -#define WINVER  0x500           /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */
    27.8 +//#define WINVER  0x500           /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */
    27.9 +#define WINVER 0x601  /* Need 0x600 (_WIN32_WINNT_WIN7) for WM_Touch */
   27.10 +#if (_WIN32_WINNT < 0x601)
   27.11 +#undef _WIN32_WINNT
   27.12 +#define _WIN32_WINNT 0x601
   27.13 +#endif
   27.14 +
   27.15 +
   27.16  #include <windows.h>
   27.17  
   27.18  #if SDL_VIDEO_RENDER_D3D
    28.1 --- a/src/video/win32/SDL_win32window.c	Sun Aug 22 11:56:07 2010 -0700
    28.2 +++ b/src/video/win32/SDL_win32window.c	Sun Aug 22 12:07:55 2010 -0700
    28.3 @@ -218,6 +218,7 @@
    28.4          WIN_SetError("Couldn't create window");
    28.5          return -1;
    28.6      }
    28.7 +	//RegisterTouchWindow(hwnd, 0);
    28.8  
    28.9      WIN_PumpEvents(_this);
   28.10  
    29.1 --- a/src/video/win32/wmmsg.h	Sun Aug 22 11:56:07 2010 -0700
    29.2 +++ b/src/video/win32/wmmsg.h	Sun Aug 22 12:07:55 2010 -0700
    29.3 @@ -283,7 +283,7 @@
    29.4      "WM_INITMENU",
    29.5      "WM_INITMENUPOPUP",
    29.6      "UNKNOWN (280)",
    29.7 -    "UNKNOWN (281)",
    29.8 +    "WM_GESTURE",
    29.9      "UNKNOWN (282)",
   29.10      "UNKNOWN (283)",
   29.11      "UNKNOWN (284)",
   29.12 @@ -578,7 +578,7 @@
   29.13      "UNKNOWN (573)",
   29.14      "UNKNOWN (574)",
   29.15      "UNKNOWN (575)",
   29.16 -    "UNKNOWN (576)",
   29.17 +    "WM_TOUCH",
   29.18      "UNKNOWN (577)",
   29.19      "UNKNOWN (578)",
   29.20      "UNKNOWN (579)",
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/src/video/x11/SDL_eventtouch.c	Sun Aug 22 12:07:55 2010 -0700
    30.3 @@ -0,0 +1,128 @@
    30.4 +/*
    30.5 +    SDL - Simple DirectMedia Layer
    30.6 +    Copyright (C) 1997-2010 Sam Lantinga
    30.7 +
    30.8 +    This library is free software; you can redistribute it and/or
    30.9 +    modify it under the terms of the GNU Lesser General Public
   30.10 +    License as published by the Free Software Foundation; either
   30.11 +    version 2.1 of the License, or (at your option) any later version.
   30.12 +
   30.13 +    This library is distributed in the hope that it will be useful,
   30.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   30.16 +    Lesser General Public License for more details.
   30.17 +
   30.18 +    You should have received a copy of the GNU Lesser General Public
   30.19 +    License along with this library; if not, write to the Free Software
   30.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   30.21 +
   30.22 +    Sam Lantinga
   30.23 +    slouken@libsdl.org
   30.24 +*/
   30.25 +#include "SDL_config.h"
   30.26 +#include "SDL_x11video.h"
   30.27 +#include "SDL_eventtouch.h"
   30.28 +#include "../../events/SDL_touch_c.h"
   30.29 +
   30.30 +
   30.31 +#ifdef SDL_INPUT_LINUXEV
   30.32 +#include <linux/input.h>
   30.33 +#include <fcntl.h>
   30.34 +#endif
   30.35 +
   30.36 +void
   30.37 +X11_InitTouch(_THIS)
   30.38 +{
   30.39 +#ifdef SDL_INPUT_LINUXEV
   30.40 +  printf("Initializing touch...\n");
   30.41 +
   30.42 +  FILE *fd;
   30.43 +  fd = fopen("/proc/bus/input/devices","r");
   30.44 +  
   30.45 +  char c;
   30.46 +  int i = 0;
   30.47 +  char line[256];
   30.48 +  char tstr[256];
   30.49 +  int vendor = -1,product = -1,event = -1;
   30.50 +  while(!feof(fd)) {
   30.51 +    if(fgets(line,256,fd) <=0) continue;
   30.52 +    //printf("%s",line);
   30.53 +    if(line[0] == '\n') {
   30.54 +      if(vendor == 1386){
   30.55 +	printf("Wacom... Assuming it is a touch device\n");
   30.56 +	sprintf(tstr,"/dev/input/event%i",event);
   30.57 +	printf("At location: %s\n",tstr);
   30.58 +
   30.59 +	SDL_Touch touch;
   30.60 +	touch.pressure_max = 0;
   30.61 +	touch.pressure_min = 0;
   30.62 +	touch.id = event; 
   30.63 +	
   30.64 +
   30.65 +	touch.driverdata = SDL_malloc(sizeof(EventTouchData));
   30.66 +	EventTouchData* data = (EventTouchData*)(touch.driverdata);
   30.67 +
   30.68 +	data->x = -1;
   30.69 +	data->y = -1;
   30.70 +	data->pressure = -1;
   30.71 +	data->finger = 0;
   30.72 +	data->up = SDL_FALSE;
   30.73 +	
   30.74 +
   30.75 +	printf("Opening device...\n");
   30.76 +	//printf("New Touch - DataPtr: %i\n",data);
   30.77 +	data->eventStream = open(tstr, 
   30.78 +				 O_RDONLY | O_NONBLOCK);
   30.79 +	ioctl (data->eventStream, EVIOCGNAME (sizeof (tstr)), tstr);
   30.80 +	printf ("Reading From : %s\n", tstr);
   30.81 +
   30.82 +
   30.83 +
   30.84 +	int abs[5];
   30.85 +	ioctl(data->eventStream,EVIOCGABS(0),abs);	
   30.86 +	touch.x_min = abs[1];
   30.87 +	touch.x_max = abs[2];
   30.88 +	touch.native_xres = touch.x_max - touch.x_min;
   30.89 +	ioctl(data->eventStream,EVIOCGABS(ABS_Y),abs);	
   30.90 +	touch.y_min = abs[1];
   30.91 +	touch.y_max = abs[2];
   30.92 +	touch.native_yres = touch.y_max - touch.y_min;
   30.93 +	ioctl(data->eventStream,EVIOCGABS(ABS_PRESSURE),abs);	
   30.94 +	touch.pressure_min = abs[1];
   30.95 +	touch.pressure_max = abs[2];
   30.96 +	touch.native_pressureres = touch.pressure_max - touch.pressure_min;
   30.97 +
   30.98 +	SDL_AddTouch(&touch, tstr);
   30.99 +      }
  30.100 +      vendor = -1;
  30.101 +      product = -1;
  30.102 +      event = -1;      
  30.103 +    }
  30.104 +    else if(line[0] == 'I') {
  30.105 +      i = 1;
  30.106 +      while(line[i]) {
  30.107 +	sscanf(&line[i],"Vendor=%x",&vendor);
  30.108 +	sscanf(&line[i],"Product=%x",&product);
  30.109 +	i++;
  30.110 +      }
  30.111 +    }
  30.112 +    else if(line[0] == 'H') {
  30.113 +      i = 1;
  30.114 +      while(line[i]) {
  30.115 +	sscanf(&line[i],"event%d",&event);
  30.116 +	i++;
  30.117 +      }
  30.118 +    }
  30.119 +  }
  30.120 +  
  30.121 +  close(fd);
  30.122 +#endif
  30.123 +}
  30.124 +
  30.125 +void
  30.126 +X11_QuitTouch(_THIS)
  30.127 +{
  30.128 +    SDL_TouchQuit();
  30.129 +}
  30.130 +
  30.131 +/* vi: set ts=4 sw=4 expandtab: */
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/src/video/x11/SDL_eventtouch.h	Sun Aug 22 12:07:55 2010 -0700
    31.3 @@ -0,0 +1,43 @@
    31.4 +/*
    31.5 +    SDL - Simple DirectMedia Layer
    31.6 +    Copyright (C) 1997-2010 Sam Lantinga
    31.7 +
    31.8 +    This library is free software; you can redistribute it and/or
    31.9 +    modify it under the terms of the GNU Lesser General Public
   31.10 +    License as published by the Free Software Foundation; either
   31.11 +    version 2.1 of the License, or (at your option) any later version.
   31.12 +
   31.13 +    This library is distributed in the hope that it will be useful,
   31.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   31.16 +    Lesser General Public License for more details.
   31.17 +
   31.18 +    You should have received a copy of the GNU Lesser General Public
   31.19 +    License along with this library; if not, write to the Free Software
   31.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   31.21 +
   31.22 +    Sam Lantinga
   31.23 +    slouken@libsdl.org
   31.24 +*/
   31.25 +#include "SDL_config.h"
   31.26 +
   31.27 +#ifndef _SDL_eventtouch_h
   31.28 +#define _SDL_eventtouch_h
   31.29 +
   31.30 +
   31.31 +//What should this be?
   31.32 +#if SDL_VIDEO_DRIVER_X11_XINPUT
   31.33 +typedef struct EventTouchData
   31.34 +{
   31.35 +    int x,y,pressure,finger; //Temporary Variables until sync
   31.36 +    int eventStream;
   31.37 +    SDL_bool up;
   31.38 +} EventTouchData;
   31.39 +#endif
   31.40 +
   31.41 +extern void X11_InitTouch(_THIS);
   31.42 +extern void X11_QuitTouch(_THIS);
   31.43 +
   31.44 +#endif /* _SDL_eventtouch_h */
   31.45 +
   31.46 +/* vi: set ts=4 sw=4 expandtab: */
    32.1 --- a/src/video/x11/SDL_x11events.c	Sun Aug 22 11:56:07 2010 -0700
    32.2 +++ b/src/video/x11/SDL_x11events.c	Sun Aug 22 12:07:55 2010 -0700
    32.3 @@ -30,10 +30,18 @@
    32.4  #include "SDL_x11video.h"
    32.5  #include "../../events/SDL_events_c.h"
    32.6  #include "../../events/SDL_mouse_c.h"
    32.7 +#include "../../events/SDL_touch_c.h"
    32.8  
    32.9  #include "SDL_timer.h"
   32.10  #include "SDL_syswm.h"
   32.11  
   32.12 +#include <stdio.h>
   32.13 +
   32.14 +#ifdef SDL_INPUT_LINUXEV
   32.15 +//Touch Input/event* includes
   32.16 +#include <linux/input.h>
   32.17 +#include <fcntl.h>
   32.18 +#endif
   32.19  /*#define DEBUG_XEVENTS*/
   32.20  
   32.21  /* Check to see if this is a repeated key.
   32.22 @@ -121,7 +129,6 @@
   32.23              SDL_SetMouseFocus(data->window);
   32.24          }
   32.25          break;
   32.26 -
   32.27          /* Losing mouse coverage? */
   32.28      case LeaveNotify:{
   32.29  #ifdef DEBUG_XEVENTS
   32.30 @@ -495,6 +502,79 @@
   32.31      while (X11_Pending(data->display)) {
   32.32          X11_DispatchEvent(_this);
   32.33      }
   32.34 +
   32.35 +#ifdef SDL_INPUT_LINUXEV
   32.36 +    /* Process Touch events - TODO When X gets touch support, use that instead*/
   32.37 +    int i = 0,rd;
   32.38 +    char name[256];
   32.39 +    struct input_event ev[64];
   32.40 +    int size = sizeof (struct input_event);
   32.41 +
   32.42 +    for(i = 0;i < SDL_GetNumTouch();++i) {
   32.43 +	SDL_Touch* touch = SDL_GetTouchIndex(i);
   32.44 +	if(!touch) printf("Touch %i/%i DNE\n",i,SDL_GetNumTouch());
   32.45 +	EventTouchData* data;
   32.46 +	data = (EventTouchData*)(touch->driverdata);
   32.47 +	if(data == NULL) {
   32.48 +	  printf("No driver data\n");
   32.49 +	  continue;
   32.50 +	}
   32.51 +	if(data->eventStream <= 0) 
   32.52 +	    printf("Error: Couldn't open stream\n");
   32.53 +	rd = read(data->eventStream, ev, size * 64);
   32.54 +	//printf("Got %i/%i bytes\n",rd,size);
   32.55 +	if(rd >= size) {
   32.56 +	    for (i = 0; i < rd / sizeof(struct input_event); i++) {
   32.57 +		switch (ev[i].type) {
   32.58 +		case EV_ABS:
   32.59 +		    //printf("Got position x: %i!\n",data->x);
   32.60 +		    switch (ev[i].code) {
   32.61 +			case ABS_X:
   32.62 +			    data->x = ev[i].value;
   32.63 +			    break;
   32.64 +			case ABS_Y:
   32.65 +			    data->y = ev[i].value;
   32.66 +			    break;
   32.67 +			case ABS_PRESSURE:
   32.68 +			    data->pressure = ev[i].value;
   32.69 +			    if(data->pressure < 0) data->pressure = 0;
   32.70 +			    break;
   32.71 +			case ABS_MISC:
   32.72 +			    if(ev[i].value == 0)
   32.73 +			        data->up = SDL_TRUE;			    
   32.74 +			    break;
   32.75 +			}
   32.76 +		    break;
   32.77 +		case EV_MSC:
   32.78 +		    if(ev[i].code == MSC_SERIAL)
   32.79 +			data->finger = ev[i].value;
   32.80 +		    break;
   32.81 +		case EV_SYN:
   32.82 +		  //printf("Id: %i\n",touch->id); 
   32.83 +		  if(data->up) {
   32.84 +		      SDL_SendFingerDown(touch->id,data->finger,
   32.85 +			  	       SDL_FALSE,data->x,data->y,
   32.86 +				       data->pressure);		    
   32.87 +		  }
   32.88 +		  else if(data->x >= 0 || data->y >= 0)
   32.89 +		    SDL_SendTouchMotion(touch->id,data->finger, 
   32.90 +					SDL_FALSE,data->x,data->y,
   32.91 +					data->pressure);
   32.92 +		  
   32.93 +		    //printf("Synched: %i tx: %i, ty: %i\n",
   32.94 +		    //	   data->finger,data->x,data->y);
   32.95 +		  data->x = -1;
   32.96 +		  data->y = -1;
   32.97 +		  data->pressure = -1;
   32.98 +		  data->finger = 0;
   32.99 +		  data->up = SDL_FALSE;
  32.100 +		    
  32.101 +		  break;		
  32.102 +		}
  32.103 +	    }
  32.104 +	}
  32.105 +    }
  32.106 +#endif
  32.107  }
  32.108  
  32.109  /* This is so wrong it hurts */
    33.1 --- a/src/video/x11/SDL_x11video.c	Sun Aug 22 11:56:07 2010 -0700
    33.2 +++ b/src/video/x11/SDL_x11video.c	Sun Aug 22 12:07:55 2010 -0700
    33.3 @@ -25,6 +25,7 @@
    33.4  
    33.5  #include "SDL_video.h"
    33.6  #include "SDL_mouse.h"
    33.7 +#include "SDL_eventtouch.h" 
    33.8  #include "../SDL_sysvideo.h"
    33.9  #include "../SDL_pixels_c.h"
   33.10  
   33.11 @@ -354,6 +355,7 @@
   33.12      }
   33.13      X11_InitMouse(_this);
   33.14  
   33.15 +    X11_InitTouch(_this);
   33.16      return 0;
   33.17  }
   33.18  
   33.19 @@ -374,6 +376,7 @@
   33.20      X11_QuitModes(_this);
   33.21      X11_QuitKeyboard(_this);
   33.22      X11_QuitMouse(_this);
   33.23 +    X11_QuitTouch(_this);
   33.24  }
   33.25  
   33.26  SDL_bool
    34.1 --- a/src/video/x11/SDL_x11video.h	Sun Aug 22 11:56:07 2010 -0700
    34.2 +++ b/src/video/x11/SDL_x11video.h	Sun Aug 22 12:07:55 2010 -0700
    34.3 @@ -62,6 +62,7 @@
    34.4  #include "SDL_x11keyboard.h"
    34.5  #include "SDL_x11modes.h"
    34.6  #include "SDL_x11mouse.h"
    34.7 +#include "SDL_eventtouch.h"
    34.8  #include "SDL_x11opengl.h"
    34.9  #include "SDL_x11window.h"
   34.10  
    35.1 --- a/test/Makefile.in	Sun Aug 22 11:56:07 2010 -0700
    35.2 +++ b/test/Makefile.in	Sun Aug 22 12:07:55 2010 -0700
    35.3 @@ -7,7 +7,7 @@
    35.4  CFLAGS  = @CFLAGS@
    35.5  LIBS	= @LIBS@
    35.6  
    35.7 -TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testatomic$(EXE) testaudioinfo$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcursor$(EXE) testdraw2$(EXE) testdyngles$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testfill$(EXE) testgamma$(EXE) testgl2$(EXE) testgles$(EXE) testgl$(EXE) testhaptic$(EXE) testhread$(EXE) testiconv$(EXE) testime$(EXE) testintersections$(EXE) testjoystick$(EXE) testkeys$(EXE) testloadso$(EXE) testlock$(EXE) testmultiaudio$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testpower$(EXE) testresample$(EXE) testsem$(EXE) testsprite2$(EXE) testsprite$(EXE) testspriteminimal$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm2$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE)
    35.8 +TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testatomic$(EXE) testaudioinfo$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcursor$(EXE) testdraw2$(EXE) testdyngles$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testfill$(EXE) testgamma$(EXE) testgl2$(EXE) testgles$(EXE) testgl$(EXE) testhaptic$(EXE) testhread$(EXE) testiconv$(EXE) testime$(EXE) testintersections$(EXE) testjoystick$(EXE) testkeys$(EXE) testloadso$(EXE) testlock$(EXE) testmultiaudio$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testpower$(EXE) testresample$(EXE) testsem$(EXE) testsprite2$(EXE) testsprite$(EXE) testspriteminimal$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm2$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE) testgesture$(EXE)
    35.9  
   35.10  all: Makefile $(TARGETS)
   35.11  
   35.12 @@ -151,6 +151,9 @@
   35.13  
   35.14  testatomic$(EXE): $(srcdir)/testatomic.c
   35.15  	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
   35.16 +
   35.17 +testgesture$(EXE): $(srcdir)/testgesture.c
   35.18 +	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
   35.19   
   35.20  testime$(EXE): $(srcdir)/testime.c
   35.21  	$(CC) -o $@ $? $(CFLAGS) $(LIBS) @SDL_TTF_LIB@
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/test/testgesture.c	Sun Aug 22 12:07:55 2010 -0700
    36.3 @@ -0,0 +1,297 @@
    36.4 +/*  Usage:
    36.5 + *  Spacebar to begin recording a gesture on all touches.
    36.6 + *  s to save all touches into "./gestureSave"
    36.7 + *  l to load all touches from "./gestureSave"
    36.8 + */
    36.9 +
   36.10 +#include <stdio.h>
   36.11 +#include <SDL.h>
   36.12 +#include <math.h>
   36.13 +#include <SDL_touch.h>
   36.14 +#include <SDL_gesture.h>
   36.15 +
   36.16 +
   36.17 +/* Make sure we have good macros for printing 32 and 64 bit values */
   36.18 +#ifndef PRIs32
   36.19 +#define PRIs32 "d"
   36.20 +#endif
   36.21 +#ifndef PRIu32
   36.22 +#define PRIu32 "u"
   36.23 +#endif
   36.24 +#ifndef PRIs64
   36.25 +#ifdef __WIN32__
   36.26 +#define PRIs64 "I64"
   36.27 +#else
   36.28 +#define PRIs64 "lld"
   36.29 +#endif
   36.30 +#endif
   36.31 +#ifndef PRIu64
   36.32 +#ifdef __WIN32__
   36.33 +#define PRIu64 "I64u"
   36.34 +#else
   36.35 +#define PRIu64 "llu"
   36.36 +#endif
   36.37 +#endif
   36.38 +
   36.39 +#define WIDTH 640
   36.40 +#define HEIGHT 480
   36.41 +#define BPP 4
   36.42 +#define DEPTH 32
   36.43 +
   36.44 +//MUST BE A POWER OF 2!
   36.45 +#define EVENT_BUF_SIZE 256
   36.46 +
   36.47 +
   36.48 +#define VERBOSE SDL_FALSE
   36.49 +
   36.50 +SDL_Event events[EVENT_BUF_SIZE];
   36.51 +int eventWrite;
   36.52 +
   36.53 +int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
   36.54 +
   36.55 +typedef struct {
   36.56 +  float x,y;
   36.57 +} Point;
   36.58 +
   36.59 +typedef struct {
   36.60 +  float ang,r;
   36.61 +  Point p;
   36.62 +} Knob;
   36.63 +
   36.64 +Knob knob;
   36.65 +
   36.66 +void handler (int sig)
   36.67 +{
   36.68 +  printf ("\exiting...(%d)\n", sig);
   36.69 +  exit (0);
   36.70 +}
   36.71 +
   36.72 +void perror_exit (char *error)
   36.73 +{
   36.74 +  perror (error);
   36.75 +  handler (9);
   36.76 +}
   36.77 +
   36.78 +void setpix(SDL_Surface *screen, int x, int y, unsigned int col)
   36.79 +{
   36.80 +  Uint32 *pixmem32;
   36.81 +  Uint32 colour;
   36.82 +  
   36.83 +  if((unsigned)x > screen->w) return;
   36.84 +  if((unsigned)y > screen->h) return;
   36.85 +
   36.86 +  pixmem32 = (Uint32*) screen->pixels  + y*screen->pitch/BPP + x;
   36.87 +  
   36.88 +  Uint8 r,g,b;
   36.89 +  float a;
   36.90 +  
   36.91 +  memcpy(&colour,pixmem32,screen->format->BytesPerPixel);
   36.92 +
   36.93 +  SDL_GetRGB(colour,screen->format,&r,&g,&b);
   36.94 +  //r = 0;g = 0; b = 0;
   36.95 +  a = (col>>24)&0xFF;
   36.96 +  if(a == 0) a = 0xFF; //Hack, to make things easier.
   36.97 +  a /= 0xFF;
   36.98 +  r = r*(1-a) + ((col>>16)&0xFF)*(a);
   36.99 +  g = g*(1-a) + ((col>> 8)&0xFF)*(a);
  36.100 +  b = b*(1-a) + ((col>> 0)&0xFF)*(a);
  36.101 +  colour = SDL_MapRGB( screen->format,r, g, b);
  36.102 +  
  36.103 +
  36.104 +  *pixmem32 = colour;
  36.105 +}
  36.106 +
  36.107 +void drawLine(SDL_Surface *screen,int x0,int y0,int x1,int y1,unsigned int col) {
  36.108 +  float t;
  36.109 +  for(t=0;t<1;t+=1.f/SDL_max(abs(x0-x1),abs(y0-y1)))
  36.110 +    setpix(screen,x1+t*(x0-x1),y1+t*(y0-y1),col);
  36.111 +}
  36.112 +
  36.113 +void drawCircle(SDL_Surface* screen,int x,int y,int r,unsigned int c)
  36.114 +{
  36.115 +  int tx,ty;
  36.116 +  float xr;
  36.117 +  for(ty = -abs(r);ty <= abs(r);ty++) {
  36.118 +    xr = sqrt(r*r - ty*ty);
  36.119 +    if(r > 0) { //r > 0 ==> filled circle
  36.120 +      for(tx=-xr+.5;tx<=xr-.5;tx++) {
  36.121 +	setpix(screen,x+tx,y+ty,c);
  36.122 +      }
  36.123 +    }
  36.124 +    else {
  36.125 +      setpix(screen,x-xr+.5,y+ty,c);
  36.126 +      setpix(screen,x+xr-.5,y+ty,c);
  36.127 +    }
  36.128 +  }
  36.129 +}
  36.130 +
  36.131 +void drawKnob(SDL_Surface* screen,Knob k) {
  36.132 +  drawCircle(screen,k.p.x*screen->w,k.p.y*screen->h,k.r*screen->w,0xFFFFFF);  
  36.133 +  drawCircle(screen,(k.p.x+k.r/2*cos(k.ang))*screen->w,
  36.134 +  	            (k.p.y+k.r/2*sin(k.ang))*screen->h,k.r/4*screen->w,0);
  36.135 +}
  36.136 +
  36.137 +void DrawScreen(SDL_Surface* screen)
  36.138 +{
  36.139 +  int x, y;
  36.140 +  if(SDL_MUSTLOCK(screen))
  36.141 +    {                                              
  36.142 +      if(SDL_LockSurface(screen) < 0) return;
  36.143 +    }
  36.144 +  for(y = 0;y < screen->h;y++)
  36.145 +    for(x = 0;x < screen->w;x++)
  36.146 +	setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
  36.147 +
  36.148 +  int i;
  36.149 +  //draw Touch History
  36.150 +  for(i = SDL_max(0,eventWrite - EVENT_BUF_SIZE);i < eventWrite;i++) {
  36.151 +    SDL_Event event = events[i&(EVENT_BUF_SIZE-1)];
  36.152 +    int age = eventWrite - i - 1;
  36.153 +    if(event.type == SDL_FINGERMOTION || 
  36.154 +       event.type == SDL_FINGERDOWN ||
  36.155 +       event.type == SDL_FINGERUP) {
  36.156 +      SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
  36.157 +      if(inTouch == NULL) continue;
  36.158 +
  36.159 +      float x = ((float)event.tfinger.x)/inTouch->xres;
  36.160 +      float y = ((float)event.tfinger.y)/inTouch->yres;      
  36.161 +      
  36.162 +      //draw the touch:      
  36.163 +      unsigned int c = colors[event.tfinger.touchId%7]; 
  36.164 +      unsigned int col = 
  36.165 +	((unsigned int)(c*(.1+.85))) |
  36.166 +	((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24;
  36.167 +
  36.168 +      if(event.type == SDL_FINGERMOTION)
  36.169 +	drawCircle(screen,x*screen->w,y*screen->h,5,col);
  36.170 +      else if(event.type == SDL_FINGERDOWN)
  36.171 +	drawCircle(screen,x*screen->w,y*screen->h,-10,col);     
  36.172 +    }
  36.173 +  }
  36.174 +  
  36.175 +  if(knob.p.x > 0)
  36.176 +    drawKnob(screen,knob);
  36.177 +  
  36.178 +  if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
  36.179 +  SDL_Flip(screen);
  36.180 +}
  36.181 +
  36.182 +SDL_Surface* initScreen(int width,int height)
  36.183 +{
  36.184 +  return SDL_SetVideoMode(width, height, DEPTH,
  36.185 +			  SDL_HWSURFACE | SDL_RESIZABLE);
  36.186 +}
  36.187 +
  36.188 +int main(int argc, char* argv[])
  36.189 +{  
  36.190 +  SDL_Surface *screen;
  36.191 +  SDL_Event event;
  36.192 +
  36.193 +  //gesture variables
  36.194 +  knob.r = .1;
  36.195 +  knob.ang = 0;
  36.196 +
  36.197 +  
  36.198 +  SDL_bool quitting = SDL_FALSE;
  36.199 +  SDL_RWops *src;
  36.200 +
  36.201 +  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
  36.202 +  
  36.203 +  if (!(screen = initScreen(WIDTH,HEIGHT)))
  36.204 +    {
  36.205 +      SDL_Quit();
  36.206 +      return 1;
  36.207 +    }
  36.208 +
  36.209 +  while(!quitting) {
  36.210 +    while(SDL_PollEvent(&event)) 
  36.211 +      {
  36.212 +	//Record _all_ events
  36.213 +	events[eventWrite & (EVENT_BUF_SIZE-1)] = event;
  36.214 +	eventWrite++;
  36.215 +	
  36.216 +	switch (event.type) 
  36.217 +	  {
  36.218 +	  case SDL_QUIT:
  36.219 +	    quitting = SDL_TRUE;
  36.220 +	    break;
  36.221 +	  case SDL_KEYDOWN:
  36.222 +	    switch (event.key.keysym.sym)
  36.223 +	      {
  36.224 +	      case SDLK_SPACE:
  36.225 +		SDL_RecordGesture(-1);
  36.226 +		break;
  36.227 +	      case SDLK_s:
  36.228 +		src = SDL_RWFromFile("gestureSave","w");
  36.229 +		printf("Wrote %i templates\n",SDL_SaveAllDollarTemplates(src));
  36.230 +		SDL_RWclose(src);
  36.231 +		break;
  36.232 +	      case SDLK_l:
  36.233 +		src = SDL_RWFromFile("gestureSave","r");
  36.234 +		printf("Loaded: %i\n",SDL_LoadDollarTemplates(-1,src));
  36.235 +		SDL_RWclose(src);
  36.236 +		break;
  36.237 +	      case SDLK_ESCAPE:
  36.238 +		quitting = SDL_TRUE;
  36.239 +		break;
  36.240 +	    }
  36.241 +	    break;
  36.242 +	  case SDL_VIDEORESIZE:
  36.243 +	    if (!(screen = initScreen(event.resize.w,
  36.244 +				      event.resize.h)))
  36.245 +	      {
  36.246 +		SDL_Quit();
  36.247 +		return 1;
  36.248 +	      }
  36.249 +	    break;
  36.250 +	  case SDL_FINGERMOTION:    
  36.251 +	    ;
  36.252 +#if VERBOSE
  36.253 +	    printf("Finger: %i,x: %i, y: %i\n",event.tfinger.fingerId,
  36.254 +	    	   event.tfinger.x,event.tfinger.y);
  36.255 +#endif
  36.256 +	    SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
  36.257 +	    SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId);
  36.258 +	    break;	    
  36.259 +	  case SDL_FINGERDOWN:
  36.260 +#if VERBOSE
  36.261 +	    printf("Finger: %"PRIs64" down - x: %i, y: %i\n",
  36.262 +		   event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
  36.263 +#endif
  36.264 +	    break;
  36.265 +	  case SDL_FINGERUP:
  36.266 +#if VERBOSE
  36.267 +	    printf("Finger: %"PRIs64" up - x: %i, y: %i\n",
  36.268 +	    	   event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
  36.269 +#endif
  36.270 +	    break;
  36.271 +	  case SDL_MULTIGESTURE:
  36.272 +#if VERBOSE	    
  36.273 +	    printf("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f\n",
  36.274 +		   event.mgesture.x,
  36.275 +		   event.mgesture.y,
  36.276 +		   event.mgesture.dTheta,
  36.277 +		   event.mgesture.dDist);
  36.278 +	    printf("MG: numDownTouch = %i\n",event.mgesture.numFingers);
  36.279 +#endif
  36.280 +	    knob.p.x = event.mgesture.x;
  36.281 +	    knob.p.y = event.mgesture.y;
  36.282 +	    knob.ang += event.mgesture.dTheta;
  36.283 +	    knob.r += event.mgesture.dDist;
  36.284 +	    break;
  36.285 +	  case SDL_DOLLARGESTURE:
  36.286 +	    printf("Gesture %"PRIs64" performed, error: %f\n",
  36.287 +		   event.dgesture.gestureId,
  36.288 +		   event.dgesture.error);
  36.289 +	    break;
  36.290 +	  case SDL_DOLLARRECORD:
  36.291 +	    printf("Recorded gesture: %"PRIs64"\n",event.dgesture.gestureId);
  36.292 +	    break;
  36.293 +	  }
  36.294 +      }
  36.295 +    DrawScreen(screen);
  36.296 +  }  
  36.297 +  SDL_Quit();  
  36.298 +  return 0;
  36.299 +}
  36.300 +