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) {