NEWS | 12 README.xspice | 4 configure.ac | 72 + examples/spiceqxl.xorg.conf.example | 43 scripts/Xspice | 181 +++ src/Makefile.am | 37 src/compat-api.h | 99 + src/dfps.c | 366 ++++++ src/dfps.h | 27 src/mspace.c | 44 src/mspace.h | 10 src/murmurhash3.c | 8 src/qxl.h | 238 +++- src/qxl_cursor.c | 55 src/qxl_driver.c | 1995 ++++++++++++++---------------------- src/qxl_drmmode.c | 952 +++++++++++++++++ src/qxl_drmmode.h | 93 + src/qxl_image.c | 92 + src/qxl_io.c | 209 +++ src/qxl_kms.c | 739 +++++++++++++ src/qxl_mem.c | 854 ++++++++++----- src/qxl_option_helpers.c | 4 src/qxl_option_helpers.h | 2 src/qxl_ring.c | 26 src/qxl_surface.c | 1265 +++++++--------------- src/qxl_surface.h | 55 src/qxl_surface_ums.c | 850 +++++++++++++++ src/qxl_ums_mode.c | 506 +++++++++ src/qxl_uxa.c | 581 ++++++++++ src/spiceqxl_audio.c | 343 ++++++ src/spiceqxl_audio.h | 31 src/spiceqxl_display.c | 22 src/spiceqxl_display.h | 2 src/spiceqxl_driver.c | 7 src/spiceqxl_inputs.c | 102 + src/spiceqxl_inputs.h | 2 src/spiceqxl_io_port.c | 41 src/spiceqxl_main_loop.c | 28 src/spiceqxl_main_loop.h | 1 src/spiceqxl_spice_server.c | 23 src/spiceqxl_uinput.c | 124 ++ src/spiceqxl_uinput.h | 8 src/spiceqxl_vdagent.c | 170 +++ src/spiceqxl_vdagent.h | 8 src/uxa/uxa-accel.c | 82 + src/uxa/uxa-damage.c | 1 src/uxa/uxa-glyphs.c | 23 src/uxa/uxa-priv.h | 6 src/uxa/uxa-render.c | 6 src/uxa/uxa.c | 21 tests/xspice_audio_test.py | 19 tests/xspice_audio_test_helper.py | 19 tests/xspice_util.py | 69 + 53 files changed, 8032 insertions(+), 2545 deletions(-)
New commits: commit b8b67dc138092de488fb6ef62ce4bcb99aaa881a Author: Alon Levy <al...@redhat.com> Date: Sun Oct 20 17:59:07 2013 +0300 Release 0.1.1 diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..4ece9fe --- /dev/null +++ b/NEWS @@ -0,0 +1,12 @@ +Major changes in 0.1.1 +====================== + +KMS support +DFPS available to guest driver too +Xspice audio & agent support +GPL code removed (EDID) +Warnings squash +Bug fixes (numbers are Red Hat Bugzilla bug ids): + 883578 - remote-viewer gets frozen after migration of guest with video playback + 968931 - Crash in Xspice after closing tab with spice-html5 + 894421 - Small change in guests resolution results in wrong resolution diff --git a/configure.ac b/configure.ac index 6322d53..01377a4 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-qxl], - [0.1.0], + [0.1.1], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-video-qxl]) AC_CONFIG_SRCDIR([Makefile.am]) commit 27cb65b1ad669789bebef356ea9086491dbed382 Author: Alon Levy <al...@redhat.com> Date: Sun Oct 20 16:33:39 2013 +0300 xspice: add tests for audio remoting Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/tests/xspice_audio_test.py b/tests/xspice_audio_test.py new file mode 100755 index 0000000..455c1aa --- /dev/null +++ b/tests/xspice_audio_test.py @@ -0,0 +1,19 @@ +#!/usr/bin/python + +from time import sleep +from xspice_audio_test_helper import produce_audio +from xspice_util import launch_xspice, launch_client + +def main(): + port = 8000 + xspice = launch_xspice(port) + sleep(2) + client = launch_client(port) + sleep(1) + produce_audio(xspice.audio_fifo_dir) + sleep(2) + client.kill() + xspice.kill() + +if __name__ == '__main__': + main() diff --git a/tests/xspice_audio_test_helper.py b/tests/xspice_audio_test_helper.py new file mode 100755 index 0000000..fbe3a54 --- /dev/null +++ b/tests/xspice_audio_test_helper.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +# coding: utf-8 +import os +import sys +import struct +from math import sin, pi + +def produce_audio(basedir): + filename = os.path.join(basedir, 'testaudio') + os.system(u'mkfifo %s' % filename) + if not os.path.exists(basedir): + print "missing fifo dir %s" % repr(basedir) + f=open(filename,'w') + singen = lambda f: lambda t: (int(min(32767, 32768*sin(t*f/1000.0*pi))), int(min(32767, 32768*sin(t*f/1000.0*pi)))) + f.write(''.join( struct.pack('hh', *singen(40)(t)) for t in xrange(44100) ) ) + os.unlink(filename) + +if __name__ == '__main__': + produce_audio(sys.argv[-1] if len(sys.argv) > 1 else '/tmp/xspice-audio/') diff --git a/tests/xspice_util.py b/tests/xspice_util.py new file mode 100755 index 0000000..a2e8578 --- /dev/null +++ b/tests/xspice_util.py @@ -0,0 +1,69 @@ +#!/usr/bin/python + +import os +from time import sleep +import subprocess +import atexit + +class Process(object): + processes = [] + @classmethod + def new(clazz, *args, **kw): + clazz.processes.append(subprocess.Popen(*args, **kw)) + return clazz.processes[-1] + + @classmethod + def atexit(clazz): + for p in reversed(clazz.processes): + print "child %s" % p.pid + if False: + slp = subprocess.Popen(['/usr/bin/sleep', '10000']) + print "wait on %d" % slp.pid + slp.wait() + if len(clazz.processes) == 0: + return + for p in reversed(clazz.processes): + print "kill %s" % p.pid + try: + p.kill() + except: + pass + if not any(p.poll() for p in clazz.processes): + return + sleep(1) + for p in reversed(clazz.processes): + if not p.poll(): + print "terminate %s" % p.pid + try: + p.terminate() + except: + pass + +atexit.register(Process.atexit) + +def which(prog): + for path_element in os.environ['PATH'].split(':'): + candidate = os.path.join(path_element, prog) + if os.path.exists(candidate): + return candidate + return None + +client_executable = which('remote-viewer') +if not client_executable: + raise SystemExit('missing remote-viewer in path') + +def launch_xspice(port): + basedir = '/tmp/xspice_test_audio' + if not os.path.exists(basedir): + os.mkdir(basedir) + assert(os.path.exists(basedir)) + xspice = Process.new(['../scripts/Xspice', '--port', '8000', '--auto', '--audio-fifo-dir', basedir, '--disable-ticketing', ':15.0']) + xspice.audio_fifo_dir = basedir + return xspice + +def launch_client(port): + client = Process.new([client_executable, 'spice://localhost:%s' % port]) + return client + +if __name__ == '__main__': + launch_xspice(port=8000) commit 7d84ff3a11d61d0619ab3492097b493d08e97ad2 Author: Alon Levy <al...@redhat.com> Date: Sun Oct 20 16:32:54 2013 +0300 Xspice: kill Xorg process on SIGTERM Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/scripts/Xspice b/scripts/Xspice index a4eb647..17439a1 100755 --- a/scripts/Xspice +++ b/scripts/Xspice @@ -22,6 +22,7 @@ import sys import tempfile import atexit import time +import signal from subprocess import Popen, PIPE def which(x): @@ -154,7 +155,7 @@ if not args.xorg: cleanup_files = [] cleanup_processes = [] -def cleanup(): +def cleanup(*args): for f in cleanup_files: if os.path.isfile(f): os.remove(f) @@ -162,12 +163,14 @@ def cleanup(): p.kill() for p in cleanup_processes: p.wait() + del cleanup_processes[:] def launch(*args, **kw): p = Popen(*args, **kw) cleanup_processes.append(p) return p +signal.signal(signal.SIGTERM, cleanup) atexit.register(cleanup) if args.auto: commit 715707cf3038447138c5408e6ed91d788c7e37fa Author: Alon Levy <al...@redhat.com> Date: Sun Oct 20 15:36:30 2013 +0300 qxl_image: fix build break once MIN/MAX switched to spice-protocol In commit 5e122e4ab1ac35186cc610cd0d518cfd5e78d902 diff --git a/src/qxl_image.c b/src/qxl_image.c index 2349fca..0a0ca30 100644 --- a/src/qxl_image.c +++ b/src/qxl_image.c @@ -31,6 +31,9 @@ #include <string.h> #include <assert.h> #include <stdlib.h> + +#include <spice/macros.h> + #include "qxl.h" #include "murmurhash3.h" commit 48d762993653d1d88da4b93a646bafd844507f26 Author: Alon Levy <al...@redhat.com> Date: Sun Oct 13 15:39:43 2013 +0300 spiceqxl_audio: fix possible buffer overflow (clang) I've tested this. Previously strncat was used incorrectly, it is replaced with snprintf per Uri's suggestion. Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/src/spiceqxl_audio.c b/src/spiceqxl_audio.c index 3cd80ff..5b87302 100644 --- a/src/spiceqxl_audio.c +++ b/src/spiceqxl_audio.c @@ -167,9 +167,9 @@ scan_fifos (struct audio_data *data, const char *dirname) return 0; } - strncpy(path, dirname, sizeof(path)); - strncat(path, "/", sizeof(path)); - strncat(path, ent->d_name, sizeof(path)); + if (snprintf(path, sizeof(path), "%s/%s", dirname, ent->d_name) >= sizeof(path)) { + ErrorF("playback: FIFO filename is too long - truncated into %s", path); + } data->fifo_fds[i] = open(path, O_RDONLY | O_RSYNC | O_NONBLOCK); if (data->fifo_fds[i] < 0) commit 2ed03db1ae39f26b4ba62a7db140a56f9acbe4bc Author: Alon Levy <al...@redhat.com> Date: Wed Oct 16 15:22:26 2013 +0300 Xspice: add --audio-fifo-dir Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/examples/spiceqxl.xorg.conf.example b/examples/spiceqxl.xorg.conf.example index d1129e7..be8a16b 100644 --- a/examples/spiceqxl.xorg.conf.example +++ b/examples/spiceqxl.xorg.conf.example @@ -111,7 +111,8 @@ Section "Device" # If a directory is given, any file in that # directory will be read for audio data to be sent # to the client. Default is no mixing. - #Option "SpicePlaybackFIFODir" "" + #Option "SpicePlaybackFIFODir" "/tmp/" + EndSection Section "InputDevice" diff --git a/scripts/Xspice b/scripts/Xspice index 221f4db..a4eb647 100755 --- a/scripts/Xspice +++ b/scripts/Xspice @@ -90,6 +90,7 @@ parser.add_argument('--vdagent-uinput-path', default='/tmp/xspice-uinput', help= parser.add_argument('--vdagentd-exec', default='spice-vdagentd') parser.add_argument('--vdagent-exec', default='spice-vdagent') parser.add_argument('--vdagent-no-launch', default=True, action='store_false', dest='vdagent_launch') +parser.add_argument('--audio-fifo-dir', default='') #TODO #Option "SpiceAddr" "" @@ -174,10 +175,15 @@ if args.auto: cleanup_files.append(cf.name + ".log") args.config = cf.name xorg_args = [ '-logfile', cf.name + ".log" ] + xorg_args + if args.audio_fifo_dir: + options = 'Option "SpicePlaybackFIFODir" "%s"' % args.audio_fifo_dir + else: + options = '' cf.write(""" Section "Device" Identifier "XSPICE" Driver "spiceqxl" + %(options)s EndSection Section "InputDevice" @@ -213,7 +219,7 @@ Section "ServerFlags" EndSection - """) + """ % locals()) cf.flush() var_args = ['port', 'tls_port', 'disable_ticketing', commit a6ce6b285e6f4783b63cc0af309562771b516dfc Author: Alon Levy <al...@redhat.com> Date: Sun Oct 13 15:39:11 2013 +0300 uxa: use PIXMAN consts instead of PICT in some places (silence clang warning) Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/src/uxa/uxa-glyphs.c b/src/uxa/uxa-glyphs.c index 6dd8e58..fe3d6e8 100644 --- a/src/uxa/uxa-glyphs.c +++ b/src/uxa/uxa-glyphs.c @@ -715,7 +715,7 @@ uxa_glyphs_to_dst(CARD8 op, src_y += localSrc->pDrawable->y + src_off_y; } else { localSrc = uxa_acquire_pattern(screen, pSrc, - PICT_a8r8g8b8, x, y, width, height); + PIXMAN_a8r8g8b8, 0, 0, width, height); if (!localSrc) return 1; diff --git a/src/uxa/uxa-render.c b/src/uxa/uxa-render.c index ac80c45..937ac2e 100644 --- a/src/uxa/uxa-render.c +++ b/src/uxa/uxa-render.c @@ -418,7 +418,7 @@ uxa_try_driver_solid_fill(PicturePtr pSrc, if (!uxa_get_rgba_from_pixel(solid->color, &red, &green, &blue, &alpha, - PICT_a8r8g8b8) || + PIXMAN_a8r8g8b8) || !uxa_get_pixel_from_rgba(&pixel, red, green, blue, alpha, pDst->format)) { @@ -880,7 +880,7 @@ uxa_acquire_source(ScreenPtr screen, INT16 * out_x, INT16 * out_y) { return uxa_acquire_picture (screen, pict, - PICT_a8r8g8b8, + PIXMAN_a8r8g8b8, x, y, width, height, out_x, out_y); @@ -894,7 +894,7 @@ uxa_acquire_mask(ScreenPtr screen, INT16 * out_x, INT16 * out_y) { return uxa_acquire_picture (screen, pict, - PICT_a8, + PIXMAN_a8, x, y, width, height, out_x, out_y); commit 8afb354f094e253585b93108175793fe7bf13606 Author: Alon Levy <al...@redhat.com> Date: Sun Oct 13 15:38:35 2013 +0300 spiceqxl_display: add noreturn attribute (silence clang warning) Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/src/spiceqxl_display.c b/src/spiceqxl_display.c index 20fb029..a3a8978 100644 --- a/src/spiceqxl_display.c +++ b/src/spiceqxl_display.c @@ -287,7 +287,8 @@ static int interface_req_cursor_notification(QXLInstance *sin) } /* called from spice server thread context */ -static void interface_notify_update(QXLInstance *sin, uint32_t update_id) +static void __attribute__ ((__noreturn__)) + interface_notify_update(QXLInstance *sin, uint32_t update_id) { fprintf(stderr, "%s: abort()\n", __FUNCTION__); abort(); commit 2f7e4c845366328e4f561654e0c38314c7aafe69 Author: Alon Levy <al...@redhat.com> Date: Sun Oct 13 15:38:16 2013 +0300 qxl_get_formats: use surface enum, not bitmap (fixes clang warning) Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/src/qxl.h b/src/qxl.h index 52e92e9..c699c58 100644 --- a/src/qxl.h +++ b/src/qxl.h @@ -607,7 +607,7 @@ Bool qxl_enter_vt_kms (VT_FUNC_ARGS_DECL); void qxl_leave_vt_kms (VT_FUNC_ARGS_DECL); void qxl_set_screen_pixmap_header (ScreenPtr pScreen); Bool qxl_resize_primary_to_virtual (qxl_screen_t *qxl); -void qxl_get_formats (int bpp, SpiceBitmapFmt *format, pixman_format_code_t *pformat); +void qxl_get_formats (int bpp, SpiceSurfaceFmt *format, pixman_format_code_t *pformat); #ifdef XF86DRM_MODE Bool qxl_pre_init_kms(ScrnInfoPtr pScrn, int flags); diff --git a/src/qxl_kms.c b/src/qxl_kms.c index 6c5b427..d6dfcee 100644 --- a/src/qxl_kms.c +++ b/src/qxl_kms.c @@ -593,7 +593,7 @@ qxl_kms_surface_create(qxl_screen_t *qxl, int height, int bpp) { - SpiceBitmapFmt format; + SpiceSurfaceFmt format; qxl_surface_t *surface; int stride; struct qxl_kms_bo *bo; diff --git a/src/qxl_surface.c b/src/qxl_surface.c index 685d09f..1075eae 100644 --- a/src/qxl_surface.c +++ b/src/qxl_surface.c @@ -804,7 +804,7 @@ qxl_surface_put_image (qxl_surface_t *dest, } void -qxl_get_formats (int bpp, SpiceBitmapFmt *format, pixman_format_code_t *pformat) +qxl_get_formats (int bpp, SpiceSurfaceFmt *format, pixman_format_code_t *pformat) { switch (bpp) { @@ -829,7 +829,8 @@ qxl_get_formats (int bpp, SpiceBitmapFmt *format, pixman_format_code_t *pformat) break; default: - *format = *pformat = -1; + *format = -1; + *pformat = -1; break; } } diff --git a/src/qxl_surface_ums.c b/src/qxl_surface_ums.c index 6839372..2c16ede 100644 --- a/src/qxl_surface_ums.c +++ b/src/qxl_surface_ums.c @@ -430,7 +430,7 @@ surface_send_create (surface_cache_t *cache, int height, int bpp) { - SpiceBitmapFmt format; + SpiceSurfaceFmt format; pixman_format_code_t pformat; struct QXLSurfaceCmd *cmd; int stride; commit 70884bd353c34c0be23c2b21eec320cd8c637f4f Author: Jeremy White <jwh...@codeweavers.com> Date: Thu Oct 17 14:08:06 2013 -0500 Use non deprecated functions, removes warnings from build. diff --git a/src/qxl_driver.c b/src/qxl_driver.c index f076f00..91ba6c2 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -270,7 +270,7 @@ qxl_unmap_memory (qxl_screen_t *qxl) #ifdef XSPICE if (qxl->worker) { - qxl->worker->stop (qxl->worker); + spice_server_vm_stop(qxl->spice_server); qxl->worker_running = FALSE; } #endif @@ -662,7 +662,7 @@ spiceqxl_screen_init (ScrnInfoPtr pScrn, qxl_screen_t *qxl) if (! qxl->worker_running) { xspice_register_handlers(); - qxl->worker->start (qxl->worker); + spice_server_vm_start(qxl->spice_server); qxl->worker_running = TRUE; } } diff --git a/src/spiceqxl_display.c b/src/spiceqxl_display.c index 9c42d84..20fb029 100644 --- a/src/spiceqxl_display.c +++ b/src/spiceqxl_display.c @@ -95,7 +95,7 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker) return; } dprint(qxl, 1, "%s:\n", __FUNCTION__); - qxl_worker->add_memslot(qxl_worker, &slot); + spice_qxl_add_memslot(sin, &slot); qxl->worker = qxl_worker; } diff --git a/src/spiceqxl_io_port.c b/src/spiceqxl_io_port.c index f570041..165b8a9 100644 --- a/src/spiceqxl_io_port.c +++ b/src/spiceqxl_io_port.c @@ -123,7 +123,7 @@ static void qxl_soft_reset(qxl_screen_t *qxl) static void qxl_reset_surfaces(qxl_screen_t *qxl) { dprint(1, "%s:\n", __FUNCTION__); - qxl->worker->destroy_surfaces(qxl->worker); + spice_qxl_destroy_surfaces(&qxl->display_sin); // TODO - do we have guest_surfaces? //memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds)); } @@ -132,8 +132,8 @@ static void qxl_hard_reset(qxl_screen_t *qxl) { dprint(1, "%s: start\n", __FUNCTION__); - qxl->worker->reset_cursor(qxl->worker); - qxl->worker->reset_image_cache(qxl->worker); + spice_qxl_reset_cursor(&qxl->display_sin); + spice_qxl_reset_image_cache(&qxl->display_sin); qxl_reset_surfaces(qxl); qxl_reset_state(qxl); @@ -161,14 +161,14 @@ static void qxl_create_guest_primary(qxl_screen_t *qxl) surface.mouse_mode = TRUE; surface.group_id = 0; qxl->cmdflags = 0; - qxl->worker->create_primary_surface(qxl->worker, 0, &surface); + spice_qxl_create_primary_surface(&qxl->display_sin, 0, &surface); } static void qxl_destroy_primary(qxl_screen_t *qxl) { dprint(1, "%s\n", __FUNCTION__); - qxl->worker->destroy_primary_surface(qxl->worker, 0); + spice_qxl_destroy_primary_surface(&qxl->display_sin, 0); } @@ -216,15 +216,15 @@ void ioport_write(qxl_screen_t *qxl, uint32_t io_port, uint32_t val) case QXL_IO_UPDATE_AREA: { QXLRect update = *(QXLRect*)&header->update_area; - qxl->worker->update_area(qxl->worker, header->update_surface, + spice_qxl_update_area(&qxl->display_sin, header->update_surface, &update, NULL, 0, 0); break; } case QXL_IO_NOTIFY_CMD: - qxl->worker->wakeup(qxl->worker); + spice_qxl_wakeup(&qxl->display_sin); break; case QXL_IO_NOTIFY_CURSOR: - qxl->worker->wakeup(qxl->worker); + spice_qxl_wakeup(&qxl->display_sin); break; case QXL_IO_UPDATE_IRQ: /* qxl_set_irq(d); */ @@ -238,7 +238,7 @@ void ioport_write(qxl_screen_t *qxl, uint32_t io_port, uint32_t val) if (!SPICE_RING_IS_EMPTY(&header->release_ring)) { break; } - qxl->worker->oom(qxl->worker); + spice_qxl_oom(&qxl->display_sin); break; case QXL_IO_SET_MODE: dprint(1, "QXL_SET_MODE %d\n", val); @@ -270,10 +270,10 @@ void ioport_write(qxl_screen_t *qxl, uint32_t io_port, uint32_t val) qxl_destroy_primary(qxl); break; case QXL_IO_DESTROY_SURFACE_WAIT: - qxl->worker->destroy_surface_wait(qxl->worker, val); + spice_qxl_destroy_surface_wait(&qxl->display_sin, val); break; case QXL_IO_DESTROY_ALL_SURFACES: - qxl->worker->destroy_surfaces(qxl->worker); + spice_qxl_destroy_surfaces(&qxl->display_sin); break; case QXL_IO_FLUSH_SURFACES_ASYNC: fprintf(stderr, "ERROR: async callback Unimplemented\n"); commit 5e122e4ab1ac35186cc610cd0d518cfd5e78d902 Author: Jeremy White <jwh...@codeweavers.com> Date: Thu Oct 17 14:07:29 2013 -0500 Remove MAX/MIN macros that are now included via spice/macros.h. diff --git a/src/qxl_image.c b/src/qxl_image.c index 40798b3..2349fca 100644 --- a/src/qxl_image.c +++ b/src/qxl_image.c @@ -125,9 +125,6 @@ remove_image_info (image_info_t *info) free (info); } -#define MAX(a,b) (((a) > (b))? (a) : (b)) -#define MIN(a,b) (((a) < (b))? (a) : (b)) - struct qxl_bo * qxl_image_create (qxl_screen_t *qxl, const uint8_t *data, int x, int y, int width, int height, commit 78f1115d11bea8be572e6959fa4db0313454b318 Author: Alon Levy <al...@redhat.com> Date: Mon Sep 2 17:40:20 2013 +0300 Xspice: vdagent{,d} launching support It checks for a new enough vdagentd/vdagent via the new -S command line parameter available via "vdagentd -h" and "vdagent -h". Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/scripts/Xspice b/scripts/Xspice index ba04951..221f4db 100755 --- a/scripts/Xspice +++ b/scripts/Xspice @@ -22,9 +22,11 @@ import sys import tempfile import atexit import time -from subprocess import Popen +from subprocess import Popen, PIPE def which(x): + if os.path.exists(x): + return x for p in os.environ['PATH'].split(':'): candidate = os.path.join(p, x) if os.path.exists(candidate): @@ -82,6 +84,12 @@ parser.add_argument('--streaming-video', choices=['off', 'all', 'filter'], default='filter', help='filter by default') add_boolean('--ipv4-only') add_boolean('--ipv6-only') +parser.add_argument('--vdagent', action='store_true', dest='vdagent_enabled', default=False, help='launch vdagent & vdagentd') +parser.add_argument('--vdagent-virtio-path', default='/tmp/xspice-virtio', help='virtio socket path') +parser.add_argument('--vdagent-uinput-path', default='/tmp/xspice-uinput', help='uinput socket path') +parser.add_argument('--vdagentd-exec', default='spice-vdagentd') +parser.add_argument('--vdagent-exec', default='spice-vdagent') +parser.add_argument('--vdagent-no-launch', default=True, action='store_false', dest='vdagent_launch') #TODO #Option "SpiceAddr" "" @@ -98,6 +106,23 @@ if cgdb: args, xorg_args = parser.parse_known_args(sys.argv[1:]) +def agents_new_enough(args): + if not os.path.exists(args.vdagent_exec) or not os.path.exists(args.vdagentd_exec): + return False + for f in [args.vdagent_exec, args.vdagentd_exec]: + if Popen(args=[f, '-h'], stdout=PIPE).stdout.read().find('-S') == -1: + return False + return True + +if args.vdagent_enabled: + args.vdagent_exec = which(args.vdagent_exec) + args.vdagentd_exec = which(args.vdagentd_exec) + if not agents_new_enough(args): + if args.vdagent_enabled: + print("erorr: vdagent is not new enough to support Xspice") + raise SystemExit + args.vdagent_enabled = False + def tls_files(args): if args.tls_port == 0: return {} @@ -196,7 +221,9 @@ var_args = ['port', 'tls_port', 'disable_ticketing', 'x509_key_file', 'x509_key_password', 'tls_ciphers', 'dh_file', 'password', 'image_compression', 'jpeg_wan_compression', 'zlib_glz_wan_compression', - 'streaming_video', 'deferred_fps', 'exit_on_disconnect'] + 'streaming_video', 'deferred_fps', 'exit_on_disconnect', + 'vdagent_enabled', 'vdagent_virtio_path', 'vdagent_uinput_path'] + for arg in var_args: if getattr(args, arg): # The Qxl code doesn't respect booleans, so pass them as 0/1 @@ -226,6 +253,13 @@ if cgdb and args.cgdb: # This is currently mandatory; the driver cannot survive a reset xorg_args = [ '-noreset' ] + xorg_args + +# TODO /tmp/xspice-vdagent - replace with temporary file in temporary directory +vdagentd_uds = '/tmp/xspice-vdagent' +if args.vdagent_enabled: + for f in [vdagentd_uds, args.vdagent_virtio_path, args.vdagent_uinput_path]: + if os.path.exists(f): + os.unlink(f) xorg = launch(executable=args.xorg, args=exec_args + xorg_args) time.sleep(2) @@ -233,6 +267,14 @@ retpid,rc = os.waitpid(xorg.pid, os.WNOHANG) if retpid != 0: print "Error: X server is not running" else: + if args.vdagent_enabled and args.vdagent_launch: + # XXX use systemd --user for this? + vdagentd = launch(args=[args.vdagentd_exec, '-x', '-S', vdagentd_uds, + '-s', args.vdagent_virtio_path, '-u', args.vdagent_uinput_path]) + time.sleep(1) + # TODO wait for uinput pipe open for write + vdagent = launch(args=[args.vdagent_exec, '-x', '-s', args.vdagent_virtio_path, '-S', + vdagentd_uds]) if args.xsession: environ = os.environ os.spawnlpe(os.P_NOWAIT, args.xsession, environ) commit aa9d1cc75d494ae2d33ee2c925a35338ce85f4c2 Author: Alon Levy <al...@redhat.com> Date: Mon Sep 2 17:39:51 2013 +0300 Xspice: require display parameter, and set if earlier in environment Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/scripts/Xspice b/scripts/Xspice index 5375624..ba04951 100755 --- a/scripts/Xspice +++ b/scripts/Xspice @@ -213,6 +213,10 @@ display="" for arg in xorg_args: if arg.startswith(":"): display = arg +if not display: + print "Error: missing display on line (i.e. :3)" + raise SystemExit +os.environ ['DISPLAY'] = display exec_args = [args.xorg, '-config', args.config] if cgdb and args.cgdb: @@ -231,7 +235,6 @@ if retpid != 0: else: if args.xsession: environ = os.environ - environ ['DISPLAY'] = display os.spawnlpe(os.P_NOWAIT, args.xsession, environ) try: commit dc451204ec5a4abceac977d99893918091324271 Author: Alon Levy <al...@redhat.com> Date: Mon Sep 2 17:39:11 2013 +0300 Xspice: correct doc string Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/scripts/Xspice b/scripts/Xspice index b50ea46..5375624 100755 --- a/scripts/Xspice +++ b/scripts/Xspice @@ -12,7 +12,7 @@ Xspice is kept in the same repository. It can also be used to debug the qxl driver. Xspice (this executable) will set a bunch of environment variables that are -used by spiceqxl_drv.so, and then exec Xorg, giving it the default config file, +used by spiceqxl_drv.so, and then spawn Xorg, giving it the default config file, which can be overridden as well. """ commit 9f4e429c13fd6e56a200d58c735b37d7eeb671fe Author: Alon Levy <al...@redhat.com> Date: Mon Sep 2 17:38:45 2013 +0300 Xspice: use subprocess.Popen, nicer cleanup of files/processes Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/scripts/Xspice b/scripts/Xspice index bfa9197..b50ea46 100755 --- a/scripts/Xspice +++ b/scripts/Xspice @@ -22,6 +22,7 @@ import sys import tempfile import atexit import time +from subprocess import Popen def which(x): for p in os.environ['PATH'].split(':'): @@ -124,13 +125,28 @@ def error(msg, exit_code=1): if not args.xorg: error("Xorg missing") +cleanup_files = [] +cleanup_processes = [] + def cleanup(): - if os.path.isfile(cf.name + ".log"): - os.remove(cf.name + ".log") + for f in cleanup_files: + if os.path.isfile(f): + os.remove(f) + for p in cleanup_processes: + p.kill() + for p in cleanup_processes: + p.wait() + +def launch(*args, **kw): + p = Popen(*args, **kw) + cleanup_processes.append(p) + return p + +atexit.register(cleanup) if args.auto: - atexit.register(cleanup) cf = tempfile.NamedTemporaryFile(prefix="Xspice-", delete=True) + cleanup_files.append(cf.name + ".log") args.config = cf.name xorg_args = [ '-logfile', cf.name + ".log" ] + xorg_args cf.write(""" @@ -206,10 +222,10 @@ if cgdb and args.cgdb: # This is currently mandatory; the driver cannot survive a reset xorg_args = [ '-noreset' ] + xorg_args -xpid = os.spawnv(os.P_NOWAIT, args.xorg, exec_args + xorg_args) +xorg = launch(executable=args.xorg, args=exec_args + xorg_args) time.sleep(2) -retpid,rc = os.waitpid(xpid, os.WNOHANG) +retpid,rc = os.waitpid(xorg.pid, os.WNOHANG) if retpid != 0: print "Error: X server is not running" else: @@ -219,7 +235,7 @@ else: os.spawnlpe(os.P_NOWAIT, args.xsession, environ) try: - os.waitpid(xpid, 0) + xorg.wait() except KeyboardInterrupt: # Catch Ctrl-C as that is the common way of ending this script print "Keyboard Interrupt" commit a6d00dccbf8257c0d225e0886cb2d4a8ba60fe38 Author: Alon Levy <al...@redhat.com> Date: Mon Sep 2 17:28:50 2013 +0300 xspice: add uinput support to vdagent support Signed-off-by: Alon Levy <al...@redhat.com> diff --git a/src/Makefile.am b/src/Makefile.am index c6e6dcd..edc2f0b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -91,6 +91,8 @@ spiceqxl_drv_la_SOURCES = \ spiceqxl_display.h \ spiceqxl_vdagent.c \ spiceqxl_vdagent.h \ + spiceqxl_uinput.c \ + spiceqxl_uinput.h \ spiceqxl_audio.c \ spiceqxl_audio.h \ spiceqxl_inputs.c \ diff --git a/src/qxl.h b/src/qxl.h index c5d5bdc..52e92e9 100644 --- a/src/qxl.h +++ b/src/qxl.h @@ -146,6 +146,7 @@ enum { OPTION_SPICE_PLAYBACK_FIFO_DIR, OPTION_SPICE_VDAGENT_ENABLED, OPTION_SPICE_VDAGENT_VIRTIO_PATH, + OPTION_SPICE_VDAGENT_UINPUT_PATH, #endif OPTION_COUNT, }; diff --git a/src/qxl_driver.c b/src/qxl_driver.c index 5da5c8f..f076f00 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -69,6 +69,7 @@ static char filter_str[] = "filter"; static char auto_str[] = "auto"; static char auto_glz_str[] = "auto_glz"; static char spice_vdagent_virtio_path_default[] = "/tmp/xspice-virtio"; +static char spice_vdagent_uinput_path_default[] = "/tmp/xspice-uinput"; #endif static char driver_name[] = QXL_DRIVER_NAME; const OptionInfoRec DefaultOptions[] = @@ -139,6 +140,8 @@ const OptionInfoRec DefaultOptions[] = "SpiceVdagentEnabled", OPTV_BOOLEAN, {0}, FALSE}, { OPTION_SPICE_VDAGENT_VIRTIO_PATH, "SpiceVdagentVirtioPath", OPTV_STRING, {.str = spice_vdagent_virtio_path_default}, FALSE}, + { OPTION_SPICE_VDAGENT_UINPUT_PATH, + "SpiceVdagentUinputPath", OPTV_STRING, {.str = spice_vdagent_uinput_path_default}, FALSE}, #endif { -1, NULL, OPTV_NONE, {0}, FALSE } diff --git a/src/spiceqxl_uinput.c b/src/spiceqxl_uinput.c new file mode 100644 index 0000000..443f931 --- /dev/null +++ b/src/spiceqxl_uinput.c @@ -0,0 +1,124 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> + +#include <linux/input.h> +#include <linux/uinput.h> + +#include "qxl_option_helpers.h" +#include "spiceqxl_inputs.h" + +#include "spiceqxl_uinput.h" + +static const char *uinput_filename; +static int uinput_fd; +static struct input_event inp_event; +static int offset; + +static void spiceqxl_uinput_read_cb(int fd, int event, void *opaque) +{ + int n; + static int x = -1; -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: http://lists.debian.org/e1vyln3-0001bi...@vasks.debian.org