[Spice-devel] [PATCH vdagent 11/11] vdagent: Use GMainLoop

2017-09-26 Thread Jakub Janků
Replace our existing loop with GMainLoop.
Use GIOChannels with g_io_add_watch() to manage IO
from udscs and x11 connections in the main loop.

Add function spice_vdagent_write_msg()
which internally uses udscs_write(), but on top of that
calls g_io_add_watch(, G_IO_OUT, ,). Once the fd becomes
ready to write, conn_channel_io_cb() is called and next
message is sent using udscs_do_write().
When using udscs_write() instead of this new function,
messages might not be delivered.

Signals are also handled in the main loop,
using g_unix_signal_add().
SIGQUIT is currently not supported by GLib.

This enables further GTK+ integration in the future.

Original author: Victor Toso
---
 src/vdagent/file-xfers.c |  29 +++
 src/vdagent/vdagent.c| 194 ---
 src/vdagent/vdagent.h|  13 
 src/vdagent/x11-randr.c  |   5 +-
 src/vdagent/x11.c|  29 +++
 5 files changed, 164 insertions(+), 106 deletions(-)

diff --git a/src/vdagent/file-xfers.c b/src/vdagent/file-xfers.c
index 4d76003..266af5f 100644
--- a/src/vdagent/file-xfers.c
+++ b/src/vdagent/file-xfers.c
@@ -39,6 +39,7 @@
 
 #include "vdagentd-proto.h"
 #include "file-xfers.h"
+#include "vdagent.h"
 
 struct vdagent_file_xfers {
 GHashTable *xfers;
@@ -221,12 +222,12 @@ void vdagent_file_xfers_start(struct vdagent_file_xfers 
*xfers,
 g_free(free_space_str);
 g_free(file_size_str);
 
-udscs_write(xfers->vdagentd,
-VDAGENTD_FILE_XFER_STATUS,
-msg->id,
-VD_AGENT_FILE_XFER_STATUS_NOT_ENOUGH_SPACE,
-(uint8_t *)_space,
-sizeof(free_space));
+spice_vdagent_write_msg(xfers->vdagentd,
+VDAGENTD_FILE_XFER_STATUS,
+msg->id,
+VD_AGENT_FILE_XFER_STATUS_NOT_ENOUGH_SPACE,
+(uint8_t *)_space,
+sizeof(free_space));
 vdagent_file_xfer_task_free(task);
 g_free(file_path);
 g_free(dir);
@@ -274,15 +275,15 @@ void vdagent_file_xfers_start(struct vdagent_file_xfers 
*xfers,
 syslog(LOG_DEBUG, "file-xfer: Adding task %u %s %"PRIu64" bytes",
task->id, path, task->file_size);
 
-udscs_write(xfers->vdagentd, VDAGENTD_FILE_XFER_STATUS,
-msg->id, VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA, NULL, 0);
+spice_vdagent_write_msg(xfers->vdagentd, VDAGENTD_FILE_XFER_STATUS,
+msg->id, VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA, 
NULL, 0);
 g_free(file_path);
 g_free(dir);
 return ;
 
 error:
-udscs_write(xfers->vdagentd, VDAGENTD_FILE_XFER_STATUS,
-msg->id, VD_AGENT_FILE_XFER_STATUS_ERROR, NULL, 0);
+spice_vdagent_write_msg(xfers->vdagentd, VDAGENTD_FILE_XFER_STATUS,
+msg->id, VD_AGENT_FILE_XFER_STATUS_ERROR, NULL, 0);
 if (task)
 vdagent_file_xfer_task_free(task);
 g_free(file_path);
@@ -353,8 +354,8 @@ void vdagent_file_xfers_data(struct vdagent_file_xfers 
*xfers,
 }
 
 if (status != -1) {
-udscs_write(xfers->vdagentd, VDAGENTD_FILE_XFER_STATUS,
-msg->id, status, NULL, 0);
+spice_vdagent_write_msg(xfers->vdagentd, VDAGENTD_FILE_XFER_STATUS,
+msg->id, status, NULL, 0);
 g_hash_table_remove(xfers->xfers, GUINT_TO_POINTER(msg->id));
 }
 }
@@ -363,6 +364,6 @@ void vdagent_file_xfers_error_disabled(struct 
udscs_connection *vdagentd, uint32
 {
 g_return_if_fail(vdagentd != NULL);
 
-udscs_write(vdagentd, VDAGENTD_FILE_XFER_STATUS,
-msg_id, VD_AGENT_FILE_XFER_STATUS_DISABLED, NULL, 0);
+spice_vdagent_write_msg(vdagentd, VDAGENTD_FILE_XFER_STATUS,
+msg_id, VD_AGENT_FILE_XFER_STATUS_DISABLED, NULL, 
0);
 }
diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c
index cdbda8b..6a5204a 100644
--- a/src/vdagent/vdagent.c
+++ b/src/vdagent/vdagent.c
@@ -34,8 +34,8 @@
 #include 
 #include 
 #include 
-#include 
 #include 
+#include 
 
 #include "vdagentd-proto.h"
 #include "vdagentd-proto-strings.h"
@@ -44,7 +44,6 @@
 
 G_DEFINE_TYPE (SpiceVDAgent, spice_vdagent, G_TYPE_OBJECT);
 
-static int quit = 0;
 static int version_mismatch = 0;
 
 /* Command line options */
@@ -164,7 +163,7 @@ static void daemon_read_complete(struct udscs_connection 
**connp,
 if (strcmp((char *)data, VERSION) != 0) {
 syslog(LOG_INFO, "vdagentd version mismatch: got %s expected %s",
data, VERSION);
-udscs_destroy_connection(connp);
+g_main_loop_quit(agent->loop);
 version_mismatch = 1;
 }
 break;
@@ -222,27 +221,6 @@ static void daemon_read_complete(struct udscs_connection 
**connp,
 }
 }
 
-static struct udscs_connection *client_setup_sync(SpiceVDAgent *agent)
-{
-

[Spice-devel] [PATCH vdagent 01/11] Bump GLib version to 2.34

2017-09-26 Thread Jakub Janků
This is required for the following GMainLoop integration,
which utilizes some of the new functions/definitions, namely:

[definition][GLib version]
g_clear_pointer()   2.34
G_SOURCE_REMOVE 2.32
G_SOURCE_CONTINUE   2.32
g_unix_signal_add() 2.30
---
 configure.ac | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index fbc20a9..d92b527 100644
--- a/configure.ac
+++ b/configure.ac
@@ -85,7 +85,7 @@ AC_ARG_ENABLE([static-uinput],
   [enable_static_uinput="$enableval"],
   [enable_static_uinput="no"])
 
-PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.28])
+PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.34])
 PKG_CHECK_MODULES(X, [xfixes xrandr >= 1.3 xinerama x11])
 PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.13])
 PKG_CHECK_MODULES(ALSA, [alsa >= 1.0.22])
