// here, just record the position of point,
        //    you can do mouse map like "OnTG_Down" etc;
        static void OnTouchPoint(ref PQMTClientImport.TouchPoint tp)
        {
            switch ((EPQT_TPoint)tp.point_event)
            {
                case EPQT_TPoint.TP_DOWN:
                    touchID[tp.id] = nextID;
                    IDsHeld.Add(tp.id);
                    if (nextID < maxTouches - 100)
                    {
                        nextID++;
                    }
                    else
                    {
                        nextID = 0;
                    }
                    break;
                case EPQT_TPoint.TP_MOVE:
                    if (!IDsHeld.Contains(tp.id))
                        IDsHeld.Add(tp.id);
                    break;
                case EPQT_TPoint.TP_UP:
                    if (IDsHeld.Contains(tp.id))
                        IDsHeld.Remove(tp.id);
                    break;
            }
            // Format data into TacTile TouchAPI format
            float xPos_ratio = ((float)tp.x / (float)screenWidth);
            float yPos_ratio = ((float)screenHeight - (float)tp.y) / (float)screenHeight;
            float intensity = (float)0.5;
            int finger = (int)touchID[tp.id];
            float xWidth_ratio = ((float)tp.dx / (float)screenWidth);
            float yWidth_ratio = ((float)tp.dy / (float)screenHeight);

            ID_x[tp.id] = xPos_ratio;
            ID_y[tp.id] = yPos_ratio;
            ID_xW[tp.id] = xWidth_ratio;
            ID_yW[tp.id] = yWidth_ratio;
            if (useHoldGesture)
                omegaDesk.updateHoldData(touchID, IDsHeld, ID_x, ID_y, ID_xW, ID_yW);
            //Console.WriteLine("{0}, {1}", xWidth_ratio, yWidth_ratio);

            // Check for valid blob width and/or height
            if ((tp.dx <= max_blob_size && tp.dy <= max_blob_size))
            {
                // Send data to TouchAPI_Connector (timestamp is set there)
                omegaDesk.SendTouchData(finger, xPos_ratio, yPos_ratio, intensity, xWidth_ratio, yWidth_ratio, tp.point_event);
                omegaDesk.SendTouchData(finger, xPos_ratio, yPos_ratio, intensity);

                //DateTime baseTime = new DateTime(1970, 1, 1, 0, 0, 0);
                long timeStamp = (DateTime.UtcNow - baseTime).Ticks / 10000;

                //String touchAPI_output = timeStamp + ":q:" + tp.id + "," + xPos_ratio + "," + yPos_ratio + "," + 0.5;
                //Console.WriteLine("<{0}:q:{1},{2},{3},{4},{5},{6}>",timeStamp,tp.id,xPos_ratio,yPos_ratio,xWidth_ratio,yWidth_ratio,tp.point_event,intensity);
                if (generateLog)
                {
                    //.Console.WriteLine("{0} {1} ({2}) {3} {4} {5} {6} {7}", timeStamp, tp.id, finger, tp.point_event, xPos_ratio, yPos_ratio, xWidth_ratio, yWidth_ratio);
                    textOut.WriteLine("{0} {1} ({2}) {3} {4} {5} {6} {7}", timeStamp, tp.id, finger, tp.point_event, xPos_ratio, yPos_ratio, xWidth_ratio, yWidth_ratio);
                }

                switch ((EPQT_TPoint)tp.point_event)
                {
                    case EPQT_TPoint.TP_DOWN:
                        downSent++;
                        if (touchText && useTouchPoints)
                            Console.WriteLine("  point {0} come at ({1},{2}) width:{3} height:{4}", finger, tp.x, tp.y, tp.dx, tp.dy);
                        break;
                    case EPQT_TPoint.TP_MOVE:
                        moveSent++;
                        if (touchText && useTouchPoints)
                            Console.WriteLine("  point {0} move at ({1},{2}) width:{3} height:{4}", finger, tp.x, tp.y, tp.dx, tp.dy);
                        break;
                    case EPQT_TPoint.TP_UP:
                        upSent++;
                        if (touchText && useTouchPoints)
                            Console.WriteLine("  point {0} leave at ({1},{2}) width:{3} height:{4}", finger, tp.x, tp.y, tp.dx, tp.dy);
                        break;
                }

            }
            else
            {
                // Current touch is too large or existing touch has grown too large
                // Send up signal to clear touch
                omegaDesk.SendTouchData(finger, -xPos_ratio, -yPos_ratio, 0, 0, 0, 3);
                upSent++;
            }
            //Console.WriteLine("Sent: Down {0}, Move {1}, Up {2}, Total {3}", downSent, moveSent, upSent, downSent + moveSent + upSent);
        }
 static void OnReceiveGesture(ref PQMTClientImport.TouchGesture gesture, IntPtr call_back_object)
 {
     OnTouchGesture(ref gesture);
 }
        // TouchGestures -----------------------------------------------
        static void OnTouchGesture(ref PQMTClientImport.TouchGesture tg)
        {
            if ((int)EPQT_TGesture.TG_NO_ACTION == tg.type)
                return;
            DefaultOnTG(ref tg);

            PFuncOnTouchGesture pf = (PFuncOnTouchGesture)g_pf_on_tges[(int)tg.type];
            if (null != pf)
            {
                pf(ref tg);
            }
        }
        // just show the gesture
        static void DefaultOnTG(ref PQMTClientImport.TouchGesture tg)
        {
            string name = Marshal.PtrToStringAnsi(PQMTClientImport.GetGestureName(ref tg));
            string dataString = "";
            if (touchText && usePQGestures)
                Console.Write("gesture:{0},type:{1},param size:{2} ", name, tg.type, tg.param_size);
            for (int i = 0; i < tg.param_size; ++i)
            {
                //double tmp = 0;
                //tg.param_s.GetValue(i,out tmp);
                if (touchText && usePQGestures)
                    Console.Write("{0} ", tg.param_s[i]);

                dataString += tg.param_s[i] + ",";
            }
            dataString += tg.type;

            if (touchText && usePQGestures)
                Console.WriteLine("");
        }