--- /dev/null
+diff -urN gtk-vnc-0.3.7/bootstrap gtk-vnc-0.3.7.mingw/bootstrap
+--- gtk-vnc-0.3.7/bootstrap 1970-01-01 01:00:00.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/bootstrap 2008-10-09 12:19:03.000000000 +0100
+@@ -0,0 +1,84 @@
++#!/bin/sh
++# Run this after autogen.sh, to pull in all of the gnulib-related bits.
++# It's important to run *after* autogen.sh, since it updates some of
++# the same files autogen.sh does, yet those from gnulib are newer,
++# and match the tests. So if a gnulib bug has been fixed since the
++# snapshot taken for whatever gettext release you're using, yet you
++# run "make check" against the wrong version, the corresponding unit
++# test in gl-tests/ may well fail.
++
++usage() {
++ echo >&2 "\
++Usage: $0 [OPTION]...
++Bootstrap this package from the checked-out sources.
++
++Options:
++ --gnulib-srcdir=DIRNAME Specify the local directory where gnulib
++ sources reside. Use this if you already
++ have gnulib sources on your machine, and
++ do not want to waste your bandwidth downloading
++ them again.
++
++If the file bootstrap.conf exists in the current working directory, its
++contents are read as shell variables to configure the bootstrap.
++
++Running without arguments will suffice in most cases.
++"
++}
++
++for option
++do
++ case $option in
++ --help)
++ usage
++ exit;;
++ --gnulib-srcdir=*)
++ GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
++ *)
++ echo >&2 "$0: $option: unknown option"
++ exit 1;;
++ esac
++done
++
++cleanup_gnulib() {
++ st=$?
++ rm -fr .gnulib
++ exit $st
++}
++
++case ${GNULIB_SRCDIR--} in
++-)
++ if [ ! -d .gnulib ]; then
++ echo "$0: getting gnulib files..."
++
++ trap cleanup_gnulib 1 2 13 15
++
++ git clone --depth 1 git://git.sv.gnu.org/gnulib .gnulib ||
++ cleanup_gnulib
++
++ trap - 1 2 13 15
++ fi
++ GNULIB_SRCDIR=.gnulib
++esac
++
++gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
++<$gnulib_tool || exit
++
++modules='
++getaddrinfo
++vc-list-files
++'
++
++# Tell gnulib to:
++# require LGPLv2+
++# put *.m4 files in new gnulib/m4/ dir
++# put *.[ch] files in new gnulib/lib/ dir.
++
++$gnulib_tool \
++ --lgpl=2 \
++ --with-tests \
++ --m4-base=gnulib/m4 \
++ --source-base=gnulib/lib \
++ --tests-base=gnulib/tests \
++ --import $modules
++
+diff -urN gtk-vnc-0.3.7/configure.ac gtk-vnc-0.3.7.mingw/configure.ac
+--- gtk-vnc-0.3.7/configure.ac 2008-09-05 13:32:15.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/configure.ac 2008-10-09 12:19:03.000000000 +0100
+@@ -23,15 +23,29 @@
+
+ AC_CONFIG_HEADERS([config.h:config.hin])
+
+-
+ AC_CANONICAL_TARGET
+
+ AM_INIT_AUTOMAKE(gtk-vnc, 0.3.7)
+
++
++dnl gl_INIT uses m4_foreach_w, yet that is not defined in autoconf-2.59.
++dnl In order to accommodate developers with such old tools, here's a
++dnl replacement definition.
++m4_ifndef([m4_foreach_w],
++ [m4_define([m4_foreach_w],
++ [m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])])
++
++gl_EARLY
++gl_INIT
++
+ AC_PROG_CC_STDC
+ AM_PROG_CC_C_O
++AC_LIBTOOL_WIN32_DLL
++
+ AC_PROG_LIBTOOL
+
++AC_CHECK_HEADERS([pwd.h winsock2.h])
++
+ AC_ARG_WITH(python,
+ [ --with-python build python bindings],
+ [case "${withval}" in
+@@ -234,6 +248,8 @@
+
+ AC_CONFIG_FILES(
+ Makefile
++ gnulib/lib/Makefile
++ gnulib/tests/Makefile
+ src/Makefile
+ examples/Makefile
+ plugin/Makefile
+diff -urN gtk-vnc-0.3.7/Makefile.am gtk-vnc-0.3.7.mingw/Makefile.am
+--- gtk-vnc-0.3.7/Makefile.am 2008-09-05 13:32:15.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/Makefile.am 2008-10-09 12:19:01.000000000 +0100
+@@ -1,5 +1,9 @@
+
+-SUBDIRS = src examples plugin
++SUBDIRS = gnulib/lib src examples plugin gnulib/tests
++
++ACLOCAL_AMFLAGS = -I gnulib/m4
++
++
+
+ pkgconfig_DATA = @PACKAGE@-1.0.pc
+ pkgconfigdir = $(libdir)/pkgconfig
+diff -urN gtk-vnc-0.3.7/src/continuation.c gtk-vnc-0.3.7.mingw/src/continuation.c
+--- gtk-vnc-0.3.7/src/continuation.c 2008-09-05 13:32:16.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/src/continuation.c 2008-10-09 12:19:03.000000000 +0100
+@@ -8,6 +8,8 @@
+ * GTK VNC Widget
+ */
+
++#include <config.h>
++
+ #include "continuation.h"
+
+ /*
+diff -urN gtk-vnc-0.3.7/src/coroutine_gthread.c gtk-vnc-0.3.7.mingw/src/coroutine_gthread.c
+--- gtk-vnc-0.3.7/src/coroutine_gthread.c 2008-09-05 13:32:16.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/src/coroutine_gthread.c 2008-10-09 12:19:03.000000000 +0100
+@@ -8,6 +8,8 @@
+ * GTK VNC Widget
+ */
+
++#include <config.h>
++
+ #include "coroutine.h"
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -17,13 +19,24 @@
+ static struct coroutine *current;
+ static struct coroutine leader;
+
++#if 0
++#define CO_DEBUG(OP) fprintf(stderr, "%s %p %s %d\n", OP, g_thread_self(), __FUNCTION__, __LINE__)
++#else
++#define CO_DEBUG(OP)
++#endif
++
+ static void coroutine_system_init(void)
+ {
+- if (!g_thread_supported())
++ if (!g_thread_supported()) {
++ CO_DEBUG("INIT");
+ g_thread_init(NULL);
++ }
++
+
+ run_cond = g_cond_new();
+ run_lock = g_mutex_new();
++ CO_DEBUG("LOCK");
++ g_mutex_lock(run_lock);
+
+ /* The thread that creates the first coroutine is the system coroutine
+ * so let's fill out a structure for it */
+@@ -42,17 +55,22 @@
+ static gpointer coroutine_thread(gpointer opaque)
+ {
+ struct coroutine *co = opaque;
+-
++ CO_DEBUG("LOCK");
+ g_mutex_lock(run_lock);
+- while (!co->runnable)
++ while (!co->runnable) {
++ CO_DEBUG("WAIT");
+ g_cond_wait(run_cond, run_lock);
++ }
+
++ CO_DEBUG("RUNNABLE");
+ current = co;
+ co->data = co->entry(co->data);
+ co->exited = 1;
+
+ co->caller->runnable = TRUE;
++ CO_DEBUG("BROADCAST");
+ g_cond_broadcast(run_cond);
++ CO_DEBUG("UNLOCK");
+ g_mutex_unlock(run_lock);
+
+ return NULL;
+@@ -62,7 +80,8 @@
+ {
+ if (run_cond == NULL)
+ coroutine_system_init();
+-
++
++ CO_DEBUG("NEW");
+ co->thread = g_thread_create_full(coroutine_thread, co, co->stack_size,
+ FALSE, TRUE,
+ G_THREAD_PRIORITY_NORMAL,
+@@ -88,15 +107,19 @@
+ to->runnable = TRUE;
+ to->data = arg;
+ to->caller = from;
++ CO_DEBUG("BROADCAST");
+ g_cond_broadcast(run_cond);
++ CO_DEBUG("UNLOCK");
+ g_mutex_unlock(run_lock);
+-
++ CO_DEBUG("LOCK");
+ g_mutex_lock(run_lock);
+- while (!from->runnable)
++ while (!from->runnable) {
++ CO_DEBUG("WAIT");
+ g_cond_wait(run_cond, run_lock);
+-
++ }
+ current = from;
+
++ CO_DEBUG("SWAPPED");
+ return from->data;
+ }
+
+@@ -111,6 +134,7 @@
+ fprintf(stderr, "Co-routine is re-entering itself\n");
+ abort();
+ }
++ CO_DEBUG("SWAP");
+ return coroutine_swap(coroutine_self(), to, arg);
+ }
+
+@@ -121,6 +145,8 @@
+ fprintf(stderr, "Co-routine is yielding to no one\n");
+ abort();
+ }
++
++ CO_DEBUG("SWAP");
+ coroutine_self()->caller = NULL;
+ return coroutine_swap(coroutine_self(), to, arg);
+ }
+diff -urN gtk-vnc-0.3.7/src/coroutine_ucontext.c gtk-vnc-0.3.7.mingw/src/coroutine_ucontext.c
+--- gtk-vnc-0.3.7/src/coroutine_ucontext.c 2008-09-05 13:32:16.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/src/coroutine_ucontext.c 2008-10-09 12:19:03.000000000 +0100
+@@ -8,6 +8,8 @@
+ * GTK VNC Widget
+ */
+
++#include <config.h>
++
+ #include <sys/types.h>
+ #include <sys/mman.h>
+ #include <stdio.h>
+diff -urN gtk-vnc-0.3.7/src/gvnc.c gtk-vnc-0.3.7.mingw/src/gvnc.c
+--- gtk-vnc-0.3.7/src/gvnc.c 2008-09-05 13:32:16.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/src/gvnc.c 2008-10-09 12:19:03.000000000 +0100
+@@ -8,13 +8,10 @@
+ * GTK VNC Widget
+ */
+
+-#include "gvnc.h"
++#include <config.h>
+
+-#include <sys/socket.h>
+-#include <netinet/in.h>
+-#include <arpa/inet.h>
++#include "gvnc.h"
+
+-#include <netdb.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <stdio.h>
+@@ -40,6 +37,15 @@
+ #include <gdk/gdkkeysyms.h>
+
+ #include "vnc_keycodes.h"
++#include "socketcompat.h"
++#include "getaddrinfo.h"
++
++/* AI_ADDRCONFIG is missing on some systems and gnulib won't provide it
++ even if its emulated getaddrinfo() for us . */
++#ifndef AI_ADDRCONFIG
++# define AI_ADDRCONFIG 0
++#endif
++
+
+ struct wait_queue
+ {
+@@ -185,7 +191,6 @@
+
+ g_io_add_watch(channel, cond | G_IO_HUP | G_IO_ERR | G_IO_NVAL, g_io_wait_helper, coroutine_self());
+ ret = coroutine_yield(NULL);
+-
+ return *ret;
+ }
+
+@@ -321,10 +326,8 @@
+
+ /* inflate as much as possible */
+ err = inflate(gvnc->strm, Z_SYNC_FLUSH);
+- if (err != Z_OK) {
+- errno = EIO;
+- return -1;
+- }
++ if (err != Z_OK)
++ return -EIO;
+
+ gvnc->uncompressed_length = (uint8_t *)gvnc->strm->next_out - gvnc->uncompressed_buffer;
+ gvnc->compressed_length -= (uint8_t *)gvnc->strm->next_in - gvnc->compressed_buffer;
+@@ -344,7 +347,7 @@
+ size_t offset = 0;
+
+ if (gvnc->has_error) return -EINVAL;
+-
++
+ while (offset < len) {
+ size_t tmp;
+
+@@ -352,10 +355,10 @@
+ * so we must by-pass it */
+ if (gvnc_use_compression(gvnc)) {
+ int ret = gvnc_zread(gvnc, data + offset, len);
+- if (ret == -1) {
++ if (ret < 0) {
+ GVNC_DEBUG("Closing the connection: gvnc_read() - gvnc_zread() failed\n");
+ gvnc->has_error = TRUE;
+- return -errno;
++ return ret;
+ }
+ offset += ret;
+ continue;
+@@ -366,17 +369,19 @@
+ ret = gnutls_read(gvnc->tls_session, gvnc->read_buffer, 4096);
+ if (ret < 0) {
+ if (ret == GNUTLS_E_AGAIN)
+- errno = EAGAIN;
++ ret = -EAGAIN;
+ else
+- errno = EIO;
+- ret = -1;
++ ret = -EIO;
+ }
+- } else
+- ret = read(fd, gvnc->read_buffer, 4096);
++ } else {
++ ret = recv(fd, gvnc->read_buffer, 4096, 0);
++ if (ret < 0)
++ ret = socket_errno() * -1;
++ }
+
+- if (ret == -1) {
+- switch (errno) {
+- case EAGAIN:
++ if (ret < 0) {
++ switch (ret * -1) {
++ case EWOULDBLOCK:
+ if (gvnc->wait_interruptable) {
+ if (!g_io_wait_interruptable(&gvnc->wait,
+ gvnc->channel, G_IO_IN))
+@@ -386,9 +391,9 @@
+ case EINTR:
+ continue;
+ default:
+- GVNC_DEBUG("Closing the connection: gvnc_read() - ret=-1\n");
++ GVNC_DEBUG("Closing the connection: gvnc_read() - ret=%d\n", ret);
+ gvnc->has_error = TRUE;
+- return -errno;
++ return ret;
+ }
+ }
+ if (ret == 0) {
+@@ -425,23 +430,25 @@
+ gvnc->write_offset-offset);
+ if (ret < 0) {
+ if (ret == GNUTLS_E_AGAIN)
+- errno = EAGAIN;
++ ret = -EAGAIN;
+ else
+- errno = EIO;
+- ret = -1;
++ ret = -EIO;
+ }
+- } else
+- ret = write(fd,
+- gvnc->write_buffer+offset,
+- gvnc->write_offset-offset);
+- if (ret == -1) {
+- switch (errno) {
+- case EAGAIN:
++ } else {
++ ret = send(fd,
++ gvnc->write_buffer+offset,
++ gvnc->write_offset-offset, 0);
++ if (ret < 0)
++ ret = socket_errno() * -1;
++ }
++ if (ret < 0) {
++ switch (ret * -1) {
++ case EWOULDBLOCK:
+ g_io_wait(gvnc->channel, G_IO_OUT);
+ case EINTR:
+ continue;
+ default:
+- GVNC_DEBUG("Closing the connection: gvnc_flush\n");
++ GVNC_DEBUG("Closing the connection: gvnc_flush %d\n", ret);
+ gvnc->has_error = TRUE;
+ return;
+ }
+@@ -488,7 +495,7 @@
+ retry:
+ ret = write(fd, data, len);
+ if (ret < 0) {
+- if (errno == EINTR)
++ if (socket_errno() == EINTR)
+ goto retry;
+ return -1;
+ }
+@@ -506,7 +513,7 @@
+ retry:
+ ret = read(fd, data, len);
+ if (ret < 0) {
+- if (errno == EINTR)
++ if (socket_errno() == EINTR)
+ goto retry;
+ return -1;
+ }
+@@ -2802,12 +2809,12 @@
+ if (gvnc_has_error(gvnc))
+ return FALSE;
+
+- if (!gvnc->fmt.true_color_flag && gvnc->ops.get_preferred_pixel_format)
++ if (!gvnc->fmt.true_color_flag && gvnc->ops.get_preferred_pixel_format) {
+ if (gvnc->ops.get_preferred_pixel_format(gvnc->ops_data, &gvnc->fmt))
+ gvnc_set_pixel_format(gvnc, &gvnc->fmt);
+ else
+ goto fail;
+-
++ }
+ memset(&gvnc->strm, 0, sizeof(gvnc->strm));
+ /* FIXME what level? */
+ for (i = 0; i < 5; i++)
+@@ -2822,15 +2829,16 @@
+ return !gvnc_has_error(gvnc);
+ }
+
+-gboolean gvnc_open_fd(struct gvnc *gvnc, int fd)
++static gboolean gvnc_set_nonblock(int fd)
+ {
+- int flags;
+- if (gvnc_is_open(gvnc)) {
+- GVNC_DEBUG ("Error: already connected?\n");
++#ifdef __MINGW32__
++ unsigned long flags = 1;
++ if (ioctlsocket(fd, FIONBIO, &flags) < 0) {
++ GVNC_DEBUG ("Failed to set nonblocking flag\n");
+ return FALSE;
+ }
+-
+- GVNC_DEBUG("Connecting to FD %d\n", fd);
++#else
++ int flags;
+ if ((flags = fcntl(fd, F_GETFL)) < 0) {
+ GVNC_DEBUG ("Failed to fcntl()\n");
+ return FALSE;
+@@ -2840,6 +2848,21 @@
+ GVNC_DEBUG ("Failed to fcntl()\n");
+ return FALSE;
+ }
++#endif
++ return TRUE;
++}
++
++gboolean gvnc_open_fd(struct gvnc *gvnc, int fd)
++{
++ if (gvnc_is_open(gvnc)) {
++ GVNC_DEBUG ("Error: already connected?\n");
++ return FALSE;
++ }
++
++ GVNC_DEBUG("Connecting to FD %d\n", fd);
++
++ if (!gvnc_set_nonblock(fd))
++ return FALSE;
+
+ if (!(gvnc->channel = g_io_channel_unix_new(fd))) {
+ GVNC_DEBUG ("Failed to g_io_channel_unix_new()\n");
+@@ -2873,7 +2896,7 @@
+
+ runp = ai;
+ while (runp != NULL) {
+- int flags, fd;
++ int fd;
+ GIOChannel *chan;
+
+ if ((fd = socket(runp->ai_family, runp->ai_socktype,
+@@ -2883,17 +2906,8 @@
+ }
+
+ GVNC_DEBUG("Trying socket %d\n", fd);
+- if ((flags = fcntl(fd, F_GETFL)) < 0) {
+- close(fd);
+- GVNC_DEBUG ("Failed to fcntl()\n");
+- break;
+- }
+- flags |= O_NONBLOCK;
+- if (fcntl(fd, F_SETFL, flags) < 0) {
+- close(fd);
+- GVNC_DEBUG ("Failed to fcntl()\n");
+- break;
+- }
++ if (!gvnc_set_nonblock(fd))
++ break;
+
+ if (!(chan = g_io_channel_unix_new(fd))) {
+ close(fd);
+@@ -2904,21 +2918,22 @@
+ reconnect:
+ /* FIXME: Better handle EINPROGRESS/EISCONN return values,
+ as explained in connect(2) man page */
+- if ( (connect(fd, runp->ai_addr, runp->ai_addrlen) == 0) || errno == EISCONN) {
++ if ((connect(fd, runp->ai_addr, runp->ai_addrlen) == 0) ||
++ socket_errno() == EISCONN) {
+ gvnc->channel = chan;
+ gvnc->fd = fd;
+ freeaddrinfo(ai);
+ return !gvnc_has_error(gvnc);
+ }
+-
+- if (errno == EINPROGRESS) {
++ if (socket_errno() == EINPROGRESS ||
++ socket_errno() == EWOULDBLOCK) {
+ g_io_wait(chan, G_IO_OUT|G_IO_ERR|G_IO_HUP);
+ goto reconnect;
+- } else if (errno != ECONNREFUSED &&
+- errno != EHOSTUNREACH) {
++ } else if (socket_errno() != ECONNREFUSED &&
++ socket_errno() != EHOSTUNREACH) {
+ g_io_channel_unref(chan);
+ close(fd);
+- GVNC_DEBUG ("Failed with errno = %d\n", errno);
++ GVNC_DEBUG ("Failed with errno = %d\n", socket_errno());
+ break;
+ }
+ close(fd);
+diff -urN gtk-vnc-0.3.7/src/Makefile.am gtk-vnc-0.3.7.mingw/src/Makefile.am
+--- gtk-vnc-0.3.7/src/Makefile.am 2008-09-05 13:32:15.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/src/Makefile.am 2008-10-09 12:19:03.000000000 +0100
+@@ -4,13 +4,15 @@
+ lib_LTLIBRARIES = libgtk-vnc-1.0.la
+
+ libgtk_vnc_1_0_la_LIBADD = @GTK_LIBS@ @GTKGLEXT_LIBS@ @GNUTLS_LIBS@ \
+- @GTHREAD_LIBS@
++ @GTHREAD_LIBS@ \
++ ../gnulib/lib/libgnu.la
+ libgtk_vnc_1_0_la_CFLAGS = @GTK_CFLAGS@ @GTKGLEXT_CFLAGS@ @GNUTLS_CFLAGS@ \
+ @GTHREAD_CFLAGS@ @WARNING_CFLAGS@ \
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
+- -DG_LOG_DOMAIN=\"gtk-vnc\"
++ -DG_LOG_DOMAIN=\"gtk-vnc\" \
++ -I$(top_srcdir)gnulib/lib -I../gnulib/lib
+ libgtk_vnc_1_0_la_LDFLAGS = -Wl, @LD_VERSION_SCRIPT_SUPPORT@ \
+- -version-info 0:1:0
++ -version-info 0:1:0 -no-undefined
+
+ gtk_vnc_includedir = $(includedir)/gtk-vnc-1.0/
+ gtk_vnc_include_HEADERS = vncdisplay.h
+@@ -22,7 +24,7 @@
+ vncdisplay.h vncdisplay.c \
+ vncmarshal.h vncmarshal.c \
+ x_keymap.h x_keymap.c vnc_keycodes.h \
+- utils.h
++ utils.h socketcompat.h
+
+ if WITH_UCONTEXT
+ libgtk_vnc_1_0_la_SOURCES += continuation.h continuation.c coroutine_ucontext.c
+diff -urN gtk-vnc-0.3.7/src/socketcompat.h gtk-vnc-0.3.7.mingw/src/socketcompat.h
+--- gtk-vnc-0.3.7/src/socketcompat.h 1970-01-01 01:00:00.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/src/socketcompat.h 2008-10-09 12:19:03.000000000 +0100
+@@ -0,0 +1,64 @@
++/*
++ * socketcompat.h: Socket compatibility for Windows, making it slightly
++ * less painful to use.
++ *
++ * Use this header under the following circumstances:
++ * (a) Instead of including any of: <net/if.h>, <netinet/in.h>,
++ * <sys/socket.h>, <netdb.h>, <netinet/tcp.h>, AND
++ * (b) The file will be part of what is built on Windows (basically
++ * just remote client stuff).
++ *
++ * You need to use socket_errno() instead of errno to get socket
++ * errors.
++ *
++ * Copyright (C) 2008 Red Hat, Inc.
++ *
++ * See COPYING.LIB for the License of this software
++ *
++ * Richard W.M. Jones <rjones@redhat.com>
++ */
++
++#ifndef __SOCKETCOMPAT_H__
++#define __SOCKETCOMPAT_H__
++
++#include <config.h>
++
++#include <errno.h>
++
++#ifndef HAVE_WINSOCK2_H /* Unix & Cygwin. */
++
++#include <sys/socket.h>
++#include <sys/un.h>
++#include <net/if.h>
++#include <netinet/in.h>
++#include <netinet/tcp.h>
++
++static inline int
++socket_errno (void)
++{
++ return errno;
++}
++
++#else /* MinGW & Win32 */
++
++#include <winsock2.h>
++
++/* Socket functions in Windows don't set errno. Instead of using errno
++ * to test for socket errors, call this function to get the errno.
++ */
++static inline int
++socket_errno (void)
++{
++ return WSAGetLastError ();
++}
++
++/* Compatibility. */
++#define EWOULDBLOCK WSAEWOULDBLOCK
++#define ECONNREFUSED WSAECONNREFUSED
++#define EINPROGRESS WSAEINPROGRESS
++#define EHOSTUNREACH WSAEHOSTUNREACH
++#define EISCONN WSAEISCONN
++
++#endif /* HAVE_WINSOCK2_H */
++
++#endif /* __WINSOCKWRAPPER_H__ */
+diff -urN gtk-vnc-0.3.7/src/vncdisplay.c gtk-vnc-0.3.7.mingw/src/vncdisplay.c
+--- gtk-vnc-0.3.7/src/vncdisplay.c 2008-10-09 12:16:42.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/src/vncdisplay.c 2008-10-09 12:19:03.000000000 +0100
+@@ -8,6 +8,8 @@
+ * GTK VNC Widget
+ */
+
++#include <config.h>
++
+ #include "vncdisplay.h"
+ #include "coroutine.h"
+ #include "gvnc.h"
+@@ -24,7 +26,9 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
++#ifdef HAVE_PWD_H
+ #include <pwd.h>
++#endif
+
+ #if WITH_GTKGLEXT
+ #include <gtk/gtkgl.h>
+@@ -2191,33 +2195,44 @@
+
+ static int vnc_display_set_x509_credential(VncDisplay *obj, const char *name)
+ {
+- char sysdir[PATH_MAX], userdir[PATH_MAX];
+- struct passwd *pw;
+ char file[PATH_MAX];
++ char sysdir[PATH_MAX];
++#ifndef __MINGW32__
++ char userdir[PATH_MAX];
++ struct passwd *pw;
+ char *dirs[] = { sysdir, userdir };
++#else
++ char *dirs[] = { sysdir };
++#endif
+
+ strncpy(sysdir, SYSCONFDIR "/pki", PATH_MAX-1);
+ sysdir[PATH_MAX-1] = '\0';
+
++#ifndef __MINGW32__
+ if (!(pw = getpwuid(getuid())))
+ return TRUE;
+
+ snprintf(userdir, PATH_MAX-1, "%s/.pki", pw->pw_dir);
+ userdir[PATH_MAX-1] = '\0';
++#endif
+
+- if (vnc_display_best_path(file, PATH_MAX, "CA", "cacert.pem", dirs, 2) < 0)
++ if (vnc_display_best_path(file, PATH_MAX, "CA", "cacert.pem",
++ dirs, sizeof(dirs)/sizeof(dirs[0])) < 0)
+ return TRUE;
+ gvnc_set_credential_x509_cacert(obj->priv->gvnc, file);
+
+ /* Don't mind failures of CRL */
+- if (vnc_display_best_path(file, PATH_MAX, "CA", "cacrl.pem", dirs, 2) == 0)
++ if (vnc_display_best_path(file, PATH_MAX, "CA", "cacrl.pem",
++ dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
+ gvnc_set_credential_x509_cacert(obj->priv->gvnc, file);
+
+ /* Set client key & cert if we have them. Server will reject auth
+ * if it decides it requires them*/
+- if (vnc_display_best_path(file, PATH_MAX, name, "private/clientkey.pem", dirs, 2) == 0)
++ if (vnc_display_best_path(file, PATH_MAX, name, "private/clientkey.pem",
++ dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
+ gvnc_set_credential_x509_key(obj->priv->gvnc, file);
+- if (vnc_display_best_path(file, PATH_MAX, name, "clientcert.pem", dirs, 2) == 0)
++ if (vnc_display_best_path(file, PATH_MAX, name, "clientcert.pem",
++ dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
+ gvnc_set_credential_x509_cert(obj->priv->gvnc, file);
+
+ return FALSE;
+diff -urN gtk-vnc-0.3.7/src/vncdisplay.c.orig gtk-vnc-0.3.7.mingw/src/vncdisplay.c.orig
+--- gtk-vnc-0.3.7/src/vncdisplay.c.orig 2008-09-05 13:32:16.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/src/vncdisplay.c.orig 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2491 +0,0 @@
+-/*
+- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU Lesser General Public License version 2 or
+- * later as published by the Free Software Foundation.
+- *
+- * GTK VNC Widget
+- */
+-
+-#include "vncdisplay.h"
+-#include "coroutine.h"
+-#include "gvnc.h"
+-#include "utils.h"
+-#include "vncmarshal.h"
+-#include "config.h"
+-#include "x_keymap.h"
+-
+-#include <gtk/gtk.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <gdk/gdkkeysyms.h>
+-#include <gdk-pixbuf/gdk-pixbuf.h>
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <unistd.h>
+-#include <pwd.h>
+-
+-#if WITH_GTKGLEXT
+-#include <gtk/gtkgl.h>
+-#include <GL/gl.h>
+-#endif
+-
+-#define VNC_DISPLAY_GET_PRIVATE(obj) \
+- (G_TYPE_INSTANCE_GET_PRIVATE((obj), VNC_TYPE_DISPLAY, VncDisplayPrivate))
+-
+-struct _VncDisplayPrivate
+-{
+- int fd;
+- char *host;
+- char *port;
+- GdkGC *gc;
+- GdkImage *image;
+- GdkCursor *null_cursor;
+- GdkCursor *remote_cursor;
+-
+-#if WITH_GTKGLEXT
+- int gl_enabled;
+- GdkGLConfig *gl_config;
+- GdkGLDrawable *gl_drawable;
+- GdkGLContext *gl_context;
+- uint8_t *gl_tex_data;
+- int gl_texture_width;
+- int gl_texture_height;
+- int gl_width;
+- int gl_height;
+- GLuint gl_tex;
+-#endif
+-
+- struct gvnc_framebuffer fb;
+- struct coroutine coroutine;
+- struct gvnc *gvnc;
+-
+- guint open_id;
+-
+- gboolean in_pointer_grab;
+- gboolean in_keyboard_grab;
+-
+- guint down_keyval[16];
+- guint down_scancode[16];
+-
+- int button_mask;
+- int last_x;
+- int last_y;
+-
+- gboolean absolute;
+-
+- gboolean grab_pointer;
+- gboolean grab_keyboard;
+- gboolean local_pointer;
+- gboolean read_only;
+- gboolean allow_lossy;
+- gboolean allow_scaling;
+- gboolean shared_flag;
+- gboolean force_size;
+-
+- GSList *preferable_auths;
+-};
+-
+-/* Delayed signal emission.
+- *
+- * We want signals to be delivered in the system coroutine. This helps avoid
+- * confusing applications. This is particularly important when using
+- * GThread based coroutines since GTK gets very upset if a signal handler is
+- * run in a different thread from the main loop if that signal handler isn't
+- * written to use explicit locking.
+- */
+-struct signal_data
+-{
+- VncDisplay *obj;
+- struct coroutine *caller;
+-
+- int signum;
+- GValueArray *cred_list;
+- int width;
+- int height;
+- const char *msg;
+- unsigned int auth_type;
+- GString *str;
+-};
+-
+-G_DEFINE_TYPE(VncDisplay, vnc_display, GTK_TYPE_DRAWING_AREA)
+-
+-/* Properties */
+-enum
+-{
+- PROP_0,
+- PROP_POINTER_LOCAL,
+- PROP_POINTER_GRAB,
+- PROP_KEYBOARD_GRAB,
+- PROP_READ_ONLY,
+- PROP_WIDTH,
+- PROP_HEIGHT,
+- PROP_NAME,
+- PROP_LOSSY_ENCODING,
+- PROP_SCALING,
+- PROP_SHARED_FLAG,
+- PROP_FORCE_SIZE
+-};
+-
+-/* Signals */
+-typedef enum
+-{
+- VNC_POINTER_GRAB,
+- VNC_POINTER_UNGRAB,
+- VNC_KEYBOARD_GRAB,
+- VNC_KEYBOARD_UNGRAB,
+-
+- VNC_CONNECTED,
+- VNC_INITIALIZED,
+- VNC_DISCONNECTED,
+- VNC_AUTH_CREDENTIAL,
+-
+- VNC_DESKTOP_RESIZE,
+-
+- VNC_AUTH_FAILURE,
+- VNC_AUTH_UNSUPPORTED,
+-
+- VNC_SERVER_CUT_TEXT,
+- VNC_BELL,
+-
+- LAST_SIGNAL
+-} vnc_display_signals;
+-
+-static guint signals[LAST_SIGNAL] = { 0, 0, 0, 0,
+- 0, 0, 0, 0,
+- 0, 0, 0, 0, 0,};
+-static GParamSpec *signalCredParam;
+-gboolean debug_enabled = FALSE;
+-
+-static const GOptionEntry gtk_vnc_args[] =
+-{
+- { "gtk-vnc-debug", 0, 0, G_OPTION_ARG_NONE, &debug_enabled, "Enables debug output", 0 },
+- { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, 0 }
+-};
+-
+-
+-static void
+-vnc_display_get_property (GObject *object,
+- guint prop_id,
+- GValue *value,
+- GParamSpec *pspec)
+-{
+- VncDisplay *vnc = VNC_DISPLAY (object);
+-
+- switch (prop_id)
+- {
+- case PROP_POINTER_LOCAL:
+- g_value_set_boolean (value, vnc->priv->local_pointer);
+- break;
+- case PROP_POINTER_GRAB:
+- g_value_set_boolean (value, vnc->priv->grab_pointer);
+- break;
+- case PROP_KEYBOARD_GRAB:
+- g_value_set_boolean (value, vnc->priv->grab_keyboard);
+- break;
+- case PROP_READ_ONLY:
+- g_value_set_boolean (value, vnc->priv->read_only);
+- break;
+- case PROP_WIDTH:
+- g_value_set_int (value, vnc_display_get_width (vnc));
+- break;
+- case PROP_HEIGHT:
+- g_value_set_int (value, vnc_display_get_height (vnc));
+- break;
+- case PROP_NAME:
+- g_value_set_string (value, vnc_display_get_name (vnc));
+- break;
+- case PROP_LOSSY_ENCODING:
+- g_value_set_boolean (value, vnc->priv->allow_lossy);
+- break;
+- case PROP_SCALING:
+- g_value_set_boolean (value, vnc->priv->allow_scaling);
+- break;
+- case PROP_SHARED_FLAG:
+- g_value_set_boolean (value, vnc->priv->shared_flag);
+- break;
+- case PROP_FORCE_SIZE:
+- g_value_set_boolean (value, vnc->priv->force_size);
+- break;
+- default:
+- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+- break;
+- }
+-}
+-
+-static void
+-vnc_display_set_property (GObject *object,
+- guint prop_id,
+- const GValue *value,
+- GParamSpec *pspec)
+-{
+- VncDisplay *vnc = VNC_DISPLAY (object);
+-
+- switch (prop_id)
+- {
+- case PROP_POINTER_LOCAL:
+- vnc_display_set_pointer_local (vnc, g_value_get_boolean (value));
+- break;
+- case PROP_POINTER_GRAB:
+- vnc_display_set_pointer_grab (vnc, g_value_get_boolean (value));
+- break;
+- case PROP_KEYBOARD_GRAB:
+- vnc_display_set_keyboard_grab (vnc, g_value_get_boolean (value));
+- break;
+- case PROP_READ_ONLY:
+- vnc_display_set_read_only (vnc, g_value_get_boolean (value));
+- break;
+- case PROP_LOSSY_ENCODING:
+- vnc_display_set_lossy_encoding (vnc, g_value_get_boolean (value));
+- break;
+- case PROP_SCALING:
+- vnc_display_set_scaling (vnc, g_value_get_boolean (value));
+- break;
+- case PROP_SHARED_FLAG:
+- vnc_display_set_shared_flag (vnc, g_value_get_boolean (value));
+- break;
+- case PROP_FORCE_SIZE:
+- vnc_display_set_force_size (vnc, g_value_get_boolean (value));
+- break;
+- default:
+- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+- break;
+- }
+-}
+-
+-GtkWidget *vnc_display_new(void)
+-{
+- return GTK_WIDGET(g_object_new(VNC_TYPE_DISPLAY, NULL));
+-}
+-
+-static GdkCursor *create_null_cursor(void)
+-{
+- GdkBitmap *image;
+- gchar data[4] = {0};
+- GdkColor fg = { 0, 0, 0, 0 };
+- GdkCursor *cursor;
+-
+- image = gdk_bitmap_create_from_data(NULL, data, 1, 1);
+-
+- cursor = gdk_cursor_new_from_pixmap(GDK_PIXMAP(image),
+- GDK_PIXMAP(image),
+- &fg, &fg, 0, 0);
+- gdk_bitmap_unref(image);
+-
+- return cursor;
+-}
+-
+-static gboolean expose_event(GtkWidget *widget, GdkEventExpose *expose)
+-{
+- VncDisplay *obj = VNC_DISPLAY(widget);
+- VncDisplayPrivate *priv = obj->priv;
+- int x, y, w, h;
+- GdkRectangle drawn;
+- GdkRegion *clear, *copy;
+-
+- GVNC_DEBUG("Expose %dx%d @ %d,%d\n",
+- expose->area.x,
+- expose->area.y,
+- expose->area.width,
+- expose->area.height);
+-
+- if (priv->image == NULL) {
+-#if WITH_GTKGLEXT
+- if (priv->gl_tex_data == NULL)
+-#endif
+- {
+- GdkGC *gc = gdk_gc_new(widget->window);
+- gdk_draw_rectangle(widget->window, gc, TRUE,
+- expose->area.x, expose->area.y,
+- expose->area.width,
+- expose->area.height);
+- g_object_unref(gc);
+- return TRUE;
+- }
+- }
+-
+-#if WITH_GTKGLEXT
+- if (priv->gl_enabled) {
+- float rx, ry;
+- int wx = 0, wy = 0;
+- int ww = priv->gl_width, wh = priv->gl_height;
+- double scale_x, scale_y;
+-
+- scale_x = (double)priv->gl_width / priv->fb.width;
+- scale_y = (double)priv->gl_height / priv->fb.height;
+-
+- x = expose->area.x / scale_x;
+- y = expose->area.y / scale_y;
+- w = expose->area.width / scale_x;
+- h = expose->area.height / scale_y;
+-
+- y -= 5;
+- h += 10;
+- if (y < 0)
+- y = 0;
+-
+- x -= 5;
+- w += 10;
+- if (x < 0)
+- x = 0;
+-
+- x = MIN(x, priv->fb.width);
+- y = MIN(y, priv->fb.height);
+- w = MIN(x + w, priv->fb.width);
+- h = MIN(y + h, priv->fb.height);
+- w -= x;
+- h -= y;
+-
+- gdk_gl_drawable_gl_begin(priv->gl_drawable, priv->gl_context);
+- glBindTexture(GL_TEXTURE_2D, priv->gl_tex);
+- glPixelStorei(GL_UNPACK_ROW_LENGTH, priv->fb.width);
+- glTexSubImage2D(GL_TEXTURE_2D, 0,
+- x, y, w, h,
+- GL_BGRA_EXT,
+- GL_UNSIGNED_BYTE,
+- priv->gl_tex_data +
+- y * 4 * priv->fb.width +
+- x * 4);
+- rx = (float)priv->fb.width / priv->gl_texture_width;
+- ry = (float)priv->fb.height / priv->gl_texture_height;
+-
+- glEnable(GL_TEXTURE_2D);
+- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+- glBegin(GL_QUADS);
+- glTexCoord2f(0,ry); glVertex3f(wx, wy, 0);
+- glTexCoord2f(0,0); glVertex3f(wx, wy+wh, 0);
+- glTexCoord2f(rx,0); glVertex3f(wx+ww, wy+wh, 0);
+- glTexCoord2f(rx,ry); glVertex3f(wx+ww, wy, 0);
+- glEnd();
+- glDisable(GL_TEXTURE_2D);
+- glFlush();
+- gdk_gl_drawable_gl_end(priv->gl_drawable);
+- } else
+-#endif
+- {
+- int mx = 0, my = 0;
+- int ww, wh;
+-
+- gdk_drawable_get_size(widget->window, &ww, &wh);
+- if (ww > priv->fb.width)
+- mx = (ww - priv->fb.width) / 2;
+- if (wh > priv->fb.height)
+- my = (wh - priv->fb.height) / 2;
+-
+- x = MIN(expose->area.x - mx, priv->fb.width);
+- y = MIN(expose->area.y - my, priv->fb.height);
+- w = MIN(expose->area.x + expose->area.width - mx, priv->fb.width);
+- h = MIN(expose->area.y + expose->area.height - my, priv->fb.height);
+- x = MAX(0, x);
+- y = MAX(0, y);
+- w = MAX(0, w);
+- h = MAX(0, h);
+-
+- w -= x;
+- h -= y;
+-
+- drawn.x = x + mx;
+- drawn.y = y + my;
+- drawn.width = w;
+- drawn.height = h;
+-
+- clear = gdk_region_rectangle(&expose->area);
+- copy = gdk_region_rectangle(&drawn);
+- gdk_region_subtract(clear, copy);
+-
+- gdk_gc_set_clip_region(priv->gc, copy);
+- gdk_draw_image(widget->window, priv->gc, priv->image,
+- x, y, x + mx, y + my, w, h);
+-
+- gdk_gc_set_clip_region(priv->gc, clear);
+- gdk_draw_rectangle(widget->window, priv->gc, TRUE, expose->area.x, expose->area.y,
+- expose->area.width, expose->area.height);
+-
+- gdk_region_destroy(clear);
+- gdk_region_destroy(copy);
+- }
+-
+- return TRUE;
+-}
+-
+-static void do_keyboard_grab(VncDisplay *obj, gboolean quiet)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+-
+- gdk_keyboard_grab(GTK_WIDGET(obj)->window,
+- FALSE,
+- GDK_CURRENT_TIME);
+- priv->in_keyboard_grab = TRUE;
+- if (!quiet)
+- g_signal_emit(obj, signals[VNC_KEYBOARD_GRAB], 0);
+-}
+-
+-
+-static void do_keyboard_ungrab(VncDisplay *obj, gboolean quiet)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+-
+- gdk_keyboard_ungrab(GDK_CURRENT_TIME);
+- priv->in_keyboard_grab = FALSE;
+- if (!quiet)
+- g_signal_emit(obj, signals[VNC_KEYBOARD_UNGRAB], 0);
+-}
+-
+-static void do_pointer_hide(VncDisplay *obj)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+- gdk_window_set_cursor(GTK_WIDGET(obj)->window,
+- priv->remote_cursor ? priv->remote_cursor : priv->null_cursor);
+-}
+-
+-static void do_pointer_show(VncDisplay *obj)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+- gdk_window_set_cursor(GTK_WIDGET(obj)->window,
+- priv->remote_cursor);
+-}
+-
+-static void do_pointer_grab(VncDisplay *obj, gboolean quiet)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+-
+- /* If we're not already grabbing keyboard, grab it now */
+- if (!priv->grab_keyboard)
+- do_keyboard_grab(obj, quiet);
+-
+- gdk_pointer_grab(GTK_WIDGET(obj)->window,
+- TRUE,
+- GDK_POINTER_MOTION_MASK |
+- GDK_BUTTON_PRESS_MASK |
+- GDK_BUTTON_RELEASE_MASK |
+- GDK_BUTTON_MOTION_MASK |
+- GDK_SCROLL_MASK,
+- GTK_WIDGET(obj)->window,
+- priv->remote_cursor ? priv->remote_cursor : priv->null_cursor,
+- GDK_CURRENT_TIME);
+- priv->in_pointer_grab = TRUE;
+- if (!quiet)
+- g_signal_emit(obj, signals[VNC_POINTER_GRAB], 0);
+-}
+-
+-static void do_pointer_ungrab(VncDisplay *obj, gboolean quiet)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+-
+- /* If we grabbed keyboard upon pointer grab, then ungrab it now */
+- if (!priv->grab_keyboard)
+- do_keyboard_ungrab(obj, quiet);
+-
+- gdk_pointer_ungrab(GDK_CURRENT_TIME);
+- priv->in_pointer_grab = FALSE;
+-
+- if (priv->absolute)
+- do_pointer_hide(obj);
+-
+- if (!quiet)
+- g_signal_emit(obj, signals[VNC_POINTER_UNGRAB], 0);
+-}
+-
+-void vnc_display_force_grab(VncDisplay *obj, gboolean enable)
+-{
+- if (enable)
+- do_pointer_grab(obj, FALSE);
+- else
+- do_pointer_ungrab(obj, FALSE);
+-}
+-
+-static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
+-{
+- VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
+- int n;
+-
+- if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
+- return FALSE;
+-
+- if (priv->read_only)
+- return FALSE;
+-
+- gtk_widget_grab_focus (widget);
+-
+- if (priv->grab_pointer && !priv->absolute && !priv->in_pointer_grab &&
+- button->button == 1 && button->type == GDK_BUTTON_PRESS)
+- do_pointer_grab(VNC_DISPLAY(widget), FALSE);
+-
+- n = 1 << (button->button - 1);
+- if (button->type == GDK_BUTTON_PRESS)
+- priv->button_mask |= n;
+- else if (button->type == GDK_BUTTON_RELEASE)
+- priv->button_mask &= ~n;
+-
+- if (priv->absolute) {
+- gvnc_pointer_event(priv->gvnc, priv->button_mask,
+- priv->last_x, priv->last_y);
+- } else {
+- gvnc_pointer_event(priv->gvnc, priv->button_mask,
+- 0x7FFF, 0x7FFF);
+- }
+-
+- return TRUE;
+-}
+-
+-static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll)
+-{
+- VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
+- int mask;
+-
+- if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
+- return FALSE;
+-
+- if (priv->read_only)
+- return FALSE;
+-
+- if (scroll->direction == GDK_SCROLL_UP)
+- mask = (1 << 3);
+- else if (scroll->direction == GDK_SCROLL_DOWN)
+- mask = (1 << 4);
+- else if (scroll->direction == GDK_SCROLL_LEFT)
+- mask = (1 << 5);
+- else if (scroll->direction == GDK_SCROLL_RIGHT)
+- mask = (1 << 6);
+- else
+- return FALSE;
+-
+- if (priv->absolute) {
+- gvnc_pointer_event(priv->gvnc, priv->button_mask | mask,
+- priv->last_x, priv->last_y);
+- gvnc_pointer_event(priv->gvnc, priv->button_mask,
+- priv->last_x, priv->last_y);
+- } else {
+- gvnc_pointer_event(priv->gvnc, priv->button_mask | mask,
+- 0x7FFF, 0x7FFF);
+- gvnc_pointer_event(priv->gvnc, priv->button_mask,
+- 0x7FFF, 0x7FFF);
+- }
+-
+- return TRUE;
+-}
+-
+-static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
+-{
+- VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
+- int dx, dy;
+-
+- if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
+- return FALSE;
+-
+- if (!priv->absolute && !priv->in_pointer_grab)
+- return FALSE;
+-
+- if (priv->read_only)
+- return FALSE;
+-
+-#if WITH_GTKGLEXT
+- if (priv->gl_enabled) {
+- motion->x *= priv->fb.width;
+- motion->x /= priv->gl_width;
+- motion->y *= priv->fb.height;
+- motion->y /= priv->gl_height;
+- } else
+-#endif
+- {
+- int ww, wh;
+- int mw = 0, mh = 0;
+-
+- gdk_drawable_get_size(widget->window, &ww, &wh);
+- if (ww > priv->fb.width)
+- mw = (ww - priv->fb.width) / 2;
+- if (wh > priv->fb.height)
+- mh = (wh - priv->fb.height) / 2;
+-
+- motion->x -= mw;
+- motion->y -= mh;
+-
+- if (motion->x < 0 || motion->x >= priv->fb.width ||
+- motion->y < 0 || motion->y >= priv->fb.height)
+- return FALSE;
+- }
+-
+- if (!priv->absolute && priv->in_pointer_grab) {
+- GdkDrawable *drawable = GDK_DRAWABLE(widget->window);
+- GdkDisplay *display = gdk_drawable_get_display(drawable);
+- GdkScreen *screen = gdk_drawable_get_screen(drawable);
+- int x = (int)motion->x_root;
+- int y = (int)motion->y_root;
+-
+- if (x == 0) x += 200;
+- if (y == 0) y += 200;
+- if (x == (gdk_screen_get_width(screen) - 1)) x -= 200;
+- if (y == (gdk_screen_get_height(screen) - 1)) y -= 200;
+-
+- if (x != (int)motion->x_root || y != (int)motion->y_root) {
+- gdk_display_warp_pointer(display, screen, x, y);
+- priv->last_x = -1;
+- priv->last_y = -1;
+- return FALSE;
+- }
+- }
+-
+- if (priv->last_x != -1) {
+- if (priv->absolute) {
+- dx = (int)motion->x;
+- dy = (int)motion->y;
+- } else {
+- dx = (int)motion->x + 0x7FFF - priv->last_x;
+- dy = (int)motion->y + 0x7FFF - priv->last_y;
+- }
+-
+- gvnc_pointer_event(priv->gvnc, priv->button_mask, dx, dy);
+- }
+-
+- priv->last_x = (int)motion->x;
+- priv->last_y = (int)motion->y;
+-
+- return TRUE;
+-}
+-
+-static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
+-{
+- VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
+- guint keyval;
+- gint group, level;
+- GdkModifierType consumed;
+-
+- if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
+- return FALSE;
+-
+- if (priv->read_only)
+- return FALSE;
+-
+- /*
+- * Key handling in VNC is screwy. The event.keyval from GTK is
+- * interpreted relative to modifier state. This really messes
+- * up with VNC which has no concept of modifiers - it just sees
+- * key up & down events - the remote end interprets modifiers
+- * itself. So if we interpret at the client end you can end up
+- * with 'Alt' key press generating Alt_L, and key release generating
+- * ISO_Prev_Group. This really really confuses the VNC server
+- * with 'Alt' getting stuck on.
+- *
+- * So we have to redo GTK's keycode -> keyval translation
+- * using only the SHIFT modifier which the RFB explicitly
+- * requires to be interpreted at client end.
+- *
+- * Arggggh.
+- */
+- gdk_keymap_translate_keyboard_state(gdk_keymap_get_default(),
+- key->hardware_keycode,
+- key->state & (GDK_SHIFT_MASK | GDK_LOCK_MASK),
+- key->group,
+- &keyval,
+- &group,
+- &level,
+- &consumed);
+-
+- keyval = x_keymap_get_keyval_from_keycode(key->hardware_keycode, keyval);
+-
+- /*
+- * More VNC suckiness with key state & modifiers in particular
+- *
+- * Because VNC has no concept of modifiers, we have to track what keys are
+- * pressed and when the widget looses focus send fake key up events for all
+- * keys current held down. This is because upon gaining focus any keys held
+- * down are no longer likely to be down. This would thus result in keys
+- * being 'stuck on' in the remote server. eg upon Alt-Tab to switch window
+- * focus you'd never see key up for the Alt or Tab keys without this :-(
+- *
+- * This is mostly a problem with modifier keys, but its best to just track
+- * all key presses regardless. There's a limit to how many keys a user can
+- * press at once due to a max of 10 fingers (normally :-), so down_key_vals
+- * is only storing upto 16 for now. Should be plenty...
+- *
+- * Arggggh.
+- */
+- if (key->type == GDK_KEY_PRESS) {
+- int i;
+- for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
+- if (priv->down_scancode[i] == 0) {
+- priv->down_keyval[i] = keyval;
+- priv->down_scancode[i] = key->hardware_keycode;
+- /* Send the actual key event we're dealing with */
+- gvnc_key_event(priv->gvnc, 1, keyval, key->hardware_keycode);
+- break;
+- } else if (priv->down_scancode[i] == key->hardware_keycode) {
+- /* Got an press when we're already pressed ! Why ... ?
+- *
+- * Well, GTK merges sequential press+release pairs of the same
+- * key so instead of press+release,press+release,press+release
+- * we only get press+press+press+press+press+release. This
+- * really annoys some VNC servers, so we have to un-merge
+- * them into a sensible stream of press+release pairs
+- */
+- /* Fake an up event for the previous down event */
+- gvnc_key_event(priv->gvnc, 0, keyval, key->hardware_keycode);
+- /* Now send our actual ldown event */
+- gvnc_key_event(priv->gvnc, 1, keyval, key->hardware_keycode);
+- break;
+- }
+- }
+- } else {
+- int i;
+- for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
+- /* We were pressed, and now we're released, so... */
+- if (priv->down_scancode[i] == key->hardware_keycode) {
+- priv->down_keyval[i] = 0;
+- priv->down_scancode[i] = 0;
+- /* ..send the key release event we're dealing with */
+- gvnc_key_event(priv->gvnc, 0, keyval, key->hardware_keycode);
+- break;
+- }
+- }
+- }
+-
+- if ((!priv->grab_keyboard || !priv->absolute) &&
+- key->type == GDK_KEY_PRESS &&
+- ((keyval == GDK_Control_L && (key->state & GDK_MOD1_MASK)) ||
+- (keyval == GDK_Alt_L && (key->state & GDK_CONTROL_MASK)))) {
+- if (priv->in_pointer_grab)
+- do_pointer_ungrab(VNC_DISPLAY(widget), FALSE);
+- else
+- do_pointer_grab(VNC_DISPLAY(widget), FALSE);
+- }
+-
+- return TRUE;
+-}
+-
+-static gboolean enter_event(GtkWidget *widget, GdkEventCrossing *crossing)
+-{
+- VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
+-
+- if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
+- return FALSE;
+-
+- if (crossing->mode != GDK_CROSSING_NORMAL)
+- return FALSE;
+-
+- if (priv->grab_keyboard)
+- do_keyboard_grab(VNC_DISPLAY(widget), FALSE);
+-
+- return TRUE;
+-}
+-
+-static gboolean leave_event(GtkWidget *widget, GdkEventCrossing *crossing)
+-{
+- VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
+-
+- if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
+- return FALSE;
+-
+- if (crossing->mode != GDK_CROSSING_NORMAL)
+- return FALSE;
+-
+- if (priv->grab_keyboard)
+- do_keyboard_ungrab(VNC_DISPLAY(widget), FALSE);
+-
+- if (priv->grab_pointer)
+- do_pointer_ungrab(VNC_DISPLAY(widget), FALSE);
+-
+- return TRUE;
+-}
+-
+-
+-static gboolean focus_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSED)
+-{
+- VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
+- int i;
+-
+- if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
+- return FALSE;
+-
+- for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
+- /* We are currently pressed so... */
+- if (priv->down_scancode[i] != 0) {
+- /* ..send the fake key release event to match */
+- gvnc_key_event(priv->gvnc, 0,
+- priv->down_keyval[i], priv->down_scancode[i]);
+- priv->down_keyval[i] = 0;
+- priv->down_scancode[i] = 0;
+- }
+- }
+-
+- return TRUE;
+-}
+-
+-#if WITH_GTKGLEXT
+-static void realize_event(GtkWidget *widget)
+-{
+- VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
+-
+- GTK_WIDGET_CLASS (vnc_display_parent_class)->realize(widget);
+-
+- if (priv->gl_config == NULL)
+- return;
+-
+- priv->gl_drawable = gtk_widget_get_gl_drawable(widget);
+- priv->gl_context = gtk_widget_get_gl_context(widget);
+-}
+-#endif
+-
+-static gboolean on_update(void *opaque, int x, int y, int w, int h)
+-{
+- GtkWidget *widget = GTK_WIDGET(opaque);
+- VncDisplay *obj = VNC_DISPLAY(widget);
+- VncDisplayPrivate *priv = obj->priv;
+-
+-#if WITH_GTKGLEXT
+- if (priv->gl_enabled) {
+- double scale_x, scale_y;
+-
+- scale_x = (double)priv->gl_width / priv->fb.width;
+- scale_y = (double)priv->gl_height / priv->fb.height;
+-
+- x *= scale_x;
+- y *= scale_y;
+- w *= scale_x;
+- h *= scale_y;
+- } else
+-#endif
+- {
+- int ww, wh;
+- int mw = 0, mh = 0;
+-
+- gdk_drawable_get_size(widget->window, &ww, &wh);
+- if (ww > priv->fb.width)
+- mw = (ww - priv->fb.width) / 2;
+- if (wh > priv->fb.height)
+- mh = (wh - priv->fb.height) / 2;
+-
+- x += mw;
+- y += mh;
+- }
+-
+- gtk_widget_queue_draw_area(widget, x, y, w, h);
+-
+- return TRUE;
+-}
+-
+-static void setup_gdk_image(VncDisplay *obj, gint width, gint height)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+- GdkVisual *visual;
+-
+- visual = gdk_drawable_get_visual(GTK_WIDGET(obj)->window);
+-
+- priv->image = gdk_image_new(GDK_IMAGE_FASTEST, visual, width, height);
+- GVNC_DEBUG("Visual mask: %3d %3d %3d\n shift: %3d %3d %3d\n",
+- visual->red_mask,
+- visual->green_mask,
+- visual->blue_mask,
+- visual->red_shift,
+- visual->green_shift,
+- visual->blue_shift);
+-
+- priv->fb.red_mask = visual->red_mask >> visual->red_shift;
+- priv->fb.green_mask = visual->green_mask >> visual->green_shift;
+- priv->fb.blue_mask = visual->blue_mask >> visual->blue_shift;
+- priv->fb.red_shift = visual->red_shift;
+- priv->fb.green_shift = visual->green_shift;
+- priv->fb.blue_shift = visual->blue_shift;
+- priv->fb.depth = priv->image->depth;
+- priv->fb.bpp = priv->image->bpp;
+- priv->fb.width = priv->image->width;
+- priv->fb.height = priv->image->height;
+- priv->fb.linesize = priv->image->bpl;
+- priv->fb.data = (uint8_t *)priv->image->mem;
+- priv->fb.byte_order = priv->image->byte_order == GDK_LSB_FIRST ? G_LITTLE_ENDIAN : G_BIG_ENDIAN;
+-
+- if (priv->force_size)
+- gtk_widget_set_size_request(GTK_WIDGET(obj), width, height);
+-}
+-
+-#if WITH_GTKGLEXT
+-static int pow_of_2(int value)
+-{
+- int i;
+- for (i = 0; value >= (1 << i); i++);
+- return (1 << i);
+-}
+-
+-static void setup_gl_image(VncDisplay *obj, gint width, gint height)
+-{
+- VncDisplayPrivate *priv = VNC_DISPLAY(obj)->priv;
+- void *dummy;
+-
+- priv->gl_texture_width = pow_of_2(width);
+- priv->gl_texture_height = pow_of_2(height);
+-
+- gdk_gl_drawable_gl_begin(priv->gl_drawable, priv->gl_context);
+-
+- glGenTextures(1, &priv->gl_tex);
+- glBindTexture(GL_TEXTURE_2D, priv->gl_tex);
+- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+-
+- dummy = g_malloc(priv->gl_texture_width*priv->gl_texture_height*4);
+- memset(dummy, 0, priv->gl_texture_width*priv->gl_texture_height*4);
+- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+- priv->gl_texture_width, priv->gl_texture_height, 0,
+- GL_RGB, GL_UNSIGNED_BYTE,
+- dummy);
+- g_free(dummy);
+-
+- gdk_gl_drawable_gl_end(priv->gl_drawable);
+-
+- priv->gl_tex_data = g_malloc(width * height * 4);
+-
+- priv->fb.red_mask = 0xFF;
+- priv->fb.green_mask = 0xFF;
+- priv->fb.blue_mask = 0xFF;
+- priv->fb.red_shift = 16;
+- priv->fb.green_shift = 8;
+- priv->fb.blue_shift = 0;
+- priv->fb.depth = 32;
+- priv->fb.bpp = 4;
+- priv->fb.width = width;
+- priv->fb.height = height;
+- priv->fb.linesize = priv->fb.width * priv->fb.bpp;
+- priv->fb.data = (uint8_t *)priv->gl_tex_data;
+-}
+-#endif
+-
+-static gboolean emit_signal_auth_cred(gpointer opaque)
+-{
+- struct signal_data *s = opaque;
+-
+- switch (s->signum) {
+- case VNC_AUTH_CREDENTIAL:
+- g_signal_emit(G_OBJECT(s->obj),
+- signals[VNC_AUTH_CREDENTIAL],
+- 0,
+- s->cred_list);
+- break;
+- case VNC_DESKTOP_RESIZE:
+- g_signal_emit(G_OBJECT(s->obj),
+- signals[VNC_DESKTOP_RESIZE],
+- 0,
+- s->width, s->height);
+- break;
+- case VNC_AUTH_FAILURE:
+- g_signal_emit(G_OBJECT(s->obj),
+- signals[VNC_AUTH_FAILURE],
+- 0,
+- s->msg);
+- break;
+- case VNC_AUTH_UNSUPPORTED:
+- g_signal_emit(G_OBJECT(s->obj),
+- signals[VNC_AUTH_UNSUPPORTED],
+- 0,
+- s->auth_type);
+- break;
+- case VNC_SERVER_CUT_TEXT:
+- g_signal_emit(G_OBJECT(s->obj),
+- signals[VNC_SERVER_CUT_TEXT],
+- 0,
+- s->str->str);
+- break;
+- case VNC_BELL:
+- case VNC_CONNECTED:
+- case VNC_INITIALIZED:
+- case VNC_DISCONNECTED:
+- g_signal_emit(G_OBJECT(s->obj),
+- signals[s->signum],
+- 0);
+- break;
+- }
+-
+- coroutine_yieldto(s->caller, NULL);
+-
+- return FALSE;
+-}
+-
+-/* This function should be used to emit signals from gvnc callbacks */
+-static void emit_signal_delayed(VncDisplay *obj, int signum,
+- struct signal_data *data)
+-{
+- data->obj = obj;
+- data->caller = coroutine_self();
+- data->signum = signum;
+- g_idle_add(emit_signal_auth_cred, data);
+- coroutine_yield(NULL);
+-}
+-
+-static gboolean do_resize(void *opaque, int width, int height, gboolean quiet)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- VncDisplayPrivate *priv = obj->priv;
+- struct signal_data s;
+-
+- if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
+- return TRUE;
+-
+- if (priv->image) {
+- g_object_unref(priv->image);
+- priv->image = NULL;
+- }
+-
+-#if WITH_GTKGLEXT
+- if (priv->gl_tex_data) {
+- gdk_gl_drawable_gl_begin(priv->gl_drawable,
+- priv->gl_context);
+- glDeleteTextures(1, &priv->gl_tex);
+- gdk_gl_drawable_gl_end(priv->gl_drawable);
+- g_free(priv->gl_tex_data);
+- priv->gl_tex_data = NULL;
+- }
+-#endif
+-
+- if (priv->gc == NULL) {
+- priv->null_cursor = create_null_cursor();
+- if (priv->local_pointer)
+- do_pointer_show(obj);
+- else if (priv->in_pointer_grab || priv->absolute)
+- do_pointer_hide(obj);
+- priv->gc = gdk_gc_new(GTK_WIDGET(obj)->window);
+- }
+-
+-#if WITH_GTKGLEXT
+- if (priv->gl_enabled)
+- setup_gl_image(obj, width, height);
+- else
+-#endif
+- setup_gdk_image(obj, width, height);
+-
+- gvnc_set_local(priv->gvnc, &priv->fb);
+-
+- if (!quiet) {
+- s.width = width;
+- s.height = height;
+- emit_signal_delayed(obj, VNC_DESKTOP_RESIZE, &s);
+- }
+-
+- return TRUE;
+-}
+-
+-static gboolean on_resize(void *opaque, int width, int height)
+-{
+- return do_resize(opaque, width, height, FALSE);
+-}
+-
+-static gboolean on_pixel_format(void *opaque,
+- struct gvnc_pixel_format *fmt G_GNUC_UNUSED)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- VncDisplayPrivate *priv = obj->priv;
+-
+- return do_resize(opaque, priv->fb.width, priv->fb.height, TRUE);
+-}
+-
+-static gboolean on_get_preferred_pixel_format(void *opaque,
+- struct gvnc_pixel_format *fmt)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- GdkVisual *v = gdk_drawable_get_visual(GTK_WIDGET(obj)->window);
+-
+- GVNC_DEBUG("Setting pixel format to true color\n");
+-
+- fmt->true_color_flag = 1;
+- fmt->depth = v->depth;
+- fmt->bits_per_pixel = v->depth > 16 ? 32 : v->depth;
+- fmt->red_max = v->red_mask >> v->red_shift;
+- fmt->green_max = v->green_mask >> v->green_shift;
+- fmt->blue_max = v->blue_mask >> v->blue_shift;
+- fmt->red_shift = v->red_shift;
+- fmt->green_shift = v->green_shift;
+- fmt->blue_shift = v->blue_shift;
+- fmt->byte_order = v->byte_order == GDK_LSB_FIRST ? G_BIG_ENDIAN : G_LITTLE_ENDIAN;
+-
+- return TRUE;
+-}
+-
+-#if WITH_GTKGLEXT
+-static void build_gl_image_from_gdk(uint32_t *data, GdkImage *image)
+-{
+- GdkVisual *visual;
+- int i, j;
+- uint8_t *row;
+-
+- visual = image->visual;
+- row = image->mem;
+- for (j = 0; j < image->height; j++) {
+- uint8_t *src = row;
+- for (i = 0; i < image->width; i++) {
+- uint32_t pixel = 0;
+- switch (image->bpp) {
+- case 1:
+- pixel = *(uint8_t *)src;
+- break;
+- case 2:
+- pixel = *(uint16_t *)src;
+- break;
+- case 4:
+- pixel = *(uint32_t *)src;
+- break;
+- }
+- *data = ((pixel & visual->red_mask) >> visual->red_shift) << (24 - visual->red_prec) |
+- ((pixel & visual->green_mask) >> visual->green_shift) << (16 - visual->green_prec) |
+- ((pixel & visual->blue_mask) >> visual->blue_shift) << (8 - visual->blue_prec);
+- src += image->bpp;
+- data++;
+- }
+- row += image->bpl;
+-
+- }
+-}
+-
+-static void build_gdk_image_from_gl(GdkImage *image, uint32_t *data)
+-{
+- GdkVisual *visual;
+- int i, j;
+- uint8_t *row;
+-
+- visual = image->visual;
+- row = image->mem;
+- for (j = 0; j < image->height; j++) {
+- uint8_t *dst = row;
+- for (i = 0; i < image->width; i++) {
+- uint32_t pixel;
+-
+- pixel = (((*data >> (24 - visual->red_prec)) << visual->red_shift) & visual->red_mask) |
+- (((*data >> (16 - visual->green_prec)) << visual->green_shift) & visual->green_mask) |
+- (((*data >> (8 - visual->blue_prec)) << visual->blue_shift) & visual->blue_mask);
+-
+- switch (image->bpp) {
+- case 1:
+- *(uint8_t *)dst = pixel;
+- break;
+- case 2:
+- *(uint16_t *)dst = pixel;
+- break;
+- case 4:
+- *(uint32_t *)dst = pixel;
+- break;
+- }
+- dst += image->bpp;
+- data++;
+- }
+- row += image->bpl;
+- }
+-}
+-
+-static void scale_display(VncDisplay *obj, gint width, gint height)
+-{
+- VncDisplayPrivate *priv = VNC_DISPLAY(obj)->priv;
+-
+- if (priv->gl_drawable == NULL)
+- return;
+-
+- if (priv->gl_enabled == 0) {
+- GdkImage *image;
+-
+- priv->gl_enabled = 1;
+-
+- image = priv->image;
+- priv->image = NULL;
+-
+- do_resize(obj, priv->fb.width, priv->fb.height, TRUE);
+- build_gl_image_from_gdk((uint32_t *)priv->fb.data, image);
+-
+- g_object_unref(image);
+- }
+-
+- priv->gl_width = width;
+- priv->gl_height = height;
+-
+- gdk_gl_drawable_gl_begin(priv->gl_drawable, priv->gl_context);
+- glClearColor (0.0, 0.0, 0.0, 0.0);
+- glShadeModel(GL_FLAT);
+- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+-
+- glViewport(0, 0, priv->gl_width, priv->gl_height);
+- glMatrixMode(GL_PROJECTION);
+- glLoadIdentity();
+- glOrtho(0.0, priv->gl_width, 0.0, priv->gl_height, -1, 1);
+- glMatrixMode(GL_MODELVIEW);
+- glLoadIdentity();
+- gdk_gl_drawable_gl_end(priv->gl_drawable);
+-}
+-
+-static void rescale_display(VncDisplay *obj, gint width, gint height)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+-
+- if (priv->allow_scaling &&
+- (priv->fb.width != width ||
+- priv->fb.height != height))
+- scale_display(obj, width, height);
+- else if (priv->gl_enabled) {
+- void *data;
+- priv->gl_enabled = 0;
+-
+- data = priv->gl_tex_data;
+- priv->gl_tex_data = NULL;
+-
+- do_resize(GTK_WIDGET(obj), priv->fb.width, priv->fb.height, TRUE);
+-
+- build_gdk_image_from_gl(priv->image, (uint32_t *)data);
+- gdk_gl_drawable_gl_begin(priv->gl_drawable,
+- priv->gl_context);
+- glDeleteTextures(1, &priv->gl_tex);
+- gdk_gl_drawable_gl_end(priv->gl_drawable);
+- g_free(data);
+- }
+-}
+-
+-static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *configure)
+-{
+- VncDisplay *obj = VNC_DISPLAY(widget);
+- VncDisplayPrivate *priv = obj->priv;
+-
+- if (priv->fb.data == NULL)
+- return FALSE;
+-
+- rescale_display(VNC_DISPLAY(widget),
+- configure->width, configure->height);
+-
+- return FALSE;
+-}
+-#endif
+-
+-static gboolean on_pointer_type_change(void *opaque, int absolute)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- VncDisplayPrivate *priv = obj->priv;
+-
+- if (absolute && priv->in_pointer_grab && !priv->grab_pointer)
+- do_pointer_ungrab(obj, FALSE);
+-
+- priv->absolute = absolute;
+-
+- if (!priv->in_pointer_grab && !priv->absolute)
+- do_pointer_show(obj);
+-
+- return TRUE;
+-}
+-
+-static gboolean on_auth_cred(void *opaque)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- GValueArray *cred_list;
+- GValue username, password, clientname;
+- struct signal_data s;
+-
+- memset(&username, 0, sizeof(username));
+- memset(&password, 0, sizeof(password));
+- memset(&clientname, 0, sizeof(clientname));
+-
+- cred_list = g_value_array_new(0);
+- if (gvnc_wants_credential_username(obj->priv->gvnc)) {
+- g_value_init(&username, G_PARAM_SPEC_VALUE_TYPE(signalCredParam));
+- g_value_set_enum(&username, VNC_DISPLAY_CREDENTIAL_USERNAME);
+- cred_list = g_value_array_append(cred_list, &username);
+- }
+- if (gvnc_wants_credential_password(obj->priv->gvnc)) {
+- g_value_init(&password, G_PARAM_SPEC_VALUE_TYPE(signalCredParam));
+- g_value_set_enum(&password, VNC_DISPLAY_CREDENTIAL_PASSWORD);
+- cred_list = g_value_array_append(cred_list, &password);
+- }
+- if (gvnc_wants_credential_x509(obj->priv->gvnc)) {
+- g_value_init(&clientname, G_PARAM_SPEC_VALUE_TYPE(signalCredParam));
+- g_value_set_enum(&clientname, VNC_DISPLAY_CREDENTIAL_CLIENTNAME);
+- cred_list = g_value_array_append(cred_list, &clientname);
+- }
+-
+- s.cred_list = cred_list;
+- emit_signal_delayed(obj, VNC_AUTH_CREDENTIAL, &s);
+-
+- g_value_array_free(cred_list);
+-
+- return TRUE;
+-}
+-
+-static gboolean on_auth_type(void *opaque, unsigned int ntype, unsigned int *types)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- VncDisplayPrivate *priv = obj->priv;
+- GSList *l;
+- guint i;
+-
+- if (!ntype)
+- return TRUE;
+-
+- for (l = priv->preferable_auths; l; l=l->next) {
+- gvnc_auth pref = GPOINTER_TO_UINT (l->data);
+-
+- for (i=0; i<ntype; i++) {
+- if (pref == types[i]) {
+- gvnc_set_auth_type(priv->gvnc, types[i]);
+- return TRUE;
+- }
+- }
+- }
+-
+- gvnc_set_auth_type(priv->gvnc, types[0]);
+- return TRUE;
+-}
+-
+-static gboolean on_auth_subtype(void *opaque, unsigned int ntype, unsigned int *types)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- VncDisplayPrivate *priv = obj->priv;
+-
+- GSList *l;
+- guint i;
+-
+- if (!ntype)
+- return TRUE;
+-
+- for (l = priv->preferable_auths; l; l=l->next) {
+- gvnc_auth pref = GPOINTER_TO_UINT (l->data);
+-
+- for (i=0; i<ntype; i++) {
+- if (pref == types[i]) {
+- gvnc_set_auth_subtype(priv->gvnc, types[i]);
+- return TRUE;
+- }
+- }
+- }
+-
+- gvnc_set_auth_subtype(priv->gvnc, types[0]);
+- return TRUE;
+-}
+-
+-static gboolean on_auth_failure(void *opaque, const char *msg)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- struct signal_data s;
+-
+- s.msg = msg;
+- emit_signal_delayed(obj, VNC_AUTH_FAILURE, &s);
+-
+- return TRUE;
+-}
+-
+-static gboolean on_auth_unsupported(void *opaque, unsigned int auth_type)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- struct signal_data s;
+-
+- s.auth_type = auth_type;
+- emit_signal_delayed(obj, VNC_AUTH_UNSUPPORTED, &s);
+-
+- return TRUE;
+-}
+-
+-static gboolean on_server_cut_text(void *opaque, const void* text, size_t len)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- GString *str = g_string_new_len ((const gchar *)text, len);
+- struct signal_data s;
+-
+- s.str = str;
+- emit_signal_delayed(obj, VNC_SERVER_CUT_TEXT, &s);
+-
+- g_string_free (str, TRUE);
+- return TRUE;
+-}
+-
+-static gboolean on_bell(void *opaque)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- struct signal_data s;
+-
+- emit_signal_delayed(obj, VNC_BELL, &s);
+-
+- return TRUE;
+-}
+-
+-static gboolean on_local_cursor(void *opaque, int x, int y, int width, int height, uint8_t *image)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- VncDisplayPrivate *priv = obj->priv;
+-
+- if (priv->remote_cursor) {
+- gdk_cursor_unref(priv->remote_cursor);
+- priv->remote_cursor = NULL;
+- }
+-
+- if (width && height) {
+- GdkDisplay *display = gdk_drawable_get_display(GDK_DRAWABLE(GTK_WIDGET(obj)->window));
+- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(image, GDK_COLORSPACE_RGB,
+- TRUE, 8, width, height,
+- width * 4, NULL, NULL);
+- priv->remote_cursor = gdk_cursor_new_from_pixbuf(display,
+- pixbuf,
+- x, y);
+- gdk_pixbuf_unref(pixbuf);
+- }
+-
+- if (priv->in_pointer_grab) {
+- do_pointer_ungrab(obj, TRUE);
+- do_pointer_grab(obj, TRUE);
+- } else if (priv->absolute) {
+- do_pointer_hide(obj);
+- }
+-
+- return TRUE;
+-}
+-
+-static gboolean check_pixbuf_support(const char *name)
+-{
+- GSList *list, *i;
+-
+- list = gdk_pixbuf_get_formats();
+-
+- for (i = list; i; i = i->next) {
+- GdkPixbufFormat *fmt = i->data;
+- if (!strcmp(gdk_pixbuf_format_get_name(fmt), name))
+- break;
+- }
+-
+- g_slist_free(list);
+-
+- return !!(i);
+-}
+-
+-static gboolean on_render_jpeg(void *opaque G_GNUC_UNUSED,
+- rgb24_render_func *render, void *render_opaque,
+- int x, int y, int w, int h,
+- uint8_t *data, int size)
+-{
+- GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
+- GdkPixbuf *p;
+- uint8_t *pixels;
+-
+- if (!gdk_pixbuf_loader_write(loader, data, size, NULL))
+- return FALSE;
+-
+- gdk_pixbuf_loader_close(loader, NULL);
+-
+- p = g_object_ref(gdk_pixbuf_loader_get_pixbuf(loader));
+- g_object_unref(loader);
+-
+- pixels = gdk_pixbuf_get_pixels(p);
+-
+- render(render_opaque, x, y, w, h,
+- gdk_pixbuf_get_pixels(p),
+- gdk_pixbuf_get_rowstride(p));
+-
+- gdk_pixbuf_unref(p);
+-
+- return TRUE;
+-}
+-
+-static const struct gvnc_ops vnc_display_ops = {
+- .auth_cred = on_auth_cred,
+- .auth_type = on_auth_type,
+- .auth_subtype = on_auth_subtype,
+- .auth_failure = on_auth_failure,
+- .update = on_update,
+- .resize = on_resize,
+- .pixel_format = on_pixel_format,
+- .pointer_type_change = on_pointer_type_change,
+- .local_cursor = on_local_cursor,
+- .auth_unsupported = on_auth_unsupported,
+- .server_cut_text = on_server_cut_text,
+- .bell = on_bell,
+- .render_jpeg = on_render_jpeg,
+- .get_preferred_pixel_format = on_get_preferred_pixel_format
+-};
+-
+-/* we use an idle function to allow the coroutine to exit before we actually
+- * unref the object since the coroutine's state is part of the object */
+-static gboolean delayed_unref_object(gpointer data)
+-{
+- VncDisplay *obj = VNC_DISPLAY(data);
+-
+- g_assert(obj->priv->coroutine.exited == TRUE);
+-
+- if (obj->priv->image) {
+- g_object_unref(obj->priv->image);
+- obj->priv->image = NULL;
+- }
+-
+-#if WITH_GTKGLEXT
+- if (obj->priv->gl_tex_data)
+- g_free(obj->priv->gl_tex_data);
+- obj->priv->gl_tex_data = NULL;
+- obj->priv->gl_enabled = 0;
+-#endif
+-
+- g_object_unref(G_OBJECT(data));
+- return FALSE;
+-}
+-
+-static void *vnc_coroutine(void *opaque)
+-{
+- VncDisplay *obj = VNC_DISPLAY(opaque);
+- VncDisplayPrivate *priv = obj->priv;
+-
+- /* this order is extremely important! */
+- int32_t encodings[] = { GVNC_ENCODING_TIGHT_JPEG5,
+- GVNC_ENCODING_TIGHT,
+- GVNC_ENCODING_EXT_KEY_EVENT,
+- GVNC_ENCODING_DESKTOP_RESIZE,
+- GVNC_ENCODING_WMVi,
+- GVNC_ENCODING_RICH_CURSOR,
+- GVNC_ENCODING_XCURSOR,
+- GVNC_ENCODING_POINTER_CHANGE,
+- GVNC_ENCODING_ZRLE,
+- GVNC_ENCODING_HEXTILE,
+- GVNC_ENCODING_RRE,
+- GVNC_ENCODING_COPY_RECT,
+- GVNC_ENCODING_RAW };
+- int32_t *encodingsp;
+- int n_encodings;
+- int ret;
+- struct signal_data s;
+-
+- if (priv->gvnc == NULL || gvnc_is_open(priv->gvnc)) {
+- g_idle_add(delayed_unref_object, obj);
+- return NULL;
+- }
+-
+- GVNC_DEBUG("Started background coroutine\n");
+- x_keymap_set_keymap_entries();
+-
+- if (priv->fd != -1) {
+- if (!gvnc_open_fd(priv->gvnc, priv->fd))
+- goto cleanup;
+- } else {
+- if (!gvnc_open_host(priv->gvnc, priv->host, priv->port))
+- goto cleanup;
+- }
+-
+- emit_signal_delayed(obj, VNC_CONNECTED, &s);
+-
+- GVNC_DEBUG("Protocol initialization\n");
+- if (!gvnc_initialize(priv->gvnc, priv->shared_flag))
+- goto cleanup;
+-
+- emit_signal_delayed(obj, VNC_INITIALIZED, &s);
+-
+- encodingsp = encodings;
+- n_encodings = G_N_ELEMENTS(encodings);
+-
+- if (check_pixbuf_support("jpeg")) {
+- if (!priv->allow_lossy) {
+- encodingsp++;
+- n_encodings--;
+- }
+- } else {
+- encodingsp += 2;
+- n_encodings -= 2;
+- }
+-
+- if (!gvnc_set_encodings(priv->gvnc, n_encodings, encodingsp))
+- goto cleanup;
+-
+- if (!gvnc_framebuffer_update_request(priv->gvnc, 0, 0, 0, priv->fb.width, priv->fb.height))
+- goto cleanup;
+-
+- GVNC_DEBUG("Running main loop\n");
+- while ((ret = gvnc_server_message(priv->gvnc))) {
+- if (!gvnc_framebuffer_update_request(priv->gvnc, 1, 0, 0,
+- priv->fb.width, priv->fb.height))
+- goto cleanup;
+- }
+-
+- cleanup:
+- GVNC_DEBUG("Doing final VNC cleanup\n");
+- gvnc_close(priv->gvnc);
+- emit_signal_delayed(obj, VNC_DISCONNECTED, &s);
+- g_idle_add(delayed_unref_object, obj);
+- x_keymap_free_keymap_entries();
+- /* Co-routine exits now - the VncDisplay object may no longer exist,
+- so don't do anything else now unless you like SEGVs */
+- return NULL;
+-}
+-
+-static gboolean do_vnc_display_open(gpointer data)
+-{
+- VncDisplay *obj = VNC_DISPLAY(data);
+- struct coroutine *co;
+-
+- if (obj->priv->gvnc == NULL || gvnc_is_open(obj->priv->gvnc)) {
+- g_object_unref(G_OBJECT(obj));
+- return FALSE;
+- }
+-
+- obj->priv->open_id = 0;
+-
+- co = &obj->priv->coroutine;
+-
+- co->stack_size = 16 << 20;
+- co->entry = vnc_coroutine;
+- co->release = NULL;
+-
+- coroutine_init(co);
+- coroutine_yieldto(co, obj);
+-
+- return FALSE;
+-}
+-
+-gboolean vnc_display_open_fd(VncDisplay *obj, int fd)
+-{
+- if (obj->priv->gvnc == NULL || gvnc_is_open(obj->priv->gvnc))
+- return FALSE;
+-
+- obj->priv->fd = fd;
+- obj->priv->host = NULL;
+- obj->priv->port = NULL;
+-
+- g_object_ref(G_OBJECT(obj)); /* Unref'd when co-routine exits */
+- obj->priv->open_id = g_idle_add(do_vnc_display_open, obj);
+-
+- return TRUE;
+-}
+-
+-gboolean vnc_display_open_host(VncDisplay *obj, const char *host, const char *port)
+-{
+- if (obj->priv->gvnc == NULL || gvnc_is_open(obj->priv->gvnc))
+- return FALSE;
+-
+- obj->priv->host = g_strdup(host);
+- if (!obj->priv->host) {
+- return FALSE;
+- }
+- obj->priv->port = g_strdup(port);
+- if (!obj->priv->port) {
+- g_free(obj->priv->host);
+- obj->priv->host = NULL;
+- return FALSE;
+- }
+-
+- g_object_ref(G_OBJECT(obj)); /* Unref'd when co-routine exits */
+- obj->priv->open_id = g_idle_add(do_vnc_display_open, obj);
+- return TRUE;
+-}
+-
+-gboolean vnc_display_is_open(VncDisplay *obj)
+-{
+- if (obj->priv->gvnc == NULL)
+- return FALSE;
+- return gvnc_is_open(obj->priv->gvnc);
+-}
+-
+-void vnc_display_close(VncDisplay *obj)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+- GtkWidget *widget = GTK_WIDGET(obj);
+-
+- if (priv->open_id) {
+- g_source_remove(priv->open_id);
+- obj->priv->open_id = 0;
+- }
+-
+- if (priv->gvnc == NULL)
+- return;
+-
+- if (gvnc_is_open(priv->gvnc)) {
+- GVNC_DEBUG("Requesting graceful shutdown of connection\n");
+- gvnc_shutdown(priv->gvnc);
+- }
+-
+-#if WITH_GTKGLEXT
+- if (priv->gl_tex_data) {
+- gdk_gl_drawable_gl_begin(priv->gl_drawable,
+- priv->gl_context);
+- glDeleteTextures(1, &priv->gl_tex);
+- gdk_gl_drawable_gl_end(priv->gl_drawable);
+- }
+-#endif
+-
+- if (widget->window) {
+- gint width, height;
+-
+- gdk_drawable_get_size(widget->window, &width, &height);
+- gtk_widget_queue_draw_area(widget, 0, 0, width, height);
+- }
+-}
+-
+-
+-void vnc_display_send_keys(VncDisplay *obj, const guint *keyvals, int nkeyvals)
+-{
+- vnc_display_send_keys_ex(obj, keyvals,
+- nkeyvals, VNC_DISPLAY_KEY_EVENT_CLICK);
+-}
+-
+-static guint get_keycode_from_keyval(guint keyval)
+-{
+- guint keycode = 0;
+- GdkKeymapKey *keys = NULL;
+- gint n_keys = 0;
+-
+- if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(),
+- keyval, &keys, &n_keys)) {
+- /* FIXME what about levels? */
+- keycode = keys[0].keycode;
+- g_free(keys);
+- }
+-
+- return keycode;
+-}
+-
+-void vnc_display_send_keys_ex(VncDisplay *obj, const guint *keyvals,
+- int nkeyvals, VncDisplayKeyEvent kind)
+-{
+- int i;
+-
+- if (obj->priv->gvnc == NULL || !gvnc_is_open(obj->priv->gvnc))
+- return;
+-
+- if (kind & VNC_DISPLAY_KEY_EVENT_PRESS) {
+- for (i = 0 ; i < nkeyvals ; i++)
+- gvnc_key_event(obj->priv->gvnc, 1, keyvals[i],
+- get_keycode_from_keyval(keyvals[i]));
+- }
+-
+- if (kind & VNC_DISPLAY_KEY_EVENT_RELEASE) {
+- for (i = (nkeyvals-1) ; i >= 0 ; i--)
+- gvnc_key_event(obj->priv->gvnc, 0, keyvals[i],
+- get_keycode_from_keyval(keyvals[i]));
+- }
+-}
+-
+-void vnc_display_send_pointer(VncDisplay *obj, gint x, gint y, int button_mask)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+-
+- if (priv->gvnc == NULL || !gvnc_is_open(obj->priv->gvnc))
+- return;
+-
+- if (priv->absolute) {
+- priv->button_mask = button_mask;
+- priv->last_x = x;
+- priv->last_y = y;
+- gvnc_pointer_event(priv->gvnc, priv->button_mask, x, y);
+- }
+-}
+-
+-static void vnc_display_destroy (GtkObject *obj)
+-{
+- VncDisplay *display = VNC_DISPLAY (obj);
+- GVNC_DEBUG("Requesting that VNC close\n");
+- vnc_display_close(display);
+- GTK_OBJECT_CLASS (vnc_display_parent_class)->destroy (obj);
+-}
+-
+-
+-static void vnc_display_finalize (GObject *obj)
+-{
+- VncDisplay *display = VNC_DISPLAY (obj);
+- VncDisplayPrivate *priv = display->priv;
+-
+- GVNC_DEBUG("Releasing VNC widget\n");
+- if (gvnc_is_open(priv->gvnc)) {
+- g_warning("VNC widget finalized before the connection finished shutting down\n");
+- }
+- gvnc_free(priv->gvnc);
+- display->priv->gvnc = NULL;
+-
+-#if WITH_GTKGLEXT
+- if (priv->gl_enabled) {
+- gdk_gl_drawable_gl_begin(priv->gl_drawable,
+- priv->gl_context);
+- glDeleteTextures(1, &priv->gl_tex);
+- gdk_gl_drawable_gl_end(priv->gl_drawable);
+- if (priv->gl_tex_data) {
+- g_free(priv->gl_tex_data);
+- priv->gl_tex_data = NULL;
+- }
+- }
+-
+- if (priv->gl_config) {
+- g_object_unref(G_OBJECT(priv->gl_config));
+- priv->gl_config = NULL;
+- }
+-#endif
+-
+- if (priv->image) {
+- g_object_unref(priv->image);
+- priv->image = NULL;
+- }
+-
+- g_slist_free (priv->preferable_auths);
+-
+- G_OBJECT_CLASS (vnc_display_parent_class)->finalize (obj);
+-}
+-
+-static void vnc_display_class_init(VncDisplayClass *klass)
+-{
+- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+- GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
+- GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
+-
+- gtkwidget_class->expose_event = expose_event;
+- gtkwidget_class->motion_notify_event = motion_event;
+- gtkwidget_class->button_press_event = button_event;
+- gtkwidget_class->button_release_event = button_event;
+- gtkwidget_class->scroll_event = scroll_event;
+- gtkwidget_class->key_press_event = key_event;
+- gtkwidget_class->key_release_event = key_event;
+- gtkwidget_class->enter_notify_event = enter_event;
+- gtkwidget_class->leave_notify_event = leave_event;
+- gtkwidget_class->focus_out_event = focus_event;
+-#if WITH_GTKGLEXT
+- gtkwidget_class->realize = realize_event;
+- gtkwidget_class->configure_event = configure_event;
+-#endif
+-
+-
+- object_class->finalize = vnc_display_finalize;
+- object_class->get_property = vnc_display_get_property;
+- object_class->set_property = vnc_display_set_property;
+-
+- gtkobject_class->destroy = vnc_display_destroy;
+-
+- g_object_class_install_property (object_class,
+- PROP_POINTER_LOCAL,
+- g_param_spec_boolean ( "local-pointer",
+- "Local Pointer",
+- "Whether we should use the local pointer",
+- FALSE,
+- G_PARAM_READWRITE |
+- G_PARAM_CONSTRUCT |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+- g_object_class_install_property (object_class,
+- PROP_POINTER_GRAB,
+- g_param_spec_boolean ( "grab-pointer",
+- "Grab Pointer",
+- "Whether we should grab the pointer",
+- FALSE,
+- G_PARAM_READWRITE |
+- G_PARAM_CONSTRUCT |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+- g_object_class_install_property (object_class,
+- PROP_KEYBOARD_GRAB,
+- g_param_spec_boolean ( "grab-keyboard",
+- "Grab Keyboard",
+- "Whether we should grab the keyboard",
+- FALSE,
+- G_PARAM_READWRITE |
+- G_PARAM_CONSTRUCT |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+- g_object_class_install_property (object_class,
+- PROP_READ_ONLY,
+- g_param_spec_boolean ( "read-only",
+- "Read Only",
+- "Whether this connection is read-only mode",
+- FALSE,
+- G_PARAM_READWRITE |
+- G_PARAM_CONSTRUCT |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+- g_object_class_install_property (object_class,
+- PROP_WIDTH,
+- g_param_spec_int ( "width",
+- "Width",
+- "The width of the remote screen",
+- 0,
+- G_MAXINT,
+- 0,
+- G_PARAM_READABLE |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+- g_object_class_install_property (object_class,
+- PROP_HEIGHT,
+- g_param_spec_int ( "height",
+- "Height",
+- "The height of the remote screen",
+- 0,
+- G_MAXINT,
+- 0,
+- G_PARAM_READABLE |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+- g_object_class_install_property (object_class,
+- PROP_NAME,
+- g_param_spec_string ( "name",
+- "Name",
+- "The screen name of the remote connection",
+- NULL,
+- G_PARAM_READABLE |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+- g_object_class_install_property (object_class,
+- PROP_LOSSY_ENCODING,
+- g_param_spec_boolean ( "lossy-encoding",
+- "Lossy Encoding",
+- "Whether we should use a lossy encoding",
+- FALSE,
+- G_PARAM_READWRITE |
+- G_PARAM_CONSTRUCT |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+- g_object_class_install_property (object_class,
+- PROP_SCALING,
+- g_param_spec_boolean ( "scaling",
+- "Scaling",
+- "Whether we should use scaling",
+- FALSE,
+- G_PARAM_READWRITE |
+- G_PARAM_CONSTRUCT |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+- g_object_class_install_property (object_class,
+- PROP_SHARED_FLAG,
+- g_param_spec_boolean ( "shared-flag",
+- "Shared Flag",
+- "Whether we should leave other clients connected to the server",
+- FALSE,
+- G_PARAM_READWRITE |
+- G_PARAM_CONSTRUCT |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+- g_object_class_install_property (object_class,
+- PROP_FORCE_SIZE,
+- g_param_spec_boolean ( "force-size",
+- "Force widget size",
+- "Whether we should define the widget size",
+- TRUE,
+- G_PARAM_READWRITE |
+- G_PARAM_CONSTRUCT |
+- G_PARAM_STATIC_NAME |
+- G_PARAM_STATIC_NICK |
+- G_PARAM_STATIC_BLURB));
+-
+- signalCredParam = g_param_spec_enum("credential",
+- "credential",
+- "credential",
+- vnc_display_credential_get_type(),
+- 0,
+- G_PARAM_READABLE);
+-
+- signals[VNC_CONNECTED] =
+- g_signal_new ("vnc-connected",
+- G_OBJECT_CLASS_TYPE (object_class),
+- G_SIGNAL_RUN_FIRST,
+- G_STRUCT_OFFSET (VncDisplayClass, vnc_connected),
+- NULL, NULL,
+- g_cclosure_marshal_VOID__VOID,
+- G_TYPE_NONE,
+- 0);
+-
+- signals[VNC_INITIALIZED] =
+- g_signal_new ("vnc-initialized",
+- G_OBJECT_CLASS_TYPE (object_class),
+- G_SIGNAL_RUN_FIRST,
+- G_STRUCT_OFFSET (VncDisplayClass, vnc_initialized),
+- NULL, NULL,
+- g_cclosure_marshal_VOID__VOID,
+- G_TYPE_NONE,
+- 0);
+-
+- signals[VNC_DISCONNECTED] =
+- g_signal_new ("vnc-disconnected",
+- G_OBJECT_CLASS_TYPE (object_class),
+- G_SIGNAL_RUN_FIRST,
+- G_STRUCT_OFFSET (VncDisplayClass, vnc_disconnected),
+- NULL, NULL,
+- g_cclosure_marshal_VOID__VOID,
+- G_TYPE_NONE,
+- 0);
+-
+- signals[VNC_AUTH_CREDENTIAL] =
+- g_signal_new ("vnc-auth-credential",
+- G_OBJECT_CLASS_TYPE (object_class),
+- G_SIGNAL_RUN_FIRST,
+- G_STRUCT_OFFSET (VncDisplayClass, vnc_auth_credential),
+- NULL, NULL,
+- g_cclosure_marshal_VOID__BOXED,
+- G_TYPE_NONE,
+- 1,
+- G_TYPE_VALUE_ARRAY);
+-
+-
+- signals[VNC_POINTER_GRAB] =
+- g_signal_new("vnc-pointer-grab",
+- G_TYPE_FROM_CLASS(klass),
+- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+- 0,
+- NULL,
+- NULL,
+- g_cclosure_marshal_VOID__VOID,
+- G_TYPE_NONE,
+- 0);
+-
+- signals[VNC_POINTER_UNGRAB] =
+- g_signal_new("vnc-pointer-ungrab",
+- G_TYPE_FROM_CLASS(klass),
+- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+- 0,
+- NULL,
+- NULL,
+- g_cclosure_marshal_VOID__VOID,
+- G_TYPE_NONE,
+- 0);
+-
+- signals[VNC_KEYBOARD_GRAB] =
+- g_signal_new("vnc-keyboard-grab",
+- G_TYPE_FROM_CLASS(klass),
+- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+- 0,
+- NULL,
+- NULL,
+- g_cclosure_marshal_VOID__VOID,
+- G_TYPE_NONE,
+- 0);
+-
+- signals[VNC_KEYBOARD_UNGRAB] =
+- g_signal_new("vnc-keyboard-ungrab",
+- G_TYPE_FROM_CLASS(klass),
+- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+- 0,
+- NULL,
+- NULL,
+- g_cclosure_marshal_VOID__VOID,
+- G_TYPE_NONE,
+- 0);
+-
+-
+- signals[VNC_DESKTOP_RESIZE] =
+- g_signal_new("vnc-desktop-resize",
+- G_TYPE_FROM_CLASS(klass),
+- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+- 0,
+- NULL,
+- NULL,
+- g_cclosure_user_marshal_VOID__INT_INT,
+- G_TYPE_NONE,
+- 2,
+- G_TYPE_INT, G_TYPE_INT);
+-
+- signals[VNC_AUTH_FAILURE] =
+- g_signal_new("vnc-auth-failure",
+- G_TYPE_FROM_CLASS(klass),
+- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+- 0,
+- NULL,
+- NULL,
+- g_cclosure_marshal_VOID__STRING,
+- G_TYPE_NONE,
+- 1,
+- G_TYPE_STRING);
+-
+- signals[VNC_AUTH_UNSUPPORTED] =
+- g_signal_new("vnc-auth-unsupported",
+- G_TYPE_FROM_CLASS(klass),
+- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+- 0,
+- NULL,
+- NULL,
+- g_cclosure_marshal_VOID__UINT,
+- G_TYPE_NONE,
+- 1,
+- G_TYPE_UINT);
+-
+- signals[VNC_SERVER_CUT_TEXT] =
+- g_signal_new("vnc-server-cut-text",
+- G_TYPE_FROM_CLASS(klass),
+- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+- 0,
+- NULL,
+- NULL,
+- g_cclosure_marshal_VOID__STRING,
+- G_TYPE_NONE,
+- 1,
+- G_TYPE_STRING);
+-
+- signals[VNC_BELL] =
+- g_signal_new("vnc-bell",
+- G_TYPE_FROM_CLASS(klass),
+- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+- 0,
+- NULL,
+- NULL,
+- g_cclosure_marshal_VOID__VOID,
+- G_TYPE_NONE,
+- 0);
+-
+- g_type_class_add_private(klass, sizeof(VncDisplayPrivate));
+-}
+-
+-static void vnc_display_init(VncDisplay *display)
+-{
+- GtkObject *obj = GTK_OBJECT(display);
+- GtkWidget *widget = GTK_WIDGET(display);
+- VncDisplayPrivate *priv;
+-
+- GTK_WIDGET_SET_FLAGS(obj, GTK_CAN_FOCUS);
+-
+- gtk_widget_add_events(widget,
+- GDK_POINTER_MOTION_MASK |
+- GDK_BUTTON_PRESS_MASK |
+- GDK_BUTTON_RELEASE_MASK |
+- GDK_BUTTON_MOTION_MASK |
+- GDK_ENTER_NOTIFY_MASK |
+- GDK_LEAVE_NOTIFY_MASK |
+- GDK_SCROLL_MASK |
+- GDK_KEY_PRESS_MASK);
+- gtk_widget_set_double_buffered(widget, FALSE);
+-
+- priv = display->priv = VNC_DISPLAY_GET_PRIVATE(display);
+- memset(priv, 0, sizeof(VncDisplayPrivate));
+- priv->last_x = -1;
+- priv->last_y = -1;
+- priv->absolute = 1;
+- priv->fd = -1;
+- priv->read_only = FALSE;
+- priv->allow_lossy = FALSE;
+- priv->allow_scaling = FALSE;
+- priv->grab_pointer = FALSE;
+- priv->grab_keyboard = FALSE;
+- priv->local_pointer = FALSE;
+- priv->shared_flag = FALSE;
+- priv->force_size = TRUE;
+-
+- priv->preferable_auths = g_slist_append (priv->preferable_auths, GUINT_TO_POINTER (GVNC_AUTH_VENCRYPT));
+- priv->preferable_auths = g_slist_append (priv->preferable_auths, GUINT_TO_POINTER (GVNC_AUTH_TLS));
+- priv->preferable_auths = g_slist_append (priv->preferable_auths, GUINT_TO_POINTER (GVNC_AUTH_VNC));
+- priv->preferable_auths = g_slist_append (priv->preferable_auths, GUINT_TO_POINTER (GVNC_AUTH_NONE));
+-
+-#if WITH_GTKGLEXT
+- if (gtk_gl_init_check(NULL, NULL)) {
+- priv->gl_config = gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB |
+- GDK_GL_MODE_DEPTH);
+- if (!gtk_widget_set_gl_capability(widget,
+- priv->gl_config,
+- NULL,
+- TRUE,
+- GDK_GL_RGBA_TYPE)) {
+- g_warning("Could not enable OpenGL");
+- g_object_unref(G_OBJECT(priv->gl_config));
+- priv->gl_config = NULL;
+- }
+- } else
+- priv->gl_config = NULL;
+-#endif
+-
+- priv->gvnc = gvnc_new(&vnc_display_ops, obj);
+-}
+-
+-static int vnc_display_best_path(char *buf,
+- int buflen,
+- const char *basedir,
+- const char *basefile,
+- char **dirs,
+- unsigned int ndirs)
+-{
+- unsigned int i;
+- for (i = 0 ; i < ndirs ; i++) {
+- struct stat sb;
+- snprintf(buf, buflen-1, "%s/%s/%s", dirs[i], basedir, basefile);
+- buf[buflen-1] = '\0';
+- if (stat(buf, &sb) == 0)
+- return 0;
+- }
+- return -1;
+-}
+-
+-static int vnc_display_set_x509_credential(VncDisplay *obj, const char *name)
+-{
+- char sysdir[PATH_MAX], userdir[PATH_MAX];
+- struct passwd *pw;
+- char file[PATH_MAX];
+- char *dirs[] = { sysdir, userdir };
+-
+- strncpy(sysdir, SYSCONFDIR "/pki", PATH_MAX-1);
+- sysdir[PATH_MAX-1] = '\0';
+-
+- if (!(pw = getpwuid(getuid())))
+- return TRUE;
+-
+- snprintf(userdir, PATH_MAX-1, "%s/.pki", pw->pw_dir);
+- userdir[PATH_MAX-1] = '\0';
+-
+- if (vnc_display_best_path(file, PATH_MAX, "CA", "cacert.pem", dirs, 2) < 0)
+- return TRUE;
+- gvnc_set_credential_x509_cacert(obj->priv->gvnc, file);
+-
+- /* Don't mind failures of CRL */
+- if (vnc_display_best_path(file, PATH_MAX, "CA", "cacrl.pem", dirs, 2) == 0)
+- gvnc_set_credential_x509_cacert(obj->priv->gvnc, file);
+-
+- /* Set client key & cert if we have them. Server will reject auth
+- * if it decides it requires them*/
+- if (vnc_display_best_path(file, PATH_MAX, name, "private/clientkey.pem", dirs, 2) == 0)
+- gvnc_set_credential_x509_key(obj->priv->gvnc, file);
+- if (vnc_display_best_path(file, PATH_MAX, name, "clientcert.pem", dirs, 2) == 0)
+- gvnc_set_credential_x509_cert(obj->priv->gvnc, file);
+-
+- return FALSE;
+-}
+-
+-gboolean vnc_display_set_credential(VncDisplay *obj, int type, const gchar *data)
+-{
+- switch (type) {
+- case VNC_DISPLAY_CREDENTIAL_PASSWORD:
+- if (gvnc_set_credential_password(obj->priv->gvnc, data))
+- return FALSE;
+- return TRUE;
+-
+- case VNC_DISPLAY_CREDENTIAL_USERNAME:
+- if (gvnc_set_credential_username(obj->priv->gvnc, data))
+- return FALSE;
+- return TRUE;
+-
+- case VNC_DISPLAY_CREDENTIAL_CLIENTNAME:
+- return vnc_display_set_x509_credential(obj, data);
+- }
+-
+- return FALSE;
+-}
+-
+-void vnc_display_set_pointer_local(VncDisplay *obj, gboolean enable)
+-{
+- if (obj->priv->gc) {
+- if (enable)
+- do_pointer_show(obj);
+- else if (obj->priv->in_pointer_grab || obj->priv->absolute)
+- do_pointer_hide(obj);
+- }
+- obj->priv->local_pointer = enable;
+-}
+-
+-void vnc_display_set_pointer_grab(VncDisplay *obj, gboolean enable)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+-
+- priv->grab_pointer = enable;
+- if (!enable && priv->absolute && priv->in_pointer_grab)
+- do_pointer_ungrab(obj, FALSE);
+-}
+-
+-void vnc_display_set_keyboard_grab(VncDisplay *obj, gboolean enable)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+-
+- priv->grab_keyboard = enable;
+- if (!enable && priv->in_keyboard_grab && !priv->in_pointer_grab)
+- do_keyboard_ungrab(obj, FALSE);
+-}
+-
+-void vnc_display_set_read_only(VncDisplay *obj, gboolean enable)
+-{
+- obj->priv->read_only = enable;
+-}
+-
+-GType vnc_display_credential_get_type(void)
+-{
+- static GType etype = 0;
+-
+- if (etype == 0) {
+- static const GEnumValue values[] = {
+- { VNC_DISPLAY_CREDENTIAL_PASSWORD, "VNC_DISPLAY_CREDENTIAL_PASSWORD", "password" },
+- { VNC_DISPLAY_CREDENTIAL_USERNAME, "VNC_DISPLAY_CREDENTIAL_USERNAME", "username" },
+- { VNC_DISPLAY_CREDENTIAL_CLIENTNAME, "VNC_DISPLAY_CREDENTIAL_CLIENTNAME", "clientname" },
+- { 0, NULL, NULL }
+- };
+- etype = g_enum_register_static ("VncDisplayCredentialType", values );
+- }
+-
+- return etype;
+-}
+-
+-GType vnc_display_key_event_get_type(void)
+-{
+- static GType etype = 0;
+-
+- if (etype == 0) {
+- static const GEnumValue values[] = {
+- { VNC_DISPLAY_KEY_EVENT_PRESS, "VNC_DISPLAY_KEY_EVENT_PRESS", "press" },
+- { VNC_DISPLAY_KEY_EVENT_RELEASE, "VNC_DISPLAY_KEY_EVENT_RELEASE", "release" },
+- { VNC_DISPLAY_KEY_EVENT_CLICK, "VNC_DISPLAY_KEY_EVENT_CLICK", "click" },
+- { 0, NULL, NULL }
+- };
+- etype = g_enum_register_static ("VncDisplayKeyEvents", values );
+- }
+-
+- return etype;
+-}
+-
+-GdkPixbuf *vnc_display_get_pixbuf(VncDisplay *obj)
+-{
+- VncDisplayPrivate *priv = obj->priv;
+- GdkPixbuf *pixbuf;
+-
+- if (!priv->gvnc ||
+- !gvnc_is_initialized(priv->gvnc))
+- return NULL;
+-
+- pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
+- priv->image->width, priv->image->height);
+-
+- if (!gdk_pixbuf_get_from_image(pixbuf,
+- priv->image,
+- gdk_colormap_get_system(),
+- 0, 0, 0, 0,
+- priv->image->width,
+- priv->image->height))
+- return NULL;
+-
+- return pixbuf;
+-}
+-
+-
+-int vnc_display_get_width(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), -1);
+-
+- return gvnc_get_width (obj->priv->gvnc);
+-}
+-
+-int vnc_display_get_height(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), -1);
+-
+- return gvnc_get_height (obj->priv->gvnc);
+-}
+-
+-const char * vnc_display_get_name(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), NULL);
+-
+- return gvnc_get_name (obj->priv->gvnc);
+-}
+-
+-void vnc_display_client_cut_text(VncDisplay *obj, const gchar *text)
+-{
+- g_return_if_fail (VNC_IS_DISPLAY (obj));
+-
+- gvnc_client_cut_text(obj->priv->gvnc, text, strlen (text));
+-}
+-
+-void vnc_display_set_lossy_encoding(VncDisplay *obj, gboolean enable)
+-{
+- g_return_if_fail (VNC_IS_DISPLAY (obj));
+- obj->priv->allow_lossy = enable;
+-}
+-
+-void vnc_display_set_shared_flag(VncDisplay *obj, gboolean shared)
+-{
+- g_return_if_fail (VNC_IS_DISPLAY (obj));
+- obj->priv->shared_flag = shared;
+-}
+-
+-#if WITH_GTKGLEXT
+-gboolean vnc_display_set_scaling(VncDisplay *obj, gboolean enable)
+-{
+- GtkWidget *widget = GTK_WIDGET(obj);
+- gint width, height;
+-
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
+- if (obj->priv->gl_config == NULL)
+- return FALSE;
+-
+- obj->priv->allow_scaling = enable;
+- if (gvnc_is_open(obj->priv->gvnc) && widget->window) {
+- gdk_drawable_get_size(widget->window, &width, &height);
+- rescale_display(obj, width, height);
+- gtk_widget_queue_draw_area(widget, 0, 0, width, height);
+- }
+-
+- return TRUE;
+-}
+-#else
+-gboolean vnc_display_set_scaling(VncDisplay *obj G_GNUC_UNUSED,
+- gboolean enable G_GNUC_UNUSED)
+-{
+- return FALSE;
+-}
+-#endif
+-
+-void vnc_display_set_force_size(VncDisplay *obj, gboolean enabled)
+-{
+- g_return_if_fail (VNC_IS_DISPLAY (obj));
+- obj->priv->force_size = enabled;
+-}
+-
+-gboolean vnc_display_get_force_size(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
+-
+- return obj->priv->force_size;
+-}
+-
+-gboolean vnc_display_get_scaling(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
+-
+- return obj->priv->allow_scaling;
+-}
+-
+-gboolean vnc_display_get_lossy_encoding(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
+-
+- return obj->priv->allow_lossy;
+-}
+-
+-gboolean vnc_display_get_shared_flag(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
+-
+- return obj->priv->shared_flag;
+-}
+-
+-gboolean vnc_display_get_pointer_local(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
+-
+- return obj->priv->local_pointer;
+-}
+-
+-gboolean vnc_display_get_pointer_grab(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
+-
+- return obj->priv->grab_pointer;
+-}
+-
+-gboolean vnc_display_get_keyboard_grab(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
+-
+- return obj->priv->grab_keyboard;
+-}
+-
+-gboolean vnc_display_get_read_only(VncDisplay *obj)
+-{
+- g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
+-
+- return obj->priv->read_only;
+-}
+-
+-gboolean vnc_display_is_pointer_absolute(VncDisplay *obj)
+-{
+- return obj->priv->absolute;
+-}
+-
+-GOptionGroup *
+-vnc_display_get_option_group (void)
+-{
+- GOptionGroup *group;
+-
+- group = g_option_group_new ("gtk-vnc", "GTK-VNC Options", "Show GTK-VNC Options", NULL, NULL);
+-
+- g_option_group_add_entries (group, gtk_vnc_args);
+-
+- return group;
+-}
+-
+-/*
+- * Local variables:
+- * c-indent-level: 8
+- * c-basic-offset: 8
+- * tab-width: 8
+- * End:
+- */
+diff -urN gtk-vnc-0.3.7/vc-list-files gtk-vnc-0.3.7.mingw/vc-list-files
+--- gtk-vnc-0.3.7/vc-list-files 1970-01-01 01:00:00.000000000 +0100
++++ gtk-vnc-0.3.7.mingw/vc-list-files 2008-10-09 12:19:03.000000000 +0100
+@@ -0,0 +1,107 @@
++#!/bin/sh
++# List version-controlled file names.
++
++# Print a version string.
++scriptversion=2008-07-11.19
++
++# Copyright (C) 2006-2008 Free Software Foundation, 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 3 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/>.
++
++
++# List the specified version-controlled files.
++# With no argument, list them all. With a single DIRECTORY argument,
++# list the version-controlled files in that directory.
++
++# If there's an argument, it must be a single, "."-relative directory name.
++# cvsu is part of the cvsutils package: http://www.red-bean.com/cvsutils/
++
++postprocess=
++case $1 in
++ --help) cat <<EOF
++Usage: $0 [-C SRCDIR] [DIR]
++
++Output a list of version-controlled files in DIR (default .), relative to
++SRCDIR (default .). SRCDIR must be the top directory of a checkout.
++
++Options:
++ --help print this help, then exit
++ --version print version number, then exit
++ -C SRCDIR change directory to SRCDIR before generating list
++
++Report bugs and patches to <bug-gnulib@gnu.org>.
++EOF
++ exit ;;
++
++ --version)
++ year=`echo "$scriptversion" | sed 's/[^0-9].*//'`
++ cat <<EOF
++vc-list-files $scriptversion
++Copyright (C) $year Free Software Foundation, Inc,
++License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
++This is free software: you are free to change and redistribute it.
++There is NO WARRANTY, to the extent permitted by law.
++EOF
++ exit ;;
++
++ -C)
++ test "$2" = . || postprocess="| sed 's|^|$2/|'"
++ cd "$2" || exit 1
++ shift; shift ;;
++esac
++
++dir=
++case $# in
++ 0) ;;
++ 1) dir=$1 ;;
++ *) echo "$0: too many arguments" 1>&2
++ echo "Usage: $0 [-C srcdir] [DIR]" 1>&2; exit 1;;
++esac
++
++test "x$dir" = x && dir=.
++
++if test -d .git; then
++ eval exec git ls-files '"$dir"' $postprocess
++elif test -d .hg; then
++ eval exec hg locate '"$dir/*"' $postprocess
++elif test -d .bzr; then
++ test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
++ eval exec bzr ls --versioned '"$dir"' $postprocess
++elif test -d CVS; then
++ test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
++ if test -x build-aux/cvsu; then
++ eval build-aux/cvsu --find --types=AFGM '"$dir"' $postprocess
++ elif (cvsu --help) >/dev/null 2>&1; then
++ eval cvsu --find --types=AFGM '"$dir"' $postprocess
++ else
++ eval awk -F/ \''{ \
++ if (!$1 && $3 !~ /^-/) { \
++ f=FILENAME; \
++ if (f ~ /CVS\/Entries$/) \
++ f = substr(f, 0, length(f)-11); \
++ print f $2; \
++ }}'\'' \
++ `find "$dir" -name Entries -print` /dev/null' $postprocess
++ fi
++else
++ echo "$0: Failed to determine type of version control used in `pwd`" 1>&2
++ exit 1
++fi
++
++# Local variables:
++# eval: (add-hook 'write-file-hooks 'time-stamp)
++# time-stamp-start: "scriptversion="
++# time-stamp-format: "%:y-%02m-%02d.%02H"
++# time-stamp-end: "$"
++# End: