summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjet-plane <avion.bg@gmail.com>2008-06-05 19:11:48 +0000
committerjet-plane <avion.bg@gmail.com>2008-06-05 19:11:48 +0000
commit04a8978db39144cc391dd698a4197b89e7f63939 (patch)
tree1150a88e7340fc585c5cffe201d0ec7f906ad9ff
parent92b2f7deec6f3975f9d707516657742290b300a3 (diff)
downloadmultitouch-04a8978db39144cc391dd698a4197b89e7f63939.tar.gz
multitouch-04a8978db39144cc391dd698a4197b89e7f63939.tar.bz2
Added key for mouse emulation, moved window movement to timeouts to prevent segfaults and initial click/double click support
-rw-r--r--multitouch.c160
1 files changed, 141 insertions, 19 deletions
diff --git a/multitouch.c b/multitouch.c
index fddc53f..179cd2a 100644
--- a/multitouch.c
+++ b/multitouch.c
@@ -69,6 +69,23 @@ typedef struct
unsigned short R,G,B,A;
} mtcolor;
+typedef struct
+{ int id;
+ float x, y;
+} mtclick;
+
+typedef struct _ClickValue
+{
+ CompDisplay *display;
+ int id;
+} ClickValue;
+
+typedef struct _MvValue
+{
+ CompWindow * w;
+ int dx,dy;
+} MvValue;
+
typedef struct _DisplayValue
{
CompDisplay *display;
@@ -88,11 +105,14 @@ typedef struct _MultitouchDisplay
Bool Debug;
Bool Wm;
Bool TuioFwd;
+ Bool Cur;
lo_server_thread st;
mtblob blob[MAXBLOBS];
mtcolor color;
+ mtclick click[MAXBLOBS];
CompTimeoutHandle timeoutHandles;
CompTimeoutHandle clickTimeoutHandle;
+ CompTimeoutHandle moveWindowHandle;
} MultitouchDisplay;
typedef struct _MultitouchScreen
@@ -109,6 +129,8 @@ MultitouchDisplay *md = GET_MULTITOUCH_DISPLAY (d)
#define MULTITOUCH_SCREEN(s) \
MultitouchScreen *ms = GET_MULTITOUCH_SCREEN (s, GET_MULTITOUCH_DISPLAY (s->display))
+/* TODO: draw debug info on cairo, animated effect for each blob, pie (radial) menu */
+
static int findWindowAtPoint ( int x, int y)
{
char *display_name;
@@ -189,16 +211,15 @@ static void moveCursorTo(int x, int y)
XCloseDisplay(d);
}
-static void mouseClick(int button, CompDisplay * d)
+static void mouseClick(int button)
{
XEvent event;
-
memset(&event, 0x00, sizeof(event));
event.type = ButtonPress;
event.xbutton.button = button;
event.xbutton.same_screen = True;
- XQueryPointer(d->display,currentRoot,
+ XQueryPointer(firstDisplay->display,currentRoot,
&event.xbutton.root,
&event.xbutton.window,
&event.xbutton.x_root,
@@ -212,7 +233,7 @@ static void mouseClick(int button, CompDisplay * d)
while (event.xbutton.subwindow)
{
event.xbutton.window = event.xbutton.subwindow;
- XQueryPointer(d->display,
+ XQueryPointer(firstDisplay->display,
event.xbutton.window,
&event.xbutton.root,
&event.xbutton.subwindow,
@@ -223,21 +244,21 @@ static void mouseClick(int button, CompDisplay * d)
&event.xbutton.state);
}
- if (XSendEvent(d->display, PointerWindow,
+ if (XSendEvent(firstDisplay->display, PointerWindow,
True, 0xfff, &event)==0)
printf("XSendEvent() error!\n");
- XFlush(d->display);
+ XFlush(firstDisplay->display);
usleep(100000);
event.type = ButtonRelease;
event.xbutton.state = 0x100;
- if (XSendEvent(d->display, PointerWindow,
+ if (XSendEvent(firstDisplay->display, PointerWindow,
True, 0xfff, &event)==0)
printf("XSendEvent() error2!\n");
- XFlush(d->display);
+ XFlush(firstDisplay->display);
}
static Bool
@@ -288,7 +309,8 @@ sendInfoToPlugin (CompDisplay * d, CompOption * argument, int nArgument,
return TRUE;
}
-/* TODO: doesn't work at the moment 4 unknown reason */
+/* Change notify for bcop
+ * TODO: doesn't work at the moment 4 unknown reason */
static void
multitouchDisplayOptionChanged (CompDisplay *d,
CompOption *opt,
@@ -355,6 +377,20 @@ multitouchToggleWm (CompDisplay *d,
}
static Bool
+multitouchToggleCur (CompDisplay *d,
+ CompAction * action,
+ CompActionState state, CompOption * option, int nOption)
+{
+ MULTITOUCH_DISPLAY(d);
+ md->Cur = !md->Cur;
+ if (md->Debug && md->Cur)
+ printf ("Mouse emulation enabled\n");
+ else if (md->Debug)
+ printf ("Mouse emulation disabled\n");
+ return FALSE;
+}
+
+static Bool
multitouchToggleFwd (CompDisplay *d,
CompAction * action,
CompActionState state, CompOption * option, int nOption)
@@ -545,6 +581,15 @@ displaytext (void *data)
return FALSE;
}
+static Bool
+moveWindow_handler (void *data)
+{
+ MvValue *mv = (MvValue *) data;
+ moveWindow(mv->w, mv->dx, mv->dy, TRUE, FALSE);
+ free (mv);
+ return FALSE;
+}
+
static int
isMemberOfSet (int *Set, int size, int value)
{
@@ -559,7 +604,53 @@ isMemberOfSet (int *Set, int size, int value)
return 0;
}
-static void click_handler(mtEvent event, CompDisplay * d,int BlobID)
+static Bool
+click_handler (void *data)
+{
+ ClickValue *cv = (ClickValue *) data;
+ MULTITOUCH_DISPLAY (cv->display);
+ mtclick *clicks = md->click;
+ CompScreen *s;
+ s = findScreenAtDisplay (cv->display, currentRoot);
+ int width = s->width;
+ int height = s->height;
+ int clicked = 0;
+ int j,dx,dy;
+ if (s && clicks[cv->id].id >= 0)
+ {
+ for ( j=0;j<MAXBLOBS; j++)
+ {
+ if (clicks[j].id > 0 )
+ if (j != cv->id && clicks[j].id > 0 )
+ {
+ dx = (int) abs(clicks[j].x - clicks[cv->id].x) * width;
+ dy = (int) abs(clicks[j].y - clicks[cv->id].y) * height;
+ if ( ( dx < 10 ) && ( dy < 10 ) )
+ {
+ clicked++;
+ clicks[j].id = -1;
+ }
+ }
+ }
+ clicks[cv->id].id = -1;
+ }
+ if (clicked == 1)
+ {
+ //moveCursorTo(clicks[cv->id].x * width, clicks[cv->id].y * height);
+ //mouseClick(1);
+ printf("DOUBLE CLICK!\n");
+ }
+ if (clicked == 2)
+ {
+ //moveCursorTo(clicks[cv->id].x * width, clicks[cv->id].y * height);
+ //mouseClick(3);
+ printf("TRIPLE CLICK!\n");
+ }
+ free (cv);
+ return FALSE;
+}
+
+static void gesture_handler(mtEvent event, CompDisplay * d,int BlobID)
{
MULTITOUCH_DISPLAY (d);
CompScreen *s;
@@ -591,7 +682,7 @@ static void click_handler(mtEvent event, CompDisplay * d,int BlobID)
if (blobs[k].id && blobs[k].id < oldestblob)
oldestblob=blobs[k].id;
}
- if (oldestblob == blobs[BlobID].id)
+ if (oldestblob == blobs[BlobID].id && md->Cur )
moveCursorTo(blobs[BlobID].x * s->width,blobs[BlobID].y * s->height);
if ( blobs[BlobID].w )
{
@@ -618,7 +709,11 @@ static void click_handler(mtEvent event, CompDisplay * d,int BlobID)
if (md->Debug)
printf("movewindow id: %d, x%d , y:%d\n", blobs[BlobID].w, dx,dy );
CompWindow * w = (void *) blobs[BlobID].w;
- moveWindow(w, dx, dy, TRUE, FALSE);
+ MvValue *mv = malloc (sizeof (MvValue));
+ mv->w = w;
+ mv->dx = dx;
+ mv->dy = dy;
+ md->moveWindowHandle = compAddTimeout (0, moveWindow_handler, mv);
}
}
break;
@@ -644,6 +739,19 @@ static void click_handler(mtEvent event, CompDisplay * d,int BlobID)
(*w->screen->windowUngrabNotify)(w);
syncWindowPosition(w);
}
+ for (k=0;k<MAXBLOBS; k++)
+ {
+ if ( md->click[k].id == -1 )
+ break;
+ }
+ ClickValue *cv = malloc (sizeof (ClickValue));
+ cv->display = d;
+ cv->id = BlobID;
+ md->click[k].id = blobs[BlobID].id;
+ md->click[k].x = blobs[BlobID].x;
+ md->click[k].y = blobs[BlobID].y;
+ md->clickTimeoutHandle = compAddTimeout (400,click_handler, cv);
+
blobs[BlobID].id = 0;
blobs[BlobID].x = 0;
blobs[BlobID].y = 0;
@@ -748,17 +856,25 @@ static int tuio2Dcur_handler(const char *path, const char *types, lo_arg **argv,
mtblob *blobs = md->blob;
int j,alive[MAXBLOBS];
int found = 0;
- if ( !strcmp((char *) argv[0],"set") && argv[1]->i)
+ if ( !strcmp((char *) argv[0],"set") )
{
for (j = 0; j < MAXBLOBS; j++)
{
if (blobs[j].id == argv[1]->i)
{
- blobs[j].oldx = blobs[j].x;
- blobs[j].oldy = blobs[j].y;
+ if ( !blobs[j].x && !blobs[j].y )
+ {
+ blobs[j].oldx = argv[2]->f;
+ blobs[j].oldy = argv[3]->f;
+ }
+ else
+ {
+ blobs[j].oldx = blobs[j].x;
+ blobs[j].oldy = blobs[j].y;
+ }
blobs[j].x = argv[2]->f;
blobs[j].y = argv[3]->f;
- click_handler(EventMove, s->display,j);
+ gesture_handler(EventMove, s->display,j);
found = 1;
break;
}
@@ -782,7 +898,7 @@ static int tuio2Dcur_handler(const char *path, const char *types, lo_arg **argv,
blobs[j].xmot = argv[4]->f;
blobs[j].ymot = argv[5]->f;
blobs[j].mot_accel = argv[6]->f;
- click_handler(EventDown, s->display, j);
+ gesture_handler(EventDown, s->display, j);
}
}
}
@@ -790,7 +906,7 @@ static int tuio2Dcur_handler(const char *path, const char *types, lo_arg **argv,
{
for (j=1;j<argc;j++)
{
- alive[j] = argv[j]->i;
+ alive[j-1] = argv[j]->i;
}
for (j = 0; j < MAXBLOBS; j++)
{
@@ -798,7 +914,7 @@ static int tuio2Dcur_handler(const char *path, const char *types, lo_arg **argv,
{
if (!(isMemberOfSet (alive, MAXBLOBS, blobs[j].id)))
{
- click_handler(EventUp, s->display, j);
+ gesture_handler(EventUp, s->display, j);
break;
}
}
@@ -845,6 +961,7 @@ multitouchToggleMultitouch (CompDisplay *d,
md->blob[j].id = 0;
md->blob[j].w = 0;
md->blob[j].oldx = 0;
+ md->click[j].id = -1;
}
md->st = lo_server_thread_new(md->port, loerror);
lo_server_thread_add_method(md->st, "/tuio/2Dobj", NULL, tuio2Dobj_handler, d);
@@ -904,6 +1021,7 @@ multitouchFiniScreen (CompPlugin * p, CompScreen * s)
static Bool
multitouchInitDisplay (CompPlugin * p, CompDisplay * d)
{
+ printf("DEBUG");
MultitouchDisplay *md;
if (!checkPluginABI ("core", CORE_ABIVERSION))
return FALSE;
@@ -923,6 +1041,7 @@ multitouchInitDisplay (CompPlugin * p, CompDisplay * d)
md->TuioFwd = multitouchGetEnableFwd(d);
md->enabled = FALSE;
md->Debug = TRUE;
+ md->Cur = FALSE;
md->Wm = FALSE;
//sprintf (port,"%d",multitouchGetPort (d));
//md->TuioFwd = multitouchGetEnableFwd(d);
@@ -931,6 +1050,7 @@ multitouchInitDisplay (CompPlugin * p, CompDisplay * d)
multitouchSetToggleDebugInitiate (d, multitouchToggleDebug);
multitouchSetToggleFwdInitiate (d, multitouchToggleFwd);
multitouchSetToggleWmInitiate (d, multitouchToggleWm);
+ multitouchSetToggleCurInitiate (d, multitouchToggleCur);
multitouchSetToggleEffectsInitiate (d, multitouchToggleEffects);
return TRUE;
}
@@ -939,6 +1059,8 @@ static void
multitouchFiniDisplay (CompPlugin * p, CompDisplay * d)
{
MULTITOUCH_DISPLAY (d);
+ if (md->enabled)
+ lo_server_thread_free(md->st);
freeScreenPrivateIndex (d, md->screenPrivateIndex);
free (md);
}