| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/automation/ui_controls.h" | 5 #include "chrome/browser/automation/ui_controls.h" |
| 6 | 6 |
| 7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 #include <gdk/gdkkeysyms.h> | 8 #include <gdk/gdkkeysyms.h> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "chrome/test/automation/automation_constants.h" | 12 #include "chrome/test/automation/automation_constants.h" |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 guint32 EventTimeNow() { |
| 17 struct timespec ts; |
| 18 clock_gettime(CLOCK_MONOTONIC, &ts); |
| 19 return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; |
| 20 } |
| 21 |
| 16 class EventWaiter : public MessageLoopForUI::Observer { | 22 class EventWaiter : public MessageLoopForUI::Observer { |
| 17 public: | 23 public: |
| 18 EventWaiter(Task* task, GdkEventType type) : task_(task), type_(type) { | 24 EventWaiter(Task* task, GdkEventType type) : task_(task), type_(type) { |
| 19 MessageLoopForUI::current()->AddObserver(this); | 25 MessageLoopForUI::current()->AddObserver(this); |
| 20 } | 26 } |
| 21 | 27 |
| 22 virtual ~EventWaiter() { | 28 virtual ~EventWaiter() { |
| 23 MessageLoopForUI::current()->RemoveObserver(this); | 29 MessageLoopForUI::current()->RemoveObserver(this); |
| 24 } | 30 } |
| 25 | 31 |
| 26 // MessageLoop::Observer implementation: | 32 // MessageLoop::Observer implementation: |
| 27 virtual void WillProcessEvent(GdkEvent* event) { | 33 virtual void WillProcessEvent(GdkEvent* event) { |
| 28 // No-op. | 34 // No-op. |
| 29 } | 35 } |
| 30 | 36 |
| 31 virtual void DidProcessEvent(GdkEvent* event) { | 37 virtual void DidProcessEvent(GdkEvent* event) { |
| 32 if (event->any.type == type_) { | 38 if (event->any.type == type_) { |
| 33 task_->Run(); | 39 task_->Run(); |
| 34 delete this; | 40 delete this; |
| 35 } | 41 } |
| 36 } | 42 } |
| 37 | 43 |
| 38 private: | 44 private: |
| 39 Task* task_; | 45 scoped_ptr<Task> task_; |
| 40 GdkEventType type_; | 46 GdkEventType type_; |
| 41 }; | 47 }; |
| 42 | 48 |
| 43 } // namespace | 49 } // namespace |
| 44 | 50 |
| 45 namespace ui_controls { | 51 namespace ui_controls { |
| 46 | 52 |
| 47 bool SendKeyPress(gfx::NativeWindow window, | 53 bool SendKeyPress(gfx::NativeWindow window, |
| 48 wchar_t key, bool control, bool shift, bool alt) { | 54 wchar_t key, bool control, bool shift, bool alt) { |
| 49 // TODO(estade): send a release as well? | 55 // TODO(estade): send a release as well? |
| 50 GdkEvent* event = gdk_event_new(GDK_KEY_PRESS); | 56 GdkEvent* event = gdk_event_new(GDK_KEY_PRESS); |
| 51 | 57 |
| 52 event->key.type = GDK_KEY_PRESS; | 58 event->key.type = GDK_KEY_PRESS; |
| 53 event->key.window = GTK_WIDGET(window)->window; | 59 event->key.window = GTK_WIDGET(window)->window; |
| 54 g_object_ref(event->key.window); | 60 g_object_ref(event->key.window); |
| 55 event->key.send_event = false; | 61 event->key.send_event = false; |
| 56 | 62 event->key.time = EventTimeNow(); |
| 57 struct timespec ts; | |
| 58 clock_gettime(CLOCK_MONOTONIC, &ts); | |
| 59 event->key.time = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; | |
| 60 | 63 |
| 61 // TODO(estade): handle other state flags besides control, shift, alt? | 64 // TODO(estade): handle other state flags besides control, shift, alt? |
| 62 // For example caps lock. | 65 // For example caps lock. |
| 63 event->key.state = (control ? GDK_CONTROL_MASK : 0) | | 66 event->key.state = (control ? GDK_CONTROL_MASK : 0) | |
| 64 (shift ? GDK_SHIFT_MASK : 0) | | 67 (shift ? GDK_SHIFT_MASK : 0) | |
| 65 (alt ? GDK_MOD1_MASK : 0); | 68 (alt ? GDK_MOD1_MASK : 0); |
| 66 event->key.keyval = key; | 69 event->key.keyval = key; |
| 67 // TODO(estade): fill in the string? | 70 // TODO(estade): fill in the string? |
| 68 | 71 |
| 69 GdkKeymapKey* keys; | 72 GdkKeymapKey* keys; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 83 } | 86 } |
| 84 | 87 |
| 85 bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window, wchar_t key, | 88 bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window, wchar_t key, |
| 86 bool control, bool shift, | 89 bool control, bool shift, |
| 87 bool alt, Task* task) { | 90 bool alt, Task* task) { |
| 88 // This object will delete itself after running |task|. | 91 // This object will delete itself after running |task|. |
| 89 new EventWaiter(task, GDK_KEY_PRESS); | 92 new EventWaiter(task, GDK_KEY_PRESS); |
| 90 return SendKeyPress(window, key, control, shift, alt); | 93 return SendKeyPress(window, key, control, shift, alt); |
| 91 } | 94 } |
| 92 | 95 |
| 93 // TODO(estade): this appears to be unused on Windows. Can we remove it? | 96 bool SendMouseMove(long x, long y) { |
| 94 bool SendKeyDown(wchar_t key) { | 97 gdk_display_warp_pointer(gdk_display_get_default(), gdk_screen_get_default(), |
| 95 NOTIMPLEMENTED(); | 98 x, y); |
| 99 return true; |
| 100 } |
| 101 |
| 102 bool SendMouseMoveNotifyWhenDone(long x, long y, Task* task) { |
| 103 bool rv = SendMouseMove(x, y); |
| 104 // We can't rely on any particular event signalling the completion of the |
| 105 // mouse move. Posting the task to the message loop should gaurantee |
| 106 // the pointer has moved before task is run (although it may not run it as |
| 107 // soon as it could). |
| 108 MessageLoop::current()->PostTask(FROM_HERE, task); |
| 109 return rv; |
| 110 } |
| 111 |
| 112 bool SendMouseClick(const gfx::Point& point, MouseButton type) { |
| 113 GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS); |
| 114 |
| 115 event->button.window = gdk_window_at_pointer(NULL, NULL); |
| 116 g_object_ref(event->button.window); |
| 117 event->button.send_event = false; |
| 118 event->button.time = EventTimeNow(); |
| 119 |
| 120 event->motion.x_root = point.x(); |
| 121 event->motion.y_root = point.x(); |
| 122 gint origin_x, origin_y; |
| 123 gdk_window_get_origin(event->button.window, &origin_x, &origin_y); |
| 124 event->button.x = point.x() - origin_x; |
| 125 event->button.y = point.y() - origin_y; |
| 126 |
| 127 event->button.axes = NULL; |
| 128 // TODO(estade): as above, we may want to pack this with the actual state. |
| 129 event->button.state = 0; |
| 130 event->button.button = type == LEFT ? 1 : (type == MIDDLE ? 2 : 3); |
| 131 event->button.device = gdk_device_get_core_pointer(); |
| 132 |
| 133 event->button.type = GDK_BUTTON_PRESS; |
| 134 gdk_event_put(event); |
| 135 |
| 136 // Also send a release event. |
| 137 GdkEvent* release_event = gdk_event_copy(event); |
| 138 release_event->button.type = GDK_BUTTON_RELEASE; |
| 139 release_event->button.time++; |
| 140 gdk_event_put(release_event); |
| 141 |
| 142 gdk_event_free(event); |
| 143 gdk_event_free(release_event); |
| 144 |
| 96 return false; | 145 return false; |
| 97 } | 146 } |
| 98 | 147 |
| 99 // TODO(estade): this appears to be unused on Windows. Can we remove it? | |
| 100 bool SendKeyUp(wchar_t key) { | |
| 101 NOTIMPLEMENTED(); | |
| 102 return false; | |
| 103 } | |
| 104 | |
| 105 bool SendMouseMove(long x, long y) { | |
| 106 NOTIMPLEMENTED(); | |
| 107 return false; | |
| 108 } | |
| 109 | |
| 110 void SendMouseMoveNotifyWhenDone(long x, long y, Task* task) { | |
| 111 NOTIMPLEMENTED(); | |
| 112 } | |
| 113 | |
| 114 bool SendMouseClick(gfx::NativeWindow window, const gfx::Point& point, | |
| 115 MouseButton type) { | |
| 116 NOTIMPLEMENTED(); | |
| 117 return false; | |
| 118 } | |
| 119 | |
| 120 // TODO(estade): need to figure out a better type for this than View. | 148 // TODO(estade): need to figure out a better type for this than View. |
| 121 void MoveMouseToCenterAndPress(views::View* view, | 149 void MoveMouseToCenterAndPress(views::View* view, |
| 122 MouseButton button, | 150 MouseButton button, |
| 123 int state, | 151 int state, |
| 124 Task* task) { | 152 Task* task) { |
| 125 NOTIMPLEMENTED(); | 153 NOTIMPLEMENTED(); |
| 126 } | 154 } |
| 127 | 155 |
| 128 } // namespace ui_controls | 156 } // namespace ui_controls |
| OLD | NEW |