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/>.
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"
29 static SpiceServer
*spice_server
;
34 QTAILQ_ENTRY(SpiceTimer
) next
;
36 static QTAILQ_HEAD(, SpiceTimer
) timers
= QTAILQ_HEAD_INITIALIZER(timers
);
38 static SpiceTimer
*timer_add(SpiceTimerFunc func
, void *opaque
)
42 timer
= qemu_mallocz(sizeof(*timer
));
43 timer
->timer
= qemu_new_timer(rt_clock
, func
, opaque
);
44 QTAILQ_INSERT_TAIL(&timers
, timer
, next
);
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
);
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
) {
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
)
106 watch
= qemu_mallocz(sizeof(*watch
));
109 watch
->opaque
= opaque
;
110 QTAILQ_INSERT_TAIL(&watches
, watch
, next
);
112 watch_update_mask(watch
, event_mask
);
116 static void watch_remove(SpiceWatch
*watch
)
118 watch_update_mask(watch
, 0);
119 QTAILQ_REMOVE(&watches
, watch
, next
);
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
;
150 port
= qemu_opt_get_number(opts
, "port", 0);
154 password
= qemu_opt_get(opts
, "password");
156 spice_server
= spice_server_new();
157 spice_server_set_port(spice_server
, port
);
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
);
171 qemu_spice_input_init();
174 int qemu_spice_add_interface(SpiceBaseInstance
*sin
)
176 return spice_server_add_interface(spice_server
, sin
);
179 static void spice_register_config(void)
181 qemu_add_opts(&qemu_spice_opts
);
183 machine_init(spice_register_config
);
185 static void spice_initialize(void)
189 device_init(spice_initialize
);