Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1915)

Unified Diff: views/touchui/touch_event_dispatcher_gtk.cc

Issue 3704005: Hijack mouse-related events for TOUCH_UI builds (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Refactoring to accomodate both Gtk and X11 easily Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « views/touchui/touch_event_dispatcher_gtk.h ('k') | views/views.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: views/touchui/touch_event_dispatcher_gtk.cc
diff --git a/views/touchui/touch_event_dispatcher_gtk.cc b/views/touchui/touch_event_dispatcher_gtk.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fc4fcd2e91a2c9945cf34b3b937f0d000972c4ce
--- /dev/null
+++ b/views/touchui/touch_event_dispatcher_gtk.cc
@@ -0,0 +1,243 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file contains a function that receives a message from the message pump
+// and dispatches that message to the appropriate root view. That function is
+// 'DispatchEventForTouchUIGtk'. (Last function in this file.)
+//
+// The appropriate RootView is determined for each incoming event. The platform
+// specific event is converted to a views event and dispatched directly to the
+// appropriate RootView.
+//
+// This implementation is Gdk specific at the moment, but a future CL will
+// provide a dispatcher that handles events from an X Windows message pump.
+
+// TODO(wyck): Make X Windows versions of all GdkEvent functions.
+// (See individual TODO's below)
+//
+// When we switch the message pump from one that gives us GdkEvents to one that
+// gives us X Windows events, we will need another version of each function.
+// These ones are obviously specific to GdkEvent.
+//
+// Potential names:
+// Maybe DispatchEventForTouchUIGtk will become DispatchEventForTouchUIX11.
+//
+// It may not be necessary to filter events with IsTouchEvent in the X version,
+// because the message pump may pre-filter the message so that we get only
+// touch events and there is nothing to filter out.
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include "views/widget/root_view.h"
+#include "views/widget/widget_gtk.h"
+
+namespace views {
+
+// gets the RootView associated with the GdkEvent.
+//
+// TODO(wyck): Make X Windows version of this function. (see earlier comment)
+static RootView* FindRootViewForGdkEvent(GdkEvent* event) {
+ GdkEventAny* event_any = reinterpret_cast<GdkEventAny*>(event);
+ if (!event_any) {
+ DLOG(WARNING) << "FindRootViewForGdkEvent was passed a null GdkEvent";
+ return NULL;
+ }
+ GdkWindow* gdk_window = event_any->window;
+
+ // and get the parent
+ gpointer data = NULL;
+ gdk_window_get_user_data(gdk_window, &data);
+ GtkWidget* gtk_widget = reinterpret_cast<GtkWidget*>(data);
+ if (!gtk_widget) {
+ DLOG(WARNING) << "no GtkWidget found for that GdkWindow";
+ return NULL;
+ }
+ WidgetGtk* widget_gtk = WidgetGtk::GetViewForNative(gtk_widget);
+
+ if (!widget_gtk) {
+ DLOG(WARNING) << "no WidgetGtk found for that GtkWidget";
+ return NULL;
+ }
+ return widget_gtk->GetRootView();
+}
+
+// Specialized dispatch for GDK_BUTTON_PRESS events
+static void DispatchButtonPressGtk(const GdkEventButton& event,
+ RootView* root_view) {
+ // TODO(wyck): may need to remap coordinates:
+ // If so, it's like this:
+ // gdk_window_get_root_origin(dest, &dest_x, &dest_y);
+ // *x = event->x_root - dest_x;
+ // *y = event->y_root - dest_y;
+
+ if (event.type == GDK_2BUTTON_PRESS || event.type == GDK_3BUTTON_PRESS) {
+ // TODO(wyck): decide what to do about 2 button and 3 button press msgs.
+ // You get both a GDK_BUTTON_PRESS and a GDK_2BUTTON_PRESS, so that's
+ // a bit weird.
+ // I'll ignore these events for now.
+ return;
+ }
+
+ MouseEvent mouse_pressed(Event::ET_MOUSE_PRESSED, event.x, event.y,
+ WidgetGtk::GetFlagsForEventButton(event));
+ root_view->OnMousePressed(mouse_pressed);
+}
+
+// Specialized dispatch for GDK_BUTTON_RELEASE events
+static void DispatchButtonReleaseGtk(const GdkEventButton& event,
+ RootView* root_view) {
+ // TODO(wyck): may need to remap coordinates.
+ // If so, it's like this:
+ // gdk_window_get_root_origin(dest, &dest_x, &dest_y);
+ // *x = event->x_root - dest_x;
+ // *y = event->y_root - dest_y;
+
+ MouseEvent mouse_up(Event::ET_MOUSE_RELEASED, event.x, event.y,
+ WidgetGtk::GetFlagsForEventButton(event));
+
+ root_view->OnMouseReleased(mouse_up, false);
+}
+
+// Specialized dispatch for GDK_MOTION_NOTIFY events
+static void DispatchMotionNotifyGtk(const GdkEventMotion& event,
+ RootView* root_view) {
+ // Regarding GDK_POINTER_MOTION_HINT_MASK:
+ // GDK_POINTER_MOTION_HINT_MASK may have been used to reduce the number of
+ // GDK_MOTION_NOTIFY events received. Normally a GDK_MOTION_NOTIFY event is
+ // received each time the mouse moves. But in the hint case, some events are
+ // marked with is_hint TRUE. Without further action after a hint, no more
+ // motion events will be received.
+ // To receive more motion events after a motion hint event, the application
+ // needs to ask for more by calling gdk_event_request_motions().
+ if (event.is_hint) {
+ gdk_event_request_motions(&event);
+ }
+
+ // TODO(wyck): handle dragging
+ // Apparently it's our job to determine the difference between a move and a
+ // drag. We should dispatch OnMouseDragged with ET_MOUSE_DRAGGED instead.
+ // It's unclear what constitutes the dragging state. Which button(s)?
+ int flags = Event::GetFlagsFromGdkState(event.state);
+ MouseEvent mouse_move(Event::ET_MOUSE_MOVED, event.x, event.y, flags);
+ root_view->OnMouseMoved(mouse_move);
+}
+
+// Specialized dispatch for GDK_ENTER_NOTIFY events
+static void DispatchEnterNotifyGtk(const GdkEventCrossing& event,
+ RootView* root_view) {
+ // TODO(wyck): I'm not sure if this is necessary yet
+ int flags = (Event::GetFlagsFromGdkState(event.state) &
+ ~(Event::EF_LEFT_BUTTON_DOWN |
+ Event::EF_MIDDLE_BUTTON_DOWN |
+ Event::EF_RIGHT_BUTTON_DOWN));
+ MouseEvent mouse_move(Event::ET_MOUSE_MOVED, event.x, event.y, flags);
+ root_view->OnMouseMoved(mouse_move);
+}
+
+// Specialized dispatch for GDK_LEAVE_NOTIFY events
+static void DispatchLeaveNotifyGtk(const GdkEventCrossing& event,
+ RootView* root_view) {
+ // TODO(wyck): I'm not sure if this is necessary yet
+ root_view->ProcessOnMouseExited();
+}
+
+// Dispatch an input-related GdkEvent to a RootView
+static void DispatchEventToRootViewGtk(GdkEvent* event, RootView* root_view) {
+ if (!event) {
+ DLOG(WARNING) << "DispatchEventToRootView was passed a null GdkEvent";
+ return;
+ }
+ if (!root_view) {
+ DLOG(WARNING) << "DispatchEventToRootView was passed a null RootView";
+ return;
+ }
+ switch (event->type) {
+ case GDK_BUTTON_PRESS:
+ DispatchButtonPressGtk(*reinterpret_cast<GdkEventButton*>(event),
+ root_view);
+ break;
+ case GDK_BUTTON_RELEASE:
+ DispatchButtonReleaseGtk(*reinterpret_cast<GdkEventButton*>(event),
+ root_view);
+ break;
+ case GDK_MOTION_NOTIFY:
+ DispatchMotionNotifyGtk(*reinterpret_cast<GdkEventMotion*>(event),
+ root_view);
+ break;
+ case GDK_ENTER_NOTIFY:
+ DispatchEnterNotifyGtk(*reinterpret_cast<GdkEventCrossing*>(event),
+ root_view);
+ break;
+ case GDK_LEAVE_NOTIFY:
+ DispatchLeaveNotifyGtk(*reinterpret_cast<GdkEventCrossing*>(event),
+ root_view);
+ break;
+ case GDK_2BUTTON_PRESS:
+ DispatchButtonPressGtk(*reinterpret_cast<GdkEventButton*>(event),
+ root_view);
+ break;
+ case GDK_3BUTTON_PRESS:
+ DispatchButtonPressGtk(*reinterpret_cast<GdkEventButton*>(event),
+ root_view);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+// Called for input-related events only. Dispatches them directly to the
+// associated RootView.
+//
+// TODO(wyck): Make X Windows version of this function. (see earlier comment)
+static void HijackEventForTouchUIGtk(GdkEvent* event) {
+ // TODO(wyck): something like this...
+ RootView* root_view = FindRootViewForGdkEvent(event);
+ if (!root_view) {
+ DLOG(WARNING) << "no RootView found for that GdkEvent";
+ return;
+ }
+ DispatchEventToRootViewGtk(event, root_view);
+}
+
+// returns true if the GdkEvent is a touch-related input event.
+//
+// TODO(wyck): Make X Windows version of this function. (see earlier comment)
+//
+// If the X Windows events are not-prefiltered, then we can provide a filtering
+// function similar to this GdkEvent-specific function. Otherwise this function
+// is not needed at all for the X Windows version.
+static bool IsTouchEventGtk(GdkEvent* event) {
+ switch (event->type) {
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_MOTION_NOTIFY:
+ case GDK_ENTER_NOTIFY:
+ case GDK_LEAVE_NOTIFY:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// This is the public entry point for the touch event dispatcher.
+//
+// Hijacks input-related events and routes them directly to a widget_gtk.
+// Returns false for non-input-related events, in which case the caller is still
+// responsible for dispatching the event.
+//
+// TODO(wyck): Make X Windows version of this function. (see earlier comment)
+bool DispatchEventForTouchUIGtk(GdkEvent* event) {
+ // is this is an input-related event...
+ if (IsTouchEventGtk(event)) {
+ HijackEventForTouchUIGtk(event);
+ return true;
+ } else {
+ return false;
+ }
+}
+} // namespace views
« no previous file with comments | « views/touchui/touch_event_dispatcher_gtk.h ('k') | views/views.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698