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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « views/touchui/touch_event_dispatcher_gtk.h ('k') | views/views.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // This file contains a function that receives a message from the message pump
6 // and dispatches that message to the appropriate root view. That function is
7 // 'DispatchEventForTouchUIGtk'. (Last function in this file.)
8 //
9 // The appropriate RootView is determined for each incoming event. The platform
10 // specific event is converted to a views event and dispatched directly to the
11 // appropriate RootView.
12 //
13 // This implementation is Gdk specific at the moment, but a future CL will
14 // provide a dispatcher that handles events from an X Windows message pump.
15
16 // TODO(wyck): Make X Windows versions of all GdkEvent functions.
17 // (See individual TODO's below)
18 //
19 // When we switch the message pump from one that gives us GdkEvents to one that
20 // gives us X Windows events, we will need another version of each function.
21 // These ones are obviously specific to GdkEvent.
22 //
23 // Potential names:
24 // Maybe DispatchEventForTouchUIGtk will become DispatchEventForTouchUIX11.
25 //
26 // It may not be necessary to filter events with IsTouchEvent in the X version,
27 // because the message pump may pre-filter the message so that we get only
28 // touch events and there is nothing to filter out.
29
30 #include <gdk/gdk.h>
31 #include <gdk/gdkx.h>
32
33 #include "views/widget/root_view.h"
34 #include "views/widget/widget_gtk.h"
35
36 namespace views {
37
38 // gets the RootView associated with the GdkEvent.
39 //
40 // TODO(wyck): Make X Windows version of this function. (see earlier comment)
41 static RootView* FindRootViewForGdkEvent(GdkEvent* event) {
42 GdkEventAny* event_any = reinterpret_cast<GdkEventAny*>(event);
43 if (!event_any) {
44 DLOG(WARNING) << "FindRootViewForGdkEvent was passed a null GdkEvent";
45 return NULL;
46 }
47 GdkWindow* gdk_window = event_any->window;
48
49 // and get the parent
50 gpointer data = NULL;
51 gdk_window_get_user_data(gdk_window, &data);
52 GtkWidget* gtk_widget = reinterpret_cast<GtkWidget*>(data);
53 if (!gtk_widget) {
54 DLOG(WARNING) << "no GtkWidget found for that GdkWindow";
55 return NULL;
56 }
57 WidgetGtk* widget_gtk = WidgetGtk::GetViewForNative(gtk_widget);
58
59 if (!widget_gtk) {
60 DLOG(WARNING) << "no WidgetGtk found for that GtkWidget";
61 return NULL;
62 }
63 return widget_gtk->GetRootView();
64 }
65
66 // Specialized dispatch for GDK_BUTTON_PRESS events
67 static void DispatchButtonPressGtk(const GdkEventButton& event,
68 RootView* root_view) {
69 // TODO(wyck): may need to remap coordinates:
70 // If so, it's like this:
71 // gdk_window_get_root_origin(dest, &dest_x, &dest_y);
72 // *x = event->x_root - dest_x;
73 // *y = event->y_root - dest_y;
74
75 if (event.type == GDK_2BUTTON_PRESS || event.type == GDK_3BUTTON_PRESS) {
76 // TODO(wyck): decide what to do about 2 button and 3 button press msgs.
77 // You get both a GDK_BUTTON_PRESS and a GDK_2BUTTON_PRESS, so that's
78 // a bit weird.
79 // I'll ignore these events for now.
80 return;
81 }
82
83 MouseEvent mouse_pressed(Event::ET_MOUSE_PRESSED, event.x, event.y,
84 WidgetGtk::GetFlagsForEventButton(event));
85 root_view->OnMousePressed(mouse_pressed);
86 }
87
88 // Specialized dispatch for GDK_BUTTON_RELEASE events
89 static void DispatchButtonReleaseGtk(const GdkEventButton& event,
90 RootView* root_view) {
91 // TODO(wyck): may need to remap coordinates.
92 // If so, it's like this:
93 // gdk_window_get_root_origin(dest, &dest_x, &dest_y);
94 // *x = event->x_root - dest_x;
95 // *y = event->y_root - dest_y;
96
97 MouseEvent mouse_up(Event::ET_MOUSE_RELEASED, event.x, event.y,
98 WidgetGtk::GetFlagsForEventButton(event));
99
100 root_view->OnMouseReleased(mouse_up, false);
101 }
102
103 // Specialized dispatch for GDK_MOTION_NOTIFY events
104 static void DispatchMotionNotifyGtk(const GdkEventMotion& event,
105 RootView* root_view) {
106 // Regarding GDK_POINTER_MOTION_HINT_MASK:
107 // GDK_POINTER_MOTION_HINT_MASK may have been used to reduce the number of
108 // GDK_MOTION_NOTIFY events received. Normally a GDK_MOTION_NOTIFY event is
109 // received each time the mouse moves. But in the hint case, some events are
110 // marked with is_hint TRUE. Without further action after a hint, no more
111 // motion events will be received.
112 // To receive more motion events after a motion hint event, the application
113 // needs to ask for more by calling gdk_event_request_motions().
114 if (event.is_hint) {
115 gdk_event_request_motions(&event);
116 }
117
118 // TODO(wyck): handle dragging
119 // Apparently it's our job to determine the difference between a move and a
120 // drag. We should dispatch OnMouseDragged with ET_MOUSE_DRAGGED instead.
121 // It's unclear what constitutes the dragging state. Which button(s)?
122 int flags = Event::GetFlagsFromGdkState(event.state);
123 MouseEvent mouse_move(Event::ET_MOUSE_MOVED, event.x, event.y, flags);
124 root_view->OnMouseMoved(mouse_move);
125 }
126
127 // Specialized dispatch for GDK_ENTER_NOTIFY events
128 static void DispatchEnterNotifyGtk(const GdkEventCrossing& event,
129 RootView* root_view) {
130 // TODO(wyck): I'm not sure if this is necessary yet
131 int flags = (Event::GetFlagsFromGdkState(event.state) &
132 ~(Event::EF_LEFT_BUTTON_DOWN |
133 Event::EF_MIDDLE_BUTTON_DOWN |
134 Event::EF_RIGHT_BUTTON_DOWN));
135 MouseEvent mouse_move(Event::ET_MOUSE_MOVED, event.x, event.y, flags);
136 root_view->OnMouseMoved(mouse_move);
137 }
138
139 // Specialized dispatch for GDK_LEAVE_NOTIFY events
140 static void DispatchLeaveNotifyGtk(const GdkEventCrossing& event,
141 RootView* root_view) {
142 // TODO(wyck): I'm not sure if this is necessary yet
143 root_view->ProcessOnMouseExited();
144 }
145
146 // Dispatch an input-related GdkEvent to a RootView
147 static void DispatchEventToRootViewGtk(GdkEvent* event, RootView* root_view) {
148 if (!event) {
149 DLOG(WARNING) << "DispatchEventToRootView was passed a null GdkEvent";
150 return;
151 }
152 if (!root_view) {
153 DLOG(WARNING) << "DispatchEventToRootView was passed a null RootView";
154 return;
155 }
156 switch (event->type) {
157 case GDK_BUTTON_PRESS:
158 DispatchButtonPressGtk(*reinterpret_cast<GdkEventButton*>(event),
159 root_view);
160 break;
161 case GDK_BUTTON_RELEASE:
162 DispatchButtonReleaseGtk(*reinterpret_cast<GdkEventButton*>(event),
163 root_view);
164 break;
165 case GDK_MOTION_NOTIFY:
166 DispatchMotionNotifyGtk(*reinterpret_cast<GdkEventMotion*>(event),
167 root_view);
168 break;
169 case GDK_ENTER_NOTIFY:
170 DispatchEnterNotifyGtk(*reinterpret_cast<GdkEventCrossing*>(event),
171 root_view);
172 break;
173 case GDK_LEAVE_NOTIFY:
174 DispatchLeaveNotifyGtk(*reinterpret_cast<GdkEventCrossing*>(event),
175 root_view);
176 break;
177 case GDK_2BUTTON_PRESS:
178 DispatchButtonPressGtk(*reinterpret_cast<GdkEventButton*>(event),
179 root_view);
180 break;
181 case GDK_3BUTTON_PRESS:
182 DispatchButtonPressGtk(*reinterpret_cast<GdkEventButton*>(event),
183 root_view);
184 break;
185 default:
186 NOTREACHED();
187 break;
188 }
189 }
190
191 // Called for input-related events only. Dispatches them directly to the
192 // associated RootView.
193 //
194 // TODO(wyck): Make X Windows version of this function. (see earlier comment)
195 static void HijackEventForTouchUIGtk(GdkEvent* event) {
196 // TODO(wyck): something like this...
197 RootView* root_view = FindRootViewForGdkEvent(event);
198 if (!root_view) {
199 DLOG(WARNING) << "no RootView found for that GdkEvent";
200 return;
201 }
202 DispatchEventToRootViewGtk(event, root_view);
203 }
204
205 // returns true if the GdkEvent is a touch-related input event.
206 //
207 // TODO(wyck): Make X Windows version of this function. (see earlier comment)
208 //
209 // If the X Windows events are not-prefiltered, then we can provide a filtering
210 // function similar to this GdkEvent-specific function. Otherwise this function
211 // is not needed at all for the X Windows version.
212 static bool IsTouchEventGtk(GdkEvent* event) {
213 switch (event->type) {
214 case GDK_BUTTON_PRESS:
215 case GDK_BUTTON_RELEASE:
216 case GDK_MOTION_NOTIFY:
217 case GDK_ENTER_NOTIFY:
218 case GDK_LEAVE_NOTIFY:
219 case GDK_2BUTTON_PRESS:
220 case GDK_3BUTTON_PRESS:
221 return true;
222 default:
223 return false;
224 }
225 }
226
227 // This is the public entry point for the touch event dispatcher.
228 //
229 // Hijacks input-related events and routes them directly to a widget_gtk.
230 // Returns false for non-input-related events, in which case the caller is still
231 // responsible for dispatching the event.
232 //
233 // TODO(wyck): Make X Windows version of this function. (see earlier comment)
234 bool DispatchEventForTouchUIGtk(GdkEvent* event) {
235 // is this is an input-related event...
236 if (IsTouchEventGtk(event)) {
237 HijackEventForTouchUIGtk(event);
238 return true;
239 } else {
240 return false;
241 }
242 }
243 } // namespace views
OLDNEW
« 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