-- 
2.13.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH vdagent 07/11] vdagent: small refactor on udscs setup function

2017-09-26 Thread Jakub Janků
From: Victor Toso 

This is mostly a preparatory patch to reduce the usage of globals and
the GMainLoop integration. The changes target one function by:

* Changing its name from client_setup() to client_setup_sync(): As it
  important to clarify that the function block;

* Removing the 'reconnect' argument as the input is the global
  'do_daemonize'. We can use the global here as it is related to
  command line options;

* Changing the return value from 'int' to 'udscs_connection *' as the
  followup patch will remove the global variable 'client'.

Signed-off-by: Victor Toso 
---
 src/vdagent/vdagent.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c
index 21f88f8..0b6df3f 100644
--- a/src/vdagent/vdagent.c
+++ b/src/vdagent/vdagent.c
@@ -223,18 +223,20 @@ static void daemon_read_complete(struct udscs_connection 
**connp,
 }
 }
 
-static int client_setup(int reconnect)
+static struct udscs_connection *client_setup_sync(void)
 {
+struct udscs_connection *conn = NULL;
+
 while (!quit) {
-client = udscs_connect(vdagentd_socket, daemon_read_complete, NULL,
-   NULL, vdagentd_messages, VDAGENTD_NO_MESSAGES,
-   debug);
-if (client || !reconnect || quit) {
+conn = udscs_connect(vdagentd_socket, daemon_read_complete, NULL,
+ NULL, vdagentd_messages, VDAGENTD_NO_MESSAGES,
+ debug);
+if (conn || !do_daemonize || quit) {
 break;
 }
 sleep(1);
 }
-return client == NULL;
+return conn;
 }
 
 static void quit_handler(int sig)
@@ -355,7 +357,8 @@ reconnect:
 execvp(argv[0], argv);
 }
 
-if (client_setup(do_daemonize)) {
+client = client_setup_sync();
+if (client == NULL) {
 return 1;
 }
 
-- 
2.13.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH vdagent 05/11] vdagent: Use glib's commandline parser

2017-09-26 Thread Jakub Janků
From: Victor Toso 

As we already depend on glib, let's remove code that glib can take
care of. In this case, we don't need to handle commandline parsing
ourselves.

In regard the global variables:

* static const char * -> static gchar * [only paths]
  path variables: portdev, fx_dir, vdagentd_socket

* static int -> static gboolean
  flags: debug, do_daemonize, x11_sync, fx_open_dir

Since fx_open_dir is gboolean, the dir is by default not opened,
using option "-o" forces it to open.

Signed-off-by: Victor Toso 
---
 src/vdagent/vdagent.c | 122 +-
 1 file changed, 62 insertions(+), 60 deletions(-)

diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c
index cc4dac1..51a7618 100644
--- a/src/vdagent/vdagent.c
+++ b/src/vdagent/vdagent.c
@@ -44,17 +44,46 @@
 #include "x11.h"
 #include "file-xfers.h"
 
-static const char *portdev = DEFAULT_VIRTIO_PORT_PATH;
-static const char *vdagentd_socket = VDAGENTD_SOCKET;
-static int debug = 0;
-static const char *fx_dir = NULL;
-static int fx_open_dir = -1;
 static struct vdagent_x11 *x11 = NULL;
 static struct vdagent_file_xfers *vdagent_file_xfers = NULL;
 static struct udscs_connection *client = NULL;
 static int quit = 0;
 static int version_mismatch = 0;
 
