Revision 29b0040b
b/Makefile.objs | ||
---|---|---|
88 | 88 |
common-obj-$(CONFIG_BRLAPI) += baum.o |
89 | 89 |
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o |
90 | 90 |
|
91 |
common-obj-$(CONFIG_SPICE) += ui/spice-core.o |
|
92 |
|
|
91 | 93 |
audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o |
92 | 94 |
audio-obj-$(CONFIG_SDL) += sdlaudio.o |
93 | 95 |
audio-obj-$(CONFIG_OSS) += ossaudio.o |
b/qemu-config.c | ||
---|---|---|
351 | 351 |
}, |
352 | 352 |
}; |
353 | 353 |
|
354 |
QemuOptsList qemu_spice_opts = { |
|
355 |
.name = "spice", |
|
356 |
.head = QTAILQ_HEAD_INITIALIZER(qemu_spice_opts.head), |
|
357 |
.desc = { |
|
358 |
{ |
|
359 |
.name = "port", |
|
360 |
.type = QEMU_OPT_NUMBER, |
|
361 |
},{ |
|
362 |
.name = "password", |
|
363 |
.type = QEMU_OPT_STRING, |
|
364 |
},{ |
|
365 |
.name = "disable-ticketing", |
|
366 |
.type = QEMU_OPT_BOOL, |
|
367 |
}, |
|
368 |
{ /* end if list */ } |
|
369 |
}, |
|
370 |
}; |
|
371 |
|
|
354 | 372 |
static QemuOptsList *vm_config_groups[32] = { |
355 | 373 |
&qemu_drive_opts, |
356 | 374 |
&qemu_chardev_opts, |
b/qemu-config.h | ||
---|---|---|
3 | 3 |
|
4 | 4 |
extern QemuOptsList qemu_fsdev_opts; |
5 | 5 |
extern QemuOptsList qemu_virtfs_opts; |
6 |
extern QemuOptsList qemu_spice_opts; |
|
6 | 7 |
|
7 | 8 |
QemuOptsList *qemu_find_opts(const char *group); |
8 | 9 |
void qemu_add_opts(QemuOptsList *list); |
b/qemu-options.hx | ||
---|---|---|
670 | 670 |
Enable SDL. |
671 | 671 |
ETEXI |
672 | 672 |
|
673 |
DEF("spice", HAS_ARG, QEMU_OPTION_spice, |
|
674 |
"-spice <args> enable spice\n", QEMU_ARCH_ALL) |
|
675 |
STEXI |
|
676 |
@item -spice @var{option}[,@var{option}[,...]] |
|
677 |
@findex -spice |
|
678 |
Enable the spice remote desktop protocol. Valid options are |
|
679 |
|
|
680 |
@table @option |
|
681 |
|
|
682 |
@item port=<nr> |
|
683 |
Set the TCP port spice is listening on. |
|
684 |
|
|
685 |
@item password=<secret> |
|
686 |
Set the password you need to authenticate. |
|
687 |
|
|
688 |
@item disable-ticketing |
|
689 |
Allow client connects without authentication. |
|
690 |
|
|
691 |
@end table |
|
692 |
ETEXI |
|
693 |
|
|
673 | 694 |
DEF("portrait", 0, QEMU_OPTION_portrait, |
674 | 695 |
"-portrait rotate graphical output 90 deg left (only PXA LCD)\n", |
675 | 696 |
QEMU_ARCH_ALL) |
b/ui/qemu-spice.h | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (C) 2010 Red Hat, Inc. |
|
3 |
* |
|
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. |
|
8 |
* |
|
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. |
|
13 |
* |
|
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/>. |
|
16 |
*/ |
|
17 |
|
|
18 |
#ifndef QEMU_SPICE_H |
|
19 |
#define QEMU_SPICE_H |
|
20 |
|
|
21 |
#ifdef CONFIG_SPICE |
|
22 |
|
|
23 |
#include <spice.h> |
|
24 |
|
|
25 |
#include "qemu-option.h" |
|
26 |
#include "qemu-config.h" |
|
27 |
|
|
28 |
extern int using_spice; |
|
29 |
|
|
30 |
void qemu_spice_init(void); |
|
31 |
int qemu_spice_add_interface(SpiceBaseInstance *sin); |
|
32 |
|
|
33 |
#else /* CONFIG_SPICE */ |
|
34 |
|
|
35 |
#define using_spice 0 |
|
36 |
|
|
37 |
#endif /* CONFIG_SPICE */ |
|
38 |
|
|
39 |
#endif /* QEMU_SPICE_H */ |
b/ui/spice-core.c | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (C) 2010 Red Hat, Inc. |
|
3 |
* |
|
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. |
|
8 |
* |
|
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. |
|
13 |
* |
|
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/>. |
|
16 |
*/ |
|
17 |
|
|
18 |
#include <spice.h> |
|
19 |
#include <spice-experimental.h> |
|
20 |
|
|
21 |
#include "qemu-common.h" |
|
22 |
#include "qemu-spice.h" |
|
23 |
#include "qemu-timer.h" |
|
24 |
#include "qemu-queue.h" |
|
25 |
#include "monitor.h" |
|
26 |
|
|
27 |
/* core bits */ |
|
28 |
|
|
29 |
static SpiceServer *spice_server; |
|
30 |
int using_spice = 0; |
|
31 |
|
|
32 |
struct SpiceTimer { |
|
33 |
QEMUTimer *timer; |
|
34 |
QTAILQ_ENTRY(SpiceTimer) next; |
|
35 |
}; |
|
36 |
static QTAILQ_HEAD(, SpiceTimer) timers = QTAILQ_HEAD_INITIALIZER(timers); |
|
37 |
|
|
38 |
static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque) |
|
39 |
{ |
|
40 |
SpiceTimer *timer; |
|
41 |
|
|
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; |
|
46 |
} |
|
47 |
|
|
48 |
static void timer_start(SpiceTimer *timer, uint32_t ms) |
|
49 |
{ |
|
50 |
qemu_mod_timer(timer->timer, qemu_get_clock(rt_clock) + ms); |
|
51 |
} |
|
52 |
|
|
53 |
static void timer_cancel(SpiceTimer *timer) |
|
54 |
{ |
|
55 |
qemu_del_timer(timer->timer); |
|
56 |
} |
|
57 |
|
|
58 |
static void timer_remove(SpiceTimer *timer) |
|
59 |
{ |
|
60 |
qemu_del_timer(timer->timer); |
|
61 |
qemu_free_timer(timer->timer); |
|
62 |
QTAILQ_REMOVE(&timers, timer, next); |
|
63 |
qemu_free(timer); |
|
64 |
} |
|
65 |
|
|
66 |
struct SpiceWatch { |
|
67 |
int fd; |
|
68 |
int event_mask; |
|
69 |
SpiceWatchFunc func; |
|
70 |
void *opaque; |
|
71 |
QTAILQ_ENTRY(SpiceWatch) next; |
|
72 |
}; |
|
73 |
static QTAILQ_HEAD(, SpiceWatch) watches = QTAILQ_HEAD_INITIALIZER(watches); |
|
74 |
|
|
75 |
static void watch_read(void *opaque) |
|
76 |
{ |
|
77 |
SpiceWatch *watch = opaque; |
|
78 |
watch->func(watch->fd, SPICE_WATCH_EVENT_READ, watch->opaque); |
|
79 |
} |
|
80 |
|
|
81 |
static void watch_write(void *opaque) |
|
82 |
{ |
|
83 |
SpiceWatch *watch = opaque; |
|
84 |
watch->func(watch->fd, SPICE_WATCH_EVENT_WRITE, watch->opaque); |
|
85 |
} |
|
86 |
|
|
87 |
static void watch_update_mask(SpiceWatch *watch, int event_mask) |
|
88 |
{ |
|
89 |
IOHandler *on_read = NULL; |
|
90 |
IOHandler *on_write = NULL; |
|
91 |
|
|
92 |
watch->event_mask = event_mask; |
|
93 |
if (watch->event_mask & SPICE_WATCH_EVENT_READ) { |
|
94 |
on_read = watch_read; |
|
95 |
} |
|
96 |
if (watch->event_mask & SPICE_WATCH_EVENT_WRITE) { |
|
97 |
on_read = watch_write; |
|
98 |
} |
|
99 |
qemu_set_fd_handler(watch->fd, on_read, on_write, watch); |
|
100 |
} |
|
101 |
|
|
102 |
static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque) |
|
103 |
{ |
|
104 |
SpiceWatch *watch; |
|
105 |
|
|
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); |
|
111 |
|
|
112 |
watch_update_mask(watch, event_mask); |
|
113 |
return watch; |
|
114 |
} |
|
115 |
|
|
116 |
static void watch_remove(SpiceWatch *watch) |
|
117 |
{ |
|
118 |
watch_update_mask(watch, 0); |
|
119 |
QTAILQ_REMOVE(&watches, watch, next); |
|
120 |
qemu_free(watch); |
|
121 |
} |
|
122 |
|
|
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, |
|
128 |
|
|
129 |
.timer_add = timer_add, |
|
130 |
.timer_start = timer_start, |
|
131 |
.timer_cancel = timer_cancel, |
|
132 |
.timer_remove = timer_remove, |
|
133 |
|
|
134 |
.watch_add = watch_add, |
|
135 |
.watch_update_mask = watch_update_mask, |
|
136 |
.watch_remove = watch_remove, |
|
137 |
}; |
|
138 |
|
|
139 |
/* functions for the rest of qemu */ |
|
140 |
|
|
141 |
void qemu_spice_init(void) |
|
142 |
{ |
|
143 |
QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head); |
|
144 |
const char *password; |
|
145 |
int port; |
|
146 |
|
|
147 |
if (!opts) { |
|
148 |
return; |
|
149 |
} |
|
150 |
port = qemu_opt_get_number(opts, "port", 0); |
|
151 |
if (!port) { |
|
152 |
return; |
|
153 |
} |
|
154 |
password = qemu_opt_get(opts, "password"); |
|
155 |
|
|
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); |
|
160 |
} |
|
161 |
if (qemu_opt_get_bool(opts, "disable-ticketing", 0)) { |
|
162 |
spice_server_set_noauth(spice_server); |
|
163 |
} |
|
164 |
|
|
165 |
/* TODO: make configurable via cmdline */ |
|
166 |
spice_server_set_image_compression(spice_server, SPICE_IMAGE_COMPRESS_AUTO_GLZ); |
|
167 |
|
|
168 |
spice_server_init(spice_server, &core_interface); |
|
169 |
using_spice = 1; |
|
170 |
} |
|
171 |
|
|
172 |
int qemu_spice_add_interface(SpiceBaseInstance *sin) |
|
173 |
{ |
|
174 |
return spice_server_add_interface(spice_server, sin); |
|
175 |
} |
|
176 |
|
|
177 |
static void spice_register_config(void) |
|
178 |
{ |
|
179 |
qemu_add_opts(&qemu_spice_opts); |
|
180 |
} |
|
181 |
machine_init(spice_register_config); |
|
182 |
|
|
183 |
static void spice_initialize(void) |
|
184 |
{ |
|
185 |
qemu_spice_init(); |
|
186 |
} |
|
187 |
device_init(spice_initialize); |
b/vl.c | ||
---|---|---|
165 | 165 |
#include "cpus.h" |
166 | 166 |
#include "arch_init.h" |
167 | 167 |
|
168 |
#include "ui/qemu-spice.h" |
|
169 |
|
|
168 | 170 |
//#define DEBUG_NET |
169 | 171 |
//#define DEBUG_SLIRP |
170 | 172 |
|
... | ... | |
2616 | 2618 |
} |
2617 | 2619 |
break; |
2618 | 2620 |
} |
2621 |
case QEMU_OPTION_spice: |
|
2622 |
olist = qemu_find_opts("spice"); |
|
2623 |
if (!olist) { |
|
2624 |
fprintf(stderr, "spice is not supported by this qemu build.\n"); |
|
2625 |
exit(1); |
|
2626 |
} |
|
2627 |
opts = qemu_opts_parse(olist, optarg, 0); |
|
2628 |
if (!opts) { |
|
2629 |
fprintf(stderr, "parse error: %s\n", optarg); |
|
2630 |
exit(1); |
|
2631 |
} |
|
2632 |
break; |
|
2619 | 2633 |
case QEMU_OPTION_writeconfig: |
2620 | 2634 |
{ |
2621 | 2635 |
FILE *fp; |
Also available in: Unified diff