hw/hppa/Kconfig: Fix building with "configure --without-default-devices"
[qemu/ar7.git] / tests / qtest / dbus-display-test.c
blob21edaa1e321fd108f1a3f0a871fd984c46f8d68a
1 #include "qemu/osdep.h"
2 #include "qemu/sockets.h"
3 #include "qemu/dbus.h"
4 #include "qemu/sockets.h"
5 #include <gio/gio.h>
6 #include <gio/gunixfdlist.h>
7 #include "libqtest.h"
8 #include "ui/dbus-display1.h"
10 static GDBusConnection*
11 test_dbus_p2p_from_fd(int fd)
13 g_autoptr(GError) err = NULL;
14 g_autoptr(GSocket) socket = NULL;
15 g_autoptr(GSocketConnection) socketc = NULL;
16 GDBusConnection *conn;
18 #ifdef WIN32
19 socket = g_socket_new_from_fd(_get_osfhandle(fd), &err);
20 #else
21 socket = g_socket_new_from_fd(fd, &err);
22 #endif
23 g_assert_no_error(err);
25 socketc = g_socket_connection_factory_create_connection(socket);
26 g_assert(socketc != NULL);
28 conn = g_dbus_connection_new_sync(
29 G_IO_STREAM(socketc), NULL,
30 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
31 G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING,
32 NULL, NULL, &err);
33 g_assert_no_error(err);
35 return conn;
38 static void
39 test_setup(QTestState **qts, GDBusConnection **conn)
41 int pair[2];
43 *qts = qtest_init("-display dbus,p2p=yes -name dbus-test");
45 g_assert_cmpint(qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, pair), ==, 0);
47 qtest_qmp_add_client(*qts, "@dbus-display", pair[1]);
49 *conn = test_dbus_p2p_from_fd(pair[0]);
50 g_dbus_connection_start_message_processing(*conn);
53 static void
54 test_dbus_display_vm(void)
56 g_autoptr(GError) err = NULL;
57 g_autoptr(GDBusConnection) conn = NULL;
58 g_autoptr(QemuDBusDisplay1VMProxy) vm = NULL;
59 QTestState *qts = NULL;
61 test_setup(&qts, &conn);
63 vm = QEMU_DBUS_DISPLAY1_VM_PROXY(
64 qemu_dbus_display1_vm_proxy_new_sync(
65 conn,
66 G_DBUS_PROXY_FLAGS_NONE,
67 NULL,
68 DBUS_DISPLAY1_ROOT "/VM",
69 NULL,
70 &err));
71 g_assert_no_error(err);
73 g_assert_cmpstr(
74 qemu_dbus_display1_vm_get_name(QEMU_DBUS_DISPLAY1_VM(vm)),
75 ==,
76 "dbus-test");
77 qtest_quit(qts);
80 typedef struct TestDBusConsoleRegister {
81 GMainLoop *loop;
82 GThread *thread;
83 GDBusConnection *listener_conn;
84 GDBusObjectManagerServer *server;
85 } TestDBusConsoleRegister;
87 static gboolean listener_handle_scanout(
88 QemuDBusDisplay1Listener *object,
89 GDBusMethodInvocation *invocation,
90 guint arg_width,
91 guint arg_height,
92 guint arg_stride,
93 guint arg_pixman_format,
94 GVariant *arg_data,
95 TestDBusConsoleRegister *test)
97 g_main_loop_quit(test->loop);
99 return DBUS_METHOD_INVOCATION_HANDLED;
102 static void
103 test_dbus_console_setup_listener(TestDBusConsoleRegister *test)
105 g_autoptr(GDBusObjectSkeleton) listener = NULL;
106 g_autoptr(QemuDBusDisplay1ListenerSkeleton) iface = NULL;
108 test->server = g_dbus_object_manager_server_new(DBUS_DISPLAY1_ROOT);
109 listener = g_dbus_object_skeleton_new(DBUS_DISPLAY1_ROOT "/Listener");
110 iface = QEMU_DBUS_DISPLAY1_LISTENER_SKELETON(
111 qemu_dbus_display1_listener_skeleton_new());
112 g_object_connect(iface,
113 "signal::handle-scanout", listener_handle_scanout, test,
114 NULL);
115 g_dbus_object_skeleton_add_interface(listener,
116 G_DBUS_INTERFACE_SKELETON(iface));
117 g_dbus_object_manager_server_export(test->server, listener);
118 g_dbus_object_manager_server_set_connection(test->server,
119 test->listener_conn);
121 g_dbus_connection_start_message_processing(test->listener_conn);
124 static void
125 test_dbus_console_registered(GObject *source_object,
126 GAsyncResult *res,
127 gpointer user_data)
129 TestDBusConsoleRegister *test = user_data;
130 g_autoptr(GError) err = NULL;
132 qemu_dbus_display1_console_call_register_listener_finish(
133 QEMU_DBUS_DISPLAY1_CONSOLE(source_object),
134 #ifndef WIN32
135 NULL,
136 #endif
137 res, &err);
138 g_assert_no_error(err);
140 test->listener_conn = g_thread_join(test->thread);
141 test_dbus_console_setup_listener(test);
144 static gpointer
145 test_dbus_p2p_server_setup_thread(gpointer data)
147 return test_dbus_p2p_from_fd(GPOINTER_TO_INT(data));
150 static void
151 test_dbus_display_console(void)
153 g_autoptr(GError) err = NULL;
154 g_autoptr(GDBusConnection) conn = NULL;
155 g_autoptr(QemuDBusDisplay1ConsoleProxy) console = NULL;
156 g_autoptr(GMainLoop) loop = NULL;
157 QTestState *qts = NULL;
158 int pair[2];
159 TestDBusConsoleRegister test;
160 #ifdef WIN32
161 WSAPROTOCOL_INFOW info;
162 g_autoptr(GVariant) listener = NULL;
163 #else
164 g_autoptr(GUnixFDList) fd_list = NULL;
165 int idx;
166 #endif
168 test_setup(&qts, &conn);
170 g_assert_cmpint(qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, pair), ==, 0);
171 #ifndef WIN32
172 fd_list = g_unix_fd_list_new();
173 idx = g_unix_fd_list_append(fd_list, pair[1], NULL);
174 #endif
176 console = QEMU_DBUS_DISPLAY1_CONSOLE_PROXY(
177 qemu_dbus_display1_console_proxy_new_sync(
178 conn,
179 G_DBUS_PROXY_FLAGS_NONE,
180 NULL,
181 "/org/qemu/Display1/Console_0",
182 NULL,
183 &err));
184 g_assert_no_error(err);
186 test.loop = loop = g_main_loop_new(NULL, FALSE);
187 test.thread = g_thread_new(NULL, test_dbus_p2p_server_setup_thread,
188 GINT_TO_POINTER(pair[0]));
190 #ifdef WIN32
191 if (WSADuplicateSocketW(_get_osfhandle(pair[1]),
192 GetProcessId((HANDLE) qtest_pid(qts)),
193 &info) == SOCKET_ERROR)
195 g_autofree char *emsg = g_win32_error_message(WSAGetLastError());
196 g_error("WSADuplicateSocket failed: %s", emsg);
198 close(pair[1]);
199 listener = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE,
200 &info,
201 sizeof(info),
203 #endif
205 qemu_dbus_display1_console_call_register_listener(
206 QEMU_DBUS_DISPLAY1_CONSOLE(console),
207 #ifdef WIN32
208 listener,
209 #else
210 g_variant_new_handle(idx),
211 #endif
212 G_DBUS_CALL_FLAGS_NONE,
214 #ifndef WIN32
215 fd_list,
216 #endif
217 NULL,
218 test_dbus_console_registered,
219 &test);
221 g_main_loop_run(loop);
223 g_clear_object(&test.server);
224 g_clear_object(&test.listener_conn);
225 qtest_quit(qts);
228 static void
229 test_dbus_display_keyboard(void)
231 g_autoptr(GError) err = NULL;
232 g_autoptr(GDBusConnection) conn = NULL;
233 g_autoptr(QemuDBusDisplay1KeyboardProxy) keyboard = NULL;
234 QTestState *qts = NULL;
236 test_setup(&qts, &conn);
238 keyboard = QEMU_DBUS_DISPLAY1_KEYBOARD_PROXY(
239 qemu_dbus_display1_keyboard_proxy_new_sync(
240 conn,
241 G_DBUS_PROXY_FLAGS_NONE,
242 NULL,
243 "/org/qemu/Display1/Console_0",
244 NULL,
245 &err));
246 g_assert_no_error(err);
249 g_assert_cmpint(qtest_inb(qts, 0x64) & 0x1, ==, 0);
250 g_assert_cmpint(qtest_inb(qts, 0x60), ==, 0);
252 qemu_dbus_display1_keyboard_call_press_sync(
253 QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard),
254 0x1C, /* qnum enter */
255 G_DBUS_CALL_FLAGS_NONE,
257 NULL,
258 &err);
259 g_assert_no_error(err);
261 /* may be should wait for interrupt? */
262 g_assert_cmpint(qtest_inb(qts, 0x64) & 0x1, ==, 1);
263 g_assert_cmpint(qtest_inb(qts, 0x60), ==, 0x5A); /* scan code 2 enter */
265 qemu_dbus_display1_keyboard_call_release_sync(
266 QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard),
267 0x1C, /* qnum enter */
268 G_DBUS_CALL_FLAGS_NONE,
270 NULL,
271 &err);
272 g_assert_no_error(err);
274 g_assert_cmpint(qtest_inb(qts, 0x64) & 0x1, ==, 1);
275 g_assert_cmpint(qtest_inb(qts, 0x60), ==, 0xF0); /* scan code 2 release */
276 g_assert_cmpint(qtest_inb(qts, 0x60), ==, 0x5A); /* scan code 2 enter */
278 g_assert_cmpint(qemu_dbus_display1_keyboard_get_modifiers(
279 QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard)), ==, 0);
281 qtest_quit(qts);
285 main(int argc, char **argv)
287 g_test_init(&argc, &argv, NULL);
289 qtest_add_func("/dbus-display/vm", test_dbus_display_vm);
290 qtest_add_func("/dbus-display/console", test_dbus_display_console);
291 qtest_add_func("/dbus-display/keyboard", test_dbus_display_keyboard);
293 return g_test_run();