+/* Command line options */
+static gboolean debug = FALSE;
+static gboolean x11_sync = FALSE;
+static gboolean fx_open_dir = FALSE;
+static gboolean do_daemonize = TRUE;
+static gchar *fx_dir = NULL;
+static gchar *portdev = NULL;
+static gchar *vdagentd_socket = NULL;
+
+static GOptionEntry entries[] = {
+{ "debug", 'd', 0,
+   G_OPTION_ARG_NONE, ,
+   "Enable debug", NULL },
+{ "virtio-serial-port-path", 's', 0,
+  G_OPTION_ARG_STRING, ,
+  "Set virtio-serial path ("  DEFAULT_VIRTIO_PORT_PATH ")", NULL },
+{ "vdagentd-socket", 'S', 0, G_OPTION_ARG_STRING,
+   _socket,
+   "Set spice-vdagentd socket (" VDAGENTD_SOCKET ")", NULL },
+{ "foreground", 'x', G_OPTION_FLAG_REVERSE,
+   G_OPTION_ARG_NONE, _daemonize,
+   "Do not daemonize the agent", NULL },
+{ "file-xfer-save-dir", 'f', 0,
+  G_OPTION_ARG_STRING, _dir,
+  "Set directory to file transfers files", NULL},
+{ "file-xfer-open-dir", 'o', 0,
+   G_OPTION_ARG_NONE, _open_dir,
+   "Open directory after completing file transfer", NULL },
+{ "x11-abort-on-error", 'y', 0,
+  G_OPTION_ARG_NONE, _sync,
+  "Aborts on errors from X11", NULL },
+{ NULL }
+};
+
 /**
  * xfer_get_download_directory
  *
@@ -96,9 +125,6 @@ static gboolean vdagent_init_file_xfer(void)
 return FALSE;
 }
 
-if (fx_open_dir == -1)
-fx_open_dir = !vdagent_x11_has_icons_on_desktop(x11);
-
 vdagent_file_xfers = vdagent_file_xfers_create(client, xfer_dir,
fx_open_dir, debug);
 return (vdagent_file_xfers != NULL);
@@ -210,22 +236,6 @@ static int client_setup(int reconnect)
 return client == NULL;
 }
 
-static void usage(FILE *fp)
-{
-fprintf(fp,
-  "Usage: spice-vdagent [OPTIONS]\n\n"
-  "Spice guest agent X11 session agent, version %s.\n\n"
-  "Options:\n"
-  "  -hprint this text\n"
-  "  -dlog debug messages\n"
-  "  -s  set virtio serial port\n"
-  "  -S  set udcs socket\n"
-  "  -xdon't daemonize\n"
-  "  -f   file xfer save dir\n"
-  "  -o <0|1>  open dir on file xfer completion\n",
-  VERSION);
-}
-
 static void quit_handler(int sig)
 {
 quit = 1;
@@ -289,45 +299,33 @@ static int file_test(const char *path)
 int main(int argc, char *argv[])
 {
 fd_set readfds, writefds;
-int c, n, nfds, x11_fd;
-int do_daemonize = 1;
+int n, nfds, x11_fd;
 int parent_socket = 0;
-int x11_sync = 0;
 struct sigaction act;
+GOptionContext *context;
+GError *error = NULL;
+
+context = g_option_context_new(NULL);
+g_option_context_add_main_entries(context, entries, NULL);
+g_option_context_set_summary(context,
+ "\tSpice session guest agent: X11\n"
+ "\tVersion: " VERSION);
+g_option_context_parse(context, , , );
+g_option_context_free(context);
+
+if (error != NULL) {
+g_printerr("Invalid arguments, %s\n", error->message);
+g_clear_error();
+return -1;
+}
 
-for (;;) {
-if (-1 == (c = getopt(argc, argv, "-dxhys:f:o:S:")))
-break;
-switch (c) {
-case 'd':
-debug++;
-break;
-case 's':
-portdev = optarg;
-break;
-case 'x':
-do_daemonize = 0;
-break;
-case 'y':
-x11_sync = 1;
-break;
-case 'h':

[Spice-devel] [PATCH vdagent 03/11] vdagent: move file xfer initialization to a function

2017-09-26 Thread Jakub Janků
From: Victor Toso 

This patch creates two functions:
- xfer_get_download_directory()
- vdagent_init_file_xfer()

The logic should be similar as it was before this patch, taking in
consideration the global variables fx_open_dir and fx_dir which are
set from command line.

Signed-off-by: Victor Toso 
---
 src/vdagent/vdagent.c | 70 ++-
 1 file changed, 53 insertions(+), 17 deletions(-)

diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c
index 6b4c127..0332bd0 100644
--- a/src/vdagent/vdagent.c
+++ b/src/vdagent/vdagent.c
@@ -55,6 +55,55 @@ static struct udscs_connection *client = NULL;
 static int quit = 0;
 static int version_mismatch = 0;
 
+/**
+ * xfer_get_download_directory
+ *
+ * Return path where transferred files should be stored.
+ * Returned path should not be freed or modified.
+ **/
+static const gchar *xfer_get_download_directory(void)
+{
+if (fx_dir != NULL)
+return fx_dir;
+
+if (vdagent_x11_has_icons_on_desktop(x11))
+return g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP);
+
+return g_get_user_special_dir(G_USER_DIRECTORY_DOWNLOAD);
+}
+
+/**
+ * vdagent_init_file_xfer
+ *
+ * Initialize handler for file xfer,
+ * return TRUE on success (vdagent_file_xfers is not NULL).
+ **/
+static gboolean vdagent_init_file_xfer(void)
+{
+const gchar *xfer_dir;
+
+if (vdagent_file_xfers != NULL) {
+syslog(LOG_DEBUG, "File-xfer already initialized");
+return TRUE;
+}
+
+xfer_dir = xfer_get_download_directory();
+if (xfer_dir == NULL) {
+syslog(LOG_WARNING,
+   "warning could not get file xfer save dir, "
+   "file transfers will be disabled");
+vdagent_file_xfers = NULL;
+return FALSE;
+}
+
+if (fx_open_dir == -1)
+fx_open_dir = !vdagent_x11_has_icons_on_desktop(x11);
+
+vdagent_file_xfers = vdagent_file_xfers_create(client, xfer_dir,
+   fx_open_dir, debug);
+return (vdagent_file_xfers != NULL);
+}
+
 static void daemon_read_complete(struct udscs_connection **connp,
 struct udscs_message_header *header, uint8_t *data)
 {
@@ -133,8 +182,8 @@ static void daemon_read_complete(struct udscs_connection 
**connp,
 vdagent_x11_client_disconnected(x11);
 if (vdagent_file_xfers != NULL) {
 vdagent_file_xfers_destroy(vdagent_file_xfers);
-vdagent_file_xfers = vdagent_file_xfers_create(client, fx_dir,
-   fx_open_dir, debug);
+vdagent_file_xfers = NULL;
+vdagent_init_file_xfer();
 }
 break;
 default:
@@ -313,21 +362,8 @@ reconnect:
 return 1;
 }
 
-if (!fx_dir)
-fx_dir = g_get_user_special_dir(vdagent_x11_has_icons_on_desktop(x11) ?
-G_USER_DIRECTORY_DESKTOP :
-G_USER_DIRECTORY_DOWNLOAD);
-if (fx_open_dir == -1)
-fx_open_dir = !vdagent_x11_has_icons_on_desktop(x11);
-
-if (fx_dir) {
-vdagent_file_xfers = vdagent_file_xfers_create(client, fx_dir,
-   fx_open_dir, debug);
-} else {
-syslog(LOG_WARNING,
-   "warning could not get file xfer save dir, file transfers will 
be disabled");
-vdagent_file_xfers = NULL;
-}
+if (!vdagent_init_file_xfer())
+syslog(LOG_WARNING, "File transfer is disabled");
 
 if (parent_socket) {
 if (write(parent_socket, "OK", 2) != 2)
-- 
2.13.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH vdagent 04/11] vdagent: move file xfer finalize to a function

2017-09-26 Thread Jakub Janků
From: Victor Toso 

This patch creates vdagent_finalize_file_xfer() to finalize and stop
file xfer. Moving this code to a function removes some duplication.

Signed-off-by: Victor Toso 
---
 src/vdagent/vdagent.c | 22 --
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c
index 0332bd0..cc4dac1 100644
--- a/src/vdagent/vdagent.c
+++ b/src/vdagent/vdagent.c
@@ -104,6 +104,15 @@ static gboolean vdagent_init_file_xfer(void)
 return (vdagent_file_xfers != NULL);
 }
 
+static gboolean vdagent_finalize_file_xfer(void)
+{
+if (vdagent_file_xfers == NULL)
+return FALSE;
+
+g_clear_pointer(_file_xfers, vdagent_file_xfers_destroy);
+return TRUE;
+}
+
 static void daemon_read_complete(struct udscs_connection **connp,
 struct udscs_message_header *header, uint8_t *data)
 {
@@ -155,10 +164,7 @@ static void daemon_read_complete(struct udscs_connection 
**connp,
 if (debug)
 syslog(LOG_DEBUG, "Disabling file-xfers");
 
-if (vdagent_file_xfers != NULL) {
-vdagent_file_xfers_destroy(vdagent_file_xfers);
-vdagent_file_xfers = NULL;
-}
+vdagent_finalize_file_xfer();
 break;
 case VDAGENTD_AUDIO_VOLUME_SYNC: {
 VDAgentAudioVolumeSync *avs = (VDAgentAudioVolumeSync *)data;
@@ -180,9 +186,7 @@ static void daemon_read_complete(struct udscs_connection 
**connp,
 break;
 case VDAGENTD_CLIENT_DISCONNECTED:
 vdagent_x11_client_disconnected(x11);
-if (vdagent_file_xfers != NULL) {
-vdagent_file_xfers_destroy(vdagent_file_xfers);
-vdagent_file_xfers = NULL;
+if (vdagent_finalize_file_xfer()) {
 vdagent_init_file_xfer();
 }
 break;
@@ -395,9 +399,7 @@ reconnect:
 udscs_client_handle_fds(, , );
 }
 
-if (vdagent_file_xfers != NULL) {
-vdagent_file_xfers_destroy(vdagent_file_xfers);
-}
+vdagent_finalize_file_xfer();
 vdagent_x11_destroy(x11, client == NULL);
 udscs_destroy_connection();
 if (!quit && do_daemonize)
-- 
2.13.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH vdagent 00/11] GMainLoop integration

2017-09-26 Thread Jakub Janků
Hi,
this patchset is supposed to be the start of tighter
GLib and GTK+ integration in spice vdagent.
The goal for the future is to replace X11-specific code
with GTK/GLib.

Main changes:
- Use GLib's command line parser
- Add SpiceVDAgent GObject
- Replace main while-loop with GMainLoop

Known limitations:
- no SIGQUIT handeling

Cheers,
  Jakub Janků


Jakub Janků (5):
  Bump GLib version to 2.34
  vdagent: remove fx_dir magic values
  vdagent: Introduce SpiceVDAgent object
  udscs: Add udscs_is_write_pending()
  vdagent: Use GMainLoop

Victor Toso (6):
  vdagent: move file xfer initialization to a function
  vdagent: move file xfer finalize to a function
  vdagent: Use glib's commandline parser
  udscs: add userdata to read_callback
  vdagent: small refactor on udscs setup function
  udscs: allow fd control outside udscs

 Makefile.am  |   3 +
 configure.ac |   3 +-
 src/udscs.c  |  37 +++-
 src/udscs.h  |  26 ++-
 src/vdagent/file-xfers.c |  29 +--
 src/vdagent/vdagent.c| 478 +--
 src/vdagent/vdagent.h|  67 +++
 src/vdagent/x11-randr.c  |   5 +-
 src/vdagent/x11.c|  29 +--
 src/vdagentd/vdagentd.c  |   7 +-
 10 files changed, 458 insertions(+), 226 deletions(-)
 create mode 100644 src/vdagent/vdagent.h

-- 
2.13.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH vdagent 10/11] udscs: Add udscs_is_write_pending()

2017-09-26 Thread Jakub Janků
This is necessary for the following GMainLoop integration.
---
 src/udscs.c | 6 ++
 src/udscs.h | 4 
 2 files changed, 10 insertions(+)

diff --git a/src/udscs.c b/src/udscs.c
index 2761cbb..4a0e193 100644
--- a/src/udscs.c
+++ b/src/udscs.c
@@ -359,6 +359,12 @@ int udscs_client_get_fd(struct udscs_connection *conn)
 return conn->fd;
 }
 
+gboolean udscs_is_write_pending(struct udscs_connection *conn)
+{
+g_return_val_if_fail(conn != NULL, FALSE);
+return (conn->write_buf != NULL);
+}
+
 #ifndef UDSCS_NO_SERVER
 
 /* -- Server-side implementation -- */
diff --git a/src/udscs.h b/src/udscs.h
index 08e71c8..a8ca952 100644
--- a/src/udscs.h
+++ b/src/udscs.h
@@ -126,6 +126,10 @@ void udscs_do_read(struct udscs_connection **connp);
  */
 void udscs_do_write(struct udscs_connection **connp);
 
+/* Return TRUE if there's some data in the write buffer to be written,
+ * otherwise return FALSE.
+ */
+gboolean udscs_is_write_pending(struct udscs_connection *conn);
 
 #ifndef UDSCS_NO_SERVER
 
-- 
2.13.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH vdagent 08/11] vdagent: Introduce SpiceVDAgent object

2017-09-26 Thread Jakub Janků
Related to ongoing work to use GMainLoop and GTK integration

Signed-off-by: Victor Toso 
---
 Makefile.am   |   3 +
 configure.ac  |   1 +
 src/vdagent/vdagent.c | 149 +++---
 src/vdagent/vdagent.h |  54 ++
 4 files changed, 150 insertions(+), 57 deletions(-)
 create mode 100644 src/vdagent/vdagent.h

diff --git a/Makefile.am b/Makefile.am
index 45f7177..efd058a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,6 +14,7 @@ common_sources =  \
 src_spice_vdagent_CFLAGS = \
$(X_CFLAGS) \
$(SPICE_CFLAGS) \
+   $(GOBJECT2_CFLAGS)  \
$(GLIB2_CFLAGS) \
$(ALSA_CFLAGS)  \
-I$(srcdir)/src \
@@ -23,6 +24,7 @@ src_spice_vdagent_CFLAGS =\
 src_spice_vdagent_LDADD =  \
$(X_LIBS)   \
$(SPICE_LIBS)   \
+   $(GOBJECT2_LIBS)\
$(GLIB2_LIBS)   \
$(ALSA_LIBS)\
$(NULL)
@@ -38,6 +40,7 @@ src_spice_vdagent_SOURCES =   \
src/vdagent/x11.c   \
src/vdagent/x11.h   \
src/vdagent/vdagent.c   \
+   src/vdagent/vdagent.h   \
$(NULL)
 
 src_spice_vdagentd_CFLAGS =\
diff --git a/configure.ac b/configure.ac
index d92b527..12b7d23 100644
--- a/configure.ac
+++ b/configure.ac
@@ -86,6 +86,7 @@ AC_ARG_ENABLE([static-uinput],
   [enable_static_uinput="no"])
 
 PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.34])
