[vinagre] Add reverse-vnc plugin
- From: Jonh Wendell <jwendell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vinagre] Add reverse-vnc plugin
- Date: Tue, 24 Aug 2010 18:38:27 +0000 (UTC)
commit c95743ebb3b8f2f7fc5bbcd431f96d28648b4945
Author: Jonh Wendell <jwendell gnome org>
Date: Tue Aug 24 15:20:37 2010 -0300
Add reverse-vnc plugin
Moved this feature from vnc plugin into its own.
configure.ac | 1 +
plugins/Makefile.am | 6 +-
plugins/reverse-vnc/Makefile.am | 40 +++
plugins/reverse-vnc/if/getifaddrs.c | 217 +++++++++++++++
plugins/reverse-vnc/if/ifaddrs.h | 48 ++++
plugins/reverse-vnc/reverse-vnc.ui | 257 ++++++++++++++++++
.../reverse-vnc.vinagre-plugin.desktop.in | 10 +
.../vinagre-reverse-vnc-listener-dialog.c | 275 ++++++++++++++++++++
.../vinagre-reverse-vnc-listener-dialog.h | 31 +++
plugins/reverse-vnc/vinagre-reverse-vnc-listener.c | 268 +++++++++++++++++++
plugins/reverse-vnc/vinagre-reverse-vnc-listener.h | 62 +++++
plugins/reverse-vnc/vinagre-reverse-vnc-plugin.c | 239 +++++++++++++++++
plugins/reverse-vnc/vinagre-reverse-vnc-plugin.h | 64 +++++
13 files changed, 1515 insertions(+), 3 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 24ede4f..da27744 100644
--- a/configure.ac
+++ b/configure.ac
@@ -311,6 +311,7 @@ plugins/Makefile
plugins/vnc/Makefile
plugins/ssh/Makefile
plugins/rdp/Makefile
+plugins/reverse-vnc/Makefile
vinagre/Makefile
vinagre/view/Makefile
])
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 0018cee..0411bb4 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -1,10 +1,10 @@
DIST_SUBDIRS = \
vnc \
ssh \
- rdp
+ rdp \
+ reverse-vnc
-SUBDIRS = \
- vnc
+SUBDIRS = vnc reverse-vnc
if SSH
SUBDIRS += ssh
diff --git a/plugins/reverse-vnc/Makefile.am b/plugins/reverse-vnc/Makefile.am
new file mode 100644
index 0000000..d5c1e5f
--- /dev/null
+++ b/plugins/reverse-vnc/Makefile.am
@@ -0,0 +1,40 @@
+# reverse-vnc plugin
+plugindir = $(VINAGRE_PLUGINS_LIBS_DIR)
+
+INCLUDES = \
+ -DDATADIR=\"$(VINAGRE_PLUGINS_DATA_DIR)/reverse-vnc\" \
+ -I$(top_srcdir) \
+ $(VINAGRE_CFLAGS) \
+ $(WARN_CFLAGS) \
+ $(DISABLE_DEPRECATED_CFLAGS)
+
+plugin_LTLIBRARIES = libreversevnc.la
+
+libreversevnc_la_SOURCES = \
+ vinagre-reverse-vnc-plugin.h vinagre-reverse-vnc-plugin.c \
+ vinagre-reverse-vnc-listener.h vinagre-reverse-vnc-listener.c \
+ vinagre-reverse-vnc-listener-dialog.h vinagre-reverse-vnc-listener-dialog.c
+
+if SELF_IFADDRS
+libreversevnc_la_SOURCES += if/ifaddrs.h if/getifaddrs.c
+endif
+
+libreversevnc_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
+libreversevnc_la_LIBADD = $(VNC_LIBS)
+
+uidir = $(VINAGRE_PLUGINS_DATA_DIR)/reverse-vnc
+ui_DATA = reverse-vnc.ui
+
+plugin_in_files = reverse-vnc.vinagre-plugin.desktop.in
+
+reverse-vnc.vinagre-plugin: reverse-vnc.vinagre-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugin_DATA = $(plugin_in_files:.vinagre-plugin.desktop.in=.vinagre-plugin)
+
+EXTRA_DIST = $(ui_DATA) $(plugin_in_files)
+
+CLEANFILES = $(plugin_DATA)
+DISTCLEANFILES = $(plugin_DATA)
+
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/reverse-vnc/if/getifaddrs.c b/plugins/reverse-vnc/if/getifaddrs.c
new file mode 100644
index 0000000..e6d4d9b
--- /dev/null
+++ b/plugins/reverse-vnc/if/getifaddrs.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2006 WIDE Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+#include "ifaddrs.h"
+
+static int
+get_lifreq(int fd, struct lifreq **ifr_ret)
+{
+ struct lifnum lifn;
+ struct lifconf lifc;
+ struct lifreq *lifrp;
+
+ lifn.lifn_family = AF_UNSPEC;
+ lifn.lifn_flags = 0;
+ if (ioctl(fd, SIOCGLIFNUM, &lifn) == -1)
+ lifn.lifn_count = 16;
+ else
+ lifn.lifn_count += 16;
+
+ for (;;) {
+ lifc.lifc_len = lifn.lifn_count * sizeof (*lifrp);
+ lifrp = malloc(lifc.lifc_len);
+ if (lifrp == NULL)
+ return (-1);
+
+ lifc.lifc_family = AF_UNSPEC;
+ lifc.lifc_flags = 0;
+ lifc.lifc_buf = (char *)lifrp;
+ if (ioctl(fd, SIOCGLIFCONF, &lifc) == -1) {
+ free(lifrp);
+ if (errno == EINVAL) {
+ lifn.lifn_count <<= 1;
+ continue;
+ }
+ (void) close(fd);
+ return (-1);
+ }
+ if (lifc.lifc_len < (lifn.lifn_count - 1) * sizeof (*lifrp))
+ break;
+ free(lifrp);
+ lifn.lifn_count <<= 1;
+ }
+
+ *ifr_ret = lifrp;
+
+ return (lifc.lifc_len / sizeof (*lifrp));
+}
+
+static size_t
+nbytes(const struct lifreq *lifrp, int nlif, size_t socklen)
+{
+ size_t len = 0;
+ size_t slen;
+
+ while (nlif > 0) {
+ slen = strlen(lifrp->lifr_name) + 1;
+ len += sizeof (struct ifaddrs) + ((slen + 3) & ~3);
+ len += 3 * socklen;
+ lifrp++;
+ nlif--;
+ }
+ return (len);
+}
+
+static struct sockaddr *
+addrcpy(struct sockaddr_storage *addr, char **bufp)
+{
+ char *buf = *bufp;
+ size_t len;
+
+ len = addr->ss_family == AF_INET ? sizeof (struct sockaddr_in) :
+ sizeof (struct sockaddr_in6);
+ (void) memcpy(buf, addr, len);
+ *bufp = buf + len;
+ return ((struct sockaddr *)buf);
+}
+
+static int
+populate(struct ifaddrs *ifa, int fd, struct lifreq *lifrp, int nlif, int af,
+ char **bufp)
+{
+ char *buf = *bufp;
+ size_t slen;
+
+ while (nlif > 0) {
+ ifa->ifa_next = (nlif > 1) ? ifa + 1 : NULL;
+ (void) strcpy(ifa->ifa_name = buf, lifrp->lifr_name);
+ slen = strlen(lifrp->lifr_name) + 1;
+ buf += (slen + 3) & ~3;
+ if (ioctl(fd, SIOCGLIFFLAGS, lifrp) == -1)
+ ifa->ifa_flags = 0;
+ else
+ ifa->ifa_flags = lifrp->lifr_flags;
+ if (ioctl(fd, SIOCGLIFADDR, lifrp) == -1)
+ ifa->ifa_addr = NULL;
+ else
+ ifa->ifa_addr = addrcpy(&lifrp->lifr_addr, &buf);
+ if (ioctl(fd, SIOCGLIFNETMASK, lifrp) == -1)
+ ifa->ifa_netmask = NULL;
+ else
+ ifa->ifa_netmask = addrcpy(&lifrp->lifr_addr, &buf);
+ if (ifa->ifa_flags & IFF_POINTOPOINT) {
+ if (ioctl(fd, SIOCGLIFDSTADDR, lifrp) == -1)
+ ifa->ifa_dstaddr = NULL;
+ else
+ ifa->ifa_dstaddr =
+ addrcpy(&lifrp->lifr_dstaddr, &buf);
+ } else if (ifa->ifa_flags & IFF_BROADCAST) {
+ if (ioctl(fd, SIOCGLIFBRDADDR, lifrp) == -1)
+ ifa->ifa_broadaddr = NULL;
+ else
+ ifa->ifa_broadaddr =
+ addrcpy(&lifrp->lifr_broadaddr, &buf);
+ } else {
+ ifa->ifa_dstaddr = NULL;
+ }
+
+ ifa++;
+ nlif--;
+ lifrp++;
+ }
+ *bufp = buf;
+ return (0);
+}
+
+int
+getifaddrs(struct ifaddrs **ifap)
+{
+ int fd4, fd6;
+ int nif4, nif6 = 0;
+ struct lifreq *ifr4 = NULL;
+ struct lifreq *ifr6 = NULL;
+ struct ifaddrs *ifa = NULL;
+ char *buf;
+
+ if ((fd4 = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ return (-1);
+ if ((fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) == -1 &&
+ errno != EAFNOSUPPORT) {
+ (void) close(fd4);
+ return (-1);
+ }
+
+ if ((nif4 = get_lifreq(fd4, &ifr4)) == -1 ||
+ (fd6 != -1 && (nif6 = get_lifreq(fd6, &ifr6)) == -1))
+ goto failure;
+
+ if (nif4 == 0 && nif6 == 0) {
+ *ifap = NULL;
+ return (0);
+ }
+
+ ifa = malloc(nbytes(ifr4, nif4, sizeof (struct sockaddr_in)) +
+ nbytes(ifr6, nif6, sizeof (struct sockaddr_in6)));
+ if (ifa == NULL)
+ goto failure;
+
+ buf = (char *)(ifa + nif4 + nif6);
+
+ if (populate(ifa, fd4, ifr4, nif4, AF_INET, &buf) == -1)
+ goto failure;
+ if (nif4 > 0 && nif6 > 0)
+ ifa[nif4 - 1].ifa_next = ifa + nif4;
+ if (populate(ifa + nif4, fd6, ifr6, nif6, AF_INET6, &buf) == -1)
+ goto failure;
+
+ *ifap = ifa;
+ return (0);
+
+failure:
+ free(ifa);
+ (void) close(fd4);
+ if (fd6 != -1)
+ (void) close(fd6);
+ free(ifr4);
+ free(ifr6);
+ return (-1);
+}
+
+void
+freeifaddrs(struct ifaddrs *ifa)
+{
+ free(ifa);
+}
diff --git a/plugins/reverse-vnc/if/ifaddrs.h b/plugins/reverse-vnc/if/ifaddrs.h
new file mode 100644
index 0000000..5686143
--- /dev/null
+++ b/plugins/reverse-vnc/if/ifaddrs.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006 WIDE Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __IFADDRS_H
+#define __IFADDRS_H
+
+#include <sys/types.h>
+
+#undef ifa_broadaddr
+#undef ifa_dstaddr
+struct ifaddrs {
+ struct ifaddrs *ifa_next; /* Pointer to next struct */
+ char *ifa_name; /* Interface name */
+ uint64_t ifa_flags; /* Interface flags */
+ struct sockaddr *ifa_addr; /* Interface address */
+ struct sockaddr *ifa_netmask; /* Interface netmask */
+ struct sockaddr *ifa_dstaddr; /* P2P interface destination */
+};
+#define ifa_broadaddr ifa_dstaddr
+
+extern int getifaddrs(struct ifaddrs **);
+extern void freeifaddrs(struct ifaddrs *);
+#endif
diff --git a/plugins/reverse-vnc/reverse-vnc.ui b/plugins/reverse-vnc/reverse-vnc.ui
new file mode 100644
index 0000000..e2e459e
--- /dev/null
+++ b/plugins/reverse-vnc/reverse-vnc.ui
@@ -0,0 +1,257 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkDialog" id="listener_dialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Reverse Connections</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window_position">center-on-parent</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="xpad">6</property>
+ <property name="stock">gtk-dialog-info</property>
+ <property name="icon-size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">By activating reverse connections you can access machines that are behind a firewall. The remote side is supposed to initiate the connection with you. For further information, checkout the help.</property>
+ <property name="wrap">True</property>
+ <attributes>
+ <attribute name="style" value="italic"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkCheckButton" id="enable_reverse_check">
+ <property name="label" translatable="yes">_Enable Reverse Connections</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label"> </property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="always_enabled_check">
+ <property name="label" translatable="yes" comments="Translators: this is the reverse connection mode. "Always enabled" means it will be enabled by default in the program startup. You can see this string in the dialog Machine->Reverse connections.">_Always Enabled</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label"> </property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkExpander" id="connectivity_exp">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkTextView" id="ip_textview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="pixels_above_lines">3</property>
+ <property name="pixels_below_lines">3</property>
+ <property name="editable">False</property>
+ <property name="buffer">ip_textbuffer</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">This machine is reachable through the following IP address(es):</property>
+ <attributes>
+ <attribute name="style" value="italic"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="port_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label">label</property>
+ <attributes>
+ <attribute name="style" value="italic"/>
+ <attribute name="scale" value="1,000000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Connectivity</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">6</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="label">gtk-help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button2">
+ <property name="label">gtk-close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">button1</action-widget>
+ <action-widget response="0">button2</action-widget>
+ </action-widgets>
+ </object>
+ <object class="GtkTextBuffer" id="ip_textbuffer"/>
+</interface>
diff --git a/plugins/reverse-vnc/reverse-vnc.vinagre-plugin.desktop.in b/plugins/reverse-vnc/reverse-vnc.vinagre-plugin.desktop.in
new file mode 100644
index 0000000..52851ff
--- /dev/null
+++ b/plugins/reverse-vnc/reverse-vnc.vinagre-plugin.desktop.in
@@ -0,0 +1,10 @@
+[Vinagre Plugin]
+Module=reversevnc
+IAge=1
+_Name=Reverse VNC
+_Description=Allows reverse VNC connections
+Authors=Jonh Wendell
+Copyright=Copyright © 2009-2010 Jonh Wendell
+Website=http://www.bani.com.br
+Version=1.0
+Depends=vnc
diff --git a/plugins/reverse-vnc/vinagre-reverse-vnc-listener-dialog.c b/plugins/reverse-vnc/vinagre-reverse-vnc-listener-dialog.c
new file mode 100644
index 0000000..e4d8a12
--- /dev/null
+++ b/plugins/reverse-vnc/vinagre-reverse-vnc-listener-dialog.c
@@ -0,0 +1,275 @@
+/*
+ * vinagre-reverse-vnc-listener-dialog.c
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2009 Jonh Wendell <wendell bani com br>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#else
+#include "if/ifaddrs.h"
+#endif
+
+#ifdef RFC2553
+#define ADDR_FAMILY_MEMBER ss_family
+#else
+#define ADDR_FAMILY_MEMBER sa_family
+#endif
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include <vinagre/vinagre-utils.h>
+#include <vinagre/vinagre-prefs.h>
+#include "vinagre-reverse-vnc-listener-dialog.h"
+#include "vinagre-reverse-vnc-listener.h"
+
+typedef struct
+{
+ GtkBuilder *xml;
+ GtkWidget *dialog;
+ GtkWidget *enable_reverse_check;
+ GtkWidget *always_enabled_check;
+ GtkWidget *port_label;
+ GtkWidget *connectivity_exp;
+ GtkTextBuffer *ip_buffer;
+ VinagreReverseVncListener *listener;
+} VncListenDialog;
+
+static void
+setup_ip_buffer (VncListenDialog *dialog)
+{
+ char buf[INET6_ADDRSTRLEN], *dup;
+ struct ifaddrs *myaddrs, *ifa;
+ void *sin;
+ GArray *ipv4, *ipv6;
+ GString *str;
+ int i;
+
+ ipv4 = g_array_new (FALSE, TRUE, sizeof (char *));
+ ipv6 = g_array_new (FALSE, TRUE, sizeof (char *));
+ str = g_string_new (NULL);
+
+ getifaddrs (&myaddrs);
+ for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr == NULL || ifa->ifa_name == NULL || (ifa->ifa_flags & IFF_UP) == 0 || strncmp (ifa->ifa_name, "lo", 2) == 0)
+ continue;
+
+ switch (ifa->ifa_addr->ADDR_FAMILY_MEMBER)
+ {
+ case AF_INET:
+ sin = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
+ inet_ntop (AF_INET, sin, buf, INET6_ADDRSTRLEN);
+ dup = g_strdup (buf);
+ g_array_append_val (ipv4, dup);
+ break;
+
+ case AF_INET6:
+ sin = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
+ inet_ntop (AF_INET6, sin, buf, INET6_ADDRSTRLEN);
+ dup = g_strdup (buf);
+ g_array_append_val (ipv6, dup);
+ break;
+ default: continue;
+ }
+ }
+
+ if (ipv4->len > 0)
+ {
+ if (ipv6->len > 0)
+ g_string_append (str, _("IPv4:"));
+
+ for (i = 0; i < ipv4->len; i++)
+ {
+ dup = g_array_index (ipv4, char *, i);
+ g_string_append_printf (str, "\n%s", dup);
+ g_free (dup);
+ }
+ }
+ if (ipv6->len > 0)
+ {
+ if (ipv4->len > 0)
+ g_string_append (str, _("\n\nIPv6:"));
+
+ for (i = 0; i < ipv6->len; i++)
+ {
+ dup = g_array_index (ipv6, char *, i);
+ g_string_append_printf (str, "\n%s", g_array_index (ipv6, char *, i));
+ g_free (dup);
+ }
+ }
+
+ gtk_text_buffer_set_text (dialog->ip_buffer, str->str, -1);
+
+ freeifaddrs (myaddrs);
+ g_array_free (ipv4, TRUE);
+ g_array_free (ipv6, TRUE);
+ g_string_free (str, TRUE);
+}
+
+static void
+dialog_destroy (GtkObject *obj,
+ VncListenDialog *dialog)
+{
+ g_object_unref (dialog->xml);
+ g_object_unref (dialog->listener);
+ g_slice_free (VncListenDialog, dialog);
+}
+
+static void
+dialog_response_handler (GtkDialog *widget,
+ gint res_id,
+ VncListenDialog *dialog)
+{
+ switch (res_id)
+ {
+ case GTK_RESPONSE_HELP:
+ // TODO: display the help
+ break;
+
+ default:
+ gtk_widget_destroy (dialog->dialog);
+ break;
+ }
+}
+
+static void
+update_ui_sensitivity (VncListenDialog *dialog)
+{
+ gboolean listening;
+ gchar *str;
+
+ listening = vinagre_reverse_vnc_listener_is_listening (dialog->listener);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->enable_reverse_check),
+ listening);
+ gtk_widget_set_sensitive (dialog->always_enabled_check, listening);
+ gtk_widget_set_sensitive (dialog->connectivity_exp, listening);
+
+ if (listening)
+ {
+ str = g_strdup_printf (_("On the port %d"), vinagre_reverse_vnc_listener_get_port (dialog->listener));
+ gtk_label_set_label (GTK_LABEL (dialog->port_label), str);
+ g_free (str);
+ }
+ else
+ {
+ gtk_expander_set_expanded (GTK_EXPANDER (dialog->connectivity_exp), FALSE);
+ }
+}
+
+static void
+enable_reverse_toggled_cb (GtkToggleButton *button, VncListenDialog *dialog)
+{
+ if (gtk_toggle_button_get_active (button))
+ vinagre_reverse_vnc_listener_start (dialog->listener);
+ else
+ {
+ vinagre_reverse_vnc_listener_stop (dialog->listener);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->always_enabled_check),
+ FALSE);
+ }
+
+ update_ui_sensitivity (dialog);
+}
+
+static void
+always_enabled_toggled_cb (GtkToggleButton *button, VncListenDialog *dialog)
+{
+ g_object_set (vinagre_prefs_get_default (),
+ "always-enable-listening", gtk_toggle_button_get_active (button),
+ NULL);
+}
+
+void
+vinagre_reverse_vnc_listener_dialog_show (GtkWindow *parent)
+{
+ VncListenDialog *dialog;
+ GtkBuilder *xml;
+ gboolean always;
+ gchar *filename;
+
+ filename = g_build_filename (DATADIR, "reverse-vnc.ui", NULL);
+
+ xml = vinagre_utils_get_builder (filename);
+ g_free (filename);
+ if (!xml)
+ return;
+
+ dialog = g_slice_new (VncListenDialog);
+ dialog->xml = xml;
+
+ dialog->listener = vinagre_reverse_vnc_listener_get_default ();
+
+ dialog->dialog = GTK_WIDGET (gtk_builder_get_object (xml, "listener_dialog"));
+ g_assert (dialog->dialog != NULL);
+
+ dialog->ip_buffer = GTK_TEXT_BUFFER (gtk_builder_get_object (xml, "ip_textbuffer"));
+ g_assert (dialog->ip_buffer != NULL);
+ setup_ip_buffer (dialog);
+
+ dialog->enable_reverse_check = GTK_WIDGET (gtk_builder_get_object (xml, "enable_reverse_check"));
+ g_assert (dialog->enable_reverse_check != NULL);
+ g_signal_connect (dialog->enable_reverse_check,
+ "toggled",
+ G_CALLBACK (enable_reverse_toggled_cb),
+ dialog);
+
+ dialog->always_enabled_check = GTK_WIDGET (gtk_builder_get_object (xml, "always_enabled_check"));
+ g_assert (dialog->always_enabled_check != NULL);
+ g_object_get (vinagre_prefs_get_default (),
+ "always-enable-listening", &always,
+ NULL);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->always_enabled_check),
+ always);
+ g_signal_connect (dialog->always_enabled_check,
+ "toggled",
+ G_CALLBACK (always_enabled_toggled_cb),
+ dialog);
+
+ dialog->connectivity_exp = GTK_WIDGET (gtk_builder_get_object (xml, "connectivity_exp"));
+ g_assert (dialog->connectivity_exp != NULL);
+
+ dialog->port_label = GTK_WIDGET (gtk_builder_get_object (xml, "port_label"));
+ g_assert (dialog->port_label != NULL);
+
+ update_ui_sensitivity (dialog);
+
+ g_signal_connect (dialog->dialog,
+ "destroy",
+ G_CALLBACK (dialog_destroy),
+ dialog);
+
+ g_signal_connect (dialog->dialog,
+ "response",
+ G_CALLBACK (dialog_response_handler),
+ dialog);
+
+ if (parent)
+ gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog), parent);
+
+ gtk_widget_show_all (dialog->dialog);
+}
+
+/* vim: set ts=8: */
diff --git a/plugins/reverse-vnc/vinagre-reverse-vnc-listener-dialog.h b/plugins/reverse-vnc/vinagre-reverse-vnc-listener-dialog.h
new file mode 100644
index 0000000..b779da1
--- /dev/null
+++ b/plugins/reverse-vnc/vinagre-reverse-vnc-listener-dialog.h
@@ -0,0 +1,31 @@
+/*
+ * vinagre-reverse-vnc-listener-dialog.h
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2009 Jonh Wendell <wendell bani com br>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __VINAGRE_REVERSE_VNC_LISTENER_DIALOG_H__
+#define __VINAGRE_REVERSE_VNC_LISTENER_DIALOG_H__
+
+G_BEGIN_DECLS
+
+void vinagre_reverse_vnc_listener_dialog_show (GtkWindow *parent);
+
+G_END_DECLS
+
+#endif /* __VINAGRE_REVERSE_VNC_LISTENER_DIALOG_H__ */
+/* vim: set ts=8: */
diff --git a/plugins/reverse-vnc/vinagre-reverse-vnc-listener.c b/plugins/reverse-vnc/vinagre-reverse-vnc-listener.c
new file mode 100644
index 0000000..ba3997f
--- /dev/null
+++ b/plugins/reverse-vnc/vinagre-reverse-vnc-listener.c
@@ -0,0 +1,268 @@
+/*
+ * vinagre-reverse-vnc-listener.c
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2009-2010 - Jonh Wendell <wendell bani com br>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <glib/gi18n.h>
+#include <vinagre/vinagre-commands.h>
+#include "vinagre-reverse-vnc-listener.h"
+#include "../vnc/vinagre-vnc-connection.h"
+
+struct _VinagreReverseVncListenerPrivate
+{
+ int server_sock;
+ GIOChannel *io;
+ gboolean listening;
+ guint io_uid;
+ gint port;
+};
+
+enum
+{
+ PROP_0,
+ PROP_LISTENING,
+ PROP_PORT
+};
+
+static VinagreReverseVncListener *listener_singleton = NULL;
+
+#define VINAGRE_REVERSE_VNC_LISTENER_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VINAGRE_TYPE_REVERSE_VNC_LISTENER, VinagreReverseVncListenerPrivate))
+G_DEFINE_TYPE (VinagreReverseVncListener, vinagre_reverse_vnc_listener, G_TYPE_OBJECT);
+
+static void
+vinagre_reverse_vnc_listener_init (VinagreReverseVncListener *listener)
+{
+ listener->priv = G_TYPE_INSTANCE_GET_PRIVATE (listener, VINAGRE_TYPE_REVERSE_VNC_LISTENER, VinagreReverseVncListenerPrivate);
+
+ listener->priv->io = NULL;
+ listener->priv->server_sock = 0;
+ listener->priv->listening = FALSE;
+ listener->priv->io_uid = 0;
+ listener->priv->port = 0;
+}
+
+static void
+vinagre_reverse_vnc_listener_dispose (GObject *object)
+{
+ VinagreReverseVncListener *listener = VINAGRE_REVERSE_VNC_LISTENER (object);
+
+ vinagre_reverse_vnc_listener_stop (listener);
+
+ G_OBJECT_CLASS (vinagre_reverse_vnc_listener_parent_class)->dispose (object);
+}
+
+static void
+vinagre_reverse_vnc_listener_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ VinagreReverseVncListener *listener;
+
+ g_return_if_fail (VINAGRE_IS_REVERSE_VNC_LISTENER (object));
+
+ listener = VINAGRE_REVERSE_VNC_LISTENER (object);
+
+ switch (prop_id)
+ {
+ case PROP_LISTENING:
+ g_value_set_boolean (value, listener->priv->listening);
+ break;
+
+ case PROP_PORT:
+ g_value_set_int (value, vinagre_reverse_vnc_listener_get_port (listener));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+vinagre_reverse_vnc_listener_class_init (VinagreReverseVncListenerClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (VinagreReverseVncListenerPrivate));
+
+ object_class->dispose = vinagre_reverse_vnc_listener_dispose;
+ object_class->get_property = vinagre_reverse_vnc_listener_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_LISTENING,
+ g_param_spec_boolean ("listening",
+ "Listening",
+ "If we are listening for incoming (reverse) VNC connections",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_BLURB));
+ g_object_class_install_property (object_class,
+ PROP_PORT,
+ g_param_spec_int ("port",
+ "Port",
+ "TCP port in which we are listening for reverse connections",
+ 5500,
+ 5600,
+ 5500,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_BLURB));
+
+}
+
+VinagreReverseVncListener *
+vinagre_reverse_vnc_listener_get_default (void)
+{
+ if (G_UNLIKELY (!listener_singleton))
+ {
+ listener_singleton = VINAGRE_REVERSE_VNC_LISTENER (g_object_new (VINAGRE_TYPE_REVERSE_VNC_LISTENER, NULL));
+ g_object_add_weak_pointer (G_OBJECT (listener_singleton), (gpointer *)&listener_singleton);
+ return listener_singleton;
+ }
+
+ return g_object_ref (listener_singleton);
+}
+
+static gboolean
+incoming (GIOChannel *source, GIOCondition condition, VinagreReverseVncListener *listener)
+{
+ VinagreConnection *conn;
+ GtkWindow *window;
+ int cl_sock;
+ struct sockaddr_in6 client_addr;
+ char client_name[INET6_ADDRSTRLEN];
+ socklen_t client_addr_len = sizeof (client_addr);
+
+ cl_sock = accept (listener->priv->server_sock, (struct sockaddr *) &client_addr, &client_addr_len);
+ if (cl_sock < 0)
+ g_error ("accept() failed");
+
+ window = gtk_application_get_window (GTK_APPLICATION (g_application_get_instance ()));
+ if (!window)
+ {
+ g_warning (_("Incoming VNC connection arrived but there is no active window"));
+ return TRUE;
+ }
+
+ conn = vinagre_vnc_connection_new ();
+ vinagre_vnc_connection_set_fd (VINAGRE_VNC_CONNECTION (conn), cl_sock);
+
+ if (inet_ntop (AF_INET6, &client_addr.sin6_addr.s6_addr, client_name, sizeof (client_name)) != NULL)
+ vinagre_connection_set_host (conn, client_name);
+ vinagre_connection_set_port (conn, ntohs (client_addr.sin6_port));
+
+ vinagre_cmd_direct_connect (conn, VINAGRE_WINDOW (window));
+
+ return TRUE;
+}
+
+void
+vinagre_reverse_vnc_listener_start (VinagreReverseVncListener *listener)
+{
+ struct sockaddr_in6 server_addr;
+ int port;
+
+ g_return_if_fail (VINAGRE_IS_REVERSE_VNC_LISTENER (listener));
+
+ if (listener->priv->listening)
+ return;
+
+ listener->priv->server_sock = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+ if (listener->priv->server_sock < 0)
+ g_error ("socket() failed");
+
+ memset (&server_addr, 0, sizeof (server_addr));
+ server_addr.sin6_family = AF_INET6;
+ server_addr.sin6_addr = in6addr_any;
+
+ for (port=5500; port<=5600; port++)
+ {
+ server_addr.sin6_port = htons (port);
+
+ if (bind (listener->priv->server_sock, (struct sockaddr *) &server_addr, sizeof (server_addr)) == 0)
+ break;
+ }
+ if (port>5600)
+ g_error ("bind() failed");
+
+ if (listen (listener->priv->server_sock, 5) < 0)
+ g_error ("listen() failed");
+
+ listener->priv->io = g_io_channel_unix_new (listener->priv->server_sock);
+ listener->priv->io_uid = g_io_add_watch (listener->priv->io, G_IO_IN, (GIOFunc)incoming, listener);
+
+ listener->priv->port = port;
+ listener->priv->listening = TRUE;
+ g_object_notify (G_OBJECT (listener), "listening");
+}
+
+void
+vinagre_reverse_vnc_listener_stop (VinagreReverseVncListener *listener)
+{
+ g_return_if_fail (VINAGRE_IS_REVERSE_VNC_LISTENER (listener));
+
+ if (!listener->priv->listening)
+ return;
+
+ if (listener->priv->io)
+ {
+ g_source_remove (listener->priv->io_uid);
+ g_io_channel_unref (listener->priv->io);
+ listener->priv->io = NULL;
+ }
+
+ if (listener->priv->server_sock > 0)
+ {
+ close (listener->priv->server_sock);
+ listener->priv->server_sock = 0;
+ }
+
+ listener->priv->listening = FALSE;
+ g_object_notify (G_OBJECT (listener), "listening");
+}
+
+gboolean
+vinagre_reverse_vnc_listener_is_listening (VinagreReverseVncListener *listener)
+{
+ g_return_val_if_fail (VINAGRE_IS_REVERSE_VNC_LISTENER (listener), FALSE);
+
+ return listener->priv->listening;
+}
+
+gint
+vinagre_reverse_vnc_listener_get_port (VinagreReverseVncListener *listener)
+{
+ g_return_val_if_fail (VINAGRE_IS_REVERSE_VNC_LISTENER (listener), 0);
+
+ return listener->priv->listening ? listener->priv->port : 0;
+}
+
+/* vim: set ts=8: */
diff --git a/plugins/reverse-vnc/vinagre-reverse-vnc-listener.h b/plugins/reverse-vnc/vinagre-reverse-vnc-listener.h
new file mode 100644
index 0000000..e84b012
--- /dev/null
+++ b/plugins/reverse-vnc/vinagre-reverse-vnc-listener.h
@@ -0,0 +1,62 @@
+/*
+ * vinagre-reverse-vnc-listener.h
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2009 - Jonh Wendell <wendell bani com br>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __VINAGRE_REVERSE_VNC_LISTENER_H__
+#define __VINAGRE_REVERSE_VNC_LISTENER_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define VINAGRE_TYPE_REVERSE_VNC_LISTENER (vinagre_reverse_vnc_listener_get_type ())
+#define VINAGRE_REVERSE_VNC_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VINAGRE_TYPE_REVERSE_VNC_LISTENER, VinagreReverseVncListener))
+#define VINAGRE_REVERSE_VNC_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VINAGRE_TYPE_REVERSE_VNC_LISTENER, VinagreReverseVncListenerClass))
+#define VINAGRE_IS_REVERSE_VNC_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VINAGRE_TYPE_REVERSE_VNC_LISTENER))
+#define VINAGRE_IS_REVERSE_VNC_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VINAGRE_TYPE_REVERSE_VNC_LISTENER))
+#define VINAGRE_REVERSE_VNC_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VINAGRE_TYPE_REVERSE_VNC_LISTENER, VinagreReverseVncListenerClass))
+
+typedef struct _VinagreReverseVncListenerClass VinagreReverseVncListenerClass;
+typedef struct _VinagreReverseVncListener VinagreReverseVncListener;
+typedef struct _VinagreReverseVncListenerPrivate VinagreReverseVncListenerPrivate;
+
+struct _VinagreReverseVncListenerClass
+{
+ GObjectClass parent_class;
+};
+
+struct _VinagreReverseVncListener
+{
+ GObject parent_instance;
+ VinagreReverseVncListenerPrivate *priv;
+};
+
+
+GType vinagre_reverse_vnc_listener_get_type (void) G_GNUC_CONST;
+
+VinagreReverseVncListener* vinagre_reverse_vnc_listener_get_default (void);
+void vinagre_reverse_vnc_listener_start (VinagreReverseVncListener *listener);
+void vinagre_reverse_vnc_listener_stop (VinagreReverseVncListener *listener);
+gboolean vinagre_reverse_vnc_listener_is_listening (VinagreReverseVncListener *listener);
+gint vinagre_reverse_vnc_listener_get_port (VinagreReverseVncListener *listener);
+
+G_END_DECLS
+
+#endif /* __VINAGRE_REVERSE_VNC_LISTENER_H__ */
+/* vim: set ts=8: */
diff --git a/plugins/reverse-vnc/vinagre-reverse-vnc-plugin.c b/plugins/reverse-vnc/vinagre-reverse-vnc-plugin.c
new file mode 100644
index 0000000..4093236
--- /dev/null
+++ b/plugins/reverse-vnc/vinagre-reverse-vnc-plugin.c
@@ -0,0 +1,239 @@
+/*
+ * vinagre-reverse-vnc-plugin.c
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2009-2010 Jonh Wendell <wendell bani com br>
+ *
+ * vinagre-reverse-vnc-plugin.c 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.
+ *
+ * vinagre-reverse-vnc-plugin.c 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+#include <gmodule.h>
+
+#include <vinagre/vinagre-prefs.h>
+
+#include "vinagre-reverse-vnc-plugin.h"
+#include "vinagre-reverse-vnc-listener-dialog.h"
+#include "vinagre-reverse-vnc-listener.h"
+
+#define WINDOW_DATA_KEY "VinagreVNCPluginWindowData"
+
+static void vnc_activatable_iface_init (PeasActivatableInterface *iface);
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (VinagreReverseVncPlugin,
+ vinagre_reverse_vnc_plugin,
+ PEAS_TYPE_EXTENSION_BASE,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_TYPE_ACTIVATABLE,
+ vnc_activatable_iface_init))
+
+struct _VinagreReverseVncPluginPrivate
+{
+ VinagreWindow *window;
+ GtkActionGroup *ui_action_group;
+ guint ui_id;
+ VinagreReverseVncListener *listener;
+};
+
+enum
+{
+ PROP_0,
+ PROP_OBJECT
+};
+
+static void
+listening_cb (GtkAction *action, VinagreReverseVncPlugin *plugin)
+{
+ vinagre_reverse_vnc_listener_dialog_show (GTK_WINDOW (plugin->priv->window));
+}
+
+static GtkActionEntry action_entries[] =
+{
+ { "VNCListener",
+ NULL,
+ /* Translators: "Reverse" here is an adjective, not a verb. */
+ N_("_Reverse Connections..."),
+ NULL,
+ N_("Configure incoming VNC connections"),
+ G_CALLBACK (listening_cb)
+ }
+};
+
+static void
+impl_activate (PeasActivatable *activatable)
+{
+ VinagreReverseVncPluginPrivate *priv;
+ GtkUIManager *manager;
+ gboolean always;
+
+ priv = VINAGRE_REVERSE_VNC_PLUGIN (activatable)->priv;
+
+ manager = vinagre_window_get_ui_manager (priv->window);
+
+ priv->ui_action_group = gtk_action_group_new ("VinagreReverseVNCPluginActions");
+ gtk_action_group_set_translation_domain (priv->ui_action_group, GETTEXT_PACKAGE);
+ gtk_action_group_add_actions (priv->ui_action_group,
+ action_entries,
+ G_N_ELEMENTS (action_entries),
+ activatable);
+ gtk_ui_manager_insert_action_group (manager,
+ priv->ui_action_group,
+ -1);
+
+ priv->ui_id = gtk_ui_manager_new_merge_id (manager);
+ gtk_ui_manager_add_ui (manager,
+ priv->ui_id,
+ "/MenuBar/MachineMenu/MachineOps_1",
+ "VNCListener",
+ "VNCListener",
+ GTK_UI_MANAGER_AUTO,
+ TRUE);
+
+ g_object_get (vinagre_prefs_get_default (),
+ "always-enable-listening", &always,
+ NULL);
+ if (always)
+ vinagre_reverse_vnc_listener_start (priv->listener);
+}
+
+static void
+impl_deactivate (PeasActivatable *activatable)
+{
+ VinagreReverseVncPluginPrivate *priv;
+ GtkUIManager *manager;
+
+ priv = VINAGRE_REVERSE_VNC_PLUGIN (activatable)->priv;
+
+ manager = vinagre_window_get_ui_manager (priv->window);
+
+ gtk_ui_manager_remove_ui (manager, priv->ui_id);
+ gtk_ui_manager_remove_action_group (manager, priv->ui_action_group);
+}
+
+static void
+vinagre_reverse_vnc_plugin_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ VinagreReverseVncPlugin *plugin = VINAGRE_REVERSE_VNC_PLUGIN (object);
+
+ switch (prop_id)
+ {
+ case PROP_OBJECT:
+ plugin->priv->window = VINAGRE_WINDOW (g_value_dup_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+vinagre_reverse_vnc_plugin_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ VinagreReverseVncPlugin *plugin = VINAGRE_REVERSE_VNC_PLUGIN (object);
+
+ switch (prop_id)
+ {
+ case PROP_OBJECT:
+ g_value_set_object (value, plugin->priv->window);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+vinagre_reverse_vnc_plugin_dispose (GObject *object)
+{
+ VinagreReverseVncPluginPrivate *priv = VINAGRE_REVERSE_VNC_PLUGIN (object)->priv;
+
+ if (priv->ui_action_group)
+ {
+ g_object_unref (priv->ui_action_group);
+ priv->ui_action_group = NULL;
+ }
+
+ if (priv->window != NULL)
+ {
+ g_object_unref (priv->window);
+ priv->window = NULL;
+ }
+
+ if (priv->listener)
+ {
+ g_object_unref (priv->listener);
+ priv->listener = NULL;
+ }
+
+ G_OBJECT_CLASS (vinagre_reverse_vnc_plugin_parent_class)->dispose (object);
+}
+
+static void
+vinagre_reverse_vnc_plugin_class_init (VinagreReverseVncPluginClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = vinagre_reverse_vnc_plugin_dispose;
+ object_class->set_property = vinagre_reverse_vnc_plugin_set_property;
+ object_class->get_property = vinagre_reverse_vnc_plugin_get_property;
+
+ g_object_class_override_property (object_class, PROP_OBJECT, "object");
+
+ g_type_class_add_private (klass, sizeof (VinagreReverseVncPluginPrivate));
+
+}
+
+static void
+vinagre_reverse_vnc_plugin_class_finalize (VinagreReverseVncPluginClass *klass)
+{
+}
+
+static void
+vinagre_reverse_vnc_plugin_init (VinagreReverseVncPlugin *plugin)
+{
+ plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (plugin,
+ VINAGRE_TYPE_REVERSE_VNC_PLUGIN,
+ VinagreReverseVncPluginPrivate);
+
+ plugin->priv->listener = vinagre_reverse_vnc_listener_get_default ();
+}
+
+static void
+vnc_activatable_iface_init (PeasActivatableInterface *iface)
+{
+ iface->activate = impl_activate;
+ iface->deactivate = impl_deactivate;
+}
+
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+ vinagre_reverse_vnc_plugin_register_type (G_TYPE_MODULE (module));
+ peas_object_module_register_extension_type (module,
+ PEAS_TYPE_ACTIVATABLE,
+ VINAGRE_TYPE_REVERSE_VNC_PLUGIN);
+}
+
+/* vim: set ts=8: */
diff --git a/plugins/reverse-vnc/vinagre-reverse-vnc-plugin.h b/plugins/reverse-vnc/vinagre-reverse-vnc-plugin.h
new file mode 100644
index 0000000..c5e3684
--- /dev/null
+++ b/plugins/reverse-vnc/vinagre-reverse-vnc-plugin.h
@@ -0,0 +1,64 @@
+/*
+ * vinagre-reverse-vnc-plugin.h
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2009 Jorge Pereira <jorge jorgepereira com br>
+ * Copyright (C) 2009-2010 Jonh Wendell <wendell bani com br>
+ *
+ * vinagre-reverse-vnc-plugin.h 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.
+ *
+ * vinagre-reverse-vnc-plugin.h 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __VINAGRE_REVERSE_VNC_PLUGIN_H__
+#define __VINAGRE_REVERSE_VNC_PLUGIN_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libpeas/peas.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define VINAGRE_TYPE_REVERSE_VNC_PLUGIN (vinagre_reverse_vnc_plugin_get_type ())
+#define VINAGRE_REVERSE_VNC_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), VINAGRE_TYPE_REVERSE_VNC_PLUGIN, VinagreReverseVncPlugin))
+#define VINAGRE_REVERSE_VNC_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), VINAGRE_TYPE_REVERSE_VNC_PLUGIN, VinagreReverseVncPluginClass))
+#define VINAGRE_IS_REVERSE_VNC_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), VINAGRE_TYPE_REVERSE_VNC_PLUGIN))
+#define VINAGRE_IS_REVERSE_VNC_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), VINAGRE_TYPE_REVERSE_VNC_PLUGIN))
+#define VINAGRE_REVERSE_VNC_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), VINAGRE_TYPE_REVERSE_VNC_PLUGIN, VinagreReverseVncPluginClass))
+
+typedef struct _VinagreReverseVncPlugin VinagreReverseVncPlugin;
+typedef struct _VinagreReverseVncPluginClass VinagreReverseVncPluginClass;
+typedef struct _VinagreReverseVncPluginPrivate VinagreReverseVncPluginPrivate;
+
+struct _VinagreReverseVncPlugin
+{
+ PeasExtensionBase parent_instance;
+ VinagreReverseVncPluginPrivate *priv;
+};
+
+struct _VinagreReverseVncPluginClass
+{
+ PeasExtensionBaseClass parent_class;
+};
+
+GType vinagre_reverse_vnc_plugin_get_type (void) G_GNUC_CONST;
+
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
+
+G_END_DECLS
+
+#endif /* __VINAGRE_REVERSE_VNC_PLUGIN_H__ */
+
+/* vim: set ts=8: */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]