/* virt-click * Copyright (C) 2011 Red Hat Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Parts are derived from 'gvnccapture': * * Vnc Image Capture * * Copyright (C) 2010 Daniel P. Berrange * * 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.0 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include "click.h" static void initialized (VncConnection *conn, gpointer opaque); static void disconnected (VncConnection *conn, gpointer opaque); static int click (struct self_t *self, int x, int y, int b); static void shutdown (self_t *self); static callbacks_t callbacks = { .click = click, .shutdown = shutdown, }; static gchar *vnc; static gchar *host; static int port; static GOptionEntry vnc_entries[] = { { "vnc", 0, 0, G_OPTION_ARG_STRING, &vnc, "Connect to VNC server directly", NULL }, { NULL } }; static GOptionGroup *vnc_group; GOptionGroup * vc_vnc_cmdline_get_option_group (void) { if (vnc_group == NULL) { vnc_group = g_option_group_new ("vnc", _("VNC Options:"), _("Show VNC Options"), NULL, NULL); g_option_group_add_entries (vnc_group, vnc_entries); } return vnc_group; } gboolean vc_vnc_is_selected (void) { return vnc != NULL; } void vc_vnc_setup (self_t *self) { gchar *display; gchar *port_str; self->callbacks = &callbacks; if (verbose) vnc_util_set_debug (TRUE); if (vnc[0] == ':') { host = g_strdup ("localhost"); display = vnc; } else { host = g_strdup (vnc); display = strchr (host, ':'); } if (display) { *display = 0; display++; port = 5900 + atoi (display); } else port = 5900; self->conn = vnc_connection_new (); g_signal_connect (self->conn, "vnc-initialized", G_CALLBACK(initialized), self); g_signal_connect (self->conn, "vnc-disconnected", G_CALLBACK(disconnected), self); g_signal_connect (self->conn, "vnc-auth-choose-type", G_CALLBACK(vc_vnc_auth_choose_type), self); g_signal_connect (self->conn, "vnc-auth-choose-subtype", G_CALLBACK(vc_vnc_auth_choose_type), self); g_signal_connect (self->conn, "vnc-auth-credential", G_CALLBACK(vc_vnc_auth_credential), self); port_str = g_strdup_printf ("%d", port); vnc_connection_open_host (self->conn, host, port_str); g_free (port_str); } static void initialized (VncConnection *conn, gpointer opaque) { self_t *self = opaque; gint32 encodings[] = { VNC_CONNECTION_ENCODING_DESKTOP_RESIZE, VNC_CONNECTION_ENCODING_ZRLE, VNC_CONNECTION_ENCODING_HEXTILE, VNC_CONNECTION_ENCODING_RRE, VNC_CONNECTION_ENCODING_COPY_RECT, VNC_CONNECTION_ENCODING_RAW }; gint32 *encodingsp; int n_encodings; if (verbose) fprintf (stderr, "Connected to %s:%d\n", host, port - 5900); /* Remember that we managed to connect. */ self->connected = TRUE; /* Send encodings. * NB: Although this step is useless, you *MUST* send encodings otherwise * qemu's internal VNC server refuses to parse any other events. */ encodingsp = encodings; n_encodings = G_N_ELEMENTS(encodings); if (!vnc_connection_set_encodings(conn, n_encodings, encodingsp)) { self->ret = EXIT_FAILURE; vnc_connection_shutdown (self->conn); return; } /* Issue the command. */ vc_issue_command (self); } static void disconnected (VncConnection *conn G_GNUC_UNUSED, gpointer opaque) { self_t *self = opaque; if (self->connected) { self->ret = EXIT_SUCCESS; if (verbose) fprintf (stderr, "Disconnected from %s:%d\n", host, port - 5900); } else { fprintf (stderr, "vnc: unable to connect to %s:%d\n", host, port - 5900); self->ret = EXIT_FAILURE; } g_main_quit(self->loop); } static void shutdown (self_t *self) { vnc_connection_shutdown (self->conn); g_object_unref (self->conn); g_free (host); } static int click (struct self_t *self, int x, int y, int b) { unsigned mask = b > 0 ? 1 << (b-1) : 0; if (!vnc_connection_pointer_event (self->conn, mask, x, y)) return -1; return 0; }