# HG changeset patch # User Sam Lantinga # Date 1278994163 25200 # Node ID 03dcb795c583d0a55046c3f0b5b688c5dca3a222 # Parent b15e7017409bad6723dadce5d9e28ac22a049f4d# Parent 6f8175ad033563743fea8fdceece8f4c5be9ad07 Merged changes from the main SDL codebase diff -r 6f8175ad0335 -r 03dcb795c583 Makefile.in --- 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@ diff -r 6f8175ad0335 -r 03dcb795c583 VisualC/SDL/SDL_VS2005.vcproj --- 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 @@ - @@ -185,6 +188,8 @@ IgnoreAllDefaultLibraries="true" ProgramDatabaseFile=".\Release/SDL.pdb" SubSystem="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" ImportLibrary=".\Release/SDL.lib" /> - @@ -941,6 +943,14 @@ > + + + + diff -r 6f8175ad0335 -r 03dcb795c583 VisualC/SDL_VS2005.sln diff -r 6f8175ad0335 -r 03dcb795c583 VisualC/SDLmain/SDLmain_VS2005.vcproj --- 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 @@ = 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 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 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= 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;jnumDownFingers;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: */ + diff -r 6f8175ad0335 -r 03dcb795c583 src/events/SDL_gesture_c.h --- /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: */ diff -r 6f8175ad0335 -r 03dcb795c583 src/events/SDL_touch.c --- /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 + + +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: */ diff -r 6f8175ad0335 -r 03dcb795c583 src/events/SDL_touch_c.h --- /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: */ diff -r 6f8175ad0335 -r 03dcb795c583 src/video/uikit/SDL_uikitview.h --- 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 diff -r 6f8175ad0335 -r 03dcb795c583 src/video/uikit/SDL_uikitview.m --- 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 +#include #include "wmmsg.h" #endif +//#include /* 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) { diff -r 6f8175ad0335 -r 03dcb795c583 src/video/win32/SDL_win32video.h --- 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 #if SDL_VIDEO_RENDER_D3D diff -r 6f8175ad0335 -r 03dcb795c583 src/video/win32/SDL_win32window.c --- 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); diff -r 6f8175ad0335 -r 03dcb795c583 src/video/win32/wmmsg.h --- 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)", diff -r 6f8175ad0335 -r 03dcb795c583 src/video/x11/SDL_eventtouch.c --- /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 +#include + +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: */ diff -r 6f8175ad0335 -r 03dcb795c583 src/video/x11/SDL_eventtouch.h --- /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: */ diff -r 6f8175ad0335 -r 03dcb795c583 src/video/x11/SDL_x11events.c --- 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 + +//Touch Input/event* includes +#include +#include + /*#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 */ diff -r 6f8175ad0335 -r 03dcb795c583 src/video/x11/SDL_x11video.c --- 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 diff -r 6f8175ad0335 -r 03dcb795c583 src/video/x11/SDL_x11video.h --- 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" diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/TODO --- /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 diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/gestureSDLTest.c --- /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 +#include +#include +#include +#include + +#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= 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 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 +#include +#include +#include + +#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;iw/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 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 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;ih; 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= 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 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= 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 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;ixres; + float y = ((float)event.tfinger.y)/inTouch->yres; + int j,empty = -1; + + for(j = 0;j 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; +} diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/makefile --- /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 + + diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/makefile~ --- /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 diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/parseDevicesTest.c --- /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 +#include +#include +#include + + +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; +} diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/testIn Binary file touchTest/testIn has changed diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/testIn.c --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/testIn.c~ --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchPong Binary file touchTest/touchPong has changed diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchPong.c --- /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 +#include +#include +#include +#include + + +#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 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 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; +} diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchPong.c~ --- /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 +#include +#include +#include +#include + + +#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 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; +} diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchSimp Binary file touchTest/touchSimp has changed diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchSimp.c --- /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 +#include +#include +#include +#include + + +#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 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; +} diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchSimp.c~ --- /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 +#include +#include +#include +#include + + +#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 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; +} diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchTest.c --- /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 +#include +#include +#include + + + +#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 0) { //r<0 ==> unfilled circle + for(tx=x-r*cos(a);txh; 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= 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; +} diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchTest2/touchTest2.ncb Binary file touchTest/touchTest2/touchTest2.ncb has changed diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchTest2/touchTest2.sln --- /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 diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchTest2/touchTest2.suo Binary file touchTest/touchTest2/touchTest2.suo has changed diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchTest2/touchTest2/SDL.dll Binary file touchTest/touchTest2/touchTest2/SDL.dll has changed diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchTest2/touchTest2/touchTest2.vcproj --- /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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 6f8175ad0335 -r 03dcb795c583 touchTest/touchTest2/touchTest2/touchTest2.vcproj.jgran-virtualPC.jgran.user --- /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 @@ + + + + + + + + + + +