+PKG_CHECK_MODULES(GOBJECT2, [gobject-2.0])
 PKG_CHECK_MODULES(X, [xfixes xrandr >= 1.3 xinerama x11])
 PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.13])
 PKG_CHECK_MODULES(ALSA, [alsa >= 1.0.22])
diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c
index 0b6df3f..cdbda8b 100644
--- a/src/vdagent/vdagent.c
+++ b/src/vdagent/vdagent.c
@@ -37,16 +37,13 @@
 #include 
 #include 
 
-#include "udscs.h"
 #include "vdagentd-proto.h"
 #include "vdagentd-proto-strings.h"
 #include "audio.h"
-#include "x11.h"
-#include "file-xfers.h"
+#include "vdagent.h"
+
+G_DEFINE_TYPE (SpiceVDAgent, spice_vdagent, G_TYPE_OBJECT);
 
-static struct vdagent_x11 *x11 = NULL;
-static struct vdagent_file_xfers *vdagent_file_xfers = NULL;
-static struct udscs_connection *client = NULL;
 static int quit = 0;
 static int version_mismatch = 0;
 
@@ -90,12 +87,12 @@ static GOptionEntry entries[] = {
  * Return path where transferred files should be stored.
  * Returned path should not be freed or modified.
  **/
-static const gchar *xfer_get_download_directory(void)
+static const gchar *xfer_get_download_directory(SpiceVDAgent *agent)
 {
 if (fx_dir != NULL)
 return fx_dir;
 
-if (vdagent_x11_has_icons_on_desktop(x11))
+if (vdagent_x11_has_icons_on_desktop(agent->x11))
 return g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP);
 
 return g_get_user_special_dir(G_USER_DIRECTORY_DOWNLOAD);
@@ -105,61 +102,63 @@ static const gchar *xfer_get_download_directory(void)
  * vdagent_init_file_xfer
  *
  * Initialize handler for file xfer,
- * return TRUE on success (vdagent_file_xfers is not NULL).
+ * return TRUE on success (agent->xfers is not NULL).
  **/
-static gboolean vdagent_init_file_xfer(void)
+static gboolean vdagent_init_file_xfer(SpiceVDAgent *agent)
 {
 const gchar *xfer_dir;
 
-if (vdagent_file_xfers != NULL) {
+if (agent->xfers != NULL) {
 syslog(LOG_DEBUG, "File-xfer already initialized");
 return TRUE;
 }
 
-xfer_dir = xfer_get_download_directory();
+xfer_dir = xfer_get_download_directory(agent);
 if (xfer_dir == NULL) {
 syslog(LOG_WARNING,
"warning could not get file xfer save dir, "
"file transfers will be disabled");
-vdagent_file_xfers = NULL;
 return FALSE;
 }
 
-vdagent_file_xfers = vdagent_file_xfers_create(client, xfer_dir,
-   fx_open_dir, debug);
-return (vdagent_file_xfers != NULL);
+agent->xfers = vdagent_file_xfers_create(agent->conn, xfer_dir,
+ fx_open_dir, debug);
+return (agent->xfers != NULL);
 }
 
-static gboolean vdagent_finalize_file_xfer(void)
+static gboolean vdagent_finalize_file_xfer(SpiceVDAgent *agent)
 {
-if (vdagent_file_xfers == NULL)
+if (agent->xfers == NULL)
 return FALSE;
 
-g_clear_pointer(_file_xfers, vdagent_file_xfers_destroy);
+g_clear_pointer(>xfers, vdagent_file_xfers_destroy);
 return TRUE;
 }
 
 static void daemon_read_complete(struct udscs_connection 

[Spice-devel] [PATCH vdagent 09/11] udscs: allow fd control outside udscs

2017-09-26 Thread Jakub Janků
From: Victor Toso 

This patch export two existing functions `udscs_do_read()` and
`udscs_do_write()` and also creates a new one `udscs_client_get_fd()`.

The intention of this functions is to allow vdagent to check if
connection's socket is ready to read or write. This will be done
together with GMainLoop integration in a followup patch.

Signed-off-by: Victor Toso 
---
 src/udscs.c | 17 +
 src/udscs.h | 17 +
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/src/udscs.c b/src/udscs.c
index f67d0a0..2761cbb 100644
--- a/src/udscs.c
+++ b/src/udscs.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "udscs.h"
 
 struct udscs_buf {
@@ -246,8 +247,7 @@ static void udscs_read_complete(struct udscs_connection 
**connp)
 conn->header_read = 0;
 }
 
-/* A helper for udscs_client_handle_fds() */
-static void udscs_do_read(struct udscs_connection **connp)
+void udscs_do_read(struct udscs_connection **connp)
 {
 ssize_t n;
 size_t to_read;
@@ -298,19 +298,15 @@ static void udscs_do_read(struct udscs_connection **connp)
 }
 
 /* A helper for udscs_client_handle_fds() */
-static void udscs_do_write(struct udscs_connection **connp)
+void udscs_do_write(struct udscs_connection **connp)
 {
 ssize_t n;
 size_t to_write;
 struct udscs_connection *conn = *connp;
 
 struct udscs_buf* wbuf = conn->write_buf;
-if (!wbuf) {
-syslog(LOG_ERR,
-   "%p do_write called on a connection without a write buf ?!",
-   conn);
+if (!wbuf)
 return;
-}
 
 to_write = wbuf->size - wbuf->pos;
 n = write(conn->fd, wbuf->buf + wbuf->pos, to_write);
@@ -357,6 +353,11 @@ int udscs_client_fill_fds(struct udscs_connection *conn, 
fd_set *readfds,
 return conn->fd + 1;
 }
 
+int udscs_client_get_fd(struct udscs_connection *conn)
+{
+g_return_val_if_fail(conn != NULL, -1);
+return conn->fd;
+}
 
 #ifndef UDSCS_NO_SERVER
 
diff --git a/src/udscs.h b/src/udscs.h
index 04377ba..08e71c8 100644
--- a/src/udscs.h
+++ b/src/udscs.h
@@ -109,6 +109,23 @@ void udscs_set_user_data(struct udscs_connection *conn, 
void *data);
  */
 void *udscs_get_user_data(struct udscs_connection *conn);
 
+/* Get fd from connection or return -1 if NULL */
+int udscs_client_get_fd(struct udscs_connection *conn);
+
+/* Performs a read in socket's connection. Note that fd should be ready for 
read
+ * otherwise it will destroy the connection. Use udscs_client_fill_fds(),
+ * select() and udscs_client_handle_fds() to delegate those checks to udscs.
+ */
+void udscs_do_read(struct udscs_connection **connp);
+
+/* Performs a write in socket's connection. Note that fd should be ready for
+ * write otherwise it will destroy the connection. Use udscs_client_fill_fds(),
+ * select() and udscs_client_handle_fds() to delegate those checks to udscs.
+ * If no buffer is ready to be written from udscs side, this function simply
+ * returns.
+ */
+void udscs_do_write(struct udscs_connection **connp);
+
 
 #ifndef UDSCS_NO_SERVER
 
-- 
2.13.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH vdagent 02/11] vdagent: remove fx_dir magic values

2017-09-26 Thread Jakub Janků
---
 src/vdagent/vdagent.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c
index dfb9284..6b4c127 100644
--- a/src/vdagent/vdagent.c
+++ b/src/vdagent/vdagent.c
@@ -168,7 +168,7 @@ static void usage(FILE *fp)
   "  -s  set virtio serial port\n"
   "  -S  set udcs socket\n"
   "  -xdon't daemonize\n"
-  "  -f  file xfer save dir\n"
+  "  -f   file xfer save dir\n"
   "  -o <0|1>  open dir on file xfer completion\n",
   VERSION);
 }
@@ -313,18 +313,13 @@ reconnect:
 return 1;
 }
 
