From: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> The spice-controller was a small library to let NPAPI browser plugins communicate with the spice client. Due to usage of vala, the library could not promise ABI stability, and was also considerer a pretty poor implementation. Furthermore, major browser vendors began to phase out NPAPI support in 2013, and some would like to see it gone by the end of this year (realistically, it may not happen though). As an alternative, remote-viewer (the first class Spice client) learned to connect with a file of mime type application/x-virt-viewer, as early as February 2013 with v0.5.5. I also proposed a DBus controller, and a simpler way to pass connection details via stdin. Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> --- Makefile.am | 4 - configure.ac | 9 - data/Makefile.am | 4 - data/org.spicespace.spicy.json | 2 +- data/spice-protocol.vapi | 210 ----------------- doc/reference/Makefile.am | 1 - spice-controller.pc.in | 12 - src/Makefile.am | 4 - src/controller/Makefile.am | 103 --------- src/controller/controller.vala | 286 ----------------------- src/controller/custom.h | 22 -- src/controller/custom.vapi | 28 --- src/controller/dump.c | 115 ---------- 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 | 330 --------------------------- 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 | 289 ----------------------- src/controller/util.vala | 42 ---- src/controller/win32-util.c | 161 ------------- src/controller/win32-util.h | 30 --- 30 files changed, 1 insertion(+), 3100 deletions(-) delete mode 100644 data/spice-protocol.vapi delete mode 100644 spice-controller.pc.in delete mode 100644 src/controller/Makefile.am delete mode 100644 src/controller/controller.vala delete mode 100644 src/controller/custom.h delete mode 100644 src/controller/custom.vapi delete mode 100644 src/controller/dump.c delete mode 100644 src/controller/foreign-menu.vala delete mode 100644 src/controller/gio-windows-2.0.vapi delete mode 100644 src/controller/menu.vala delete mode 100644 src/controller/namedpipe.c delete mode 100644 src/controller/namedpipe.h delete mode 100644 src/controller/namedpipeconnection.c delete mode 100644 src/controller/namedpipeconnection.h delete mode 100644 src/controller/namedpipelistener.c delete mode 100644 src/controller/namedpipelistener.h delete mode 100644 src/controller/spice-controller-listener.c delete mode 100644 src/controller/spice-controller-listener.h delete mode 100644 src/controller/spice-foreign-menu-listener.c delete mode 100644 src/controller/spice-foreign-menu-listener.h delete mode 100644 src/controller/test.c delete mode 100644 src/controller/util.vala delete mode 100644 src/controller/win32-util.c delete mode 100644 src/controller/win32-util.h diff --git a/Makefile.am b/Makefile.am index ccb81aa..8717cbc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,10 +22,6 @@ if WITH_GTK pkgconfig_DATA += spice-client-gtk-3.0.pc endif -if WITH_CONTROLLER -pkgconfig_DATA += spice-controller.pc -endif - DISTCLEANFILES = $(pkgconfig_DATA) EXTRA_DIST = \ diff --git a/configure.ac b/configure.ac index f915d81..4a4e8a6 100644 --- a/configure.ac +++ b/configure.ac @@ -523,13 +523,6 @@ m4_ifdef([GOBJECT_INTROSPECTION_CHECK],[ ]) AM_CONDITIONAL([G_IR_SCANNER_SYMBOL_PREFIX], [test "x$has_symbol_prefix" = "xyes"]) -AC_ARG_ENABLE([controller], - AS_HELP_STRING([--enable-controller], [Enable controller build @<:@default=yes@:>@]), - [], - enable_controller="yes") - -AM_CONDITIONAL(WITH_CONTROLLER, [test "x$enable_controller" != "xno"]) - AC_ARG_ENABLE([vala], AS_HELP_STRING([--enable-vala], [Check for vala requirements @<:@default=no@:>@]), [], @@ -604,12 +597,10 @@ AC_OUTPUT([ Makefile spice-client-glib-2.0.pc spice-client-gtk-3.0.pc -spice-controller.pc data/Makefile po/Makefile.in src/Makefile src/spice-version.h -src/controller/Makefile tools/Makefile doc/Makefile doc/reference/Makefile diff --git a/data/Makefile.am b/data/Makefile.am index 06592de..59e90f9 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,13 +1,9 @@ NULL= EXTRA_DIST = \ - spice-protocol.vapi \ org.spice-space.lowlevelusbaccess.policy \ $(NULL) -vapidir = $(VAPIDIR) -vapi_DATA = spice-protocol.vapi - policydir = $(POLICYDIR) policy_DATA = org.spice-space.lowlevelusbaccess.policy diff --git a/data/org.spicespace.spicy.json b/data/org.spicespace.spicy.json index 1e03bf9..064b9a6 100644 --- a/data/org.spicespace.spicy.json +++ b/data/org.spicespace.spicy.json @@ -58,7 +58,7 @@ "PYTHONPATH": "/app" } }, - "config-opts": [ "--disable-controller", "--disable-vala", + "config-opts": [ "--disable-vala", "--disable-gtk-doc", "--enable-python-checks" ], "sources": [ { diff --git a/data/spice-protocol.vapi b/data/spice-protocol.vapi deleted file mode 100644 index cca03ed..0000000 --- a/data/spice-protocol.vapi +++ /dev/null @@ -1,210 +0,0 @@ -namespace SpiceProtocol { - [CCode (cprefix = "Controller", cheader_filename = "spice/controller_prot.h")] - namespace Controller { - [CCode (cname = "CONTROLLER_MAGIC")] - public const uint32 MAGIC; - [CCode (cname = "CONTROLLER_VERSION")] - public const int VERSION; - - [Compact] - public struct InitHeader { - uint32 magic; - uint32 version; - uint32 size; - } - - [Compact] - public struct Init { - InitHeader base; - uint64 credentials; - uint32 flags; - } - - [CCode (cprefix = "CONTROLLER_FLAG_")] - [Flags] - public enum Flag { - EXCLUSIVE, - } - - [Compact] - public struct Msg { - uint32 id; - uint32 size; - } - - [CCode (cprefix = "CONTROLLER_")] - public enum MsgId { - //external app -> spice client - HOST, - PORT, - SPORT, - PASSWORD, - - SECURE_CHANNELS, - DISABLE_CHANNELS, - - TLS_CIPHERS, - CA_FILE, - HOST_SUBJECT, - - FULL_SCREEN, - SET_TITLE, - - CREATE_MENU, - DELETE_MENU, - - HOTKEYS, - SEND_CAD, - - CONNECT, - SHOW, - HIDE, - - ENABLE_SMARTCARD, - - ENABLE_USB, - ENABLE_USB_AUTOSHARE, - USB_FILTER, - - PROXY, - - //spice client -> external app - MENU_ITEM_CLICK, - - COLOR_DEPTH, - DISABLE_EFFECTS, - } - - [CCode (cname = "unsigned int", cprefix = "CONTROLLER_", has_type_id = false)] - [Flags] - public enum Display { - SET_FULL_SCREEN, - AUTO_DISPLAY_RES, - } - - [Compact] - [CCode (cname = "ControllerValue")] - public struct MsgValue: Msg { - Msg base; - uint32 value; - } - - [Compact] - [CCode (cname = "ControllerData")] - public struct MsgData { - Msg base; - uint8 data[0]; - } - - [CCode (cname = "CONTROLLER_MENU_ITEM_DELIMITER")] - public static string MENU_ITEM_DELIMITER; - [CCode (cname = "CONTROLLER_MENU_PARAM_DELIMITER")] - public static string MENU_PARAM_DELIMITER; - - [CCode (cname = "SPICE_MENU_INTERNAL_ID_BASE")] - public static int MENU_INTERNAL_ID_BASE; - [CCode (cname = "SPICE_MENU_INTERNAL_ID_SHIFT")] - public static int MENU_INTERNAL_ID_SHIFT; - - [CCode (cprefix = "CONTROLLER_MENU_FLAGS_", cname = "unsigned int", has_type_id = false)] - [Flags] - public enum MenuFlags { - SEPARATOR, - DISABLED, - POPUP, - CHECKED, - GRAYED, - } - } - - [CCode (cprefix = "FrgMenu", cheader_filename = "spice/foreign_menu_prot.h")] - namespace ForeignMenu { - [CCode (cname = "FOREIGN_MENU_MAGIC")] - public const uint32 MAGIC; - [CCode (cname = "FOREIGN_MENU_VERSION")] - public const int VERSION; - - [Compact] - public struct InitHeader { - uint32 magic; - uint32 version; - uint32 size; - } - - [Compact] - [CCode (has_destroy_function = false)] - public struct Init { - InitHeader base; - uint64 credentials; - string title; // utf8 - } - - [Compact] - public struct Msg { - uint32 id; - uint32 size; - } - - [CCode (cprefix = "FOREIGN_MENU_", cname = "int")] - public enum MsgId { - //external app -> spice client - SET_TITLE, - ADD_ITEM, - MODIFY_ITEM, - REMOVE_ITEM, - CLEAR, - - //spice client -> external app - ITEM_EVENT, - APP_ACTIVATED, - APP_DEACTIVATED, - } - - [Compact] - [CCode (cname = "FrgMenuSetTitle")] - public struct SetTitle { - Msg base; - string string; // utf8 - } - - [CCode (cprefix = "FOREIGN_MENU_ITEM_TYPE_", cname = "unsigned int", has_type_id = false)] - [Flags] - public enum MenuFlags { - CHECKED, - DIM, - SEPARATOR - } - - [Compact] - [CCode (cname = "FrgMenuAddItem")] - public struct AddItem { - Msg base; - uint32 id; - uint32 type; - uint32 position; - string string; // utf8 - } - - [Compact] - [CCode (cname = "FrgMenuRmItem")] - public struct RmItem { - Msg base; - uint32 id; - } - - [CCode (cprefix = "FOREIGN_MENU_EVENT_", cname = "int")] - public enum EventType { - CLICK, - CHECKED, - UNCHECKED, - } - - [Compact] - [CCode (cname = "FrgMenuEvent")] - public struct Event { - Msg base; - uint32 id; - uint32 action; - } - } -} diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am index 999c1dc..c7d09f0 100644 --- a/doc/reference/Makefile.am +++ b/doc/reference/Makefile.am @@ -28,7 +28,6 @@ IGNORE_HFILES= \ channel-usbredir-priv.h \ client_sw_canvas.h \ continuation.h \ - controller \ coroutine.h \ decode.h \ desktop-integration.h \ diff --git a/spice-controller.pc.in b/spice-controller.pc.in deleted file mode 100644 index 7dfe4b4..0000000 --- a/spice-controller.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: spice-controller -Description: SPICE Client controller library -Version: @VERSION@ - -Requires: glib-2.0 -Libs: -L${libdir} -lspice-controller -Cflags: -I${includedir}/spice-controller diff --git a/src/Makefile.am b/src/Makefile.am index 5430d84..4dbc2eb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,10 +1,6 @@ NULL = SUBDIRS = -if WITH_CONTROLLER -SUBDIRS += controller -endif - KEYMAPS = \ vncdisplaykeymap_xorgevdev2xtkbd.c \ vncdisplaykeymap_xorgkbd2xtkbd.c \ diff --git a/src/controller/Makefile.am b/src/controller/Makefile.am deleted file mode 100644 index c68373c..0000000 --- a/src/controller/Makefile.am +++ /dev/null @@ -1,103 +0,0 @@ -NULL = - -# FIXME: We need to disable the deprecation warnings until valac stops -# generating code that uses the deprecated GSimpleAsyncResult class. -AM_CPPFLAGS = \ - -DG_LOG_DOMAIN=\"GSpiceController\" \ - $(GIO_CFLAGS) \ - $(COMMON_CFLAGS) \ - -Wno-deprecated-declarations \ - $(NULL) - -# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html -AM_LDFLAGS = \ - -no-undefined \ - $(GIO_LIBS) \ - $(NULL) - -AM_VALAFLAGS = \ - --pkg gio-2.0 \ - --pkg spice-protocol --vapidir=$(top_srcdir)/data \ - --pkg custom --vapidir=$(srcdir) \ - -C \ - $(NULL) - -lib_LTLIBRARIES = libspice-controller.la -noinst_PROGRAMS = test-controller spice-controller-dump - -libspice_controller_la_VALASOURCES = \ - menu.vala \ - controller.vala \ - foreign-menu.vala \ - util.vala \ - $(NULL) - -libspice_controller_la_BUILT_SOURCES = \ - $(libspice_controller_la_VALASOURCES:.vala=.c) \ - spice-controller.h \ - $(NULL) - -BUILT_SOURCES = \ - $(libspice_controller_la_BUILT_SOURCES) \ - controller.vala.stamp \ - $(NULL) - -libspice_controller_la_SOURCES = \ - $(libspice_controller_la_BUILT_SOURCES) \ - custom.h \ - spice-controller-listener.c \ - spice-controller-listener.h \ - spice-foreign-menu-listener.c \ - spice-foreign-menu-listener.h \ - $(NULL) - -if OS_WIN32 -libspice_controller_la_SOURCES += \ - namedpipe.c \ - namedpipe.h \ - namedpipeconnection.c \ - namedpipeconnection.h \ - namedpipelistener.c \ - namedpipelistener.h \ - win32-util.c \ - win32-util.h \ - $(NULL) -endif -libspice_controller_la_LDFLAGS = \ - $(AM_LDFLAGS) \ - -version-info 0:0:0 \ - $(NULL) - -libspice_controllerincludedir = $(includedir)/spice-controller -libspice_controllerinclude_HEADERS = \ - spice-controller.h - -test_controller_SOURCES = test.c -test_controller_LDADD = libspice-controller.la - -spice_controller_dump_SOURCES = dump.c -spice_controller_dump_LDADD = libspice-controller.la - -controller.vala.stamp: $(libspice_controller_la_VALASOURCES) custom.vapi - @if test -z "$(VALAC)"; then \ - echo "" ; \ - echo " *** Error: missing valac!" ; \ - echo " *** You must run autogen.sh or configure --enable-vala" ; \ - echo "" ; \ - exit 1 ; \ - fi - $(VALA_V)$(VALAC) $(VALAFLAGS) $(AM_VALAFLAGS) \ - $(addprefix $(srcdir)/,$(libspice_controller_la_VALASOURCES)) \ - -H spice-controller.h - @touch $@ - -$(libspice_controller_la_BUILT_SOURCES): controller.vala.stamp - -EXTRA_DIST = \ - $(libspice_controller_la_VALASOURCES) \ - controller.vala.stamp \ - custom.vapi \ - gio-windows-2.0.vapi \ - $(NULL) - --include $(top_srcdir)/git.mk diff --git a/src/controller/controller.vala b/src/controller/controller.vala deleted file mode 100644 index 84b4527..0000000 --- a/src/controller/controller.vala +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright (C) 2011 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/>. - -using GLib; -using Custom; -using Win32; -using Spice; -using SpiceProtocol; - -namespace SpiceCtrl { - -public errordomain Error { - VALUE, -} - -public class Controller: Object { - public string host { private set; get; } - public uint32 port { private set; get; } - public uint32 sport { private set; get; } - public string password { private set; get; } - public SpiceProtocol.Controller.Display display_flags { private set; get; } - public string tls_ciphers { private set; get; } - public string host_subject { private set; get; } - public string ca_file { private set; get; } - public string title { private set; get; } - public string hotkeys { private set; get; } - public string[] secure_channels { private set; get; } - public string[] disable_channels { private set; get; } - public SpiceCtrl.Menu? menu { private set; get; } - public bool enable_smartcard { private set; get; } - public bool send_cad { private set; get; } - public string[] disable_effects {private set; get; } - public uint32 color_depth {private set; get; } - public bool enable_usbredir { private set; get; } - public bool enable_usb_autoshare { private set; get; } - public string usb_filter { private set; get; } - public string proxy { private set; get; } - - public signal void do_connect (); - public signal void show (); - public signal void hide (); - - public signal void client_connected (); - - public void menu_item_click_msg (int32 item_id) { - var msg = SpiceProtocol.Controller.MsgValue (); - msg.base.size = (uint32)sizeof (SpiceProtocol.Controller.MsgValue); - msg.base.id = SpiceProtocol.Controller.MsgId.MENU_ITEM_CLICK; - msg.value = item_id; - unowned uint8[] p = ((uint8[])(&msg))[0:msg.base.size]; - send_msg.begin (p); - } - - public async bool send_msg (uint8[] p) throws GLib.Error { - // vala FIXME: pass Controller.Msg instead - // vala doesn't keep reference on the struct in async methods - // it copies only base, which is not enough to transmit the whole - // message. - try { - if (excl_connection != null) { - yield output_stream_write (excl_connection.output_stream, p); - } else { - foreach (var c in clients) - yield output_stream_write (c.output_stream, p); - } - } catch (GLib.Error e) { - warning (e.message); - } - - return true; - } - - private GLib.IOStream? excl_connection; - private int nclients; - List<IOStream> clients; - - private bool handle_message (SpiceProtocol.Controller.Msg* msg) { - var v = (SpiceProtocol.Controller.MsgValue*)(msg); - var d = (SpiceProtocol.Controller.MsgData*)(msg); - unowned string str = (string)(&d.data); - - switch (msg.id) { - case SpiceProtocol.Controller.MsgId.HOST: - host = str; - debug ("got HOST: %s".printf (str)); - break; - case SpiceProtocol.Controller.MsgId.PORT: - port = v.value; - debug ("got PORT: %u".printf (port)); - break; - case SpiceProtocol.Controller.MsgId.SPORT: - sport = v.value; - debug ("got SPORT: %u".printf (sport)); - break; - case SpiceProtocol.Controller.MsgId.PASSWORD: - password = str; - debug ("got PASSWORD"); - break; - - case SpiceProtocol.Controller.MsgId.SECURE_CHANNELS: - secure_channels = str.split(","); - debug ("got SECURE_CHANNELS %s".printf (str)); - break; - - case SpiceProtocol.Controller.MsgId.DISABLE_CHANNELS: - disable_channels = str.split(","); - debug ("got DISABLE_CHANNELS %s".printf (str)); - break; - - case SpiceProtocol.Controller.MsgId.TLS_CIPHERS: - tls_ciphers = str; - debug ("got TLS_CIPHERS %s".printf (str)); - break; - case SpiceProtocol.Controller.MsgId.CA_FILE: - ca_file = str; - debug ("got CA_FILE %s".printf (str)); - break; - case SpiceProtocol.Controller.MsgId.HOST_SUBJECT: - host_subject = str; - debug ("got HOST_SUBJECT %s".printf (str)); - break; - - case SpiceProtocol.Controller.MsgId.FULL_SCREEN: - display_flags = (SpiceProtocol.Controller.Display)v.value; - debug ("got FULL_SCREEN 0x%x".printf (v.value)); - break; - case SpiceProtocol.Controller.MsgId.SET_TITLE: - title = str; - debug ("got TITLE %s".printf (str)); - break; - case SpiceProtocol.Controller.MsgId.ENABLE_SMARTCARD: - enable_smartcard = (bool)v.value; - debug ("got ENABLE_SMARTCARD 0x%x".printf (v.value)); - break; - - case SpiceProtocol.Controller.MsgId.CREATE_MENU: - menu = new SpiceCtrl.Menu.from_string (str); - debug ("got CREATE_MENU %s".printf (str)); - break; - case SpiceProtocol.Controller.MsgId.DELETE_MENU: - menu = null; - debug ("got DELETE_MENU request"); - break; - - case SpiceProtocol.Controller.MsgId.SEND_CAD: - send_cad = (bool)v.value; - debug ("got SEND_CAD %u".printf (v.value)); - break; - - case SpiceProtocol.Controller.MsgId.HOTKEYS: - hotkeys = str; - debug ("got HOTKEYS %s".printf (str)); - break; - - case SpiceProtocol.Controller.MsgId.COLOR_DEPTH: - color_depth = v.value; - debug ("got COLOR_DEPTH %u".printf (v.value)); - break; - case SpiceProtocol.Controller.MsgId.DISABLE_EFFECTS: - disable_effects = str.split(","); - debug ("got DISABLE_EFFECTS %s".printf (str)); - break; - - case SpiceProtocol.Controller.MsgId.CONNECT: - do_connect (); - debug ("got CONNECT request"); - break; - case SpiceProtocol.Controller.MsgId.SHOW: - show (); - debug ("got SHOW request"); - break; - case SpiceProtocol.Controller.MsgId.HIDE: - hide (); - debug ("got HIDE request"); - break; - case SpiceProtocol.Controller.MsgId.ENABLE_USB: - enable_usbredir = (bool)v.value; - debug ("got ENABLE_USB %u".printf (v.value)); - break; - case SpiceProtocol.Controller.MsgId.ENABLE_USB_AUTOSHARE: - enable_usb_autoshare = (bool)v.value; - debug ("got ENABLE_USB_AUTOSHARE %u".printf (v.value)); - break; - case SpiceProtocol.Controller.MsgId.USB_FILTER: - usb_filter = str; - debug ("got USB_FILTER %s".printf (str)); - break; - case SpiceProtocol.Controller.MsgId.PROXY: - proxy = str; - debug ("got PROXY %s".printf (str)); - break; - default: - debug ("got unknown msg.id %u".printf (msg.id)); - warn_if_reached (); - return false; - } - return true; - } - - private async void handle_client (IOStream c) throws GLib.Error { - var excl = false; - - debug ("new socket client, reading init header"); - - var p = new uint8[sizeof(SpiceProtocol.Controller.Init)]; - var init = (SpiceProtocol.Controller.Init*)p; - yield input_stream_read (c.input_stream, p); - if (warn_if (init.base.magic != SpiceProtocol.Controller.MAGIC)) - return; - if (warn_if (init.base.version != SpiceProtocol.Controller.VERSION)) - return; - if (warn_if (init.base.size < sizeof (SpiceProtocol.Controller.Init))) - return; - if (warn_if (init.credentials != 0)) - return; - if (warn_if (excl_connection != null)) - return; - - excl = (bool)(init.flags & SpiceProtocol.Controller.Flag.EXCLUSIVE); - if (excl) { - if (nclients > 1) { - warning (@"Can't make the client exclusive, there is already $nclients connected clients"); - return; - } - excl_connection = c; - } - - client_connected (); - - for (;;) { - var t = new uint8[sizeof(SpiceProtocol.Controller.Msg)]; - yield input_stream_read (c.input_stream, t); - var msg = (SpiceProtocol.Controller.Msg*)t; - debug ("new message " + msg.id.to_string () + "size " + msg.size.to_string ()); - if (warn_if (msg.size < sizeof (SpiceProtocol.Controller.Msg))) - break; - - if (msg.size > sizeof (SpiceProtocol.Controller.Msg)) { - t.resize ((int)msg.size); - msg = (SpiceProtocol.Controller.Msg*)t; - yield input_stream_read (c.input_stream, t[sizeof(SpiceProtocol.Controller.Msg):msg.size]); - } - - handle_message (msg); - } - - if (excl) - excl_connection = null; - } - - public Controller() { - } - - public async void listen (string? addr = null) throws GLib.Error, SpiceCtrl.Error - { - var listener = ControllerListener.new_listener (addr); - - for (;;) { - var c = yield listener.accept_async (); - nclients += 1; - clients.append (c); - try { - yield handle_client (c); - } catch (GLib.Error e) { - warning (e.message); - } - c.close (); - clients.remove (c); - nclients -= 1; - } - } -} - -} // SpiceCtrl diff --git a/src/controller/custom.h b/src/controller/custom.h deleted file mode 100644 index 7f849fc..0000000 --- a/src/controller/custom.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CUSTOM_H_ -#define CUSTOM_H_ - -#include <glib.h> - -static inline gboolean g_warn_if_expr (gboolean condition, - const char *pretty_func, - const char *expression) { - if G_UNLIKELY(condition) { - g_log (G_LOG_DOMAIN, - G_LOG_LEVEL_CRITICAL, - "%s: `%s' condition reached", - pretty_func, - expression); - } - - return condition; -} - -#define g_warn_if(expr) g_warn_if_expr((expr), __PRETTY_FUNCTION__, #expr) - -#endif diff --git a/src/controller/custom.vapi b/src/controller/custom.vapi deleted file mode 100644 index a12fdec..0000000 --- a/src/controller/custom.vapi +++ /dev/null @@ -1,28 +0,0 @@ -using GLib; - -namespace Custom { - - [CCode (cname = "g_warn_if", cheader_filename = "custom.h")] - public bool warn_if(bool condition); -} - -namespace Spice { - - [CCode (cname = "GObject", ref_function = "g_object_ref", unref_function = "g_object_unref", free_function = "")] - class ControllerListener { - [CCode (cname = "spice_controller_listener_new", cheader_filename = "spice-controller-listener.h")] - public static ControllerListener new_listener (string addr) throws GLib.Error; - - [CCode (cname = "spice_controller_listener_accept_async", cheader_filename = "spice-controller-listener.h")] - public async unowned GLib.IOStream accept_async (GLib.Cancellable? cancellable = null, out GLib.Object? source_object = null) throws GLib.Error; - } - - [CCode (cname = "GObject", ref_function = "g_object_ref", unref_function = "g_object_unref", free_function = "")] - class ForeignMenuListener { - [CCode (cname = "spice_foreign_menu_listener_new", cheader_filename = "spice-foreign-menu-listener.h")] - public static ForeignMenuListener new_listener (string addr) throws GLib.Error; - - [CCode (cname = "spice_foreign_menu_listener_accept_async", cheader_filename = "spice-foreign-menu-listener.h")] - public async unowned GLib.IOStream accept_async (GLib.Cancellable? cancellable = null, out GLib.Object? source_object = null) throws GLib.Error; - } -} diff --git a/src/controller/dump.c b/src/controller/dump.c deleted file mode 100644 index b260264..0000000 --- a/src/controller/dump.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (C) 2011 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 <stdio.h> -#include <stdint.h> - -#ifdef WIN32 -#include <windows.h> -#else -#include <sys/socket.h> -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#include <sys/un.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#endif - -#include "spice-controller.h" - -SpiceCtrlController *ctrl = NULL; -SpiceCtrlForeignMenu *menu = NULL; -GMainLoop *loop = NULL; - -void signaled (GObject *gobject, const gchar *signal_name) -{ - g_message ("signaled: %s", signal_name); -} - -void notified (GObject *gobject, GParamSpec *pspec, - gpointer user_data) -{ - GValue value = { 0, }; - GValue strvalue = { 0, }; - - g_return_if_fail (gobject != NULL); - g_return_if_fail (pspec != NULL); - - g_value_init (&value, pspec->value_type); - g_value_init (&strvalue, G_TYPE_STRING); - g_object_get_property (gobject, pspec->name, &value); - - if (pspec->value_type == G_TYPE_STRV) { - gchar** p = (gchar **)g_value_get_boxed (&value); - g_message ("notify::%s == ", pspec->name); - while (*p) - g_message ("%s", *p++); - } else if (G_TYPE_IS_OBJECT(pspec->value_type)) { - GObject *o = g_value_get_object (&value); - g_message ("notify::%s == %s", pspec->name, o ? G_OBJECT_TYPE_NAME (o) : "null"); - } else { - g_value_transform (&value, &strvalue); - g_message ("notify::%s = %s", pspec->name, g_value_get_string (&strvalue)); - } - - g_value_unset (&value); - g_value_unset (&strvalue); -} - -void connect_signals (gpointer obj) -{ - guint i, n_ids = 0; - guint *ids = NULL; - GType type = G_OBJECT_TYPE (obj); - - ids = g_signal_list_ids (type, &n_ids); - for (i = 0; i < n_ids; i++) { - const gchar *name = g_signal_name (ids[i]); - g_signal_connect (obj, name, G_CALLBACK (signaled), (gpointer)name); - } -} - -int main (int argc, char *argv[]) -{ - loop = g_main_loop_new (NULL, FALSE); - - if (argc > 1 && g_str_equal(argv[1], "--menu")) { - menu = spice_ctrl_foreign_menu_new (); - g_signal_connect (menu, "notify", G_CALLBACK (notified), NULL); - connect_signals (menu); - - spice_ctrl_foreign_menu_listen (menu, NULL, NULL, NULL); - } else { - ctrl = spice_ctrl_controller_new (); - g_signal_connect (ctrl, "notify", G_CALLBACK (notified), NULL); - connect_signals (ctrl); - - spice_ctrl_controller_listen (ctrl, NULL, NULL, NULL); - } - - g_main_loop_run (loop); - - if (ctrl != NULL) - g_object_unref (ctrl); - if (menu != NULL) - g_object_unref (menu); - - return 0; -} diff --git a/src/controller/foreign-menu.vala b/src/controller/foreign-menu.vala deleted file mode 100644 index 005955a..0000000 --- a/src/controller/foreign-menu.vala +++ /dev/null @@ -1,197 +0,0 @@ -// 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/>. - -using Custom; - -namespace SpiceCtrl { - -public class ForeignMenu: Object { - - public Menu menu { get; private set; } - public string title { get; private set; } - - public signal void client_connected (); - - private int nclients; - private List<IOStream> clients; - - public ForeignMenu() { - menu = new Menu (); - } - - public void menu_item_click_msg (int32 item_id) { - debug ("clicked id: %d".printf (item_id)); - - var msg = SpiceProtocol.ForeignMenu.Event (); - msg.base.size = (uint32)sizeof (SpiceProtocol.ForeignMenu.Event); - msg.base.id = SpiceProtocol.ForeignMenu.MsgId.ITEM_EVENT; - msg.id = item_id; - msg.action = SpiceProtocol.ForeignMenu.EventType.CLICK; - - unowned uint8[] p = ((uint8[])(&msg))[0:msg.base.size]; - send_msg.begin (p); - } - - public void menu_item_checked_msg (int32 item_id, bool checked = true) { - debug ("%schecked id: %d".printf (checked ? "" : "un", item_id)); - - var msg = SpiceProtocol.ForeignMenu.Event (); - msg.base.size = (uint32)sizeof (SpiceProtocol.ForeignMenu.Event); - msg.base.id = SpiceProtocol.ForeignMenu.MsgId.ITEM_EVENT; - msg.id = item_id; - msg.action = checked ? - SpiceProtocol.ForeignMenu.EventType.CHECKED : - SpiceProtocol.ForeignMenu.EventType.UNCHECKED; - - unowned uint8[] p = ((uint8[])(&msg))[0:msg.base.size]; - send_msg.begin (p); - } - - public void app_activated_msg (bool activated = true) { - var msg = SpiceProtocol.ForeignMenu.Msg (); - msg.size = (uint32)sizeof (SpiceProtocol.ForeignMenu.Event); - msg.id = activated ? - SpiceProtocol.ForeignMenu.MsgId.APP_ACTIVATED : - SpiceProtocol.ForeignMenu.MsgId.APP_DEACTIVATED; - - unowned uint8[] p = ((uint8[])(&msg))[0:msg.size]; - send_msg.begin (p); - } - - public async bool send_msg (owned uint8[] p) throws GLib.Error { - // vala FIXME: pass Controller.Msg instead - // vala doesn't keep reference on the struct in async methods - // it copies only base, which is not enough to transmit the whole - // message. - try { - foreach (var c in clients) { - yield output_stream_write (c.output_stream, p); - } - } catch (GLib.Error e) { - warning (e.message); - } - - return true; - } - - SpiceProtocol.Controller.MenuFlags get_menu_flags (uint32 type) { - SpiceProtocol.Controller.MenuFlags flags = 0; - - if ((SpiceProtocol.ForeignMenu.MenuFlags.CHECKED & type) != 0) - flags |= SpiceProtocol.Controller.MenuFlags.CHECKED; - if ((SpiceProtocol.ForeignMenu.MenuFlags.DIM & type) != 0) - flags |= SpiceProtocol.Controller.MenuFlags.GRAYED; - - return flags; - } - - private bool handle_message (SpiceProtocol.ForeignMenu.Msg* msg) { - switch (msg.id) { - case SpiceProtocol.ForeignMenu.MsgId.SET_TITLE: - var t = (SpiceProtocol.ForeignMenu.SetTitle*)(msg); - title = t.string; - break; - case SpiceProtocol.ForeignMenu.MsgId.ADD_ITEM: - var i = (SpiceProtocol.ForeignMenu.AddItem*)(msg); - debug ("add id:%u type:%u position:%u title:%s", i.id, i.type, i.position, i.string); - menu.items.append (new MenuItem ((int)i.id, i.string, get_menu_flags (i.type))); - notify_property ("menu"); - break; - case SpiceProtocol.ForeignMenu.MsgId.MODIFY_ITEM: - debug ("deprecated: modify item"); - break; - case SpiceProtocol.ForeignMenu.MsgId.REMOVE_ITEM: - var i = (SpiceProtocol.ForeignMenu.RmItem*)(msg); - debug ("not implemented: remove id:%u".printf (i.id)); - break; - case SpiceProtocol.ForeignMenu.MsgId.CLEAR: - menu = new Menu (); - break; - default: - warn_if_reached (); - return false; - } - return true; - } - - private async void handle_client (IOStream c) throws GLib.Error { - debug ("new socket client, reading init header"); - - var p = new uint8[sizeof(SpiceProtocol.ForeignMenu.InitHeader)]; - var header = (SpiceProtocol.ForeignMenu.InitHeader*)p; - yield input_stream_read (c.input_stream, p); - if (warn_if (header.magic != SpiceProtocol.ForeignMenu.MAGIC)) - return; - if (warn_if (header.version != SpiceProtocol.ForeignMenu.VERSION)) - return; - if (warn_if (header.size < sizeof (SpiceProtocol.ForeignMenu.Init))) - return; - - var cp = new uint8[sizeof(uint64)]; - yield input_stream_read (c.input_stream, cp); - uint64 credentials = *(uint64*)cp; - if (warn_if (credentials != 0)) - return; - - var title_size = header.size - sizeof(SpiceProtocol.ForeignMenu.Init); - var title = new uint8[title_size + 1]; - yield c.input_stream.read_async (title[0:title_size]); - this.title = (string)title; - - client_connected (); - - for (;;) { - var t = new uint8[sizeof(SpiceProtocol.ForeignMenu.Msg)]; - yield input_stream_read (c.input_stream, t); - var msg = (SpiceProtocol.ForeignMenu.Msg*)t; - debug ("new message " + msg.id.to_string () + "size " + msg.size.to_string ()); - - if (warn_if (msg.size < sizeof (SpiceProtocol.ForeignMenu.Msg))) - break; - - if (msg.size > sizeof (SpiceProtocol.ForeignMenu.Msg)) { - t.resize ((int)msg.size); - msg = (SpiceProtocol.ForeignMenu.Msg*)t; - - yield input_stream_read (c.input_stream, t[sizeof(SpiceProtocol.ForeignMenu.Msg):msg.size]); - } - - handle_message (msg); - } - - } - - public async void listen (string? addr = null) throws GLib.Error, SpiceCtrl.Error - { - var listener = Spice.ForeignMenuListener.new_listener (addr); - - for (;;) { - var c = yield listener.accept_async (); - nclients += 1; - clients.append (c); - try { - yield handle_client (c); - } catch (GLib.Error e) { - warning (e.message); - } - c.close (); - clients.remove (c); - nclients -= 1; - } - } - -} - -} // SpiceCtrl diff --git a/src/controller/gio-windows-2.0.vapi b/src/controller/gio-windows-2.0.vapi deleted file mode 100644 index a09cfe8..0000000 --- a/src/controller/gio-windows-2.0.vapi +++ /dev/null @@ -1,30 +0,0 @@ -/* gio-windows-2.0.vapi generated by vapigen. */ -/* NOT YET UPSTREAM: https://bugzilla.gnome.org/show_bug.cgi?id=650052 */ - -[CCode (cprefix = "GLib", lower_case_cprefix = "glib_")] -namespace GLib { - [CCode (cheader_filename = "gio/gwin32inputstream.h")] - public class Win32InputStream : GLib.InputStream { - public weak GLib.InputStream parent_instance; - [CCode (cname = "g_win32_input_stream_new", type = "GInputStream*", has_construct_function = false)] - public Win32InputStream (void* handle, bool close_handle); - [CCode (cname = "g_win32_input_stream_get_close_handle")] - public static bool get_close_handle (GLib.Win32InputStream stream); - [CCode (cname = "g_win32_input_stream_get_handle")] - public static void* get_handle (GLib.Win32InputStream stream); - [CCode (cname = "g_win32_input_stream_set_close_handle")] - public static void set_close_handle (GLib.Win32InputStream stream, bool close_handle); - } - [CCode (cheader_filename = "gio/gwin32inputstream.h")] - public class Win32OutputStream : GLib.OutputStream { - public weak GLib.OutputStream parent_instance; - [CCode (cname = "g_win32_output_stream_new", type = "GOutputStream*", has_construct_function = false)] - public Win32OutputStream (void* handle, bool close_handle); - [CCode (cname = "g_win32_output_stream_get_close_handle")] - public static bool get_close_handle (GLib.Win32OutputStream stream); - [CCode (cname = "g_win32_output_stream_get_handle")] - public static void* get_handle (GLib.Win32OutputStream stream); - [CCode (cname = "g_win32_output_stream_set_close_handle")] - public static void set_close_handle (GLib.Win32OutputStream stream, bool close_handle); - } -} diff --git a/src/controller/menu.vala b/src/controller/menu.vala deleted file mode 100644 index 7e8fc16..0000000 --- a/src/controller/menu.vala +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2011 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/>. - -using GLib; -using Custom; -using SpiceProtocol.Controller; - -namespace SpiceCtrl { - -public class MenuItem: Object { - - public Menu submenu; - public int parent_id; - public int id; - public string text; - public string accel; - public SpiceProtocol.Controller.MenuFlags flags; - - public MenuItem (int id, string text, SpiceProtocol.Controller.MenuFlags flags) { - this.id = id; - this.text = text; - this.flags = flags; - } - - public MenuItem.from_string (string str) throws SpiceCtrl.Error { - var params = str.split (SpiceProtocol.Controller.MENU_PARAM_DELIMITER); - if (warn_if (params.length != 5)) - throw new SpiceCtrl.Error.VALUE(""); /* Vala: why is it mandatory to give a string? */ - parent_id = int.parse (params[0]); - id = int.parse (params[1]); - var textaccel = params[2].split ("\t"); - text = textaccel[0]; - if (textaccel.length > 1) - accel = textaccel[1]; - flags = (SpiceProtocol.Controller.MenuFlags)int.parse (params[3]); - - submenu = new Menu (); - } - - public string to_string () { - var sub = submenu.to_string (); - var str = @"pid: $parent_id, id: $id, text: \"$text\", flags: $flags"; - foreach (var l in sub.to_string ().split ("\n")) { - if (l == "") - continue; - str += @"\n $l"; - } - return str; - } -} - -public class Menu: Object { - - public List<MenuItem> items; - - public Menu? find_id (int id) { - if (id == 0) - return this; - - foreach (var item in items) { - if (item.id == id) - return item.submenu; - - var menu = item.submenu.find_id (id); - if (menu != null) - return menu; - } - - return null; - } - - public Menu.from_string (string str) { - foreach (var itemstr in str.split (SpiceProtocol.Controller.MENU_ITEM_DELIMITER)) { - try { - if (itemstr.length == 0) - continue; - var item = new MenuItem.from_string (itemstr); - var parent = find_id (item.parent_id); - if (parent == null) - throw new SpiceCtrl.Error.VALUE("Invalid parent menu id"); - parent.items.append (item); - } catch (SpiceCtrl.Error e) { - warning (e.message); - } - } - } - - public string to_string () { - var str = ""; - foreach (var i in items) - str += @"\n$i"; - return str; - } -} - -} // SpiceCtrl diff --git a/src/controller/namedpipe.c b/src/controller/namedpipe.c deleted file mode 100644 index 5312218..0000000 --- a/src/controller/namedpipe.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - Copyright (C) 2011 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 "namedpipe.h" - -#include <windows.h> -#include <stdio.h> -#include <conio.h> -#include <tchar.h> - -static void spice_named_pipe_initable_iface_init (GInitableIface *iface); -static gboolean spice_named_pipe_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error); - -G_DEFINE_TYPE_WITH_CODE (SpiceNamedPipe, spice_named_pipe, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - spice_named_pipe_initable_iface_init)); - -enum -{ - PROP_0, - PROP_NAME, - PROP_HANDLE, -}; - -struct _SpiceNamedPipePrivate -{ - gchar * name; - GError * construct_error; - guint inited : 1; - HANDLE handle; -}; - -static void -spice_named_pipe_finalize (GObject *object) -{ - SpiceNamedPipe *np = SPICE_NAMED_PIPE (object); - - g_clear_error (&np->priv->construct_error); - - g_free (np->priv->name); - np->priv->name = NULL; - - if (np->priv->handle) - { - CloseHandle (np->priv->handle); - np->priv->handle = NULL; - } - - if (G_OBJECT_CLASS (spice_named_pipe_parent_class)->finalize) - G_OBJECT_CLASS (spice_named_pipe_parent_class)->finalize (object); -} - -#define DEFAULT_PIPE_BUF_SIZE 4096 - -static void -spice_named_pipe_constructed (GObject *object) -{ - SpiceNamedPipe *np = SPICE_NAMED_PIPE (object); - - if (np->priv->handle) - /* TODO: find a way to ensure user provided handle is a named - pipe, in overlapped mode */ - goto end; - - np->priv->handle = CreateNamedPipe (np->priv->name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, - DEFAULT_PIPE_BUF_SIZE, DEFAULT_PIPE_BUF_SIZE, - 0, NULL); - - if (np->priv->handle == INVALID_HANDLE_VALUE) - { - int errsv = GetLastError (); - gchar *emsg = g_win32_error_message (errsv); - - g_set_error (&np->priv->construct_error, - G_IO_ERROR, - g_io_error_from_win32_error (errsv), - "Error CreateNamedPipe(): %s", - emsg); - - g_free (emsg); - return; - } - - /* TODO: we could have a client backlog by creating many pipes, the - maximum number of outstanding connections.. or we could just let - the named_pipe_listener take multiple NamedPipe instances */ -end: - g_assert (np->priv->handle != INVALID_HANDLE_VALUE); - return; -} - -static void -spice_named_pipe_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - SpiceNamedPipe *np = SPICE_NAMED_PIPE (object); - - switch (prop_id) - { - case PROP_NAME: - g_value_set_string (value, np->priv->name); - break; - case PROP_HANDLE: - g_value_set_pointer (value, np->priv->handle); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -spice_named_pipe_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - SpiceNamedPipe *np = SPICE_NAMED_PIPE (object); - - switch (prop_id) - { - case PROP_NAME: - g_free (np->priv->name); - np->priv->name = g_value_dup_string (value); - break; - case PROP_HANDLE: - np->priv->handle = g_value_get_pointer (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -spice_named_pipe_class_init (SpiceNamedPipeClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (SpiceNamedPipePrivate)); - - gobject_class->set_property = spice_named_pipe_set_property; - gobject_class->get_property = spice_named_pipe_get_property; - gobject_class->finalize = spice_named_pipe_finalize; - gobject_class->constructed = spice_named_pipe_constructed; - - g_object_class_install_property (gobject_class, PROP_NAME, - g_param_spec_string ("name", - "Pipe Name", - "The NamedPipe name", - NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_HANDLE, - g_param_spec_pointer ("handle", - "Pipe handle", - "The pipe handle", - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); -} - -static void -spice_named_pipe_init (SpiceNamedPipe *np) -{ - np->priv = G_TYPE_INSTANCE_GET_PRIVATE (np, - SPICE_TYPE_NAMED_PIPE, - SpiceNamedPipePrivate); -} - -static gboolean -spice_named_pipe_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) -{ - SpiceNamedPipe *np; - - g_return_val_if_fail (SPICE_IS_NAMED_PIPE (initable), FALSE); - - np = SPICE_NAMED_PIPE (initable); - - if (cancellable != NULL) - { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "Cancellable initialization not supported"); - return FALSE; - } - - np->priv->inited = TRUE; - - if (np->priv->construct_error) - { - if (error) - *error = g_error_copy (np->priv->construct_error); - return FALSE; - } - - - return TRUE; -} - -static void -spice_named_pipe_initable_iface_init (GInitableIface *iface) -{ - iface->init = spice_named_pipe_initable_init; -} - -SpiceNamedPipe * -spice_named_pipe_new (const gchar *name, GError **error) -{ - return SPICE_NAMED_PIPE (g_initable_new (SPICE_TYPE_NAMED_PIPE, - NULL, error, - "name", name, - NULL)); -} - -void * -spice_named_pipe_get_handle (SpiceNamedPipe *namedpipe) -{ - g_return_val_if_fail (SPICE_IS_NAMED_PIPE (namedpipe), NULL); - - return namedpipe->priv->handle; -} - -gboolean -spice_named_pipe_close (SpiceNamedPipe *np, - GError **error) -{ - BOOL res; - - g_return_val_if_fail (SPICE_IS_NAMED_PIPE (np), FALSE); - - res = CloseHandle (np->priv->handle); - np->priv->handle = NULL; - if (!res) - { - int errsv = GetLastError (); - gchar *emsg = g_win32_error_message (errsv); - - g_set_error (error, G_IO_ERROR, - g_io_error_from_win32_error (errsv), - "Error closing handle: %s", - emsg); - g_free (emsg); - return FALSE; - } - - return TRUE; -} diff --git a/src/controller/namedpipe.h b/src/controller/namedpipe.h deleted file mode 100644 index e0e873b..0000000 --- a/src/controller/namedpipe.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 2011 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 __NAMED_PIPE_H__ -#define __NAMED_PIPE_H__ - -#include <gio/gio.h> - -G_BEGIN_DECLS - -#define SPICE_TYPE_NAMED_PIPE (spice_named_pipe_get_type ()) -#define SPICE_NAMED_PIPE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ - SPICE_TYPE_NAMED_PIPE, SpiceNamedPipe)) -#define SPICE_NAMED_PIPE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ - SPICE_TYPE_NAMED_PIPE, SpiceNamedPipeClass)) -#define SPICE_IS_NAMED_PIPE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ - SPICE_TYPE_NAMED_PIPE)) -#define SPICE_IS_NAMED_PIPE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ - SPICE_TYPE_NAMED_PIPE)) -#define SPICE_NAMED_PIPE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ - SPICE_TYPE_NAMED_PIPE, SpiceNamedPipeClass)) - -typedef struct _SpiceNamedPipe SpiceNamedPipe; -typedef struct _SpiceNamedPipePrivate SpiceNamedPipePrivate; -typedef struct _SpiceNamedPipeClass SpiceNamedPipeClass; - -struct _SpiceNamedPipeClass -{ - GObjectClass parent_class; -}; - -struct _SpiceNamedPipe -{ - GObject parent_instance; - SpiceNamedPipePrivate *priv; -}; - -GType spice_named_pipe_get_type (void) G_GNUC_CONST; - -SpiceNamedPipe * spice_named_pipe_new (const gchar *name, GError **error); -void * spice_named_pipe_get_handle(SpiceNamedPipe *namedpipe); -gboolean spice_named_pipe_close (SpiceNamedPipe *namedpipe, - GError **error); -G_END_DECLS - -#endif /* __NAMED_PIPE_H__ */ diff --git a/src/controller/namedpipeconnection.c b/src/controller/namedpipeconnection.c deleted file mode 100644 index 3173b61..0000000 --- a/src/controller/namedpipeconnection.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - Copyright (C) 2011 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 "namedpipeconnection.h" - -#include <windows.h> -#include <stdio.h> -#include <conio.h> -#include <tchar.h> - -#include <gio/gwin32inputstream.h> -#include <gio/gwin32outputstream.h> - -G_DEFINE_TYPE (SpiceNamedPipeConnection, spice_named_pipe_connection, - G_TYPE_IO_STREAM) - -enum -{ - PROP_0, - PROP_NAMED_PIPE, -}; - -struct _SpiceNamedPipeConnectionPrivate -{ - GInputStream *input_stream; - GOutputStream *output_stream; - SpiceNamedPipe *namedpipe; - gboolean in_dispose; -}; - -static void -spice_named_pipe_connection_init (SpiceNamedPipeConnection *connection) -{ - connection->priv = G_TYPE_INSTANCE_GET_PRIVATE (connection, - SPICE_TYPE_NAMED_PIPE_CONNECTION, - SpiceNamedPipeConnectionPrivate); -} - -static void -spice_named_pipe_connection_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (object); - - switch (prop_id) - { - case PROP_NAMED_PIPE: - g_return_if_fail (c->priv->namedpipe == NULL); - g_value_set_object (value, c->priv->namedpipe); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -spice_named_pipe_connection_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (object); - - switch (prop_id) - { - case PROP_NAMED_PIPE: - c->priv->namedpipe = g_value_get_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static GInputStream * -spice_named_pipe_connection_get_input_stream (GIOStream *io_stream) -{ - SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (io_stream); - HANDLE h = spice_named_pipe_get_handle (c->priv->namedpipe); - - g_return_val_if_fail (h != NULL, NULL); - - if (c->priv->input_stream == NULL) - c->priv->input_stream = g_win32_input_stream_new (h, FALSE); - - return c->priv->input_stream; -} - -static GOutputStream * -spice_named_pipe_connection_get_output_stream (GIOStream *io_stream) -{ - SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (io_stream); - HANDLE h = spice_named_pipe_get_handle (c->priv->namedpipe); - - g_return_val_if_fail (h != NULL, NULL); - - if (c->priv->output_stream == NULL) - c->priv->output_stream = g_win32_output_stream_new (h, FALSE); - - return c->priv->output_stream; -} - -static void -spice_named_pipe_connection_dispose (GObject *object) -{ - SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (object); - - c->priv->in_dispose = TRUE; - - if (G_OBJECT_CLASS (spice_named_pipe_connection_parent_class)->dispose) - G_OBJECT_CLASS (spice_named_pipe_connection_parent_class)->dispose (object); - - c->priv->in_dispose = FALSE; -} - -static void -spice_named_pipe_connection_finalize (GObject *object) -{ - SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (object); - - if (c->priv->output_stream) - { - g_object_unref (c->priv->output_stream); - c->priv->output_stream = NULL; - } - - if (c->priv->input_stream) - { - g_object_unref (c->priv->input_stream); - c->priv->input_stream = NULL; - } - - g_object_unref (c->priv->namedpipe); - - if (G_OBJECT_CLASS (spice_named_pipe_connection_parent_class)->finalize) - G_OBJECT_CLASS (spice_named_pipe_connection_parent_class)->finalize (object); -} - -static gboolean -spice_named_pipe_connection_close (GIOStream *stream, - GCancellable *cancellable, - GError **error) -{ - SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (stream); - - if (c->priv->output_stream) - g_output_stream_close (c->priv->output_stream, cancellable, NULL); - if (c->priv->input_stream) - g_input_stream_close (c->priv->input_stream, cancellable, NULL); - - /* Don't close the underlying socket if this is being called - * as part of dispose(); when destroying the GSocketConnection, - * we only want to close the socket if we're holding the last - * reference on it, and in that case it will close itself when - * we unref namedpipe in finalize(). - */ - if (c->priv->in_dispose) - return TRUE; - - return spice_named_pipe_close (c->priv->namedpipe, error); -} - -static void -spice_named_pipe_connection_close_async (GIOStream *stream, - int io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *res; - GIOStreamClass *class; - GError *error; - - class = G_IO_STREAM_GET_CLASS (stream); - - /* namedpipe close is not blocking, just do it! */ - error = NULL; - if (class->close_fn && - !class->close_fn (stream, cancellable, &error)) - { - g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream), - callback, user_data, - error); - return; - } - - res = g_simple_async_result_new (G_OBJECT (stream), - callback, - user_data, - spice_named_pipe_connection_close_async); - g_simple_async_result_complete_in_idle (res); - g_object_unref (res); -} - -static gboolean -spice_named_pipe_connection_close_finish (GIOStream *stream, - GAsyncResult *result, - GError **error) -{ - return TRUE; -} - -static void -spice_named_pipe_connection_class_init (SpiceNamedPipeConnectionClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass); - - g_type_class_add_private (klass, sizeof (SpiceNamedPipeConnectionPrivate)); - - gobject_class->set_property = spice_named_pipe_connection_set_property; - gobject_class->get_property = spice_named_pipe_connection_get_property; - gobject_class->dispose = spice_named_pipe_connection_dispose; - gobject_class->finalize = spice_named_pipe_connection_finalize; - - stream_class->get_input_stream = spice_named_pipe_connection_get_input_stream; - stream_class->get_output_stream = spice_named_pipe_connection_get_output_stream; - stream_class->close_fn = spice_named_pipe_connection_close; - stream_class->close_async = spice_named_pipe_connection_close_async; - stream_class->close_finish = spice_named_pipe_connection_close_finish; - - g_object_class_install_property (gobject_class, PROP_NAMED_PIPE, - g_param_spec_object ("namedpipe", - "NamedPipe", - "The associated NamedPipe", - SPICE_TYPE_NAMED_PIPE, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); -} diff --git a/src/controller/namedpipeconnection.h b/src/controller/namedpipeconnection.h deleted file mode 100644 index 86f0be6..0000000 --- a/src/controller/namedpipeconnection.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (C) 2011 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 __NAMED_PIPE_CONNECTION_H__ -#define __NAMED_PIPE_CONNECTION_H__ - -#include <gio/gio.h> -#include "namedpipe.h" - -G_BEGIN_DECLS - -#define SPICE_TYPE_NAMED_PIPE_CONNECTION (spice_named_pipe_connection_get_type ()) -#define SPICE_NAMED_PIPE_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ - SPICE_TYPE_NAMED_PIPE_CONNECTION, SpiceNamedPipeConnection)) -#define SPICE_NAMED_PIPE_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ - SPICE_TYPE_NAMED_PIPE_CONNECTION, SpiceNamedPipeConnectionClass)) -#define SPICE_IS_NAMED_PIPE_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ - SPICE_TYPE_NAMED_PIPE_CONNECTION)) -#define SPICE_IS_NAMED_PIPE_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ - SPICE_TYPE_NAMED_PIPE_CONNECTION)) -#define SPICE_NAMED_PIPE_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ - SPICE_TYPE_NAMED_PIPE_CONNECTION, SpiceNamedPipeConnectionClass)) - -typedef struct _SpiceNamedPipeConnection SpiceNamedPipeConnection; -typedef struct _SpiceNamedPipeConnectionPrivate SpiceNamedPipeConnectionPrivate; -typedef struct _SpiceNamedPipeConnectionClass SpiceNamedPipeConnectionClass; - -struct _SpiceNamedPipeConnectionClass -{ - GIOStreamClass parent_class; -}; - -struct _SpiceNamedPipeConnection -{ - GIOStream parent_instance; - SpiceNamedPipeConnectionPrivate *priv; -}; - -GType spice_named_pipe_connection_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __NAMED_PIPE_CONNECTION_H__ */ diff --git a/src/controller/namedpipelistener.c b/src/controller/namedpipelistener.c deleted file mode 100644 index b4b6057..0000000 --- a/src/controller/namedpipelistener.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - Copyright (C) 2011 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 "namedpipelistener.h" - -#include <windows.h> -#include <stdio.h> -#include <conio.h> -#include <tchar.h> - -static GSource *g_win32_handle_source_add (HANDLE handle, - GSourceFunc callback, - gpointer user_data); - -G_DEFINE_TYPE (SpiceNamedPipeListener, spice_named_pipe_listener, G_TYPE_OBJECT); - -struct _SpiceNamedPipeListenerPrivate -{ - GQueue namedpipes; -}; - -static void -spice_named_pipe_listener_dispose (GObject *object) -{ - SpiceNamedPipeListener *listener = SPICE_NAMED_PIPE_LISTENER (object); - SpiceNamedPipe *p; - - while ((p = g_queue_pop_head (&listener->priv->namedpipes)) != NULL) - g_object_unref (p); - - g_return_if_fail (g_queue_get_length (&listener->priv->namedpipes) == 0); - g_queue_clear (&listener->priv->namedpipes); - - if (G_OBJECT_CLASS (spice_named_pipe_listener_parent_class)->dispose) - G_OBJECT_CLASS (spice_named_pipe_listener_parent_class)->dispose (object); -} - -static void -spice_named_pipe_listener_class_init (SpiceNamedPipeListenerClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (SpiceNamedPipeListenerPrivate)); - - gobject_class->dispose = spice_named_pipe_listener_dispose; -} - -static void -spice_named_pipe_listener_init (SpiceNamedPipeListener *listener) -{ - listener->priv = G_TYPE_INSTANCE_GET_PRIVATE (listener, - SPICE_TYPE_NAMED_PIPE_LISTENER, - SpiceNamedPipeListenerPrivate); - - g_queue_init (&listener->priv->namedpipes); -} - -void -spice_named_pipe_listener_add_named_pipe (SpiceNamedPipeListener *listener, - SpiceNamedPipe *namedpipe) -{ - g_return_if_fail (SPICE_IS_NAMED_PIPE_LISTENER (listener)); - g_return_if_fail (SPICE_IS_NAMED_PIPE (namedpipe)); - - g_queue_push_head (&listener->priv->namedpipes, g_object_ref (namedpipe)); -} - -typedef struct { - GCancellable *cancellable; - GSource *source; - GSimpleAsyncResult *async_result; - SpiceNamedPipe *np; - OVERLAPPED overlapped; -} ConnectData; - -static void -connect_cancelled (GCancellable *cancellable, - gpointer user_data) -{ - ConnectData *c = user_data; - GError *error = NULL; - - g_source_destroy (c->source); - c->source = NULL; - - g_cancellable_set_error_if_cancelled (cancellable, &error); - g_simple_async_result_set_from_error (c->async_result, error); - g_error_free (error); - - g_simple_async_result_complete (c->async_result); - g_object_unref (c->async_result); -} - -static gboolean -connect_ready (gpointer user_data) -{ - ConnectData *c = user_data; - gulong cbret; - gboolean success; - - /* Now complete the result (assuming it wasn't already completed) */ - g_return_val_if_fail (c->async_result != NULL, FALSE); - - success = GetOverlappedResult (c->np, &c->overlapped, &cbret, FALSE); - if (!success) - { - int errsv = GetLastError (); - gchar *emsg = g_win32_error_message (errsv); - - g_simple_async_result_set_error (c->async_result, - G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - "GetOverlappedResult(): %s %d", - emsg, errsv); - g_free (emsg); - } - - g_simple_async_result_complete (c->async_result); - g_object_unref (c->async_result); /* TODO: that sould free c? */ - - return FALSE; -} - -static void -connect_data_free (gpointer data) -{ - ConnectData *c = data; - - if (c->source) - { - g_source_destroy (c->source); - g_source_unref (c->source); - c->source = NULL; - } - if (c->cancellable) - { - g_signal_handlers_disconnect_by_func (c->cancellable, connect_cancelled, c); - g_object_unref (c->cancellable); - c->cancellable = NULL; - } - - if (c->async_result) /* this is only a weak reference */ - c->async_result = NULL; - - if (c->overlapped.hEvent != NULL) - { - CloseHandle (c->overlapped.hEvent); - c->overlapped.hEvent = NULL; - } - - if (c->np != NULL) - { - g_object_unref (c->np); - c->np = NULL; - } - - g_free (c); -} - -void -spice_named_pipe_listener_accept_async (SpiceNamedPipeListener *listener, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - ConnectData *c; - SpiceNamedPipe *namedpipe; - - g_return_if_fail (SPICE_IS_NAMED_PIPE_LISTENER (listener)); - - namedpipe = SPICE_NAMED_PIPE (g_queue_pop_head (&listener->priv->namedpipes)); - /* do not unref, we keep that ref */ - g_return_if_fail (namedpipe != NULL); - - c = g_new0 (ConnectData, 1); - c->np = namedpipe; /* transfer what used to be the avail_namedpipes ref */ - c->async_result = g_simple_async_result_new (G_OBJECT (listener), callback, user_data, - spice_named_pipe_listener_accept_async); - c->overlapped.hEvent = CreateEvent (NULL, /* default security attribute */ - TRUE, /* manual-reset event */ - TRUE, /* initial state = signaled */ - NULL); /* unnamed event object */ - g_simple_async_result_set_op_res_gpointer (c->async_result, c, connect_data_free); - - if (ConnectNamedPipe (spice_named_pipe_get_handle (namedpipe), &c->overlapped) != 0) - { - /* we shouldn't get there if the listener is in non-blocking */ - g_warn_if_reached (); - } - - switch (GetLastError ()) - { - case ERROR_SUCCESS: - case ERROR_IO_PENDING: - break; - case ERROR_PIPE_CONNECTED: - g_simple_async_result_complete_in_idle (c->async_result); - g_object_unref (c->async_result); - return; - default: - g_simple_async_report_error_in_idle (G_OBJECT (listener), - callback, user_data, - G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, - "ConnectNamedPipe() failed %ld", GetLastError ()); - g_object_unref (c->async_result); - return; - } - - c->source = g_win32_handle_source_add (c->overlapped.hEvent, - connect_ready, c); - - if (cancellable) - { - c->cancellable = g_object_ref (cancellable); - g_signal_connect (cancellable, "cancelled", - G_CALLBACK (connect_cancelled), c); - } -} - -SpiceNamedPipeConnection * -spice_named_pipe_listener_accept_finish (SpiceNamedPipeListener *listener, - GAsyncResult *result, - GObject **source_object, - GError **error) -{ - GSimpleAsyncResult *simple; - ConnectData *c; - SpiceNamedPipeConnection *connection; - - g_return_val_if_fail (SPICE_IS_NAMED_PIPE_LISTENER (listener), NULL); - g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); - g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (listener), - spice_named_pipe_listener_accept_async), - NULL); - - simple = G_SIMPLE_ASYNC_RESULT (result); - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - c = g_simple_async_result_get_op_res_gpointer (simple); - - connection = g_object_new (SPICE_TYPE_NAMED_PIPE_CONNECTION, - "namedpipe", c->np, - NULL); - return connection; -} - -SpiceNamedPipeListener * -spice_named_pipe_listener_new (void) -{ - return g_object_new (SPICE_TYPE_NAMED_PIPE_LISTENER, NULL); -} - -/* Windows HANDLE GSource - from gio/gwin32resolver.c */ - -typedef struct { - GSource source; - GPollFD pollfd; -} GWin32HandleSource; - -static gboolean -g_win32_handle_source_prepare (GSource *source, - gint *timeout) -{ - *timeout = -1; - return FALSE; -} - -static gboolean -g_win32_handle_source_check (GSource *source) -{ - GWin32HandleSource *hsource = (GWin32HandleSource *)source; - - return hsource->pollfd.revents; -} - -static gboolean -g_win32_handle_source_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - return (*callback) (user_data); -} - -static void -g_win32_handle_source_finalize (GSource *source) -{ - ; -} - -GSourceFuncs g_win32_handle_source_funcs = { - g_win32_handle_source_prepare, - g_win32_handle_source_check, - g_win32_handle_source_dispatch, - g_win32_handle_source_finalize -}; - -static GSource * -g_win32_handle_source_add (HANDLE handle, - GSourceFunc callback, - gpointer user_data) -{ - GWin32HandleSource *hsource; - GSource *source; - - source = g_source_new (&g_win32_handle_source_funcs, sizeof (GWin32HandleSource)); - hsource = (GWin32HandleSource *)source; - hsource->pollfd.fd = (gint)handle; - hsource->pollfd.events = G_IO_IN; - hsource->pollfd.revents = 0; - g_source_add_poll (source, &hsource->pollfd); - - g_source_set_callback (source, callback, user_data, NULL); - g_source_attach (source, g_main_context_get_thread_default ()); - return source; -} diff --git a/src/controller/namedpipelistener.h b/src/controller/namedpipelistener.h deleted file mode 100644 index c2dbd0a..0000000 --- a/src/controller/namedpipelistener.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (C) 2011 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 __NAMED_PIPE_LISTENER_H__ -#define __NAMED_PIPE_LISTENER_H__ - -#include <gio/gio.h> - -#include "namedpipe.h" -#include "namedpipeconnection.h" - -G_BEGIN_DECLS - -#define SPICE_TYPE_NAMED_PIPE_LISTENER (spice_named_pipe_listener_get_type ()) -#define SPICE_NAMED_PIPE_LISTENER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ - SPICE_TYPE_NAMED_PIPE_LISTENER, SpiceNamedPipeListener)) -#define SPICE_NAMED_PIPE_LISTENER_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ - SPICE_TYPE_NAMED_PIPE_LISTENER, SpiceNamedPipeListenerClass)) -#define SPICE_IS_NAMED_PIPE_LISTENER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ - SPICE_TYPE_NAMED_PIPE_LISTENER)) -#define SPICE_IS_NAMED_PIPE_LISTENER_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ - SPICE_TYPE_NAMED_PIPE_LISTENER)) -#define SPICE_NAMED_PIPE_LISTENER_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ - SPICE_TYPE_NAMED_PIPE_LISTENER, SpiceNamedPipeListenerClass)) - -typedef struct _SpiceNamedPipeListener SpiceNamedPipeListener; -typedef struct _SpiceNamedPipeListenerPrivate SpiceNamedPipeListenerPrivate; -typedef struct _SpiceNamedPipeListenerClass SpiceNamedPipeListenerClass; - -struct _SpiceNamedPipeListenerClass -{ - GObjectClass parent_class; -}; - -struct _SpiceNamedPipeListener -{ - GObject parent_instance; - SpiceNamedPipeListenerPrivate *priv; -}; - -GType spice_named_pipe_listener_get_type (void) G_GNUC_CONST; - -SpiceNamedPipeListener * spice_named_pipe_listener_new (void); -void spice_named_pipe_listener_add_named_pipe (SpiceNamedPipeListener *listener, - SpiceNamedPipe *namedpipe); -void spice_named_pipe_listener_accept_async (SpiceNamedPipeListener *listener, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -SpiceNamedPipeConnection * spice_named_pipe_listener_accept_finish (SpiceNamedPipeListener *listener, - GAsyncResult *result, - GObject **source_object, - GError **error); - -G_END_DECLS - -#endif /* __NAMED_PIPE_LISTENER_H__ */ diff --git a/src/controller/spice-controller-listener.c b/src/controller/spice-controller-listener.c deleted file mode 100644 index 98baf33..0000000 --- a/src/controller/spice-controller-listener.c +++ /dev/null @@ -1,159 +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 <glib.h> -#include <glib/gstdio.h> - -#include "spice-controller-listener.h" - -#ifdef G_OS_WIN32 -#include <windows.h> -#include "namedpipe.h" -#include "namedpipelistener.h" -#include "win32-util.h" -#endif - -#ifdef G_OS_UNIX -#include <gio/gunixsocketaddress.h> -#endif - -/** - * SpiceControllerListenerError: - * @SPICE_CONTROLLER_LISTENER_ERROR_VALUE: invalid value. - * - * Possible errors of controller listener related functions. - **/ - -/** - * SPICE_CONTROLLER_LISTENER_ERROR: - * - * The error domain of the controller listener subsystem. - **/ -GQuark -spice_controller_listener_error_quark (void) -{ - return g_quark_from_static_string ("spice-controller-listener-error"); -} - -GObject* -spice_controller_listener_new (const gchar *address, GError **error) -{ - GObject *listener = NULL; - gchar *addr = NULL; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - addr = g_strdup (address); - -#ifdef G_OS_WIN32 - if (addr == NULL) - addr = g_strdup (g_getenv ("SPICE_XPI_NAMEDPIPE")); - if (addr == NULL) - addr = g_strdup_printf ("\\\\.\\pipe\\SpiceController-%" G_GUINT64_FORMAT, (guint64)GetCurrentProcessId ()); -#else - if (addr == NULL) - addr = g_strdup (g_getenv ("SPICE_XPI_SOCKET")); -#endif - if (addr == NULL) { - g_set_error (error, - SPICE_CONTROLLER_LISTENER_ERROR, - SPICE_CONTROLLER_LISTENER_ERROR_VALUE, -#ifdef G_OS_WIN32 - "Missing namedpipe address" -#else - "Missing socket address" -#endif - ); - goto end; - } - - g_unlink (addr); - -#ifdef G_OS_WIN32 - { - SpiceNamedPipe *np; - - listener = G_OBJECT (spice_named_pipe_listener_new ()); - - np = spice_win32_user_pipe_new (addr, error); - if (!np) { - g_object_unref (listener); - listener = NULL; - goto end; - } - - spice_named_pipe_listener_add_named_pipe (SPICE_NAMED_PIPE_LISTENER (listener), np); - } -#else - { - listener = G_OBJECT (g_socket_listener_new ()); - - if (!g_socket_listener_add_address (G_SOCKET_LISTENER (listener), - G_SOCKET_ADDRESS (g_unix_socket_address_new (addr)), - G_SOCKET_TYPE_STREAM, - G_SOCKET_PROTOCOL_DEFAULT, - NULL, - NULL, - error)) - g_warning ("failed to add address"); - } -#endif - -end: - g_free (addr); - return listener; -} - -void -spice_controller_listener_accept_async (GObject *listener, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - g_return_if_fail(G_IS_OBJECT(listener)); - -#ifdef G_OS_WIN32 - spice_named_pipe_listener_accept_async (SPICE_NAMED_PIPE_LISTENER (listener), cancellable, callback, user_data); -#else - g_socket_listener_accept_async (G_SOCKET_LISTENER (listener), cancellable, callback, user_data); -#endif -} - -GIOStream* -spice_controller_listener_accept_finish (GObject *listener, - GAsyncResult *result, - GObject **source_object, - GError **error) -{ - g_return_val_if_fail(G_IS_OBJECT(listener), NULL); - -#ifdef G_OS_WIN32 - SpiceNamedPipeConnection *np; - np = spice_named_pipe_listener_accept_finish (SPICE_NAMED_PIPE_LISTENER (listener), result, source_object, error); - if (np) - return G_IO_STREAM (np); -#else - GSocketConnection *socket; - socket = g_socket_listener_accept_finish (G_SOCKET_LISTENER (listener), result, source_object, error); - if (socket) - return G_IO_STREAM (socket); -#endif - - return NULL; -} diff --git a/src/controller/spice-controller-listener.h b/src/controller/spice-controller-listener.h deleted file mode 100644 index a50bdea..0000000 --- a/src/controller/spice-controller-listener.h +++ /dev/null @@ -1,47 +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 __SPICE_CONTROLLER_LISTENER_H__ -#define __SPICE_CONTROLLER_LISTENER_H__ - -#include <gio/gio.h> - -G_BEGIN_DECLS - -#define SPICE_CONTROLLER_LISTENER_ERROR spice_controller_listener_error_quark () -GQuark spice_controller_listener_error_quark (void); - -typedef enum -{ - SPICE_CONTROLLER_LISTENER_ERROR_VALUE /* incorrect value */ -} SpiceControllerListenerError; - - -GObject* spice_controller_listener_new (const gchar *address, GError **error); - -void spice_controller_listener_accept_async (GObject *listener, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -GIOStream* spice_controller_listener_accept_finish (GObject *listener, - GAsyncResult *result, - GObject **source_object, - GError **error); -G_END_DECLS - -#endif /* __SPICE_CONTROLLER_LISTENER_H__ */ diff --git a/src/controller/spice-foreign-menu-listener.c b/src/controller/spice-foreign-menu-listener.c deleted file mode 100644 index 5e62606..0000000 --- a/src/controller/spice-foreign-menu-listener.c +++ /dev/null @@ -1,161 +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 <glib.h> -#include <glib/gstdio.h> - -#include "spice-foreign-menu-listener.h" - -#ifdef G_OS_WIN32 -#include <windows.h> -#include "namedpipe.h" -#include "namedpipelistener.h" -#include "win32-util.h" -#endif - -#ifdef G_OS_UNIX -#include <gio/gunixsocketaddress.h> -#endif - -/** - * SpiceForeignMenuListenerError: - * @SPICE_FOREIGN_MENU_LISTENER_ERROR_VALUE: invalid value. - * - * Possible errors of foreign menu listener related functions. - **/ - -/** - * SPICE_FOREIGN_MENU_LISTENER_ERROR: - * - * The error domain of the foreign menu listener subsystem. - **/ -GQuark -spice_foreign_menu_listener_error_quark (void) -{ - return g_quark_from_static_string ("spice-foreign-menu-listener-error"); -} - -GObject* -spice_foreign_menu_listener_new (const gchar *address, GError **error) -{ - GObject *listener = NULL; - gchar *addr = NULL; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - addr = g_strdup (address); - -#ifdef G_OS_WIN32 - if (addr == NULL) - addr = g_strdup (g_getenv ("SPICE_FOREIGN_MENU_NAMEDPIPE")); - if (addr == NULL) - addr = g_strdup_printf ("\\\\.\\pipe\\SpiceForeignMenu-%" G_GUINT64_FORMAT, (guint64)GetCurrentProcessId ()); -#else - if (addr == NULL) - addr = g_strdup (g_getenv ("SPICE_FOREIGN_MENU_SOCKET")); - if (addr == NULL) - addr = g_strdup_printf ("/tmp/SpiceForeignMenu-%" G_GUINT64_FORMAT ".uds", (guint64)getpid ()); -#endif - if (addr == NULL) { - g_set_error (error, - SPICE_FOREIGN_MENU_LISTENER_ERROR, - SPICE_FOREIGN_MENU_LISTENER_ERROR_VALUE, -#ifdef G_OS_WIN32 - "Missing namedpipe address" -#else - "Missing socket address" -#endif - ); - goto end; - } - - g_unlink (addr); - -#ifdef G_OS_WIN32 - { - SpiceNamedPipe *np; - - listener = G_OBJECT (spice_named_pipe_listener_new ()); - - np = spice_win32_user_pipe_new (addr, error); - if (!np) { - g_object_unref (listener); - listener = NULL; - goto end; - } - - spice_named_pipe_listener_add_named_pipe (SPICE_NAMED_PIPE_LISTENER (listener), np); - } -#else - { - listener = G_OBJECT (g_socket_listener_new ()); - - if (!g_socket_listener_add_address (G_SOCKET_LISTENER (listener), - G_SOCKET_ADDRESS (g_unix_socket_address_new (addr)), - G_SOCKET_TYPE_STREAM, - G_SOCKET_PROTOCOL_DEFAULT, - NULL, - NULL, - error)) - g_warning ("failed to add address"); - } -#endif - -end: - g_free (addr); - return listener; -} - -void -spice_foreign_menu_listener_accept_async (GObject *listener, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - g_return_if_fail(G_IS_OBJECT(listener)); - -#ifdef G_OS_WIN32 - spice_named_pipe_listener_accept_async (SPICE_NAMED_PIPE_LISTENER (listener), cancellable, callback, user_data); -#else - g_socket_listener_accept_async (G_SOCKET_LISTENER (listener), cancellable, callback, user_data); -#endif -} - -GIOStream* -spice_foreign_menu_listener_accept_finish (GObject *listener, - GAsyncResult *result, - GObject **source_object, - GError **error) -{ - g_return_val_if_fail(G_IS_OBJECT(listener), NULL); - -#ifdef G_OS_WIN32 - SpiceNamedPipeConnection *np; - np = spice_named_pipe_listener_accept_finish (SPICE_NAMED_PIPE_LISTENER (listener), result, source_object, error); - if (np) - return G_IO_STREAM (np); -#else - GSocketConnection *socket; - socket = g_socket_listener_accept_finish (G_SOCKET_LISTENER (listener), result, source_object, error); - if (socket) - return G_IO_STREAM (socket); -#endif - - return NULL; -} diff --git a/src/controller/spice-foreign-menu-listener.h b/src/controller/spice-foreign-menu-listener.h deleted file mode 100644 index 1071528..0000000 --- a/src/controller/spice-foreign-menu-listener.h +++ /dev/null @@ -1,47 +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 __SPICE_FOREIGN_MENU_LISTENER_H__ -#define __SPICE_FOREIGN_MENU_LISTENER_H__ - -#include <gio/gio.h> - -G_BEGIN_DECLS - -#define SPICE_FOREIGN_MENU_LISTENER_ERROR spice_foreign_menu_listener_error_quark () -GQuark spice_foreign_menu_listener_error_quark (void); - -typedef enum -{ - SPICE_FOREIGN_MENU_LISTENER_ERROR_VALUE /* incorrect value */ -} SpiceForeignMenuListenerError; - - -GObject* spice_foreign_menu_listener_new (const gchar *address, GError **error); - -void spice_foreign_menu_listener_accept_async (GObject *listener, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -GIOStream* spice_foreign_menu_listener_accept_finish (GObject *listener, - GAsyncResult *result, - GObject **source_object, - GError **error); -G_END_DECLS - -#endif /* __SPICE_FOREIGN_MENU_LISTENER_H__ */ diff --git a/src/controller/test.c b/src/controller/test.c deleted file mode 100644 index 783499c..0000000 --- a/src/controller/test.c +++ /dev/null @@ -1,289 +0,0 @@ -/* Copyright (C) 2011 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 <stdio.h> -#include <stdint.h> -#include <spice/controller_prot.h> - -#include "spice-controller.h" - -#ifdef WIN32 -#include <windows.h> -#define PIPE_NAME TEXT("\\\\.\\pipe\\SpiceController-%lu") -static HANDLE pipe = INVALID_HANDLE_VALUE; -#else - -#include <sys/socket.h> -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#include <sys/un.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -#define PIPE_NAME "/tmp/test" -static int sock = -1; - -#endif - -#define PIPE_NAME_MAX_LEN 256 - -void write_to_pipe (const void* data, size_t len) -{ -#ifdef WIN32 - DWORD written; - if (!WriteFile (pipe, data, len, &written, NULL) || written != len) { - printf("Write to pipe failed %lu\n", GetLastError()); - } -#else - if (send (sock, data, len, 0) != len) { - printf ("send failed, (%d) %s\n", errno, strerror(errno)); - } -#endif -} - -gboolean send_init (void) -{ - ControllerInit msg = { - { CONTROLLER_MAGIC, CONTROLLER_VERSION, sizeof (msg) }, - 0, - CONTROLLER_FLAG_EXCLUSIVE - }; - - write_to_pipe(&msg, sizeof (msg)); - return FALSE; -} - -void send_msg (uint32_t id) -{ - ControllerMsg msg = { - id, sizeof (msg) - }; - - write_to_pipe (&msg, sizeof (msg)); -} - -void send_value (uint32_t id, uint32_t value) -{ - ControllerValue msg = { - { id, sizeof(msg) }, - value - }; - - write_to_pipe (&msg, sizeof (msg)); -} - -void send_data (uint32_t id, uint8_t* data, size_t data_size) -{ - size_t size = sizeof (ControllerData) + data_size; - ControllerData* msg = (ControllerData*)g_malloc0 (size); - - msg->base.id = id; - msg->base.size = (uint32_t)size; - memcpy (msg->data, data, data_size); - write_to_pipe (msg, size); - g_free (msg); -} - -ssize_t read_from_pipe (void* data, size_t size) -{ - ssize_t read; -#ifdef WIN32 - DWORD bytes; - if (!ReadFile (pipe, data, size, &bytes, NULL)) { - printf ("Read from pipe failed %lu\n", GetLastError()); - } - read = bytes; -#else - read = recv (sock, data, size, 0); - if ((read == -1 || read == 0)) { - printf ("recv failed, (%d) %s\n", errno, strerror (errno)); - } -#endif - return read; -} - -#define HOST "localhost" -#define PORT 5931 -#define SPORT 0 -#define PWD "P@s5w0rd" -#define SECURE_CHANNELS "main,inputs,playback" -#define DISABLED_CHANNELS "playback,record" -#define TITLE "Hello from controller" -#define HOTKEYS "toggle-fullscreen=shift+f1,release-cursor=shift+f2" -#define MENU "0\r4864\rS&end Ctrl+Alt+Del\tCtrl+Alt+End\r0\r\n" \ - "0\r5120\r&Toggle full screen\tShift+F11\r0\r\n" \ - "0\r1\r&Special keys\r4\r\n" \ - "1\r5376\r&Send Shift+F11\r0\r\n" \ - "1\r5632\r&Send Shift+F12\r0\r\n" \ - "1\r5888\r&Send Ctrl+Alt+End\r0\r\n" \ - "0\r1\r-\r1\r\n" \ - "0\r2\rChange CD\r4\r\n" \ - "2\r3\rNo CDs\r0\r\n" \ - "2\r4\r[Eject]\r0\r\n" \ - "0\r5\r-\r1\r\n" \ - "0\r6\rPlay\r0\r\n" \ - "0\r7\rSuspend\r0\r\n" \ - "0\r8\rStop\r0\r\n" - -#define TLS_CIPHERS "TLS_C1PHERS" -#define CA_FILE "C@_FILE" -#define HOST_SUBJECT "Host_SUBJ3CT" - -SpiceCtrlController *ctrl; -GMainLoop *loop; - -void signaled (GObject *gobject, const gchar *signal_name) -{ - g_message ("signaled: %s", signal_name); - if (g_str_equal (signal_name, "hide")) { - spice_ctrl_controller_menu_item_click_msg (ctrl, 42); - g_timeout_add (1000, (GSourceFunc)g_main_loop_quit, loop); - } -} - -void notified (GObject *gobject, GParamSpec *pspec, - gpointer user_data) -{ - GValue value = { 0, }; - GValue strvalue = { 0, }; - - g_return_if_fail (gobject != NULL); - g_return_if_fail (pspec != NULL); - - g_value_init (&value, pspec->value_type); - g_value_init (&strvalue, G_TYPE_STRING); - g_object_get_property (gobject, pspec->name, &value); - - if (pspec->value_type == G_TYPE_STRV) { - gchar** p = (gchar **)g_value_get_boxed (&value); - g_message ("notify::%s == ", pspec->name); - while (*p) - g_message ("%s", *p++); - } else if (G_TYPE_IS_OBJECT(pspec->value_type)) { - GObject *o = g_value_get_object (&value); - g_message ("notify::%s == %s", pspec->name, o ? G_OBJECT_TYPE_NAME (o) : "null"); - } else { - g_value_transform (&value, &strvalue); - g_message ("notify::%s = %s", pspec->name, g_value_get_string (&strvalue)); - } - - g_value_unset (&value); - g_value_unset (&strvalue); -} - -void connect_signals (gpointer obj) -{ - guint i, n_ids = 0; - guint *ids = NULL; - GType type = G_OBJECT_TYPE (obj); - - ids = g_signal_list_ids (type, &n_ids); - for (i = 0; i < n_ids; i++) { - const gchar *name = g_signal_name (ids[i]); - g_signal_connect (obj, name, G_CALLBACK (signaled), (gpointer)name); - } -} - -int main (int argc, char *argv[]) -{ -#ifdef WIN32 - int spicec_pid = (argc > 1 ? atoi (argv[1]) : 0); -#endif - char* host = (argc > 2 ? argv[2] : (char*)HOST); - int port = (argc > 3 ? atoi (argv[3]) : PORT); - char pipe_name[PIPE_NAME_MAX_LEN]; - ControllerValue msg; - ssize_t read; - - ctrl = spice_ctrl_controller_new (); - loop = g_main_loop_new (NULL, FALSE); - g_signal_connect (ctrl, "notify", G_CALLBACK (notified), NULL); - connect_signals (ctrl); - -#ifdef WIN32 - snprintf (pipe_name, PIPE_NAME_MAX_LEN, PIPE_NAME, spicec_pid); - spice_ctrl_controller_listen (ctrl, pipe_name, NULL, NULL); - - printf ("Creating Spice controller connection %s\n", pipe_name); - pipe = CreateFile (pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - if (pipe == INVALID_HANDLE_VALUE) { - printf ("Could not open pipe %lu\n", GetLastError()); - return -1; - } -#else - spice_ctrl_controller_listen (ctrl, PIPE_NAME, NULL, NULL); - - snprintf (pipe_name, PIPE_NAME_MAX_LEN, PIPE_NAME); - printf ("Creating a controller connection %s\n", pipe_name); - struct sockaddr_un remote; - if ((sock = socket (AF_UNIX, SOCK_STREAM, 0)) == -1) { - printf ("Could not open socket, (%d) %s\n", errno, strerror(errno)); - return -1; - } - remote.sun_family = AF_UNIX; - strcpy (remote.sun_path, pipe_name); - if (connect (sock, (struct sockaddr *)&remote, - strlen (remote.sun_path) + sizeof(remote.sun_family)) == -1) { - printf ("Socket connect failed, (%d) %s\n", errno, strerror(errno)); - close (sock); - return -1; - } -#endif - - /* TODO: we rely on socket / pipe buffer... which is lame :) */ - send_init (); - - send_data (CONTROLLER_HOST, (uint8_t*)host, strlen(host) + 1); - send_value (CONTROLLER_PORT, port); - send_value (CONTROLLER_SPORT, SPORT); - send_data (CONTROLLER_PASSWORD, (uint8_t*)PWD, strlen(PWD) + 1); - send_data (CONTROLLER_SECURE_CHANNELS, (uint8_t*)SECURE_CHANNELS, strlen(SECURE_CHANNELS) + 1); - send_data (CONTROLLER_DISABLE_CHANNELS, (uint8_t*)DISABLED_CHANNELS, strlen(DISABLED_CHANNELS) + 1); - send_data (CONTROLLER_TLS_CIPHERS, (uint8_t*)TLS_CIPHERS, strlen(TLS_CIPHERS) + 1); - send_data (CONTROLLER_CA_FILE, (uint8_t*)CA_FILE, strlen(CA_FILE) + 1); - send_data (CONTROLLER_HOST_SUBJECT, (uint8_t*)HOST_SUBJECT, strlen(HOST_SUBJECT) + 1); - send_data (CONTROLLER_SET_TITLE, (uint8_t*)TITLE, strlen(TITLE) + 1); - send_data (CONTROLLER_HOTKEYS, (uint8_t*)HOTKEYS, strlen(HOTKEYS) + 1); - send_data (CONTROLLER_CREATE_MENU, (uint8_t*)MENU, strlen(MENU)); - - send_value (CONTROLLER_FULL_SCREEN, /*CONTROLLER_SET_FULL_SCREEN |*/ CONTROLLER_AUTO_DISPLAY_RES); - - send_msg (CONTROLLER_SHOW); - send_msg (CONTROLLER_CONNECT); - send_msg (CONTROLLER_SHOW); - send_msg (CONTROLLER_DELETE_MENU); - send_msg (CONTROLLER_HIDE); - - g_main_loop_run (loop); - - while ((read = read_from_pipe (&msg, sizeof(msg))) == sizeof(msg)) { - printf ("Received id %u, size %u, value %u\n", msg.base.id, msg.base.size, msg.value); - if (msg.value == 42) - break; - } - -#ifdef WIN32 - CloseHandle (pipe); -#else - close (sock); -#endif - g_object_unref (ctrl); - return 0; -} diff --git a/src/controller/util.vala b/src/controller/util.vala deleted file mode 100644 index acd677e..0000000 --- a/src/controller/util.vala +++ /dev/null @@ -1,42 +0,0 @@ -// 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/>. - -namespace SpiceCtrl { - - public async void input_stream_read (InputStream stream, uint8[] buffer) throws GLib.IOError { - var length = buffer.length; - ssize_t i = 0; - - while (i < length) { - var n = yield stream.read_async (buffer[i:length]); - if (n == 0) - throw new GLib.IOError.CLOSED ("closed stream") ; - i += n; - } - } - - public async void output_stream_write (OutputStream stream, owned uint8[] buffer) throws GLib.IOError { - var length = buffer.length; - ssize_t i = 0; - - while (i < length) { - var n = yield stream.write_async (buffer[i:length]); - if (n == 0) - throw new GLib.IOError.CLOSED ("closed stream") ; - i += n; - } - } - -} diff --git a/src/controller/win32-util.c b/src/controller/win32-util.c deleted file mode 100644 index c3e0400..0000000 --- a/src/controller/win32-util.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - 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 "win32-util.h" -#include <windows.h> -#include <sddl.h> -#include <aclapi.h> - -gboolean -spice_win32_set_low_integrity (void* handle, GError **error) -{ - g_return_val_if_fail (handle != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* see also http://msdn.microsoft.com/en-us/library/bb625960.aspx */ - PSECURITY_DESCRIPTOR psd = NULL; - PACL psacl = NULL; - BOOL sacl_present = FALSE; - BOOL sacl_defaulted = FALSE; - char *emsg; - int errsv; - gboolean success = FALSE; - - if (!ConvertStringSecurityDescriptorToSecurityDescriptor ("S:(ML;;NW;;;LW)", - SDDL_REVISION_1, &psd, NULL)) - goto failed; - - if (!GetSecurityDescriptorSacl (psd, &sacl_present, &psacl, &sacl_defaulted)) - goto failed; - - if (SetSecurityInfo (handle, SE_KERNEL_OBJECT, LABEL_SECURITY_INFORMATION, - NULL, NULL, NULL, psacl) != ERROR_SUCCESS) - goto failed; - - success = TRUE; - goto end; - -failed: - errsv = GetLastError (); - emsg = g_win32_error_message (errsv); - g_set_error (error, G_IO_ERROR, - g_io_error_from_win32_error (errsv), - "Error setting integrity: %s", - emsg); - g_free (emsg); - -end: - if (psd != NULL) - LocalFree (psd); - - return success; -} - -static gboolean -get_user_security_attributes (SECURITY_ATTRIBUTES* psa, SECURITY_DESCRIPTOR* psd, PACL* ppdacl) -{ - EXPLICIT_ACCESS ea; - TRUSTEE trst; - DWORD ret = 0; - - ZeroMemory (psa, sizeof (*psa)); - ZeroMemory (psd, sizeof (*psd)); - psa->nLength = sizeof (*psa); - psa->bInheritHandle = FALSE; - psa->lpSecurityDescriptor = psd; - - ZeroMemory (&trst, sizeof (trst)); - trst.pMultipleTrustee = NULL; - trst.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; - trst.TrusteeForm = TRUSTEE_IS_NAME; - trst.TrusteeType = TRUSTEE_IS_USER; - trst.ptstrName = "CURRENT_USER"; - - ZeroMemory (&ea, sizeof (ea)); - ea.grfAccessPermissions = GENERIC_WRITE | GENERIC_READ; - ea.grfAccessMode = SET_ACCESS; - ea.grfInheritance = NO_INHERITANCE; - ea.Trustee = trst; - - ret = SetEntriesInAcl (1, &ea, NULL, ppdacl); - if (ret != ERROR_SUCCESS) - return FALSE; - - if (!InitializeSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION)) - return FALSE; - - if (!SetSecurityDescriptorDacl (psd, TRUE, *ppdacl, FALSE)) - return FALSE; - - return TRUE; -} - -#define DEFAULT_PIPE_BUF_SIZE 4096 - -SpiceNamedPipe* -spice_win32_user_pipe_new (gchar *name, GError **error) -{ - SECURITY_ATTRIBUTES sa; - SECURITY_DESCRIPTOR sd; - PACL dacl = NULL; - HANDLE pipe; - SpiceNamedPipe *np = NULL; - - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (error != NULL, NULL); - - if (!get_user_security_attributes (&sa, &sd, &dacl)) - return NULL; - - pipe = CreateNamedPipe (name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | - /* FIXME: why is FILE_FLAG_FIRST_PIPE_INSTANCE needed for WRITE_DAC - * (apparently needed by SetSecurityInfo). This will prevent - * multiple pipe listener....?! */ - FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, - DEFAULT_PIPE_BUF_SIZE, DEFAULT_PIPE_BUF_SIZE, - 0, &sa); - - if (pipe == INVALID_HANDLE_VALUE) { - int errsv = GetLastError (); - gchar *emsg = g_win32_error_message (errsv); - - g_set_error (error, - G_IO_ERROR, - g_io_error_from_win32_error (errsv), - "Error CreateNamedPipe(): %s", - emsg); - - g_free (emsg); - goto end; - } - - /* lower integrity on Vista/Win7+ */ - if ((LOBYTE (g_win32_get_windows_version()) > 0x05) && - !spice_win32_set_low_integrity (pipe, error)) - goto end; - - np = SPICE_NAMED_PIPE (g_initable_new (SPICE_TYPE_NAMED_PIPE, - NULL, error, "handle", pipe, NULL)); - -end: - LocalFree (dacl); - - return np; -} diff --git a/src/controller/win32-util.h b/src/controller/win32-util.h deleted file mode 100644 index b24ac77..0000000 --- a/src/controller/win32-util.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - 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 __WIN32_UTIL_H__ -#define __WIN32_UTIL_H__ - -#include <gio/gio.h> -#include "namedpipe.h" - -G_BEGIN_DECLS - -gboolean spice_win32_set_low_integrity (void* handle, GError **error); -SpiceNamedPipe* spice_win32_user_pipe_new (gchar *name, GError **error); - -G_END_DECLS - -#endif /* __WIN32_UTIL_H__ */ -- 2.14.0.rc0.1.g40ca67566 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel