modules/graphics/src/main/native-glass/win/ViewContainer.cpp

Print this page

        

*** 90,99 **** --- 90,100 ---- m_deadKeyWParam(0) { m_kbLayout = ::GetKeyboardLayout(0); m_idLang = LOWORD(m_kbLayout); m_codePage = LangToCodePage(m_idLang); + m_lastTouchInputCount = 0; } jobject ViewContainer::GetView() { return GetGlassView() != NULL ? GetGlassView()->GetView() : NULL;
*** 1214,1223 **** --- 1215,1239 ---- operator HTOUCHINPUT() const { return m_h; } }; + static BOOL debugTouch = false; + + static char * touchEventName(unsigned int dwFlags) { + if (dwFlags & TOUCHEVENTF_MOVE) { + return "MOVE"; + } + if (dwFlags & TOUCHEVENTF_DOWN) { + return "PRESS"; + } + if (dwFlags & TOUCHEVENTF_UP) { + return "RELEASE"; + } + return "UNKOWN"; + } + void NotifyTouchInput( HWND hWnd, jobject view, jclass gestureSupportCls, const TOUCHINPUT* ti, unsigned count) {
*** 1293,1332 **** } } } // namespace ! void ViewContainer::HandleViewTouchEvent( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { ! // Preallocated arrays. One element per finger. Though so far ! // Win 7 can handle at most four touch points simultaneously, ! // so the buffer is excessive. ! TOUCHINPUT staticTouchInputBuf[10]; ! ! std::vector<TOUCHINPUT> dynamicTouchInputBuf; ! PTOUCHINPUT pInputs = staticTouchInputBuf; ! ! const UINT cInputs = static_cast<UINT>(LOWORD(wParam)); ! if (ARRAYSIZE(staticTouchInputBuf) < cInputs) { ! dynamicTouchInputBuf.resize(cInputs); ! pInputs = &*dynamicTouchInputBuf.begin(); } do { AutoTouchInputHandle inputInfo(lParam); ! if (!::GetTouchInputInfo(inputInfo, cInputs, ! pInputs, sizeof(TOUCHINPUT))) { ! return; } } while(0); // scope for 'inputInfo' ! NotifyTouchInput(hWnd, GetView(), m_gestureSupportCls, pInputs, cInputs); if (m_manipProc) { ! NotifyManipulationProcessor(*m_manipProc, pInputs, cInputs); } } void ViewContainer::HandleViewTimerEvent(HWND hwnd, UINT_PTR timerID) { if (IDT_GLASS_INERTIAPROCESSOR == timerID) { --- 1309,1459 ---- } } } // namespace ! unsigned int ViewContainer::HandleViewTouchEvent( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { ! const UINT newCount = static_cast<UINT>(LOWORD(wParam)); ! TOUCHINPUT * tempTouchInputBuf; ! ! unsigned int bufsz = newCount > 10 ? newCount : 10; ! if (m_thisTouchInputBuf.size() < bufsz) { ! m_thisTouchInputBuf.resize(bufsz); } + if (newCount > 0) { + tempTouchInputBuf = new TOUCHINPUT[newCount]; do { AutoTouchInputHandle inputInfo(lParam); ! if (!::GetTouchInputInfo(inputInfo, newCount, ! tempTouchInputBuf, sizeof(TOUCHINPUT))) { ! return 0; } } while(0); // scope for 'inputInfo' + } + + // Fix up the touch point stream. Some drivers seem to lose touch events, + // dropping PRESS, MOVE, UP, so we need to add them back in. + + unsigned int activeCount = 0; + unsigned int pointsCount = 0; ! // check first for any "lost" touches ! // these need to get added to the send list of points ! for (unsigned int i = 0 ; i < m_lastTouchInputCount; i++) { ! if (!(m_lastTouchInputBuf[i].dwFlags & TOUCHEVENTF_UP)) { ! // looking for a dwID that is ! // not present in the new batch ! // was not UP in the old batch ! bool found = false; ! for (unsigned int j = 0; j < newCount; j++) { ! if (m_lastTouchInputBuf[i].dwID == tempTouchInputBuf[j].dwID) { ! found = true; ! //break; ! } ! } ! if (!found) { ! // We have a old event but not a new one, so release it ! m_thisTouchInputBuf[pointsCount].dwFlags = TOUCHEVENTF_UP; ! m_thisTouchInputBuf[pointsCount].dwID = m_lastTouchInputBuf[i].dwID; ! m_thisTouchInputBuf[pointsCount].x = m_lastTouchInputBuf[i].x; ! m_thisTouchInputBuf[pointsCount].y = m_lastTouchInputBuf[i].y; ! if (newCount > 0) { ! //use the time of the first new element for our inserted event ! m_thisTouchInputBuf[pointsCount].dwTime = tempTouchInputBuf[0].dwTime; ! } else { ! m_thisTouchInputBuf[pointsCount].dwTime = m_lastTouchInputBuf[i].dwTime; ! } ! m_thisTouchInputBuf[pointsCount].dwMask = m_lastTouchInputBuf[i].dwMask; ! ! if (debugTouch) { ! printf("TOUCH FIX UP %d, %s\n", m_lastTouchInputBuf[i].dwID, touchEventName(m_lastTouchInputBuf[i].dwFlags)); ! } ! ! pointsCount++; ! } ! } ! } ! ! if (pointsCount + newCount > m_thisTouchInputBuf.size()) { ! bufsz = pointsCount + newCount; ! m_thisTouchInputBuf.resize(bufsz); ! } ! ! // now fold in the current touch points ! for (unsigned int i = 0 ; i < newCount; i++) { ! bool found = false; ! for (unsigned int j = 0 ; j < m_lastTouchInputCount; j++) { ! if (m_lastTouchInputBuf[j].dwID == tempTouchInputBuf[i].dwID) { ! found = true; ! break; ! } ! } ! ! m_thisTouchInputBuf[pointsCount].dwFlags = tempTouchInputBuf[i].dwFlags; ! m_thisTouchInputBuf[pointsCount].dwID = tempTouchInputBuf[i].dwID; ! m_thisTouchInputBuf[pointsCount].dwTime = tempTouchInputBuf[i].dwTime; ! m_thisTouchInputBuf[pointsCount].dwMask = tempTouchInputBuf[i].dwMask; ! m_thisTouchInputBuf[pointsCount].x = tempTouchInputBuf[i].x; ! m_thisTouchInputBuf[pointsCount].y = tempTouchInputBuf[i].y; ! ! if (m_thisTouchInputBuf[pointsCount].dwFlags & TOUCHEVENTF_DOWN) { ! pointsCount++; ! activeCount ++; ! } else if (m_thisTouchInputBuf[pointsCount].dwFlags & TOUCHEVENTF_MOVE) { ! if (!found) { ! if (debugTouch) { ! printf("TOUCH FIX MV->DOWN %d, %s\n", m_thisTouchInputBuf[pointsCount].dwID, touchEventName(m_thisTouchInputBuf[pointsCount].dwFlags)); ! } ! m_thisTouchInputBuf[pointsCount].dwFlags = TOUCHEVENTF_DOWN; ! } ! pointsCount++; ! activeCount ++; ! } else if (m_thisTouchInputBuf[pointsCount].dwFlags & TOUCHEVENTF_UP) { ! if (found) { ! pointsCount++; ! } else { ! // UP without a previous DOWN, ignore it ! } ! } ! } ! ! if (debugTouch) { ! printf("Touch Sequence %d/%d win=%d view=%d %d,%d,%d\n",pointsCount,activeCount, ! hWnd, GetView(), ! m_lastTouchInputCount, newCount, pointsCount); ! for (unsigned int i = 0 ; i < m_lastTouchInputCount; i++) { ! printf(" old %d, %s\n", m_lastTouchInputBuf[i].dwID, touchEventName(m_lastTouchInputBuf[i].dwFlags)); ! } ! for (unsigned int i = 0 ; i < newCount; i++) { ! printf(" in %d, %s\n", tempTouchInputBuf[i].dwID, touchEventName(tempTouchInputBuf[i].dwFlags)); ! } ! for (unsigned int i = 0 ; i < pointsCount; i++) { ! printf(" this %d, %d\n", m_thisTouchInputBuf[i].dwID, m_thisTouchInputBuf[i].dwFlags & 0x07); ! } ! printf(" ---\n"); ! fflush(stdout); ! } ! ! if (pointsCount > 0) { ! NotifyTouchInput(hWnd, GetView(), m_gestureSupportCls, &m_thisTouchInputBuf[0], pointsCount); if (m_manipProc) { ! NotifyManipulationProcessor(*m_manipProc, &m_thisTouchInputBuf[0], pointsCount); } + + std::swap(m_lastTouchInputBuf, m_thisTouchInputBuf); + m_lastTouchInputCount = pointsCount; + } + + if ( newCount > 0) { + delete [] tempTouchInputBuf; + } + + return activeCount; } void ViewContainer::HandleViewTimerEvent(HWND hwnd, UINT_PTR timerID) { if (IDT_GLASS_INERTIAPROCESSOR == timerID) {