aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile13
-rw-r--r--MultitouchSupport.h39
-rw-r--r--multitouch-help.pd13
-rw-r--r--multitouch.c148
4 files changed, 210 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 9498e23..a58276d 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ SOURCES =
# For objects that only build on certain platforms, add those to the SOURCES
# line for the right platforms.
-SOURCES_Darwin = ambient_light_sensor.c iodisplay.c keyboard_light.c sudden_motion_sensor.c smc.c
+SOURCES_Darwin = ambient_light_sensor.c iodisplay.c keyboard_light.c sudden_motion_sensor.c smc.c multitouch.c
SOURCES_Linux =
SOURCES_Windows =
@@ -51,9 +51,9 @@ ifeq ($(UNAME),Darwin)
SOURCES += $(SOURCES_Darwin)
EXTENSION = pd_darwin
OS = macosx
- OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast
+ OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=3 -fast
FAT_FLAGS = -arch i386 -arch ppc -mmacosx-version-min=10.4
- CFLAGS += -fPIC $(FAT_FLAGS)
+ CFLAGS += -fPIC -std=c99 $(FAT_FLAGS)
LDFLAGS += -bundle -undefined dynamic_lookup $(FAT_FLAGS)
LIBS += -lc
STRIP = strip -x
@@ -97,6 +97,13 @@ CFLAGS += $(OPT_CFLAGS)
all: $(SOURCES:.c=.$(EXTENSION))
+multitouch.$(EXTENSION): multitouch.c
+ $(CC) $(CFLAGS) -o multitouch.o -c multitouch.c
+ $(CC) $(LDFLAGS) -F/System/Library/PrivateFrameworks \
+ -o multitouch.$(EXTENSION) multitouch.o $(LIBS) -framework MultitouchSupport
+ chmod a-x multitouch.$(EXTENSION)
+ rm -f -- multitouch.o
+
%.$(EXTENSION): %.c
$(CC) $(CFLAGS) -o "$*.o" -c "$*.c"
$(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(LIBS)
diff --git a/MultitouchSupport.h b/MultitouchSupport.h
new file mode 100644
index 0000000..835c1a4
--- /dev/null
+++ b/MultitouchSupport.h
@@ -0,0 +1,39 @@
+#ifndef _MULTITOUCHSUPPORT_H_
+#define _MULTITOUCHSUPPORT_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct { float x,y; } mtPoint;
+typedef struct { mtPoint pos,vel; } mtReadout;
+
+typedef struct {
+ int frame;
+ double timestamp;
+ int identifier, state, foo3, foo4;
+ mtReadout normalized;
+ float size;
+ int zero1;
+ float angle, majorAxis, minorAxis; // ellipsoid
+ mtReadout mm;
+ int zero2[2];
+ float unk2;
+} Finger;
+
+typedef void *MTDeviceRef;
+typedef int (*MTContactCallbackFunction)(int,Finger*,int,double,int);
+
+
+MTDeviceRef MTDeviceCreateDefault();
+void MTRegisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction);
+void MTDeviceStart(MTDeviceRef, int);
+void MTDeviceStop(MTDeviceRef);
+void MTDeviceRelease(MTDeviceRef);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MULTITOUCHSUPPORT_H_ */
diff --git a/multitouch-help.pd b/multitouch-help.pd
new file mode 100644
index 0000000..0745a85
--- /dev/null
+++ b/multitouch-help.pd
@@ -0,0 +1,13 @@
+#N canvas 236 102 450 300 10;
+#X obj 153 120 multitouch;
+#X msg 162 52 bang;
+#X obj 170 98 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
+1;
+#X obj 142 153 print DATA;
+#X obj 216 153 print STATUS;
+#X msg 199 83 info;
+#X connect 0 0 3 0;
+#X connect 0 1 4 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 5 0 0 0;
diff --git a/multitouch.c b/multitouch.c
new file mode 100644
index 0000000..3118d8c
--- /dev/null
+++ b/multitouch.c
@@ -0,0 +1,148 @@
+/* --------------------------------------------------------------------------*/
+/* */
+/* get info from the multitouch trackpad on Apple Mac OS X */
+/* based on 'fingerpinger' */
+/* */
+/* Copyright (c) 2009 Hans-Christoph Steiner */
+/* Copyright (c) 2009 Michael & Max Egger */
+/* Copyright (c) 2008 Steike */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 3 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* See file LICENSE for further informations on licensing terms. */
+/* */
+/* This program 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 General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software Foundation, */
+/* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+/* */
+/* --------------------------------------------------------------------------*/
+
+#include <mach/mach.h>
+#include <IOKit/IOKitLib.h>
+#include <math.h>
+#include <unistd.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include "MultitouchSupport.h"
+#include <m_pd.h>
+
+//#define DEBUG(x)
+#define DEBUG(x) x
+
+/*------------------------------------------------------------------------------
+ * CLASS DEF
+ */
+
+static t_class *multitouch_class;
+
+typedef struct _multitouch {
+ t_object x_obj;
+ t_outlet* data_outlet;
+ t_outlet* status_outlet;
+} t_multitouch;
+
+static MTDeviceRef dev; /* reference to the trackpad */
+static int fingerc; /* current count of Fingers */
+static Finger fingerv[32]; /* current list of Fingers */
+static int polling = 0; /* set when one instance is polling so others don't */
+
+/*------------------------------------------------------------------------------
+ * CALLBACK TO GET DATA
+ */
+
+static int callback(int device, Finger *data, int nFingers, double timestamp, int frame)
+{
+ DEBUG(post("callback"););
+ memcpy(fingerv, data, nFingers * sizeof(Finger));
+ fingerc = nFingers;
+ return 0;
+}
+
+/*------------------------------------------------------------------------------
+ * IMPLEMENTATION
+ */
+
+static void multitouch_output(t_multitouch* x)
+{
+ DEBUG(post("multitouch_output"););
+ int i;
+ t_atom output_list[12];
+ for (i=0; i < fingerc; i++) {
+ Finger *f = &fingerv[i];
+ SETFLOAT(output_list,i);
+ SETFLOAT(output_list + 1 , f->frame);
+ SETFLOAT(output_list + 2 , f->angle);
+ SETFLOAT(output_list + 3 , f->majorAxis);
+ SETFLOAT(output_list + 4 , f->minorAxis);
+ SETFLOAT(output_list + 5 , f->normalized.pos.x);
+ SETFLOAT(output_list + 6 , f->normalized.pos.y);
+ SETFLOAT(output_list + 7 , f->normalized.vel.x);
+ SETFLOAT(output_list + 8 , f->normalized.vel.y);
+ SETFLOAT(output_list + 9 , f->identifier);
+ SETFLOAT(output_list + 10 , f->state);
+ SETFLOAT(output_list + 11 , f->size);
+ outlet_list(x->data_outlet, &s_, 12, output_list);
+ }
+}
+
+
+static void multitouch_float(t_multitouch* x, t_float f)
+{
+ DEBUG(post("multitouch_float"););
+ if (f > 0) {
+ polling++;
+ /* if I am the first instance to poll, then set the callback up */
+ if (polling == 1) {
+ dev = MTDeviceCreateDefault();
+ MTRegisterContactFrameCallback(dev, callback);
+ MTDeviceStart(dev, 0);
+ }
+ } else {
+ polling--;
+ /* if I am the last instance, clean up the callback stuff */
+ if (polling == 0) {
+ MTDeviceStop(dev);
+ MTDeviceRelease(dev);
+ dev = NULL;
+ }
+ }
+}
+
+
+static void multitouch_free(t_multitouch* x)
+{
+ DEBUG(post("multitouch_free"););
+ /* make sure callback is released before deleting the object */
+ multitouch_float(x, 0);
+}
+
+static void *multitouch_new(void)
+{
+ DEBUG(post("multitouch_new"););
+ t_multitouch *x = (t_multitouch *)pd_new(multitouch_class);
+
+ x->data_outlet = outlet_new(&x->x_obj, &s_list);
+ x->status_outlet = outlet_new(&x->x_obj, &s_anything);
+
+ return (x);
+}
+
+void multitouch_setup(void)
+{
+ multitouch_class = class_new(gensym("multitouch"),
+ (t_newmethod)multitouch_new,
+ (t_method)multitouch_free,
+ sizeof(t_multitouch),
+ CLASS_DEFAULT,
+ 0);
+ /* add inlet datatype methods */
+ class_addbang(multitouch_class,(t_method) multitouch_output);
+ class_addfloat(multitouch_class,(t_method) multitouch_float);
+}