-if (!fx_dir) {
-if (vdagent_x11_has_icons_on_desktop(x11))
-fx_dir = "xdg-desktop";
-else
-fx_dir = "xdg-download";
-}
+if (!fx_dir)
+fx_dir = g_get_user_special_dir(vdagent_x11_has_icons_on_desktop(x11) ?
+G_USER_DIRECTORY_DESKTOP :
+G_USER_DIRECTORY_DOWNLOAD);
 if (fx_open_dir == -1)
 fx_open_dir = !vdagent_x11_has_icons_on_desktop(x11);
-if (!strcmp(fx_dir, "xdg-desktop"))
-fx_dir = g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP);
-else if (!strcmp(fx_dir, "xdg-download"))
-fx_dir = g_get_user_special_dir(G_USER_DIRECTORY_DOWNLOAD);
+
 if (fx_dir) {
 vdagent_file_xfers = vdagent_file_xfers_create(client, fx_dir,
fx_open_dir, debug);
-- 
2.13.5

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH vdagent 06/11] udscs: add userdata to read_callback

2017-09-26 Thread Jakub Janků
From: Victor Toso 

Introduce new parameter to the functions:
  * udscs_create_server() - only used in vdagentd.c
  * udscs_connect() - only used in vdagent.c

Related changes were necessary to the predefined callback types and
its implementations to include this new parameter.

