Mercurial > sdl-ios-xcode
changeset 4661:03dcb795c583
Merged changes from the main SDL codebase
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 12 Jul 2010 21:09:23 -0700 |
parents | b15e7017409b (diff) 6f8175ad0335 (current diff) |
children | 3c4e0130c9b1 |
files | Makefile.in VisualC/SDL.sln VisualC/SDL/SDL.vcproj VisualC/SDL/SDL_VS2005.vcproj VisualC/SDL_VS2005.sln VisualC/SDLmain/SDLmain.vcproj VisualC/SDLmain/SDLmain_VS2005.vcproj VisualC/tests/automated/automated.vcproj VisualC/tests/checkkeys/checkkeys.vcproj VisualC/tests/graywin/graywin.vcproj VisualC/tests/loopwave/loopwave.vcproj VisualC/tests/testalpha/testalpha.vcproj VisualC/tests/testdraw2/testdraw2.vcproj VisualC/tests/testfile/testfile.vcproj VisualC/tests/testgamma/testgamma.vcproj VisualC/tests/testgl/testgl.vcproj VisualC/tests/testgl2/testgl2.vcproj VisualC/tests/testjoystick/testjoystick.vcproj VisualC/tests/testoverlay/testoverlay.vcproj VisualC/tests/testoverlay2/testoverlay2.vcproj VisualC/tests/testpalette/testpalette.vcproj VisualC/tests/testplatform/testplatform.vcproj VisualC/tests/testpower/testpower.vcproj VisualC/tests/testsprite/testsprite.vcproj VisualC/tests/testsprite2/testsprite2.vcproj VisualC/tests/testvidinfo/testvidinfo.vcproj VisualC/tests/testwin/testwin.vcproj VisualC/tests/testwm/testwm.vcproj include/SDL_events.h src/video/uikit/SDL_uikitview.h src/video/uikit/SDL_uikitview.m src/video/win32/SDL_win32events.c src/video/win32/SDL_win32video.h src/video/win32/SDL_win32window.c src/video/win32/wactab/pktdef.h src/video/win32/wactab/wintab.h src/video/win32/wactab/wintabx.h src/video/x11/SDL_x11events.c src/video/x11/SDL_x11video.c src/video/x11/SDL_x11video.h test/testmmousetablet.c |
diffstat | 45 files changed, 4804 insertions(+), 120 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.in Mon Jul 12 01:20:57 2010 -0700 +++ b/Makefile.in Mon Jul 12 21:09:23 2010 -0700 @@ -44,7 +44,7 @@ DIST = acinclude autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS include INSTALL Makefile.minimal Makefile.in README* sdl-config.in sdl.m4 sdl.pc.in SDL.spec SDL.spec.in src test TODO VisualC.html VisualC VisualCE Watcom-Win32.zip WhatsNew Xcode Xcode-iPhoneOS -HDRS = SDL.h SDL_assert.h SDL_atomic.h SDL_audio.h SDL_clipboard.h SDL_compat.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_haptic.h SDL_input.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_pixels.h SDL_platform.h SDL_power.h SDL_quit.h SDL_rect.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_stdinc.h SDL_surface.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h +HDRS = SDL.h SDL_assert.h SDL_atomic.h SDL_audio.h SDL_clipboard.h SDL_compat.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_gesture.h SDL_haptic.h SDL_input.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_pixels.h SDL_platform.h SDL_power.h SDL_quit.h SDL_rect.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_stdinc.h SDL_surface.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_touch.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@
--- a/VisualC/SDL/SDL_VS2005.vcproj Mon Jul 12 01:20:57 2010 -0700 +++ b/VisualC/SDL/SDL_VS2005.vcproj Mon Jul 12 21:09:23 2010 -0700 @@ -1,10 +1,11 @@ <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="8.00" + Version="9.00" Name="SDL" ProjectGUID="{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}" RootNamespace="SDL" + TargetFrameworkVersion="131072" > <Platforms> <Platform @@ -76,16 +77,21 @@ /> <Tool Name="VCLinkerTool" - AdditionalOptions="/MACHINE:I386" + AdditionalOptions="/MACHINE:I386
msvcrt.lib" AdditionalDependencies="msimg32.lib winmm.lib" OutputFile=".\Debug/SDL.dll" LinkIncremental="2" SuppressStartupBanner="true" - IgnoreAllDefaultLibraries="true" + IgnoreAllDefaultLibraries="false" + IgnoreDefaultLibraryNames="" GenerateDebugInformation="true" ProgramDatabaseFile=".\Debug/SDL.pdb" - SubSystem="2" + SubSystem="0" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" ImportLibrary=".\Debug/SDL.lib" + Profile="true" + CLRThreadAttribute="0" CLRUnmanagedCodeCheck="false" /> <Tool @@ -107,9 +113,6 @@ Name="VCAppVerifierTool" /> <Tool - Name="VCWebDeploymentTool" - /> - <Tool Name="VCPostBuildEventTool" /> </Configuration> @@ -185,6 +188,8 @@ IgnoreAllDefaultLibraries="true" ProgramDatabaseFile=".\Release/SDL.pdb" SubSystem="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" ImportLibrary=".\Release/SDL.lib" /> <Tool @@ -206,9 +211,6 @@ Name="VCAppVerifierTool" /> <Tool - Name="VCWebDeploymentTool" - /> - <Tool Name="VCPostBuildEventTool" /> </Configuration> @@ -941,6 +943,14 @@ > </File> <File + RelativePath="..\..\src\events\SDL_touch.c" + > + </File> + <File + RelativePath="..\..\src\events\SDL_touch_c.h" + > + </File> + <File RelativePath="..\..\src\video\SDL_video.c" > </File>
--- a/VisualC/SDLmain/SDLmain_VS2005.vcproj Mon Jul 12 01:20:57 2010 -0700 +++ b/VisualC/SDLmain/SDLmain_VS2005.vcproj Mon Jul 12 21:09:23 2010 -0700 @@ -1,9 +1,10 @@ <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="8.00" + Version="9.00" Name="SDLmain" ProjectGUID="{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}" + TargetFrameworkVersion="131072" > <Platforms> <Platform @@ -25,7 +26,7 @@ <Tool Name="VCPreBuildEventTool" Description="Making sure basic SDL headers are in place..." - CommandLine="if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY
echo Copying SDL_config_win32.h to SDL_config.h...
copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h"
:SDLCONFIGOKAY

if exist "$(ProjectDir)\..\..\include\SDL_revision.h" goto SDLREVISIONOKAY
echo Creating stub SDL_revision.h file...
echo #define SDL_REVISION 0 >"$(ProjectDir)\..\..\include\SDL_revision.h"
:SDLREVISIONOKAY" + CommandLine="if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY
echo Copying SDL_config_win32.h to SDL_config.h...
copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h"
:SDLCONFIGOKAY

if exist "$(ProjectDir)\..\..\include\SDL_revision.h" goto SDLREVISIONOKAY
echo Creating stub SDL_revision.h file...
echo #define SDL_REVISION 0 >"$(ProjectDir)\..\..\include\SDL_revision.h"
:SDLREVISIONOKAY
" /> <Tool Name="VCCustomBuildTool" @@ -98,7 +99,7 @@ <Tool Name="VCPreBuildEventTool" Description="Making sure basic SDL headers are in place..." - CommandLine="if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY
echo Copying SDL_config_win32.h to SDL_config.h...
copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h"
:SDLCONFIGOKAY

if exist "$(ProjectDir)\..\..\include\SDL_revision.h" goto SDLREVISIONOKAY
echo Creating stub SDL_revision.h file...
echo #define SDL_REVISION 0 >"$(ProjectDir)\..\..\include\SDL_revision.h"
:SDLREVISIONOKAY" + CommandLine="if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY
echo Copying SDL_config_win32.h to SDL_config.h...
copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h"
:SDLCONFIGOKAY

if exist "$(ProjectDir)\..\..\include\SDL_revision.h" goto SDLREVISIONOKAY
echo Creating stub SDL_revision.h file...
echo #define SDL_REVISION 0 >"$(ProjectDir)\..\..\include\SDL_revision.h"
:SDLREVISIONOKAY
" /> <Tool Name="VCCustomBuildTool" @@ -171,7 +172,7 @@ <Tool Name="VCPreBuildEventTool" Description="Making sure basic SDL headers are in place..." - CommandLine="if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY
echo Copying SDL_config_win32.h to SDL_config.h...
copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h"
:SDLCONFIGOKAY

if exist "$(ProjectDir)\..\..\include\SDL_revision.h" goto SDLREVISIONOKAY
echo Creating stub SDL_revision.h file...
echo #define SDL_REVISION 0 >"$(ProjectDir)\..\..\include\SDL_revision.h"
:SDLREVISIONOKAY" + CommandLine="if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY
echo Copying SDL_config_win32.h to SDL_config.h...
copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h"
:SDLCONFIGOKAY

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