Index: content/browser/renderer_host/render_widget_host_view_win.cc |
=================================================================== |
--- content/browser/renderer_host/render_widget_host_view_win.cc (revision 108760) |
+++ content/browser/renderer_host/render_widget_host_view_win.cc (working copy) |
@@ -5,14 +5,17 @@ |
#include "content/browser/renderer_host/render_widget_host_view_win.h" |
#include <algorithm> |
+#include <vector> |
#include "base/command_line.h" |
#include "base/i18n/rtl.h" |
+#include "base/logging.h" |
#include "base/metrics/histogram.h" |
#include "base/process_util.h" |
#include "base/threading/thread.h" |
#include "base/win/scoped_comptr.h" |
#include "base/win/scoped_gdi_object.h" |
+#include "base/win/windows_version.h" |
#include "base/win/win_util.h" |
#include "base/win/windows_version.h" |
#include "base/win/wrapped_window_proc.h" |
@@ -889,8 +892,12 @@ |
{ GID_TWOFINGERTAP, GC_TWOFINGERTAP , 0}, |
{ GID_PRESSANDTAP, GC_PRESSANDTAP , 0} |
}; |
- if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc, sizeof(GESTURECONFIG))) |
- { |
+ if (base::win::GetVersion() >= base::win::VERSION_WIN7 && |
+ CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableTouchEvents)) { |
+ DCHECK(RegisterTouchWindow(m_hWnd, 0)); |
cpu_(ooo_6.6-7.5)
2011/11/08 02:34:04
bug: on release RTE is not called.
jschuh
2011/11/08 17:12:41
I'm confused. Are you saying I need a call to Unre
cpu_(ooo_6.6-7.5)
2011/11/08 19:20:14
No. release build. dcheck goes *puff*
|
+ } else if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc, |
+ sizeof(GESTURECONFIG))) { |
cpu_(ooo_6.6-7.5)
2011/11/08 02:34:04
886 to 893 should be moved inside this block and t
jschuh
2011/11/08 17:12:41
Ugh, merge noise. Sorry, I should have caught that
|
NOTREACHED(); |
} |
} |
@@ -1102,6 +1109,7 @@ |
render_widget_host_->GotFocus(); |
render_widget_host_->SetActive(true); |
} |
+ FinishTouchEvent(); |
} |
void RenderWidgetHostViewWin::OnKillFocus(HWND window) { |
@@ -1109,6 +1117,7 @@ |
render_widget_host_->SetActive(false); |
render_widget_host_->Blur(); |
} |
+ FinishTouchEvent(); |
} |
void RenderWidgetHostViewWin::OnCaptureChanged(HWND window) { |
@@ -1570,6 +1579,174 @@ |
return 0; |
} |
+void RenderWidgetHostViewWin::FinishTouchEvent() { |
+ if (touch_event_.touchesLength == 0) |
+ return; |
+ |
+ // Release all active touchpoints. |
+ for (unsigned int i = 0; i < touch_event_.touchesLength; ++i) { |
+ touch_event_.touches[i].state = WebKit::WebTouchPoint::StateReleased; |
+ touch_event_.changedTouches[i].state = |
+ WebKit::WebTouchPoint::StateReleased; |
+ } |
+ touch_event_.changedTouchesLength = touch_event_.touchesLength = 0; |
+ touch_event_.type = WebKit::WebInputEvent::TouchEnd; |
+ render_widget_host_->ForwardTouchEvent(touch_event_); |
+ touch_event_.touchesLength = 0; |
+} |
+ |
+WebKit::WebTouchPoint* RenderWidgetHostViewWin::AddTouchPoint( |
+ TOUCHINPUT* touch_input) { |
+ if (touch_event_.touchesLength >= WebKit::WebTouchEvent::touchesLengthCap) |
+ return NULL; |
+ WebKit::WebTouchPoint* point = |
+ &touch_event_.touches[touch_event_.touchesLength++]; |
+ point->state = WebKit::WebTouchPoint::StatePressed; |
+ point->id = touch_input->dwID; |
+ UpdateTouchPoint(point, touch_input); |
+ return point; |
+} |
+ |
+bool RenderWidgetHostViewWin::UpdateTouchPoint( |
+ WebKit::WebTouchPoint* touch_point, |
+ TOUCHINPUT* touch_input) { |
+ CPoint coordinates(TOUCH_COORD_TO_PIXEL(touch_input->x), |
+ TOUCH_COORD_TO_PIXEL(touch_input->y)); |
+ int radius_x = 0; |
+ int radius_y = 0; |
+ if (touch_input->dwMask & TOUCHINPUTMASKF_CONTACTAREA) { |
+ radius_x = TOUCH_COORD_TO_PIXEL(touch_input->cxContact); |
+ radius_y = TOUCH_COORD_TO_PIXEL(touch_input->cyContact); |
+ } |
+ |
+ // Detect and exclude stationary moves. |
+ if (touch_point->state == WebKit::WebTouchPoint::StateMoved && |
+ touch_point->screenPosition.x == coordinates.x && |
+ touch_point->screenPosition.y == coordinates.y && |
+ touch_point->radiusX == radius_x && |
+ touch_point->radiusY == radius_y) { |
+ touch_point->state = WebKit::WebTouchPoint::StateStationary; |
+ return true; |
+ } |
+ |
+ touch_point->screenPosition.x = coordinates.x; |
+ touch_point->screenPosition.y = coordinates.y; |
+ GetParent().ScreenToClient(&coordinates); |
+ touch_point->position.x = coordinates.x; |
+ touch_point->position.y = coordinates.y; |
+ touch_point->radiusX = radius_x; |
+ touch_point->radiusY = radius_y; |
+ touch_point->force = 1.0; |
+ touch_point->rotationAngle = 0; |
+ return false; |
+} |
+ |
+LRESULT RenderWidgetHostViewWin::OnTouchEvent(UINT message, WPARAM wparam, |
+ LPARAM lparam, BOOL& handled) { |
+ unsigned int touches_down = 0; |
+ unsigned int touches_up = 0; |
+ unsigned int touches_moved = 0; |
+ // TODO(jschuh): Add support for an arbitrary number of touchpoints. |
+ size_t points_count = std::min(static_cast<int>(LOWORD(wparam)), |
+ static_cast<int>(WebKit::WebTouchEvent::touchesLengthCap)); |
+ TOUCHINPUT points[WebKit::WebTouchEvent::touchesLengthCap]; |
+ |
+ if (points_count > WebKit::WebTouchEvent::touchesLengthCap) |
+ points_count = WebKit::WebTouchEvent::touchesLengthCap; |
+ if (!points_count || !GetTouchInputInfo((HTOUCHINPUT)lparam, points_count, |
+ points, sizeof(TOUCHINPUT))) { |
+ return 0; |
+ } |
+ touch_event_.changedTouchesLength = 0; |
+ |
+ for (size_t i = 0; i < points_count; i++) { |
+ if (points[i].dwID == 0ul) |
+ continue; |
+ |
+ WebKit::WebTouchPoint* point = NULL; |
+ for (unsigned j = 0; j < touch_event_.touchesLength; ++j) { |
+ if (static_cast<DWORD>(touch_event_.touches[j].id) == points[i].dwID) { |
+ point = &touch_event_.touches[j]; |
+ break; |
+ } |
+ } |
+ |
+ // Use a move instead if we see a down on a point we already have. |
+ if (point && (points[i].dwFlags & 0x7) == TOUCHEVENTF_DOWN) |
+ points[i].dwFlags = (points[i].dwFlags & ~0x7) | TOUCHEVENTF_MOVE; |
+ |
+ switch (points[i].dwFlags & 0x7) { |
+ case TOUCHEVENTF_DOWN: { |
+ if (!(point = AddTouchPoint(&points[i]))) |
+ continue; |
+ ++touches_down; |
+ break; |
+ } |
+ |
+ case TOUCHEVENTF_UP: { |
+ if (!point) |
+ continue; |
+ point->state = WebKit::WebTouchPoint::StateReleased; |
+ UpdateTouchPoint(point, &points[i]); |
+ ++touches_up; |
+ break; |
+ } |
+ |
+ case TOUCHEVENTF_MOVE: { |
+ if (point) { |
+ point->state = WebKit::WebTouchPoint::StateMoved; |
+ // Don't update the message if the point didn't really move. |
+ if (UpdateTouchPoint(point, &points[i])) |
+ continue; |
+ ++touches_moved; |
+ } else { // Add a new point if we missed the TOUCHEVENTF_DOWN |
+ if (!(point = AddTouchPoint(&points[i]))) |
+ continue; |
+ ++touches_down; |
+ } |
+ break; |
+ } |
+ |
+ default: |
+ NOTREACHED(); |
+ continue; |
+ } |
+ touch_event_.changedTouches[touch_event_.changedTouchesLength++] = *point; |
+ } |
+ |
+ CloseTouchInputHandle((HTOUCHINPUT)lparam); |
+ |
+ // Set the event type based on what we've received. |
+ if (touches_down) |
+ touch_event_.type = WebKit::WebInputEvent::TouchStart; |
+ else if (touches_up) |
+ touch_event_.type = WebKit::WebInputEvent::TouchEnd; |
+ else if (touches_moved) |
+ touch_event_.type = WebKit::WebInputEvent::TouchMove; |
+ else |
+ touch_event_.type = WebKit::WebInputEvent::Undefined; |
+ |
+ // Forward the event only when there's a legitimate change. |
+ if (touch_event_.changedTouchesLength) |
+ render_widget_host_->ForwardTouchEvent(touch_event_); |
+ |
+ // Clean up released touches and reset everything else to staitonary. |
+ WebKit::WebTouchPoint* point = touch_event_.touches; |
+ WebKit::WebTouchPoint* end = |
+ &touch_event_.touches[touch_event_.touchesLength]; |
+ while (point < end) { |
+ if (point->state == WebKit::WebTouchPoint::StateReleased) { |
+ *point = *(--end); |
+ --touch_event_.touchesLength; |
+ } else { |
+ point->state = WebKit::WebTouchPoint::StateStationary; |
+ point++; |
+ } |
+ } |
+ |
+ return 0; |
+} |
+ |
LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT message, |
WPARAM wparam, |
LPARAM lparam, |