[Spice-devel] [PATCH spice-gtk 2/3] Move gtk/ -> src/

Fabiano Fidencio ffidenci at redhat.com
Mon Jun 8 08:22:47 PDT 2015



----- Original Message -----
> From: "Marc-André Lureau" <marcandre.lureau at redhat.com>
> To: spice-devel at lists.freedesktop.org
> Sent: Friday, June 5, 2015 6:29:43 PM
> Subject: [Spice-devel] [PATCH spice-gtk 2/3] Move gtk/ -> src/
> 
> For historical reasons, the code was placed under gtk/ subdirectory.
> If it was always bugging you, bug no more!

Finally! ACK!

> ---
>  Makefile.am                                  |    2 +-
>  configure.ac                                 |   10 +-
>  doc/reference/Makefile.am                    |   10 +-
>  gtk/Makefile.am                              |  703 ------
>  gtk/bio-gio.c                                |  114 -
>  gtk/bio-gio.h                                |   30 -
>  gtk/channel-base.c                           |  284 ---
>  gtk/channel-cursor.c                         |  529 -----
>  gtk/channel-cursor.h                         |   77 -
>  gtk/channel-display-mjpeg.c                  |  156 --
>  gtk/channel-display-priv.h                   |  113 -
>  gtk/channel-display.c                        | 1789 ---------------
>  gtk/channel-display.h                        |  102 -
>  gtk/channel-inputs.c                         |  603 ------
>  gtk/channel-inputs.h                         |   89 -
>  gtk/channel-main.c                           | 2993
>  --------------------------
>  gtk/channel-main.h                           |  109 -
>  gtk/channel-playback-priv.h                  |   24 -
>  gtk/channel-playback.c                       |  496 -----
>  gtk/channel-playback.h                       |   76 -
>  gtk/channel-port.c                           |  361 ----
>  gtk/channel-port.h                           |   76 -
>  gtk/channel-record.c                         |  482 -----
>  gtk/channel-record.h                         |   77 -
>  gtk/channel-smartcard.c                      |  587 -----
>  gtk/channel-smartcard.h                      |   68 -
>  gtk/channel-usbredir-priv.h                  |   61 -
>  gtk/channel-usbredir.c                       |  686 ------
>  gtk/channel-usbredir.h                       |   71 -
>  gtk/channel-webdav.c                         |  613 ------
>  gtk/channel-webdav.h                         |   68 -
>  gtk/client_sw_canvas.c                       |   20 -
>  gtk/client_sw_canvas.h                       |   25 -
>  gtk/continuation.c                           |  102 -
>  gtk/continuation.h                           |   61 -
>  gtk/controller/Makefile.am                   |  100 -
>  gtk/controller/controller.vala               |  286 ---
>  gtk/controller/custom.h                      |   22 -
>  gtk/controller/custom.vapi                   |   28 -
>  gtk/controller/dump.c                        |  118 -
>  gtk/controller/foreign-menu.vala             |  197 --
>  gtk/controller/gio-windows-2.0.vapi          |   30 -
>  gtk/controller/menu.vala                     |  108 -
>  gtk/controller/namedpipe.c                   |  270 ---
>  gtk/controller/namedpipe.h                   |   59 -
>  gtk/controller/namedpipeconnection.c         |  245 ---
>  gtk/controller/namedpipeconnection.h         |   56 -
>  gtk/controller/namedpipelistener.c           |  329 ---
>  gtk/controller/namedpipelistener.h           |   70 -
>  gtk/controller/spice-controller-listener.c   |  159 --
>  gtk/controller/spice-controller-listener.h   |   47 -
>  gtk/controller/spice-foreign-menu-listener.c |  161 --
>  gtk/controller/spice-foreign-menu-listener.h |   47 -
>  gtk/controller/test.c                        |  292 ---
>  gtk/controller/util.vala                     |   42 -
>  gtk/controller/win32-util.c                  |  161 --
>  gtk/controller/win32-util.h                  |   30 -
>  gtk/coroutine.h                              |   83 -
>  gtk/coroutine_gthread.c                      |  170 --
>  gtk/coroutine_ucontext.c                     |  150 --
>  gtk/coroutine_winfibers.c                    |  126 --
>  gtk/decode-glz-tmpl.c                        |  336 ---
>  gtk/decode-glz.c                             |  475 ----
>  gtk/decode-jpeg.c                            |  191 --
>  gtk/decode-zlib.c                            |   89 -
>  gtk/decode.h                                 |   44 -
>  gtk/desktop-integration.c                    |  223 --
>  gtk/desktop-integration.h                    |   64 -
>  gtk/gio-coroutine.c                          |  275 ---
>  gtk/gio-coroutine.h                          |   66 -
>  gtk/giopipe.c                                |  484 -----
>  gtk/giopipe.h                                |   29 -
>  gtk/glib-compat.c                            |   79 -
>  gtk/glib-compat.h                            |   68 -
>  gtk/gtk-compat.h                             |   56 -
>  gtk/keymap-gen.pl                            |  214 --
>  gtk/keymaps.csv                              |  490 -----
>  gtk/map-file                                 |  139 --
>  gtk/smartcard-manager-priv.h                 |   37 -
>  gtk/smartcard-manager.c                      |  737 -------
>  gtk/smartcard-manager.h                      |   80 -
>  gtk/spice-audio-priv.h                       |   42 -
>  gtk/spice-audio.c                            |  274 ---
>  gtk/spice-audio.h                            |  109 -
>  gtk/spice-channel-cache.h                    |  106 -
>  gtk/spice-channel-enums.h                    |    7 -
>  gtk/spice-channel-priv.h                     |  203 --
>  gtk/spice-channel.c                          | 2960
>  -------------------------
>  gtk/spice-channel.h                          |  131 --
>  gtk/spice-client-glib-usb-acl-helper.c       |  372 ----
>  gtk/spice-client-gtk-manual.defs             |  117 -
>  gtk/spice-client-gtk-module.c                |   45 -
>  gtk/spice-client-gtk.override                |  171 --
>  gtk/spice-client.c                           |   27 -
>  gtk/spice-client.h                           |   79 -
>  gtk/spice-cmdline.c                          |   98 -
>  gtk/spice-cmdline.h                          |   29 -
>  gtk/spice-common.h                           |   36 -
>  gtk/spice-glib-sym-file                      |  111 -
>  gtk/spice-grabsequence.c                     |  163 --
>  gtk/spice-grabsequence.h                     |   61 -
>  gtk/spice-gstaudio.c                         |  739 -------
>  gtk/spice-gstaudio.h                         |   56 -
>  gtk/spice-gtk-session-priv.h                 |   34 -
>  gtk/spice-gtk-session.c                      | 1229 -----------
>  gtk/spice-gtk-session.h                      |   65 -
>  gtk/spice-gtk-sym-file                       |   23 -
>  gtk/spice-marshal.txt                        |   14 -
>  gtk/spice-option.c                           |  284 ---
>  gtk/spice-option.h                           |   31 -
>  gtk/spice-pulse.c                            | 1354 ------------
>  gtk/spice-pulse.h                            |   57 -
>  gtk/spice-session-priv.h                     |  104 -
>  gtk/spice-session.c                          | 2728 -----------------------
>  gtk/spice-session.h                          |  103 -
>  gtk/spice-types.h                            |   35 -
>  gtk/spice-uri-priv.h                         |   30 -
>  gtk/spice-uri.c                              |  462 ----
>  gtk/spice-uri.h                              |   52 -
>  gtk/spice-util-priv.h                        |   52 -
>  gtk/spice-util.c                             |  497 -----
>  gtk/spice-util.h                             |   63 -
>  gtk/spice-version.h.in                       |   70 -
>  gtk/spice-widget-cairo.c                     |  160 --
>  gtk/spice-widget-priv.h                      |  141 --
>  gtk/spice-widget-x11.c                       |  280 ---
>  gtk/spice-widget.c                           | 2642 -----------------------
>  gtk/spice-widget.h                           |   92 -
>  gtk/spicy-screenshot.c                       |  196 --
>  gtk/spicy-stats.c                            |  144 --
>  gtk/spicy.c                                  | 1855 ----------------
>  gtk/usb-acl-helper.c                         |  299 ---
>  gtk/usb-acl-helper.h                         |   72 -
>  gtk/usb-device-manager-priv.h                |   48 -
>  gtk/usb-device-manager.c                     | 1932 -----------------
>  gtk/usb-device-manager.h                     |  122 --
>  gtk/usb-device-widget.c                      |  554 -----
>  gtk/usb-device-widget.h                      |   81 -
>  gtk/usbutil.c                                |  323 ---
>  gtk/usbutil.h                                |   39 -
>  gtk/vmcstream.c                              |  535 -----
>  gtk/vmcstream.h                              |   81 -
>  gtk/vncdisplaykeymap.c                       |  323 ---
>  gtk/vncdisplaykeymap.h                       |   36 -
>  gtk/win-usb-clerk.h                          |   36 -
>  gtk/win-usb-dev.c                            |  542 -----
>  gtk/win-usb-dev.h                            |  110 -
>  gtk/win-usb-driver-install.c                 |  398 ----
>  gtk/win-usb-driver-install.h                 |  104 -
>  gtk/wocky-http-proxy.c                       |  537 -----
>  gtk/wocky-http-proxy.h                       |   56 -
>  po/POTFILES.in                               |   22 +-
>  po/POTFILES.skip                             |    3 +-
>  src/Makefile.am                              |  703 ++++++
>  src/bio-gio.c                                |  114 +
>  src/bio-gio.h                                |   30 +
>  src/channel-base.c                           |  284 +++
>  src/channel-cursor.c                         |  529 +++++
>  src/channel-cursor.h                         |   77 +
>  src/channel-display-mjpeg.c                  |  156 ++
>  src/channel-display-priv.h                   |  113 +
>  src/channel-display.c                        | 1789 +++++++++++++++
>  src/channel-display.h                        |  102 +
>  src/channel-inputs.c                         |  603 ++++++
>  src/channel-inputs.h                         |   89 +
>  src/channel-main.c                           | 2993
>  ++++++++++++++++++++++++++
>  src/channel-main.h                           |  109 +
>  src/channel-playback-priv.h                  |   24 +
>  src/channel-playback.c                       |  496 +++++
>  src/channel-playback.h                       |   76 +
>  src/channel-port.c                           |  361 ++++
>  src/channel-port.h                           |   76 +
>  src/channel-record.c                         |  482 +++++
>  src/channel-record.h                         |   77 +
>  src/channel-smartcard.c                      |  587 +++++
>  src/channel-smartcard.h                      |   68 +
>  src/channel-usbredir-priv.h                  |   61 +
>  src/channel-usbredir.c                       |  686 ++++++
>  src/channel-usbredir.h                       |   71 +
>  src/channel-webdav.c                         |  613 ++++++
>  src/channel-webdav.h                         |   68 +
>  src/client_sw_canvas.c                       |   20 +
>  src/client_sw_canvas.h                       |   25 +
>  src/continuation.c                           |  102 +
>  src/continuation.h                           |   61 +
>  src/controller/Makefile.am                   |  100 +
>  src/controller/controller.vala               |  286 +++
>  src/controller/custom.h                      |   22 +
>  src/controller/custom.vapi                   |   28 +
>  src/controller/dump.c                        |  118 +
>  src/controller/foreign-menu.vala             |  197 ++
>  src/controller/gio-windows-2.0.vapi          |   30 +
>  src/controller/menu.vala                     |  108 +
>  src/controller/namedpipe.c                   |  270 +++
>  src/controller/namedpipe.h                   |   59 +
>  src/controller/namedpipeconnection.c         |  245 +++
>  src/controller/namedpipeconnection.h         |   56 +
>  src/controller/namedpipelistener.c           |  329 +++
>  src/controller/namedpipelistener.h           |   70 +
>  src/controller/spice-controller-listener.c   |  159 ++
>  src/controller/spice-controller-listener.h   |   47 +
>  src/controller/spice-foreign-menu-listener.c |  161 ++
>  src/controller/spice-foreign-menu-listener.h |   47 +
>  src/controller/test.c                        |  292 +++
>  src/controller/util.vala                     |   42 +
>  src/controller/win32-util.c                  |  161 ++
>  src/controller/win32-util.h                  |   30 +
>  src/coroutine.h                              |   83 +
>  src/coroutine_gthread.c                      |  170 ++
>  src/coroutine_ucontext.c                     |  150 ++
>  src/coroutine_winfibers.c                    |  126 ++
>  src/decode-glz-tmpl.c                        |  336 +++
>  src/decode-glz.c                             |  475 ++++
>  src/decode-jpeg.c                            |  191 ++
>  src/decode-zlib.c                            |   89 +
>  src/decode.h                                 |   44 +
>  src/desktop-integration.c                    |  223 ++
>  src/desktop-integration.h                    |   64 +
>  src/gio-coroutine.c                          |  275 +++
>  src/gio-coroutine.h                          |   66 +
>  src/giopipe.c                                |  484 +++++
>  src/giopipe.h                                |   29 +
>  src/glib-compat.c                            |   79 +
>  src/glib-compat.h                            |   68 +
>  src/gtk-compat.h                             |   56 +
>  src/keymap-gen.pl                            |  214 ++
>  src/keymaps.csv                              |  490 +++++
>  src/map-file                                 |  139 ++
>  src/smartcard-manager-priv.h                 |   37 +
>  src/smartcard-manager.c                      |  737 +++++++
>  src/smartcard-manager.h                      |   80 +
>  src/spice-audio-priv.h                       |   42 +
>  src/spice-audio.c                            |  274 +++
>  src/spice-audio.h                            |  109 +
>  src/spice-channel-cache.h                    |  106 +
>  src/spice-channel-enums.h                    |    7 +
>  src/spice-channel-priv.h                     |  203 ++
>  src/spice-channel.c                          | 2960
>  +++++++++++++++++++++++++
>  src/spice-channel.h                          |  131 ++
>  src/spice-client-glib-usb-acl-helper.c       |  372 ++++
>  src/spice-client-gtk-manual.defs             |  117 +
>  src/spice-client-gtk-module.c                |   45 +
>  src/spice-client-gtk.override                |  171 ++
>  src/spice-client.c                           |   27 +
>  src/spice-client.h                           |   79 +
>  src/spice-cmdline.c                          |   98 +
>  src/spice-cmdline.h                          |   29 +
>  src/spice-common.h                           |   36 +
>  src/spice-glib-sym-file                      |  111 +
>  src/spice-grabsequence.c                     |  163 ++
>  src/spice-grabsequence.h                     |   61 +
>  src/spice-gstaudio.c                         |  739 +++++++
>  src/spice-gstaudio.h                         |   56 +
>  src/spice-gtk-session-priv.h                 |   34 +
>  src/spice-gtk-session.c                      | 1229 +++++++++++
>  src/spice-gtk-session.h                      |   65 +
>  src/spice-gtk-sym-file                       |   23 +
>  src/spice-marshal.txt                        |   14 +
>  src/spice-option.c                           |  284 +++
>  src/spice-option.h                           |   31 +
>  src/spice-pulse.c                            | 1354 ++++++++++++
>  src/spice-pulse.h                            |   57 +
>  src/spice-session-priv.h                     |  104 +
>  src/spice-session.c                          | 2728 +++++++++++++++++++++++
>  src/spice-session.h                          |  103 +
>  src/spice-types.h                            |   35 +
>  src/spice-uri-priv.h                         |   30 +
>  src/spice-uri.c                              |  462 ++++
>  src/spice-uri.h                              |   52 +
>  src/spice-util-priv.h                        |   52 +
>  src/spice-util.c                             |  497 +++++
>  src/spice-util.h                             |   63 +
>  src/spice-version.h.in                       |   70 +
>  src/spice-widget-cairo.c                     |  160 ++
>  src/spice-widget-priv.h                      |  141 ++
>  src/spice-widget-x11.c                       |  280 +++
>  src/spice-widget.c                           | 2642 +++++++++++++++++++++++
>  src/spice-widget.h                           |   92 +
>  src/spicy-screenshot.c                       |  196 ++
>  src/spicy-stats.c                            |  144 ++
>  src/spicy.c                                  | 1855 ++++++++++++++++
>  src/usb-acl-helper.c                         |  299 +++
>  src/usb-acl-helper.h                         |   72 +
>  src/usb-device-manager-priv.h                |   48 +
>  src/usb-device-manager.c                     | 1932 +++++++++++++++++
>  src/usb-device-manager.h                     |  122 ++
>  src/usb-device-widget.c                      |  554 +++++
>  src/usb-device-widget.h                      |   81 +
>  src/usbutil.c                                |  323 +++
>  src/usbutil.h                                |   39 +
>  src/vmcstream.c                              |  535 +++++
>  src/vmcstream.h                              |   81 +
>  src/vncdisplaykeymap.c                       |  323 +++
>  src/vncdisplaykeymap.h                       |   36 +
>  src/win-usb-clerk.h                          |   36 +
>  src/win-usb-dev.c                            |  542 +++++
>  src/win-usb-dev.h                            |  110 +
>  src/win-usb-driver-install.c                 |  398 ++++
>  src/win-usb-driver-install.h                 |  104 +
>  src/wocky-http-proxy.c                       |  537 +++++
>  src/wocky-http-proxy.h                       |   56 +
>  tests/Makefile.am                            |    6 +-
>  vapi/Makefile.am                             |    6 +-
>  303 files changed, 44198 insertions(+), 44197 deletions(-)
>  delete mode 100644 gtk/Makefile.am
>  delete mode 100644 gtk/bio-gio.c
>  delete mode 100644 gtk/bio-gio.h
>  delete mode 100644 gtk/channel-base.c
>  delete mode 100644 gtk/channel-cursor.c
>  delete mode 100644 gtk/channel-cursor.h
>  delete mode 100644 gtk/channel-display-mjpeg.c
>  delete mode 100644 gtk/channel-display-priv.h
>  delete mode 100644 gtk/channel-display.c
>  delete mode 100644 gtk/channel-display.h
>  delete mode 100644 gtk/channel-inputs.c
>  delete mode 100644 gtk/channel-inputs.h
>  delete mode 100644 gtk/channel-main.c
>  delete mode 100644 gtk/channel-main.h
>  delete mode 100644 gtk/channel-playback-priv.h
>  delete mode 100644 gtk/channel-playback.c
>  delete mode 100644 gtk/channel-playback.h
>  delete mode 100644 gtk/channel-port.c
>  delete mode 100644 gtk/channel-port.h
>  delete mode 100644 gtk/channel-record.c
>  delete mode 100644 gtk/channel-record.h
>  delete mode 100644 gtk/channel-smartcard.c
>  delete mode 100644 gtk/channel-smartcard.h
>  delete mode 100644 gtk/channel-usbredir-priv.h
>  delete mode 100644 gtk/channel-usbredir.c
>  delete mode 100644 gtk/channel-usbredir.h
>  delete mode 100644 gtk/channel-webdav.c
>  delete mode 100644 gtk/channel-webdav.h
>  delete mode 100644 gtk/client_sw_canvas.c
>  delete mode 100644 gtk/client_sw_canvas.h
>  delete mode 100644 gtk/continuation.c
>  delete mode 100644 gtk/continuation.h
>  delete mode 100644 gtk/controller/Makefile.am
>  delete mode 100644 gtk/controller/controller.vala
>  delete mode 100644 gtk/controller/custom.h
>  delete mode 100644 gtk/controller/custom.vapi
>  delete mode 100644 gtk/controller/dump.c
>  delete mode 100644 gtk/controller/foreign-menu.vala
>  delete mode 100644 gtk/controller/gio-windows-2.0.vapi
>  delete mode 100644 gtk/controller/menu.vala
>  delete mode 100644 gtk/controller/namedpipe.c
>  delete mode 100644 gtk/controller/namedpipe.h
>  delete mode 100644 gtk/controller/namedpipeconnection.c
>  delete mode 100644 gtk/controller/namedpipeconnection.h
>  delete mode 100644 gtk/controller/namedpipelistener.c
>  delete mode 100644 gtk/controller/namedpipelistener.h
>  delete mode 100644 gtk/controller/spice-controller-listener.c
>  delete mode 100644 gtk/controller/spice-controller-listener.h
>  delete mode 100644 gtk/controller/spice-foreign-menu-listener.c
>  delete mode 100644 gtk/controller/spice-foreign-menu-listener.h
>  delete mode 100644 gtk/controller/test.c
>  delete mode 100644 gtk/controller/util.vala
>  delete mode 100644 gtk/controller/win32-util.c
>  delete mode 100644 gtk/controller/win32-util.h
>  delete mode 100644 gtk/coroutine.h
>  delete mode 100644 gtk/coroutine_gthread.c
>  delete mode 100644 gtk/coroutine_ucontext.c
>  delete mode 100644 gtk/coroutine_winfibers.c
>  delete mode 100644 gtk/decode-glz-tmpl.c
>  delete mode 100644 gtk/decode-glz.c
>  delete mode 100644 gtk/decode-jpeg.c
>  delete mode 100644 gtk/decode-zlib.c
>  delete mode 100644 gtk/decode.h
>  delete mode 100644 gtk/desktop-integration.c
>  delete mode 100644 gtk/desktop-integration.h
>  delete mode 100644 gtk/gio-coroutine.c
>  delete mode 100644 gtk/gio-coroutine.h
>  delete mode 100644 gtk/giopipe.c
>  delete mode 100644 gtk/giopipe.h
>  delete mode 100644 gtk/glib-compat.c
>  delete mode 100644 gtk/glib-compat.h
>  delete mode 100644 gtk/gtk-compat.h
>  delete mode 100755 gtk/keymap-gen.pl
>  delete mode 100644 gtk/keymaps.csv
>  delete mode 100644 gtk/map-file
>  delete mode 100644 gtk/smartcard-manager-priv.h
>  delete mode 100644 gtk/smartcard-manager.c
>  delete mode 100644 gtk/smartcard-manager.h
>  delete mode 100644 gtk/spice-audio-priv.h
>  delete mode 100644 gtk/spice-audio.c
>  delete mode 100644 gtk/spice-audio.h
>  delete mode 100644 gtk/spice-channel-cache.h
>  delete mode 100644 gtk/spice-channel-enums.h
>  delete mode 100644 gtk/spice-channel-priv.h
>  delete mode 100644 gtk/spice-channel.c
>  delete mode 100644 gtk/spice-channel.h
>  delete mode 100644 gtk/spice-client-glib-usb-acl-helper.c
>  delete mode 100644 gtk/spice-client-gtk-manual.defs
>  delete mode 100644 gtk/spice-client-gtk-module.c
>  delete mode 100644 gtk/spice-client-gtk.override
>  delete mode 100644 gtk/spice-client.c
>  delete mode 100644 gtk/spice-client.h
>  delete mode 100644 gtk/spice-cmdline.c
>  delete mode 100644 gtk/spice-cmdline.h
>  delete mode 100644 gtk/spice-common.h
>  delete mode 100644 gtk/spice-glib-sym-file
>  delete mode 100644 gtk/spice-grabsequence.c
>  delete mode 100644 gtk/spice-grabsequence.h
>  delete mode 100644 gtk/spice-gstaudio.c
>  delete mode 100644 gtk/spice-gstaudio.h
>  delete mode 100644 gtk/spice-gtk-session-priv.h
>  delete mode 100644 gtk/spice-gtk-session.c
>  delete mode 100644 gtk/spice-gtk-session.h
>  delete mode 100644 gtk/spice-gtk-sym-file
>  delete mode 100644 gtk/spice-marshal.txt
>  delete mode 100644 gtk/spice-option.c
>  delete mode 100644 gtk/spice-option.h
>  delete mode 100644 gtk/spice-pulse.c
>  delete mode 100644 gtk/spice-pulse.h
>  delete mode 100644 gtk/spice-session-priv.h
>  delete mode 100644 gtk/spice-session.c
>  delete mode 100644 gtk/spice-session.h
>  delete mode 100644 gtk/spice-types.h
>  delete mode 100644 gtk/spice-uri-priv.h
>  delete mode 100644 gtk/spice-uri.c
>  delete mode 100644 gtk/spice-uri.h
>  delete mode 100644 gtk/spice-util-priv.h
>  delete mode 100644 gtk/spice-util.c
>  delete mode 100644 gtk/spice-util.h
>  delete mode 100644 gtk/spice-version.h.in
>  delete mode 100644 gtk/spice-widget-cairo.c
>  delete mode 100644 gtk/spice-widget-priv.h
>  delete mode 100644 gtk/spice-widget-x11.c
>  delete mode 100644 gtk/spice-widget.c
>  delete mode 100644 gtk/spice-widget.h
>  delete mode 100644 gtk/spicy-screenshot.c
>  delete mode 100644 gtk/spicy-stats.c
>  delete mode 100644 gtk/spicy.c
>  delete mode 100644 gtk/usb-acl-helper.c
>  delete mode 100644 gtk/usb-acl-helper.h
>  delete mode 100644 gtk/usb-device-manager-priv.h
>  delete mode 100644 gtk/usb-device-manager.c
>  delete mode 100644 gtk/usb-device-manager.h
>  delete mode 100644 gtk/usb-device-widget.c
>  delete mode 100644 gtk/usb-device-widget.h
>  delete mode 100644 gtk/usbutil.c
>  delete mode 100644 gtk/usbutil.h
>  delete mode 100644 gtk/vmcstream.c
>  delete mode 100644 gtk/vmcstream.h
>  delete mode 100644 gtk/vncdisplaykeymap.c
>  delete mode 100644 gtk/vncdisplaykeymap.h
>  delete mode 100644 gtk/win-usb-clerk.h
>  delete mode 100644 gtk/win-usb-dev.c
>  delete mode 100644 gtk/win-usb-dev.h
>  delete mode 100644 gtk/win-usb-driver-install.c
>  delete mode 100644 gtk/win-usb-driver-install.h
>  delete mode 100644 gtk/wocky-http-proxy.c
>  delete mode 100644 gtk/wocky-http-proxy.h
>  create mode 100644 src/Makefile.am
>  create mode 100644 src/bio-gio.c
>  create mode 100644 src/bio-gio.h
>  create mode 100644 src/channel-base.c
>  create mode 100644 src/channel-cursor.c
>  create mode 100644 src/channel-cursor.h
>  create mode 100644 src/channel-display-mjpeg.c
>  create mode 100644 src/channel-display-priv.h
>  create mode 100644 src/channel-display.c
>  create mode 100644 src/channel-display.h
>  create mode 100644 src/channel-inputs.c
>  create mode 100644 src/channel-inputs.h
>  create mode 100644 src/channel-main.c
>  create mode 100644 src/channel-main.h
>  create mode 100644 src/channel-playback-priv.h
>  create mode 100644 src/channel-playback.c
>  create mode 100644 src/channel-playback.h
>  create mode 100644 src/channel-port.c
>  create mode 100644 src/channel-port.h
>  create mode 100644 src/channel-record.c
>  create mode 100644 src/channel-record.h
>  create mode 100644 src/channel-smartcard.c
>  create mode 100644 src/channel-smartcard.h
>  create mode 100644 src/channel-usbredir-priv.h
>  create mode 100644 src/channel-usbredir.c
>  create mode 100644 src/channel-usbredir.h
>  create mode 100644 src/channel-webdav.c
>  create mode 100644 src/channel-webdav.h
>  create mode 100644 src/client_sw_canvas.c
>  create mode 100644 src/client_sw_canvas.h
>  create mode 100644 src/continuation.c
>  create mode 100644 src/continuation.h
>  create mode 100644 src/controller/Makefile.am
>  create mode 100644 src/controller/controller.vala
>  create mode 100644 src/controller/custom.h
>  create mode 100644 src/controller/custom.vapi
>  create mode 100644 src/controller/dump.c
>  create mode 100644 src/controller/foreign-menu.vala
>  create mode 100644 src/controller/gio-windows-2.0.vapi
>  create mode 100644 src/controller/menu.vala
>  create mode 100644 src/controller/namedpipe.c
>  create mode 100644 src/controller/namedpipe.h
>  create mode 100644 src/controller/namedpipeconnection.c
>  create mode 100644 src/controller/namedpipeconnection.h
>  create mode 100644 src/controller/namedpipelistener.c
>  create mode 100644 src/controller/namedpipelistener.h
>  create mode 100644 src/controller/spice-controller-listener.c
>  create mode 100644 src/controller/spice-controller-listener.h
>  create mode 100644 src/controller/spice-foreign-menu-listener.c
>  create mode 100644 src/controller/spice-foreign-menu-listener.h
>  create mode 100644 src/controller/test.c
>  create mode 100644 src/controller/util.vala
>  create mode 100644 src/controller/win32-util.c
>  create mode 100644 src/controller/win32-util.h
>  create mode 100644 src/coroutine.h
>  create mode 100644 src/coroutine_gthread.c
>  create mode 100644 src/coroutine_ucontext.c
>  create mode 100644 src/coroutine_winfibers.c
>  create mode 100644 src/decode-glz-tmpl.c
>  create mode 100644 src/decode-glz.c
>  create mode 100644 src/decode-jpeg.c
>  create mode 100644 src/decode-zlib.c
>  create mode 100644 src/decode.h
>  create mode 100644 src/desktop-integration.c
>  create mode 100644 src/desktop-integration.h
>  create mode 100644 src/gio-coroutine.c
>  create mode 100644 src/gio-coroutine.h
>  create mode 100644 src/giopipe.c
>  create mode 100644 src/giopipe.h
>  create mode 100644 src/glib-compat.c
>  create mode 100644 src/glib-compat.h
>  create mode 100644 src/gtk-compat.h
>  create mode 100755 src/keymap-gen.pl
>  create mode 100644 src/keymaps.csv
>  create mode 100644 src/map-file
>  create mode 100644 src/smartcard-manager-priv.h
>  create mode 100644 src/smartcard-manager.c
>  create mode 100644 src/smartcard-manager.h
>  create mode 100644 src/spice-audio-priv.h
>  create mode 100644 src/spice-audio.c
>  create mode 100644 src/spice-audio.h
>  create mode 100644 src/spice-channel-cache.h
>  create mode 100644 src/spice-channel-enums.h
>  create mode 100644 src/spice-channel-priv.h
>  create mode 100644 src/spice-channel.c
>  create mode 100644 src/spice-channel.h
>  create mode 100644 src/spice-client-glib-usb-acl-helper.c
>  create mode 100644 src/spice-client-gtk-manual.defs
>  create mode 100644 src/spice-client-gtk-module.c
>  create mode 100644 src/spice-client-gtk.override
>  create mode 100644 src/spice-client.c
>  create mode 100644 src/spice-client.h
>  create mode 100644 src/spice-cmdline.c
>  create mode 100644 src/spice-cmdline.h
>  create mode 100644 src/spice-common.h
>  create mode 100644 src/spice-glib-sym-file
>  create mode 100644 src/spice-grabsequence.c
>  create mode 100644 src/spice-grabsequence.h
>  create mode 100644 src/spice-gstaudio.c
>  create mode 100644 src/spice-gstaudio.h
>  create mode 100644 src/spice-gtk-session-priv.h
>  create mode 100644 src/spice-gtk-session.c
>  create mode 100644 src/spice-gtk-session.h
>  create mode 100644 src/spice-gtk-sym-file
>  create mode 100644 src/spice-marshal.txt
>  create mode 100644 src/spice-option.c
>  create mode 100644 src/spice-option.h
>  create mode 100644 src/spice-pulse.c
>  create mode 100644 src/spice-pulse.h
>  create mode 100644 src/spice-session-priv.h
>  create mode 100644 src/spice-session.c
>  create mode 100644 src/spice-session.h
>  create mode 100644 src/spice-types.h
>  create mode 100644 src/spice-uri-priv.h
>  create mode 100644 src/spice-uri.c
>  create mode 100644 src/spice-uri.h
>  create mode 100644 src/spice-util-priv.h
>  create mode 100644 src/spice-util.c
>  create mode 100644 src/spice-util.h
>  create mode 100644 src/spice-version.h.in
>  create mode 100644 src/spice-widget-cairo.c
>  create mode 100644 src/spice-widget-priv.h
>  create mode 100644 src/spice-widget-x11.c
>  create mode 100644 src/spice-widget.c
>  create mode 100644 src/spice-widget.h
>  create mode 100644 src/spicy-screenshot.c
>  create mode 100644 src/spicy-stats.c
>  create mode 100644 src/spicy.c
>  create mode 100644 src/usb-acl-helper.c
>  create mode 100644 src/usb-acl-helper.h
>  create mode 100644 src/usb-device-manager-priv.h
>  create mode 100644 src/usb-device-manager.c
>  create mode 100644 src/usb-device-manager.h
>  create mode 100644 src/usb-device-widget.c
>  create mode 100644 src/usb-device-widget.h
>  create mode 100644 src/usbutil.c
>  create mode 100644 src/usbutil.h
>  create mode 100644 src/vmcstream.c
>  create mode 100644 src/vmcstream.h
>  create mode 100644 src/vncdisplaykeymap.c
>  create mode 100644 src/vncdisplaykeymap.h
>  create mode 100644 src/win-usb-clerk.h
>  create mode 100644 src/win-usb-dev.c
>  create mode 100644 src/win-usb-dev.h
>  create mode 100644 src/win-usb-driver-install.c
>  create mode 100644 src/win-usb-driver-install.h
>  create mode 100644 src/wocky-http-proxy.c
>  create mode 100644 src/wocky-http-proxy.h
> 
> diff --git a/Makefile.am b/Makefile.am
> index e559c4d..3d7a174 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -1,7 +1,7 @@
>  ACLOCAL_AMFLAGS = -I m4
>  NULL =
>  
> -SUBDIRS = spice-common gtk man po doc data
> +SUBDIRS = spice-common src man po doc data
>  
>  if BUILD_TESTS
>  SUBDIRS += tests
> diff --git a/configure.ac b/configure.ac
> index cf5a039..1d8f4d0 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -88,7 +88,7 @@ dnl
> =========================================================================
>  dnl Chek optional features
>  
>  srcdir="$(dirname $0)"
> -if test ! -e "$srcdir/gtk/vncdisplaykeymap_osx2xtkbd.c"; then
> +if test ! -e "$srcdir/src/vncdisplaykeymap_osx2xtkbd.c"; then
>    AC_MSG_CHECKING([for Text::CSV Perl module])
>    perl -MText::CSV -e "" >/dev/null 2>&1
>    if test $? -ne 0 ; then
> @@ -708,7 +708,7 @@ dnl
> ===========================================================================
>  dnl check compiler flags
>  
>  # We want to enable these, but need to sort out the
> -# decl mess with  gtk/generated_*.c
> +# decl mess with  src/generated_*.c
>  dontwarn="-Wmissing-prototypes -Wmissing-declarations"
>  
>  # We want to enable these, but Gtk+2.0 has a bad decl
> @@ -746,9 +746,9 @@ spice-controller.pc
>  data/Makefile
>  data/spicy.nsis
>  po/Makefile.in
> -gtk/Makefile
> -gtk/spice-version.h
> -gtk/controller/Makefile
> +src/Makefile
> +src/spice-version.h
> +src/controller/Makefile
>  doc/Makefile
>  doc/reference/Makefile
>  man/Makefile
> diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
> index 76c7d34..0e4d5b3 100644
> --- a/doc/reference/Makefile.am
> +++ b/doc/reference/Makefile.am
> @@ -7,7 +7,7 @@ DOC_MODULE = spice-gtk
>  DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml
>  
>  # Source code location
> -DOC_SOURCE_DIR = $(top_srcdir)/gtk
> +DOC_SOURCE_DIR = $(top_srcdir)/src
>  
>  # Extra options to supply to gtkdoc-scan.
>  SCAN_OPTIONS = \
> @@ -18,8 +18,8 @@ SCAN_OPTIONS = \
>  MKDB_OPTIONS = --xml-mode --output-format=xml
>  
>  # Used for dependencies. The docs will be rebuilt if any of these change.
> -HFILE_GLOB = $(top_srcdir)/gtk/*.h
> -CFILE_GLOB = $(top_srcdir)/gtk/*.c
> +HFILE_GLOB = $(top_srcdir)/src/*.h
> +CFILE_GLOB = $(top_srcdir)/src/*.c
>  
>  # Header files to ignore when scanning. Use base file name, no paths
>  IGNORE_HFILES=					\
> @@ -54,8 +54,8 @@ IGNORE_HFILES=					\
>  	$(NULL)
>  
>  # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
> -GTKDOC_CFLAGS = -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/gtk
> -I$(top_builddir)/gtk $(SPICE_GLIB_CFLAGS) $(SPICE_GTK_CFLAGS)
> $(COMMON_CFLAGS)
> -GTKDOC_LIBS = $(top_builddir)/gtk/libspice-client-glib-2.0.la
> $(top_builddir)/gtk/libspice-client-gtk-$(SPICE_GTK_API_VERSION).la
> +GTKDOC_CFLAGS = -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src
> -I$(top_builddir)/src $(SPICE_GLIB_CFLAGS) $(SPICE_GTK_CFLAGS)
> $(COMMON_CFLAGS)
> +GTKDOC_LIBS = $(top_builddir)/src/libspice-client-glib-2.0.la
> $(top_builddir)/src/libspice-client-gtk-$(SPICE_GTK_API_VERSION).la
>  
>  include $(top_srcdir)/gtk-doc.make
>  
> diff --git a/gtk/Makefile.am b/gtk/Makefile.am
> deleted file mode 100644
> index 25e2255..0000000
> --- a/gtk/Makefile.am
> +++ /dev/null
> @@ -1,703 +0,0 @@
> -NULL =
> -SUBDIRS =
> -
> -if WITH_CONTROLLER
> -SUBDIRS += controller
> -endif
> -
> -# Avoid need for perl(Text::CSV) by end users
> -KEYMAPS =					\
> -	vncdisplaykeymap_xorgevdev2xtkbd.c	\
> -	vncdisplaykeymap_xorgkbd2xtkbd.c	\
> -	vncdisplaykeymap_xorgxquartz2xtkbd.c	\
> -	vncdisplaykeymap_xorgxwin2xtkbd.c	\
> -	vncdisplaykeymap_osx2xtkbd.c		\
> -	vncdisplaykeymap_win322xtkbd.c		\
> -	vncdisplaykeymap_x112xtkbd.c		\
> -	$(NULL)
> -
> -# End users build dependencies can be cleaned
> -GLIBGENS =					\
> -	spice-glib-enums.c			\
> -	spice-glib-enums.h			\
> -	spice-marshal.c				\
> -	spice-marshal.h				\
> -	spice-widget-enums.c			\
> -	spice-widget-enums.h			\
> -	$(NULL)
> -
> -CLEANFILES = $(GLIBGENS)
> -BUILT_SOURCES = $(GLIBGENS) $(KEYMAPS)
> -
> -EXTRA_DIST =					\
> -	$(KEYMAPS)				\
> -	decode-glz-tmpl.c			\
> -	keymap-gen.pl				\
> -	keymaps.csv				\
> -	map-file				\
> -	spice-glib-sym-file			\
> -	spice-gtk-sym-file			\
> -	spice-client-gtk-manual.defs		\
> -	spice-client-gtk.override		\
> -	spice-marshal.txt			\
> -	spice-version.h.in			\
> -	$(NULL)
> -
> -DISTCLEANFILES = spice-version.h
> -
> -bin_PROGRAMS = spicy-stats spicy-screenshot
> -if WITH_GTK
> -bin_PROGRAMS += spicy
> -endif
> -if WITH_POLKIT
> -acldir = $(ACL_HELPER_DIR)
> -acl_PROGRAMS = spice-client-glib-usb-acl-helper
> -endif
> -
> -lib_LTLIBRARIES = libspice-client-glib-2.0.la
> -
> -if WITH_GTK
> -if HAVE_GTK_2
> -lib_LTLIBRARIES += libspice-client-gtk-2.0.la
> -else
> -lib_LTLIBRARIES += libspice-client-gtk-3.0.la
> -endif
> -endif
> -
> -if HAVE_LD_VERSION_SCRIPT
> -GLIB_SYMBOLS_LDFLAGS = -Wl,--version-script=${srcdir}/map-file
> -GLIB_SYMBOLS_FILE = map-file
> -GTK_SYMBOLS_LDFLAGS = $(GLIB_SYMBOLS_LDFLAGS)
> -GTK_SYMBOLS_FILE = $(GLIB_SYMBOLS_FILE)
> -else
> -GLIB_SYMBOLS_LDFLAGS = -export-symbols ${srcdir}/spice-glib-sym-file
> -GLIB_SYMBOLS_FILE = spice-glib-sym-file
> -GTK_SYMBOLS_LDFLAGS = -export-symbols ${srcdir}/spice-gtk-sym-file
> -GTK_SYMBOLS_FILE = spice-gtk-sym-file
> -endif
> -
> -KEYMAP_GEN = $(srcdir)/keymap-gen.pl
> -
> -SPICE_COMMON_CPPFLAGS =						\
> -	-DG_LOG_DOMAIN=\"GSpice\"				\
> -	-DSPICE_NO_DEPRECATED					\
> -	-DSPICE_GTK_LOCALEDIR=\"${SPICE_GTK_LOCALEDIR}\"	\
> -	-DPNP_IDS=\""$(PNP_IDS)"\"				\
> -	-DUSB_IDS=\""$(USB_IDS)"\"				\
> -	-DSPICE_DISABLE_ABORT					\
> -	-I$(top_srcdir)						\
> -	$(COMMON_CFLAGS)					\
> -	$(PIXMAN_CFLAGS)					\
> -	$(PULSE_CFLAGS)						\
> -	$(GTK_CFLAGS)						\
> -	$(CAIRO_CFLAGS)						\
> -	$(GLIB2_CFLAGS)						\
> -	$(GIO_CFLAGS)						\
> -	$(GOBJECT2_CFLAGS)					\
> -	$(SSL_CFLAGS)						\
> -	$(SASL_CFLAGS)						\
> -	$(GST_CFLAGS)						\
> -	$(SMARTCARD_CFLAGS)					\
> -	$(USBREDIR_CFLAGS)					\
> -	$(GUDEV_CFLAGS)						\
> -	$(SOUP_CFLAGS)						\
> -	$(PHODAV_CFLAGS)					\
> -	$(LZ4_CFLAGS)					\
> -	$(NULL)
> -
> -AM_CPPFLAGS =					\
> -	$(SPICE_COMMON_CPPFLAGS)		\
> -	$(SPICE_CFLAGS)				\
> -	$(NULL)
> -
> -#
> http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
> -SPICE_GTK_LDFLAGS_COMMON =		\
> -	-version-info 4:0:0		\
> -	-no-undefined			\
> -	$(GTK_SYMBOLS_LDFLAGS)		\
> -	$(NULL)
> -
> -SPICE_GTK_LIBADD_COMMON =		\
> -	libspice-client-glib-2.0.la	\
> -	$(GTK_LIBS)			\
> -	$(CAIRO_LIBS)			\
> -	$(XRANDR_LIBS)			\
> -	$(LIBM)				\
> -	$(NULL)
> -
> -SPICE_GTK_SOURCES_COMMON =		\
> -	glib-compat.h			\
> -	gtk-compat.h			\
> -	spice-util.c			\
> -	spice-util-priv.h		\
> -	spice-gtk-session.c		\
> -	spice-gtk-session-priv.h	\
> -	spice-widget.c			\
> -	spice-widget-priv.h		\
> -	vncdisplaykeymap.c		\
> -	vncdisplaykeymap.h		\
> -	spice-grabsequence.c		\
> -	spice-grabsequence.h		\
> -	desktop-integration.c		\
> -	desktop-integration.h		\
> -	usb-device-widget.c		\
> -	$(NULL)
> -
> -nodist_SPICE_GTK_SOURCES_COMMON =	\
> -	spice-widget-enums.c		\
> -	spice-marshal.c			\
> -	$(NULL)
> -
> -if WITH_X11
> -SPICE_GTK_SOURCES_COMMON +=		\
> -	spice-widget-x11.c		\
> -	$(NULL)
> -else
> -SPICE_GTK_SOURCES_COMMON +=		\
> -	spice-widget-cairo.c		\
> -	$(NULL)
> -endif
> -
> -if WITH_GTK
> -if HAVE_GTK_2
> -libspice_client_gtk_2_0_la_DEPEDENCIES = $(GTK_SYMBOLS_FILE)
> -libspice_client_gtk_2_0_la_LDFLAGS = $(SPICE_GTK_LDFLAGS_COMMON)
> -libspice_client_gtk_2_0_la_LIBADD = $(SPICE_GTK_LIBADD_COMMON)
> -libspice_client_gtk_2_0_la_SOURCES = $(SPICE_GTK_SOURCES_COMMON)
> -nodist_libspice_client_gtk_2_0_la_SOURCES =
> $(nodist_SPICE_GTK_SOURCES_COMMON)
> -else
> -libspice_client_gtk_3_0_la_DEPEDENCIES = $(GTK_SYMBOLS_FILE)
> -libspice_client_gtk_3_0_la_LDFLAGS = $(SPICE_GTK_LDFLAGS_COMMON)
> -libspice_client_gtk_3_0_la_LIBADD = $(SPICE_GTK_LIBADD_COMMON)
> -libspice_client_gtk_3_0_la_SOURCES = $(SPICE_GTK_SOURCES_COMMON)
> -nodist_libspice_client_gtk_3_0_la_SOURCES =
> $(nodist_SPICE_GTK_SOURCES_COMMON)
> -endif
> -
> -libspice_client_gtkincludedir =
> $(includedir)/spice-client-gtk-$(SPICE_GTK_API_VERSION)
> -libspice_client_gtkinclude_HEADERS =	\
> -	spice-gtk-session.h		\
> -	spice-widget.h			\
> -	spice-grabsequence.h		\
> -	usb-device-widget.h		\
> -	$(NULL)
> -
> -nodist_libspice_client_gtkinclude_HEADERS =	\
> -	spice-widget-enums.h			\
> -	$(NULL)
> -endif
> -
> -libspice_client_glib_2_0_la_DEPENDENCIES = $(GLIB_SYMBOLS_FILE)
> -
> -libspice_client_glib_2_0_la_LDFLAGS =	\
> -	-version-info 13:0:5		\
> -	-no-undefined			\
> -	$(GLIB_SYMBOLS_LDFLAGS)		\
> -	$(NULL)
> -
> -libspice_client_glib_2_0_la_LIBADD =					\
> -	$(top_builddir)/spice-common/common/libspice-common.la		\
> -	$(top_builddir)/spice-common/common/libspice-common-client.la	\
> -	$(GLIB2_LIBS)							\
> -	$(SOUP_LIBS)							\
> -	$(GIO_LIBS)							\
> -	$(GOBJECT2_LIBS)						\
> -	$(JPEG_LIBS)							\
> -	$(Z_LIBS)							\
> -	$(LZ4_LIBS)							\
> -	$(PIXMAN_LIBS)							\
> -	$(SSL_LIBS)							\
> -	$(PULSE_LIBS)							\
> -	$(GST_LIBS)							\
> -	$(SASL_LIBS)							\
> -	$(SMARTCARD_LIBS)						\
> -	$(USBREDIR_LIBS)						\
> -	$(GUDEV_LIBS)							\
> -	$(PHODAV_LIBS)							\
> -	$(NULL)
> -
> -if WITH_POLKIT
> -USB_ACL_HELPER_SRCS =				\
> -	usb-acl-helper.c			\
> -	usb-acl-helper.h			\
> -	$(NULL)
> -AM_CPPFLAGS += -DACL_HELPER_PATH="\"$(ACL_HELPER_DIR)\""
> -else
> -USB_ACL_HELPER_SRCS =
> -endif
> -
> -libspice_client_glib_2_0_la_SOURCES =			\
> -	bio-gio.c					\
> -	bio-gio.h					\
> -	glib-compat.c					\
> -	glib-compat.h					\
> -	spice-audio.c					\
> -	spice-audio-priv.h				\
> -	spice-common.h					\
> -	spice-util.c					\
> -	spice-util-priv.h				\
> -	spice-option.h					\
> -	spice-option.c					\
> -							\
> -	spice-client.c					\
> -	spice-session.c					\
> -	spice-session-priv.h				\
> -	spice-channel.c					\
> -	spice-channel-cache.h				\
> -	spice-channel-priv.h				\
> -	coroutine.h					\
> -	gio-coroutine.c					\
> -	gio-coroutine.h					\
> -							\
> -	channel-base.c					\
> -	channel-webdav.c				\
> -	channel-cursor.c				\
> -	channel-display.c				\
> -	channel-display-priv.h				\
> -	channel-display-mjpeg.c				\
> -	channel-inputs.c				\
> -	channel-main.c					\
> -	channel-playback.c				\
> -	channel-playback-priv.h				\
> -	channel-port.c					\
> -	channel-record.c				\
> -	channel-smartcard.c				\
> -	channel-usbredir.c				\
> -	channel-usbredir-priv.h				\
> -	smartcard-manager.c				\
> -	smartcard-manager-priv.h			\
> -	spice-uri.c					\
> -	spice-uri-priv.h				\
> -	usb-device-manager.c				\
> -	usb-device-manager-priv.h			\
> -	usbutil.c					\
> -	usbutil.h					\
> -	$(USB_ACL_HELPER_SRCS)				\
> -	vmcstream.c					\
> -	vmcstream.h					\
> -	wocky-http-proxy.c				\
> -	wocky-http-proxy.h				\
> -							\
> -	decode.h					\
> -	decode-glz.c					\
> -	decode-jpeg.c					\
> -	decode-zlib.c					\
> -							\
> -	client_sw_canvas.c	\
> -	client_sw_canvas.h	\
> -	$(NULL)
> -
> -nodist_libspice_client_glib_2_0_la_SOURCES =	\
> -	spice-glib-enums.c			\
> -	spice-marshal.c				\
> -	spice-marshal.h				\
> -	$(NULL)
> -
> -libspice_client_glibincludedir = $(includedir)/spice-client-glib-2.0
> -libspice_client_glibinclude_HEADERS =	\
> -	spice-audio.h			\
> -	spice-client.h			\
> -	spice-uri.h			\
> -	spice-types.h			\
> -	spice-session.h			\
> -	spice-channel.h			\
> -	spice-util.h			\
> -	spice-option.h			\
> -	spice-version.h			\
> -	channel-cursor.h		\
> -	channel-display.h		\
> -	channel-inputs.h		\
> -	channel-main.h			\
> -	channel-playback.h		\
> -	channel-port.h			\
> -	channel-record.h		\
> -	channel-smartcard.h		\
> -	channel-usbredir.h		\
> -	channel-webdav.h		\
> -	usb-device-manager.h		\
> -	smartcard-manager.h		\
> -	$(NULL)
> -
> -nodist_libspice_client_glibinclude_HEADERS =	\
> -	spice-glib-enums.h			\
> -	$(NULL)
> -
> -# file for API compatibility, but we don't want warning during our
> compilation
> -dist_libspice_client_glibinclude_DATA =	\
> -	spice-channel-enums.h		\
> -	$(NULL)
> -
> -if WITH_PULSE
> -libspice_client_glib_2_0_la_SOURCES +=	\
> -	spice-pulse.c			\
> -	spice-pulse.h			\
> -	$(NULL)
> -endif
> -
> -if WITH_GSTAUDIO
> -libspice_client_glib_2_0_la_SOURCES +=	\
> -	spice-gstaudio.c		\
> -	spice-gstaudio.h		\
> -	$(NULL)
> -endif
> -
> -if WITH_PHODAV
> -libspice_client_glib_2_0_la_SOURCES +=	\
> -	giopipe.c			\
> -	giopipe.h			\
> -	$(NULL)
> -endif
> -
> -if WITH_UCONTEXT
> -libspice_client_glib_2_0_la_SOURCES += continuation.h continuation.c
> coroutine_ucontext.c
> -endif
> -
> -if WITH_WINFIBER
> -libspice_client_glib_2_0_la_SOURCES += coroutine_winfibers.c
> -endif
> -
> -if WITH_GTHREAD
> -libspice_client_glib_2_0_la_SOURCES += coroutine_gthread.c
> -libspice_client_glib_2_0_la_LIBADD += $(GTHREAD_LIBS)
> -endif
> -
> -
> -WIN_USB_FILES= \
> -	win-usb-dev.h			\
> -	win-usb-dev.c			\
> -	win-usb-clerk.h			\
> -	win-usb-driver-install.h	\
> -	win-usb-driver-install.c	\
> -	$(NULL)
> -
> -if OS_WIN32
> -if WITH_USBREDIR
> -libspice_client_glib_2_0_la_SOURCES += \
> -	$(WIN_USB_FILES)
> -endif
> -libspice_client_glib_2_0_la_LIBADD += -lws2_32 -lgdi32
> -endif
> -
> -spicy_SOURCES =					\
> -	spicy.c					\
> -	spice-cmdline.h				\
> -	spice-cmdline.c				\
> -	$(NULL)
> -
> -spicy_LDADD =						\
> -	libspice-client-gtk-$(SPICE_GTK_API_VERSION).la	\
> -	libspice-client-glib-2.0.la			\
> -	$(XRANDR_LIBS)					\
> -	$(GTHREAD_LIBS)					\
> -	$(GTK_LIBS)					\
> -	$(LIBM)						\
> -	$(NULL)
> -
> -spicy_CPPFLAGS =			\
> -	$(AM_CPPFLAGS)			\
> -	$(XRANDR_CFLAGS)		\
> -	$(GTHREAD_CFLAGS)		\
> -	-DSPICE_DISABLE_DEPRECATED	\
> -	$(NULL)
> -
> -
> -if WITH_POLKIT
> -spice_client_glib_usb_acl_helper_SOURCES =	\
> -	glib-compat.c				\
> -	glib-compat.h				\
> -	spice-client-glib-usb-acl-helper.c	\
> -	$(NULL)
> -
> -spice_client_glib_usb_acl_helper_LDADD =	\
> -	$(GLIB2_LIBS)				\
> -	$(GIO_LIBS)				\
> -	$(POLKIT_LIBS)				\
> -	$(ACL_LIBS)				\
> -	$(PIE_LDFLAGS)				\
> -	$(NULL)
> -
> -spice_client_glib_usb_acl_helper_CPPFLAGS =	\
> -	$(SPICE_CFLAGS)				\
> -	$(GLIB2_CFLAGS)				\
> -	$(GIO_CFLAGS)				\
> -	$(POLKIT_CFLAGS)			\
> -	$(PIE_CFLAGS)				\
> -	$(NULL)
> -
> -install-data-hook:
> -	-chown root $(DESTDIR)$(acldir)/spice-client-glib-usb-acl-helper
> -	-chmod u+s  $(DESTDIR)$(acldir)/spice-client-glib-usb-acl-helper
> -
> -endif
> -
> -
> -spicy_screenshot_SOURCES =			\
> -	spicy-screenshot.c			\
> -	spice-cmdline.h				\
> -	spice-cmdline.c				\
> -	$(NULL)
> -
> -spicy_screenshot_LDADD =			\
> -	libspice-client-glib-2.0.la		\
> -	$(GOBJECT2_LIBS)			\
> -	$(NULL)
> -
> -spicy_stats_SOURCES =			\
> -	spicy-stats.c			\
> -	spice-cmdline.h			\
> -	spice-cmdline.c			\
> -	$(NULL)
> -
> -spicy_stats_LDADD =				\
> -	libspice-client-glib-2.0.la		\
> -	$(GOBJECT2_LIBS)			\
> -	$(NULL)
> -
> -
> -
> -$(libspice_client_glib_2_0_la_SOURCES): spice-glib-enums.h spice-marshal.h
> -
> -if WITH_GTK
> -if HAVE_GTK_2
> -$(libspice_client_gtk_2_0_la_SOURCES): spice-glib-enums.h
> spice-widget-enums.h
> -else
> -$(libspice_client_gtk_3_0_la_SOURCES): spice-glib-enums.h
> spice-widget-enums.h
> -endif
> -endif
> -
> -spice-marshal.c: spice-marshal.h
> -spice-glib-enums.c: spice-glib-enums.h
> -spice-widget-enums.c: spice-widget-enums.h
> -
> -spice-marshal.c: spice-marshal.txt
> -	$(AM_V_GEN)echo "#include \"config.h\"" > $@ && \
> -		echo "#include \"spice-marshal.h\"" > $@ && \
> -		glib-genmarshal --body $< >> $@ || (rm -f $@ && exit 1)
> -
> -spice-marshal.h: spice-marshal.txt
> -	$(AM_V_GEN)glib-genmarshal --header $< > $@ || (rm -f $@ && exit 1)
> -
> -spice-glib-enums.c: spice-channel.h channel-inputs.h spice-session.h
> -	$(AM_V_GEN)glib-mkenums --fhead "#include \"config.h\"\n\n" \
> -			--fhead "#include <glib-object.h>\n" \
> -			--fhead "#include \"spice-glib-enums.h\"\n\n" \
> -			--fprod "\n#include \"spice-session.h\"\n" \
> -			--fprod "\n#include \"spice-channel.h\"\n" \
> -			--fprod "\n#include \"channel-inputs.h\"\n" \
> -			--vhead "static const G at Type@Value _ at enum_name@_values[] = {" \
> -			--vprod "  { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
> -			--vtail "  { 0, NULL, NULL }\n};\n\n" \
> -			--vtail "GType\n at enum_name@_get_type (void)\n{\n" \
> -			--vtail "  static GType type = 0;\n" \
> -			--vtail "  static volatile gsize type_volatile = 0;\n\n" \
> -			--vtail "  if (g_once_init_enter(&type_volatile)) {\n" \
> -			--vtail "    type = g_ at type@_register_static (\"@EnumName@\",
> _ at enum_name@_values);\n" \
> -			--vtail "    g_once_init_leave(&type_volatile, type);\n" \
> -			--vtail "  }\n\n" \
> -			--vtail "  return type;\n}\n\n" \
> -		$^ > $@
> -
> -spice-glib-enums.h: spice-channel.h channel-inputs.h spice-session.h
> -	$(AM_V_GEN)glib-mkenums --fhead "#ifndef SPICE_GLIB_ENUMS_H\n" \
> -			--fhead "#define SPICE_GLIB_ENUMS_H\n\n" \
> -			--fhead "G_BEGIN_DECLS\n\n" \
> -			--ftail "G_END_DECLS\n\n" \
> -			--ftail "#endif /* SPICE_CHANNEL_ENUMS_H */\n" \
> -			--eprod "#define SPICE_TYPE_ at ENUMSHORT@ @enum_name at _get_type()\n" \
> -			--eprod "GType @enum_name at _get_type (void);\n" \
> -		$^ >  $@
> -
> -spice-widget-enums.c: spice-widget.h
> -	$(AM_V_GEN)glib-mkenums --fhead "#include \"config.h\"\n\n" \
> -			--fhead "#include <glib-object.h>\n" \
> -			--fhead "#include \"spice-widget-enums.h\"\n\n" \
> -			--fprod "\n#include \"spice-widget.h\"\n" \
> -			--vhead "static const G at Type@Value _ at enum_name@_values[] = {" \
> -			--vprod "  { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
> -			--vtail "  { 0, NULL, NULL }\n};\n\n" \
> -			--vtail "GType\n at enum_name@_get_type (void)\n{\n" \
> -			--vtail "  static GType type = 0;\n" \
> -			--vtail "  static volatile gsize type_volatile = 0;\n\n" \
> -			--vtail "  if (g_once_init_enter(&type_volatile)) {\n" \
> -			--vtail "    type = g_ at type@_register_static (\"@EnumName@\",
> _ at enum_name@_values);\n" \
> -			--vtail "    g_once_init_leave(&type_volatile, type);\n" \
> -			--vtail "  }\n\n" \
> -			--vtail "  return type;\n}\n\n" \
> -		$< > $@
> -
> -spice-widget-enums.h: spice-widget.h
> -	$(AM_V_GEN)glib-mkenums --fhead "#ifndef SPICE_WIDGET_ENUMS_H\n" \
> -			--fhead "#define SPICE_WIDGET_ENUMS_H\n\n" \
> -			--fhead "G_BEGIN_DECLS\n\n" \
> -			--ftail "G_END_DECLS\n\n" \
> -			--ftail "#endif /* SPICE_WIDGET_ENUMS_H */\n" \
> -			--eprod "#define SPICE_TYPE_ at ENUMSHORT@ @enum_name at _get_type()\n" \
> -			--eprod "GType @enum_name at _get_type (void);\n" \
> -		$< >  $@
> -
> -
> -vncdisplaykeymap.c: $(KEYMAPS)
> -
> -$(KEYMAPS): $(KEYMAP_GEN) keymaps.csv
> -
> -# Note despite being autogenerated these are not part of CLEANFILES, they
> -# are actually a part of EXTRA_DIST to avoid the need for perl(Text::CSV) by
> -# end users
> -vncdisplaykeymap_xorgevdev2xtkbd.c:
> -	$(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgevdev xtkbd > $@ || rm
> $@
> -
> -vncdisplaykeymap_xorgkbd2xtkbd.c:
> -	$(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgkbd xtkbd > $@ || rm $@
> -
> -vncdisplaykeymap_xorgxquartz2xtkbd.c:
> -	$(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgxquartz xtkbd > $@ || rm
> $@
> -
> -vncdisplaykeymap_xorgxwin2xtkbd.c:
> -	$(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgxwin xtkbd > $@ || rm $@
> -
> -vncdisplaykeymap_osx2xtkbd.c:
> -	$(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv osx xtkbd > $@ || rm $@
> -
> -vncdisplaykeymap_win322xtkbd.c:
> -	$(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv win32 xtkbd > $@ || rm $@
> -
> -vncdisplaykeymap_x112xtkbd.c:
> -	$(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv x11 xtkbd > $@ || rm $@
> -
> -if WITH_PYTHON
> -pyexec_LTLIBRARIES = SpiceClientGtk.la
> -
> -# workaround for broken parallel install support in automake with
> LTLIBRARIES
> -# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=7328
> -install_pyexecLTLIBRARIES = install-pyexecLTLIBRARIES
> -$(install_pyexecLTLIBRARIES): install-libLTLIBRARIES
> -
> -SpiceClientGtk_la_LIBADD = libspice-client-gtk-2.0.la
> libspice-client-glib-2.0.la $(PYGTK_LIBS)
> -SpiceClientGtk_la_CFLAGS = $(GTK_CFLAGS) $(PYTHON_INCLUDES) $(PYGTK_CFLAGS)
> $(WARN_PYFLAGS)
> -SpiceClientGtk_la_LDFLAGS = -module -avoid-version -fPIC
> -SpiceClientGtk_la_SOURCES = spice-client-gtk-module.c
> -nodist_SpiceClientGtk_la_SOURCES = spice-client-gtk-module.defs.c
> -
> -CODEGENDIR = `pkg-config --variable=codegendir pygtk-2.0`
> -DEFSDIR = `pkg-config --variable=defsdir pygtk-2.0`
> -
> -spice-client-gtk.defs: $(libspice_client_gtkinclude_HEADERS)
> $(nodist_libspice_client_gtkinclude_HEADERS)
> $(libspice_client_glibinclude_HEADERS)
> $(nodist_libspice_client_glibinclude_HEADERS)
> -	$(AM_V_GEN)$(PYTHON) $(CODEGENDIR)/h2def.py \
> -		-f $(srcdir)/spice-client-gtk-manual.defs \
> -		$^ > $@
> -
> -spice-client-gtk-module.defs.c: spice-client-gtk.override
> spice-client-gtk.defs spice-client-gtk-manual.defs
> -	@cat spice-client-gtk.defs $(srcdir)/spice-client-gtk-manual.defs >
> tmp.defs
> -	$(AM_V_GEN)pygobject-codegen-2.0 --prefix spice \
> -			  --register $(DEFSDIR)/gdk-types.defs \
> -			  --register $(DEFSDIR)/gtk-types.defs \
> -			  --override $(srcdir)/spice-client-gtk.override \
> -			  tmp.defs > $@
> -	@rm tmp.defs
> -
> -CLEANFILES += spice-client-gtk-module.defs.c spice-client-gtk.defs
> -endif
> -
> --include $(INTROSPECTION_MAKEFILE)
> -
> -if G_IR_SCANNER_SYMBOL_PREFIX
> -PREFIX_ARGS = --symbol-prefix=spice --identifier-prefix=Spice
> -else
> -PREFIX_ARGS = --strip-prefix=Spice
> -endif
> -
> -INTROSPECTION_GIRS =
> -INTROSPECTION_SCANNER_ARGS = --warn-all --accept-unprefixed
> --add-include-path=$(builddir) $(PREFIX_ARGS)
> -INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir)
> -
> -if HAVE_INTROSPECTION
> -glib_introspection_files =				\
> -	$(libspice_client_glibinclude_HEADERS)		\
> -	$(nodist_libspice_client_glibinclude_HEADERS)	\
> -	spice-audio.c					\
> -	spice-client.c					\
> -	spice-session.c					\
> -	spice-channel.c					\
> -	spice-glib-enums.c				\
> -	spice-option.c					\
> -	spice-util.c					\
> -	channel-webdav.c				\
> -	channel-cursor.c				\
> -	channel-display.c				\
> -	channel-inputs.c				\
> -	channel-main.c					\
> -	channel-playback.c				\
> -	channel-port.c					\
> -	channel-record.c				\
> -	channel-smartcard.c				\
> -	channel-usbredir.c				\
> -	smartcard-manager.c				\
> -	usb-device-manager.c				\
> -	$(NULL)
> -
> -gtk_introspection_files =				\
> -	$(libspice_client_gtkinclude_HEADERS)		\
> -	$(nodist_libspice_client_gtkinclude_HEADERS)	\
> -	spice-gtk-session.c				\
> -	spice-widget.c					\
> -	spice-grabsequence.c				\
> -	usb-device-widget.c				\
> -	$(NULL)
> -
> -SpiceClientGLib-2.0.gir: libspice-client-glib-2.0.la
> -SpiceClientGLib_2_0_gir_INCLUDES = GObject-2.0 Gio-2.0
> -SpiceClientGLib_2_0_gir_CFLAGS = $(SPICE_COMMON_CPPFLAGS)
> -SpiceClientGLib_2_0_gir_LIBS = libspice-client-glib-2.0.la
> -SpiceClientGLib_2_0_gir_FILES = $(glib_introspection_files)
> -SpiceClientGLib_2_0_gir_EXPORT_PACKAGES = spice-client-glib-2.0
> -SpiceClientGLib_2_0_gir_SCANNERFLAGS = --c-include="spice-client.h"
> -INTROSPECTION_GIRS += SpiceClientGLib-2.0.gir
> -
> -if WITH_GTK
> -if HAVE_GTK_2
> -SpiceClientGtk-2.0.gir: libspice-client-gtk-2.0.la SpiceClientGLib-2.0.gir
> -SpiceClientGtk_2_0_gir_INCLUDES = GObject-2.0 Gtk-2.0 SpiceClientGLib-2.0
> -SpiceClientGtk_2_0_gir_CFLAGS = $(SPICE_COMMON_CPPFLAGS)
> -SpiceClientGtk_2_0_gir_LIBS = libspice-client-gtk-2.0.la
> libspice-client-glib-2.0.la
> -SpiceClientGtk_2_0_gir_FILES = $(gtk_introspection_files)
> -SpiceClientGtk_2_0_gir_EXPORT_PACKAGES = spice-client-gtk-2.0
> -SpiceClientGtk_2_0_gir_SCANNERFLAGS = --c-include="spice-widget.h"
> -else
> -SpiceClientGtk-3.0.gir: libspice-client-gtk-3.0.la SpiceClientGLib-2.0.gir
> -SpiceClientGtk_3_0_gir_INCLUDES = GObject-2.0 Gtk-3.0 SpiceClientGLib-2.0
> -SpiceClientGtk_3_0_gir_CFLAGS = $(SPICE_COMMON_CPPFLAGS)
> -SpiceClientGtk_3_0_gir_LIBS = libspice-client-gtk-3.0.la
> libspice-client-glib-2.0.la
> -SpiceClientGtk_3_0_gir_FILES = $(gtk_introspection_files)
> -SpiceClientGtk_3_0_gir_EXPORT_PACKAGES = spice-client-gtk-3.0
> -SpiceClientGtk_3_0_gir_SCANNERFLAGS = --c-include="spice-widget.h"
> -endif
> -INTROSPECTION_GIRS += SpiceClientGtk-$(SPICE_GTK_API_VERSION).gir
> -endif
> -
> -girdir = $(datadir)/gir-1.0
> -gir_DATA = $(INTROSPECTION_GIRS)
> -
> -typelibsdir = $(libdir)/girepository-1.0
> -typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
> -
> -CLEANFILES += $(gir_DATA) $(typelibs_DATA)
> -endif
> -
> -update-map-file: $(libspice_client_gtkinclude_HEADERS)
> $(nodist_libspice_client_gtkinclude_HEADERS)
> $(libspice_client_glibinclude_HEADERS)
> $(nodist_libspice_client_glibinclude_HEADERS)
> -	( echo "SPICEGTK_1 {" ; \
> -	  echo "global:" ; \
> -	  ctags -f - -I G_GNUC_CONST --c-kinds=p $^ | awk '/^spice_/ { print $$1
> ";" }' | sort ; \
> -	  echo "local:" ;  \
> -	  echo "*;" ; \
> -	  echo "};" ) > $(srcdir)/map-file
> -
> -update-glib-sym-file: $(libspice_client_glibinclude_HEADERS)
> $(nodist_libspice_client_glibinclude_HEADERS)
> -	( ctags -f - -I G_GNUC_CONST --c-kinds=p $^ | awk '/^spice_/ { print $$1 }'
> | sort ; \
> -	) > $(srcdir)/spice-glib-sym-file
> -
> -update-gtk-sym-file: $(libspice_client_gtkinclude_HEADERS)
> $(nodist_libspice_client_gtkinclude_HEADERS)
> -	( ctags -f - -I G_GNUC_CONST --c-kinds=p $^ | awk '/^spice_/ { print $$1 }'
> | sort ; \
> -	) > $(srcdir)/spice-gtk-sym-file
> -
> -update-symbol-files: update-map-file update-glib-sym-file
> update-gtk-sym-file
> -
> --include $(top_srcdir)/git.mk
> diff --git a/gtk/bio-gio.c b/gtk/bio-gio.c
> deleted file mode 100644
> index 108ac1a..0000000
> --- a/gtk/bio-gio.c
> +++ /dev/null
> @@ -1,114 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2012 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#include "config.h"
> -
> -#include <string.h>
> -#include <glib.h>
> -
> -#include "spice-util.h"
> -#include "bio-gio.h"
> -
> -typedef struct bio_gsocket_method {
> -    BIO_METHOD method;
> -    GIOStream *stream;
> -} bio_gsocket_method;
> -
> -#define BIO_GET_GSOCKET(bio)  (((bio_gsocket_method*)bio->method)->gsocket)
> -#define BIO_GET_ISTREAM(bio)
> (g_io_stream_get_input_stream(((bio_gsocket_method*)bio->method)->stream))
> -#define BIO_GET_OSTREAM(bio)
> (g_io_stream_get_output_stream(((bio_gsocket_method*)bio->method)->stream))
> -
> -static int bio_gio_write(BIO *bio, const char *in, int inl)
> -{
> -    gssize ret;
> -    GError *error = NULL;
> -
> -    ret =
> g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(BIO_GET_OSTREAM(bio)),
> -                                                     in, inl, NULL, &error);
> -    BIO_clear_retry_flags(bio);
> -
> -    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
> -        BIO_set_retry_write(bio);
> -    if (error != NULL) {
> -        g_warning("%s", error->message);
> -        g_clear_error(&error);
> -    }
> -
> -    return ret;
> -}
> -
> -static int bio_gio_read(BIO *bio, char *out, int outl)
> -{
> -    gssize ret;
> -    GError *error = NULL;
> -
> -    ret =
> g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(BIO_GET_ISTREAM(bio)),
> -                                                   out, outl, NULL, &error);
> -    BIO_clear_retry_flags(bio);
> -
> -    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
> -        BIO_set_retry_read(bio);
> -    else if (error != NULL)
> -        g_warning("%s", error->message);
> -
> -    g_clear_error(&error);
> -
> -    return ret;
> -}
> -
> -static int bio_gio_destroy(BIO *bio)
> -{
> -    if (bio == NULL || bio->method == NULL)
> -        return 0;
> -
> -    SPICE_DEBUG("bio gsocket destroy");
> -    g_free(bio->method);
> -    bio->method = NULL;;
> -
> -    return 1;
> -}
> -
> -static int bio_gio_puts(BIO *bio, const char *str)
> -{
> -    int n, ret;
> -
> -    n = strlen(str);
> -    ret = bio_gio_write(bio, str, n);
> -
> -    return ret;
> -}
> -
> -G_GNUC_INTERNAL
> -BIO* bio_new_giostream(GIOStream *stream)
> -{
> -    // TODO: make an actual new BIO type, or just switch to GTls already...
> -    BIO *bio = BIO_new_socket(-1, BIO_NOCLOSE);
> -
> -    bio_gsocket_method *bio_method = g_new(bio_gsocket_method, 1);
> -    bio_method->method = *bio->method;
> -    bio_method->stream = stream;
> -
> -    bio->method->destroy(bio);
> -    bio->method = (BIO_METHOD*)bio_method;
> -
> -    bio->method->bwrite = bio_gio_write;
> -    bio->method->bread = bio_gio_read;
> -    bio->method->bputs = bio_gio_puts;
> -    bio->method->destroy = bio_gio_destroy;
> -
> -    return bio;
> -}
> diff --git a/gtk/bio-gio.h b/gtk/bio-gio.h
> deleted file mode 100644
> index 31fd369..0000000
> --- a/gtk/bio-gio.h
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2012 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#ifndef BIO_GIO_H_
> -# define BIO_GIO_H_
> -
> -#include <openssl/bio.h>
> -#include <gio/gio.h>
> -
> -G_BEGIN_DECLS
> -
> -BIO* bio_new_giostream(GIOStream *stream);
> -
> -G_END_DECLS
> -
> -#endif /* !BIO_GIO_H_ */
> diff --git a/gtk/channel-base.c b/gtk/channel-base.c
> deleted file mode 100644
> index 77d339c..0000000
> --- a/gtk/channel-base.c
> +++ /dev/null
> @@ -1,284 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2010 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#include "config.h"
> -
> -#include "spice-client.h"
> -#include "spice-common.h"
> -
> -#include "spice-session-priv.h"
> -#include "spice-channel-priv.h"
> -
> -/* coroutine context */
> -G_GNUC_INTERNAL
> -void spice_channel_handle_set_ack(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceChannelPrivate *c = channel->priv;
> -    SpiceMsgSetAck* ack = spice_msg_in_parsed(in);
> -    SpiceMsgOut *out = spice_msg_out_new(channel, SPICE_MSGC_ACK_SYNC);
> -    SpiceMsgcAckSync sync = {
> -        .generation = ack->generation,
> -    };
> -
> -    c->message_ack_window = c->message_ack_count = ack->window;
> -    c->marshallers->msgc_ack_sync(out->marshaller, &sync);
> -    spice_msg_out_send_internal(out);
> -}
> -
> -/* coroutine context */
> -G_GNUC_INTERNAL
> -void spice_channel_handle_ping(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceChannelPrivate *c = channel->priv;
> -    SpiceMsgPing *ping = spice_msg_in_parsed(in);
> -    SpiceMsgOut *pong = spice_msg_out_new(channel, SPICE_MSGC_PONG);
> -
> -    c->marshallers->msgc_pong(pong->marshaller, ping);
> -    spice_msg_out_send_internal(pong);
> -}
> -
> -/* coroutine context */
> -G_GNUC_INTERNAL
> -void spice_channel_handle_notify(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    static const char* severity_strings[] = {"info", "warn", "error"};
> -    static const char* visibility_strings[] = {"!", "!!", "!!!"};
> -
> -    SpiceMsgNotify *notify = spice_msg_in_parsed(in);
> -    const char *severity   = "?";
> -    const char *visibility = "?";
> -    const char *message_str = NULL;
> -
> -    if (notify->severity <= SPICE_NOTIFY_SEVERITY_ERROR) {
> -        severity = severity_strings[notify->severity];
> -    }
> -    if (notify->visibilty <= SPICE_NOTIFY_VISIBILITY_HIGH) {
> -        visibility = visibility_strings[notify->visibilty];
> -    }
> -
> -    if (notify->message_len &&
> -        notify->message_len <= in->dpos - sizeof(*notify)) {
> -        message_str = (char*)notify->message;
> -    }
> -
> -    CHANNEL_DEBUG(channel, "%s -- %s%s #%u%s%.*s", __FUNCTION__,
> -            severity, visibility, notify->what,
> -            message_str ? ": " : "", notify->message_len,
> -            message_str ? message_str : "");
> -}
> -
> -/* coroutine context */
> -G_GNUC_INTERNAL
> -void spice_channel_handle_disconnect(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgDisconnect *disconnect = spice_msg_in_parsed(in);
> -
> -    CHANNEL_DEBUG(channel, "%s: ts: %" PRIu64", reason: %u", __FUNCTION__,
> -                  disconnect->time_stamp, disconnect->reason);
> -}
> -
> -typedef struct WaitForChannelData
> -{
> -    SpiceWaitForChannel *wait;
> -    SpiceChannel *channel;
> -} WaitForChannelData;
> -
> -/* coroutine and main context */
> -static gboolean wait_for_channel(gpointer data)
> -{
> -    WaitForChannelData *wfc = data;
> -    SpiceChannelPrivate *c = wfc->channel->priv;
> -    SpiceChannel *wait_channel;
> -
> -    wait_channel = spice_session_lookup_channel(c->session,
> wfc->wait->channel_id, wfc->wait->channel_type);
> -    g_return_val_if_fail(wait_channel != NULL, TRUE);
> -
> -    if (wait_channel->priv->last_message_serial >=
> wfc->wait->message_serial)
> -        return TRUE;
> -
> -    return FALSE;
> -}
> -
> -/* coroutine context */
> -G_GNUC_INTERNAL
> -void spice_channel_handle_wait_for_channels(SpiceChannel *channel,
> SpiceMsgIn *in)
> -{
> -    SpiceChannelPrivate *c = channel->priv;
> -    SpiceMsgWaitForChannels *wfc = spice_msg_in_parsed(in);
> -    int i;
> -
> -    for (i = 0; i < wfc->wait_count; ++i) {
> -        WaitForChannelData data = {
> -            .wait = wfc->wait_list + i,
> -            .channel = channel
> -        };
> -
> -        CHANNEL_DEBUG(channel, "waiting for serial %" PRIu64 " (%d/%d)",
> data.wait->message_serial, i + 1, wfc->wait_count);
> -        if (g_coroutine_condition_wait(&c->coroutine, wait_for_channel,
> &data))
> -            CHANNEL_DEBUG(channel, "waiting for serial %"  PRIu64 ", done",
> data.wait->message_serial);
> -        else
> -            CHANNEL_DEBUG(channel, "waiting for serial %" PRIu64 ",
> cancelled", data.wait->message_serial);
> -    }
> -}
> -
> -static void
> -get_msg_handler(SpiceChannel *channel, SpiceMsgIn *in, gpointer data)
> -{
> -    SpiceMsgIn **msg = data;
> -
> -    g_return_if_fail(msg != NULL);
> -    g_return_if_fail(*msg == NULL);
> -
> -    spice_msg_in_ref(in);
> -    *msg = in;
> -}
> -
> -/* coroutine context */
> -G_GNUC_INTERNAL
> -void spice_channel_handle_migrate(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgOut *out;
> -    SpiceMsgIn *data = NULL;
> -    SpiceMsgMigrate *mig = spice_msg_in_parsed(in);
> -    SpiceChannelPrivate *c = channel->priv;
> -
> -    CHANNEL_DEBUG(channel, "%s: flags %u", __FUNCTION__, mig->flags);
> -    if (mig->flags & SPICE_MIGRATE_NEED_FLUSH) {
> -        /* if peer version > 1: pushing the mark msg before all other
> messgages and sending it,
> -         * and only it */
> -        if (c->peer_hdr.major_version == 1) {
> -            /* iterate_write is blocking and flushing all pending write */
> -            SPICE_CHANNEL_GET_CLASS(channel)->iterate_write(channel);
> -        }
> -        out = spice_msg_out_new(SPICE_CHANNEL(channel),
> SPICE_MSGC_MIGRATE_FLUSH_MARK);
> -        spice_msg_out_send_internal(out);
> -    }
> -    if (mig->flags & SPICE_MIGRATE_NEED_DATA_TRANSFER) {
> -        spice_channel_recv_msg(channel, get_msg_handler, &data);
> -        if (!data) {
> -            g_critical("expected SPICE_MSG_MIGRATE_DATA, got empty
> message");
> -            goto end;
> -        } else if (spice_header_get_msg_type(data->header,
> c->use_mini_header) !=
> -                   SPICE_MSG_MIGRATE_DATA) {
> -            g_critical("expected SPICE_MSG_MIGRATE_DATA, got %d",
> -                      spice_header_get_msg_type(data->header,
> c->use_mini_header));
> -            goto end;
> -        }
> -    }
> -
> -    /* swapping channels sockets */
> -    spice_session_channel_migrate(c->session, channel);
> -
> -    /* pushing the MIGRATE_DATA before all other pending messages */
> -    if ((mig->flags & SPICE_MIGRATE_NEED_DATA_TRANSFER) && (data != NULL)) {
> -        out = spice_msg_out_new(SPICE_CHANNEL(channel),
> SPICE_MSGC_MIGRATE_DATA);
> -        spice_marshaller_add(out->marshaller, data->data,
> -                             spice_header_get_msg_size(data->header,
> c->use_mini_header));
> -        spice_msg_out_send_internal(out);
> -    }
> -
> -end:
> -    if (data)
> -        spice_msg_in_unref(data);
> -}
> -
> -
> -static void set_handlers(SpiceChannelClass *klass,
> -                         const spice_msg_handler* handlers, const int n)
> -{
> -    int i;
> -
> -    g_array_set_size(klass->handlers, MAX(klass->handlers->len, n));
> -    for (i = 0; i < n; i++) {
> -        if (handlers[i])
> -            g_array_index(klass->handlers, spice_msg_handler, i) =
> handlers[i];
> -    }
> -}
> -
> -static void spice_channel_add_base_handlers(SpiceChannelClass *klass)
> -{
> -    static const spice_msg_handler handlers[] = {
> -        [ SPICE_MSG_SET_ACK ]                  =
> spice_channel_handle_set_ack,
> -        [ SPICE_MSG_PING ]                     = spice_channel_handle_ping,
> -        [ SPICE_MSG_NOTIFY ]                   =
> spice_channel_handle_notify,
> -        [ SPICE_MSG_DISCONNECTING ]            =
> spice_channel_handle_disconnect,
> -        [ SPICE_MSG_WAIT_FOR_CHANNELS ]        =
> spice_channel_handle_wait_for_channels,
> -        [ SPICE_MSG_MIGRATE ]                  =
> spice_channel_handle_migrate,
> -    };
> -
> -    set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
> -}
> -
> -G_GNUC_INTERNAL
> -void spice_channel_set_handlers(SpiceChannelClass *klass,
> -                                const spice_msg_handler* handlers, const int
> n)
> -{
> -    /* FIXME: use class private (requires glib 2.24) */
> -    g_return_if_fail(klass->handlers == NULL);
> -    klass->handlers = g_array_sized_new(FALSE, TRUE,
> sizeof(spice_msg_handler), n);
> -
> -    spice_channel_add_base_handlers(klass);
> -    set_handlers(klass, handlers, n);
> -}
> -
> -static void
> -vmc_write_free_cb(uint8_t *data, void *user_data)
> -{
> -    GSimpleAsyncResult *result = user_data;
> -
> -    g_simple_async_result_complete_in_idle(result);
> -    g_object_unref(result);
> -}
> -
> -G_GNUC_INTERNAL
> -void spice_vmc_write_async(SpiceChannel *self,
> -                           const void *buffer, gsize count,
> -                           GCancellable *cancellable,
> -                           GAsyncReadyCallback callback,
> -                           gpointer user_data)
> -{
> -    SpiceMsgOut *msg;
> -    GSimpleAsyncResult *simple;
> -
> -    simple = g_simple_async_result_new(G_OBJECT(self), callback, user_data,
> -                                       spice_port_write_async);
> -    g_simple_async_result_set_op_res_gssize(simple, count);
> -
> -    msg = spice_msg_out_new(SPICE_CHANNEL(self), SPICE_MSGC_SPICEVMC_DATA);
> -    spice_marshaller_add_ref_full(msg->marshaller, (uint8_t*)buffer, count,
> -                                  vmc_write_free_cb, simple);
> -    spice_msg_out_send(msg);
> -}
> -
> -G_GNUC_INTERNAL
> -gssize spice_vmc_write_finish(SpiceChannel *self,
> -                              GAsyncResult *result, GError **error)
> -{
> -    GSimpleAsyncResult *simple;
> -
> -    g_return_val_if_fail(result != NULL, -1);
> -
> -    simple = (GSimpleAsyncResult *)result;
> -
> -    if (g_simple_async_result_propagate_error(simple, error))
> -        return -1;
> -
> -    g_return_val_if_fail(g_simple_async_result_is_valid(result,
> G_OBJECT(self),
> -
> spice_port_write_async),
> -1);
> -
> -    return g_simple_async_result_get_op_res_gssize(simple);
> -}
> diff --git a/gtk/channel-cursor.c b/gtk/channel-cursor.c
> deleted file mode 100644
> index e6514a2..0000000
> --- a/gtk/channel-cursor.c
> +++ /dev/null
> @@ -1,529 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2010 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#include "config.h"
> -
> -#include "glib-compat.h"
> -#include "spice-client.h"
> -#include "spice-common.h"
> -
> -#include "spice-channel-priv.h"
> -#include "spice-channel-cache.h"
> -#include "spice-marshal.h"
> -
> -/**
> - * SECTION:channel-cursor
> - * @short_description: update cursor shape and position
> - * @title: Cursor Channel
> - * @section_id:
> - * @see_also: #SpiceChannel, and the GTK widget #SpiceDisplay
> - * @stability: Stable
> - * @include: channel-cursor.h
> - *
> - * The Spice protocol defines a set of messages for controlling cursor
> - * shape and position on the remote display area. The cursor changes
> - * that should be reflected on the display are notified by
> - * signals. See for example #SpiceCursorChannel::cursor-set
> - * #SpiceCursorChannel::cursor-move signals.
> - */
> -
> -#define SPICE_CURSOR_CHANNEL_GET_PRIVATE(obj)
> \
> -    (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_CURSOR_CHANNEL,
> SpiceCursorChannelPrivate))
> -
> -typedef struct display_cursor display_cursor;
> -
> -struct display_cursor {
> -    SpiceCursorHeader           hdr;
> -    gboolean                    default_cursor;
> -    int                         refcount;
> -    guint32                     data[];
> -};
> -
> -struct _SpiceCursorChannelPrivate {
> -    display_cache               *cursors;
> -    gboolean                    init_done;
> -};
> -
> -enum {
> -    SPICE_CURSOR_SET,
> -    SPICE_CURSOR_MOVE,
> -    SPICE_CURSOR_HIDE,
> -    SPICE_CURSOR_RESET,
> -
> -    SPICE_CURSOR_LAST_SIGNAL,
> -};
> -
> -static guint signals[SPICE_CURSOR_LAST_SIGNAL];
> -
> -static display_cursor * display_cursor_ref(display_cursor *cursor);
> -static void display_cursor_unref(display_cursor *cursor);
> -static void channel_set_handlers(SpiceChannelClass *klass);
> -
> -G_DEFINE_TYPE(SpiceCursorChannel, spice_cursor_channel, SPICE_TYPE_CHANNEL)
> -
> -/* ------------------------------------------------------------------ */
> -
> -static void spice_cursor_channel_init(SpiceCursorChannel *channel)
> -{
> -    SpiceCursorChannelPrivate *c;
> -
> -    c = channel->priv = SPICE_CURSOR_CHANNEL_GET_PRIVATE(channel);
> -
> -    c->cursors = cache_new((GDestroyNotify)display_cursor_unref);
> -}
> -
> -static void spice_cursor_channel_finalize(GObject *obj)
> -{
> -    SpiceCursorChannel *channel = SPICE_CURSOR_CHANNEL(obj);
> -    SpiceCursorChannelPrivate *c = channel->priv;
> -
> -    g_clear_pointer(&c->cursors, cache_unref);
> -
> -    if (G_OBJECT_CLASS(spice_cursor_channel_parent_class)->finalize)
> -        G_OBJECT_CLASS(spice_cursor_channel_parent_class)->finalize(obj);
> -}
> -
> -/* coroutine context */
> -static void spice_cursor_channel_reset(SpiceChannel *channel, gboolean
> migrating)
> -{
> -    SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
> -
> -    cache_clear(c->cursors);
> -    c->init_done = FALSE;
> -
> -
> SPICE_CHANNEL_CLASS(spice_cursor_channel_parent_class)->channel_reset(channel,
> migrating);
> -}
> -
> -static void spice_cursor_channel_class_init(SpiceCursorChannelClass *klass)
> -{
> -    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
> -    SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
> -
> -    gobject_class->finalize     = spice_cursor_channel_finalize;
> -    channel_class->channel_reset = spice_cursor_channel_reset;
> -
> -    /**
> -     * SpiceCursorChannel::cursor-set:
> -     * @cursor: the #SpiceCursorChannel that emitted the signal
> -     * @width: width of the shape
> -     * @height: height of the shape
> -     * @hot_x: horizontal offset of the 'hotspot' of the cursor
> -     * @hot_y: vertical offset of the 'hotspot' of the cursor
> -     * @rgba: 32bits shape data, or %NULL if default cursor. It might
> -     * be freed after the signal is emitted, so make sure to copy it
> -     * if you need it later!
> -     *
> -     * The #SpiceCursorChannel::cursor-set signal is emitted to modify
> -     * cursor aspect and position on the display area.
> -     **/
> -    signals[SPICE_CURSOR_SET] =
> -        g_signal_new("cursor-set",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceCursorChannelClass, cursor_set),
> -                     NULL, NULL,
> -                     g_cclosure_user_marshal_VOID__INT_INT_INT_INT_POINTER,
> -                     G_TYPE_NONE,
> -                     5,
> -                     G_TYPE_INT, G_TYPE_INT,
> -                     G_TYPE_INT, G_TYPE_INT,
> -                     G_TYPE_POINTER);
> -
> -    /**
> -     * SpiceCursorChannel::cursor-move:
> -     * @cursor: the #SpiceCursorChannel that emitted the signal
> -     * @x: x position
> -     * @y: y position
> -     *
> -     * The #SpiceCursorChannel::cursor-move signal is emitted to update
> -     * the cursor position on the display area.
> -     **/
> -    signals[SPICE_CURSOR_MOVE] =
> -        g_signal_new("cursor-move",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceCursorChannelClass, cursor_move),
> -                     NULL, NULL,
> -                     g_cclosure_user_marshal_VOID__INT_INT,
> -                     G_TYPE_NONE,
> -                     2,
> -                     G_TYPE_INT, G_TYPE_INT);
> -
> -    /**
> -     * SpiceCursorChannel::cursor-hide:
> -     * @cursor: the #SpiceCursorChannel that emitted the signal
> -     *
> -     * The #SpiceCursorChannel::cursor-hide signal is emitted to hide
> -     * the cursor/pointer on the display area.
> -     **/
> -    signals[SPICE_CURSOR_HIDE] =
> -        g_signal_new("cursor-hide",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceCursorChannelClass, cursor_hide),
> -                     NULL, NULL,
> -                     g_cclosure_marshal_VOID__VOID,
> -                     G_TYPE_NONE,
> -                     0);
> -
> -    /**
> -     * SpiceCursorChannel::cursor-reset:
> -     * @cursor: the #SpiceCursorChannel that emitted the signal
> -     *
> -     * The #SpiceCursorChannel::cursor-reset signal is emitted to
> -     * reset the cursor to its default context.
> -     **/
> -    signals[SPICE_CURSOR_RESET] =
> -        g_signal_new("cursor-reset",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceCursorChannelClass, cursor_reset),
> -                     NULL, NULL,
> -                     g_cclosure_marshal_VOID__VOID,
> -                     G_TYPE_NONE,
> -                     0);
> -
> -    g_type_class_add_private(klass, sizeof(SpiceCursorChannelPrivate));
> -    channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
> -}
> -
> -/* ------------------------------------------------------------------ */
> -
> -#ifdef DEBUG_CURSOR
> -static void print_cursor(display_cursor *cursor, const guint8 *data)
> -{
> -    int x, y, bpl;
> -    const guint8 *xor, *and;
> -
> -    bpl = (cursor->hdr.width + 7) / 8;
> -    and = data;
> -    xor = and + bpl * cursor->hdr.height;
> -
> -    printf("data (%d x %d):\n", cursor->hdr.width, cursor->hdr.height);
> -    for (y = 0 ; y < cursor->hdr.height; ++y) {
> -        for (x = 0 ; x < cursor->hdr.width / 8; x++) {
> -            printf("%02X", and[x]);
> -        }
> -        and += bpl;
> -        printf("\n");
> -    }
> -    printf("xor:\n");
> -    for (y = 0 ; y < cursor->hdr.height; ++y) {
> -        for (x = 0 ; x < cursor->hdr.width / 8; ++x) {
> -            printf("%02X", xor[x]);
> -        }
> -        xor += bpl;
> -        printf("\n");
> -    }
> -}
> -#endif
> -
> -static void mono_cursor(display_cursor *cursor, const guint8 *data)
> -{
> -    int bpl = (cursor->hdr.width + 7) / 8;
> -    const guint8 *xor, *and;
> -    guint8 *dest;
> -    dest = (uint8_t *)cursor->data;
> -
> -#ifdef DEBUG_CURSOR
> -    print_cursor(cursor, data);
> -#endif
> -    and = data;
> -    xor = and + bpl * cursor->hdr.height;
> -    spice_mono_edge_highlight(cursor->hdr.width, cursor->hdr.height,
> -                              and, xor, dest);
> -}
> -
> -static guint8 get_pix_mask(const guint8 *data, gint offset, gint pix_index)
> -{
> -    return data[offset + (pix_index >> 3)] & (0x80 >> (pix_index % 8));
> -}
> -
> -static guint32 get_pix_hack(gint pix_index, gint width)
> -{
> -    return (((pix_index % width) ^ (pix_index / width)) & 1) ? 0xc0303030 :
> 0x30505050;
> -}
> -
> -static display_cursor * display_cursor_ref(display_cursor *cursor)
> -{
> -    g_return_val_if_fail(cursor != NULL, NULL);
> -    g_return_val_if_fail(cursor->refcount > 0, NULL);
> -
> -    cursor->refcount++;
> -    return cursor;
> -}
> -
> -static void display_cursor_unref(display_cursor *cursor)
> -{
> -    g_return_if_fail(cursor != NULL);
> -    g_return_if_fail(cursor->refcount > 0);
> -
> -    cursor->refcount--;
> -    if (cursor->refcount == 0)
> -        g_free(cursor);
> -}
> -
> -static const char *cursor_type_to_string(int type)
> -{
> -    switch (type) {
> -    case SPICE_CURSOR_TYPE_MONO:
> -        return "mono";
> -    case SPICE_CURSOR_TYPE_ALPHA:
> -        return "alpha";
> -    case SPICE_CURSOR_TYPE_COLOR32:
> -        return "color32";
> -    case SPICE_CURSOR_TYPE_COLOR16:
> -        return "color16";
> -    case SPICE_CURSOR_TYPE_COLOR4:
> -        return "color4";
> -    }
> -    return "unknown";
> -}
> -
> -static display_cursor *set_cursor(SpiceChannel *channel, SpiceCursor
> *scursor)
> -{
> -    SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
> -    SpiceCursorHeader *hdr = &scursor->header;
> -    display_cursor *cursor;
> -    size_t size;
> -    gint i, pix_mask, pix;
> -    const guint8* data;
> -    guint8 *rgba;
> -    guint8 val;
> -
> -    CHANNEL_DEBUG(channel, "%s: flags %d, size %d", __FUNCTION__,
> -                  scursor->flags, scursor->data_size);
> -
> -    if (scursor->flags & SPICE_CURSOR_FLAGS_NONE)
> -        return NULL;
> -
> -    CHANNEL_DEBUG(channel, "%s: type %s(%d), %" PRIx64 ", %dx%d",
> __FUNCTION__,
> -                  cursor_type_to_string(hdr->type), hdr->type, hdr->unique,
> -                  hdr->width, hdr->height);
> -
> -    if (scursor->flags & SPICE_CURSOR_FLAGS_FROM_CACHE) {
> -        cursor = cache_find(c->cursors, hdr->unique);
> -        g_return_val_if_fail(cursor != NULL, NULL);
> -        return display_cursor_ref(cursor);
> -    }
> -
> -    g_return_val_if_fail(scursor->data_size != 0, NULL);
> -
> -    size = 4u * hdr->width * hdr->height;
> -    cursor = g_malloc0(sizeof(*cursor) + size);
> -    cursor->hdr = *hdr;
> -    cursor->default_cursor = FALSE;
> -    cursor->refcount = 1;
> -    data = scursor->data;
> -
> -    switch (hdr->type) {
> -    case SPICE_CURSOR_TYPE_MONO:
> -        mono_cursor(cursor, data);
> -        break;
> -    case SPICE_CURSOR_TYPE_ALPHA:
> -        memcpy(cursor->data, data, size);
> -        break;
> -    case SPICE_CURSOR_TYPE_COLOR32:
> -        memcpy(cursor->data, data, size);
> -        for (i = 0; i < hdr->width * hdr->height; i++) {
> -            pix_mask = get_pix_mask(data, size, i);
> -            if (pix_mask && *((guint32*)data + i) == 0xffffff) {
> -                cursor->data[i] = get_pix_hack(i, hdr->width);
> -            } else {
> -                cursor->data[i] |= (pix_mask ? 0 : 0xff000000);
> -            }
> -        }
> -        break;
> -    case SPICE_CURSOR_TYPE_COLOR16:
> -        for (i = 0; i < hdr->width * hdr->height; i++) {
> -            pix_mask = get_pix_mask(data, size, i);
> -            pix = *((guint16*)data + i);
> -            if (pix_mask && pix == 0x7fff) {
> -                cursor->data[i] = get_pix_hack(i, hdr->width);
> -            } else {
> -                cursor->data[i] |= ((pix & 0x1f) << 3) | ((pix & 0x3e0) <<
> 6) |
> -                    ((pix & 0x7c00) << 9) | (pix_mask ? 0 : 0xff000000);
> -            }
> -        }
> -        break;
> -    case SPICE_CURSOR_TYPE_COLOR4:
> -        size = ((unsigned int)(SPICE_ALIGN(hdr->width, 2) / 2)) *
> hdr->height;
> -        for (i = 0; i < hdr->width * hdr->height; i++) {
> -            pix_mask = get_pix_mask(data, size + (sizeof(uint32_t) << 4),
> i);
> -            int idx = (i & 1) ? (data[i >> 1] & 0x0f) : ((data[i >> 1] &
> 0xf0) >> 4);
> -            pix = *((uint32_t*)(data + size) + idx);
> -            if (pix_mask && pix == 0xffffff) {
> -                cursor->data[i] = get_pix_hack(i, hdr->width);
> -            } else {
> -                cursor->data[i] = pix | (pix_mask ? 0 : 0xff000000);
> -            }
> -        }
> -
> -        break;
> -    default:
> -        g_warning("%s: unimplemented cursor type %d", __FUNCTION__,
> -                  hdr->type);
> -        cursor->default_cursor = TRUE;
> -        goto cache_add;
> -    }
> -
> -    rgba = (guint8*)cursor->data;
> -    for (i = 0; i < hdr->width * hdr->height; i++) {
> -        val = rgba[0];
> -        rgba[0] = rgba[2];
> -        rgba[2] = val;
> -        rgba += 4;
> -    }
> -
> -cache_add:
> -    if (scursor->flags & SPICE_CURSOR_FLAGS_CACHE_ME) {
> -        cache_add(c->cursors, hdr->unique, display_cursor_ref(cursor));
> -    }
> -
> -    return cursor;
> -}
> -
> -/* coroutine context */
> -static void emit_cursor_set(SpiceChannel *channel, display_cursor *cursor)
> -{
> -    g_return_if_fail(cursor != NULL);
> -    g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_SET], 0,
> -                            cursor->hdr.width, cursor->hdr.height,
> -                            cursor->hdr.hot_spot_x, cursor->hdr.hot_spot_y,
> -                            cursor->default_cursor ? NULL : cursor->data);
> -}
> -
> -/* coroutine context */
> -static void cursor_handle_init(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgCursorInit *init = spice_msg_in_parsed(in);
> -    SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
> -    display_cursor *cursor;
> -
> -    g_return_if_fail(c->init_done == FALSE);
> -
> -    cache_clear(c->cursors);
> -    cursor = set_cursor(channel, &init->cursor);
> -    c->init_done = TRUE;
> -    if (cursor)
> -        emit_cursor_set(channel, cursor);
> -    if (!init->visible || !cursor)
> -        g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_HIDE], 0);
> -    if (cursor)
> -        display_cursor_unref(cursor);
> -}
> -
> -/* coroutine context */
> -static void cursor_handle_reset(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
> -
> -    CHANNEL_DEBUG(channel, "%s, init_done: %d", __FUNCTION__, c->init_done);
> -
> -    cache_clear(c->cursors);
> -    g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_RESET], 0);
> -    c->init_done = FALSE;
> -}
> -
> -/* coroutine context */
> -static void cursor_handle_set(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgCursorSet *set = spice_msg_in_parsed(in);
> -    SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
> -    display_cursor *cursor;
> -
> -    g_return_if_fail(c->init_done == TRUE);
> -
> -    cursor = set_cursor(channel, &set->cursor);
> -    if (cursor)
> -        emit_cursor_set(channel, cursor);
> -    else
> -        g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_HIDE], 0);
> -
> -
> -    if (cursor)
> -        display_cursor_unref(cursor);
> -}
> -
> -/* coroutine context */
> -static void cursor_handle_move(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgCursorMove *move = spice_msg_in_parsed(in);
> -    SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
> -
> -    g_return_if_fail(c->init_done == TRUE);
> -
> -    g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_MOVE], 0,
> -                            move->position.x, move->position.y);
> -}
> -
> -/* coroutine context */
> -static void cursor_handle_hide(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -#ifdef EXTRA_CHECKS
> -    SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
> -
> -    g_return_if_fail(c->init_done == TRUE);
> -#endif
> -
> -    g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_HIDE], 0);
> -}
> -
> -/* coroutine context */
> -static void cursor_handle_trail(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
> -
> -    g_return_if_fail(c->init_done == TRUE);
> -
> -    g_warning("%s: TODO", __FUNCTION__);
> -}
> -
> -/* coroutine context */
> -static void cursor_handle_inval_one(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
> -    SpiceMsgDisplayInvalOne *zap = spice_msg_in_parsed(in);
> -
> -    g_return_if_fail(c->init_done == TRUE);
> -
> -    cache_remove(c->cursors, zap->id);
> -}
> -
> -/* coroutine context */
> -static void cursor_handle_inval_all(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
> -
> -    cache_clear(c->cursors);
> -}
> -
> -static void channel_set_handlers(SpiceChannelClass *klass)
> -{
> -    static const spice_msg_handler handlers[] = {
> -        [ SPICE_MSG_CURSOR_INIT ]              = cursor_handle_init,
> -        [ SPICE_MSG_CURSOR_RESET ]             = cursor_handle_reset,
> -        [ SPICE_MSG_CURSOR_SET ]               = cursor_handle_set,
> -        [ SPICE_MSG_CURSOR_MOVE ]              = cursor_handle_move,
> -        [ SPICE_MSG_CURSOR_HIDE ]              = cursor_handle_hide,
> -        [ SPICE_MSG_CURSOR_TRAIL ]             = cursor_handle_trail,
> -        [ SPICE_MSG_CURSOR_INVAL_ONE ]         = cursor_handle_inval_one,
> -        [ SPICE_MSG_CURSOR_INVAL_ALL ]         = cursor_handle_inval_all,
> -    };
> -
> -    spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
> -}
> diff --git a/gtk/channel-cursor.h b/gtk/channel-cursor.h
> deleted file mode 100644
> index 5b5ed47..0000000
> --- a/gtk/channel-cursor.h
> +++ /dev/null
> @@ -1,77 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2010 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#ifndef __SPICE_CLIENT_CURSOR_CHANNEL_H__
> -#define __SPICE_CLIENT_CURSOR_CHANNEL_H__
> -
> -#include "spice-client.h"
> -
> -G_BEGIN_DECLS
> -
> -#define SPICE_TYPE_CURSOR_CHANNEL
> (spice_cursor_channel_get_type())
> -#define SPICE_CURSOR_CHANNEL(obj)
> (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_CURSOR_CHANNEL,
> SpiceCursorChannel))
> -#define SPICE_CURSOR_CHANNEL_CLASS(klass)
> (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_CURSOR_CHANNEL,
> SpiceCursorChannelClass))
> -#define SPICE_IS_CURSOR_CHANNEL(obj)
> (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_CURSOR_CHANNEL))
> -#define SPICE_IS_CURSOR_CHANNEL_CLASS(klass)
> (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_CURSOR_CHANNEL))
> -#define SPICE_CURSOR_CHANNEL_GET_CLASS(obj)
> (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_CURSOR_CHANNEL,
> SpiceCursorChannelClass))
> -
> -typedef struct _SpiceCursorChannel SpiceCursorChannel;
> -typedef struct _SpiceCursorChannelClass SpiceCursorChannelClass;
> -typedef struct _SpiceCursorChannelPrivate SpiceCursorChannelPrivate;
> -
> -/**
> - * SpiceCursorChannel:
> - *
> - * The #SpiceCursorChannel struct is opaque and should not be accessed
> directly.
> - */
> -struct _SpiceCursorChannel {
> -    SpiceChannel parent;
> -
> -    /*< private >*/
> -    SpiceCursorChannelPrivate *priv;
> -    /* Do not add fields to this struct */
> -};
> -
> -/**
> - * SpiceCursorChannelClass:
> - * @parent_class: Parent class.
> - * @cursor_set: Signal class handler for the #SpiceCursorChannel::cursor-set
> signal.
> - * @cursor_move: Signal class handler for the
> #SpiceCursorChannel::cursor-move signal.
> - * @cursor_hide: Signal class handler for the
> #SpiceCursorChannel::cursor-hide signal.
> - * @cursor_reset: Signal class handler for the
> #SpiceCursorChannel::cursor-reset signal.
> - *
> - * Class structure for #SpiceCursorChannel.
> - */
> -struct _SpiceCursorChannelClass {
> -    SpiceChannelClass parent_class;
> -
> -    /* signals */
> -    void (*cursor_set)(SpiceCursorChannel *channel, gint width, gint height,
> -                       gint hot_x, gint hot_y, gpointer rgba);
> -    void (*cursor_move)(SpiceCursorChannel *channel, gint x, gint y);
> -    void (*cursor_hide)(SpiceCursorChannel *channel);
> -    void (*cursor_reset)(SpiceCursorChannel *channel);
> -
> -    /*< private >*/
> -    /* Do not add fields to this struct */
> -};
> -
> -GType spice_cursor_channel_get_type(void);
> -
> -G_END_DECLS
> -
> -#endif /* __SPICE_CLIENT_CURSOR_CHANNEL_H__ */
> diff --git a/gtk/channel-display-mjpeg.c b/gtk/channel-display-mjpeg.c
> deleted file mode 100644
> index 95d5b33..0000000
> --- a/gtk/channel-display-mjpeg.c
> +++ /dev/null
> @@ -1,156 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2010 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#include "config.h"
> -
> -#include "spice-client.h"
> -#include "spice-common.h"
> -#include "spice-channel-priv.h"
> -
> -#include "channel-display-priv.h"
> -
> -static void mjpeg_src_init(struct jpeg_decompress_struct *cinfo)
> -{
> -    display_stream *st = SPICE_CONTAINEROF(cinfo->src, display_stream,
> mjpeg_src);
> -    uint8_t *data;
> -
> -    cinfo->src->bytes_in_buffer = stream_get_current_frame(st, &data);
> -    cinfo->src->next_input_byte = data;
> -}
> -
> -static boolean mjpeg_src_fill(struct jpeg_decompress_struct *cinfo)
> -{
> -    g_critical("need more input data");
> -    return 0;
> -}
> -
> -static void mjpeg_src_skip(struct jpeg_decompress_struct *cinfo,
> -                           long num_bytes)
> -{
> -    cinfo->src->next_input_byte += num_bytes;
> -}
> -
> -static void mjpeg_src_term(struct jpeg_decompress_struct *cinfo)
> -{
> -    /* nothing */
> -}
> -
> -G_GNUC_INTERNAL
> -void stream_mjpeg_init(display_stream *st)
> -{
> -    st->mjpeg_cinfo.err = jpeg_std_error(&st->mjpeg_jerr);
> -    jpeg_create_decompress(&st->mjpeg_cinfo);
> -
> -    st->mjpeg_src.init_source         = mjpeg_src_init;
> -    st->mjpeg_src.fill_input_buffer   = mjpeg_src_fill;
> -    st->mjpeg_src.skip_input_data     = mjpeg_src_skip;
> -    st->mjpeg_src.resync_to_restart   = jpeg_resync_to_restart;
> -    st->mjpeg_src.term_source         = mjpeg_src_term;
> -    st->mjpeg_cinfo.src               = &st->mjpeg_src;
> -}
> -
> -G_GNUC_INTERNAL
> -void stream_mjpeg_data(display_stream *st)
> -{
> -    gboolean back_compat = st->channel->priv->peer_hdr.major_version == 1;
> -    int width;
> -    int height;
> -    uint8_t *dest;
> -    uint8_t *lines[4];
> -
> -    stream_get_dimensions(st, &width, &height);
> -    dest = g_malloc0(width * height * 4);
> -
> -    g_free(st->out_frame);
> -    st->out_frame = dest;
> -
> -    jpeg_read_header(&st->mjpeg_cinfo, 1);
> -#ifdef JCS_EXTENSIONS
> -    // requires jpeg-turbo
> -    if (back_compat)
> -        st->mjpeg_cinfo.out_color_space = JCS_EXT_RGBX;
> -    else
> -        st->mjpeg_cinfo.out_color_space = JCS_EXT_BGRX;
> -#else
> -#warning "You should consider building with libjpeg-turbo"
> -    st->mjpeg_cinfo.out_color_space = JCS_RGB;
> -#endif
> -
> -#ifndef SPICE_QUALITY
> -    st->mjpeg_cinfo.dct_method = JDCT_IFAST;
> -    st->mjpeg_cinfo.do_fancy_upsampling = FALSE;
> -    st->mjpeg_cinfo.do_block_smoothing = FALSE;
> -    st->mjpeg_cinfo.dither_mode = JDITHER_ORDERED;
> -#endif
> -    // TODO: in theory should check cinfo.output_height match with our
> height
> -    jpeg_start_decompress(&st->mjpeg_cinfo);
> -    /* rec_outbuf_height is the recommended size of the output buffer we
> -     * pass to libjpeg for optimum performance
> -     */
> -    if (st->mjpeg_cinfo.rec_outbuf_height > G_N_ELEMENTS(lines)) {
> -        jpeg_abort_decompress(&st->mjpeg_cinfo);
> -        g_return_if_reached();
> -    }
> -
> -    while (st->mjpeg_cinfo.output_scanline < st->mjpeg_cinfo.output_height)
> {
> -        /* only used when JCS_EXTENSIONS is undefined */
> -        G_GNUC_UNUSED unsigned int lines_read;
> -
> -        for (unsigned int j = 0; j < st->mjpeg_cinfo.rec_outbuf_height; j++)
> {
> -            lines[j] = dest;
> -#ifdef JCS_EXTENSIONS
> -            dest += 4 * width;
> -#else
> -            dest += 3 * width;
> -#endif
> -        }
> -        lines_read = jpeg_read_scanlines(&st->mjpeg_cinfo, lines,
> -                                st->mjpeg_cinfo.rec_outbuf_height);
> -#ifndef JCS_EXTENSIONS
> -        {
> -            uint8_t *s = lines[0];
> -            uint32_t *d = (uint32_t *)s;
> -
> -            if (back_compat) {
> -                for (unsigned int j = lines_read * width; j > 0; ) {
> -                    j -= 1; // reverse order, bad for cache?
> -                    d[j] = s[j * 3 + 0] |
> -                        s[j * 3 + 1] << 8 |
> -                        s[j * 3 + 2] << 16;
> -                }
> -            } else {
> -                for (unsigned int j = lines_read * width; j > 0; ) {
> -                    j -= 1; // reverse order, bad for cache?
> -                    d[j] = s[j * 3 + 0] << 16 |
> -                        s[j * 3 + 1] << 8 |
> -                        s[j * 3 + 2];
> -                }
> -            }
> -        }
> -#endif
> -        dest = &st->out_frame[st->mjpeg_cinfo.output_scanline * width * 4];
> -    }
> -    jpeg_finish_decompress(&st->mjpeg_cinfo);
> -}
> -
> -G_GNUC_INTERNAL
> -void stream_mjpeg_cleanup(display_stream *st)
> -{
> -    jpeg_destroy_decompress(&st->mjpeg_cinfo);
> -    g_free(st->out_frame);
> -    st->out_frame = NULL;
> -}
> diff --git a/gtk/channel-display-priv.h b/gtk/channel-display-priv.h
> deleted file mode 100644
> index 71f5d17..0000000
> --- a/gtk/channel-display-priv.h
> +++ /dev/null
> @@ -1,113 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2010 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#ifndef CHANNEL_DISPLAY_PRIV_H_
> -# define CHANNEL_DISPLAY_PRIV_H_
> -
> -#include <pixman.h>
> -#ifdef WIN32
> -/* We need some hacks to avoid warnings from the jpeg headers */
> -#define HAVE_BOOLEAN
> -#define XMD_H
> -#endif
> -#include <jpeglib.h>
> -
> -#include "common/canvas_utils.h"
> -#include "client_sw_canvas.h"
> -#include "common/ring.h"
> -#include "common/quic.h"
> -#include "common/rop3.h"
> -
> -G_BEGIN_DECLS
> -
> -
> -typedef struct display_surface {
> -    guint32                     surface_id;
> -    bool                        primary;
> -    enum SpiceSurfaceFmt        format;
> -    int                         width, height, stride, size;
> -    int                         shmid;
> -    uint8_t                     *data;
> -    SpiceCanvas                 *canvas;
> -    SpiceGlzDecoder             *glz_decoder;
> -    SpiceZlibDecoder            *zlib_decoder;
> -    SpiceJpegDecoder            *jpeg_decoder;
> -} display_surface;
> -
> -typedef struct drops_sequence_stats {
> -    uint32_t len;
> -    uint32_t start_mm_time;
> -    uint32_t duration;
> -} drops_sequence_stats;
> -
> -typedef struct display_stream {
> -    SpiceMsgIn                  *msg_create;
> -    SpiceMsgIn                  *msg_clip;
> -    SpiceMsgIn                  *msg_data;
> -
> -    /* from messages */
> -    display_surface             *surface;
> -    SpiceClip                   *clip;
> -    QRegion                     region;
> -    int                         have_region;
> -    int                         codec;
> -
> -    /* mjpeg decoder */
> -    struct jpeg_source_mgr         mjpeg_src;
> -    struct jpeg_decompress_struct  mjpeg_cinfo;
> -    struct jpeg_error_mgr          mjpeg_jerr;
> -
> -    uint8_t                     *out_frame;
> -    GQueue                      *msgq;
> -    guint                       timeout;
> -    SpiceChannel                *channel;
> -
> -    /* stats */
> -    uint32_t             first_frame_mm_time;
> -    uint32_t             num_drops_on_receive;
> -    uint64_t             arrive_late_time;
> -    uint32_t             num_drops_on_playback;
> -    uint32_t             num_input_frames;
> -    drops_sequence_stats cur_drops_seq_stats;
> -    GArray               *drops_seqs_stats_arr;
> -    uint32_t             num_drops_seqs;
> -
> -    uint32_t             playback_sync_drops_seq_len;
> -
> -    /* playback quality report to server */
> -    gboolean report_is_active;
> -    uint32_t report_id;
> -    uint32_t report_max_window;
> -    uint32_t report_timeout;
> -    uint64_t report_start_time;
> -    uint32_t report_start_frame_time;
> -    uint32_t report_num_frames;
> -    uint32_t report_num_drops;
> -    uint32_t report_drops_seq_len;
> -} display_stream;
> -
> -void stream_get_dimensions(display_stream *st, int *width, int *height);
> -uint32_t stream_get_current_frame(display_stream *st, uint8_t **data);
> -
> -/* channel-display-mjpeg.c */
> -void stream_mjpeg_init(display_stream *st);
> -void stream_mjpeg_data(display_stream *st);
> -void stream_mjpeg_cleanup(display_stream *st);
> -
> -G_END_DECLS
> -
> -#endif // CHANNEL_DISPLAY_PRIV_H_
> diff --git a/gtk/channel-display.c b/gtk/channel-display.c
> deleted file mode 100644
> index efe2259..0000000
> --- a/gtk/channel-display.c
> +++ /dev/null
> @@ -1,1789 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2010 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#include "config.h"
> -
> -#ifdef HAVE_SYS_TYPES_H
> -#include <sys/types.h>
> -#endif
> -
> -#ifdef HAVE_SYS_SHM_H
> -#include <sys/shm.h>
> -#endif
> -
> -#ifdef HAVE_SYS_IPC_H
> -#include <sys/ipc.h>
> -#endif
> -
> -#include "glib-compat.h"
> -#include "spice-client.h"
> -#include "spice-common.h"
> -
> -#include "spice-marshal.h"
> -#include "spice-channel-priv.h"
> -#include "spice-session-priv.h"
> -#include "channel-display-priv.h"
> -#include "decode.h"
> -
> -/**
> - * SECTION:channel-display
> - * @short_description: remote display area
> - * @title: Display Channel
> - * @section_id:
> - * @see_also: #SpiceChannel, and the GTK widget #SpiceDisplay
> - * @stability: Stable
> - * @include: channel-display.h
> - *
> - * A class that handles the rendering of the remote display and inform
> - * of its updates.
> - *
> - * The creation of the main graphic buffer is signaled with
> - * #SpiceDisplayChannel::display-primary-create.
> - *
> - * The update of regions is notified by
> - * #SpiceDisplayChannel::display-invalidate signals.
> - */
> -
> -#define SPICE_DISPLAY_CHANNEL_GET_PRIVATE(obj)
> \
> -    (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_DISPLAY_CHANNEL,
> SpiceDisplayChannelPrivate))
> -
> -#define MONITORS_MAX 256
> -
> -struct _SpiceDisplayChannelPrivate {
> -    GHashTable                  *surfaces;
> -    display_surface             *primary;
> -    display_cache               *images;
> -    display_cache               *palettes;
> -    SpiceImageCache             image_cache;
> -    SpicePaletteCache           palette_cache;
> -    SpiceImageSurfaces          image_surfaces;
> -    SpiceGlzDecoderWindow       *glz_window;
> -    display_stream              **streams;
> -    int                         nstreams;
> -    gboolean                    mark;
> -    guint                       mark_false_event_id;
> -    GArray                      *monitors;
> -    guint                       monitors_max;
> -    gboolean                    enable_adaptive_streaming;
> -#ifdef G_OS_WIN32
> -    HDC dc;
> -#endif
> -};
> -
> -G_DEFINE_TYPE(SpiceDisplayChannel, spice_display_channel,
> SPICE_TYPE_CHANNEL)
> -
> -/* Properties */
> -enum {
> -    PROP_0,
> -    PROP_WIDTH,
> -    PROP_HEIGHT,
> -    PROP_MONITORS,
> -    PROP_MONITORS_MAX
> -};
> -
> -enum {
> -    SPICE_DISPLAY_PRIMARY_CREATE,
> -    SPICE_DISPLAY_PRIMARY_DESTROY,
> -    SPICE_DISPLAY_INVALIDATE,
> -    SPICE_DISPLAY_MARK,
> -
> -    SPICE_DISPLAY_LAST_SIGNAL,
> -};
> -
> -static guint signals[SPICE_DISPLAY_LAST_SIGNAL];
> -
> -static void spice_display_channel_up(SpiceChannel *channel);
> -static void channel_set_handlers(SpiceChannelClass *klass);
> -
> -static void clear_surfaces(SpiceChannel *channel, gboolean keep_primary);
> -static void clear_streams(SpiceChannel *channel);
> -static display_surface *find_surface(SpiceDisplayChannelPrivate *c, guint32
> surface_id);
> -static gboolean display_stream_render(display_stream *st);
> -static void spice_display_channel_reset(SpiceChannel *channel, gboolean
> migrating);
> -static void spice_display_channel_reset_capabilities(SpiceChannel *channel);
> -static void destroy_canvas(display_surface *surface);
> -static void _msg_in_unref_func(gpointer data, gpointer user_data);
> -static void display_session_mm_time_reset_cb(SpiceSession *session, gpointer
> data);
> -
> -/* ------------------------------------------------------------------ */
> -
> -static void spice_display_channel_dispose(GObject *object)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(object)->priv;
> -
> -    if (c->mark_false_event_id != 0) {
> -        g_source_remove(c->mark_false_event_id);
> -        c->mark_false_event_id = 0;
> -    }
> -
> -    if (G_OBJECT_CLASS(spice_display_channel_parent_class)->dispose)
> -        G_OBJECT_CLASS(spice_display_channel_parent_class)->dispose(object);
> -}
> -
> -static void spice_display_channel_finalize(GObject *object)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(object)->priv;
> -
> -    g_clear_pointer(&c->monitors, g_array_unref);
> -    clear_surfaces(SPICE_CHANNEL(object), FALSE);
> -    g_hash_table_unref(c->surfaces);
> -    clear_streams(SPICE_CHANNEL(object));
> -    g_clear_pointer(&c->palettes, cache_unref);
> -
> -    if (G_OBJECT_CLASS(spice_display_channel_parent_class)->finalize)
> -
> G_OBJECT_CLASS(spice_display_channel_parent_class)->finalize(object);
> -}
> -
> -static void spice_display_channel_constructed(GObject *object)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(object)->priv;
> -    SpiceSession *s = spice_channel_get_session(SPICE_CHANNEL(object));
> -
> -    g_return_if_fail(s != NULL);
> -    spice_session_get_caches(s, &c->images, &c->glz_window);
> -    c->palettes = cache_new(g_free);
> -
> -    g_return_if_fail(c->glz_window != NULL);
> -    g_return_if_fail(c->images != NULL);
> -    g_return_if_fail(c->palettes != NULL);
> -
> -    c->monitors = g_array_new(FALSE, TRUE,
> sizeof(SpiceDisplayMonitorConfig));
> -    spice_g_signal_connect_object(s, "mm-time-reset",
> -
> G_CALLBACK(display_session_mm_time_reset_cb),
> -                                  SPICE_CHANNEL(object), 0);
> -
> -
> -    if (G_OBJECT_CLASS(spice_display_channel_parent_class)->constructed)
> -
> G_OBJECT_CLASS(spice_display_channel_parent_class)->constructed(object);
> -}
> -
> -
> -static void spice_display_get_property(GObject    *object,
> -                                       guint       prop_id,
> -                                       GValue     *value,
> -                                       GParamSpec *pspec)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(object)->priv;
> -
> -    switch (prop_id) {
> -    case PROP_WIDTH: {
> -        g_value_set_uint(value, c->primary ? c->primary->width : 0);
> -        break;
> -    }
> -    case PROP_HEIGHT: {
> -        g_value_set_uint(value, c->primary ? c->primary->height : 0);
> -        break;
> -    }
> -    case PROP_MONITORS: {
> -        g_value_set_boxed(value, c->monitors);
> -        break;
> -    }
> -    case PROP_MONITORS_MAX: {
> -        g_value_set_uint(value, c->monitors_max);
> -        break;
> -    }
> -    default:
> -        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
> -        break;
> -    }
> -}
> -
> -static void spice_display_set_property(GObject      *object,
> -                                       guint         prop_id,
> -                                       const GValue *value,
> -                                       GParamSpec   *pspec)
> -{
> -    switch (prop_id) {
> -    default:
> -        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
> -        break;
> -    }
> -}
> -
> -/* main or coroutine context */
> -static void spice_display_channel_reset(SpiceChannel *channel, gboolean
> migrating)
> -{
> -    /* palettes, images, and glz_window are cleared in the session */
> -    clear_streams(channel);
> -    clear_surfaces(channel, TRUE);
> -
> -
> SPICE_CHANNEL_CLASS(spice_display_channel_parent_class)->channel_reset(channel,
> migrating);
> -}
> -
> -static void spice_display_channel_class_init(SpiceDisplayChannelClass
> *klass)
> -{
> -    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
> -    SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
> -
> -    gobject_class->finalize     = spice_display_channel_finalize;
> -    gobject_class->dispose      = spice_display_channel_dispose;
> -    gobject_class->get_property = spice_display_get_property;
> -    gobject_class->set_property = spice_display_set_property;
> -    gobject_class->constructed = spice_display_channel_constructed;
> -
> -    channel_class->channel_up   = spice_display_channel_up;
> -    channel_class->channel_reset = spice_display_channel_reset;
> -    channel_class->channel_reset_capabilities =
> spice_display_channel_reset_capabilities;
> -
> -    g_object_class_install_property
> -        (gobject_class, PROP_HEIGHT,
> -         g_param_spec_uint("height",
> -                           "Display height",
> -                           "The primary surface height",
> -                           0, G_MAXUINT, 0,
> -                           G_PARAM_READABLE |
> -                           G_PARAM_STATIC_STRINGS));
> -
> -    g_object_class_install_property
> -        (gobject_class, PROP_WIDTH,
> -         g_param_spec_uint("width",
> -                           "Display width",
> -                           "The primary surface width",
> -                           0, G_MAXUINT, 0,
> -                           G_PARAM_READABLE |
> -                           G_PARAM_STATIC_STRINGS));
> -
> -    /**
> -     * SpiceDisplayChannel:monitors:
> -     *
> -     * Current monitors configuration.
> -     *
> -     * Since: 0.13
> -     */
> -    g_object_class_install_property
> -        (gobject_class, PROP_MONITORS,
> -         g_param_spec_boxed("monitors",
> -                            "Display monitors",
> -                            "The monitors configuration",
> -                            G_TYPE_ARRAY,
> -                            G_PARAM_READABLE |
> -                            G_PARAM_STATIC_STRINGS));
> -
> -    /**
> -     * SpiceDisplayChannel:monitors-max:
> -     *
> -     * The maximum number of monitors the server or guest supports.
> -     * May change during client lifetime, for instance guest may
> -     * reboot or dynamically adjust this.
> -     *
> -     * Since: 0.13
> -     */
> -    g_object_class_install_property
> -        (gobject_class, PROP_MONITORS_MAX,
> -         g_param_spec_uint("monitors-max",
> -                           "Max display monitors",
> -                           "The current maximum number of monitors",
> -                           1, MONITORS_MAX, 1,
> -                           G_PARAM_READABLE |
> -                           G_PARAM_STATIC_STRINGS));
> -
> -    /**
> -     * SpiceDisplayChannel::display-primary-create:
> -     * @display: the #SpiceDisplayChannel that emitted the signal
> -     * @format: %SPICE_SURFACE_FMT_32_xRGB or %SPICE_SURFACE_FMT_16_555;
> -     * @width: width resolution
> -     * @height: height resolution
> -     * @stride: the buffer stride ("width" padding)
> -     * @shmid: identifier of the shared memory segment associated with
> -     * the @imgdata, or -1 if not shm
> -     * @imgdata: pointer to surface buffer
> -     *
> -     * The #SpiceDisplayChannel::display-primary-create signal
> -     * provides main display buffer data.
> -     **/
> -    signals[SPICE_DISPLAY_PRIMARY_CREATE] =
> -        g_signal_new("display-primary-create",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceDisplayChannelClass,
> -                                     display_primary_create),
> -                     NULL, NULL,
> -
> g_cclosure_user_marshal_VOID__INT_INT_INT_INT_INT_POINTER,
> -                     G_TYPE_NONE,
> -                     6,
> -                     G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
> -                     G_TYPE_INT, G_TYPE_INT, G_TYPE_POINTER);
> -
> -    /**
> -     * SpiceDisplayChannel::display-primary-destroy:
> -     * @display: the #SpiceDisplayChannel that emitted the signal
> -     *
> -     * The #SpiceDisplayChannel::display-primary-destroy signal is
> -     * emitted when the primary surface is freed and should not be
> -     * accessed anymore.
> -     **/
> -    signals[SPICE_DISPLAY_PRIMARY_DESTROY] =
> -        g_signal_new("display-primary-destroy",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceDisplayChannelClass,
> -                                     display_primary_destroy),
> -                     NULL, NULL,
> -                     g_cclosure_marshal_VOID__VOID,
> -                     G_TYPE_NONE,
> -                     0);
> -
> -    /**
> -     * SpiceDisplayChannel::display-invalidate:
> -     * @display: the #SpiceDisplayChannel that emitted the signal
> -     * @x: x position
> -     * @y: y position
> -     * @width: width
> -     * @height: height
> -     *
> -     * The #SpiceDisplayChannel::display-invalidate signal is emitted
> -     * when the rectangular region x/y/w/h of the primary buffer is
> -     * updated.
> -     **/
> -    signals[SPICE_DISPLAY_INVALIDATE] =
> -        g_signal_new("display-invalidate",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceDisplayChannelClass,
> -                                     display_invalidate),
> -                     NULL, NULL,
> -                     g_cclosure_user_marshal_VOID__INT_INT_INT_INT,
> -                     G_TYPE_NONE,
> -                     4,
> -                     G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
> -
> -    /**
> -     * SpiceDisplayChannel::display-mark:
> -     * @display: the #SpiceDisplayChannel that emitted the signal
> -     * @mark: %TRUE when the display mark has been received
> -     *
> -     * The #SpiceDisplayChannel::display-mark signal is emitted when
> -     * the %RED_DISPLAY_MARK command is received, and the display
> -     * should be exposed.
> -     **/
> -    signals[SPICE_DISPLAY_MARK] =
> -        g_signal_new("display-mark",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceDisplayChannelClass,
> -                                     display_mark),
> -                     NULL, NULL,
> -                     g_cclosure_marshal_VOID__INT,
> -                     G_TYPE_NONE,
> -                     1,
> -                     G_TYPE_INT);
> -
> -    g_type_class_add_private(klass, sizeof(SpiceDisplayChannelPrivate));
> -
> -    sw_canvas_init();
> -    quic_init();
> -    rop3_init();
> -    channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
> -}
> -
> -/**
> - * spice_display_get_primary:
> - * @channel:
> - * @surface_id:
> - * @primary:
> - *
> - * Retrieve primary display surface @surface_id.
> - *
> - * Returns: %TRUE if the primary surface was found and its details
> - * collected in @primary.
> - */
> -gboolean spice_display_get_primary(SpiceChannel *channel, guint32
> surface_id,
> -                                   SpiceDisplayPrimary *primary)
> -{
> -    g_return_val_if_fail(SPICE_IS_DISPLAY_CHANNEL(channel), FALSE);
> -    g_return_val_if_fail(primary != NULL, FALSE);
> -
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    display_surface *surface = find_surface(c, surface_id);
> -
> -    if (surface == NULL)
> -        return FALSE;
> -
> -    g_return_val_if_fail(surface->primary, FALSE);
> -
> -    primary->format = surface->format;
> -    primary->width = surface->width;
> -    primary->height = surface->height;
> -    primary->stride = surface->stride;
> -    primary->shmid = surface->shmid;
> -    primary->data = surface->data;
> -    primary->marked = c->mark;
> -    CHANNEL_DEBUG(channel, "get primary %p", primary->data);
> -
> -    return TRUE;
> -}
> -
> -/* ------------------------------------------------------------------ */
> -
> -static void image_put(SpiceImageCache *cache, uint64_t id, pixman_image_t
> *image)
> -{
> -    SpiceDisplayChannelPrivate *c =
> -        SPICE_CONTAINEROF(cache, SpiceDisplayChannelPrivate, image_cache);
> -
> -    cache_add(c->images, id, pixman_image_ref(image));
> -}
> -
> -typedef struct _WaitImageData
> -{
> -    gboolean lossy;
> -    SpiceImageCache *cache;
> -    uint64_t id;
> -    pixman_image_t *image;
> -} WaitImageData;
> -
> -static gboolean wait_image(gpointer data)
> -{
> -    gboolean lossy;
> -    WaitImageData *wait = data;
> -    SpiceDisplayChannelPrivate *c =
> -        SPICE_CONTAINEROF(wait->cache, SpiceDisplayChannelPrivate,
> image_cache);
> -    pixman_image_t *image = cache_find_lossy(c->images, wait->id, &lossy);
> -
> -    if (!image || (lossy && !wait->lossy))
> -        return FALSE;
> -
> -    wait->image = pixman_image_ref(image);
> -
> -    return TRUE;
> -}
> -
> -static pixman_image_t *image_get(SpiceImageCache *cache, uint64_t id)
> -{
> -    WaitImageData wait = {
> -        .lossy = TRUE,
> -        .cache = cache,
> -        .id = id,
> -        .image = NULL
> -    };
> -    if (!g_coroutine_condition_wait(g_coroutine_self(), wait_image, &wait))
> -        SPICE_DEBUG("wait image got cancelled");
> -
> -    return wait.image;
> -}
> -
> -static void palette_put(SpicePaletteCache *cache, SpicePalette *palette)
> -{
> -    SpiceDisplayChannelPrivate *c =
> -        SPICE_CONTAINEROF(cache, SpiceDisplayChannelPrivate, palette_cache);
> -
> -    cache_add(c->palettes, palette->unique,
> -              g_memdup(palette, sizeof(SpicePalette) +
> -                       palette->num_ents * sizeof(palette->ents[0])));
> -}
> -
> -static SpicePalette *palette_get(SpicePaletteCache *cache, uint64_t id)
> -{
> -    SpiceDisplayChannelPrivate *c =
> -        SPICE_CONTAINEROF(cache, SpiceDisplayChannelPrivate, palette_cache);
> -
> -    /* here the returned pointer is weak, no ref given to caller.  it
> -     * seems spice canvas usage is exclusively temporary, so it's ok.
> -     * palette_release is a noop. */
> -    return cache_find(c->palettes, id);
> -}
> -
> -static void palette_remove(SpicePaletteCache *cache, uint64_t id)
> -{
> -    SpiceDisplayChannelPrivate *c =
> -        SPICE_CONTAINEROF(cache, SpiceDisplayChannelPrivate, palette_cache);
> -
> -    cache_remove(c->palettes, id);
> -}
> -
> -static void palette_release(SpicePaletteCache *cache, SpicePalette *palette)
> -{
> -    /* there is no refcount of palette, see palette_get() */
> -}
> -
> -static void image_put_lossy(SpiceImageCache *cache, uint64_t id,
> -                            pixman_image_t *surface)
> -{
> -    SpiceDisplayChannelPrivate *c =
> -        SPICE_CONTAINEROF(cache, SpiceDisplayChannelPrivate, image_cache);
> -
> -#ifndef NDEBUG
> -    g_warn_if_fail(cache_find(c->images, id) == NULL);
> -#endif
> -
> -    cache_add_lossy(c->images, id, pixman_image_ref(surface), TRUE);
> -}
> -
> -static void image_replace_lossy(SpiceImageCache *cache, uint64_t id,
> -                                pixman_image_t *surface)
> -{
> -    image_put(cache, id, surface);
> -}
> -
> -static pixman_image_t* image_get_lossless(SpiceImageCache *cache, uint64_t
> id)
> -{
> -    WaitImageData wait = {
> -        .lossy = FALSE,
> -        .cache = cache,
> -        .id = id,
> -        .image = NULL
> -    };
> -    if (!g_coroutine_condition_wait(g_coroutine_self(), wait_image, &wait))
> -        SPICE_DEBUG("wait lossless got cancelled");
> -
> -    return wait.image;
> -}
> -
> -static SpiceCanvas *surfaces_get(SpiceImageSurfaces *surfaces,
> -                                 uint32_t surface_id)
> -{
> -    SpiceDisplayChannelPrivate *c =
> -        SPICE_CONTAINEROF(surfaces, SpiceDisplayChannelPrivate,
> image_surfaces);
> -
> -    display_surface *s =
> -        find_surface(c, surface_id);
> -
> -    return s ? s->canvas : NULL;
> -}
> -
> -static SpiceImageCacheOps image_cache_ops = {
> -    .put = image_put,
> -    .get = image_get,
> -
> -    .put_lossy = image_put_lossy,
> -    .replace_lossy = image_replace_lossy,
> -    .get_lossless = image_get_lossless,
> -};
> -
> -static SpicePaletteCacheOps palette_cache_ops = {
> -    .put     = palette_put,
> -    .get     = palette_get,
> -    .release = palette_release,
> -};
> -
> -static SpiceImageSurfacesOps image_surfaces_ops = {
> -    .get = surfaces_get
> -};
> -
> -#if defined(G_OS_WIN32)
> -static HDC create_compatible_dc(void)
> -{
> -    HDC dc = CreateCompatibleDC(NULL);
> -    if (!dc) {
> -        g_warning("create compatible DC failed");
> -    }
> -    return dc;
> -}
> -#endif
> -
> -static void spice_display_channel_reset_capabilities(SpiceChannel *channel)
> -{
> -    spice_channel_set_capability(SPICE_CHANNEL(channel),
> SPICE_DISPLAY_CAP_SIZED_STREAM);
> -    spice_channel_set_capability(SPICE_CHANNEL(channel),
> SPICE_DISPLAY_CAP_MONITORS_CONFIG);
> -    spice_channel_set_capability(SPICE_CHANNEL(channel),
> SPICE_DISPLAY_CAP_COMPOSITE);
> -    spice_channel_set_capability(SPICE_CHANNEL(channel),
> SPICE_DISPLAY_CAP_A8_SURFACE);
> -#ifdef USE_LZ4
> -    spice_channel_set_capability(SPICE_CHANNEL(channel),
> SPICE_DISPLAY_CAP_LZ4_COMPRESSION);
> -#endif
> -    if (SPICE_DISPLAY_CHANNEL(channel)->priv->enable_adaptive_streaming) {
> -        spice_channel_set_capability(SPICE_CHANNEL(channel),
> SPICE_DISPLAY_CAP_STREAM_REPORT);
> -    }
> -}
> -
> -static void destroy_surface(gpointer data)
> -{
> -    display_surface *surface = data;
> -
> -    destroy_canvas(surface);
> -    g_slice_free(display_surface, surface);
> -}
> -
> -static void spice_display_channel_init(SpiceDisplayChannel *channel)
> -{
> -    SpiceDisplayChannelPrivate *c;
> -
> -    c = channel->priv = SPICE_DISPLAY_CHANNEL_GET_PRIVATE(channel);
> -
> -    c->surfaces = g_hash_table_new_full(NULL, NULL, NULL, destroy_surface);
> -    c->image_cache.ops = &image_cache_ops;
> -    c->palette_cache.ops = &palette_cache_ops;
> -    c->image_surfaces.ops = &image_surfaces_ops;
> -#if defined(G_OS_WIN32)
> -    c->dc = create_compatible_dc();
> -#endif
> -    c->monitors_max = 1;
> -
> -    if (g_getenv("SPICE_DISABLE_ADAPTIVE_STREAMING")) {
> -        SPICE_DEBUG("adaptive video disabled");
> -        c->enable_adaptive_streaming = FALSE;
> -    } else {
> -        c->enable_adaptive_streaming = TRUE;
> -    }
> -    spice_display_channel_reset_capabilities(SPICE_CHANNEL(channel));
> -}
> -
> -/* ------------------------------------------------------------------ */
> -
> -static int create_canvas(SpiceChannel *channel, display_surface *surface)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -
> -    if (surface->primary) {
> -        if (c->primary) {
> -            if (c->primary->width == surface->width &&
> -                c->primary->height == surface->height) {
> -                CHANNEL_DEBUG(channel, "Reusing existing primary surface");
> -                return 0;
> -            }
> -
> -            g_coroutine_signal_emit(channel,
> signals[SPICE_DISPLAY_PRIMARY_DESTROY], 0);
> -
> -            g_hash_table_remove(c->surfaces,
> GINT_TO_POINTER(c->primary->surface_id));
> -        }
> -
> -        CHANNEL_DEBUG(channel, "Create primary canvas");
> -#if defined(WITH_X11) && defined(HAVE_SYS_SHM_H)
> -        surface->shmid = shmget(IPC_PRIVATE, surface->size, IPC_CREAT |
> 0777);
> -        if (surface->shmid >= 0) {
> -            surface->data = shmat(surface->shmid, 0, 0);
> -            if (surface->data == NULL) {
> -                shmctl(surface->shmid, IPC_RMID, 0);
> -                surface->shmid = -1;
> -            }
> -        }
> -#else
> -        surface->shmid = -1;
> -#endif
> -    } else {
> -        surface->shmid = -1;
> -    }
> -
> -    if (surface->shmid == -1)
> -        surface->data = g_malloc0(surface->size);
> -
> -    g_return_val_if_fail(c->glz_window, 0);
> -
> -    g_warn_if_fail(surface->canvas == NULL);
> -    g_warn_if_fail(surface->glz_decoder == NULL);
> -    g_warn_if_fail(surface->zlib_decoder == NULL);
> -    g_warn_if_fail(surface->jpeg_decoder == NULL);
> -
> -    surface->glz_decoder = glz_decoder_new(c->glz_window);
> -    surface->zlib_decoder = zlib_decoder_new();
> -    surface->jpeg_decoder = jpeg_decoder_new();
> -
> -    surface->canvas = canvas_create_for_data(surface->width,
> -                                             surface->height,
> -                                             surface->format,
> -                                             surface->data,
> -                                             surface->stride,
> -                                             &c->image_cache,
> -                                             &c->palette_cache,
> -                                             &c->image_surfaces,
> -                                             surface->glz_decoder,
> -                                             surface->jpeg_decoder,
> -                                             surface->zlib_decoder);
> -
> -    g_return_val_if_fail(surface->canvas != NULL, 0);
> -    g_hash_table_insert(c->surfaces, GINT_TO_POINTER(surface->surface_id),
> surface);
> -
> -    if (surface->primary) {
> -        g_warn_if_fail(c->primary == NULL);
> -        c->primary = surface;
> -        g_coroutine_signal_emit(channel,
> signals[SPICE_DISPLAY_PRIMARY_CREATE], 0,
> -                                surface->format, surface->width,
> surface->height,
> -                                surface->stride, surface->shmid,
> surface->data);
> -
> -        if (!spice_channel_test_capability(channel,
> SPICE_DISPLAY_CAP_MONITORS_CONFIG)) {
> -            g_array_set_size(c->monitors, 1);
> -            SpiceDisplayMonitorConfig *config = &g_array_index(c->monitors,
> SpiceDisplayMonitorConfig, 0);
> -            config->x = config->y = 0;
> -            config->width = surface->width;
> -            config->height = surface->height;
> -            g_coroutine_object_notify(G_OBJECT(channel), "monitors");
> -        }
> -    }
> -
> -    return 0;
> -}
> -
> -static void destroy_canvas(display_surface *surface)
> -{
> -    if (surface == NULL)
> -        return;
> -
> -    glz_decoder_destroy(surface->glz_decoder);
> -    zlib_decoder_destroy(surface->zlib_decoder);
> -    jpeg_decoder_destroy(surface->jpeg_decoder);
> -
> -    if (surface->shmid == -1) {
> -        g_free(surface->data);
> -    }
> -#ifdef HAVE_SYS_SHM_H
> -    else {
> -        shmdt(surface->data);
> -        shmctl(surface->shmid, IPC_RMID, 0);
> -    }
> -#endif
> -    surface->shmid = -1;
> -    surface->data = NULL;
> -
> -    surface->canvas->ops->destroy(surface->canvas);
> -    surface->canvas = NULL;
> -}
> -
> -static display_surface *find_surface(SpiceDisplayChannelPrivate *c, guint32
> surface_id)
> -{
> -    if (c->primary && c->primary->surface_id == surface_id)
> -        return c->primary;
> -
> -    return g_hash_table_lookup(c->surfaces, GINT_TO_POINTER(surface_id));
> -}
> -
> -/* main or coroutine context */
> -static void clear_surfaces(SpiceChannel *channel, gboolean keep_primary)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    GHashTableIter iter;
> -    display_surface *surface;
> -
> -    if (!keep_primary) {
> -        c->primary = NULL;
> -        g_coroutine_signal_emit(channel,
> signals[SPICE_DISPLAY_PRIMARY_DESTROY], 0);
> -    }
> -
> -    g_hash_table_iter_init(&iter, c->surfaces);
> -    while (g_hash_table_iter_next(&iter, NULL, (gpointer*)&surface)) {
> -
> -        if (keep_primary && surface->primary) {
> -            CHANNEL_DEBUG(channel, "keeping existing primary surface,
> migration or reset");
> -            continue;
> -        }
> -
> -        g_hash_table_iter_remove(&iter);
> -    }
> -}
> -
> -/* coroutine context */
> -static void emit_invalidate(SpiceChannel *channel, SpiceRect *bbox)
> -{
> -    g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_INVALIDATE], 0,
> -                            bbox->left, bbox->top,
> -                            bbox->right - bbox->left,
> -                            bbox->bottom - bbox->top);
> -}
> -
> -/* ------------------------------------------------------------------ */
> -
> -/* coroutine context */
> -static void spice_display_channel_up(SpiceChannel *channel)
> -{
> -    SpiceMsgOut *out;
> -    SpiceSession *s = spice_channel_get_session(channel);
> -    SpiceMsgcDisplayInit init;
> -    int cache_size;
> -    int glz_window_size;
> -
> -    g_object_get(s,
> -                 "cache-size", &cache_size,
> -                 "glz-window-size", &glz_window_size,
> -                 NULL);
> -    CHANNEL_DEBUG(channel, "%s: cache_size %d, glz_window_size %d (bytes)",
> __FUNCTION__,
> -                  cache_size, glz_window_size);
> -    init.pixmap_cache_id = 1;
> -    init.glz_dictionary_id = 1;
> -    init.pixmap_cache_size = cache_size / 4; /* pixels */
> -    init.glz_dictionary_window_size = glz_window_size / 4; /* pixels */
> -    out = spice_msg_out_new(channel, SPICE_MSGC_DISPLAY_INIT);
> -    out->marshallers->msgc_display_init(out->marshaller, &init);
> -    spice_msg_out_send_internal(out);
> -
> -    /* if we are not using monitors config, notify of existence of
> -       this monitor */
> -    if (channel->priv->channel_id != 0)
> -        g_coroutine_object_notify(G_OBJECT(channel), "monitors");
> -}
> -
> -#define DRAW(type) {                                                    \
> -        display_surface *surface =                                      \
> -            find_surface(SPICE_DISPLAY_CHANNEL(channel)->priv,          \
> -                op->base.surface_id);                                   \
> -        g_return_if_fail(surface != NULL);                              \
> -        surface->canvas->ops->draw_##type(surface->canvas, &op->base.box, \
> -                                          &op->base.clip, &op->data);   \
> -        if (surface->primary) {                                         \
> -            emit_invalidate(channel, &op->base.box);                    \
> -        }                                                               \
> -}
> -
> -/* coroutine context */
> -static void display_handle_mode(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    SpiceMsgDisplayMode *mode = spice_msg_in_parsed(in);
> -    display_surface *surface;
> -
> -    g_warn_if_fail(c->mark == FALSE);
> -
> -    surface = g_slice_new0(display_surface);
> -    surface->format  = mode->bits == 32 ?
> -        SPICE_SURFACE_FMT_32_xRGB : SPICE_SURFACE_FMT_16_555;
> -    surface->width   = mode->x_res;
> -    surface->height  = mode->y_res;
> -    surface->stride  = surface->width * 4;
> -    surface->size    = surface->height * surface->stride;
> -    surface->primary = true;
> -    create_canvas(channel, surface);
> -}
> -
> -/* coroutine context */
> -static void display_handle_mark(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -
> -    CHANNEL_DEBUG(channel, "%s", __FUNCTION__);
> -    g_return_if_fail(c->primary != NULL);
> -#ifdef EXTRA_CHECKS
> -    g_warn_if_fail(c->mark == FALSE);
> -#endif
> -
> -    c->mark = TRUE;
> -    g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_MARK], 0, TRUE);
> -}
> -
> -/* coroutine context */
> -static void display_handle_reset(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    display_surface *surface = c->primary;
> -
> -    CHANNEL_DEBUG(channel, "%s: TODO detach_from_screen", __FUNCTION__);
> -
> -    if (surface != NULL)
> -        surface->canvas->ops->clear(surface->canvas);
> -
> -    cache_clear(c->palettes);
> -
> -    c->mark = FALSE;
> -    g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_MARK], 0, FALSE);
> -}
> -
> -/* coroutine context */
> -static void display_handle_copy_bits(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgDisplayCopyBits *op = spice_msg_in_parsed(in);
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    display_surface *surface = find_surface(c, op->base.surface_id);
> -
> -    g_return_if_fail(surface != NULL);
> -    surface->canvas->ops->copy_bits(surface->canvas, &op->base.box,
> -                                    &op->base.clip, &op->src_pos);
> -    if (surface->primary) {
> -        emit_invalidate(channel, &op->base.box);
> -    }
> -}
> -
> -/* coroutine context */
> -static void display_handle_inv_list(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    SpiceResourceList *list = spice_msg_in_parsed(in);
> -    int i;
> -
> -    for (i = 0; i < list->count; i++) {
> -        guint64 id = list->resources[i].id;
> -
> -        switch (list->resources[i].type) {
> -        case SPICE_RES_TYPE_PIXMAP:
> -            if (!cache_remove(c->images, id))
> -                SPICE_DEBUG("fail to remove image %" G_GUINT64_FORMAT, id);
> -            break;
> -        default:
> -            g_return_if_reached();
> -            break;
> -        }
> -    }
> -}
> -
> -/* coroutine context */
> -static void display_handle_inv_pixmap_all(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -
> -    spice_channel_handle_wait_for_channels(channel, in);
> -    cache_clear(c->images);
> -}
> -
> -/* coroutine context */
> -static void display_handle_inv_palette(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    SpiceMsgDisplayInvalOne* op = spice_msg_in_parsed(in);
> -
> -    palette_remove(&c->palette_cache, op->id);
> -}
> -
> -/* coroutine context */
> -static void display_handle_inv_palette_all(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -
> -    cache_clear(c->palettes);
> -}
> -
> -/* ------------------------------------------------------------------ */
> -
> -static void display_update_stream_region(display_stream *st)
> -{
> -    int i;
> -
> -    switch (st->clip->type) {
> -    case SPICE_CLIP_TYPE_RECTS:
> -        region_clear(&st->region);
> -        for (i = 0; i < st->clip->rects->num_rects; i++) {
> -            region_add(&st->region, &st->clip->rects->rects[i]);
> -        }
> -        st->have_region = true;
> -        break;
> -    case SPICE_CLIP_TYPE_NONE:
> -    default:
> -        st->have_region = false;
> -        break;
> -    }
> -}
> -
> -/* coroutine context */
> -static void display_handle_stream_create(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    SpiceMsgDisplayStreamCreate *op = spice_msg_in_parsed(in);
> -    display_stream *st;
> -
> -    CHANNEL_DEBUG(channel, "%s: id %d", __FUNCTION__, op->id);
> -
> -    if (op->id >= c->nstreams) {
> -        int n = c->nstreams;
> -        if (!c->nstreams) {
> -            c->nstreams = 1;
> -        }
> -        while (op->id >= c->nstreams) {
> -            c->nstreams *= 2;
> -        }
> -        c->streams = realloc(c->streams, c->nstreams *
> sizeof(c->streams[0]));
> -        memset(c->streams + n, 0, (c->nstreams - n) *
> sizeof(c->streams[0]));
> -    }
> -    g_return_if_fail(c->streams[op->id] == NULL);
> -    c->streams[op->id] = g_new0(display_stream, 1);
> -    st = c->streams[op->id];
> -
> -    st->msg_create = in;
> -    spice_msg_in_ref(in);
> -    st->clip = &op->clip;
> -    st->codec = op->codec_type;
> -    st->surface = find_surface(c, op->surface_id);
> -    st->msgq = g_queue_new();
> -    st->channel = channel;
> -    st->drops_seqs_stats_arr = g_array_new(FALSE, FALSE,
> sizeof(drops_sequence_stats));
> -
> -    region_init(&st->region);
> -    display_update_stream_region(st);
> -
> -    switch (st->codec) {
> -    case SPICE_VIDEO_CODEC_TYPE_MJPEG:
> -        stream_mjpeg_init(st);
> -        break;
> -    }
> -}
> -
> -/* coroutine or main context */
> -static gboolean display_stream_schedule(display_stream *st)
> -{
> -    SpiceSession *session = spice_channel_get_session(st->channel);
> -    guint32 time, d;
> -    SpiceStreamDataHeader *op;
> -    SpiceMsgIn *in;
> -
> -    SPICE_DEBUG("%s", __FUNCTION__);
> -    if (st->timeout || !session)
> -        return TRUE;
> -
> -    time = spice_session_get_mm_time(session);
> -    in = g_queue_peek_head(st->msgq);
> -
> -    if (in == NULL) {
> -        return TRUE;
> -    }
> -
> -    op = spice_msg_in_parsed(in);
> -    if (time < op->multi_media_time) {
> -        d = op->multi_media_time - time;
> -        SPICE_DEBUG("scheduling next stream render in %u ms", d);
> -        st->timeout = g_timeout_add(d, (GSourceFunc)display_stream_render,
> st);
> -        return TRUE;
> -    } else {
> -        SPICE_DEBUG("%s: rendering too late by %u ms (ts: %u, mmtime: %u),
> dropping ",
> -                    __FUNCTION__, time - op->multi_media_time,
> -                    op->multi_media_time, time);
> -        in = g_queue_pop_head(st->msgq);
> -        spice_msg_in_unref(in);
> -        st->num_drops_on_playback++;
> -        if (g_queue_get_length(st->msgq) == 0)
> -            return TRUE;
> -    }
> -
> -    return FALSE;
> -}
> -
> -static SpiceRect *stream_get_dest(display_stream *st)
> -{
> -    if (st->msg_data == NULL ||
> -        spice_msg_in_type(st->msg_data) !=
> SPICE_MSG_DISPLAY_STREAM_DATA_SIZED) {
> -        SpiceMsgDisplayStreamCreate *info =
> spice_msg_in_parsed(st->msg_create);
> -
> -        return &info->dest;
> -    } else {
> -        SpiceMsgDisplayStreamDataSized *op =
> spice_msg_in_parsed(st->msg_data);
> -
> -        return &op->dest;
> -   }
> -
> -}
> -
> -static uint32_t stream_get_flags(display_stream *st)
> -{
> -    SpiceMsgDisplayStreamCreate *info = spice_msg_in_parsed(st->msg_create);
> -
> -    return info->flags;
> -}
> -
> -G_GNUC_INTERNAL
> -uint32_t stream_get_current_frame(display_stream *st, uint8_t **data)
> -{
> -    if (st->msg_data == NULL) {
> -        *data = NULL;
> -        return 0;
> -    }
> -
> -    if (spice_msg_in_type(st->msg_data) == SPICE_MSG_DISPLAY_STREAM_DATA) {
> -        SpiceMsgDisplayStreamData *op = spice_msg_in_parsed(st->msg_data);
> -
> -        *data = op->data;
> -        return op->data_size;
> -    } else {
> -        SpiceMsgDisplayStreamDataSized *op =
> spice_msg_in_parsed(st->msg_data);
> -
> -        g_return_val_if_fail(spice_msg_in_type(st->msg_data) ==
> -                             SPICE_MSG_DISPLAY_STREAM_DATA_SIZED, 0);
> -        *data = op->data;
> -        return op->data_size;
> -   }
> -
> -}
> -
> -G_GNUC_INTERNAL
> -void stream_get_dimensions(display_stream *st, int *width, int *height)
> -{
> -    g_return_if_fail(width != NULL);
> -    g_return_if_fail(height != NULL);
> -
> -    if (st->msg_data == NULL ||
> -        spice_msg_in_type(st->msg_data) !=
> SPICE_MSG_DISPLAY_STREAM_DATA_SIZED) {
> -        SpiceMsgDisplayStreamCreate *info =
> spice_msg_in_parsed(st->msg_create);
> -
> -        *width = info->stream_width;
> -        *height = info->stream_height;
> -    } else {
> -        SpiceMsgDisplayStreamDataSized *op =
> spice_msg_in_parsed(st->msg_data);
> -
> -        *width = op->width;
> -        *height = op->height;
> -   }
> -}
> -
> -/* main context */
> -static gboolean display_stream_render(display_stream *st)
> -{
> -    SpiceMsgIn *in;
> -
> -    st->timeout = 0;
> -    do {
> -        in = g_queue_pop_head(st->msgq);
> -
> -        g_return_val_if_fail(in != NULL, FALSE);
> -
> -        st->msg_data = in;
> -        switch (st->codec) {
> -        case SPICE_VIDEO_CODEC_TYPE_MJPEG:
> -            stream_mjpeg_data(st);
> -            break;
> -        }
> -
> -        if (st->out_frame) {
> -            int width;
> -            int height;
> -            SpiceRect *dest;
> -            uint8_t *data;
> -            int stride;
> -
> -            stream_get_dimensions(st, &width, &height);
> -            dest = stream_get_dest(st);
> -
> -            data = st->out_frame;
> -            stride = width * sizeof(uint32_t);
> -            if (!(stream_get_flags(st) & SPICE_STREAM_FLAGS_TOP_DOWN)) {
> -                data += stride * (height - 1);
> -                stride = -stride;
> -            }
> -
> -            st->surface->canvas->ops->put_image(
> -                st->surface->canvas,
> -#ifdef G_OS_WIN32
> -                SPICE_DISPLAY_CHANNEL(st->channel)->priv->dc,
> -#endif
> -                dest, data,
> -                width, height, stride,
> -                st->have_region ? &st->region : NULL);
> -
> -            if (st->surface->primary)
> -                g_signal_emit(st->channel,
> signals[SPICE_DISPLAY_INVALIDATE], 0,
> -                    dest->left, dest->top,
> -                    dest->right - dest->left,
> -                    dest->bottom - dest->top);
> -        }
> -
> -        st->msg_data = NULL;
> -        spice_msg_in_unref(in);
> -
> -        in = g_queue_peek_head(st->msgq);
> -        if (in == NULL)
> -            break;
> -
> -        if (display_stream_schedule(st))
> -            return FALSE;
> -    } while (1);
> -
> -    return FALSE;
> -}
> -/* after a sequence of 3 drops, push a report to the server, even
> - * if the report window is bigger */
> -#define STREAM_REPORT_DROP_SEQ_LEN_LIMIT 3
> -
> -static void display_update_stream_report(SpiceDisplayChannel *channel,
> uint32_t stream_id,
> -                                         uint32_t frame_time, int32_t
> latency)
> -{
> -    display_stream *st = channel->priv->streams[stream_id];
> -    guint64 now;
> -
> -    if (!st->report_is_active) {
> -        return;
> -    }
> -    now = g_get_monotonic_time();
> -
> -    if (st->report_num_frames == 0) {
> -        st->report_start_frame_time = frame_time;
> -        st->report_start_time = now;
> -    }
> -    st->report_num_frames++;
> -
> -    if (latency < 0) { // drop
> -        st->report_num_drops++;
> -        st->report_drops_seq_len++;
> -    } else {
> -        st->report_drops_seq_len = 0;
> -    }
> -
> -    if (st->report_num_frames >= st->report_max_window ||
> -        now - st->report_start_time >= st->report_timeout ||
> -        st->report_drops_seq_len >= STREAM_REPORT_DROP_SEQ_LEN_LIMIT) {
> -        SpiceMsgcDisplayStreamReport report;
> -        SpiceSession *session =
> spice_channel_get_session(SPICE_CHANNEL(channel));
> -        SpiceMsgOut *msg;
> -
> -        report.stream_id = stream_id;
> -        report.unique_id = st->report_id;
> -        report.start_frame_mm_time = st->report_start_frame_time;
> -        report.end_frame_mm_time = frame_time;
> -        report.num_frames = st->report_num_frames;
> -        report.num_drops = st-> report_num_drops;
> -        report.last_frame_delay = latency;
> -        if (spice_session_is_playback_active(session)) {
> -            report.audio_delay =
> spice_session_get_playback_latency(session);
> -        } else {
> -            report.audio_delay = UINT_MAX;
> -        }
> -
> -        msg = spice_msg_out_new(SPICE_CHANNEL(channel),
> SPICE_MSGC_DISPLAY_STREAM_REPORT);
> -        msg->marshallers->msgc_display_stream_report(msg->marshaller,
> &report);
> -        spice_msg_out_send(msg);
> -
> -        st->report_start_time = 0;
> -        st->report_start_frame_time = 0;
> -        st->report_num_frames = 0;
> -        st->report_num_drops = 0;
> -        st->report_drops_seq_len = 0;
> -    }
> -}
> -
> -static void display_stream_reset_rendering_timer(display_stream *st)
> -{
> -    SPICE_DEBUG("%s", __FUNCTION__);
> -    if (st->timeout != 0) {
> -        g_source_remove(st->timeout);
> -        st->timeout = 0;
> -    }
> -    while (!display_stream_schedule(st)) {
> -    }
> -}
> -
> -/*
> - * Migration can occur between 2 spice-servers with different mm-times.
> - * Then, the following cases can happen after migration completes:
> - * (We refer to src/dst-time as the mm-times on the src/dst servers):
> - *
> - * (case 1) Frames with time ~= dst-time arrive to the client before the
> - *          playback-channel updates the session's mm-time (i.e., the
> mm_time
> - *          of the session is still based on the src-time).
> - *     (a) If src-time < dst-time:
> - *         display_stream_schedule schedules the next rendering to
> - *         ~(dst-time - src-time) milliseconds from now.
> - *         Since we assume monotonic mm_time, display_stream_schedule,
> - *         returns immediately when a rendering timeout
> - *         has already been set, and doesn't update the timeout,
> - *         even after the mm_time is updated.
> - *         When src-time << dst-time, a significant video frames loss will
> occur.
> - *     (b) If src-time > dst-time
> - *         Frames will be dropped till the mm-time will be updated.
> - * (case 2) mm-time is synced with dst-time, but frames that were in the
> command
> - *         ring during migration still arrive (such frames hold src-time).
> - *    (a) If src-time < dst-time
> - *        The frames that hold src-time will be dropped, since their
> - *        mm_time < session-mm_time. But all the new frames that are
> generated in
> - *        the driver after migration, will be rendered appropriately.
> - *    (b) If src-time > dst-time
> - *        Similar consequences as in 1 (a)
> - * case 2 is less likely, since at takes at least 20 frames till the
> dst-server re-identifies
> - * the video stream and starts sending stream data
> - *
> - * display_session_mm_time_reset_cb handles case 1.a, and
> - * display_stream_test_frames_mm_time_reset handles case 2.b
> - */
> -
> -/* main context */
> -static void display_session_mm_time_reset_cb(SpiceSession *session, gpointer
> data)
> -{
> -    SpiceChannel *channel = data;
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    guint i;
> -
> -    CHANNEL_DEBUG(channel, "%s", __FUNCTION__);
> -
> -    for (i = 0; i < c->nstreams; i++) {
> -        display_stream *st;
> -
> -        if (c->streams[i] == NULL) {
> -            continue;
> -        }
> -        SPICE_DEBUG("%s: stream-id %d", __FUNCTION__, i);
> -        st = c->streams[i];
> -        display_stream_reset_rendering_timer(st);
> -    }
> -}
> -
> -/* coroutine context */
> -static void display_stream_test_frames_mm_time_reset(display_stream *st,
> -                                                     SpiceMsgIn
> *new_frame_msg,
> -                                                     guint32 mm_time)
> -{
> -    SpiceStreamDataHeader *tail_op, *new_op;
> -    SpiceMsgIn *tail_msg;
> -
> -    SPICE_DEBUG("%s", __FUNCTION__);
> -    g_return_if_fail(new_frame_msg != NULL);
> -    tail_msg = g_queue_peek_tail(st->msgq);
> -    if (!tail_msg) {
> -        return;
> -    }
> -    tail_op = spice_msg_in_parsed(tail_msg);
> -    new_op = spice_msg_in_parsed(new_frame_msg);
> -
> -    if (new_op->multi_media_time < tail_op->multi_media_time) {
> -        SPICE_DEBUG("new-frame-time < tail-frame-time (%u < %u):"
> -                    " reseting stream, id %d",
> -                    new_op->multi_media_time,
> -                    tail_op->multi_media_time,
> -                    new_op->id);
> -        g_queue_foreach(st->msgq, _msg_in_unref_func, NULL);
> -        g_queue_clear(st->msgq);
> -        display_stream_reset_rendering_timer(st);
> -    }
> -}
> -
> -#define STREAM_PLAYBACK_SYNC_DROP_SEQ_LEN_LIMIT 5
> -
> -/* coroutine context */
> -static void display_handle_stream_data(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    SpiceStreamDataHeader *op = spice_msg_in_parsed(in);
> -    display_stream *st;
> -    guint32 mmtime;
> -    int32_t latency;
> -
> -    g_return_if_fail(c != NULL);
> -    g_return_if_fail(c->streams != NULL);
> -    g_return_if_fail(c->nstreams > op->id);
> -
> -    st =  c->streams[op->id];
> -    mmtime = spice_session_get_mm_time(spice_channel_get_session(channel));
> -
> -    if (spice_msg_in_type(in) == SPICE_MSG_DISPLAY_STREAM_DATA_SIZED) {
> -        CHANNEL_DEBUG(channel, "stream %d contains sized data", op->id);
> -    }
> -
> -    if (op->multi_media_time == 0) {
> -        g_critical("Received frame with invalid 0 timestamp! perhaps wrong
> graphic driver?");
> -        op->multi_media_time = mmtime + 100; /* workaround... */
> -    }
> -
> -    if (!st->num_input_frames) {
> -        st->first_frame_mm_time = op->multi_media_time;
> -    }
> -    st->num_input_frames++;
> -
> -    latency = op->multi_media_time - mmtime;
> -    if (latency < 0) {
> -        CHANNEL_DEBUG(channel, "stream data too late by %u ms (ts: %u,
> mmtime: %u), dropping",
> -                      mmtime - op->multi_media_time, op->multi_media_time,
> mmtime);
> -        st->arrive_late_time += mmtime - op->multi_media_time;
> -        st->num_drops_on_receive++;
> -
> -        if (!st->cur_drops_seq_stats.len) {
> -            st->cur_drops_seq_stats.start_mm_time = op->multi_media_time;
> -        }
> -        st->cur_drops_seq_stats.len++;
> -        st->playback_sync_drops_seq_len++;
> -    } else {
> -        CHANNEL_DEBUG(channel, "video latency: %d", latency);
> -        spice_msg_in_ref(in);
> -        display_stream_test_frames_mm_time_reset(st, in, mmtime);
> -        g_queue_push_tail(st->msgq, in);
> -        while (!display_stream_schedule(st)) {
> -        }
> -        if (st->cur_drops_seq_stats.len) {
> -            st->cur_drops_seq_stats.duration = op->multi_media_time -
> -
> st->cur_drops_seq_stats.start_mm_time;
> -            g_array_append_val(st->drops_seqs_stats_arr,
> st->cur_drops_seq_stats);
> -            memset(&st->cur_drops_seq_stats, 0,
> sizeof(st->cur_drops_seq_stats));
> -            st->num_drops_seqs++;
> -        }
> -        st->playback_sync_drops_seq_len = 0;
> -    }
> -    if (c->enable_adaptive_streaming) {
> -        display_update_stream_report(SPICE_DISPLAY_CHANNEL(channel), op->id,
> -                                     op->multi_media_time, latency);
> -        if (st->playback_sync_drops_seq_len >=
> STREAM_PLAYBACK_SYNC_DROP_SEQ_LEN_LIMIT) {
> -
> spice_session_sync_playback_latency(spice_channel_get_session(channel));
> -            st->playback_sync_drops_seq_len = 0;
> -        }
> -    }
> -}
> -
> -/* coroutine context */
> -static void display_handle_stream_clip(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    SpiceMsgDisplayStreamClip *op = spice_msg_in_parsed(in);
> -    display_stream *st;
> -
> -    g_return_if_fail(c != NULL);
> -    g_return_if_fail(c->streams != NULL);
> -    g_return_if_fail(c->nstreams > op->id);
> -
> -    st = c->streams[op->id];
> -
> -    if (st->msg_clip) {
> -        spice_msg_in_unref(st->msg_clip);
> -    }
> -    spice_msg_in_ref(in);
> -    st->msg_clip = in;
> -    st->clip = &op->clip;
> -    display_update_stream_region(st);
> -}
> -
> -static void _msg_in_unref_func(gpointer data, gpointer user_data)
> -{
> -    spice_msg_in_unref(data);
> -}
> -
> -static void destroy_stream(SpiceChannel *channel, int id)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    display_stream *st;
> -    guint64 drops_duration_total = 0;
> -    guint32 num_out_frames;
> -    int i;
> -
> -    g_return_if_fail(c != NULL);
> -    g_return_if_fail(c->streams != NULL);
> -    g_return_if_fail(c->nstreams > id);
> -
> -    st = c->streams[id];
> -    if (!st)
> -        return;
> -
> -    num_out_frames = st->num_input_frames - st->num_drops_on_receive -
> st->num_drops_on_playback;
> -    CHANNEL_DEBUG(channel, "%s: id=%d #in-frames=%d out/in=%.2f "
> -        "#drops-on-receive=%d avg-late-time(ms)=%.2f "
> -        "#drops-on-playback=%d", __FUNCTION__,
> -        id,
> -        st->num_input_frames,
> -        num_out_frames / (double)st->num_input_frames,
> -        st->num_drops_on_receive,
> -        st->num_drops_on_receive ? st->arrive_late_time /
> ((double)st->num_drops_on_receive): 0,
> -        st->num_drops_on_playback);
> -    if (st->num_drops_seqs) {
> -        CHANNEL_DEBUG(channel, "%s: #drops-sequences=%u ==>", __FUNCTION__,
> st->num_drops_seqs);
> -    }
> -    for (i = 0; i < st->num_drops_seqs; i++) {
> -            drops_sequence_stats *stats =
> &g_array_index(st->drops_seqs_stats_arr,
> -
> drops_sequence_stats,
> -                                                         i);
> -            drops_duration_total += stats->duration;
> -            CHANNEL_DEBUG(channel, "%s: \t len=%u start-ms=%u
> duration-ms=%u", __FUNCTION__,
> -                                   stats->len,
> -                                   stats->start_mm_time -
> st->first_frame_mm_time,
> -                                   stats->duration);
> -    }
> -    if (st->num_drops_seqs) {
> -        CHANNEL_DEBUG(channel, "%s: drops-total-duration=%"G_GUINT64_FORMAT"
> ==>", __FUNCTION__, drops_duration_total);
> -    }
> -
> -    g_array_free(st->drops_seqs_stats_arr, TRUE);
> -
> -    switch (st->codec) {
> -    case SPICE_VIDEO_CODEC_TYPE_MJPEG:
> -        stream_mjpeg_cleanup(st);
> -        break;
> -    }
> -
> -    if (st->msg_clip)
> -        spice_msg_in_unref(st->msg_clip);
> -    spice_msg_in_unref(st->msg_create);
> -
> -    g_queue_foreach(st->msgq, _msg_in_unref_func, NULL);
> -    g_queue_free(st->msgq);
> -    if (st->timeout != 0)
> -        g_source_remove(st->timeout);
> -    g_free(st);
> -    c->streams[id] = NULL;
> -}
> -
> -static void clear_streams(SpiceChannel *channel)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    int i;
> -
> -    for (i = 0; i < c->nstreams; i++) {
> -        destroy_stream(channel, i);
> -    }
> -    g_free(c->streams);
> -    c->streams = NULL;
> -    c->nstreams = 0;
> -}
> -
> -/* coroutine context */
> -static void display_handle_stream_destroy(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceMsgDisplayStreamDestroy *op = spice_msg_in_parsed(in);
> -
> -    g_return_if_fail(op != NULL);
> -    CHANNEL_DEBUG(channel, "%s: id %d", __FUNCTION__, op->id);
> -    destroy_stream(channel, op->id);
> -}
> -
> -/* coroutine context */
> -static void display_handle_stream_destroy_all(SpiceChannel *channel,
> SpiceMsgIn *in)
> -{
> -    clear_streams(channel);
> -}
> -
> -/* coroutine context */
> -static void display_handle_stream_activate_report(SpiceChannel *channel,
> SpiceMsgIn *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    SpiceMsgDisplayStreamActivateReport *op = spice_msg_in_parsed(in);
> -    display_stream *st;
> -
> -    g_return_if_fail(c != NULL);
> -    g_return_if_fail(c->streams != NULL);
> -    g_return_if_fail(c->nstreams > op->stream_id);
> -
> -    st = c->streams[op->stream_id];
> -    g_return_if_fail(st != NULL);
> -
> -    st->report_is_active = TRUE;
> -    st->report_id = op->unique_id;
> -    st->report_max_window = op->max_window_size;
> -    st->report_timeout = op->timeout_ms * 1000;
> -    st->report_start_time = 0;
> -    st->report_start_frame_time = 0;
> -    st->report_num_frames = 0;
> -    st->report_num_drops = 0;
> -    st->report_drops_seq_len = 0;
> -}
> -
> -/* ------------------------------------------------------------------ */
> -
> -/* coroutine context */
> -static void display_handle_draw_fill(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgDisplayDrawFill *op = spice_msg_in_parsed(in);
> -    DRAW(fill);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_opaque(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceMsgDisplayDrawOpaque *op = spice_msg_in_parsed(in);
> -    DRAW(opaque);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_copy(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgDisplayDrawCopy *op = spice_msg_in_parsed(in);
> -    DRAW(copy);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_blend(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgDisplayDrawBlend *op = spice_msg_in_parsed(in);
> -    DRAW(blend);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_blackness(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceMsgDisplayDrawBlackness *op = spice_msg_in_parsed(in);
> -    DRAW(blackness);
> -}
> -
> -static void display_handle_draw_whiteness(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceMsgDisplayDrawWhiteness *op = spice_msg_in_parsed(in);
> -    DRAW(whiteness);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_invers(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceMsgDisplayDrawInvers *op = spice_msg_in_parsed(in);
> -    DRAW(invers);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_rop3(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgDisplayDrawRop3 *op = spice_msg_in_parsed(in);
> -    DRAW(rop3);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_stroke(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceMsgDisplayDrawStroke *op = spice_msg_in_parsed(in);
> -    DRAW(stroke);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_text(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgDisplayDrawText *op = spice_msg_in_parsed(in);
> -    DRAW(text);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_transparent(SpiceChannel *channel,
> SpiceMsgIn *in)
> -{
> -    SpiceMsgDisplayDrawTransparent *op = spice_msg_in_parsed(in);
> -    DRAW(transparent);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_alpha_blend(SpiceChannel *channel,
> SpiceMsgIn *in)
> -{
> -    SpiceMsgDisplayDrawAlphaBlend *op = spice_msg_in_parsed(in);
> -    DRAW(alpha_blend);
> -}
> -
> -/* coroutine context */
> -static void display_handle_draw_composite(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceMsgDisplayDrawComposite *op = spice_msg_in_parsed(in);
> -    DRAW(composite);
> -}
> -
> -/* coroutine context */
> -static void display_handle_surface_create(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    SpiceMsgSurfaceCreate *create = spice_msg_in_parsed(in);
> -    display_surface *surface = g_slice_new0(display_surface);
> -
> -    surface->surface_id = create->surface_id;
> -    surface->format = create->format;
> -    surface->width  = create->width;
> -    surface->height = create->height;
> -    surface->stride = create->width * 4;
> -    surface->size   = surface->height * surface->stride;
> -
> -    if (create->flags & SPICE_SURFACE_FLAGS_PRIMARY) {
> -        SPICE_DEBUG("primary flags: %d", create->flags);
> -        surface->primary = true;
> -        create_canvas(channel, surface);
> -        if (c->mark_false_event_id != 0) {
> -            g_source_remove(c->mark_false_event_id);
> -            c->mark_false_event_id = FALSE;
> -        }
> -    } else {
> -        surface->primary = false;
> -        create_canvas(channel, surface);
> -    }
> -}
> -
> -static gboolean display_mark_false(gpointer data)
> -{
> -    SpiceChannel *channel = data;
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -
> -    c->mark = FALSE;
> -    g_signal_emit(channel, signals[SPICE_DISPLAY_MARK], 0, FALSE);
> -
> -    c->mark_false_event_id = 0;
> -    return FALSE;
> -}
> -
> -/* coroutine context */
> -static void display_handle_surface_destroy(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceMsgSurfaceDestroy *destroy = spice_msg_in_parsed(in);
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    display_surface *surface;
> -
> -    g_return_if_fail(destroy != NULL);
> -
> -    surface = find_surface(c, destroy->surface_id);
> -    if (surface == NULL) {
> -        /* this is not a problem in spicec, it happens as well and returns..
> */
> -        /* g_warn_if_reached(); */
> -        return;
> -    }
> -    if (surface->primary) {
> -        int id = spice_channel_get_channel_id(channel);
> -        CHANNEL_DEBUG(channel, "%d: FIXME primary destroy, but is display
> really disabled?", id);
> -        /* this is done with a timeout in spicec as well, it's *ugly* */
> -        if (id != 0 && c->mark_false_event_id == 0) {
> -            c->mark_false_event_id = g_timeout_add_seconds(1,
> display_mark_false, channel);
> -        }
> -        c->primary = NULL;
> -        g_coroutine_signal_emit(channel,
> signals[SPICE_DISPLAY_PRIMARY_DESTROY], 0);
> -    }
> -
> -    g_hash_table_remove(c->surfaces, GINT_TO_POINTER(surface->surface_id));
> -}
> -
> -#define CLAMP_CHECK(x, low, high)  (((x) > (high)) ? TRUE : (((x) < (low)) ?
> TRUE : FALSE))
> -
> -/* coroutine context */
> -static void display_handle_monitors_config(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    SpiceMsgDisplayMonitorsConfig *config = spice_msg_in_parsed(in);
> -    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    guint i;
> -
> -    g_return_if_fail(config != NULL);
> -    g_return_if_fail(config->count > 0);
> -
> -    CHANNEL_DEBUG(channel, "monitors config: n: %d/%d", config->count,
> config->max_allowed);
> -
> -    c->monitors_max = config->max_allowed;
> -    if (CLAMP_CHECK(c->monitors_max, 1, MONITORS_MAX)) {
> -        g_warning("MonitorConfig max_allowed is not within permitted range,
> clamping");
> -        c->monitors_max = CLAMP(c->monitors_max, 1, MONITORS_MAX);
> -    }
> -
> -    if (CLAMP_CHECK(config->count, 1, c->monitors_max)) {
> -        g_warning("MonitorConfig count is not within permitted range,
> clamping");
> -        config->count = CLAMP(config->count, 1, c->monitors_max);
> -    }
> -
> -    c->monitors = g_array_set_size(c->monitors, config->count);
> -
> -    for (i = 0; i < config->count; i++) {
> -        SpiceDisplayMonitorConfig *mc = &g_array_index(c->monitors,
> SpiceDisplayMonitorConfig, i);
> -        SpiceHead *head = &config->heads[i];
> -        CHANNEL_DEBUG(channel, "monitor id: %u, surface id: %u,
> +%u+%u-%ux%u",
> -                    head->id, head->surface_id,
> -                    head->x, head->y, head->width, head->height);
> -        mc->id = head->id;
> -        mc->surface_id = head->surface_id;
> -        mc->x = head->x;
> -        mc->y = head->y;
> -        mc->width = head->width;
> -        mc->height = head->height;
> -    }
> -
> -    g_coroutine_object_notify(G_OBJECT(channel), "monitors");
> -}
> -
> -static void channel_set_handlers(SpiceChannelClass *klass)
> -{
> -    static const spice_msg_handler handlers[] = {
> -        [ SPICE_MSG_DISPLAY_MODE ]               = display_handle_mode,
> -        [ SPICE_MSG_DISPLAY_MARK ]               = display_handle_mark,
> -        [ SPICE_MSG_DISPLAY_RESET ]              = display_handle_reset,
> -        [ SPICE_MSG_DISPLAY_COPY_BITS ]          = display_handle_copy_bits,
> -        [ SPICE_MSG_DISPLAY_INVAL_LIST ]         = display_handle_inv_list,
> -        [ SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS ]  =
> display_handle_inv_pixmap_all,
> -        [ SPICE_MSG_DISPLAY_INVAL_PALETTE ]      =
> display_handle_inv_palette,
> -        [ SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES ] =
> display_handle_inv_palette_all,
> -
> -        [ SPICE_MSG_DISPLAY_STREAM_CREATE ]      =
> display_handle_stream_create,
> -        [ SPICE_MSG_DISPLAY_STREAM_DATA ]        =
> display_handle_stream_data,
> -        [ SPICE_MSG_DISPLAY_STREAM_CLIP ]        =
> display_handle_stream_clip,
> -        [ SPICE_MSG_DISPLAY_STREAM_DESTROY ]     =
> display_handle_stream_destroy,
> -        [ SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL ] =
> display_handle_stream_destroy_all,
> -        [ SPICE_MSG_DISPLAY_STREAM_DATA_SIZED ]  =
> display_handle_stream_data,
> -        [ SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT ] =
> display_handle_stream_activate_report,
> -
> -        [ SPICE_MSG_DISPLAY_DRAW_FILL ]          = display_handle_draw_fill,
> -        [ SPICE_MSG_DISPLAY_DRAW_OPAQUE ]        =
> display_handle_draw_opaque,
> -        [ SPICE_MSG_DISPLAY_DRAW_COPY ]          = display_handle_draw_copy,
> -        [ SPICE_MSG_DISPLAY_DRAW_BLEND ]         =
> display_handle_draw_blend,
> -        [ SPICE_MSG_DISPLAY_DRAW_BLACKNESS ]     =
> display_handle_draw_blackness,
> -        [ SPICE_MSG_DISPLAY_DRAW_WHITENESS ]     =
> display_handle_draw_whiteness,
> -        [ SPICE_MSG_DISPLAY_DRAW_INVERS ]        =
> display_handle_draw_invers,
> -        [ SPICE_MSG_DISPLAY_DRAW_ROP3 ]          = display_handle_draw_rop3,
> -        [ SPICE_MSG_DISPLAY_DRAW_STROKE ]        =
> display_handle_draw_stroke,
> -        [ SPICE_MSG_DISPLAY_DRAW_TEXT ]          = display_handle_draw_text,
> -        [ SPICE_MSG_DISPLAY_DRAW_TRANSPARENT ]   =
> display_handle_draw_transparent,
> -        [ SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND ]   =
> display_handle_draw_alpha_blend,
> -        [ SPICE_MSG_DISPLAY_DRAW_COMPOSITE ]     =
> display_handle_draw_composite,
> -
> -        [ SPICE_MSG_DISPLAY_SURFACE_CREATE ]     =
> display_handle_surface_create,
> -        [ SPICE_MSG_DISPLAY_SURFACE_DESTROY ]    =
> display_handle_surface_destroy,
> -
> -        [ SPICE_MSG_DISPLAY_MONITORS_CONFIG ]    =
> display_handle_monitors_config,
> -    };
> -
> -    spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
> -}
> diff --git a/gtk/channel-display.h b/gtk/channel-display.h
> deleted file mode 100644
> index 88e60d9..0000000
> --- a/gtk/channel-display.h
> +++ /dev/null
> @@ -1,102 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2010 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#ifndef __SPICE_CLIENT_DISPLAY_CHANNEL_H__
> -#define __SPICE_CLIENT_DISPLAY_CHANNEL_H__
> -
> -#include "spice-client.h"
> -
> -G_BEGIN_DECLS
> -
> -#define SPICE_TYPE_DISPLAY_CHANNEL
> (spice_display_channel_get_type())
> -#define SPICE_DISPLAY_CHANNEL(obj)
> (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_DISPLAY_CHANNEL,
> SpiceDisplayChannel))
> -#define SPICE_DISPLAY_CHANNEL_CLASS(klass)
> (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_DISPLAY_CHANNEL,
> SpiceDisplayChannelClass))
> -#define SPICE_IS_DISPLAY_CHANNEL(obj)
> (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_DISPLAY_CHANNEL))
> -#define SPICE_IS_DISPLAY_CHANNEL_CLASS(klass)
> (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_DISPLAY_CHANNEL))
> -#define SPICE_DISPLAY_CHANNEL_GET_CLASS(obj)
> (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_DISPLAY_CHANNEL,
> SpiceDisplayChannelClass))
> -
> -typedef struct _SpiceDisplayChannel SpiceDisplayChannel;
> -typedef struct _SpiceDisplayChannelClass SpiceDisplayChannelClass;
> -typedef struct _SpiceDisplayChannelPrivate SpiceDisplayChannelPrivate;
> -
> -typedef struct _SpiceDisplayMonitorConfig SpiceDisplayMonitorConfig;
> -struct _SpiceDisplayMonitorConfig {
> -    guint id;
> -    guint surface_id;
> -    guint x;
> -    guint y;
> -    guint width;
> -    guint height;
> -};
> -
> -typedef struct _SpiceDisplayPrimary SpiceDisplayPrimary;
> -struct _SpiceDisplayPrimary {
> -    enum SpiceSurfaceFmt format;
> -    gint width;
> -    gint height;
> -    gint stride;
> -    gint shmid;
> -    guint8 *data;
> -    gboolean marked;
> -};
> -
> -/**
> - * SpiceDisplayChannel:
> - *
> - * The #SpiceDisplayChannel struct is opaque and should not be accessed
> directly.
> - */
> -struct _SpiceDisplayChannel {
> -    SpiceChannel parent;
> -
> -    /*< private >*/
> -    SpiceDisplayChannelPrivate *priv;
> -    /* Do not add fields to this struct */
> -};
> -
> -/**
> - * SpiceDisplayChannelClass:
> - * @parent_class: Parent class.
> - * @display_primary_create: Signal class handler for the
> #SpiceDisplayChannel::display-primary-create signal.
> - * @display_primary_destroy: Signal class handler for the
> #SpiceDisplayChannel::display-primary-destroy signal.
> - * @display_invalidate: Signal class handler for the
> #SpiceDisplayChannel::display-invalidate signal.
> - * @display_mark: Signal class handler for the
> #SpiceDisplayChannel::display-mark signal.
> - *
> - * Class structure for #SpiceDisplayChannel.
> - */
> -struct _SpiceDisplayChannelClass {
> -    SpiceChannelClass parent_class;
> -
> -    /* signals */
> -    void (*display_primary_create)(SpiceChannel *channel, gint format,
> -                                   gint width, gint height, gint stride,
> -                                   gint shmid, gpointer data);
> -    void (*display_primary_destroy)(SpiceChannel *channel);
> -    void (*display_invalidate)(SpiceChannel *channel,
> -                               gint x, gint y, gint w, gint h);
> -    void (*display_mark)(SpiceChannel *channel,
> -                         gboolean mark);
> -
> -    /*< private >*/
> -};
> -
> -GType	        spice_display_channel_get_type(void);
> -gboolean        spice_display_get_primary(SpiceChannel *channel, guint32
> surface_id,
> -                                          SpiceDisplayPrimary *primary);
> -
> -G_END_DECLS
> -
> -#endif /* __SPICE_CLIENT_DISPLAY_CHANNEL_H__ */
> diff --git a/gtk/channel-inputs.c b/gtk/channel-inputs.c
> deleted file mode 100644
> index df1ffe1..0000000
> --- a/gtk/channel-inputs.c
> +++ /dev/null
> @@ -1,603 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2010 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#include "config.h"
> -
> -#include "spice-client.h"
> -#include "spice-common.h"
> -#include "spice-channel-priv.h"
> -
> -/**
> - * SECTION:channel-inputs
> - * @short_description: control the server mouse and keyboard
> - * @title: Inputs Channel
> - * @section_id:
> - * @see_also: #SpiceChannel, and the GTK widget #SpiceDisplay
> - * @stability: Stable
> - * @include: channel-inputs.h
> - *
> - * Spice supports sending keyboard key events and keyboard leds
> - * synchronization. The key events are sent using
> - * spice_inputs_key_press() and spice_inputs_key_release() using
> - * a modified variant of PC XT scancodes.
> - *
> - * Guest keyboard leds state can be manipulated with
> - * spice_inputs_set_key_locks(). When key lock change, a notification
> - * is emitted with #SpiceInputsChannel::inputs-modifiers signal.
> - */
> -
> -#define SPICE_INPUTS_CHANNEL_GET_PRIVATE(obj)
> \
> -    (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_INPUTS_CHANNEL,
> SpiceInputsChannelPrivate))
> -
> -struct _SpiceInputsChannelPrivate {
> -    int                         bs;
> -    int                         dx, dy;
> -    unsigned int                x, y, dpy;
> -    int                         motion_count;
> -    int                         modifiers;
> -    guint32                     locks;
> -};
> -
> -G_DEFINE_TYPE(SpiceInputsChannel, spice_inputs_channel, SPICE_TYPE_CHANNEL)
> -
> -/* Properties */
> -enum {
> -    PROP_0,
> -    PROP_KEY_MODIFIERS,
> -};
> -
> -/* Signals */
> -enum {
> -    SPICE_INPUTS_MODIFIERS,
> -
> -    SPICE_INPUTS_LAST_SIGNAL,
> -};
> -
> -static guint signals[SPICE_INPUTS_LAST_SIGNAL];
> -
> -static void spice_inputs_channel_up(SpiceChannel *channel);
> -static void spice_inputs_channel_reset(SpiceChannel *channel, gboolean
> migrating);
> -static void channel_set_handlers(SpiceChannelClass *klass);
> -
> -/* ------------------------------------------------------------------ */
> -
> -static void spice_inputs_channel_init(SpiceInputsChannel *channel)
> -{
> -    channel->priv = SPICE_INPUTS_CHANNEL_GET_PRIVATE(channel);
> -}
> -
> -static void spice_inputs_get_property(GObject    *object,
> -                                      guint       prop_id,
> -                                      GValue     *value,
> -                                      GParamSpec *pspec)
> -{
> -    SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(object)->priv;
> -
> -    switch (prop_id) {
> -    case PROP_KEY_MODIFIERS:
> -        g_value_set_int(value, c->modifiers);
> -        break;
> -    default:
> -        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
> -        break;
> -    }
> -}
> -
> -static void spice_inputs_channel_finalize(GObject *obj)
> -{
> -    if (G_OBJECT_CLASS(spice_inputs_channel_parent_class)->finalize)
> -        G_OBJECT_CLASS(spice_inputs_channel_parent_class)->finalize(obj);
> -}
> -
> -static void spice_inputs_channel_class_init(SpiceInputsChannelClass *klass)
> -{
> -    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
> -    SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
> -
> -    gobject_class->finalize     = spice_inputs_channel_finalize;
> -    gobject_class->get_property = spice_inputs_get_property;
> -    channel_class->channel_up   = spice_inputs_channel_up;
> -    channel_class->channel_reset = spice_inputs_channel_reset;
> -
> -    g_object_class_install_property
> -        (gobject_class, PROP_KEY_MODIFIERS,
> -         g_param_spec_int("key-modifiers",
> -                          "Key modifiers",
> -                          "Guest keyboard lock/led state",
> -                          0, INT_MAX, 0,
> -                          G_PARAM_READABLE |
> -                          G_PARAM_STATIC_NAME |
> -                          G_PARAM_STATIC_NICK |
> -                          G_PARAM_STATIC_BLURB));
> -
> -    /**
> -     * SpiceInputsChannel::inputs-modifier:
> -     * @display: the #SpiceInputsChannel that emitted the signal
> -     *
> -     * The #SpiceInputsChannel::inputs-modifier signal is emitted when
> -     * the guest keyboard locks are changed. You can read the current
> -     * state from #SpiceInputsChannel:key-modifiers property.
> -     **/
> -    /* TODO: use notify instead? */
> -    signals[SPICE_INPUTS_MODIFIERS] =
> -        g_signal_new("inputs-modifiers",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceInputsChannelClass,
> inputs_modifiers),
> -                     NULL, NULL,
> -                     g_cclosure_marshal_VOID__VOID,
> -                     G_TYPE_NONE,
> -                     0);
> -
> -    g_type_class_add_private(klass, sizeof(SpiceInputsChannelPrivate));
> -    channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
> -}
> -
> -/* ------------------------------------------------------------------ */
> -
> -static SpiceMsgOut* mouse_motion(SpiceInputsChannel *channel)
> -{
> -    SpiceInputsChannelPrivate *c = channel->priv;
> -    SpiceMsgcMouseMotion motion;
> -    SpiceMsgOut *msg;
> -
> -    if (!c->dx && !c->dy)
> -        return NULL;
> -
> -    motion.buttons_state = c->bs;
> -    motion.dx            = c->dx;
> -    motion.dy            = c->dy;
> -    msg = spice_msg_out_new(SPICE_CHANNEL(channel),
> -                            SPICE_MSGC_INPUTS_MOUSE_MOTION);
> -    msg->marshallers->msgc_inputs_mouse_motion(msg->marshaller, &motion);
> -
> -    c->motion_count++;
> -    c->dx = 0;
> -    c->dy = 0;
> -
> -    return msg;
> -}
> -
> -static SpiceMsgOut* mouse_position(SpiceInputsChannel *channel)
> -{
> -    SpiceInputsChannelPrivate *c = channel->priv;
> -    SpiceMsgcMousePosition position;
> -    SpiceMsgOut *msg;
> -
> -    if (c->dpy == -1)
> -        return NULL;
> -
> -    /* CHANNEL_DEBUG(channel, "%s: +%d+%d", __FUNCTION__, c->x, c->y); */
> -    position.buttons_state = c->bs;
> -    position.x             = c->x;
> -    position.y             = c->y;
> -    position.display_id    = c->dpy;
> -    msg = spice_msg_out_new(SPICE_CHANNEL(channel),
> -                            SPICE_MSGC_INPUTS_MOUSE_POSITION);
> -    msg->marshallers->msgc_inputs_mouse_position(msg->marshaller,
> &position);
> -
> -    c->motion_count++;
> -    c->dpy = -1;
> -
> -    return msg;
> -}
> -
> -/* main context */
> -static void send_position(SpiceInputsChannel *channel)
> -{
> -    SpiceMsgOut *msg;
> -
> -    if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
> -        return;
> -
> -    msg = mouse_position(channel);
> -    if (!msg) /* if no motion */
> -        return;
> -
> -    spice_msg_out_send(msg);
> -}
> -
> -/* main context */
> -static void send_motion(SpiceInputsChannel *channel)
> -{
> -    SpiceMsgOut *msg;
> -
> -    if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
> -        return;
> -
> -    msg = mouse_motion(channel);
> -    if (!msg) /* if no motion */
> -        return;
> -
> -    spice_msg_out_send(msg);
> -}
> -
> -/* coroutine context */
> -static void inputs_handle_init(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
> -    SpiceMsgInputsInit *init = spice_msg_in_parsed(in);
> -
> -    c->modifiers = init->keyboard_modifiers;
> -    g_coroutine_signal_emit(channel, signals[SPICE_INPUTS_MODIFIERS], 0);
> -}
> -
> -/* coroutine context */
> -static void inputs_handle_modifiers(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
> -    SpiceMsgInputsKeyModifiers *modifiers = spice_msg_in_parsed(in);
> -
> -    c->modifiers = modifiers->modifiers;
> -    g_coroutine_signal_emit(channel, signals[SPICE_INPUTS_MODIFIERS], 0);
> -}
> -
> -/* coroutine context */
> -static void inputs_handle_ack(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
> -    SpiceMsgOut *msg;
> -
> -    c->motion_count -= SPICE_INPUT_MOTION_ACK_BUNCH;
> -
> -    msg = mouse_motion(SPICE_INPUTS_CHANNEL(channel));
> -    if (msg) { /* if no motion, msg == NULL */
> -        spice_msg_out_send_internal(msg);
> -    }
> -
> -    msg = mouse_position(SPICE_INPUTS_CHANNEL(channel));
> -    if (msg) {
> -        spice_msg_out_send_internal(msg);
> -    }
> -}
> -
> -static void channel_set_handlers(SpiceChannelClass *klass)
> -{
> -    static const spice_msg_handler handlers[] = {
> -        [ SPICE_MSG_INPUTS_INIT ]              = inputs_handle_init,
> -        [ SPICE_MSG_INPUTS_KEY_MODIFIERS ]     = inputs_handle_modifiers,
> -        [ SPICE_MSG_INPUTS_MOUSE_MOTION_ACK ]  = inputs_handle_ack,
> -    };
> -
> -    spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
> -}
> -
> -/**
> - * spice_inputs_motion:
> - * @channel:
> - * @dx: delta X mouse coordinates
> - * @dy: delta Y mouse coordinates
> - * @button_state: SPICE_MOUSE_BUTTON_MASK flags
> - *
> - * Change mouse position (used in SPICE_MOUSE_MODE_CLIENT).
> - **/
> -void spice_inputs_motion(SpiceInputsChannel *channel, gint dx, gint dy,
> -                         gint button_state)
> -{
> -    SpiceInputsChannelPrivate *c;
> -
> -    g_return_if_fail(channel != NULL);
> -    g_return_if_fail(SPICE_CHANNEL(channel)->priv->state !=
> SPICE_CHANNEL_STATE_UNCONNECTED);
> -    if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
> -        return;
> -
> -    if (dx == 0 && dy == 0)
> -        return;
> -
> -    c = channel->priv;
> -    c->bs  = button_state;
> -    c->dx += dx;
> -    c->dy += dy;
> -
> -    if (c->motion_count < SPICE_INPUT_MOTION_ACK_BUNCH * 2) {
> -        send_motion(channel);
> -    }
> -}
> -
> -/**
> - * spice_inputs_position:
> - * @channel:
> - * @x: X mouse coordinates
> - * @y: Y mouse coordinates
> - * @display: display channel id
> - * @button_state: SPICE_MOUSE_BUTTON_MASK flags
> - *
> - * Change mouse position (used in SPICE_MOUSE_MODE_CLIENT).
> - **/
> -void spice_inputs_position(SpiceInputsChannel *channel, gint x, gint y,
> -                           gint display, gint button_state)
> -{
> -    SpiceInputsChannelPrivate *c;
> -
> -    g_return_if_fail(channel != NULL);
> -
> -    if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
> -        return;
> -
> -    c = channel->priv;
> -    c->bs  = button_state;
> -    c->x   = x;
> -    c->y   = y;
> -    c->dpy = display;
> -
> -    if (c->motion_count < SPICE_INPUT_MOTION_ACK_BUNCH * 2) {
> -        send_position(channel);
> -    } else {
> -        CHANNEL_DEBUG(channel, "over SPICE_INPUT_MOTION_ACK_BUNCH * 2,
> dropping");
> -    }
> -}
> -
> -/**
> - * spice_inputs_button_press:
> - * @channel:
> - * @button: a SPICE_MOUSE_BUTTON
> - * @button_state: SPICE_MOUSE_BUTTON_MASK flags
> - *
> - * Press a mouse button.
> - **/
> -void spice_inputs_button_press(SpiceInputsChannel *channel, gint button,
> -                               gint button_state)
> -{
> -    SpiceInputsChannelPrivate *c;
> -    SpiceMsgcMousePress press;
> -    SpiceMsgOut *msg;
> -
> -    g_return_if_fail(channel != NULL);
> -
> -    if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
> -        return;
> -    if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
> -        return;
> -
> -    c = channel->priv;
> -    switch (button) {
> -    case SPICE_MOUSE_BUTTON_LEFT:
> -        button_state |= SPICE_MOUSE_BUTTON_MASK_LEFT;
> -        break;
> -    case SPICE_MOUSE_BUTTON_MIDDLE:
> -        button_state |= SPICE_MOUSE_BUTTON_MASK_MIDDLE;
> -        break;
> -    case SPICE_MOUSE_BUTTON_RIGHT:
> -        button_state |= SPICE_MOUSE_BUTTON_MASK_RIGHT;
> -        break;
> -    }
> -
> -    c->bs  = button_state;
> -    send_motion(channel);
> -    send_position(channel);
> -
> -    msg = spice_msg_out_new(SPICE_CHANNEL(channel),
> -                            SPICE_MSGC_INPUTS_MOUSE_PRESS);
> -    press.button = button;
> -    press.buttons_state = button_state;
> -    msg->marshallers->msgc_inputs_mouse_press(msg->marshaller, &press);
> -    spice_msg_out_send(msg);
> -}
> -
> -/**
> - * spice_inputs_button_release:
> - * @channel:
> - * @button: a SPICE_MOUSE_BUTTON
> - * @button_state: SPICE_MOUSE_BUTTON_MASK flags
> - *
> - * Release a button.
> - **/
> -void spice_inputs_button_release(SpiceInputsChannel *channel, gint button,
> -                                 gint button_state)
> -{
> -    SpiceInputsChannelPrivate *c;
> -    SpiceMsgcMouseRelease release;
> -    SpiceMsgOut *msg;
> -
> -    g_return_if_fail(channel != NULL);
> -
> -    if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
> -        return;
> -    if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
> -        return;
> -
> -    c = channel->priv;
> -    switch (button) {
> -    case SPICE_MOUSE_BUTTON_LEFT:
> -        button_state &= ~SPICE_MOUSE_BUTTON_MASK_LEFT;
> -        break;
> -    case SPICE_MOUSE_BUTTON_MIDDLE:
> -        button_state &= ~SPICE_MOUSE_BUTTON_MASK_MIDDLE;
> -        break;
> -    case SPICE_MOUSE_BUTTON_RIGHT:
> -        button_state &= ~SPICE_MOUSE_BUTTON_MASK_RIGHT;
> -        break;
> -    }
> -
> -    c->bs = button_state;
> -    send_motion(channel);
> -    send_position(channel);
> -
> -    msg = spice_msg_out_new(SPICE_CHANNEL(channel),
> -                            SPICE_MSGC_INPUTS_MOUSE_RELEASE);
> -    release.button = button;
> -    release.buttons_state = button_state;
> -    msg->marshallers->msgc_inputs_mouse_release(msg->marshaller, &release);
> -    spice_msg_out_send(msg);
> -}
> -
> -/**
> - * spice_inputs_key_press:
> - * @channel:
> - * @scancode: a PC XT (set 1) key scancode.  For scancodes with an %0xe0
> - *            prefix, drop the prefix and OR the scancode with %0x100.
> - *
> - * Press a key.
> - **/
> -void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode)
> -{
> -    SpiceMsgcKeyDown down;
> -    SpiceMsgOut *msg;
> -
> -    g_return_if_fail(channel != NULL);
> -    g_return_if_fail(SPICE_CHANNEL(channel)->priv->state !=
> SPICE_CHANNEL_STATE_UNCONNECTED);
> -    if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
> -        return;
> -    if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
> -        return;
> -
> -    down.code = spice_make_scancode(scancode, FALSE);
> -    msg = spice_msg_out_new(SPICE_CHANNEL(channel),
> SPICE_MSGC_INPUTS_KEY_DOWN);
> -    msg->marshallers->msgc_inputs_key_down(msg->marshaller, &down);
> -    spice_msg_out_send(msg);
> -}
> -
> -/**
> - * spice_inputs_key_release:
> - * @channel:
> - * @scancode: a PC XT (set 1) key scancode.  For scancodes with an %0xe0
> - *            prefix, drop the prefix and OR the scancode with %0x100.
> - *
> - * Release a key.
> - **/
> -void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode)
> -{
> -    SpiceMsgcKeyUp up;
> -    SpiceMsgOut *msg;
> -
> -    g_return_if_fail(channel != NULL);
> -    g_return_if_fail(SPICE_CHANNEL(channel)->priv->state !=
> SPICE_CHANNEL_STATE_UNCONNECTED);
> -    if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
> -        return;
> -    if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
> -        return;
> -
> -    up.code = spice_make_scancode(scancode, TRUE);
> -    msg = spice_msg_out_new(SPICE_CHANNEL(channel),
> SPICE_MSGC_INPUTS_KEY_UP);
> -    msg->marshallers->msgc_inputs_key_up(msg->marshaller, &up);
> -    spice_msg_out_send(msg);
> -}
> -
> -/**
> - * spice_inputs_key_press_and_release:
> - * @channel:
> - * @scancode: a PC XT (set 1) key scancode.  For scancodes with an %0xe0
> - *            prefix, drop the prefix and OR the scancode with %0x100.
> - *
> - * Press and release a key event atomically (in the same message).
> - *
> - * Since: 0.13
> - **/
> -void spice_inputs_key_press_and_release(SpiceInputsChannel *input_channel,
> guint scancode)
> -{
> -    SpiceChannel *channel = SPICE_CHANNEL(input_channel);
> -
> -    g_return_if_fail(channel != NULL);
> -    g_return_if_fail(channel->priv->state !=
> SPICE_CHANNEL_STATE_UNCONNECTED);
> -
> -    if (channel->priv->state != SPICE_CHANNEL_STATE_READY)
> -        return;
> -    if (spice_channel_get_read_only(channel))
> -        return;
> -
> -    if (spice_channel_test_capability(channel,
> SPICE_INPUTS_CAP_KEY_SCANCODE)) {
> -        SpiceMsgOut *msg;
> -        guint16 code;
> -        guint8 *buf;
> -
> -        msg = spice_msg_out_new(channel, SPICE_MSGC_INPUTS_KEY_SCANCODE);
> -        if (scancode < 0x100) {
> -            buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller,
> 2);
> -            buf[0] = spice_make_scancode(scancode, FALSE);
> -            buf[1] = spice_make_scancode(scancode, TRUE);
> -        } else {
> -            buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller,
> 4);
> -            code = spice_make_scancode(scancode, FALSE);
> -            buf[0] = code & 0xff;
> -            buf[1] = code >> 8;
> -            code = spice_make_scancode(scancode, TRUE);
> -            buf[2] = code & 0xff;
> -            buf[3] = code >> 8;
> -        }
> -        spice_msg_out_send(msg);
> -    } else {
> -        CHANNEL_DEBUG(channel, "The server doesn't support atomic press and
> release");
> -        spice_inputs_key_press(input_channel, scancode);
> -        spice_inputs_key_release(input_channel, scancode);
> -    }
> -}
> -
> -/* main or coroutine context */
> -static SpiceMsgOut* set_key_locks(SpiceInputsChannel *channel, guint locks)
> -{
> -    SpiceMsgcKeyModifiers modifiers;
> -    SpiceMsgOut *msg;
> -    SpiceInputsChannelPrivate *ic;
> -    SpiceChannelPrivate *c;
> -
> -    g_return_val_if_fail(SPICE_IS_INPUTS_CHANNEL(channel), NULL);
> -
> -    ic = channel->priv;
> -    c = SPICE_CHANNEL(channel)->priv;
> -
> -    ic->locks = locks;
> -    if (c->state != SPICE_CHANNEL_STATE_READY)
> -        return NULL;
> -
> -    msg = spice_msg_out_new(SPICE_CHANNEL(channel),
> -                            SPICE_MSGC_INPUTS_KEY_MODIFIERS);
> -    modifiers.modifiers = locks;
> -    msg->marshallers->msgc_inputs_key_modifiers(msg->marshaller,
> &modifiers);
> -    return msg;
> -}
> -
> -/**
> - * spice_inputs_set_key_locks:
> - * @channel:
> - * @locks: #SpiceInputsLock modifiers flags
> - *
> - * Set the keyboard locks on the guest (Caps, Num, Scroll..)
> - **/
> -void spice_inputs_set_key_locks(SpiceInputsChannel *channel, guint locks)
> -{
> -    SpiceMsgOut *msg;
> -
> -    if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
> -        return;
> -
> -    msg = set_key_locks(channel, locks);
> -    if (!msg) /* you can set_key_locks() even if the channel is not ready */
> -        return;
> -
> -    spice_msg_out_send(msg); /* main -> coroutine */
> -}
> -
> -/* coroutine context */
> -static void spice_inputs_channel_up(SpiceChannel *channel)
> -{
> -    SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
> -    SpiceMsgOut *msg;
> -
> -    if (spice_channel_get_read_only(channel))
> -        return;
> -
> -    msg = set_key_locks(SPICE_INPUTS_CHANNEL(channel), c->locks);
> -    spice_msg_out_send_internal(msg);
> -}
> -
> -static void spice_inputs_channel_reset(SpiceChannel *channel, gboolean
> migrating)
> -{
> -    SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
> -    c->motion_count = 0;
> -
> -
> SPICE_CHANNEL_CLASS(spice_inputs_channel_parent_class)->channel_reset(channel,
> migrating);
> -}
> diff --git a/gtk/channel-inputs.h b/gtk/channel-inputs.h
> deleted file mode 100644
> index 3179a76..0000000
> --- a/gtk/channel-inputs.h
> +++ /dev/null
> @@ -1,89 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2010 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#ifndef __SPICE_CLIENT_INPUTS_CHANNEL_H__
> -#define __SPICE_CLIENT_INPUTS_CHANNEL_H__
> -
> -#include "spice-client.h"
> -
> -G_BEGIN_DECLS
> -
> -#define SPICE_TYPE_INPUTS_CHANNEL
> (spice_inputs_channel_get_type())
> -#define SPICE_INPUTS_CHANNEL(obj)
> (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_INPUTS_CHANNEL,
> SpiceInputsChannel))
> -#define SPICE_INPUTS_CHANNEL_CLASS(klass)
> (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_INPUTS_CHANNEL,
> SpiceInputsChannelClass))
> -#define SPICE_IS_INPUTS_CHANNEL(obj)
> (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_INPUTS_CHANNEL))
> -#define SPICE_IS_INPUTS_CHANNEL_CLASS(klass)
> (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_INPUTS_CHANNEL))
> -#define SPICE_INPUTS_CHANNEL_GET_CLASS(obj)
> (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_INPUTS_CHANNEL,
> SpiceInputsChannelClass))
> -
> -typedef struct _SpiceInputsChannel SpiceInputsChannel;
> -typedef struct _SpiceInputsChannelClass SpiceInputsChannelClass;
> -typedef struct _SpiceInputsChannelPrivate SpiceInputsChannelPrivate;
> -
> -typedef enum {
> -    SPICE_INPUTS_SCROLL_LOCK = (1 << 0),
> -    SPICE_INPUTS_NUM_LOCK    = (1 << 1),
> -    SPICE_INPUTS_CAPS_LOCK   = (1 << 2)
> -} SpiceInputsLock;
> -
> -/**
> - * SpiceInputsChannel:
> - *
> - * The #SpiceInputsChannel struct is opaque and should not be accessed
> directly.
> - */
> -struct _SpiceInputsChannel {
> -    SpiceChannel parent;
> -
> -    /*< private >*/
> -    SpiceInputsChannelPrivate *priv;
> -    /* Do not add fields to this struct */
> -};
> -
> -/**
> - * SpiceInputsChannelClass:
> - * @parent_class: Parent class.
> - * @inputs_modifiers: Signal class handler for the
> #SpiceInputsChannel::inputs-modifiers signal.
> - *
> - * Class structure for #SpiceInputsChannel.
> - */
> -struct _SpiceInputsChannelClass {
> -    SpiceChannelClass parent_class;
> -
> -    /* signals */
> -    void (*inputs_modifiers)(SpiceChannel *channel);
> -
> -    /*< private >*/
> -    /* Do not add fields to this struct */
> -};
> -
> -GType spice_inputs_channel_get_type(void);
> -
> -void spice_inputs_motion(SpiceInputsChannel *channel, gint dx, gint dy,
> -                         gint button_state);
> -void spice_inputs_position(SpiceInputsChannel *channel, gint x, gint y,
> -                           gint display, gint button_state);
> -void spice_inputs_button_press(SpiceInputsChannel *channel, gint button,
> -                               gint button_state);
> -void spice_inputs_button_release(SpiceInputsChannel *channel, gint button,
> -                                 gint button_state);
> -void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode);
> -void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode);
> -void spice_inputs_set_key_locks(SpiceInputsChannel *channel, guint locks);
> -void spice_inputs_key_press_and_release(SpiceInputsChannel *channel, guint
> scancode);
> -
> -G_END_DECLS
> -
> -#endif /* __SPICE_CLIENT_INPUTS_CHANNEL_H__ */
> diff --git a/gtk/channel-main.c b/gtk/channel-main.c
> deleted file mode 100644
> index c55d097..0000000
> --- a/gtk/channel-main.c
> +++ /dev/null
> @@ -1,2993 +0,0 @@
> -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> -/*
> -   Copyright (C) 2010 Red Hat, Inc.
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> -*/
> -#include "config.h"
> -
> -#include <math.h>
> -#include <spice/vd_agent.h>
> -#include <common/rect.h>
> -#include <glib/gstdio.h>
> -
> -#include "glib-compat.h"
> -#include "spice-client.h"
> -#include "spice-common.h"
> -#include "spice-marshal.h"
> -
> -#include "spice-util-priv.h"
> -#include "spice-channel-priv.h"
> -#include "spice-session-priv.h"
> -#include "spice-audio-priv.h"
> -
> -/**
> - * SECTION:channel-main
> - * @short_description: the main Spice channel
> - * @title: Main Channel
> - * @section_id:
> - * @see_also: #SpiceChannel, and the GTK widget #SpiceDisplay
> - * @stability: Stable
> - * @include: channel-main.h
> - *
> - * The main channel is the Spice session control channel. It handles
> - * communication initialization (channels list), migrations, mouse
> - * modes, multimedia time, and agent communication.
> - *
> - *
> - */
> -
> -#define SPICE_MAIN_CHANNEL_GET_PRIVATE(obj)                             \
> -    (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_MAIN_CHANNEL,
> SpiceMainChannelPrivate))
> -
> -#define MAX_DISPLAY 16 /* Note must fit in a guint32, see monitors_align */
> -
> -typedef struct spice_migrate spice_migrate;
> -
> -#define FILE_XFER_CHUNK_SIZE (VD_AGENT_MAX_DATA_SIZE * 32)
> -typedef struct SpiceFileXferTask {
> -    uint32_t                       id;
> -    gboolean                       pending;
> -    GFile                          *file;
> -    SpiceMainChannel               *channel;
> -    GFileInputStream               *file_stream;
> -    GFileCopyFlags                 flags;
> -    GCancellable                   *cancellable;
> -    GFileProgressCallback          progress_callback;
> -    gpointer                       progress_callback_data;
> -    GAsyncReadyCallback            callback;
> -    gpointer                       user_data;
> -    char                           buffer[FILE_XFER_CHUNK_SIZE];
> -    uint64_t                       read_bytes;
> -    uint64_t                       file_size;
> -    GError                         *error;
> -} SpiceFileXferTask;
> -
> -struct _SpiceMainChannelPrivate  {
> -    enum SpiceMouseMode         mouse_mode;
> -    bool                        agent_connected;
> -    bool                        agent_caps_received;
> -
> -    gboolean                    agent_display_config_sent;
> -    guint8                      display_color_depth;
> -    gboolean                    display_disable_wallpaper:1;
> -    gboolean                    display_disable_font_smooth:1;
> -    gboolean                    display_disable_animation:1;
> -    gboolean                    disable_display_position:1;
> -    gboolean                    disable_display_align:1;
> -
> -    int                         agent_tokens;
> -    VDAgentMessage              agent_msg; /* partial msg reconstruction */
> -    guint8                      *agent_msg_data;
> -    guint                       agent_msg_pos;
> -    uint8_t                     agent_msg_size;
> -    uint32_t                    agent_caps[VD_AGENT_CAPS_SIZE];
> -    struct {
> -        int                     x;
> -        int                     y;
> -        int                     width;
> -        int                     height;
> -        gboolean                enabled;
> -        gboolean                enabled_set;
> -    } display[MAX_DISPLAY];
> -    gint                        timer_id;
> -    GQueue                      *agent_msg_queue;
> -    GHashTable                  *file_xfer_tasks;
> -    GSList                      *flushing;
> -
> -    guint                       switch_host_delayed_id;
> -    guint                       migrate_delayed_id;
> -    spice_migrate               *migrate_data;
> -    int                         max_clipboard;
> -
> -    gboolean                    agent_volume_playback_sync;
> -    gboolean                    agent_volume_record_sync;
> -    GCancellable                *cancellable_volume_info;
> -};
> -
> -struct spice_migrate {
> -    struct coroutine *from;
> -    SpiceMigrationDstInfo *info;
> -    SpiceSession *session;
> -    guint nchannels;
> -    SpiceChannel *src_channel;
> -    SpiceChannel *dst_channel;
> -    bool do_seamless; /* used as input and output for the seamless migration
> handshake.
> -                         input: whether to send to the dest
> SPICE_MSGC_MAIN_MIGRATE_DST_DO_SEAMLESS
> -                         output: whether the dest approved seamless
> migration
> -                         (SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK/NACK)
> -                       */
> -    uint32_t src_mig_version;
> -};
> -
> -G_DEFINE_TYPE(SpiceMainChannel, spice_main_channel, SPICE_TYPE_CHANNEL)
> -
> -/* Properties */
> -enum {
> -    PROP_0,
> -    PROP_MOUSE_MODE,
> -    PROP_AGENT_CONNECTED,
> -    PROP_AGENT_CAPS_0,
> -    PROP_DISPLAY_DISABLE_WALLPAPER,
> -    PROP_DISPLAY_DISABLE_FONT_SMOOTH,
> -    PROP_DISPLAY_DISABLE_ANIMATION,
> -    PROP_DISPLAY_COLOR_DEPTH,
> -    PROP_DISABLE_DISPLAY_POSITION,
> -    PROP_DISABLE_DISPLAY_ALIGN,
> -    PROP_MAX_CLIPBOARD,
> -};
> -
> -/* Signals */
> -enum {
> -    SPICE_MAIN_MOUSE_UPDATE,
> -    SPICE_MAIN_AGENT_UPDATE,
> -    SPICE_MAIN_CLIPBOARD,
> -    SPICE_MAIN_CLIPBOARD_GRAB,
> -    SPICE_MAIN_CLIPBOARD_REQUEST,
> -    SPICE_MAIN_CLIPBOARD_RELEASE,
> -    SPICE_MAIN_CLIPBOARD_SELECTION,
> -    SPICE_MAIN_CLIPBOARD_SELECTION_GRAB,
> -    SPICE_MAIN_CLIPBOARD_SELECTION_REQUEST,
> -    SPICE_MAIN_CLIPBOARD_SELECTION_RELEASE,
> -    SPICE_MIGRATION_STARTED,
> -    SPICE_MAIN_LAST_SIGNAL,
> -};
> -
> -static guint signals[SPICE_MAIN_LAST_SIGNAL];
> -
> -static void spice_main_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
> -static void channel_set_handlers(SpiceChannelClass *klass);
> -static void agent_send_msg_queue(SpiceMainChannel *channel);
> -static void agent_free_msg_queue(SpiceMainChannel *channel);
> -static void migrate_channel_event_cb(SpiceChannel *channel,
> SpiceChannelEvent event,
> -                                     gpointer data);
> -static gboolean main_migrate_handshake_done(gpointer data);
> -static void spice_main_channel_send_migration_handshake(SpiceChannel
> *channel);
> -static void file_xfer_continue_read(SpiceFileXferTask *task);
> -static void file_xfer_completed(SpiceFileXferTask *task, GError *error);
> -static void file_xfer_flushed(SpiceMainChannel *channel, gboolean success);
> -static void spice_main_set_max_clipboard(SpiceMainChannel *self, gint max);
> -static void set_agent_connected(SpiceMainChannel *channel, gboolean
> connected);
> -
> -/* ------------------------------------------------------------------ */
> -
> -static const char *agent_msg_types[] = {
> -    [ VD_AGENT_MOUSE_STATE             ] = "mouse state",
> -    [ VD_AGENT_MONITORS_CONFIG         ] = "monitors config",
> -    [ VD_AGENT_REPLY                   ] = "reply",
> -    [ VD_AGENT_CLIPBOARD               ] = "clipboard",
> -    [ VD_AGENT_DISPLAY_CONFIG          ] = "display config",
> -    [ VD_AGENT_ANNOUNCE_CAPABILITIES   ] = "announce caps",
> -    [ VD_AGENT_CLIPBOARD_GRAB          ] = "clipboard grab",
> -    [ VD_AGENT_CLIPBOARD_REQUEST       ] = "clipboard request",
> -    [ VD_AGENT_CLIPBOARD_RELEASE       ] = "clipboard release",
> -    [ VD_AGENT_AUDIO_VOLUME_SYNC       ] = "volume-sync",
> -};
> -
> -static const char *agent_caps[] = {
> -    [ VD_AGENT_CAP_MOUSE_STATE         ] = "mouse state",
> -    [ VD_AGENT_CAP_MONITORS_CONFIG     ] = "monitors config",
> -    [ VD_AGENT_CAP_REPLY               ] = "reply",
> -    [ VD_AGENT_CAP_CLIPBOARD           ] = "clipboard (old)",
> -    [ VD_AGENT_CAP_DISPLAY_CONFIG      ] = "display config",
> -    [ VD_AGENT_CAP_CLIPBOARD_BY_DEMAND ] = "clipboard",
> -    [ VD_AGENT_CAP_CLIPBOARD_SELECTION ] = "clipboard selection",
> -    [ VD_AGENT_CAP_SPARSE_MONITORS_CONFIG ] = "sparse monitors",
> -    [ VD_AGENT_CAP_GUEST_LINEEND_LF    ] = "line-end lf",
> -    [ VD_AGENT_CAP_GUEST_LINEEND_CRLF  ] = "line-end crlf",
> -    [ VD_AGENT_CAP_MAX_CLIPBOARD       ] = "max-clipboard",
> -    [ VD_AGENT_CAP_AUDIO_VOLUME_SYNC   ] = "volume-sync",
> -};
> -#define NAME(_a, _i) ((_i) < SPICE_N_ELEMENTS(_a) ? (_a[(_i)] ?: "?") : "?")
> -
> -/* ------------------------------------------------------------------ */
> -
> -static gboolean test_agent_cap(SpiceMainChannel *channel, guint32 cap)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -
> -    if (!c->agent_caps_received)
> -        return FALSE;
> -
> -    return VD_AGENT_HAS_CAPABILITY(c->agent_caps,
> G_N_ELEMENTS(c->agent_caps), cap);
> -}
> -
> -static void spice_main_channel_reset_capabilties(SpiceChannel *channel)
> -{
> -    spice_channel_set_capability(SPICE_CHANNEL(channel),
> SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE);
> -    spice_channel_set_capability(SPICE_CHANNEL(channel),
> SPICE_MAIN_CAP_NAME_AND_UUID);
> -    spice_channel_set_capability(SPICE_CHANNEL(channel),
> SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS);
> -    spice_channel_set_capability(SPICE_CHANNEL(channel),
> SPICE_MAIN_CAP_SEAMLESS_MIGRATE);
> -}
> -
> -static void spice_main_channel_init(SpiceMainChannel *channel)
> -{
> -    SpiceMainChannelPrivate *c;
> -
> -    c = channel->priv = SPICE_MAIN_CHANNEL_GET_PRIVATE(channel);
> -    c->agent_msg_queue = g_queue_new();
> -    c->file_xfer_tasks = g_hash_table_new(g_direct_hash, g_direct_equal);
> -    c->cancellable_volume_info = g_cancellable_new();
> -
> -    spice_main_channel_reset_capabilties(SPICE_CHANNEL(channel));
> -}
> -
> -static gint spice_main_get_max_clipboard(SpiceMainChannel *self)
> -{
> -    g_return_val_if_fail(SPICE_IS_MAIN_CHANNEL(self), 0);
> -
> -    if (g_getenv("SPICE_MAX_CLIPBOARD"))
> -        return atoi(g_getenv("SPICE_MAX_CLIPBOARD"));
> -
> -    return self->priv->max_clipboard;
> -}
> -
> -static void spice_main_get_property(GObject    *object,
> -                                    guint       prop_id,
> -                                    GValue     *value,
> -                                    GParamSpec *pspec)
> -{
> -    SpiceMainChannel *self = SPICE_MAIN_CHANNEL(object);
> -    SpiceMainChannelPrivate *c = self->priv;
> -
> -    switch (prop_id) {
> -    case PROP_MOUSE_MODE:
> -        g_value_set_int(value, c->mouse_mode);
> -	break;
> -    case PROP_AGENT_CONNECTED:
> -        g_value_set_boolean(value, c->agent_connected);
> -	break;
> -    case PROP_AGENT_CAPS_0:
> -        g_value_set_int(value, c->agent_caps[0]);
> -	break;
> -    case PROP_DISPLAY_DISABLE_WALLPAPER:
> -        g_value_set_boolean(value, c->display_disable_wallpaper);
> -        break;
> -    case PROP_DISPLAY_DISABLE_FONT_SMOOTH:
> -        g_value_set_boolean(value, c->display_disable_font_smooth);
> -        break;
> -    case PROP_DISPLAY_DISABLE_ANIMATION:
> -        g_value_set_boolean(value, c->display_disable_animation);
> -        break;
> -    case PROP_DISPLAY_COLOR_DEPTH:
> -        g_value_set_uint(value, c->display_color_depth);
> -        break;
> -    case PROP_DISABLE_DISPLAY_POSITION:
> -        g_value_set_boolean(value, c->disable_display_position);
> -        break;
> -    case PROP_DISABLE_DISPLAY_ALIGN:
> -        g_value_set_boolean(value, c->disable_display_align);
> -        break;
> -    case PROP_MAX_CLIPBOARD:
> -        g_value_set_int(value, spice_main_get_max_clipboard(self));
> -        break;
> -    default:
> -	G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
> -	break;
> -    }
> -}
> -
> -static void spice_main_set_property(GObject *gobject, guint prop_id,
> -                                    const GValue *value, GParamSpec *pspec)
> -{
> -    SpiceMainChannel *self = SPICE_MAIN_CHANNEL(gobject);
> -    SpiceMainChannelPrivate *c = self->priv;
> -
> -    switch (prop_id) {
> -    case PROP_DISPLAY_DISABLE_WALLPAPER:
> -        c->display_disable_wallpaper = g_value_get_boolean(value);
> -        break;
> -    case PROP_DISPLAY_DISABLE_FONT_SMOOTH:
> -        c->display_disable_font_smooth = g_value_get_boolean(value);
> -        break;
> -    case PROP_DISPLAY_DISABLE_ANIMATION:
> -        c->display_disable_animation = g_value_get_boolean(value);
> -        break;
> -    case PROP_DISPLAY_COLOR_DEPTH: {
> -        guint color_depth = g_value_get_uint(value);
> -        g_return_if_fail(color_depth % 8 == 0);
> -        c->display_color_depth = color_depth;
> -        break;
> -    }
> -    case PROP_DISABLE_DISPLAY_POSITION:
> -        c->disable_display_position = g_value_get_boolean(value);
> -        break;
> -    case PROP_DISABLE_DISPLAY_ALIGN:
> -        c->disable_display_align = g_value_get_boolean(value);
> -        break;
> -    case PROP_MAX_CLIPBOARD:
> -        spice_main_set_max_clipboard(self, g_value_get_int(value));
> -        break;
> -    default:
> -	G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
> -	break;
> -    }
> -}
> -
> -static void spice_main_channel_dispose(GObject *obj)
> -{
> -    SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(obj)->priv;
> -
> -    if (c->timer_id) {
> -        g_source_remove(c->timer_id);
> -        c->timer_id = 0;
> -    }
> -
> -    if (c->switch_host_delayed_id) {
> -        g_source_remove(c->switch_host_delayed_id);
> -        c->switch_host_delayed_id = 0;
> -    }
> -
> -    if (c->migrate_delayed_id) {
> -        g_source_remove(c->migrate_delayed_id);
> -        c->migrate_delayed_id = 0;
> -    }
> -
> -    g_cancellable_cancel(c->cancellable_volume_info);
> -    g_clear_object(&c->cancellable_volume_info);
> -
> -    if (G_OBJECT_CLASS(spice_main_channel_parent_class)->dispose)
> -        G_OBJECT_CLASS(spice_main_channel_parent_class)->dispose(obj);
> -}
> -
> -static void spice_main_channel_finalize(GObject *obj)
> -{
> -    SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(obj)->priv;
> -
> -    g_free(c->agent_msg_data);
> -    agent_free_msg_queue(SPICE_MAIN_CHANNEL(obj));
> -    if (c->file_xfer_tasks)
> -        g_hash_table_unref(c->file_xfer_tasks);
> -
> -    if (G_OBJECT_CLASS(spice_main_channel_parent_class)->finalize)
> -        G_OBJECT_CLASS(spice_main_channel_parent_class)->finalize(obj);
> -}
> -
> -/* coroutine context */
> -static void spice_channel_iterate_write(SpiceChannel *channel)
> -{
> -    agent_send_msg_queue(SPICE_MAIN_CHANNEL(channel));
> -
> -    if (SPICE_CHANNEL_CLASS(spice_main_channel_parent_class)->iterate_write)
> -
> SPICE_CHANNEL_CLASS(spice_main_channel_parent_class)->iterate_write(channel);
> -}
> -
> -/* main or coroutine context */
> -static void spice_main_channel_reset_agent(SpiceMainChannel *channel)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    GError *error;
> -    GList *tasks;
> -    GList *l;
> -
> -    c->agent_connected = FALSE;
> -    c->agent_caps_received = FALSE;
> -    c->agent_display_config_sent = FALSE;
> -    c->agent_msg_pos = 0;
> -    g_free(c->agent_msg_data);
> -    c->agent_msg_data = NULL;
> -    c->agent_msg_size = 0;
> -
> -    tasks = g_hash_table_get_values(c->file_xfer_tasks);
> -    for (l = tasks; l != NULL; l = l->next) {
> -        SpiceFileXferTask *task = (SpiceFileXferTask *)l->data;
> -
> -        error = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
> -                            "Agent connection closed");
> -        file_xfer_completed(task, error);
> -    }
> -    g_list_free(tasks);
> -    file_xfer_flushed(channel, FALSE);
> -}
> -
> -/* main or coroutine context */
> -static void spice_main_channel_reset(SpiceChannel *channel, gboolean
> migrating)
> -{
> -    SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
> -
> -    /* This is not part of reset_agent, since the spice-server expects any
> -       pending multi-chunk messages to be completed by the client, even
> after
> -       it has send an agent-disconnected msg as that is what the original
> -       spicec did. Also see the TODO in server/reds.c reds_reset_vdp() */
> -    c->agent_tokens = 0;
> -    agent_free_msg_queue(SPICE_MAIN_CHANNEL(channel));
> -    c->agent_msg_queue = g_queue_new();
> -
> -    c->agent_volume_playback_sync = FALSE;
> -    c->agent_volume_record_sync = FALSE;
> -
> -    set_agent_connected(SPICE_MAIN_CHANNEL(channel), FALSE);
> -
> -
> SPICE_CHANNEL_CLASS(spice_main_channel_parent_class)->channel_reset(channel,
> migrating);
> -}
> -
> -static void spice_main_constructed(GObject *object)
> -{
> -    SpiceMainChannel *self = SPICE_MAIN_CHANNEL(object);
> -    SpiceMainChannelPrivate *c = self->priv;
> -
> -    /* update default value */
> -    c->max_clipboard = spice_main_get_max_clipboard(self);
> -
> -    if (G_OBJECT_CLASS(spice_main_channel_parent_class)->constructed)
> -
> G_OBJECT_CLASS(spice_main_channel_parent_class)->constructed(object);
> -}
> -
> -static void spice_main_channel_class_init(SpiceMainChannelClass *klass)
> -{
> -    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
> -    SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
> -
> -    gobject_class->dispose      = spice_main_channel_dispose;
> -    gobject_class->finalize     = spice_main_channel_finalize;
> -    gobject_class->get_property = spice_main_get_property;
> -    gobject_class->set_property = spice_main_set_property;
> -    gobject_class->constructed  = spice_main_constructed;
> -
> -    channel_class->handle_msg    = spice_main_handle_msg;
> -    channel_class->iterate_write = spice_channel_iterate_write;
> -    channel_class->channel_reset = spice_main_channel_reset;
> -    channel_class->channel_reset_capabilities =
> spice_main_channel_reset_capabilties;
> -    channel_class->channel_send_migration_handshake =
> spice_main_channel_send_migration_handshake;
> -
> -    /**
> -     * SpiceMainChannel:mouse-mode:
> -     *
> -     * Spice protocol specifies two mouse modes, client mode and
> -     * server mode. In client mode (%SPICE_MOUSE_MODE_CLIENT), the
> -     * affective mouse is the client side mouse: the client sends
> -     * mouse position within the display and the server sends mouse
> -     * shape messages. In server mode (%SPICE_MOUSE_MODE_SERVER), the
> -     * client sends relative mouse movements and the server sends
> -     * position and shape commands.
> -     **/
> -    g_object_class_install_property
> -        (gobject_class, PROP_MOUSE_MODE,
> -         g_param_spec_int("mouse-mode",
> -                          "Mouse mode",
> -                          "Mouse mode",
> -                          0, INT_MAX, 0,
> -                          G_PARAM_READABLE |
> -                          G_PARAM_STATIC_NAME |
> -                          G_PARAM_STATIC_NICK |
> -                          G_PARAM_STATIC_BLURB));
> -
> -    g_object_class_install_property
> -        (gobject_class, PROP_AGENT_CONNECTED,
> -         g_param_spec_boolean("agent-connected",
> -                              "Agent connected",
> -                              "Whether the agent is connected",
> -                              FALSE,
> -                              G_PARAM_READABLE |
> -                              G_PARAM_STATIC_NAME |
> -                              G_PARAM_STATIC_NICK |
> -                              G_PARAM_STATIC_BLURB));
> -
> -    g_object_class_install_property
> -        (gobject_class, PROP_AGENT_CAPS_0,
> -         g_param_spec_int("agent-caps-0",
> -                          "Agent caps 0",
> -                          "Agent capability bits 0 -> 31",
> -                          0, INT_MAX, 0,
> -                          G_PARAM_READABLE |
> -                          G_PARAM_STATIC_NAME |
> -                          G_PARAM_STATIC_NICK |
> -                          G_PARAM_STATIC_BLURB));
> -
> -    g_object_class_install_property
> -        (gobject_class, PROP_DISPLAY_DISABLE_WALLPAPER,
> -         g_param_spec_boolean("disable-wallpaper",
> -                              "Disable guest wallpaper",
> -                              "Disable guest wallpaper",
> -                              FALSE,
> -                              G_PARAM_READWRITE |
> -                              G_PARAM_CONSTRUCT |
> -                              G_PARAM_STATIC_STRINGS));
> -
> -    g_object_class_install_property
> -        (gobject_class, PROP_DISPLAY_DISABLE_FONT_SMOOTH,
> -         g_param_spec_boolean("disable-font-smooth",
> -                              "Disable guest font smooth",
> -                              "Disable guest font smoothing",
> -                              FALSE,
> -                              G_PARAM_READWRITE |
> -                              G_PARAM_CONSTRUCT |
> -                              G_PARAM_STATIC_STRINGS));
> -
> -    g_object_class_install_property
> -        (gobject_class, PROP_DISPLAY_DISABLE_ANIMATION,
> -         g_param_spec_boolean("disable-animation",
> -                              "Disable guest animations",
> -                              "Disable guest animations",
> -                              FALSE,
> -                              G_PARAM_READWRITE |
> -                              G_PARAM_CONSTRUCT |
> -                              G_PARAM_STATIC_STRINGS));
> -
> -    g_object_class_install_property
> -        (gobject_class, PROP_DISABLE_DISPLAY_POSITION,
> -         g_param_spec_boolean("disable-display-position",
> -                              "Disable display position",
> -                              "Disable using display position when setting
> monitor config",
> -                              TRUE,
> -                              G_PARAM_READWRITE |
> -                              G_PARAM_CONSTRUCT |
> -                              G_PARAM_STATIC_STRINGS));
> -
> -    g_object_class_install_property
> -        (gobject_class, PROP_DISPLAY_COLOR_DEPTH,
> -         g_param_spec_uint("color-depth",
> -                           "Color depth",
> -                           "Color depth", 0, 32, 0,
> -                           G_PARAM_READWRITE |
> -                           G_PARAM_CONSTRUCT |
> -                           G_PARAM_STATIC_STRINGS));
> -
> -    /**
> -     * SpiceMainChannel:disable-display-align:
> -     *
> -     * Disable automatic horizontal display position alignment.
> -     *
> -     * Since: 0.13
> -     */
> -    g_object_class_install_property
> -        (gobject_class, PROP_DISABLE_DISPLAY_ALIGN,
> -         g_param_spec_boolean("disable-display-align",
> -                              "Disable display align",
> -                              "Disable display position alignment",
> -                              FALSE,
> -                              G_PARAM_READWRITE |
> -                              G_PARAM_CONSTRUCT |
> -                              G_PARAM_STATIC_STRINGS));
> -
> -    /**
> -     * SpiceMainChannel:max-clipboard:
> -     *
> -     * Maximum size of clipboard operations in bytes (default 100MB,
> -     * -1 for unlimited size);
> -     *
> -     * Since: 0.22
> -     **/
> -    g_object_class_install_property
> -        (gobject_class, PROP_MAX_CLIPBOARD,
> -         g_param_spec_int("max-clipboard",
> -                          "max clipboard",
> -                          "Maximum clipboard data size",
> -                          -1, G_MAXINT, 100 * 1024 * 1024,
> -                          G_PARAM_READWRITE |
> -                          G_PARAM_CONSTRUCT |
> -                          G_PARAM_STATIC_STRINGS));
> -
> -    /* TODO use notify instead */
> -    /**
> -     * SpiceMainChannel::main-mouse-update:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     *
> -     * Notify when the mouse mode has changed.
> -     **/
> -    signals[SPICE_MAIN_MOUSE_UPDATE] =
> -        g_signal_new("main-mouse-update",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceMainChannelClass, mouse_update),
> -                     NULL, NULL,
> -                     g_cclosure_marshal_VOID__VOID,
> -                     G_TYPE_NONE,
> -                     0);
> -
> -    /* TODO use notify instead */
> -    /**
> -     * SpiceMainChannel::main-agent-update:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     *
> -     * Notify when the %SpiceMainChannel:agent-connected or
> -     * %SpiceMainChannel:agent-caps-0 property change.
> -     **/
> -    signals[SPICE_MAIN_AGENT_UPDATE] =
> -        g_signal_new("main-agent-update",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_FIRST,
> -                     G_STRUCT_OFFSET(SpiceMainChannelClass, agent_update),
> -                     NULL, NULL,
> -                     g_cclosure_marshal_VOID__VOID,
> -                     G_TYPE_NONE,
> -                     0);
> -    /**
> -     * SpiceMainChannel::main-clipboard:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     * @type: the VD_AGENT_CLIPBOARD data type
> -     * @data: clipboard data
> -     * @size: size of @data in bytes
> -     *
> -     * Provides guest clipboard data requested by
> spice_main_clipboard_request().
> -     *
> -     * Deprecated: 0.6: use SpiceMainChannel::main-clipboard-selection
> instead.
> -     **/
> -    signals[SPICE_MAIN_CLIPBOARD] =
> -        g_signal_new("main-clipboard",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
> -                     0,
> -                     NULL, NULL,
> -                     g_cclosure_user_marshal_VOID__UINT_POINTER_UINT,
> -                     G_TYPE_NONE,
> -                     3,
> -                     G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_UINT);
> -
> -    /**
> -     * SpiceMainChannel::main-clipboard-selection:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     * @selection: a VD_AGENT_CLIPBOARD_SELECTION clipboard
> -     * @type: the VD_AGENT_CLIPBOARD data type
> -     * @data: clipboard data
> -     * @size: size of @data in bytes
> -     *
> -     * Since: 0.6
> -     **/
> -    signals[SPICE_MAIN_CLIPBOARD_SELECTION] =
> -        g_signal_new("main-clipboard-selection",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_LAST,
> -                     0,
> -                     NULL, NULL,
> -                     g_cclosure_user_marshal_VOID__UINT_UINT_POINTER_UINT,
> -                     G_TYPE_NONE,
> -                     4,
> -                     G_TYPE_UINT, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_UINT);
> -
> -    /**
> -     * SpiceMainChannel::main-clipboard-grab:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     * @types: the VD_AGENT_CLIPBOARD data types
> -     * @ntypes: the number of @types
> -     *
> -     * Inform when clipboard data is available from the guest, and for
> -     * which @types.
> -     *
> -     * Deprecated: 0.6: use SpiceMainChannel::main-clipboard-selection-grab
> instead.
> -     **/
> -    signals[SPICE_MAIN_CLIPBOARD_GRAB] =
> -        g_signal_new("main-clipboard-grab",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
> -                     0,
> -                     NULL, NULL,
> -                     g_cclosure_user_marshal_BOOLEAN__POINTER_UINT,
> -                     G_TYPE_BOOLEAN,
> -                     2,
> -                     G_TYPE_POINTER, G_TYPE_UINT);
> -
> -    /**
> -     * SpiceMainChannel::main-clipboard-selection-grab:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     * @selection: a VD_AGENT_CLIPBOARD_SELECTION clipboard
> -     * @types: the VD_AGENT_CLIPBOARD data types
> -     * @ntypes: the number of @types
> -     *
> -     * Inform when clipboard data is available from the guest, and for
> -     * which @types.
> -     *
> -     * Since: 0.6
> -     **/
> -    signals[SPICE_MAIN_CLIPBOARD_SELECTION_GRAB] =
> -        g_signal_new("main-clipboard-selection-grab",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_LAST,
> -                     0,
> -                     NULL, NULL,
> -                     g_cclosure_user_marshal_BOOLEAN__UINT_POINTER_UINT,
> -                     G_TYPE_BOOLEAN,
> -                     3,
> -                     G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_UINT);
> -
> -    /**
> -     * SpiceMainChannel::main-clipboard-request:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     * @types: the VD_AGENT_CLIPBOARD request type
> -     *
> -     * Return value: %TRUE if the request is successful
> -     *
> -     * Request clipbard data from the client.
> -     *
> -     * Deprecated: 0.6: use
> SpiceMainChannel::main-clipboard-selection-request instead.
> -     **/
> -    signals[SPICE_MAIN_CLIPBOARD_REQUEST] =
> -        g_signal_new("main-clipboard-request",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
> -                     0,
> -                     NULL, NULL,
> -                     g_cclosure_user_marshal_BOOLEAN__UINT,
> -                     G_TYPE_BOOLEAN,
> -                     1,
> -                     G_TYPE_UINT);
> -
> -    /**
> -     * SpiceMainChannel::main-clipboard-selection-request:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     * @selection: a VD_AGENT_CLIPBOARD_SELECTION clipboard
> -     * @types: the VD_AGENT_CLIPBOARD request type
> -     *
> -     * Return value: %TRUE if the request is successful
> -     *
> -     * Request clipbard data from the client.
> -     *
> -     * Since: 0.6
> -     **/
> -    signals[SPICE_MAIN_CLIPBOARD_SELECTION_REQUEST] =
> -        g_signal_new("main-clipboard-selection-request",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_LAST,
> -                     0,
> -                     NULL, NULL,
> -                     g_cclosure_user_marshal_BOOLEAN__UINT_UINT,
> -                     G_TYPE_BOOLEAN,
> -                     2,
> -                     G_TYPE_UINT, G_TYPE_UINT);
> -
> -    /**
> -     * SpiceMainChannel::main-clipboard-release:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     *
> -     * Inform when the clipboard is released from the guest, when no
> -     * clipboard data is available from the guest.
> -     *
> -     * Deprecated: 0.6: use
> SpiceMainChannel::main-clipboard-selection-release instead.
> -     **/
> -    signals[SPICE_MAIN_CLIPBOARD_RELEASE] =
> -        g_signal_new("main-clipboard-release",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
> -                     0,
> -                     NULL, NULL,
> -                     g_cclosure_marshal_VOID__VOID,
> -                     G_TYPE_NONE,
> -                     0);
> -
> -    /**
> -     * SpiceMainChannel::main-clipboard-selection-release:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     * @selection: a VD_AGENT_CLIPBOARD_SELECTION clipboard
> -     *
> -     * Inform when the clipboard is released from the guest, when no
> -     * clipboard data is available from the guest.
> -     *
> -     * Since: 0.6
> -     **/
> -    signals[SPICE_MAIN_CLIPBOARD_SELECTION_RELEASE] =
> -        g_signal_new("main-clipboard-selection-release",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_LAST,
> -                     0,
> -                     NULL, NULL,
> -                     g_cclosure_marshal_VOID__UINT,
> -                     G_TYPE_NONE,
> -                     1,
> -                     G_TYPE_UINT);
> -
> -    /**
> -     * SpiceMainChannel::migration-started:
> -     * @main: the #SpiceMainChannel that emitted the signal
> -     * @session: a migration #SpiceSession
> -     *
> -     * Inform when migration is starting. Application wishing to make
> -     * connections themself can set the #SpiceSession:client-sockets
> -     * to @TRUE, then follow #SpiceSession::channel-new creation, and
> -     * use spice_channel_open_fd() once the socket is created.
> -     *
> -     **/
> -    signals[SPICE_MIGRATION_STARTED] =
> -        g_signal_new("migration-started",
> -                     G_OBJECT_CLASS_TYPE(gobject_class),
> -                     G_SIGNAL_RUN_LAST,
> -                     0,
> -                     NULL, NULL,
> -                     g_cclosure_marshal_VOID__OBJECT,
> -                     G_TYPE_NONE,
> -                     1,
> -                     G_TYPE_OBJECT);
> -
> -    g_type_class_add_private(klass, sizeof(SpiceMainChannelPrivate));
> -    channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
> -}
> -
> -/* ------------------------------------------------------------------ */
> -
> -
> -static void agent_free_msg_queue(SpiceMainChannel *channel)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    SpiceMsgOut *out;
> -
> -    if (!c->agent_msg_queue)
> -        return;
> -
> -    while (!g_queue_is_empty(c->agent_msg_queue)) {
> -        out = g_queue_pop_head(c->agent_msg_queue);
> -        spice_msg_out_unref(out);
> -    }
> -
> -    g_queue_free(c->agent_msg_queue);
> -    c->agent_msg_queue = NULL;
> -}
> -
> -/* Here, flushing algorithm is stolen from spice-channel.c */
> -static void file_xfer_flushed(SpiceMainChannel *channel, gboolean success)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    GSList *l;
> -
> -    for (l = c->flushing; l != NULL; l = l->next) {
> -        GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT(l->data);
> -        g_simple_async_result_set_op_res_gboolean(result, success);
> -        g_simple_async_result_complete_in_idle(result);
> -    }
> -
> -    g_slist_free_full(c->flushing, g_object_unref);
> -    c->flushing = NULL;
> -}
> -
> -static void file_xfer_flush_async(SpiceMainChannel *channel, GCancellable
> *cancellable,
> -                                  GAsyncReadyCallback callback, gpointer
> user_data)
> -{
> -    GSimpleAsyncResult *simple;
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    gboolean was_empty;
> -
> -    simple = g_simple_async_result_new(G_OBJECT(channel), callback,
> user_data,
> -                                       file_xfer_flush_async);
> -
> -    was_empty = g_queue_is_empty(c->agent_msg_queue);
> -    if (was_empty) {
> -        g_simple_async_result_set_op_res_gboolean(simple, TRUE);
> -        g_simple_async_result_complete_in_idle(simple);
> -        g_object_unref(simple);
> -        return;
> -    }
> -
> -    c->flushing = g_slist_append(c->flushing, simple);
> -}
> -
> -static gboolean file_xfer_flush_finish(SpiceMainChannel *channel,
> GAsyncResult *result,
> -                                       GError **error)
> -{
> -    GSimpleAsyncResult *simple = (GSimpleAsyncResult *)result;
> -
> -    g_return_val_if_fail(g_simple_async_result_is_valid(result,
> -        G_OBJECT(channel), file_xfer_flush_async), FALSE);
> -
> -    if (g_simple_async_result_propagate_error(simple, error)) {
> -        return FALSE;
> -    }
> -
> -    CHANNEL_DEBUG(channel, "flushed finished!");
> -    return g_simple_async_result_get_op_res_gboolean(simple);
> -}
> -
> -/* coroutine context */
> -static void agent_send_msg_queue(SpiceMainChannel *channel)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    SpiceMsgOut *out;
> -
> -    while (c->agent_tokens > 0 &&
> -           !g_queue_is_empty(c->agent_msg_queue)) {
> -        c->agent_tokens--;
> -        out = g_queue_pop_head(c->agent_msg_queue);
> -        spice_msg_out_send_internal(out);
> -    }
> -    if (g_queue_is_empty(c->agent_msg_queue) && c->flushing != NULL) {
> -        file_xfer_flushed(channel, TRUE);
> -    }
> -}
> -
> -/* any context: the message is not flushed immediately,
> -   you can wakeup() the channel coroutine or send_msg_queue()
> -
> -   expected arguments, pair of data/data_size to send terminated with NULL:
> -   agent_msg_queue_many(main, VD_AGENT_...,
> -                        &foo, sizeof(Foo),
> -                        data, data_size, NULL);
> -*/
> -G_GNUC_NULL_TERMINATED
> -static void agent_msg_queue_many(SpiceMainChannel *channel, int type, const
> void *data, ...)
> -{
> -    va_list args;
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    SpiceMsgOut *out;
> -    VDAgentMessage msg;
> -    guint8 *payload;
> -    gsize paysize, s, mins, size = 0;
> -    const guint8 *d;
> -
> -    G_STATIC_ASSERT(VD_AGENT_MAX_DATA_SIZE > sizeof(VDAgentMessage));
> -
> -    va_start(args, data);
> -    for (d = data; d != NULL; d = va_arg(args, void*)) {
> -        size += va_arg(args, gsize);
> -    }
> -    va_end(args);
> -
> -    msg.protocol = VD_AGENT_PROTOCOL;
> -    msg.type = type;
> -    msg.opaque = 0;
> -    msg.size = size;
> -
> -    paysize = MIN(VD_AGENT_MAX_DATA_SIZE, size + sizeof(VDAgentMessage));
> -    out = spice_msg_out_new(SPICE_CHANNEL(channel),
> SPICE_MSGC_MAIN_AGENT_DATA);
> -    payload = spice_marshaller_reserve_space(out->marshaller, paysize);
> -    memcpy(payload, &msg, sizeof(VDAgentMessage));
> -    payload += sizeof(VDAgentMessage);
> -    paysize -= sizeof(VDAgentMessage);
> -    if (paysize == 0) {
> -        g_queue_push_tail(c->agent_msg_queue, out);
> -        out = NULL;
> -    }
> -
> -    va_start(args, data);
> -    for (d = data; size > 0; d = va_arg(args, void*)) {
> -        s = va_arg(args, gsize);
> -        while (s > 0) {
> -            if (out == NULL) {
> -                paysize = MIN(VD_AGENT_MAX_DATA_SIZE, size);
> -                out = spice_msg_out_new(SPICE_CHANNEL(channel),
> SPICE_MSGC_MAIN_AGENT_DATA);
> -                payload = spice_marshaller_reserve_space(out->marshaller,
> paysize);
> -            }
> -            mins = MIN(paysize, s);
> -            memcpy(payload, d, mins);
> -            d += mins;
> -            payload += mins;
> -            s -= mins;
> -            size -= mins;
> -            paysize -= mins;
> -            if (paysize == 0) {
> -                g_queue_push_tail(c->agent_msg_queue, out);
> -                out = NULL;
> -            }
> -        }
> -    }
> -    va_end(args);
> -    g_warn_if_fail(out == NULL);
> -}
> -
> -static int monitors_cmp(const void *p1, const void *p2, gpointer user_data)
> -{
> -    const VDAgentMonConfig *m1 = p1;
> -    const VDAgentMonConfig *m2 = p2;
> -    double d1 = sqrt(m1->x * m1->x + m1->y * m1->y);
> -    double d2 = sqrt(m2->x * m2->x + m2->y * m2->y);
> -    int diff = d1 - d2;
> -
> -    return diff == 0 ? (char*)p1 - (char*)p2 : diff;
> -}
> -
> -static void monitors_align(VDAgentMonConfig *monitors, int nmonitors)
> -{
> -    gint i, j, x = 0;
> -    guint32 used = 0;
> -    VDAgentMonConfig *sorted_monitors;
> -
> -    if (nmonitors == 0)
> -        return;
> -
> -    /* sort by distance from origin */
> -    sorted_monitors = g_memdup(monitors, nmonitors *
> sizeof(VDAgentMonConfig));
> -    g_qsort_with_data(sorted_monitors, nmonitors, sizeof(VDAgentMonConfig),
> monitors_cmp, NULL);
> -
> -    /* super-KISS ltr alignment, feel free to improve */
> -    for (i = 0; i < nmonitors; i++) {
> -        /* Find where this monitor is in the sorted order */
> -        for (j = 0; j < nmonitors; j++) {
> -            /* Avoid using the same entry twice, this happens with older
> -               virt-viewer versions which always set x and y to 0 */
> -            if (used & (1 << j))
> -                continue;
> -            if (memcmp(&monitors[j], &sorted_monitors[i],
> -                       sizeof(VDAgentMonConfig)) == 0)
> -                break;
> -        }
> -        used |= 1 << j;
> -        monitors[j].x = x;
> -        monitors[j].y = 0;
> -        x += monitors[j].width;
> -        if (monitors[j].width || monitors[j].height)
> -            SPICE_DEBUG("#%d +%d+%d-%dx%d", j, monitors[j].x, monitors[j].y,
> -                        monitors[j].width, monitors[j].height);
> -    }
> -    g_free(sorted_monitors);
> -}
> -
> -
> -#define agent_msg_queue(Channel, Type, Size, Data) \
> -    agent_msg_queue_many((Channel), (Type), (Data), (Size), NULL)
> -
> -/**
> - * spice_main_send_monitor_config:
> - * @channel:
> - *
> - * Send monitors configuration previously set with
> - * spice_main_set_display() and spice_main_set_display_enabled()
> - *
> - * Returns: %TRUE on success.
> - **/
> -gboolean spice_main_send_monitor_config(SpiceMainChannel *channel)
> -{
> -    SpiceMainChannelPrivate *c;
> -    VDAgentMonitorsConfig *mon;
> -    int i, j, monitors;
> -    size_t size;
> -
> -    g_return_val_if_fail(SPICE_IS_MAIN_CHANNEL(channel), FALSE);
> -    c = channel->priv;
> -    g_return_val_if_fail(c->agent_connected, FALSE);
> -
> -    if (spice_main_agent_test_capability(channel,
> -                                     VD_AGENT_CAP_SPARSE_MONITORS_CONFIG)) {
> -        monitors = SPICE_N_ELEMENTS(c->display);
> -    } else {
> -        monitors = 0;
> -        for (i = 0; i < SPICE_N_ELEMENTS(c->display); i++) {
> -            if (c->display[i].enabled)
> -                monitors += 1;
> -        }
> -    }
> -
> -    size = sizeof(VDAgentMonitorsConfig) + sizeof(VDAgentMonConfig) *
> monitors;
> -    mon = g_malloc0(size);
> -
> -    mon->num_of_monitors = monitors;
> -    if (c->disable_display_position == FALSE ||
> -        c->disable_display_align == FALSE)
> -        mon->flags |= VD_AGENT_CONFIG_MONITORS_FLAG_USE_POS;
> -
> -    j = 0;
> -    for (i = 0; i < SPICE_N_ELEMENTS(c->display); i++) {
> -        if (!c->display[i].enabled) {
> -            if (spice_main_agent_test_capability(channel,
> -                                     VD_AGENT_CAP_SPARSE_MONITORS_CONFIG))
> -                j++;
> -            continue;
> -        }
> -        mon->monitors[j].depth  = c->display_color_depth ?
> c->display_color_depth : 32;
> -        mon->monitors[j].width  = c->display[i].width;
> -        mon->monitors[j].height = c->display[i].height;
> -        mon->monitors[j].x = c->display[i].x;
> -        mon->monitors[j].y = c->display[i].y;
> -        CHANNEL_DEBUG(channel, "monitor config: #%d %dx%d+%d+%d @ %d bpp",
> j,
> -                      mon->monitors[j].width, mon->monitors[j].height,
> -                      mon->monitors[j].x, mon->monitors[j].y,
> -                      mon->monitors[j].depth);
> -        j++;
> -    }
> -
> -    if (c->disable_display_align == FALSE)
> -        monitors_align(mon->monitors, mon->num_of_monitors);
> -
> -    agent_msg_queue(channel, VD_AGENT_MONITORS_CONFIG, size, mon);
> -    g_free(mon);
> -
> -    spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
> -    if (c->timer_id != 0) {
> -        g_source_remove(c->timer_id);
> -        c->timer_id = 0;
> -    }
> -
> -    return TRUE;
> -}
> -
> -static void audio_playback_volume_info_cb(GObject *object, GAsyncResult
> *res, gpointer user_data)
> -{
> -    SpiceMainChannel *main_channel = user_data;
> -    SpiceSession *session =
> spice_channel_get_session(SPICE_CHANNEL(main_channel));
> -    SpiceAudio *audio = spice_audio_get(session, NULL);
> -    VDAgentAudioVolumeSync *avs;
> -    guint16 *volume;
> -    guint8 nchannels;
> -    gboolean mute, ret;
> -    gsize array_size;
> -    GError *error = NULL;
> -
> -    ret = spice_audio_get_playback_volume_info_finish(audio, res, &mute,
> &nchannels,
> -                                                      &volume, &error);
> -    if (ret == FALSE || volume == NULL || nchannels == 0) {
> -        if (error != NULL) {
> -            spice_warning("Failed to get playback async volume info: %s",
> error->message);
> -            g_error_free (error);
> -        } else {
> -            SPICE_DEBUG("Failed to get playback async volume info");
> -        }
> -        main_channel->priv->agent_volume_playback_sync = FALSE;
> -        return;
> -    }
> -
> -    array_size = sizeof(uint16_t) * nchannels;
> -    avs = g_malloc0(sizeof(VDAgentAudioVolumeSync) + array_size);
> -    avs->is_playback = TRUE;
> -    avs->mute = mute;
> -    avs->nchannels = nchannels;
> -    memcpy(avs->volume, volume, array_size);
> -
> -    SPICE_DEBUG("%s mute=%s nchannels=%u volume[0]=%u",
> -                __func__, spice_yes_no(mute), nchannels, volume[0]);
> -    g_free(volume);
> -    agent_msg_queue(main_channel, VD_AGENT_AUDIO_VOLUME_SYNC,
> -                    sizeof(VDAgentAudioVolumeSync) + array_size, avs);
> -}
> -
> -static void agent_sync_audio_playback(SpiceMainChannel *main_channel)
> -{
> -    SpiceSession *session =
> spice_channel_get_session(SPICE_CHANNEL(main_channel));
> -    SpiceAudio *audio = spice_audio_get(session, NULL);
> -    SpiceMainChannelPrivate *c = main_channel->priv;
> -
> -    if (!test_agent_cap(main_channel, VD_AGENT_CAP_AUDIO_VOLUME_SYNC) ||
> -        c->agent_volume_playback_sync == TRUE) {
> -        SPICE_DEBUG("%s - is not going to sync audio with guest", __func__);
> -        return;
> -    }
> -    /* only one per connection */
> -    g_cancellable_reset(c->cancellable_volume_info);
> -    c->agent_volume_playback_sync = TRUE;
> -    spice_audio_get_playback_volume_info_async(audio,
> c->cancellable_volume_info, main_channel,
> -
> audio_playback_volume_info_cb,
> main_channel);
> -}
> -
> -static void audio_record_volume_info_cb(GObject *object, GAsyncResult *res,
> gpointer user_data)
> -{
> -    SpiceMainChannel *main_channel = user_data;
> -    SpiceSession *session =
> spice_channel_get_session(SPICE_CHANNEL(main_channel));
> -    SpiceAudio *audio = spice_audio_get(session, NULL);
> -    VDAgentAudioVolumeSync *avs;
> -    guint16 *volume;
> -    guint8 nchannels;
> -    gboolean ret, mute;
> -    gsize array_size;
> -    GError *error = NULL;
> -
> -    ret = spice_audio_get_record_volume_info_finish(audio, res, &mute,
> &nchannels, &volume, &error);
> -    if (ret == FALSE || volume == NULL || nchannels == 0) {
> -        if (error != NULL) {
> -            spice_warning ("Failed to get record async volume info: %s",
> error->message);
> -            g_error_free (error);
> -        } else {
> -            SPICE_DEBUG("Failed to get record async volume info");
> -        }
> -        main_channel->priv->agent_volume_record_sync = FALSE;
> -        return;
> -    }
> -
> -    array_size = sizeof(uint16_t) * nchannels;
> -    avs = g_malloc0(sizeof(VDAgentAudioVolumeSync) + array_size);
> -    avs->is_playback = FALSE;
> -    avs->mute = mute;
> -    avs->nchannels = nchannels;
> -    memcpy(avs->volume, volume, array_size);
> -
> -    SPICE_DEBUG("%s mute=%s nchannels=%u volume[0]=%u",
> -                __func__, spice_yes_no(mute), nchannels, volume[0]);
> -    g_free(volume);
> -    agent_msg_queue(main_channel, VD_AGENT_AUDIO_VOLUME_SYNC,
> -                    sizeof(VDAgentAudioVolumeSync) + array_size, avs);
> -}
> -
> -static void agent_sync_audio_record(SpiceMainChannel *main_channel)
> -{
> -    SpiceSession *session =
> spice_channel_get_session(SPICE_CHANNEL(main_channel));
> -    SpiceAudio *audio = spice_audio_get(session, NULL);
> -    SpiceMainChannelPrivate *c = main_channel->priv;
> -
> -    if (!test_agent_cap(main_channel, VD_AGENT_CAP_AUDIO_VOLUME_SYNC) ||
> -        c->agent_volume_record_sync == TRUE) {
> -        SPICE_DEBUG("%s - is not going to sync audio with guest", __func__);
> -        return;
> -    }
> -    /* only one per connection */
> -    g_cancellable_reset(c->cancellable_volume_info);
> -    c->agent_volume_record_sync = TRUE;
> -    spice_audio_get_record_volume_info_async(audio,
> c->cancellable_volume_info, main_channel,
> -                                             audio_record_volume_info_cb,
> main_channel);
> -}
> -
> -/* any context: the message is not flushed immediately,
> -   you can wakeup() the channel coroutine or send_msg_queue() */
> -static void agent_display_config(SpiceMainChannel *channel)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    VDAgentDisplayConfig config = { 0, };
> -
> -    if (c->display_disable_wallpaper) {
> -        config.flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_WALLPAPER;
> -    }
> -
> -    if (c->display_disable_font_smooth) {
> -        config.flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_FONT_SMOOTH;
> -    }
> -
> -    if (c->display_disable_animation) {
> -        config.flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_ANIMATION;
> -    }
> -
> -    if (c->display_color_depth != 0) {
> -        config.flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_SET_COLOR_DEPTH;
> -        config.depth = c->display_color_depth;
> -    }
> -
> -    CHANNEL_DEBUG(channel, "display_config: flags: %u, depth: %u",
> config.flags, config.depth);
> -
> -    agent_msg_queue(channel, VD_AGENT_DISPLAY_CONFIG,
> sizeof(VDAgentDisplayConfig), &config);
> -}
> -
> -/* any context: the message is not flushed immediately,
> -   you can wakeup() the channel coroutine or send_msg_queue() */
> -static void agent_announce_caps(SpiceMainChannel *channel)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    VDAgentAnnounceCapabilities *caps;
> -    size_t size;
> -
> -    if (!c->agent_connected)
> -        return;
> -
> -    size = sizeof(VDAgentAnnounceCapabilities) + VD_AGENT_CAPS_BYTES;
> -    caps = g_malloc0(size);
> -    if (!c->agent_caps_received)
> -        caps->request = 1;
> -    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MOUSE_STATE);
> -    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MONITORS_CONFIG);
> -    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_REPLY);
> -    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_DISPLAY_CONFIG);
> -    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND);
> -    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_SELECTION);
> -
> -    agent_msg_queue(channel, VD_AGENT_ANNOUNCE_CAPABILITIES, size, caps);
> -    g_free(caps);
> -}
> -
> -/* any context: the message is not flushed immediately,
> -   you can wakeup() the channel coroutine or send_msg_queue() */
> -static void agent_clipboard_grab(SpiceMainChannel *channel, guint selection,
> -                                 guint32 *types, int ntypes)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    guint8 *msg;
> -    VDAgentClipboardGrab *grab;
> -    size_t size;
> -    int i;
> -
> -    if (!c->agent_connected)
> -        return;
> -
> -    g_return_if_fail(test_agent_cap(channel,
> VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
> -
> -    size = sizeof(VDAgentClipboardGrab) + sizeof(uint32_t) * ntypes;
> -    if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
> -        size += 4;
> -    } else if (selection != VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) {
> -        CHANNEL_DEBUG(channel, "Ignoring clipboard grab");
> -        return;
> -    }
> -
> -    msg = g_alloca(size);
> -    memset(msg, 0, size);
> -
> -    grab = (VDAgentClipboardGrab *)msg;
> -
> -    if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
> -        msg[0] = selection;
> -        grab = (VDAgentClipboardGrab *)(msg + 4);
> -    }
> -
> -    for (i = 0; i < ntypes; i++) {
> -        grab->types[i] = types[i];
> -    }
> -
> -    agent_msg_queue(channel, VD_AGENT_CLIPBOARD_GRAB, size, msg);
> -}
> -
> -/* any context: the message is not flushed immediately,
> -   you can wakeup() the channel coroutine or send_msg_queue() */
> -static void agent_clipboard_notify(SpiceMainChannel *self, guint selection,
> -                                   guint32 type, const guchar *data, size_t
> size)
> -{
> -    SpiceMainChannelPrivate *c = self->priv;
> -    VDAgentClipboard *cb;
> -    guint8 *msg;
> -    size_t msgsize;
> -    gint max_clipboard = spice_main_get_max_clipboard(self);
> -
> -    g_return_if_fail(c->agent_connected);
> -    g_return_if_fail(test_agent_cap(self,
> VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
> -    g_return_if_fail(max_clipboard == -1 || size < max_clipboard);
> -
> -    msgsize = sizeof(VDAgentClipboard);
> -    if (test_agent_cap(self, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
> -        msgsize += 4;
> -    } else if (selection != VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) {
> -        CHANNEL_DEBUG(self, "Ignoring clipboard notify");
> -        return;
> -    }
> -
> -    msg = g_alloca(msgsize);
> -    memset(msg, 0, msgsize);
> -
> -    cb = (VDAgentClipboard *)msg;
> -
> -    if (test_agent_cap(self, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
> -        msg[0] = selection;
> -        cb = (VDAgentClipboard *)(msg + 4);
> -    }
> -
> -    cb->type = type;
> -    agent_msg_queue_many(self, VD_AGENT_CLIPBOARD, msg, msgsize, data, size,
> NULL);
> -}
> -
> -/* any context: the message is not flushed immediately,
> -   you can wakeup() the channel coroutine or send_msg_queue() */
> -static void agent_clipboard_request(SpiceMainChannel *channel, guint
> selection, guint32 type)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    VDAgentClipboardRequest *request;
> -    guint8 *msg;
> -    size_t msgsize;
> -
> -    g_return_if_fail(c->agent_connected);
> -    g_return_if_fail(test_agent_cap(channel,
> VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
> -
> -    msgsize = sizeof(VDAgentClipboardRequest);
> -    if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
> -        msgsize += 4;
> -    } else if (selection != VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) {
> -        SPICE_DEBUG("Ignoring clipboard request");
> -        return;
> -    }
> -
> -    msg = g_alloca(msgsize);
> -    memset(msg, 0, msgsize);
> -
> -    request = (VDAgentClipboardRequest *)msg;
> -
> -    if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
> -        msg[0] = selection;
> -        request = (VDAgentClipboardRequest *)(msg + 4);
> -    }
> -
> -    request->type = type;
> -
> -    agent_msg_queue(channel, VD_AGENT_CLIPBOARD_REQUEST, msgsize, msg);
> -}
> -
> -/* any context: the message is not flushed immediately,
> -   you can wakeup() the channel coroutine or send_msg_queue() */
> -static void agent_clipboard_release(SpiceMainChannel *channel, guint
> selection)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    guint8 msg[4] = { 0, };
> -    guint8 msgsize = 0;
> -
> -    g_return_if_fail(c->agent_connected);
> -    g_return_if_fail(test_agent_cap(channel,
> VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
> -
> -    if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
> -        msg[0] = selection;
> -        msgsize += 4;
> -    } else if (selection != VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) {
> -        SPICE_DEBUG("Ignoring clipboard release");
> -        return;
> -    }
> -
> -    agent_msg_queue(channel, VD_AGENT_CLIPBOARD_RELEASE, msgsize, msg);
> -}
> -
> -/* main context*/
> -static gboolean timer_set_display(gpointer data)
> -{
> -    SpiceMainChannel *channel = data;
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    SpiceSession *session;
> -    gint i;
> -
> -    c->timer_id = 0;
> -    if (!c->agent_connected)
> -        return FALSE;
> -
> -    session = spice_channel_get_session(SPICE_CHANNEL(channel));
> -
> -    /* ensure we have an explicit monitor configuration at least for
> -       number of display channels */
> -    for (i = 0; i < spice_session_get_n_display_channels(session); i++)
> -        if (!c->display[i].enabled_set) {
> -            SPICE_DEBUG("Not sending monitors config, missing monitors");
> -            return FALSE;
> -        }
> -
> -    spice_main_send_monitor_config(channel);
> -
> -    return FALSE;
> -}
> -
> -/* any context  */
> -static void update_display_timer(SpiceMainChannel *channel, guint seconds)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -
> -    if (c->timer_id)
> -        g_source_remove(c->timer_id);
> -
> -    c->timer_id = g_timeout_add_seconds(seconds, timer_set_display,
> channel);
> -}
> -
> -/* coroutine context  */
> -static void set_agent_connected(SpiceMainChannel *channel, gboolean
> connected)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -
> -    SPICE_DEBUG("agent connected: %s", spice_yes_no(connected));
> -    if (connected != c->agent_connected) {
> -        c->agent_connected = connected;
> -        g_coroutine_object_notify(G_OBJECT(channel), "agent-connected");
> -    }
> -    if (!connected)
> -        spice_main_channel_reset_agent(SPICE_MAIN_CHANNEL(channel));
> -
> -    g_coroutine_signal_emit(channel, signals[SPICE_MAIN_AGENT_UPDATE], 0);
> -}
> -
> -/* coroutine context  */
> -static void agent_start(SpiceMainChannel *channel)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -    SpiceMsgcMainAgentStart agent_start = {
> -        .num_tokens = ~0,
> -    };
> -    SpiceMsgOut *out;
> -
> -    c->agent_volume_playback_sync = FALSE;
> -    c->agent_volume_record_sync = FALSE;
> -    c->agent_caps_received = false;
> -    set_agent_connected(channel, TRUE);
> -
> -    out = spice_msg_out_new(SPICE_CHANNEL(channel),
> SPICE_MSGC_MAIN_AGENT_START);
> -    out->marshallers->msgc_main_agent_start(out->marshaller, &agent_start);
> -    spice_msg_out_send_internal(out);
> -
> -    if (c->agent_connected) {
> -        agent_announce_caps(channel);
> -        agent_send_msg_queue(channel);
> -    }
> -}
> -
> -/* coroutine context  */
> -static void agent_stopped(SpiceMainChannel *channel)
> -{
> -    set_agent_connected(channel, FALSE);
> -}
> -
> -/* coroutine context */
> -static void set_mouse_mode(SpiceMainChannel *channel, uint32_t supported,
> uint32_t current)
> -{
> -    SpiceMainChannelPrivate *c = channel->priv;
> -
> -    if (c->mouse_mode != current) {
> -        c->mouse_mode = current;
> -        g_coroutine_signal_emit(channel, signals[SPICE_MAIN_MOUSE_UPDATE],
> 0);
> -        g_coroutine_object_notify(G_OBJECT(channel), "mouse-mode");
> -    }
> -
> -    /* switch to client mode if possible */
> -    if (!spice_channel_get_read_only(SPICE_CHANNEL(channel)) &&
> -        supported & SPICE_MOUSE_MODE_CLIENT &&
> -        current != SPICE_MOUSE_MODE_CLIENT) {
> -        SpiceMsgcMainMouseModeRequest req = {
> -            .mode = SPICE_MOUSE_MODE_CLIENT,
> -        };
> -        SpiceMsgOut *out;
> -
> -        out = spice_msg_out_new(SPICE_CHANNEL(channel),
> SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST);
> -        out->marshallers->msgc_main_mouse_mode_request(out->marshaller,
> &req);
> -        spice_msg_out_send_internal(out);
> -    }
> -}
> -
> -/* coroutine context */
> -static void main_handle_init(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
> -    SpiceMsgMainInit *init = spice_msg_in_parsed(in);
> -    SpiceSession *session;
> -    SpiceMsgOut *out;
> -
> -    session = spice_channel_get_session(channel);
> -    spice_session_set_connection_id(session, init->session_id);
> -
> -    set_mouse_mode(SPICE_MAIN_CHANNEL(channel), init->supported_mouse_modes,
> -                   init->current_mouse_mode);
> -
> -    spice_session_set_mm_time(session, init->multi_media_time);
> -    spice_session_set_caches_hints(session, init->ram_hint,
> init->display_channels_hint);
> -
> -    c->agent_tokens = init->agent_tokens;
> -    if (init->agent_connected)
> -        agent_start(SPICE_MAIN_CHANNEL(channel));
> -
> -    if (spice_session_migrate_after_main_init(session))
> -        return;
> -
> -    out = spice_msg_out_new(SPICE_CHANNEL(channel),
> SPICE_MSGC_MAIN_ATTACH_CHANNELS);
> -    spice_msg_out_send_internal(out);
> -}
> -
> -/* coroutine context */
> -static void main_handle_name(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgMainName *name = spice_msg_in_parsed(in);
> -    SpiceSession *session = spice_channel_get_session(channel);
> -
> -    SPICE_DEBUG("server name: %s", name->name);
> -    spice_session_set_name(session, (const gchar *)name->name);
> -}
> -
> -/* coroutine context */
> -static void main_handle_uuid(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgMainUuid *uuid = spice_msg_in_parsed(in);
> -    SpiceSession *session = spice_channel_get_session(channel);
> -    gchar *uuid_str = spice_uuid_to_string(uuid->uuid);
> -
> -    SPICE_DEBUG("server uuid: %s", uuid_str);
> -    spice_session_set_uuid(session, uuid->uuid);
> -
> -    g_free(uuid_str);
> -}
> -
> -/* coroutine context */
> -static void main_handle_mm_time(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceSession *session;
> -    SpiceMsgMainMultiMediaTime *msg = spice_msg_in_parsed(in);
> -
> -    session = spice_channel_get_session(channel);
> -    spice_session_set_mm_time(session, msg->time);
> -}
> -
> -typedef struct channel_new {
> -    SpiceSession *session;
> -    int type;
> -    int id;
> -} channel_new_t;
> -
> -/* main context */
> -static gboolean _channel_new(channel_new_t *c)
> -{
> -    g_return_val_if_fail(c != NULL, FALSE);
> -
> -    spice_channel_new(c->session, c->type, c->id);
> -
> -    g_object_unref(c->session);
> -    g_free(c);
> -
> -    return FALSE;
> -}
> -
> -/* coroutine context */
> -static void main_handle_channels_list(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgChannels *msg = spice_msg_in_parsed(in);
> -    SpiceSession *session;
> -    int i;
> -
> -    session = spice_channel_get_session(channel);
> -
> -    /* guarantee that uuid is notified before setting up the channels, even
> if
> -     * the server is older and doesn't actually send the uuid */
> -    g_coroutine_object_notify(G_OBJECT(session), "uuid");
> -
> -    for (i = 0; i < msg->num_of_channels; i++) {
> -        channel_new_t *c;
> -
> -        c = g_new(channel_new_t, 1);
> -        c->session = g_object_ref(session);
> -        c->type = msg->channels[i].type;
> -        c->id = msg->channels[i].id;
> -        /* no need to explicitely switch to main context, since
> -           synchronous call is not needed. */
> -        /* no need to track idle, session is refed */
> -        g_idle_add((GSourceFunc)_channel_new, c);
> -    }
> -}
> -
> -/* coroutine context */
> -static void main_handle_mouse_mode(SpiceChannel *channel, SpiceMsgIn *in)
> -{
> -    SpiceMsgMainMouseMode *msg = spice_msg_in_parsed(in);
> -    set_mouse_mode(SPICE_MAIN_CHANNEL(channel), msg->supported_modes,
> msg->current_mode);
> -}
> -
> -/* coroutine context */
> -static void main_handle_agent_connected(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    agent_start(SPICE_MAIN_CHANNEL(channel));
> -}
> -
> -/* coroutine context */
> -static void main_handle_agent_connected_tokens(SpiceChannel *channel,
> SpiceMsgIn *in)
> -{
> -    SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
> -    SpiceMsgMainAgentConnectedTokens *msg = spice_msg_in_parsed(in);
> -
> -    c->agent_tokens = msg->num_tokens;
> -    agent_start(SPICE_MAIN_CHANNEL(channel));
> -}
> -
> -/* coroutine context */
> -static void main_handle_agent_disconnected(SpiceChannel *channel, SpiceMsgIn
> *in)
> -{
> -    agent_stopped(SPICE_MAIN_CHANNEL(channel));
> -}
> -
> -static void file_xfer_task_free(SpiceFileXferTask *task)
> -{
> -    SpiceMainChannelPrivate *c;
> -
> -    g_return_if_fail(task != NULL);
> -
> -    c = task->channel->priv;
> -    g_hash_table_remove(c->file_xfer_tasks, GUINT_TO_POINTER(task->id));
> -
> -    g_clear_object(&task->channel);
> -    g_clear_object(&task->file);
> -    g_clear_object(&task->file_stream);
> -    g_free(task);
> -}
> -
> -/* main context */
> -static void file_xfer_close_cb(GObject      *object,
> -
> 
> [Message truncated]
> 
> 


More information about the Spice-devel mailing list