void TouchDevice::ReadTouchEvents(int touch_device) { s_curPointerCount = 0; s_curSlotId = 0; int oldX = -1, oldY = -1; int64_t downTime = 0; for (;;) { MoveEvent* moveEvent = ReadSingleTouchEvent(touch_device); if (NULL == moveEvent) { continue; } if (MoveEvent::ACTION_DOWN == moveEvent->GetActionMasked()) { oldX = moveEvent->GetX(); oldY = moveEvent->GetY(); downTime = moveEvent->m_eventTime; moveEvent->m_downTime = downTime; SNativeMessage msg; msg.iType = MESSAGE_TYPE; msg.iParam1 = (uint32_t)moveEvent; msg.iParam2 = 0; msg.iParam3 = 0; INativeMessageQueue::GetMessageQueue()->Send(msg); } else if (MoveEvent::ACTION_UP == moveEvent->GetActionMasked()) { SNativeMessage msg; moveEvent->m_x[0] = oldX; moveEvent->m_y[0] = oldY; moveEvent->m_downTime = downTime; msg.iType = MESSAGE_TYPE; msg.iParam1 = (uint32_t)moveEvent; msg.iParam2 = 0; msg.iParam3 = 0; INativeMessageQueue::GetMessageQueue()->Send(msg); break; } else if (MoveEvent::ACTION_MOVE == moveEvent->GetActionMasked()) { oldX = moveEvent->GetX(); oldY = moveEvent->GetY(); moveEvent->m_downTime = downTime; //send message SNativeMessage msg; msg.iType = MESSAGE_TYPE; msg.iParam1 = (uint32_t)moveEvent; msg.iParam2 = 0; msg.iParam3 = 0; INativeMessageQueue::GetMessageQueue()->Send(msg); } } }
//maybe just update one of x/y MoveEvent* TouchDevice::ReadSingleTouchEvent(int _touch_device) { struct input_event iebuf; MoveEvent moveEvent; int moveAction = MoveEvent::ACTION_MASK; int curActionIndex = -1; int curIndex = -1; static int s_oldX[2] = {-1, -1}; static int s_oldY[2] = {-1, -1}; static int index2Slots[2] ={-1, -1}; static int64_t downTime = -1; int readCount = 0; for (;;) { if (read(_touch_device, &iebuf, sizeof(iebuf)) >0 ) { if (EV_ABS == iebuf.type) { ++readCount; } DebugPrintf(DLC_GESTURE, "type: %d, code: %d, value: %d", iebuf.type, iebuf.code, iebuf.value); if (iebuf.type == EV_ABS && iebuf.code == ABS_MT_SLOT) { s_curSlotId = iebuf.value; continue; } if (iebuf.type == EV_ABS && iebuf.code == ABS_MT_TRACKING_ID && iebuf.value >=0) { ++curIndex; index2Slots[curIndex] = s_curSlotId; ++s_curPointerCount; if (1 == s_curPointerCount) { moveAction = MoveEvent::ACTION_DOWN; downTime = SystemUtil::GetUpdateTimeInMs(); } else if (2 == s_curPointerCount) { moveAction = MoveEvent::ACTION_POINTER_DOWN; } curActionIndex = curIndex; } if (iebuf.type == EV_ABS && iebuf.code == ABS_MT_TRACKING_ID && iebuf.value ==-1) { ++curIndex; index2Slots[curIndex] = s_curSlotId; --s_curPointerCount; curActionIndex = curIndex; if (1 == s_curPointerCount) { moveAction = MoveEvent::ACTION_POINTER_UP; // sometimes we get two ABS_MT_TRACKING_ID in one loop // and must break it in two break; } else if (0 == s_curPointerCount) { moveAction = MoveEvent::ACTION_UP; } } if (iebuf.type == EV_ABS && iebuf.code == ABS_MT_POSITION_X) { if (-1 == curIndex || s_curSlotId != index2Slots[curIndex]) { ++curIndex; index2Slots[curIndex] = s_curSlotId; } if (-1 == curActionIndex) { curActionIndex = curIndex; } s_oldX[s_curSlotId] = GetScreenHorizonPostion(iebuf.value); if (MoveEvent::ACTION_MASK == moveAction) { moveAction = MoveEvent::ACTION_MOVE; } } if (iebuf.type == EV_ABS && iebuf.code == ABS_MT_POSITION_Y) { if (-1 == curIndex || s_curSlotId != index2Slots[curIndex]) { ++curIndex; index2Slots[curIndex] = s_curSlotId; } if (-1 == curActionIndex) { curActionIndex = curIndex; } s_oldY[s_curSlotId] = GetScreenVerticalPostion(iebuf.value); if (MoveEvent::ACTION_MASK == moveAction) { moveAction = MoveEvent::ACTION_MOVE; } if (MoveEvent::ACTION_DOWN == moveAction) { // 有可能action_down后还有一个action_pointer_down // 需要拆成两个move event break; } } if (iebuf.type == EV_SYN && iebuf.code == SYN_REPORT && iebuf.value ==0) { break; } } else { break; } } // previous read bread before read (0, 0, 0) // currently only read (0, 0, 0) if (0 == readCount) { return NULL; } moveEvent.m_pointerCount = curIndex + 1; moveEvent.m_action = moveAction; moveEvent.m_downTime = downTime; for (int i = 0; i < moveEvent.m_pointerCount; ++i) { moveEvent.m_x[i] = s_oldX[index2Slots[i]]; moveEvent.m_y[i] = s_oldY[index2Slots[i]]; moveEvent.m_pointerId[i] = index2Slots[i]; } // 1. currently there're two fingers on touch screen // but only one finger position information is reported in this loop // 2. previously there're two fingers on toush screen // but only one finger up information is reported in this loop // adding another's information if (2 == s_curPointerCount && 0 == curIndex || (MoveEvent::ACTION_POINTER_UP == moveAction && 0 == curIndex)) { int anotherSlot = 1 - index2Slots[0]; moveEvent.m_x[1] = s_oldX[anotherSlot]; moveEvent.m_y[1] = s_oldY[anotherSlot]; moveEvent.m_pointerId[1] = anotherSlot; moveEvent.m_pointerCount = 2; } moveEvent.m_actionIndex = curActionIndex; moveEvent.m_eventTime = SystemUtil::GetUpdateTimeInMs(); for (int i = 0; i < 2; ++i) { DebugPrintf(DLC_GESTURE, "Slot %d: (%d, %d)", i, s_oldX[i], s_oldY[i]); } DebugPrintf(DLC_GESTURE, "Read move event %d: (%d, %d), pointer count: %d, action index: %d", moveEvent.GetActionMasked(), moveEvent.GetX(), moveEvent.GetY(), moveEvent.GetPointerCount(), moveEvent.GetActionIndex()); return moveEvent.Clone(); }