This change intends to remove some global variables from vdagent.c and
vdagentd.c

Signed-off-by: Victor Toso 
---
 src/udscs.c | 14 --
 src/udscs.h |  5 -
 src/vdagent/vdagent.c   |  5 +++--
 src/vdagentd/vdagentd.c |  7 ---
 4 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/udscs.c b/src/udscs.c
index 8b16f89..f67d0a0 100644
--- a/src/udscs.c
+++ b/src/udscs.c
@@ -62,6 +62,7 @@ struct udscs_connection {
 
 /* Callbacks */
 udscs_read_callback read_callback;
+void *read_callback_user_data;
 udscs_disconnect_callback disconnect_callback;
 
 struct udscs_connection *next;
@@ -70,6 +71,7 @@ struct udscs_connection {
 
 struct udscs_connection *udscs_connect(const char *socketname,
 udscs_read_callback read_callback,
+void *read_callback_user_data,
 udscs_disconnect_callback disconnect_callback,
 const char * const type_to_string[], int no_types, int debug)
 {
@@ -104,6 +106,7 @@ struct udscs_connection *udscs_connect(const char 
*socketname,
 }
 
 conn->read_callback = read_callback;
+conn->read_callback_user_data = read_callback_user_data;
 conn->disconnect_callback = disconnect_callback;
 
 if (conn->debug)
@@ -232,7 +235,8 @@ static void udscs_read_complete(struct udscs_connection 
**connp)
 }
 
 if (conn->read_callback) {
-conn->read_callback(connp, >header, conn->data.buf);
+conn->read_callback(connp, >header, conn->data.buf,
+conn->read_callback_user_data);
 if (!*connp) /* Was the connection disconnected by the callback ? */
 return;
 }
@@ -366,12 +370,14 @@ struct udscs_server {
 struct udscs_connection connections_head;
 udscs_connect_callback connect_callback;
 udscs_read_callback read_callback;
+void *read_callback_user_data;
 udscs_disconnect_callback disconnect_callback;
 };
 
 struct udscs_server *udscs_create_server_for_fd(int fd,
 udscs_connect_callback connect_callback,
 udscs_read_callback read_callback,
+void *read_callback_user_data,
 udscs_disconnect_callback disconnect_callback,
 const char * const type_to_string[], int no_types, int debug)
 {
@@ -392,6 +398,7 @@ struct udscs_server *udscs_create_server_for_fd(int fd,
 server->fd = fd;
 server->connect_callback = connect_callback;
 server->read_callback = read_callback;
+server->read_callback_user_data = read_callback_user_data;
 server->disconnect_callback = disconnect_callback;
 
 return server;
@@ -400,6 +407,7 @@ struct udscs_server *udscs_create_server_for_fd(int fd,
 struct udscs_server *udscs_create_server(const char *socketname,
 udscs_connect_callback connect_callback,
 udscs_read_callback read_callback,
+void *read_callback_user_data,
 udscs_disconnect_callback disconnect_callback,
 const char * const type_to_string[], int no_types, int debug)
 {
@@ -427,7 +435,8 @@ struct udscs_server *udscs_create_server(const char 
*socketname,
 return NULL;
 }
 
-return udscs_create_server_for_fd(fd, connect_callback, read_callback,
+return udscs_create_server_for_fd(fd, connect_callback,
+  read_callback, read_callback_user_data,
   disconnect_callback, type_to_string,
   no_types, debug);
 }
@@ -480,6 +489,7 @@ static void udscs_server_accept(struct udscs_server 
*server) {
 new_conn->no_types = server->no_types;
 new_conn->debug = server->debug;
 new_conn->read_callback = server->read_callback;
+new_conn->read_callback_user_data = server->read_callback_user_data;
 new_conn->disconnect_callback = server->disconnect_callback;
 
 length = sizeof(new_conn->peer_cred);
diff --git a/src/udscs.h b/src/udscs.h
index 30a96db..04377ba 100644
--- a/src/udscs.h
+++ b/src/udscs.h
@@ -45,7 +45,7 @@ struct udscs_message_header {
  * made NULL (which udscs_destroy_connection takes care of).
  */
 typedef void (*udscs_read_callback)(struct udscs_connection **connp,
-struct udscs_message_header *header, uint8_t *data);
+struct udscs_message_header *header, uint8_t *data, void *user_data);
 
 /* Callbacks with this type will be called when the connection is disconnected.
  * Note:
@@ -68,6 +68,7 @@ typedef void (*udscs_disconnect_callback)(struct 
udscs_connection *conn);
  */
 struct udscs_connection *udscs_connect(const char *socketname,
 udscs_read_callback read_callback,
+void *read_callback_user_data,
 udscs_disconnect_callback disconnect_callback,
 const char * const type_to_string[], 

[Spice-devel] Announcing spice 0.13.91 release

2017-09-26 Thread Christophe Fergeau
Hey everyone,

Another unstable spice-server release, not a lot of bugs found after the
release of 0.13.90, hopefully this means we are in a good shape... a new
spice-server unstable release. This release should be the final release
candidate for 0.14.0, which will be released next week if no big issues
are found. Any testing you can do is welcome, and if you find any
bugs/regressions compared to 0.12, please report them in our bugzilla:
https://bugs.freedesktop.org

Major Changes in 0.13.91:
=

* set human-readable name on spice threads
* leak fixes
* robustness improvements (fix potential crashes in situation which
  should not happen on normal use)
* add sanity-checks for ORC library as it can abort spice-server when
  selinux is in use
* more code cleanups/improvements


https://www.spice-space.org/download/releases/spice-0.13.91.tar.bz2
https://www.spice-space.org/download/releases/spice-0.13.91.tar.bz2.sign

These releases are signed with my GPG key:

 94A9 F756 61F7 7A61 6864  9B23 A9D8 C214 29AC 6C82

Christophe


signature.asc
Description: PGP signature
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel