Add support for SPICE.
[virt-click.git] / main.c
1 /* virt-click
2  * Copyright (C) 2011 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include <config.h>
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25
26 #include <glib/gi18n.h>
27
28 #include "click.h"
29
30 gboolean verbose = 0;
31
32 static void parse_click (self_t *self, const char *binary, guint nr_args, gchar **args);
33
34 static void
35 short_usage (const char *binary, const char *error)
36 {
37   if (error)
38     fprintf (stderr, "Error: %s\n\n", error);
39   fprintf
40     (stderr,
41      "Run '%s --help' to see a full list of available command line\n"
42      "options or consult the virt-click(1) manual page.\n",
43      binary);
44 }
45
46 int
47 main (int argc, char **argv)
48 {
49   GOptionContext *context;
50   GError *error = NULL;
51   gboolean version = 0;
52   gchar **args = NULL;
53   guint nr_args;
54   const GOptionEntry options [] = {
55     { "verbose", 'v', 0,  G_OPTION_ARG_NONE,
56       &verbose, "Enables verbose output", NULL },
57     { "version", 'V', 0,  G_OPTION_ARG_NONE,
58       &version, "Display version and exit", NULL },
59     { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &args,
60       NULL, "(click|...) [args...]" },
61     { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, 0 }
62   };
63   self_t *self;
64
65   g_type_init ();
66
67   /* Command line options */
68   context = g_option_context_new ("- send click events");
69   g_option_context_set_summary
70     (context,
71      "Send mouse click and key press events to a virtual machine, VNC\n"
72      "server, or SPICE server.  See virt-click(1) manual page for complete\n"
73      "information.  This is just a summary.\n"
74      "\n"
75      "Commands:\n"
76      "  virt-click <cmd> where <cmd> is:\n"
77      "    click x y [b]                   Mouse click at (x, y), with button b"
78      );
79   g_option_context_add_main_entries (context, options, NULL);
80   g_option_context_add_group (context, vc_vnc_cmdline_get_option_group ());
81   g_option_context_add_group (context, vc_spice_cmdline_get_option_group ());
82   g_option_context_parse (context, &argc, &argv, &error);
83   if (error) {
84     short_usage (argv[0], error->message);
85     g_error_free (error);
86     exit (EXIT_FAILURE);
87   }
88   if (version) {
89     printf ("%s\n", PACKAGE_STRING);
90     exit (EXIT_SUCCESS);
91   }
92
93   /* Initialize structure. */
94   self = g_new0 (self_t, 1);
95   self->loop = g_main_loop_new (g_main_context_default(), FALSE);
96   self->ret = EXIT_FAILURE;
97
98   /* Parse the command in detail. */
99   if (!args || (nr_args = g_strv_length (args)) < 1) {
100     short_usage (argv[0], "missing command");
101     exit (EXIT_FAILURE);
102   }
103
104   if (vc_parse_command (self, args, nr_args) == -1) {
105     short_usage (argv[0], "could not parse the command");
106     exit (EXIT_FAILURE);
107   }
108
109   /* Create VNC/SPICE/... object. */
110   if (vc_vnc_is_selected ())
111     vc_vnc_setup (self);
112   else if (vc_spice_is_selected ()) {
113     vc_spice_setup (self);
114   }
115   else {
116     short_usage (argv[0], "no --vnc or --spice option");
117     exit (EXIT_FAILURE);
118   }
119
120   /* Main loop. */
121   g_main_loop_run (self->loop);
122
123   /* Shut down and exit. */
124   self->callbacks->shutdown (self);
125
126   g_free(self);
127
128   exit (self->ret);
129 }