1/*
2 * Copyright (C) 2011 Igalia S.L.
3 * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#include "config.h"
22#include "WebViewTest.h"
23
24#include <WebCore/GUniquePtrGtk.h>
25#include <gtk/gtk.h>
26
27void WebViewTest::platformDestroy()
28{
29 if (m_parentWindow)
30 gtk_widget_destroy(m_parentWindow);
31}
32
33void WebViewTest::platformInitializeWebView()
34{
35 g_assert_true(WEBKIT_WEB_VIEW(m_webView));
36 g_assert_true(g_object_is_floating(m_webView));
37 g_object_ref_sink(m_webView);
38}
39
40void WebViewTest::quitMainLoopAfterProcessingPendingEvents()
41{
42 while (gtk_events_pending())
43 gtk_main_iteration();
44 quitMainLoop();
45}
46
47void WebViewTest::resizeView(int width, int height)
48{
49 GtkAllocation allocation;
50 gtk_widget_get_allocation(GTK_WIDGET(m_webView), &allocation);
51 if (width != -1)
52 allocation.width = width;
53 if (height != -1)
54 allocation.height = height;
55 gtk_widget_size_allocate(GTK_WIDGET(m_webView), &allocation);
56}
57
58void WebViewTest::hideView()
59{
60 gtk_widget_hide(GTK_WIDGET(m_webView));
61}
62
63static gboolean parentWindowMapped(GtkWidget* widget, GdkEvent*, WebViewTest* test)
64{
65 g_signal_handlers_disconnect_by_func(widget, reinterpret_cast<void*>(parentWindowMapped), test);
66 g_main_loop_quit(test->m_mainLoop);
67
68 return FALSE;
69}
70
71void WebViewTest::showInWindow(GtkWindowType windowType)
72{
73 g_assert_null(m_parentWindow);
74 m_parentWindow = gtk_window_new(windowType);
75 gtk_container_add(GTK_CONTAINER(m_parentWindow), GTK_WIDGET(m_webView));
76 gtk_widget_show(GTK_WIDGET(m_webView));
77 gtk_widget_show(m_parentWindow);
78}
79
80void WebViewTest::showInWindowAndWaitUntilMapped(GtkWindowType windowType, int width, int height)
81{
82 g_assert_null(m_parentWindow);
83 m_parentWindow = gtk_window_new(windowType);
84 if (width && height)
85 gtk_window_resize(GTK_WINDOW(m_parentWindow), width, height);
86 gtk_container_add(GTK_CONTAINER(m_parentWindow), GTK_WIDGET(m_webView));
87 gtk_widget_show(GTK_WIDGET(m_webView));
88
89 g_signal_connect(m_parentWindow, "map-event", G_CALLBACK(parentWindowMapped), this);
90 gtk_widget_show(m_parentWindow);
91 g_main_loop_run(m_mainLoop);
92}
93
94void WebViewTest::mouseMoveTo(int x, int y, unsigned mouseModifiers)
95{
96 g_assert_nonnull(m_parentWindow);
97 GtkWidget* viewWidget = GTK_WIDGET(m_webView);
98 g_assert_true(gtk_widget_get_realized(viewWidget));
99
100 GUniquePtr<GdkEvent> event(gdk_event_new(GDK_MOTION_NOTIFY));
101 event->motion.x = x;
102 event->motion.y = y;
103
104 event->motion.time = GDK_CURRENT_TIME;
105 event->motion.window = gtk_widget_get_window(viewWidget);
106 g_object_ref(event->motion.window);
107 event->motion.device = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(viewWidget)));
108 event->motion.state = mouseModifiers;
109 event->motion.axes = 0;
110
111 int xRoot, yRoot;
112 gdk_window_get_root_coords(gtk_widget_get_window(viewWidget), x, y, &xRoot, &yRoot);
113 event->motion.x_root = xRoot;
114 event->motion.y_root = yRoot;
115 gtk_main_do_event(event.get());
116}
117
118void WebViewTest::clickMouseButton(int x, int y, unsigned button, unsigned mouseModifiers)
119{
120 doMouseButtonEvent(GDK_BUTTON_PRESS, x, y, button, mouseModifiers);
121 doMouseButtonEvent(GDK_BUTTON_RELEASE, x, y, button, mouseModifiers);
122}
123
124void WebViewTest::emitPopupMenuSignal()
125{
126 GtkWidget* viewWidget = GTK_WIDGET(m_webView);
127 g_assert_true(gtk_widget_get_realized(viewWidget));
128
129 gboolean handled;
130 g_signal_emit_by_name(viewWidget, "popup-menu", &handled);
131}
132
133void WebViewTest::keyStroke(unsigned keyVal, unsigned keyModifiers)
134{
135 g_assert_nonnull(m_parentWindow);
136 GtkWidget* viewWidget = GTK_WIDGET(m_webView);
137 g_assert_true(gtk_widget_get_realized(viewWidget));
138
139 GUniquePtr<GdkEvent> event(gdk_event_new(GDK_KEY_PRESS));
140 event->key.keyval = keyVal;
141
142 event->key.time = GDK_CURRENT_TIME;
143 event->key.window = gtk_widget_get_window(viewWidget);
144 g_object_ref(event->key.window);
145 gdk_event_set_device(event.get(), gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(viewWidget))));
146 event->key.state = keyModifiers;
147
148 // When synthesizing an event, an invalid hardware_keycode value can cause it to be badly processed by GTK+.
149 GUniqueOutPtr<GdkKeymapKey> keys;
150 int keysCount;
151 if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount) && keysCount)
152 event->key.hardware_keycode = keys.get()[0].keycode;
153
154 gtk_main_do_event(event.get());
155 event->key.type = GDK_KEY_RELEASE;
156 gtk_main_do_event(event.get());
157}
158
159void WebViewTest::doMouseButtonEvent(GdkEventType eventType, int x, int y, unsigned button, unsigned mouseModifiers)
160{
161 g_assert_nonnull(m_parentWindow);
162 GtkWidget* viewWidget = GTK_WIDGET(m_webView);
163 g_assert_true(gtk_widget_get_realized(viewWidget));
164
165 GUniquePtr<GdkEvent> event(gdk_event_new(eventType));
166 event->button.window = gtk_widget_get_window(viewWidget);
167 g_object_ref(event->button.window);
168
169 event->button.time = GDK_CURRENT_TIME;
170 event->button.x = x;
171 event->button.y = y;
172 event->button.axes = 0;
173 event->button.state = mouseModifiers;
174 event->button.button = button;
175
176 event->button.device = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(viewWidget)));
177
178 int xRoot, yRoot;
179 gdk_window_get_root_coords(gtk_widget_get_window(viewWidget), x, y, &xRoot, &yRoot);
180 event->button.x_root = xRoot;
181 event->button.y_root = yRoot;
182 gtk_main_do_event(event.get());
183}
184