From 029f0be8e4beea787feb984b2797f6e23f7964ac Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sun, 25 Oct 2009 04:11:05 +0000 Subject: first version of object for private MultitouchSupport framework based on code from steide and fingerpinger svn path=/trunk/externals/apple/; revision=12669 --- multitouch.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 multitouch.c (limited to 'multitouch.c') 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 +#include +#include +#include +#include +#include "MultitouchSupport.h" +#include + +//#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); +} -- cgit v1.2.1