events sent to multiple apps

May 22, 2009 at 11:13 PM
Edited May 23, 2009 at 9:14 PM

[preface]
Hi, i'm working on a multitouch  mouselessand keyboardless table using your framework , CCV, Xna and C#. In my Xna app i use the OpenFileDialog() class to allow the user add photos so he could rotate/zoom/move them. This need an additional app, a mouse driver that simulate a real mouse using touch events, using the function SendInput(uint nInputs,INPUT[] pInputs,int cbSize) found in user32.dll.
[body]
Here comes the issue: even if i create a ContactHandler class with IntPtr.Zero as parameter, i can get events only if no apps are getting that event. I though IntPtr.Zero was allowing me to get any event in any case, but this is not how it's working atm (i think it's doing is job as developers thought it). Even if my coding skills are ridiculous, i created this TEMP patch to let ContactHandlers called with IntPtr.Zero as parameter get any event, even if another app already processed it. I tested this with 2 apps, 1 with IntPtr.Zero as parameter and 1 with it's own Handle, using ContactHandler.Frame in both. Here's a link for the patch: http://web.tiscali.it/jackpoz/IntPtrZeroEvents.patch
Edit: new patch at http://web.tiscali.it/jackpoz/IntPtrZeroEvents2.patch
Edit 2: new patch at http://web.tiscali.it/jackpoz/IntPtrZeroEvents3.patch


Index: Main Source/Multitouch.Service.Logic/ExternalInterfaces/ApplicationInterfaceService.cs
===================================================================
--- Main Source/Multitouch.Service.Logic/ExternalInterfaces/ApplicationInterfaceService.cs (revision 19641)
+++ Main Source/Multitouch.Service.Logic/ExternalInterfaces/ApplicationInterfaceService.cs (working copy)
@@ -107,6 +107,8 @@
    // For each contact determinte it's target handle and group by this handle
    IEnumerable<IGrouping<IntPtr, Contact>> contactsGroups = e.Contacts.GroupBy(contact => Utils.GetWindowFromPoint(contact.Position));
 
+   List<ContactData> IntPtrZero_contacts = new List<ContactData>();//list of all Contacts
+   
    // Create a list with sessions and contacts that belong to this session
    Dictionary<SessionContext, List<ContactData>> sessionList = new Dictionary<SessionContext, List<ContactData>>();
 
@@ -118,8 +120,15 @@
     SessionContext sessionContext;
     if (!handleToSessionMap.TryGetValue(contactsGroup.Key, out sessionContext))
     {
-     if (!handleToSessionMap.TryGetValue(IntPtr.Zero, out sessionContext))
-      continue;
+     if (handleToSessionMap.TryGetValue(IntPtr.Zero, out sessionContext))//IntPtr.Zero handlers get contacts only with my code to fix "double events" bug
+     {
+      if (!sessionList.TryGetValue(sessionContext, out contacts))
+      {
+       contacts = new List<ContactData>();
+      }
+      IntPtrZero_contacts.AddRange(contactsGroup.Select(c => new ContactData(c, IntPtr.Zero)));//add the found contacts to my List with the origin at the upper-left corner fo the screen
+     }
+     continue;
     }
 
     if(!sessionList.TryGetValue(sessionContext, out contacts))
@@ -129,6 +138,7 @@
     }
 
     contacts.AddRange(contactsGroup.Select(c => new ContactData(c, contactsGroup.Key)));
+    IntPtrZero_contacts.AddRange(contactsGroup.Select(c => new ContactData(c, IntPtr.Zero)));//add the found contacts to my List with the origin at the upper-left corner fo the screen
    }
 
    List<SessionContext> emptyFrameReceivers = new List<SessionContext>(sessions.Values);
@@ -148,7 +158,24 @@
     }
     emptyFrameReceivers.Remove(keyValuePair.Key);
    }
+   //Send frame data to IntPtr.Zero Handlers
 
+   foreach (KeyValuePair<IntPtr, SessionContext> IntPtrZero_keyValuePair in handleToSessionMap)
+   {
+    if (IntPtrZero_keyValuePair.Key == IntPtr.Zero)
+    {
+                    try
+                    {
+                        IntPtrZero_keyValuePair.Value.Callback.Frame(new FrameData(e.Timestamp, IntPtrZero_contacts, GetImages(IntPtrZero_keyValuePair.Value, e.Images)));
+                    }
+                    catch (Exception exc)
+                    {
+                        Trace.TraceError("Error during sending frame to application:\r\n" + exc.Message);
+                    }
+                    emptyFrameReceivers.Remove(IntPtrZero_keyValuePair.Value);
+    }
+   }
+
    // Send frame data to sessions that requested empty frames
    foreach (SessionContext session in emptyFrameReceivers.Where(s => s.SendEmptyFrames))
    {

I'd like to get something better added to the source code, maybe using a different IntPtr and with a different code (i learnt today something about what's a List and a Dictionary and an IEnumerable, i bet my code it's rly not the best) and with Contact.Position giving the position on the screen, with the origin at the upper-left side of the screen.

Thx for reading this long post, sry for the bad english, the awful formatting of this post and the lack of coding skillz,
Best Regards, 
                        JackPoz

 Edit: Fixed a bug where i was sending twice the same event at IntPtr.Zero in same cases, and sending empty frames even if 2 line before i sent events. If there is any problem to download the patch file just tell here.
Edit 2: now IntPtr.Zero handlers get contact.Position with the origin at the upper-left corner of the screen.
Edit 3: i made a pretty well mouse driver using MultiTouchVIsta + my patch, here's the source code: http://web.tiscali.it/jackpoz/MouseDriver.cs . To hide it compile it as Windows Application instead of Console Application. Credits to Google, TUIO_Mouse found at http://tuio.org/?software, MultiTouchVista and 1% to me :D. How to use it (i tested it on a multitouch table):
- move the cursor with 1 finger
- right-click adding another finger on the right of the already added one (2 fingers on the table)
- left-click adding another finger on the left of the already added one (2 fingers on the table)
button up&down supported, that means you can drap&drop icon, files and windows as you were using a real mouse. The wheel will be added soon, i hope someone will appreciate this.

Coordinator
May 24, 2009 at 1:01 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.