Add support for SPICE.
[virt-click.git] / commands.c
index 2564bfd..1c981ad 100644 (file)
@@ -27,6 +27,8 @@
 
 #include "click.h"
 
+static gboolean click_release (gpointer opaque);
+
 static int
 parse_click (self_t *self, gchar **args, guint nr_args)
 {
@@ -59,7 +61,7 @@ parse_click (self_t *self, gchar **args, guint nr_args)
       return -1;
   }
 
-  self->command.click.mask = 1 << (b-1);
+  self->command.click.b = b;
   self->command.cmd = CMD_CLICK;
 
   return 0;
@@ -74,6 +76,15 @@ vc_parse_command (self_t *self, gchar **args, guint nr_args)
   return -1;
 }
 
+#define NOT_SUPPORTED(cmd) \
+  do { \
+    fprintf (stderr, "virt-click: %s: "                                 \
+             "command is not implemented for this connection type\n", cmd); \
+    self->ret = EXIT_FAILURE;                                           \
+    self->callbacks->shutdown (self);                                   \
+    return;                                                             \
+  } while (0)
+
 void
 vc_issue_command (self_t *self)
 {
@@ -82,21 +93,49 @@ vc_issue_command (self_t *self)
   switch (self->command.cmd) {
   case CMD_CLICK:
     if (verbose)
-      fprintf (stderr, "click x=%d y=%d mask=0x%x\n",
+      fprintf (stderr, "click x=%d y=%d b=%d\n",
                self->command.click.x, self->command.click.y,
-               self->command.click.mask);
+               self->command.click.b);
+
+    if (!self->callbacks->click)
+      NOT_SUPPORTED ("click");
 
     r = self->callbacks->click (self,
-                                self->command.click.x,
-                                self->command.click.y,
-                                self->command.click.mask);
+                                self->command.click.x, self->command.click.y,
+                                self->command.click.b);
+    if (r == -1)
+      goto out;
+
+    g_timeout_add (100, click_release, self);
+
     break;
   }
 
+ out:
   if (r == -1) {
     fprintf (stderr, "virt-click: error sending command to remote server\n");
     self->ret = EXIT_FAILURE;
+    self->callbacks->shutdown (self);
   }
+}
+
+/* To perform a button press in VNC we have to send the button press
+ * event, wait a short period, then send a button release event (ie.
+ * no buttons pressed).
+ */
+static gboolean
+click_release (gpointer opaque)
+{
+  self_t *self = opaque;
+
+  if (verbose)
+    fprintf (stderr, "click release x=%d y=%d\n",
+             self->command.click.x, self->command.click.y);
+
+  self->callbacks->click (self,
+                          self->command.click.x, self->command.click.y,
+                          0);
+  self->callbacks->shutdown (self);
 
-  /* XXX Shutdown connection. */
+  return FALSE;
 }