spice: core bits
[qemu.git] / ui / spice-core.c
blob006604b62ed6ece040c53c9bbdf30e04bbda2da7
1 /*
2 * Copyright (C) 2010 Red Hat, Inc.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 or
7 * (at your option) version 3 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 #include <spice.h>
19 #include <spice-experimental.h>
21 #include "qemu-common.h"
22 #include "qemu-spice.h"
23 #include "qemu-timer.h"
24 #include "qemu-queue.h"
25 #include "monitor.h"
27 /* core bits */
29 static SpiceServer *spice_server;
30 int using_spice = 0;
32 struct SpiceTimer {
33 QEMUTimer *timer;
34 QTAILQ_ENTRY(SpiceTimer) next;
36 static QTAILQ_HEAD(, SpiceTimer) timers = QTAILQ_HEAD_INITIALIZER(timers);
38 static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
40 SpiceTimer *timer;
42 timer = qemu_mallocz(sizeof(*timer));
43 timer->timer = qemu_new_timer(rt_clock, func, opaque);
44 QTAILQ_INSERT_TAIL(&timers, timer, next);
45 return timer;
48 static void timer_start(SpiceTimer *timer, uint32_t ms)
50 qemu_mod_timer(timer->timer, qemu_get_clock(rt_clock) + ms);
53 static void timer_cancel(SpiceTimer *timer)
55 qemu_del_timer(timer->timer);
58 static void timer_remove(SpiceTimer *timer)
60 qemu_del_timer(timer->timer);
61 qemu_free_timer(timer->timer);
62 QTAILQ_REMOVE(&timers, timer, next);
63 qemu_free(timer);
66 struct SpiceWatch {
67 int fd;
68 int event_mask;
69 SpiceWatchFunc func;
70 void *opaque;
71 QTAILQ_ENTRY(SpiceWatch) next;
73 static QTAILQ_HEAD(, SpiceWatch) watches = QTAILQ_HEAD_INITIALIZER(watches);
75 static void watch_read(void *opaque)
77 SpiceWatch *watch = opaque;
78 watch->func(watch->fd, SPICE_WATCH_EVENT_READ, watch->opaque);
81 static void watch_write(void *opaque)
83 SpiceWatch *watch = opaque;
84 watch->func(watch->fd, SPICE_WATCH_EVENT_WRITE, watch->opaque);
87 static void watch_update_mask(SpiceWatch *watch, int event_mask)
89 IOHandler *on_read = NULL;
90 IOHandler *on_write = NULL;
92 watch->event_mask = event_mask;
93 if (watch->event_mask & SPICE_WATCH_EVENT_READ) {
94 on_read = watch_read;
96 if (watch->event_mask & SPICE_WATCH_EVENT_WRITE) {
97 on_read = watch_write;
99 qemu_set_fd_handler(watch->fd, on_read, on_write, watch);
102 static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
104 SpiceWatch *watch;
106 watch = qemu_mallocz(sizeof(*watch));
107 watch->fd = fd;
108 watch->func = func;
109 watch->opaque = opaque;
110 QTAILQ_INSERT_TAIL(&watches, watch, next);
112 watch_update_mask(watch, event_mask);
113 return watch;
116 static void watch_remove(SpiceWatch *watch)
118 watch_update_mask(watch, 0);
119 QTAILQ_REMOVE(&watches, watch, next);
120 qemu_free(watch);
123 static SpiceCoreInterface core_interface = {
124 .base.type = SPICE_INTERFACE_CORE,
125 .base.description = "qemu core services",
126 .base.major_version = SPICE_INTERFACE_CORE_MAJOR,
127 .base.minor_version = SPICE_INTERFACE_CORE_MINOR,
129 .timer_add = timer_add,
130 .timer_start = timer_start,
131 .timer_cancel = timer_cancel,
132 .timer_remove = timer_remove,
134 .watch_add = watch_add,
135 .watch_update_mask = watch_update_mask,
136 .watch_remove = watch_remove,
139 /* functions for the rest of qemu */
141 void qemu_spice_init(void)
143 QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);
144 const char *password;
145 int port;
147 if (!opts) {
148 return;
150 port = qemu_opt_get_number(opts, "port", 0);
151 if (!port) {
152 return;
154 password = qemu_opt_get(opts, "password");
156 spice_server = spice_server_new();
157 spice_server_set_port(spice_server, port);
158 if (password) {
159 spice_server_set_ticket(spice_server, password, 0, 0, 0);
161 if (qemu_opt_get_bool(opts, "disable-ticketing", 0)) {
162 spice_server_set_noauth(spice_server);
165 /* TODO: make configurable via cmdline */
166 spice_server_set_image_compression(spice_server, SPICE_IMAGE_COMPRESS_AUTO_GLZ);
168 spice_server_init(spice_server, &core_interface);
169 using_spice = 1;
172 int qemu_spice_add_interface(SpiceBaseInstance *sin)
174 return spice_server_add_interface(spice_server, sin);
177 static void spice_register_config(void)
179 qemu_add_opts(&qemu_spice_opts);
181 machine_init(spice_register_config);
183 static void spice_initialize(void)
185 qemu_spice_init();
187 device_init(spice_initialize);