gtk-vnc with Dan's version 2 patch.
[fedora-mingw.git] / gtk-vnc / gtk-vnc-0.3.7-mingw32-dan2.patch
1 diff -urN gtk-vnc-0.3.7/bootstrap gtk-vnc-0.3.7.mingw/bootstrap
2 --- gtk-vnc-0.3.7/bootstrap     1970-01-01 01:00:00.000000000 +0100
3 +++ gtk-vnc-0.3.7.mingw/bootstrap       2008-10-09 12:19:03.000000000 +0100
4 @@ -0,0 +1,84 @@
5 +#!/bin/sh
6 +# Run this after autogen.sh, to pull in all of the gnulib-related bits.
7 +# It's important to run *after* autogen.sh, since it updates some of
8 +# the same files autogen.sh does, yet those from gnulib are newer,
9 +# and match the tests.  So if a gnulib bug has been fixed since the
10 +# snapshot taken for whatever gettext release you're using, yet you
11 +# run "make check" against the wrong version, the corresponding unit
12 +# test in gl-tests/ may well fail.
13 +
14 +usage() {
15 +  echo >&2 "\
16 +Usage: $0 [OPTION]...
17 +Bootstrap this package from the checked-out sources.
18 +
19 +Options:
20 + --gnulib-srcdir=DIRNAME  Specify the local directory where gnulib
21 +                          sources reside.  Use this if you already
22 +                          have gnulib sources on your machine, and
23 +                          do not want to waste your bandwidth downloading
24 +                          them again.
25 +
26 +If the file bootstrap.conf exists in the current working directory, its
27 +contents are read as shell variables to configure the bootstrap.
28 +
29 +Running without arguments will suffice in most cases.
30 +"
31 +}
32 +
33 +for option
34 +do
35 +  case $option in
36 +  --help)
37 +    usage
38 +    exit;;
39 +  --gnulib-srcdir=*)
40 +    GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
41 +  *)
42 +    echo >&2 "$0: $option: unknown option"
43 +    exit 1;;
44 +  esac
45 +done
46 +
47 +cleanup_gnulib() {
48 +  st=$?
49 +  rm -fr .gnulib
50 +  exit $st
51 +}
52 +
53 +case ${GNULIB_SRCDIR--} in
54 +-)
55 +  if [ ! -d .gnulib ]; then
56 +    echo "$0: getting gnulib files..."
57 +
58 +    trap cleanup_gnulib 1 2 13 15
59 +
60 +    git clone --depth 1 git://git.sv.gnu.org/gnulib .gnulib ||
61 +      cleanup_gnulib
62 +
63 +    trap - 1 2 13 15
64 +  fi
65 +  GNULIB_SRCDIR=.gnulib
66 +esac
67 +
68 +gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
69 +<$gnulib_tool || exit
70 +
71 +modules='
72 +getaddrinfo
73 +vc-list-files
74 +'
75 +
76 +# Tell gnulib to:
77 +#   require LGPLv2+
78 +#   put *.m4 files in new gnulib/m4/ dir
79 +#   put *.[ch] files in new gnulib/lib/ dir.
80 +
81 +$gnulib_tool                   \
82 +  --lgpl=2                     \
83 +  --with-tests                 \
84 +  --m4-base=gnulib/m4          \
85 +  --source-base=gnulib/lib     \
86 +  --tests-base=gnulib/tests    \
87 +  --import $modules
88 +
89 diff -urN gtk-vnc-0.3.7/configure.ac gtk-vnc-0.3.7.mingw/configure.ac
90 --- gtk-vnc-0.3.7/configure.ac  2008-09-05 13:32:15.000000000 +0100
91 +++ gtk-vnc-0.3.7.mingw/configure.ac    2008-10-09 12:19:03.000000000 +0100
92 @@ -23,15 +23,29 @@
93  
94  AC_CONFIG_HEADERS([config.h:config.hin])
95  
96 -
97  AC_CANONICAL_TARGET
98  
99  AM_INIT_AUTOMAKE(gtk-vnc, 0.3.7)
100  
101 +
102 +dnl gl_INIT uses m4_foreach_w, yet that is not defined in autoconf-2.59.
103 +dnl In order to accommodate developers with such old tools, here's a
104 +dnl replacement definition.
105 +m4_ifndef([m4_foreach_w],
106 +  [m4_define([m4_foreach_w],
107 +    [m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])])
108 +
109 +gl_EARLY
110 +gl_INIT
111 +
112  AC_PROG_CC_STDC
113  AM_PROG_CC_C_O
114 +AC_LIBTOOL_WIN32_DLL
115 +
116  AC_PROG_LIBTOOL
117  
118 +AC_CHECK_HEADERS([pwd.h winsock2.h])
119 +
120  AC_ARG_WITH(python,
121  [  --with-python           build python bindings],
122  [case "${withval}" in
123 @@ -234,6 +248,8 @@
124  
125  AC_CONFIG_FILES(
126    Makefile
127 +  gnulib/lib/Makefile
128 +  gnulib/tests/Makefile
129    src/Makefile
130    examples/Makefile
131    plugin/Makefile
132 diff -urN gtk-vnc-0.3.7/Makefile.am gtk-vnc-0.3.7.mingw/Makefile.am
133 --- gtk-vnc-0.3.7/Makefile.am   2008-09-05 13:32:15.000000000 +0100
134 +++ gtk-vnc-0.3.7.mingw/Makefile.am     2008-10-09 12:19:01.000000000 +0100
135 @@ -1,5 +1,9 @@
136  
137 -SUBDIRS = src examples plugin
138 +SUBDIRS = gnulib/lib src examples plugin gnulib/tests
139 +
140 +ACLOCAL_AMFLAGS = -I gnulib/m4
141 +
142 +
143  
144  pkgconfig_DATA = @PACKAGE@-1.0.pc
145  pkgconfigdir = $(libdir)/pkgconfig
146 diff -urN gtk-vnc-0.3.7/src/continuation.c gtk-vnc-0.3.7.mingw/src/continuation.c
147 --- gtk-vnc-0.3.7/src/continuation.c    2008-09-05 13:32:16.000000000 +0100
148 +++ gtk-vnc-0.3.7.mingw/src/continuation.c      2008-10-09 12:19:03.000000000 +0100
149 @@ -8,6 +8,8 @@
150   *  GTK VNC Widget
151   */
152  
153 +#include <config.h>
154 +
155  #include "continuation.h"
156  
157  /*
158 diff -urN gtk-vnc-0.3.7/src/coroutine_gthread.c gtk-vnc-0.3.7.mingw/src/coroutine_gthread.c
159 --- gtk-vnc-0.3.7/src/coroutine_gthread.c       2008-09-05 13:32:16.000000000 +0100
160 +++ gtk-vnc-0.3.7.mingw/src/coroutine_gthread.c 2008-10-09 12:19:03.000000000 +0100
161 @@ -8,6 +8,8 @@
162   *  GTK VNC Widget
163   */
164  
165 +#include <config.h>
166 +
167  #include "coroutine.h"
168  #include <stdio.h>
169  #include <stdlib.h>
170 @@ -17,13 +19,24 @@
171  static struct coroutine *current;
172  static struct coroutine leader;
173  
174 +#if 0
175 +#define CO_DEBUG(OP) fprintf(stderr, "%s %p %s %d\n", OP, g_thread_self(), __FUNCTION__, __LINE__)
176 +#else
177 +#define CO_DEBUG(OP)
178 +#endif
179 +
180  static void coroutine_system_init(void)
181  {
182 -       if (!g_thread_supported())
183 +       if (!g_thread_supported()) {
184 +               CO_DEBUG("INIT");
185                 g_thread_init(NULL);
186 +       }
187 +
188  
189         run_cond = g_cond_new();
190         run_lock = g_mutex_new();
191 +       CO_DEBUG("LOCK");
192 +       g_mutex_lock(run_lock);
193  
194         /* The thread that creates the first coroutine is the system coroutine
195          * so let's fill out a structure for it */
196 @@ -42,17 +55,22 @@
197  static gpointer coroutine_thread(gpointer opaque)
198  {
199         struct coroutine *co = opaque;
200 -
201 +       CO_DEBUG("LOCK");
202         g_mutex_lock(run_lock);
203 -       while (!co->runnable)
204 +       while (!co->runnable) {
205 +               CO_DEBUG("WAIT");
206                 g_cond_wait(run_cond, run_lock);
207 +       }
208  
209 +       CO_DEBUG("RUNNABLE");
210         current = co;
211         co->data = co->entry(co->data);
212         co->exited = 1;
213  
214         co->caller->runnable = TRUE;
215 +       CO_DEBUG("BROADCAST");
216         g_cond_broadcast(run_cond);
217 +       CO_DEBUG("UNLOCK");
218         g_mutex_unlock(run_lock);
219  
220         return NULL;
221 @@ -62,7 +80,8 @@
222  {
223         if (run_cond == NULL)
224                 coroutine_system_init();
225 -       
226 +
227 +       CO_DEBUG("NEW");
228         co->thread = g_thread_create_full(coroutine_thread, co, co->stack_size,
229                                           FALSE, TRUE,
230                                           G_THREAD_PRIORITY_NORMAL,
231 @@ -88,15 +107,19 @@
232         to->runnable = TRUE;
233         to->data = arg;
234         to->caller = from;
235 +       CO_DEBUG("BROADCAST");
236         g_cond_broadcast(run_cond);
237 +       CO_DEBUG("UNLOCK");
238         g_mutex_unlock(run_lock);
239 -
240 +       CO_DEBUG("LOCK");
241         g_mutex_lock(run_lock);
242 -       while (!from->runnable)
243 +       while (!from->runnable) {
244 +               CO_DEBUG("WAIT");
245                 g_cond_wait(run_cond, run_lock);
246 -
247 +       }
248         current = from;
249  
250 +       CO_DEBUG("SWAPPED");
251         return from->data;
252  }
253  
254 @@ -111,6 +134,7 @@
255                 fprintf(stderr, "Co-routine is re-entering itself\n");
256                 abort();
257         }
258 +       CO_DEBUG("SWAP");
259         return coroutine_swap(coroutine_self(), to, arg);
260  }
261  
262 @@ -121,6 +145,8 @@
263                 fprintf(stderr, "Co-routine is yielding to no one\n");
264                 abort();
265         }
266 +
267 +       CO_DEBUG("SWAP");
268         coroutine_self()->caller = NULL;
269         return coroutine_swap(coroutine_self(), to, arg);
270  }
271 diff -urN gtk-vnc-0.3.7/src/coroutine_ucontext.c gtk-vnc-0.3.7.mingw/src/coroutine_ucontext.c
272 --- gtk-vnc-0.3.7/src/coroutine_ucontext.c      2008-09-05 13:32:16.000000000 +0100
273 +++ gtk-vnc-0.3.7.mingw/src/coroutine_ucontext.c        2008-10-09 12:19:03.000000000 +0100
274 @@ -8,6 +8,8 @@
275   *  GTK VNC Widget
276   */
277  
278 +#include <config.h>
279 +
280  #include <sys/types.h>
281  #include <sys/mman.h>
282  #include <stdio.h>
283 diff -urN gtk-vnc-0.3.7/src/gvnc.c gtk-vnc-0.3.7.mingw/src/gvnc.c
284 --- gtk-vnc-0.3.7/src/gvnc.c    2008-09-05 13:32:16.000000000 +0100
285 +++ gtk-vnc-0.3.7.mingw/src/gvnc.c      2008-10-09 12:19:03.000000000 +0100
286 @@ -8,13 +8,10 @@
287   *  GTK VNC Widget
288   */
289  
290 -#include "gvnc.h"
291 +#include <config.h>
292  
293 -#include <sys/socket.h>
294 -#include <netinet/in.h>
295 -#include <arpa/inet.h>
296 +#include "gvnc.h"
297  
298 -#include <netdb.h>
299  #include <string.h>
300  #include <unistd.h>
301  #include <stdio.h>
302 @@ -40,6 +37,15 @@
303  #include <gdk/gdkkeysyms.h>
304  
305  #include "vnc_keycodes.h"
306 +#include "socketcompat.h"
307 +#include "getaddrinfo.h"
308 +
309 +/* AI_ADDRCONFIG is missing on some systems and gnulib won't provide it
310 +   even if its emulated getaddrinfo() for us . */
311 +#ifndef AI_ADDRCONFIG
312 +# define AI_ADDRCONFIG 0
313 +#endif
314 +
315  
316  struct wait_queue
317  {
318 @@ -185,7 +191,6 @@
319  
320         g_io_add_watch(channel, cond | G_IO_HUP | G_IO_ERR | G_IO_NVAL, g_io_wait_helper, coroutine_self());
321         ret = coroutine_yield(NULL);
322 -
323         return *ret;
324  }
325  
326 @@ -321,10 +326,8 @@
327  
328                         /* inflate as much as possible */
329                         err = inflate(gvnc->strm, Z_SYNC_FLUSH);
330 -                       if (err != Z_OK) {
331 -                               errno = EIO;
332 -                               return -1;
333 -                       }
334 +                       if (err != Z_OK)
335 +                               return -EIO;
336  
337                         gvnc->uncompressed_length = (uint8_t *)gvnc->strm->next_out - gvnc->uncompressed_buffer;
338                         gvnc->compressed_length -= (uint8_t *)gvnc->strm->next_in - gvnc->compressed_buffer;
339 @@ -344,7 +347,7 @@
340         size_t offset = 0;
341  
342         if (gvnc->has_error) return -EINVAL;
343 -       
344 +
345         while (offset < len) {
346                 size_t tmp;
347  
348 @@ -352,10 +355,10 @@
349                  * so we must by-pass it */
350                 if (gvnc_use_compression(gvnc)) {
351                         int ret = gvnc_zread(gvnc, data + offset, len);
352 -                       if (ret == -1) {
353 +                       if (ret < 0) {
354                                 GVNC_DEBUG("Closing the connection: gvnc_read() - gvnc_zread() failed\n");
355                                 gvnc->has_error = TRUE;
356 -                               return -errno;
357 +                               return ret;
358                         }
359                         offset += ret;
360                         continue;
361 @@ -366,17 +369,19 @@
362                                 ret = gnutls_read(gvnc->tls_session, gvnc->read_buffer, 4096);
363                                 if (ret < 0) {
364                                         if (ret == GNUTLS_E_AGAIN)
365 -                                               errno = EAGAIN;
366 +                                               ret = -EAGAIN;
367                                         else
368 -                                               errno = EIO;
369 -                                       ret = -1;
370 +                                               ret = -EIO;
371                                 }
372 -                       } else
373 -                               ret = read(fd, gvnc->read_buffer, 4096);
374 +                       } else {
375 +                               ret = recv(fd, gvnc->read_buffer, 4096, 0);
376 +                               if (ret < 0)
377 +                                       ret = socket_errno() * -1;
378 +                       }
379  
380 -                       if (ret == -1) {
381 -                               switch (errno) {
382 -                               case EAGAIN:
383 +                       if (ret < 0) {
384 +                               switch (ret * -1) {
385 +                               case EWOULDBLOCK:
386                                         if (gvnc->wait_interruptable) {
387                                                 if (!g_io_wait_interruptable(&gvnc->wait,
388                                                                              gvnc->channel, G_IO_IN))
389 @@ -386,9 +391,9 @@
390                                 case EINTR:
391                                         continue;
392                                 default:
393 -                                       GVNC_DEBUG("Closing the connection: gvnc_read() - ret=-1\n");
394 +                                       GVNC_DEBUG("Closing the connection: gvnc_read() - ret=%d\n", ret);
395                                         gvnc->has_error = TRUE;
396 -                                       return -errno;
397 +                                       return ret;
398                                 }
399                         }
400                         if (ret == 0) {
401 @@ -425,23 +430,25 @@
402                                            gvnc->write_offset-offset);
403                         if (ret < 0) {
404                                 if (ret == GNUTLS_E_AGAIN)
405 -                                       errno = EAGAIN;
406 +                                       ret = -EAGAIN;
407                                 else
408 -                                       errno = EIO;
409 -                               ret = -1;
410 +                                       ret = -EIO;
411                         }
412 -               } else
413 -                       ret = write(fd,
414 -                                   gvnc->write_buffer+offset,
415 -                                   gvnc->write_offset-offset);
416 -               if (ret == -1) {
417 -                       switch (errno) {
418 -                       case EAGAIN:
419 +               } else {
420 +                       ret = send(fd,
421 +                                  gvnc->write_buffer+offset,
422 +                                  gvnc->write_offset-offset, 0);
423 +                       if (ret < 0)
424 +                               ret = socket_errno() * -1;
425 +               }
426 +               if (ret < 0) {
427 +                       switch (ret * -1) {
428 +                       case EWOULDBLOCK:
429                                 g_io_wait(gvnc->channel, G_IO_OUT);
430                         case EINTR:
431                                 continue;
432                         default:
433 -                               GVNC_DEBUG("Closing the connection: gvnc_flush\n");
434 +                               GVNC_DEBUG("Closing the connection: gvnc_flush %d\n", ret);
435                                 gvnc->has_error = TRUE;
436                                 return;
437                         }
438 @@ -488,7 +495,7 @@
439   retry:
440         ret = write(fd, data, len);
441         if (ret < 0) {
442 -               if (errno == EINTR)
443 +               if (socket_errno() == EINTR)
444                         goto retry;
445                 return -1;
446         }
447 @@ -506,7 +513,7 @@
448   retry:
449         ret = read(fd, data, len);
450         if (ret < 0) {
451 -               if (errno == EINTR)
452 +               if (socket_errno() == EINTR)
453                         goto retry;
454                 return -1;
455         }
456 @@ -2802,12 +2809,12 @@
457         if (gvnc_has_error(gvnc))
458                 return FALSE;
459  
460 -       if (!gvnc->fmt.true_color_flag && gvnc->ops.get_preferred_pixel_format)
461 +       if (!gvnc->fmt.true_color_flag && gvnc->ops.get_preferred_pixel_format) {
462                 if (gvnc->ops.get_preferred_pixel_format(gvnc->ops_data, &gvnc->fmt))
463                         gvnc_set_pixel_format(gvnc, &gvnc->fmt);
464                 else
465                         goto fail;
466 -
467 +       }
468         memset(&gvnc->strm, 0, sizeof(gvnc->strm));
469         /* FIXME what level? */
470         for (i = 0; i < 5; i++)
471 @@ -2822,15 +2829,16 @@
472         return !gvnc_has_error(gvnc);
473  }
474  
475 -gboolean gvnc_open_fd(struct gvnc *gvnc, int fd)
476 +static gboolean gvnc_set_nonblock(int fd)
477  {
478 -       int flags;
479 -       if (gvnc_is_open(gvnc)) {
480 -               GVNC_DEBUG ("Error: already connected?\n");
481 +#ifdef __MINGW32__
482 +       unsigned long flags = 1;
483 +       if (ioctlsocket(fd, FIONBIO, &flags) < 0) {
484 +               GVNC_DEBUG ("Failed to set nonblocking flag\n");
485                 return FALSE;
486         }
487 -
488 -       GVNC_DEBUG("Connecting to FD %d\n", fd);
489 +#else
490 +       int flags;
491         if ((flags = fcntl(fd, F_GETFL)) < 0) {
492                 GVNC_DEBUG ("Failed to fcntl()\n");
493                 return FALSE;
494 @@ -2840,6 +2848,21 @@
495                 GVNC_DEBUG ("Failed to fcntl()\n");
496                 return FALSE;
497         }
498 +#endif
499 +       return TRUE;
500 +}
501 +
502 +gboolean gvnc_open_fd(struct gvnc *gvnc, int fd)
503 +{
504 +       if (gvnc_is_open(gvnc)) {
505 +               GVNC_DEBUG ("Error: already connected?\n");
506 +               return FALSE;
507 +       }
508 +
509 +       GVNC_DEBUG("Connecting to FD %d\n", fd);
510 +
511 +       if (!gvnc_set_nonblock(fd))
512 +               return FALSE;
513  
514         if (!(gvnc->channel = g_io_channel_unix_new(fd))) {
515                 GVNC_DEBUG ("Failed to g_io_channel_unix_new()\n");
516 @@ -2873,7 +2896,7 @@
517  
518          runp = ai;
519          while (runp != NULL) {
520 -                int flags, fd;
521 +                int fd;
522                  GIOChannel *chan;
523  
524                 if ((fd = socket(runp->ai_family, runp->ai_socktype,
525 @@ -2883,17 +2906,8 @@
526                 }
527  
528                  GVNC_DEBUG("Trying socket %d\n", fd);
529 -                if ((flags = fcntl(fd, F_GETFL)) < 0) {
530 -                        close(fd);
531 -                        GVNC_DEBUG ("Failed to fcntl()\n");
532 -                        break;
533 -                }
534 -                flags |= O_NONBLOCK;
535 -                if (fcntl(fd, F_SETFL, flags) < 0) {
536 -                        close(fd);
537 -                        GVNC_DEBUG ("Failed to fcntl()\n");
538 -                        break;
539 -                }
540 +               if (!gvnc_set_nonblock(fd))
541 +                       break;
542  
543                  if (!(chan = g_io_channel_unix_new(fd))) {
544                          close(fd);
545 @@ -2904,21 +2918,22 @@
546          reconnect:
547                  /* FIXME: Better handle EINPROGRESS/EISCONN return values,
548                     as explained in connect(2) man page */
549 -                if ( (connect(fd, runp->ai_addr, runp->ai_addrlen) == 0) || errno == EISCONN) {
550 +                if ((connect(fd, runp->ai_addr, runp->ai_addrlen) == 0) ||
551 +                   socket_errno() == EISCONN) {
552                          gvnc->channel = chan;
553                          gvnc->fd = fd;
554                          freeaddrinfo(ai);
555                          return !gvnc_has_error(gvnc);
556                  }
557 -
558 -                if (errno == EINPROGRESS) {
559 +                if (socket_errno() == EINPROGRESS ||
560 +                    socket_errno() == EWOULDBLOCK) {
561                          g_io_wait(chan, G_IO_OUT|G_IO_ERR|G_IO_HUP);
562                          goto reconnect;
563 -                } else if (errno != ECONNREFUSED &&
564 -                           errno != EHOSTUNREACH) {
565 +                } else if (socket_errno() != ECONNREFUSED &&
566 +                           socket_errno() != EHOSTUNREACH) {
567                          g_io_channel_unref(chan);
568                          close(fd);
569 -                        GVNC_DEBUG ("Failed with errno = %d\n", errno);
570 +                        GVNC_DEBUG ("Failed with errno = %d\n", socket_errno());
571                          break;
572                  }
573                  close(fd);
574 diff -urN gtk-vnc-0.3.7/src/Makefile.am gtk-vnc-0.3.7.mingw/src/Makefile.am
575 --- gtk-vnc-0.3.7/src/Makefile.am       2008-09-05 13:32:15.000000000 +0100
576 +++ gtk-vnc-0.3.7.mingw/src/Makefile.am 2008-10-09 12:19:03.000000000 +0100
577 @@ -4,13 +4,15 @@
578  lib_LTLIBRARIES = libgtk-vnc-1.0.la
579  
580  libgtk_vnc_1_0_la_LIBADD = @GTK_LIBS@ @GTKGLEXT_LIBS@ @GNUTLS_LIBS@ \
581 -                          @GTHREAD_LIBS@
582 +                          @GTHREAD_LIBS@ \
583 +                           ../gnulib/lib/libgnu.la
584  libgtk_vnc_1_0_la_CFLAGS = @GTK_CFLAGS@ @GTKGLEXT_CFLAGS@ @GNUTLS_CFLAGS@ \
585                            @GTHREAD_CFLAGS@ @WARNING_CFLAGS@ \
586                            -DSYSCONFDIR=\""$(sysconfdir)"\" \
587 -                           -DG_LOG_DOMAIN=\"gtk-vnc\"
588 +                           -DG_LOG_DOMAIN=\"gtk-vnc\" \
589 +                           -I$(top_srcdir)gnulib/lib -I../gnulib/lib
590  libgtk_vnc_1_0_la_LDFLAGS = -Wl, @LD_VERSION_SCRIPT_SUPPORT@ \
591 -                            -version-info 0:1:0
592 +                            -version-info 0:1:0 -no-undefined
593  
594  gtk_vnc_includedir = $(includedir)/gtk-vnc-1.0/
595  gtk_vnc_include_HEADERS = vncdisplay.h
596 @@ -22,7 +24,7 @@
597         vncdisplay.h vncdisplay.c \
598          vncmarshal.h vncmarshal.c \
599         x_keymap.h x_keymap.c vnc_keycodes.h \
600 -       utils.h
601 +       utils.h socketcompat.h
602  
603  if WITH_UCONTEXT
604  libgtk_vnc_1_0_la_SOURCES += continuation.h continuation.c coroutine_ucontext.c
605 diff -urN gtk-vnc-0.3.7/src/socketcompat.h gtk-vnc-0.3.7.mingw/src/socketcompat.h
606 --- gtk-vnc-0.3.7/src/socketcompat.h    1970-01-01 01:00:00.000000000 +0100
607 +++ gtk-vnc-0.3.7.mingw/src/socketcompat.h      2008-10-09 12:19:03.000000000 +0100
608 @@ -0,0 +1,64 @@
609 +/*
610 + * socketcompat.h: Socket compatibility for Windows, making it slightly
611 + * less painful to use.
612 + *
613 + * Use this header under the following circumstances:
614 + * (a) Instead of including any of: <net/if.h>, <netinet/in.h>,
615 + *     <sys/socket.h>, <netdb.h>, <netinet/tcp.h>, AND
616 + * (b) The file will be part of what is built on Windows (basically
617 + *     just remote client stuff).
618 + *
619 + * You need to use socket_errno() instead of errno to get socket
620 + * errors.
621 + *
622 + * Copyright (C) 2008 Red Hat, Inc.
623 + *
624 + * See COPYING.LIB for the License of this software
625 + *
626 + * Richard W.M. Jones <rjones@redhat.com>
627 + */
628 +
629 +#ifndef __SOCKETCOMPAT_H__
630 +#define __SOCKETCOMPAT_H__
631 +
632 +#include <config.h>
633 +
634 +#include <errno.h>
635 +
636 +#ifndef HAVE_WINSOCK2_H                /* Unix & Cygwin. */
637 +
638 +#include <sys/socket.h>
639 +#include <sys/un.h>
640 +#include <net/if.h>
641 +#include <netinet/in.h>
642 +#include <netinet/tcp.h>
643 +
644 +static inline int
645 +socket_errno (void)
646 +{
647 +  return errno;
648 +}
649 +
650 +#else                           /* MinGW & Win32 */
651 +
652 +#include <winsock2.h>
653 +
654 +/* Socket functions in Windows don't set errno.  Instead of using errno
655 + * to test for socket errors, call this function to get the errno.
656 + */
657 +static inline int
658 +socket_errno (void)
659 +{
660 +  return WSAGetLastError ();
661 +}
662 +
663 +/* Compatibility. */
664 +#define EWOULDBLOCK             WSAEWOULDBLOCK
665 +#define ECONNREFUSED            WSAECONNREFUSED
666 +#define EINPROGRESS             WSAEINPROGRESS
667 +#define EHOSTUNREACH            WSAEHOSTUNREACH
668 +#define EISCONN                 WSAEISCONN
669 +
670 +#endif /* HAVE_WINSOCK2_H */
671 +
672 +#endif /* __WINSOCKWRAPPER_H__ */
673 diff -urN gtk-vnc-0.3.7/src/vncdisplay.c gtk-vnc-0.3.7.mingw/src/vncdisplay.c
674 --- gtk-vnc-0.3.7/src/vncdisplay.c      2008-10-09 12:16:42.000000000 +0100
675 +++ gtk-vnc-0.3.7.mingw/src/vncdisplay.c        2008-10-09 12:19:03.000000000 +0100
676 @@ -8,6 +8,8 @@
677   *  GTK VNC Widget
678   */
679  
680 +#include <config.h>
681 +
682  #include "vncdisplay.h"
683  #include "coroutine.h"
684  #include "gvnc.h"
685 @@ -24,7 +26,9 @@
686  #include <sys/types.h>
687  #include <sys/stat.h>
688  #include <unistd.h>
689 +#ifdef HAVE_PWD_H
690  #include <pwd.h>
691 +#endif
692  
693  #if WITH_GTKGLEXT
694  #include <gtk/gtkgl.h>
695 @@ -2191,33 +2195,44 @@
696  
697  static int vnc_display_set_x509_credential(VncDisplay *obj, const char *name)
698  {
699 -       char sysdir[PATH_MAX], userdir[PATH_MAX];
700 -       struct passwd *pw;
701         char file[PATH_MAX];
702 +       char sysdir[PATH_MAX];
703 +#ifndef __MINGW32__
704 +       char userdir[PATH_MAX];
705 +       struct passwd *pw;
706         char *dirs[] = { sysdir, userdir };
707 +#else
708 +       char *dirs[] = { sysdir };
709 +#endif
710  
711         strncpy(sysdir, SYSCONFDIR "/pki", PATH_MAX-1);
712         sysdir[PATH_MAX-1] = '\0';
713  
714 +#ifndef __MINGW32__
715         if (!(pw = getpwuid(getuid())))
716                 return TRUE;
717  
718         snprintf(userdir, PATH_MAX-1, "%s/.pki", pw->pw_dir);
719         userdir[PATH_MAX-1] = '\0';
720 +#endif
721  
722 -       if (vnc_display_best_path(file, PATH_MAX, "CA", "cacert.pem", dirs, 2) < 0)
723 +       if (vnc_display_best_path(file, PATH_MAX, "CA", "cacert.pem",
724 +                                 dirs, sizeof(dirs)/sizeof(dirs[0])) < 0)
725                 return TRUE;
726         gvnc_set_credential_x509_cacert(obj->priv->gvnc, file);
727  
728         /* Don't mind failures of CRL */
729 -       if (vnc_display_best_path(file, PATH_MAX, "CA", "cacrl.pem", dirs, 2) == 0)
730 +       if (vnc_display_best_path(file, PATH_MAX, "CA", "cacrl.pem",
731 +                                 dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
732                 gvnc_set_credential_x509_cacert(obj->priv->gvnc, file);
733  
734         /* Set client key & cert if we have them. Server will reject auth
735          * if it decides it requires them*/
736 -       if (vnc_display_best_path(file, PATH_MAX, name, "private/clientkey.pem", dirs, 2) == 0)
737 +       if (vnc_display_best_path(file, PATH_MAX, name, "private/clientkey.pem",
738 +                                 dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
739                 gvnc_set_credential_x509_key(obj->priv->gvnc, file);
740 -       if (vnc_display_best_path(file, PATH_MAX, name, "clientcert.pem", dirs, 2) == 0)
741 +       if (vnc_display_best_path(file, PATH_MAX, name, "clientcert.pem",
742 +                                 dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
743                 gvnc_set_credential_x509_cert(obj->priv->gvnc, file);
744  
745         return FALSE;
746 diff -urN gtk-vnc-0.3.7/src/vncdisplay.c.orig gtk-vnc-0.3.7.mingw/src/vncdisplay.c.orig
747 --- gtk-vnc-0.3.7/src/vncdisplay.c.orig 2008-09-05 13:32:16.000000000 +0100
748 +++ gtk-vnc-0.3.7.mingw/src/vncdisplay.c.orig   1970-01-01 01:00:00.000000000 +0100
749 @@ -1,2491 +0,0 @@
750 -/*
751 - * Copyright (C) 2006  Anthony Liguori <anthony@codemonkey.ws>
752 - *
753 - * This program is free software; you can redistribute it and/or modify
754 - * it under the terms of the GNU Lesser General Public License version 2 or
755 - * later as published by the Free Software Foundation.
756 - *
757 - *  GTK VNC Widget
758 - */
759 -
760 -#include "vncdisplay.h"
761 -#include "coroutine.h"
762 -#include "gvnc.h"
763 -#include "utils.h"
764 -#include "vncmarshal.h"
765 -#include "config.h"
766 -#include "x_keymap.h"
767 -
768 -#include <gtk/gtk.h>
769 -#include <string.h>
770 -#include <stdlib.h>
771 -#include <gdk/gdkkeysyms.h>
772 -#include <gdk-pixbuf/gdk-pixbuf.h>
773 -#include <sys/types.h>
774 -#include <sys/stat.h>
775 -#include <unistd.h>
776 -#include <pwd.h>
777 -
778 -#if WITH_GTKGLEXT
779 -#include <gtk/gtkgl.h>
780 -#include <GL/gl.h>
781 -#endif
782 -
783 -#define VNC_DISPLAY_GET_PRIVATE(obj) \
784 -      (G_TYPE_INSTANCE_GET_PRIVATE((obj), VNC_TYPE_DISPLAY, VncDisplayPrivate))
785 -
786 -struct _VncDisplayPrivate
787 -{
788 -       int fd;
789 -       char *host;
790 -       char *port;
791 -       GdkGC *gc;
792 -       GdkImage *image;
793 -       GdkCursor *null_cursor;
794 -       GdkCursor *remote_cursor;
795 -
796 -#if WITH_GTKGLEXT
797 -       int gl_enabled;
798 -       GdkGLConfig *gl_config;
799 -       GdkGLDrawable *gl_drawable;
800 -       GdkGLContext *gl_context;
801 -       uint8_t *gl_tex_data;
802 -       int gl_texture_width;
803 -       int gl_texture_height;
804 -       int gl_width;
805 -       int gl_height;
806 -       GLuint gl_tex;
807 -#endif
808 -
809 -       struct gvnc_framebuffer fb;
810 -       struct coroutine coroutine;
811 -       struct gvnc *gvnc;
812 -
813 -       guint open_id;
814 -
815 -       gboolean in_pointer_grab;
816 -       gboolean in_keyboard_grab;
817 -
818 -       guint down_keyval[16];
819 -       guint down_scancode[16];
820 -
821 -       int button_mask;
822 -       int last_x;
823 -       int last_y;
824 -
825 -       gboolean absolute;
826 -
827 -       gboolean grab_pointer;
828 -       gboolean grab_keyboard;
829 -       gboolean local_pointer;
830 -       gboolean read_only;
831 -       gboolean allow_lossy;
832 -       gboolean allow_scaling;
833 -       gboolean shared_flag;
834 -       gboolean force_size;
835 -
836 -       GSList *preferable_auths;
837 -};
838 -
839 -/* Delayed signal emission.
840 - *
841 - * We want signals to be delivered in the system coroutine.  This helps avoid
842 - * confusing applications.  This is particularly important when using
843 - * GThread based coroutines since GTK gets very upset if a signal handler is
844 - * run in a different thread from the main loop if that signal handler isn't
845 - * written to use explicit locking.
846 - */
847 -struct signal_data
848 -{
849 -       VncDisplay *obj;
850 -       struct coroutine *caller;
851 -
852 -       int signum;
853 -       GValueArray *cred_list;
854 -       int width;
855 -       int height;
856 -       const char *msg;
857 -       unsigned int auth_type;
858 -       GString *str;
859 -};
860 -
861 -G_DEFINE_TYPE(VncDisplay, vnc_display, GTK_TYPE_DRAWING_AREA)
862 -
863 -/* Properties */
864 -enum
865 -{
866 -  PROP_0,
867 -  PROP_POINTER_LOCAL,
868 -  PROP_POINTER_GRAB,
869 -  PROP_KEYBOARD_GRAB,
870 -  PROP_READ_ONLY,
871 -  PROP_WIDTH,
872 -  PROP_HEIGHT,
873 -  PROP_NAME,
874 -  PROP_LOSSY_ENCODING,
875 -  PROP_SCALING,
876 -  PROP_SHARED_FLAG,
877 -  PROP_FORCE_SIZE
878 -};
879 -
880 -/* Signals */
881 -typedef enum
882 -{
883 -       VNC_POINTER_GRAB,
884 -       VNC_POINTER_UNGRAB,
885 -       VNC_KEYBOARD_GRAB,
886 -       VNC_KEYBOARD_UNGRAB,
887 -
888 -       VNC_CONNECTED,
889 -       VNC_INITIALIZED,
890 -       VNC_DISCONNECTED,
891 -       VNC_AUTH_CREDENTIAL,
892 -
893 -       VNC_DESKTOP_RESIZE,
894 -
895 -       VNC_AUTH_FAILURE,
896 -       VNC_AUTH_UNSUPPORTED,
897 -
898 -       VNC_SERVER_CUT_TEXT,
899 -       VNC_BELL,
900 -
901 -       LAST_SIGNAL
902 -} vnc_display_signals;
903 -
904 -static guint signals[LAST_SIGNAL] = { 0, 0, 0, 0,
905 -                                     0, 0, 0, 0,
906 -                                     0, 0, 0, 0, 0,};
907 -static GParamSpec *signalCredParam;
908 -gboolean debug_enabled = FALSE;
909 -
910 -static const GOptionEntry gtk_vnc_args[] =
911 -{
912 -  { "gtk-vnc-debug", 0, 0, G_OPTION_ARG_NONE, &debug_enabled, "Enables debug output", 0 },
913 -  { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, 0 }
914 -};
915 -
916 -
917 -static void
918 -vnc_display_get_property (GObject    *object,
919 -                         guint       prop_id,
920 -                         GValue     *value,
921 -                         GParamSpec *pspec)
922 -{
923 -  VncDisplay *vnc = VNC_DISPLAY (object);
924 -
925 -  switch (prop_id)
926 -    {
927 -      case PROP_POINTER_LOCAL:
928 -        g_value_set_boolean (value, vnc->priv->local_pointer);
929 -       break;
930 -      case PROP_POINTER_GRAB:
931 -        g_value_set_boolean (value, vnc->priv->grab_pointer);
932 -       break;
933 -      case PROP_KEYBOARD_GRAB:
934 -        g_value_set_boolean (value, vnc->priv->grab_keyboard);
935 -       break;
936 -      case PROP_READ_ONLY:
937 -        g_value_set_boolean (value, vnc->priv->read_only);
938 -       break;
939 -      case PROP_WIDTH:
940 -        g_value_set_int (value, vnc_display_get_width (vnc));
941 -       break;
942 -      case PROP_HEIGHT:
943 -        g_value_set_int (value, vnc_display_get_height (vnc));
944 -       break;
945 -      case PROP_NAME:
946 -        g_value_set_string (value, vnc_display_get_name (vnc));
947 -       break;
948 -      case PROP_LOSSY_ENCODING:
949 -        g_value_set_boolean (value, vnc->priv->allow_lossy);
950 -       break;
951 -      case PROP_SCALING:
952 -        g_value_set_boolean (value, vnc->priv->allow_scaling);
953 -       break;
954 -      case PROP_SHARED_FLAG:
955 -        g_value_set_boolean (value, vnc->priv->shared_flag);
956 -       break;
957 -      case PROP_FORCE_SIZE:
958 -        g_value_set_boolean (value, vnc->priv->force_size);
959 -       break;
960 -      default:
961 -       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
962 -       break;                  
963 -    }
964 -}
965 -
966 -static void
967 -vnc_display_set_property (GObject      *object,
968 -                         guint         prop_id,
969 -                         const GValue *value,
970 -                         GParamSpec   *pspec)
971 -{
972 -  VncDisplay *vnc = VNC_DISPLAY (object);
973 -
974 -  switch (prop_id)
975 -    {
976 -      case PROP_POINTER_LOCAL:
977 -        vnc_display_set_pointer_local (vnc, g_value_get_boolean (value));
978 -        break;
979 -      case PROP_POINTER_GRAB:
980 -        vnc_display_set_pointer_grab (vnc, g_value_get_boolean (value));
981 -        break;
982 -      case PROP_KEYBOARD_GRAB:
983 -        vnc_display_set_keyboard_grab (vnc, g_value_get_boolean (value));
984 -        break;
985 -      case PROP_READ_ONLY:
986 -        vnc_display_set_read_only (vnc, g_value_get_boolean (value));
987 -        break;
988 -      case PROP_LOSSY_ENCODING:
989 -        vnc_display_set_lossy_encoding (vnc, g_value_get_boolean (value));
990 -        break;
991 -      case PROP_SCALING:
992 -        vnc_display_set_scaling (vnc, g_value_get_boolean (value));
993 -        break;
994 -      case PROP_SHARED_FLAG:
995 -        vnc_display_set_shared_flag (vnc, g_value_get_boolean (value));
996 -        break;
997 -      case PROP_FORCE_SIZE:
998 -        vnc_display_set_force_size (vnc, g_value_get_boolean (value));
999 -        break;
1000 -      default:
1001 -        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1002 -        break;                 
1003 -    }
1004 -}
1005 -
1006 -GtkWidget *vnc_display_new(void)
1007 -{
1008 -       return GTK_WIDGET(g_object_new(VNC_TYPE_DISPLAY, NULL));
1009 -}
1010 -
1011 -static GdkCursor *create_null_cursor(void)
1012 -{
1013 -       GdkBitmap *image;
1014 -       gchar data[4] = {0};
1015 -       GdkColor fg = { 0, 0, 0, 0 };
1016 -       GdkCursor *cursor;
1017 -
1018 -       image = gdk_bitmap_create_from_data(NULL, data, 1, 1);
1019 -
1020 -       cursor = gdk_cursor_new_from_pixmap(GDK_PIXMAP(image),
1021 -                                           GDK_PIXMAP(image),
1022 -                                           &fg, &fg, 0, 0);
1023 -       gdk_bitmap_unref(image);
1024 -
1025 -       return cursor;
1026 -}
1027 -
1028 -static gboolean expose_event(GtkWidget *widget, GdkEventExpose *expose)
1029 -{
1030 -       VncDisplay *obj = VNC_DISPLAY(widget);
1031 -       VncDisplayPrivate *priv = obj->priv;
1032 -       int x, y, w, h;
1033 -       GdkRectangle drawn;
1034 -       GdkRegion *clear, *copy;
1035 -
1036 -       GVNC_DEBUG("Expose %dx%d @ %d,%d\n",
1037 -                  expose->area.x,
1038 -                  expose->area.y,
1039 -                  expose->area.width,
1040 -                  expose->area.height);
1041 -
1042 -       if (priv->image == NULL) {
1043 -#if WITH_GTKGLEXT
1044 -               if (priv->gl_tex_data == NULL)
1045 -#endif
1046 -               {
1047 -                       GdkGC *gc = gdk_gc_new(widget->window);
1048 -                       gdk_draw_rectangle(widget->window, gc, TRUE,
1049 -                                          expose->area.x, expose->area.y,
1050 -                                          expose->area.width,
1051 -                                          expose->area.height);
1052 -                       g_object_unref(gc);
1053 -                       return TRUE;
1054 -               }
1055 -       }
1056 -
1057 -#if WITH_GTKGLEXT
1058 -       if (priv->gl_enabled) {
1059 -               float rx, ry;
1060 -               int wx = 0, wy = 0;
1061 -               int ww = priv->gl_width, wh = priv->gl_height;
1062 -               double scale_x, scale_y;
1063 -
1064 -               scale_x = (double)priv->gl_width / priv->fb.width;
1065 -               scale_y = (double)priv->gl_height / priv->fb.height;
1066 -
1067 -               x = expose->area.x / scale_x;
1068 -               y = expose->area.y / scale_y;
1069 -               w = expose->area.width / scale_x;
1070 -               h = expose->area.height / scale_y;
1071 -
1072 -               y -= 5;
1073 -               h += 10;
1074 -               if (y < 0)
1075 -                       y = 0;
1076 -
1077 -               x -= 5;
1078 -               w += 10;
1079 -               if (x < 0)
1080 -                       x = 0;
1081 -
1082 -               x = MIN(x, priv->fb.width);
1083 -               y = MIN(y, priv->fb.height);
1084 -               w = MIN(x + w, priv->fb.width);
1085 -               h = MIN(y + h, priv->fb.height);
1086 -               w -= x;
1087 -               h -= y;
1088 -
1089 -               gdk_gl_drawable_gl_begin(priv->gl_drawable, priv->gl_context);
1090 -               glBindTexture(GL_TEXTURE_2D, priv->gl_tex);
1091 -               glPixelStorei(GL_UNPACK_ROW_LENGTH, priv->fb.width);
1092 -               glTexSubImage2D(GL_TEXTURE_2D, 0,
1093 -                               x, y, w, h,
1094 -                               GL_BGRA_EXT,
1095 -                               GL_UNSIGNED_BYTE,
1096 -                               priv->gl_tex_data +
1097 -                               y * 4 * priv->fb.width +
1098 -                               x * 4);
1099 -               rx = (float)priv->fb.width  / priv->gl_texture_width;
1100 -               ry = (float)priv->fb.height / priv->gl_texture_height;
1101 -               
1102 -               glEnable(GL_TEXTURE_2D);
1103 -               glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
1104 -               glBegin(GL_QUADS);
1105 -               glTexCoord2f(0,ry);  glVertex3f(wx, wy, 0);
1106 -               glTexCoord2f(0,0);  glVertex3f(wx, wy+wh, 0);
1107 -               glTexCoord2f(rx,0);  glVertex3f(wx+ww, wy+wh, 0);
1108 -               glTexCoord2f(rx,ry);  glVertex3f(wx+ww, wy, 0);
1109 -               glEnd();                
1110 -               glDisable(GL_TEXTURE_2D);
1111 -               glFlush();
1112 -               gdk_gl_drawable_gl_end(priv->gl_drawable);
1113 -       } else
1114 -#endif
1115 -       {
1116 -               int mx = 0, my = 0;
1117 -               int ww, wh;
1118 -
1119 -               gdk_drawable_get_size(widget->window, &ww, &wh);
1120 -               if (ww > priv->fb.width)
1121 -                       mx = (ww - priv->fb.width) / 2;
1122 -               if (wh > priv->fb.height)
1123 -                       my = (wh - priv->fb.height) / 2;
1124 -
1125 -               x = MIN(expose->area.x - mx, priv->fb.width);
1126 -               y = MIN(expose->area.y - my, priv->fb.height);
1127 -               w = MIN(expose->area.x + expose->area.width - mx, priv->fb.width);
1128 -               h = MIN(expose->area.y + expose->area.height - my, priv->fb.height);
1129 -               x = MAX(0, x);
1130 -               y = MAX(0, y);
1131 -               w = MAX(0, w);
1132 -               h = MAX(0, h);
1133 -
1134 -               w -= x;
1135 -               h -= y;
1136 -
1137 -               drawn.x = x + mx;
1138 -               drawn.y = y + my;
1139 -               drawn.width = w;
1140 -               drawn.height = h;
1141 -
1142 -               clear = gdk_region_rectangle(&expose->area);
1143 -               copy = gdk_region_rectangle(&drawn);
1144 -               gdk_region_subtract(clear, copy);
1145 -
1146 -               gdk_gc_set_clip_region(priv->gc, copy);
1147 -               gdk_draw_image(widget->window, priv->gc, priv->image,
1148 -                              x, y, x + mx, y + my, w, h);
1149 -
1150 -               gdk_gc_set_clip_region(priv->gc, clear);
1151 -               gdk_draw_rectangle(widget->window, priv->gc, TRUE, expose->area.x, expose->area.y,
1152 -                                  expose->area.width, expose->area.height);
1153 -
1154 -               gdk_region_destroy(clear);
1155 -               gdk_region_destroy(copy);
1156 -       }
1157 -
1158 -       return TRUE;
1159 -}
1160 -
1161 -static void do_keyboard_grab(VncDisplay *obj, gboolean quiet)
1162 -{
1163 -       VncDisplayPrivate *priv = obj->priv;
1164 -
1165 -       gdk_keyboard_grab(GTK_WIDGET(obj)->window,
1166 -                         FALSE,
1167 -                         GDK_CURRENT_TIME);
1168 -       priv->in_keyboard_grab = TRUE;
1169 -       if (!quiet)
1170 -               g_signal_emit(obj, signals[VNC_KEYBOARD_GRAB], 0);
1171 -}
1172 -
1173 -
1174 -static void do_keyboard_ungrab(VncDisplay *obj, gboolean quiet)
1175 -{
1176 -       VncDisplayPrivate *priv = obj->priv;
1177 -
1178 -       gdk_keyboard_ungrab(GDK_CURRENT_TIME);
1179 -       priv->in_keyboard_grab = FALSE;
1180 -       if (!quiet)
1181 -               g_signal_emit(obj, signals[VNC_KEYBOARD_UNGRAB], 0);
1182 -}
1183 -
1184 -static void do_pointer_hide(VncDisplay *obj)
1185 -{
1186 -       VncDisplayPrivate *priv = obj->priv;
1187 -       gdk_window_set_cursor(GTK_WIDGET(obj)->window,
1188 -                             priv->remote_cursor ? priv->remote_cursor : priv->null_cursor);
1189 -}
1190 -
1191 -static void do_pointer_show(VncDisplay *obj)
1192 -{
1193 -       VncDisplayPrivate *priv = obj->priv;
1194 -       gdk_window_set_cursor(GTK_WIDGET(obj)->window,
1195 -                             priv->remote_cursor);
1196 -}
1197 -
1198 -static void do_pointer_grab(VncDisplay *obj, gboolean quiet)
1199 -{
1200 -       VncDisplayPrivate *priv = obj->priv;
1201 -
1202 -       /* If we're not already grabbing keyboard, grab it now */
1203 -       if (!priv->grab_keyboard)
1204 -               do_keyboard_grab(obj, quiet);
1205 -
1206 -       gdk_pointer_grab(GTK_WIDGET(obj)->window,
1207 -                        TRUE,
1208 -                        GDK_POINTER_MOTION_MASK |
1209 -                        GDK_BUTTON_PRESS_MASK |
1210 -                        GDK_BUTTON_RELEASE_MASK |
1211 -                        GDK_BUTTON_MOTION_MASK |
1212 -                        GDK_SCROLL_MASK,
1213 -                        GTK_WIDGET(obj)->window,
1214 -                        priv->remote_cursor ? priv->remote_cursor : priv->null_cursor,
1215 -                        GDK_CURRENT_TIME);
1216 -       priv->in_pointer_grab = TRUE;
1217 -       if (!quiet)
1218 -               g_signal_emit(obj, signals[VNC_POINTER_GRAB], 0);
1219 -}
1220 -
1221 -static void do_pointer_ungrab(VncDisplay *obj, gboolean quiet)
1222 -{
1223 -       VncDisplayPrivate *priv = obj->priv;
1224 -
1225 -       /* If we grabbed keyboard upon pointer grab, then ungrab it now */
1226 -       if (!priv->grab_keyboard)
1227 -               do_keyboard_ungrab(obj, quiet);
1228 -
1229 -       gdk_pointer_ungrab(GDK_CURRENT_TIME);
1230 -       priv->in_pointer_grab = FALSE;
1231 -
1232 -       if (priv->absolute)
1233 -               do_pointer_hide(obj);
1234 -
1235 -       if (!quiet)
1236 -               g_signal_emit(obj, signals[VNC_POINTER_UNGRAB], 0);
1237 -}
1238 -
1239 -void vnc_display_force_grab(VncDisplay *obj, gboolean enable)
1240 -{
1241 -       if (enable)
1242 -               do_pointer_grab(obj, FALSE);
1243 -       else
1244 -               do_pointer_ungrab(obj, FALSE);
1245 -}
1246 -
1247 -static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
1248 -{
1249 -       VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
1250 -       int n;
1251 -
1252 -       if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
1253 -               return FALSE;
1254 -
1255 -       if (priv->read_only)
1256 -               return FALSE;
1257 -
1258 -       gtk_widget_grab_focus (widget);
1259 -
1260 -       if (priv->grab_pointer && !priv->absolute && !priv->in_pointer_grab &&
1261 -           button->button == 1 && button->type == GDK_BUTTON_PRESS)
1262 -               do_pointer_grab(VNC_DISPLAY(widget), FALSE);
1263 -
1264 -       n = 1 << (button->button - 1);
1265 -       if (button->type == GDK_BUTTON_PRESS)
1266 -               priv->button_mask |= n;
1267 -       else if (button->type == GDK_BUTTON_RELEASE)
1268 -               priv->button_mask &= ~n;
1269 -
1270 -       if (priv->absolute) {
1271 -               gvnc_pointer_event(priv->gvnc, priv->button_mask,
1272 -                                  priv->last_x, priv->last_y);
1273 -       } else {
1274 -               gvnc_pointer_event(priv->gvnc, priv->button_mask,
1275 -                                  0x7FFF, 0x7FFF);
1276 -       }
1277 -
1278 -       return TRUE;
1279 -}
1280 -
1281 -static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll)
1282 -{
1283 -       VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
1284 -       int mask;
1285 -
1286 -       if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
1287 -               return FALSE;
1288 -
1289 -       if (priv->read_only)
1290 -               return FALSE;
1291 -
1292 -       if (scroll->direction == GDK_SCROLL_UP)
1293 -               mask = (1 << 3);
1294 -       else if (scroll->direction == GDK_SCROLL_DOWN)
1295 -               mask = (1 << 4);
1296 -       else if (scroll->direction == GDK_SCROLL_LEFT)
1297 -               mask = (1 << 5);
1298 -       else if (scroll->direction == GDK_SCROLL_RIGHT)
1299 -               mask = (1 << 6);
1300 -       else
1301 -               return FALSE;
1302 -
1303 -       if (priv->absolute) {
1304 -               gvnc_pointer_event(priv->gvnc, priv->button_mask | mask,
1305 -                                  priv->last_x, priv->last_y);
1306 -               gvnc_pointer_event(priv->gvnc, priv->button_mask,
1307 -                                  priv->last_x, priv->last_y);
1308 -       } else {
1309 -               gvnc_pointer_event(priv->gvnc, priv->button_mask | mask,
1310 -                                  0x7FFF, 0x7FFF);
1311 -               gvnc_pointer_event(priv->gvnc, priv->button_mask,
1312 -                                  0x7FFF, 0x7FFF);
1313 -       }
1314 -
1315 -       return TRUE;
1316 -}
1317 -
1318 -static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
1319 -{
1320 -       VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
1321 -       int dx, dy;
1322 -
1323 -       if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
1324 -               return FALSE;
1325 -
1326 -       if (!priv->absolute && !priv->in_pointer_grab)
1327 -               return FALSE;
1328 -
1329 -       if (priv->read_only)
1330 -               return FALSE;
1331 -
1332 -#if WITH_GTKGLEXT
1333 -       if (priv->gl_enabled) {
1334 -               motion->x *= priv->fb.width;
1335 -               motion->x /= priv->gl_width;
1336 -               motion->y *= priv->fb.height;
1337 -               motion->y /= priv->gl_height;
1338 -       } else
1339 -#endif
1340 -       {
1341 -               int ww, wh;
1342 -               int mw = 0, mh = 0;
1343 -
1344 -               gdk_drawable_get_size(widget->window, &ww, &wh);
1345 -               if (ww > priv->fb.width)
1346 -                       mw = (ww - priv->fb.width) / 2;
1347 -               if (wh > priv->fb.height)
1348 -                       mh = (wh - priv->fb.height) / 2;
1349 -
1350 -               motion->x -= mw;
1351 -               motion->y -= mh;
1352 -
1353 -               if (motion->x < 0 || motion->x >= priv->fb.width ||
1354 -                   motion->y < 0 || motion->y >= priv->fb.height)
1355 -                       return FALSE;
1356 -       }
1357 -
1358 -       if (!priv->absolute && priv->in_pointer_grab) {
1359 -               GdkDrawable *drawable = GDK_DRAWABLE(widget->window);
1360 -               GdkDisplay *display = gdk_drawable_get_display(drawable);
1361 -               GdkScreen *screen = gdk_drawable_get_screen(drawable);
1362 -               int x = (int)motion->x_root;
1363 -               int y = (int)motion->y_root;
1364 -
1365 -               if (x == 0) x += 200;
1366 -               if (y == 0) y += 200;
1367 -               if (x == (gdk_screen_get_width(screen) - 1)) x -= 200;
1368 -               if (y == (gdk_screen_get_height(screen) - 1)) y -= 200;
1369 -
1370 -               if (x != (int)motion->x_root || y != (int)motion->y_root) {
1371 -                       gdk_display_warp_pointer(display, screen, x, y);
1372 -                       priv->last_x = -1;
1373 -                       priv->last_y = -1;
1374 -                       return FALSE;
1375 -               }
1376 -       }
1377 -
1378 -       if (priv->last_x != -1) {
1379 -               if (priv->absolute) {
1380 -                       dx = (int)motion->x;
1381 -                       dy = (int)motion->y;
1382 -               } else {
1383 -                       dx = (int)motion->x + 0x7FFF - priv->last_x;
1384 -                       dy = (int)motion->y + 0x7FFF - priv->last_y;
1385 -               }
1386 -
1387 -               gvnc_pointer_event(priv->gvnc, priv->button_mask, dx, dy);
1388 -       }
1389 -
1390 -       priv->last_x = (int)motion->x;
1391 -       priv->last_y = (int)motion->y;
1392 -
1393 -       return TRUE;
1394 -}
1395 -
1396 -static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
1397 -{
1398 -       VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
1399 -       guint keyval;
1400 -       gint group, level;
1401 -       GdkModifierType consumed;
1402 -
1403 -       if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
1404 -               return FALSE;
1405 -
1406 -       if (priv->read_only)
1407 -               return FALSE;
1408 -
1409 -       /*
1410 -        * Key handling in VNC is screwy. The event.keyval from GTK is
1411 -        * interpreted relative to modifier state. This really messes
1412 -        * up with VNC which has no concept of modifiers - it just sees
1413 -        * key up & down events - the remote end interprets modifiers
1414 -        * itself. So if we interpret at the client end you can end up
1415 -        * with 'Alt' key press generating Alt_L, and key release generating
1416 -        * ISO_Prev_Group. This really really confuses the VNC server
1417 -        * with 'Alt' getting stuck on.
1418 -        *
1419 -        * So we have to redo GTK's  keycode -> keyval translation
1420 -        * using only the SHIFT modifier which the RFB explicitly
1421 -        * requires to be interpreted at client end.
1422 -        *
1423 -        * Arggggh.
1424 -        */
1425 -       gdk_keymap_translate_keyboard_state(gdk_keymap_get_default(),
1426 -                                           key->hardware_keycode,
1427 -                                           key->state & (GDK_SHIFT_MASK | GDK_LOCK_MASK),
1428 -                                           key->group,
1429 -                                           &keyval,
1430 -                                           &group,
1431 -                                           &level,
1432 -                                           &consumed);
1433 -
1434 -       keyval = x_keymap_get_keyval_from_keycode(key->hardware_keycode, keyval);
1435 -
1436 -       /*
1437 -        * More VNC suckiness with key state & modifiers in particular
1438 -        *
1439 -        * Because VNC has no concept of modifiers, we have to track what keys are
1440 -        * pressed and when the widget looses focus send fake key up events for all
1441 -        * keys current held down. This is because upon gaining focus any keys held
1442 -        * down are no longer likely to be down. This would thus result in keys
1443 -        * being 'stuck on' in the remote server. eg upon Alt-Tab to switch window
1444 -        * focus you'd never see key up for the Alt or Tab keys without this :-(
1445 -        *
1446 -        * This is mostly a problem with modifier keys, but its best to just track
1447 -        * all key presses regardless. There's a limit to how many keys a user can
1448 -        * press at once due to a max of 10 fingers (normally :-), so down_key_vals
1449 -        * is only storing upto 16 for now. Should be plenty...
1450 -        *
1451 -        * Arggggh.
1452 -        */
1453 -       if (key->type == GDK_KEY_PRESS) {
1454 -               int i;
1455 -               for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
1456 -                       if (priv->down_scancode[i] == 0) {
1457 -                               priv->down_keyval[i] = keyval;
1458 -                               priv->down_scancode[i] = key->hardware_keycode;
1459 -                               /* Send the actual key event we're dealing with */
1460 -                               gvnc_key_event(priv->gvnc, 1, keyval, key->hardware_keycode);
1461 -                               break;
1462 -                       } else if (priv->down_scancode[i] == key->hardware_keycode) {
1463 -                               /* Got an press when we're already pressed ! Why ... ?
1464 -                                *
1465 -                                * Well, GTK merges sequential press+release pairs of the same
1466 -                                * key so instead of press+release,press+release,press+release
1467 -                                * we only get press+press+press+press+press+release. This
1468 -                                * really annoys some VNC servers, so we have to un-merge
1469 -                                * them into a sensible stream of press+release pairs
1470 -                                */
1471 -                               /* Fake an up event for the previous down event */
1472 -                               gvnc_key_event(priv->gvnc, 0, keyval, key->hardware_keycode);
1473 -                               /* Now send our actual ldown event */
1474 -                               gvnc_key_event(priv->gvnc, 1, keyval, key->hardware_keycode);
1475 -                               break;
1476 -                       }
1477 -               }
1478 -       } else {
1479 -               int i;
1480 -               for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
1481 -                       /* We were pressed, and now we're released, so... */
1482 -                       if (priv->down_scancode[i] == key->hardware_keycode) {
1483 -                               priv->down_keyval[i] = 0;
1484 -                               priv->down_scancode[i] = 0;
1485 -                               /* ..send the key release event we're dealing with */
1486 -                               gvnc_key_event(priv->gvnc, 0, keyval, key->hardware_keycode);
1487 -                               break;
1488 -                       }
1489 -               }
1490 -       }
1491 -
1492 -       if ((!priv->grab_keyboard || !priv->absolute) &&
1493 -           key->type == GDK_KEY_PRESS &&
1494 -           ((keyval == GDK_Control_L && (key->state & GDK_MOD1_MASK)) ||
1495 -            (keyval == GDK_Alt_L && (key->state & GDK_CONTROL_MASK)))) {
1496 -               if (priv->in_pointer_grab)
1497 -                       do_pointer_ungrab(VNC_DISPLAY(widget), FALSE);
1498 -               else
1499 -                       do_pointer_grab(VNC_DISPLAY(widget), FALSE);
1500 -       }
1501 -
1502 -       return TRUE;
1503 -}
1504 -
1505 -static gboolean enter_event(GtkWidget *widget, GdkEventCrossing *crossing)
1506 -{
1507 -        VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
1508 -
1509 -        if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
1510 -                return FALSE;
1511 -
1512 -        if (crossing->mode != GDK_CROSSING_NORMAL)
1513 -                return FALSE;
1514 -
1515 -        if (priv->grab_keyboard)
1516 -                do_keyboard_grab(VNC_DISPLAY(widget), FALSE);
1517 -
1518 -        return TRUE;
1519 -}
1520 -
1521 -static gboolean leave_event(GtkWidget *widget, GdkEventCrossing *crossing)
1522 -{
1523 -        VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
1524 -
1525 -        if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
1526 -                return FALSE;
1527 -
1528 -        if (crossing->mode != GDK_CROSSING_NORMAL)
1529 -                return FALSE;
1530 -
1531 -        if (priv->grab_keyboard)
1532 -                do_keyboard_ungrab(VNC_DISPLAY(widget), FALSE);
1533 -
1534 -        if (priv->grab_pointer)
1535 -                do_pointer_ungrab(VNC_DISPLAY(widget), FALSE);
1536 -
1537 -        return TRUE;
1538 -}
1539 -
1540 -
1541 -static gboolean focus_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSED)
1542 -{
1543 -        VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
1544 -       int i;
1545 -
1546 -        if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
1547 -                return FALSE;
1548 -
1549 -       for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
1550 -               /* We are currently pressed so... */
1551 -               if (priv->down_scancode[i] != 0) {
1552 -                       /* ..send the fake key release event to match */
1553 -                       gvnc_key_event(priv->gvnc, 0,
1554 -                                      priv->down_keyval[i], priv->down_scancode[i]);
1555 -                       priv->down_keyval[i] = 0;
1556 -                       priv->down_scancode[i] = 0;
1557 -               }
1558 -       }
1559 -
1560 -        return TRUE;
1561 -}
1562 -
1563 -#if WITH_GTKGLEXT
1564 -static void realize_event(GtkWidget *widget)
1565 -{
1566 -       VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
1567 -
1568 -       GTK_WIDGET_CLASS (vnc_display_parent_class)->realize(widget);
1569 -
1570 -       if (priv->gl_config == NULL)
1571 -               return;
1572 -
1573 -       priv->gl_drawable = gtk_widget_get_gl_drawable(widget);
1574 -       priv->gl_context = gtk_widget_get_gl_context(widget);
1575 -}
1576 -#endif
1577 -
1578 -static gboolean on_update(void *opaque, int x, int y, int w, int h)
1579 -{
1580 -       GtkWidget *widget = GTK_WIDGET(opaque);
1581 -       VncDisplay *obj = VNC_DISPLAY(widget);
1582 -       VncDisplayPrivate *priv = obj->priv;
1583 -
1584 -#if WITH_GTKGLEXT
1585 -       if (priv->gl_enabled) {
1586 -               double scale_x, scale_y;
1587 -
1588 -               scale_x = (double)priv->gl_width / priv->fb.width;
1589 -               scale_y = (double)priv->gl_height / priv->fb.height;
1590 -
1591 -               x *= scale_x;
1592 -               y *= scale_y;
1593 -               w *= scale_x;
1594 -               h *= scale_y;
1595 -       } else
1596 -#endif
1597 -       {
1598 -               int ww, wh;
1599 -               int mw = 0, mh = 0;
1600 -
1601 -               gdk_drawable_get_size(widget->window, &ww, &wh);
1602 -               if (ww > priv->fb.width)
1603 -                       mw = (ww - priv->fb.width) / 2;
1604 -               if (wh > priv->fb.height)
1605 -                       mh = (wh - priv->fb.height) / 2;
1606 -
1607 -               x += mw;
1608 -               y += mh;
1609 -       }
1610 -
1611 -       gtk_widget_queue_draw_area(widget, x, y, w, h);
1612 -
1613 -       return TRUE;
1614 -}
1615 -
1616 -static void setup_gdk_image(VncDisplay *obj, gint width, gint height)
1617 -{
1618 -       VncDisplayPrivate *priv = obj->priv;
1619 -       GdkVisual *visual;
1620 -
1621 -       visual = gdk_drawable_get_visual(GTK_WIDGET(obj)->window);
1622 -
1623 -       priv->image = gdk_image_new(GDK_IMAGE_FASTEST, visual, width, height);
1624 -       GVNC_DEBUG("Visual mask: %3d %3d %3d\n      shift: %3d %3d %3d\n",
1625 -                  visual->red_mask,
1626 -                  visual->green_mask,
1627 -                  visual->blue_mask,
1628 -                  visual->red_shift,
1629 -                  visual->green_shift,
1630 -                  visual->blue_shift);
1631 -
1632 -       priv->fb.red_mask = visual->red_mask >> visual->red_shift;
1633 -       priv->fb.green_mask = visual->green_mask >> visual->green_shift;
1634 -       priv->fb.blue_mask = visual->blue_mask >> visual->blue_shift;
1635 -       priv->fb.red_shift = visual->red_shift;
1636 -       priv->fb.green_shift = visual->green_shift;
1637 -       priv->fb.blue_shift = visual->blue_shift;
1638 -       priv->fb.depth = priv->image->depth;
1639 -       priv->fb.bpp = priv->image->bpp;
1640 -       priv->fb.width = priv->image->width;
1641 -       priv->fb.height = priv->image->height;
1642 -       priv->fb.linesize = priv->image->bpl;
1643 -       priv->fb.data = (uint8_t *)priv->image->mem;
1644 -       priv->fb.byte_order = priv->image->byte_order == GDK_LSB_FIRST ? G_LITTLE_ENDIAN : G_BIG_ENDIAN;
1645 -
1646 -       if (priv->force_size)
1647 -               gtk_widget_set_size_request(GTK_WIDGET(obj), width, height);
1648 -}
1649 -
1650 -#if WITH_GTKGLEXT
1651 -static int pow_of_2(int value)
1652 -{
1653 -       int i;
1654 -       for (i = 0; value >= (1 << i); i++);
1655 -       return (1 << i);
1656 -}
1657 -
1658 -static void setup_gl_image(VncDisplay *obj, gint width, gint height)
1659 -{
1660 -       VncDisplayPrivate *priv = VNC_DISPLAY(obj)->priv;
1661 -       void *dummy;
1662 -
1663 -       priv->gl_texture_width = pow_of_2(width);
1664 -       priv->gl_texture_height = pow_of_2(height);
1665 -
1666 -       gdk_gl_drawable_gl_begin(priv->gl_drawable, priv->gl_context);
1667 -
1668 -       glGenTextures(1, &priv->gl_tex);
1669 -       glBindTexture(GL_TEXTURE_2D, priv->gl_tex);
1670 -       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1671 -       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1672 -
1673 -       dummy = g_malloc(priv->gl_texture_width*priv->gl_texture_height*4);
1674 -       memset(dummy, 0, priv->gl_texture_width*priv->gl_texture_height*4);
1675 -       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
1676 -                    priv->gl_texture_width, priv->gl_texture_height, 0,
1677 -                    GL_RGB, GL_UNSIGNED_BYTE,
1678 -                    dummy);
1679 -       g_free(dummy);
1680 -       
1681 -       gdk_gl_drawable_gl_end(priv->gl_drawable);
1682 -
1683 -       priv->gl_tex_data = g_malloc(width * height * 4);
1684 -
1685 -       priv->fb.red_mask = 0xFF;
1686 -       priv->fb.green_mask = 0xFF;
1687 -       priv->fb.blue_mask = 0xFF;
1688 -       priv->fb.red_shift = 16;
1689 -       priv->fb.green_shift = 8;
1690 -       priv->fb.blue_shift = 0;
1691 -       priv->fb.depth = 32;
1692 -       priv->fb.bpp = 4;
1693 -       priv->fb.width = width;
1694 -       priv->fb.height = height;
1695 -       priv->fb.linesize = priv->fb.width * priv->fb.bpp;
1696 -       priv->fb.data = (uint8_t *)priv->gl_tex_data;
1697 -}
1698 -#endif
1699 -
1700 -static gboolean emit_signal_auth_cred(gpointer opaque)
1701 -{
1702 -       struct signal_data *s = opaque;
1703 -
1704 -       switch (s->signum) {
1705 -       case VNC_AUTH_CREDENTIAL:
1706 -               g_signal_emit(G_OBJECT(s->obj),
1707 -                             signals[VNC_AUTH_CREDENTIAL],
1708 -                             0,
1709 -                             s->cred_list);
1710 -               break;
1711 -       case VNC_DESKTOP_RESIZE:
1712 -               g_signal_emit(G_OBJECT(s->obj),
1713 -                             signals[VNC_DESKTOP_RESIZE],
1714 -                             0,
1715 -                             s->width, s->height);
1716 -               break;
1717 -       case VNC_AUTH_FAILURE:
1718 -               g_signal_emit(G_OBJECT(s->obj),
1719 -                             signals[VNC_AUTH_FAILURE],
1720 -                             0,
1721 -                             s->msg);
1722 -               break;
1723 -       case VNC_AUTH_UNSUPPORTED:
1724 -               g_signal_emit(G_OBJECT(s->obj),
1725 -                             signals[VNC_AUTH_UNSUPPORTED],
1726 -                             0,
1727 -                             s->auth_type);
1728 -               break;
1729 -       case VNC_SERVER_CUT_TEXT:
1730 -               g_signal_emit(G_OBJECT(s->obj),
1731 -                             signals[VNC_SERVER_CUT_TEXT],
1732 -                             0,
1733 -                             s->str->str);
1734 -               break;
1735 -       case VNC_BELL:
1736 -       case VNC_CONNECTED:
1737 -       case VNC_INITIALIZED:
1738 -       case VNC_DISCONNECTED:
1739 -               g_signal_emit(G_OBJECT(s->obj),
1740 -                             signals[s->signum],
1741 -                             0);
1742 -               break;
1743 -       }
1744 -
1745 -       coroutine_yieldto(s->caller, NULL);
1746 -       
1747 -       return FALSE;
1748 -}
1749 -
1750 -/* This function should be used to emit signals from gvnc callbacks */
1751 -static void emit_signal_delayed(VncDisplay *obj, int signum,
1752 -                               struct signal_data *data)
1753 -{
1754 -       data->obj = obj;
1755 -       data->caller = coroutine_self();
1756 -       data->signum = signum;
1757 -       g_idle_add(emit_signal_auth_cred, data);
1758 -       coroutine_yield(NULL);
1759 -}
1760 -
1761 -static gboolean do_resize(void *opaque, int width, int height, gboolean quiet)
1762 -{
1763 -       VncDisplay *obj = VNC_DISPLAY(opaque);
1764 -       VncDisplayPrivate *priv = obj->priv;
1765 -       struct signal_data s;
1766 -
1767 -       if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
1768 -               return TRUE;
1769 -
1770 -       if (priv->image) {
1771 -               g_object_unref(priv->image);
1772 -               priv->image = NULL;
1773 -       }
1774 -
1775 -#if WITH_GTKGLEXT
1776 -       if (priv->gl_tex_data) {
1777 -               gdk_gl_drawable_gl_begin(priv->gl_drawable,
1778 -                                        priv->gl_context);
1779 -               glDeleteTextures(1, &priv->gl_tex);
1780 -               gdk_gl_drawable_gl_end(priv->gl_drawable);
1781 -               g_free(priv->gl_tex_data);
1782 -               priv->gl_tex_data = NULL;
1783 -       }
1784 -#endif
1785 -
1786 -       if (priv->gc == NULL) {
1787 -               priv->null_cursor = create_null_cursor();
1788 -               if (priv->local_pointer)
1789 -                       do_pointer_show(obj);
1790 -               else if (priv->in_pointer_grab || priv->absolute)
1791 -                       do_pointer_hide(obj);
1792 -               priv->gc = gdk_gc_new(GTK_WIDGET(obj)->window);
1793 -       }
1794 -
1795 -#if WITH_GTKGLEXT
1796 -       if (priv->gl_enabled)
1797 -               setup_gl_image(obj, width, height);
1798 -       else
1799 -#endif
1800 -               setup_gdk_image(obj, width, height);
1801 -
1802 -       gvnc_set_local(priv->gvnc, &priv->fb);
1803 -
1804 -       if (!quiet) {
1805 -               s.width = width;
1806 -               s.height = height;
1807 -               emit_signal_delayed(obj, VNC_DESKTOP_RESIZE, &s);
1808 -       }
1809 -
1810 -       return TRUE;
1811 -}
1812 -
1813 -static gboolean on_resize(void *opaque, int width, int height)
1814 -{
1815 -       return do_resize(opaque, width, height, FALSE);
1816 -}
1817 -
1818 -static gboolean on_pixel_format(void *opaque, 
1819 -       struct gvnc_pixel_format *fmt G_GNUC_UNUSED)
1820 -{
1821 -        VncDisplay *obj = VNC_DISPLAY(opaque);
1822 -        VncDisplayPrivate *priv = obj->priv;
1823 -
1824 -        return do_resize(opaque, priv->fb.width, priv->fb.height, TRUE);
1825 -}
1826 -
1827 -static gboolean on_get_preferred_pixel_format(void *opaque,
1828 -       struct gvnc_pixel_format *fmt)
1829 -{
1830 -       VncDisplay *obj = VNC_DISPLAY(opaque);
1831 -       GdkVisual *v =  gdk_drawable_get_visual(GTK_WIDGET(obj)->window);
1832 -
1833 -       GVNC_DEBUG("Setting pixel format to true color\n");
1834 -
1835 -       fmt->true_color_flag = 1;
1836 -       fmt->depth = v->depth;
1837 -       fmt->bits_per_pixel = v->depth > 16 ? 32 : v->depth;
1838 -       fmt->red_max = v->red_mask >> v->red_shift;
1839 -       fmt->green_max = v->green_mask >> v->green_shift;
1840 -       fmt->blue_max = v->blue_mask >> v->blue_shift;
1841 -       fmt->red_shift = v->red_shift;
1842 -       fmt->green_shift = v->green_shift;
1843 -       fmt->blue_shift = v->blue_shift;
1844 -       fmt->byte_order = v->byte_order == GDK_LSB_FIRST ? G_BIG_ENDIAN : G_LITTLE_ENDIAN;
1845 -
1846 -       return TRUE;
1847 -}
1848 -
1849 -#if WITH_GTKGLEXT
1850 -static void build_gl_image_from_gdk(uint32_t *data, GdkImage *image)
1851 -{
1852 -       GdkVisual *visual;
1853 -       int i, j;
1854 -       uint8_t *row;
1855 -
1856 -       visual = image->visual;
1857 -       row = image->mem;
1858 -       for (j = 0; j < image->height; j++) {
1859 -               uint8_t *src = row;
1860 -               for (i = 0; i < image->width; i++) {
1861 -                       uint32_t pixel = 0;
1862 -                       switch (image->bpp) {
1863 -                       case 1:
1864 -                               pixel = *(uint8_t *)src;
1865 -                               break;
1866 -                       case 2:
1867 -                               pixel = *(uint16_t *)src;
1868 -                               break;
1869 -                       case 4:
1870 -                               pixel = *(uint32_t *)src;
1871 -                               break;
1872 -                       }
1873 -                       *data = ((pixel & visual->red_mask) >> visual->red_shift) << (24 - visual->red_prec) |
1874 -                               ((pixel & visual->green_mask) >> visual->green_shift) << (16 - visual->green_prec) |
1875 -                               ((pixel & visual->blue_mask) >> visual->blue_shift) << (8 - visual->blue_prec);
1876 -                       src += image->bpp;
1877 -                       data++;
1878 -               }
1879 -               row += image->bpl;
1880 -
1881 -       }
1882 -}
1883 -
1884 -static void build_gdk_image_from_gl(GdkImage *image, uint32_t *data)
1885 -{
1886 -       GdkVisual *visual;
1887 -       int i, j;
1888 -       uint8_t *row;
1889 -
1890 -       visual = image->visual;
1891 -       row = image->mem;
1892 -       for (j = 0; j < image->height; j++) {
1893 -               uint8_t *dst = row;
1894 -               for (i = 0; i < image->width; i++) {
1895 -                       uint32_t pixel;
1896 -
1897 -                       pixel = (((*data >> (24 - visual->red_prec)) << visual->red_shift) & visual->red_mask) |
1898 -                               (((*data >> (16 - visual->green_prec)) << visual->green_shift) & visual->green_mask) |
1899 -                               (((*data >> (8 - visual->blue_prec)) << visual->blue_shift) & visual->blue_mask);
1900 -
1901 -                       switch (image->bpp) {
1902 -                       case 1:
1903 -                               *(uint8_t *)dst = pixel;
1904 -                               break;
1905 -                       case 2:
1906 -                               *(uint16_t *)dst = pixel;
1907 -                               break;
1908 -                       case 4:
1909 -                               *(uint32_t *)dst = pixel;
1910 -                               break;
1911 -                       }
1912 -                       dst += image->bpp;
1913 -                       data++;
1914 -               }
1915 -               row += image->bpl;
1916 -       }
1917 -}
1918 -
1919 -static void scale_display(VncDisplay *obj, gint width, gint height)
1920 -{
1921 -       VncDisplayPrivate *priv = VNC_DISPLAY(obj)->priv;
1922 -
1923 -       if (priv->gl_drawable == NULL)
1924 -               return;
1925 -
1926 -       if (priv->gl_enabled == 0) {
1927 -               GdkImage *image;
1928 -
1929 -               priv->gl_enabled = 1;
1930 -
1931 -               image = priv->image;
1932 -               priv->image = NULL;
1933 -       
1934 -               do_resize(obj, priv->fb.width, priv->fb.height, TRUE);
1935 -               build_gl_image_from_gdk((uint32_t *)priv->fb.data, image);
1936 -
1937 -               g_object_unref(image);
1938 -       }
1939 -
1940 -       priv->gl_width = width;
1941 -       priv->gl_height = height;
1942 -
1943 -       gdk_gl_drawable_gl_begin(priv->gl_drawable, priv->gl_context);
1944 -       glClearColor (0.0, 0.0, 0.0, 0.0);
1945 -       glShadeModel(GL_FLAT);
1946 -       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1947 -    
1948 -       glViewport(0, 0, priv->gl_width, priv->gl_height);
1949 -       glMatrixMode(GL_PROJECTION);
1950 -       glLoadIdentity();
1951 -       glOrtho(0.0, priv->gl_width, 0.0, priv->gl_height, -1, 1);
1952 -       glMatrixMode(GL_MODELVIEW);
1953 -       glLoadIdentity();
1954 -       gdk_gl_drawable_gl_end(priv->gl_drawable);
1955 -}
1956 -
1957 -static void rescale_display(VncDisplay *obj, gint width, gint height)
1958 -{
1959 -       VncDisplayPrivate *priv = obj->priv;
1960 -
1961 -       if (priv->allow_scaling && 
1962 -           (priv->fb.width != width ||
1963 -            priv->fb.height != height))
1964 -               scale_display(obj, width, height);
1965 -       else if (priv->gl_enabled) {
1966 -               void *data;
1967 -               priv->gl_enabled = 0;
1968 -
1969 -               data = priv->gl_tex_data;
1970 -               priv->gl_tex_data = NULL;
1971 -
1972 -               do_resize(GTK_WIDGET(obj), priv->fb.width, priv->fb.height, TRUE);
1973 -
1974 -               build_gdk_image_from_gl(priv->image, (uint32_t *)data);
1975 -               gdk_gl_drawable_gl_begin(priv->gl_drawable,
1976 -                                        priv->gl_context);
1977 -               glDeleteTextures(1, &priv->gl_tex);
1978 -               gdk_gl_drawable_gl_end(priv->gl_drawable);
1979 -               g_free(data);
1980 -       }
1981 -}
1982 -
1983 -static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *configure)
1984 -{
1985 -       VncDisplay *obj = VNC_DISPLAY(widget);
1986 -       VncDisplayPrivate *priv = obj->priv;
1987 -
1988 -       if (priv->fb.data == NULL)
1989 -               return FALSE;
1990 -
1991 -       rescale_display(VNC_DISPLAY(widget),
1992 -                       configure->width, configure->height);
1993 -       
1994 -       return FALSE;
1995 -}
1996 -#endif
1997 -
1998 -static gboolean on_pointer_type_change(void *opaque, int absolute)
1999 -{
2000 -       VncDisplay *obj = VNC_DISPLAY(opaque);
2001 -       VncDisplayPrivate *priv = obj->priv;
2002 -
2003 -       if (absolute && priv->in_pointer_grab && !priv->grab_pointer)
2004 -               do_pointer_ungrab(obj, FALSE);
2005 -
2006 -       priv->absolute = absolute;
2007 -
2008 -       if (!priv->in_pointer_grab && !priv->absolute)
2009 -               do_pointer_show(obj);
2010 -
2011 -       return TRUE;
2012 -}
2013 -
2014 -static gboolean on_auth_cred(void *opaque)
2015 -{
2016 -       VncDisplay *obj = VNC_DISPLAY(opaque);
2017 -       GValueArray *cred_list;
2018 -       GValue username, password, clientname;
2019 -       struct signal_data s;
2020 -
2021 -       memset(&username, 0, sizeof(username));
2022 -       memset(&password, 0, sizeof(password));
2023 -       memset(&clientname, 0, sizeof(clientname));
2024 -
2025 -       cred_list = g_value_array_new(0);
2026 -       if (gvnc_wants_credential_username(obj->priv->gvnc)) {
2027 -               g_value_init(&username, G_PARAM_SPEC_VALUE_TYPE(signalCredParam));
2028 -               g_value_set_enum(&username, VNC_DISPLAY_CREDENTIAL_USERNAME);
2029 -               cred_list = g_value_array_append(cred_list, &username);
2030 -       }
2031 -       if (gvnc_wants_credential_password(obj->priv->gvnc)) {
2032 -               g_value_init(&password, G_PARAM_SPEC_VALUE_TYPE(signalCredParam));
2033 -               g_value_set_enum(&password, VNC_DISPLAY_CREDENTIAL_PASSWORD);
2034 -               cred_list = g_value_array_append(cred_list, &password);
2035 -       }
2036 -       if (gvnc_wants_credential_x509(obj->priv->gvnc)) {
2037 -               g_value_init(&clientname, G_PARAM_SPEC_VALUE_TYPE(signalCredParam));
2038 -               g_value_set_enum(&clientname, VNC_DISPLAY_CREDENTIAL_CLIENTNAME);
2039 -               cred_list = g_value_array_append(cred_list, &clientname);
2040 -       }
2041 -
2042 -       s.cred_list = cred_list;
2043 -       emit_signal_delayed(obj, VNC_AUTH_CREDENTIAL, &s);
2044 -
2045 -       g_value_array_free(cred_list);
2046 -
2047 -       return TRUE;
2048 -}
2049 -
2050 -static gboolean on_auth_type(void *opaque, unsigned int ntype, unsigned int *types)
2051 -{
2052 -       VncDisplay *obj = VNC_DISPLAY(opaque);
2053 -       VncDisplayPrivate *priv = obj->priv;
2054 -       GSList *l;
2055 -       guint i;
2056 -
2057 -       if (!ntype)
2058 -               return TRUE;
2059 -
2060 -       for (l = priv->preferable_auths; l; l=l->next) {
2061 -               gvnc_auth pref = GPOINTER_TO_UINT (l->data);
2062 -
2063 -               for (i=0; i<ntype; i++) {
2064 -                       if (pref == types[i]) {
2065 -                               gvnc_set_auth_type(priv->gvnc, types[i]);
2066 -                               return TRUE;
2067 -                       }
2068 -               }
2069 -       }
2070 -       
2071 -       gvnc_set_auth_type(priv->gvnc, types[0]);
2072 -       return TRUE;
2073 -}
2074 -
2075 -static gboolean on_auth_subtype(void *opaque, unsigned int ntype, unsigned int *types)
2076 -{
2077 -       VncDisplay *obj = VNC_DISPLAY(opaque);
2078 -       VncDisplayPrivate *priv = obj->priv;
2079 -
2080 -       GSList *l;
2081 -       guint i;
2082 -
2083 -       if (!ntype)
2084 -               return TRUE;
2085 -
2086 -       for (l = priv->preferable_auths; l; l=l->next) {
2087 -               gvnc_auth pref = GPOINTER_TO_UINT (l->data);
2088 -
2089 -               for (i=0; i<ntype; i++) {
2090 -                       if (pref == types[i]) {
2091 -                               gvnc_set_auth_subtype(priv->gvnc, types[i]);
2092 -                               return TRUE;
2093 -                       }
2094 -               }
2095 -       }
2096 -       
2097 -       gvnc_set_auth_subtype(priv->gvnc, types[0]);
2098 -       return TRUE;
2099 -}
2100 -
2101 -static gboolean on_auth_failure(void *opaque, const char *msg)
2102 -{
2103 -       VncDisplay *obj = VNC_DISPLAY(opaque);
2104 -       struct signal_data s;
2105 -
2106 -       s.msg = msg;
2107 -       emit_signal_delayed(obj, VNC_AUTH_FAILURE, &s);
2108 -
2109 -       return TRUE;
2110 -}
2111 -
2112 -static gboolean on_auth_unsupported(void *opaque, unsigned int auth_type)
2113 -{
2114 -       VncDisplay *obj = VNC_DISPLAY(opaque);
2115 -       struct signal_data s;
2116 -
2117 -       s.auth_type = auth_type;
2118 -       emit_signal_delayed(obj, VNC_AUTH_UNSUPPORTED, &s);
2119 -
2120 -       return TRUE;
2121 -}
2122 -
2123 -static gboolean on_server_cut_text(void *opaque, const void* text, size_t len)
2124 -{
2125 -       VncDisplay *obj = VNC_DISPLAY(opaque);
2126 -       GString *str = g_string_new_len ((const gchar *)text, len);
2127 -       struct signal_data s;
2128 -
2129 -       s.str = str;
2130 -       emit_signal_delayed(obj, VNC_SERVER_CUT_TEXT, &s);
2131 -
2132 -       g_string_free (str, TRUE);
2133 -       return TRUE;
2134 -}
2135 -
2136 -static gboolean on_bell(void *opaque)
2137 -{
2138 -       VncDisplay *obj = VNC_DISPLAY(opaque);
2139 -       struct signal_data s;
2140 -
2141 -       emit_signal_delayed(obj, VNC_BELL, &s);
2142 -
2143 -       return TRUE;
2144 -}
2145 -
2146 -static gboolean on_local_cursor(void *opaque, int x, int y, int width, int height, uint8_t *image)
2147 -{
2148 -       VncDisplay *obj = VNC_DISPLAY(opaque);
2149 -       VncDisplayPrivate *priv = obj->priv;
2150 -
2151 -       if (priv->remote_cursor) {
2152 -               gdk_cursor_unref(priv->remote_cursor);
2153 -               priv->remote_cursor = NULL;
2154 -       }
2155 -
2156 -       if (width && height) {
2157 -               GdkDisplay *display = gdk_drawable_get_display(GDK_DRAWABLE(GTK_WIDGET(obj)->window));
2158 -               GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(image, GDK_COLORSPACE_RGB,
2159 -                                                            TRUE, 8, width, height,
2160 -                                                            width * 4, NULL, NULL);
2161 -               priv->remote_cursor = gdk_cursor_new_from_pixbuf(display,
2162 -                                                                pixbuf,
2163 -                                                                x, y);
2164 -               gdk_pixbuf_unref(pixbuf);
2165 -       }
2166 -
2167 -       if (priv->in_pointer_grab) {
2168 -               do_pointer_ungrab(obj, TRUE);
2169 -               do_pointer_grab(obj, TRUE);
2170 -       } else if (priv->absolute) {
2171 -               do_pointer_hide(obj);
2172 -       }
2173 -
2174 -       return TRUE;
2175 -}
2176 -
2177 -static gboolean check_pixbuf_support(const char *name)
2178 -{
2179 -       GSList *list, *i;
2180 -
2181 -       list = gdk_pixbuf_get_formats();
2182 -
2183 -       for (i = list; i; i = i->next) {
2184 -               GdkPixbufFormat *fmt = i->data;
2185 -               if (!strcmp(gdk_pixbuf_format_get_name(fmt), name))
2186 -                       break;
2187 -       }
2188 -
2189 -       g_slist_free(list);
2190 -
2191 -       return !!(i);
2192 -}
2193 -
2194 -static gboolean on_render_jpeg(void *opaque G_GNUC_UNUSED,
2195 -                              rgb24_render_func *render, void *render_opaque,
2196 -                              int x, int y, int w, int h,
2197 -                              uint8_t *data, int size)
2198 -{
2199 -       GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
2200 -       GdkPixbuf *p;
2201 -       uint8_t *pixels;
2202 -
2203 -       if (!gdk_pixbuf_loader_write(loader, data, size, NULL))
2204 -               return FALSE;
2205 -
2206 -       gdk_pixbuf_loader_close(loader, NULL);
2207 -
2208 -       p = g_object_ref(gdk_pixbuf_loader_get_pixbuf(loader));
2209 -       g_object_unref(loader);
2210 -
2211 -       pixels = gdk_pixbuf_get_pixels(p);
2212 -
2213 -       render(render_opaque, x, y, w, h,
2214 -              gdk_pixbuf_get_pixels(p),
2215 -              gdk_pixbuf_get_rowstride(p));
2216 -
2217 -       gdk_pixbuf_unref(p);
2218 -
2219 -       return TRUE;
2220 -}
2221 -
2222 -static const struct gvnc_ops vnc_display_ops = {
2223 -       .auth_cred = on_auth_cred,
2224 -       .auth_type = on_auth_type,
2225 -       .auth_subtype = on_auth_subtype,
2226 -       .auth_failure = on_auth_failure,
2227 -       .update = on_update,
2228 -       .resize = on_resize,
2229 -        .pixel_format = on_pixel_format,
2230 -       .pointer_type_change = on_pointer_type_change,
2231 -       .local_cursor = on_local_cursor,
2232 -       .auth_unsupported = on_auth_unsupported,
2233 -       .server_cut_text = on_server_cut_text,
2234 -       .bell = on_bell,
2235 -       .render_jpeg = on_render_jpeg,
2236 -       .get_preferred_pixel_format = on_get_preferred_pixel_format
2237 -};
2238 -
2239 -/* we use an idle function to allow the coroutine to exit before we actually
2240 - * unref the object since the coroutine's state is part of the object */
2241 -static gboolean delayed_unref_object(gpointer data)
2242 -{
2243 -       VncDisplay *obj = VNC_DISPLAY(data);
2244 -
2245 -       g_assert(obj->priv->coroutine.exited == TRUE);
2246 -
2247 -       if (obj->priv->image) {
2248 -               g_object_unref(obj->priv->image);
2249 -               obj->priv->image = NULL;
2250 -       }
2251 -
2252 -#if WITH_GTKGLEXT
2253 -       if (obj->priv->gl_tex_data)
2254 -               g_free(obj->priv->gl_tex_data);
2255 -       obj->priv->gl_tex_data = NULL;
2256 -       obj->priv->gl_enabled = 0;
2257 -#endif
2258 -
2259 -       g_object_unref(G_OBJECT(data));
2260 -       return FALSE;
2261 -}
2262 -
2263 -static void *vnc_coroutine(void *opaque)
2264 -{
2265 -       VncDisplay *obj = VNC_DISPLAY(opaque);
2266 -       VncDisplayPrivate *priv = obj->priv;
2267 -
2268 -       /* this order is extremely important! */
2269 -       int32_t encodings[] = { GVNC_ENCODING_TIGHT_JPEG5,
2270 -                               GVNC_ENCODING_TIGHT,
2271 -                               GVNC_ENCODING_EXT_KEY_EVENT,
2272 -                               GVNC_ENCODING_DESKTOP_RESIZE,
2273 -                                GVNC_ENCODING_WMVi,
2274 -                               GVNC_ENCODING_RICH_CURSOR,
2275 -                               GVNC_ENCODING_XCURSOR,
2276 -                               GVNC_ENCODING_POINTER_CHANGE,
2277 -                               GVNC_ENCODING_ZRLE,
2278 -                               GVNC_ENCODING_HEXTILE,
2279 -                               GVNC_ENCODING_RRE,
2280 -                               GVNC_ENCODING_COPY_RECT,
2281 -                               GVNC_ENCODING_RAW };
2282 -       int32_t *encodingsp;
2283 -       int n_encodings;
2284 -       int ret;
2285 -       struct signal_data s;
2286 -
2287 -       if (priv->gvnc == NULL || gvnc_is_open(priv->gvnc)) {
2288 -               g_idle_add(delayed_unref_object, obj);
2289 -               return NULL;
2290 -       }
2291 -
2292 -       GVNC_DEBUG("Started background coroutine\n");
2293 -       x_keymap_set_keymap_entries();
2294 -
2295 -       if (priv->fd != -1) {
2296 -               if (!gvnc_open_fd(priv->gvnc, priv->fd))
2297 -                       goto cleanup;
2298 -       } else {
2299 -               if (!gvnc_open_host(priv->gvnc, priv->host, priv->port))
2300 -                       goto cleanup;
2301 -       }
2302 -
2303 -       emit_signal_delayed(obj, VNC_CONNECTED, &s);
2304 -
2305 -       GVNC_DEBUG("Protocol initialization\n");
2306 -       if (!gvnc_initialize(priv->gvnc, priv->shared_flag))
2307 -               goto cleanup;
2308 -
2309 -       emit_signal_delayed(obj, VNC_INITIALIZED, &s);
2310 -
2311 -       encodingsp = encodings;
2312 -       n_encodings = G_N_ELEMENTS(encodings);
2313 -
2314 -       if (check_pixbuf_support("jpeg")) {
2315 -               if (!priv->allow_lossy) {
2316 -                       encodingsp++;
2317 -                       n_encodings--;
2318 -               }
2319 -       } else {
2320 -               encodingsp += 2;
2321 -               n_encodings -= 2;
2322 -       }
2323 -
2324 -       if (!gvnc_set_encodings(priv->gvnc, n_encodings, encodingsp))
2325 -                       goto cleanup;
2326 -
2327 -       if (!gvnc_framebuffer_update_request(priv->gvnc, 0, 0, 0, priv->fb.width, priv->fb.height))
2328 -               goto cleanup;
2329 -
2330 -       GVNC_DEBUG("Running main loop\n");
2331 -       while ((ret = gvnc_server_message(priv->gvnc))) {
2332 -               if (!gvnc_framebuffer_update_request(priv->gvnc, 1, 0, 0,
2333 -                                                    priv->fb.width, priv->fb.height))
2334 -                       goto cleanup;
2335 -       }
2336 -
2337 - cleanup:
2338 -       GVNC_DEBUG("Doing final VNC cleanup\n");
2339 -       gvnc_close(priv->gvnc);
2340 -       emit_signal_delayed(obj, VNC_DISCONNECTED, &s);
2341 -       g_idle_add(delayed_unref_object, obj);
2342 -       x_keymap_free_keymap_entries();
2343 -       /* Co-routine exits now - the VncDisplay object may no longer exist,
2344 -          so don't do anything else now unless you like SEGVs */
2345 -       return NULL;
2346 -}
2347 -
2348 -static gboolean do_vnc_display_open(gpointer data)
2349 -{
2350 -       VncDisplay *obj = VNC_DISPLAY(data);
2351 -       struct coroutine *co;
2352 -
2353 -       if (obj->priv->gvnc == NULL || gvnc_is_open(obj->priv->gvnc)) {
2354 -               g_object_unref(G_OBJECT(obj));
2355 -               return FALSE;
2356 -       }
2357 -
2358 -       obj->priv->open_id = 0;
2359 -
2360 -       co = &obj->priv->coroutine;
2361 -
2362 -       co->stack_size = 16 << 20;
2363 -       co->entry = vnc_coroutine;
2364 -       co->release = NULL;
2365 -
2366 -       coroutine_init(co);
2367 -       coroutine_yieldto(co, obj);
2368 -
2369 -       return FALSE;
2370 -}
2371 -
2372 -gboolean vnc_display_open_fd(VncDisplay *obj, int fd)
2373 -{
2374 -       if (obj->priv->gvnc == NULL || gvnc_is_open(obj->priv->gvnc))
2375 -               return FALSE;
2376 -
2377 -       obj->priv->fd = fd;
2378 -       obj->priv->host = NULL;
2379 -       obj->priv->port = NULL;
2380 -
2381 -       g_object_ref(G_OBJECT(obj)); /* Unref'd when co-routine exits */
2382 -       obj->priv->open_id = g_idle_add(do_vnc_display_open, obj);
2383 -
2384 -       return TRUE;
2385 -}
2386 -
2387 -gboolean vnc_display_open_host(VncDisplay *obj, const char *host, const char *port)
2388 -{
2389 -       if (obj->priv->gvnc == NULL || gvnc_is_open(obj->priv->gvnc))
2390 -               return FALSE;
2391 -
2392 -       obj->priv->host = g_strdup(host);
2393 -       if (!obj->priv->host) {
2394 -               return FALSE;
2395 -       }
2396 -       obj->priv->port = g_strdup(port);
2397 -       if (!obj->priv->port) {
2398 -               g_free(obj->priv->host);
2399 -               obj->priv->host = NULL;
2400 -               return FALSE;
2401 -       }
2402 -
2403 -       g_object_ref(G_OBJECT(obj)); /* Unref'd when co-routine exits */
2404 -       obj->priv->open_id = g_idle_add(do_vnc_display_open, obj);
2405 -       return TRUE;
2406 -}
2407 -
2408 -gboolean vnc_display_is_open(VncDisplay *obj)
2409 -{
2410 -       if (obj->priv->gvnc == NULL)
2411 -               return FALSE;
2412 -       return gvnc_is_open(obj->priv->gvnc);
2413 -}
2414 -
2415 -void vnc_display_close(VncDisplay *obj)
2416 -{
2417 -       VncDisplayPrivate *priv = obj->priv;
2418 -       GtkWidget *widget = GTK_WIDGET(obj);
2419 -
2420 -       if (priv->open_id) {
2421 -               g_source_remove(priv->open_id);
2422 -               obj->priv->open_id = 0;
2423 -       }
2424 -
2425 -       if (priv->gvnc == NULL)
2426 -               return;
2427 -
2428 -       if (gvnc_is_open(priv->gvnc)) {
2429 -               GVNC_DEBUG("Requesting graceful shutdown of connection\n");
2430 -               gvnc_shutdown(priv->gvnc);
2431 -       }
2432 -
2433 -#if WITH_GTKGLEXT
2434 -       if (priv->gl_tex_data) {
2435 -               gdk_gl_drawable_gl_begin(priv->gl_drawable,
2436 -                                        priv->gl_context);
2437 -               glDeleteTextures(1, &priv->gl_tex);
2438 -               gdk_gl_drawable_gl_end(priv->gl_drawable);
2439 -       }
2440 -#endif
2441 -
2442 -       if (widget->window) {
2443 -               gint width, height;
2444 -
2445 -               gdk_drawable_get_size(widget->window, &width, &height);
2446 -               gtk_widget_queue_draw_area(widget, 0, 0, width, height);
2447 -       }
2448 -}
2449 -
2450 -
2451 -void vnc_display_send_keys(VncDisplay *obj, const guint *keyvals, int nkeyvals)
2452 -{
2453 -       vnc_display_send_keys_ex(obj, keyvals,
2454 -                                nkeyvals, VNC_DISPLAY_KEY_EVENT_CLICK);
2455 -}
2456 -
2457 -static guint get_keycode_from_keyval(guint keyval)
2458 -{
2459 -       guint keycode = 0;
2460 -       GdkKeymapKey *keys = NULL;
2461 -       gint n_keys = 0;
2462 -
2463 -       if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(),
2464 -                                             keyval, &keys, &n_keys)) {
2465 -               /* FIXME what about levels? */
2466 -               keycode = keys[0].keycode;
2467 -               g_free(keys);
2468 -       }
2469 -
2470 -       return keycode;
2471 -}
2472 -
2473 -void vnc_display_send_keys_ex(VncDisplay *obj, const guint *keyvals,
2474 -                             int nkeyvals, VncDisplayKeyEvent kind)
2475 -{
2476 -       int i;
2477 -
2478 -       if (obj->priv->gvnc == NULL || !gvnc_is_open(obj->priv->gvnc))
2479 -               return;
2480 -
2481 -       if (kind & VNC_DISPLAY_KEY_EVENT_PRESS) {
2482 -               for (i = 0 ; i < nkeyvals ; i++)
2483 -                       gvnc_key_event(obj->priv->gvnc, 1, keyvals[i],
2484 -                                      get_keycode_from_keyval(keyvals[i]));
2485 -       }
2486 -
2487 -       if (kind & VNC_DISPLAY_KEY_EVENT_RELEASE) {
2488 -               for (i = (nkeyvals-1) ; i >= 0 ; i--)
2489 -                       gvnc_key_event(obj->priv->gvnc, 0, keyvals[i],
2490 -                                      get_keycode_from_keyval(keyvals[i]));
2491 -       }
2492 -}
2493 -
2494 -void vnc_display_send_pointer(VncDisplay *obj, gint x, gint y, int button_mask)
2495 -{
2496 -       VncDisplayPrivate *priv = obj->priv;
2497 -
2498 -       if (priv->gvnc == NULL || !gvnc_is_open(obj->priv->gvnc))
2499 -               return;
2500 -
2501 -       if (priv->absolute) {
2502 -               priv->button_mask = button_mask;
2503 -               priv->last_x = x;
2504 -               priv->last_y = y;
2505 -               gvnc_pointer_event(priv->gvnc, priv->button_mask, x, y);
2506 -       }
2507 -}
2508 -
2509 -static void vnc_display_destroy (GtkObject *obj)
2510 -{
2511 -       VncDisplay *display = VNC_DISPLAY (obj);
2512 -       GVNC_DEBUG("Requesting that VNC close\n");
2513 -       vnc_display_close(display);
2514 -       GTK_OBJECT_CLASS (vnc_display_parent_class)->destroy (obj);
2515 -}
2516 -
2517 -
2518 -static void vnc_display_finalize (GObject *obj)
2519 -{
2520 -       VncDisplay *display = VNC_DISPLAY (obj);
2521 -       VncDisplayPrivate *priv = display->priv;
2522 -
2523 -       GVNC_DEBUG("Releasing VNC widget\n");
2524 -       if (gvnc_is_open(priv->gvnc)) {
2525 -               g_warning("VNC widget finalized before the connection finished shutting down\n");
2526 -       }
2527 -       gvnc_free(priv->gvnc);
2528 -       display->priv->gvnc = NULL;
2529 -
2530 -#if WITH_GTKGLEXT
2531 -       if (priv->gl_enabled) {
2532 -               gdk_gl_drawable_gl_begin(priv->gl_drawable,
2533 -                                        priv->gl_context);
2534 -               glDeleteTextures(1, &priv->gl_tex);
2535 -               gdk_gl_drawable_gl_end(priv->gl_drawable);
2536 -               if (priv->gl_tex_data) {
2537 -                       g_free(priv->gl_tex_data);
2538 -                       priv->gl_tex_data = NULL;
2539 -               }
2540 -       }
2541 -
2542 -       if (priv->gl_config) {
2543 -               g_object_unref(G_OBJECT(priv->gl_config));
2544 -               priv->gl_config = NULL;
2545 -       }
2546 -#endif
2547 -
2548 -       if (priv->image) {
2549 -               g_object_unref(priv->image);
2550 -               priv->image = NULL;
2551 -       }
2552 -
2553 -       g_slist_free (priv->preferable_auths);
2554 -
2555 -       G_OBJECT_CLASS (vnc_display_parent_class)->finalize (obj);
2556 -}
2557 -
2558 -static void vnc_display_class_init(VncDisplayClass *klass)
2559 -{
2560 -       GObjectClass *object_class = G_OBJECT_CLASS (klass);
2561 -       GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
2562 -       GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
2563 -
2564 -       gtkwidget_class->expose_event = expose_event;
2565 -       gtkwidget_class->motion_notify_event = motion_event;
2566 -       gtkwidget_class->button_press_event = button_event;
2567 -       gtkwidget_class->button_release_event = button_event;
2568 -       gtkwidget_class->scroll_event = scroll_event;
2569 -       gtkwidget_class->key_press_event = key_event;
2570 -       gtkwidget_class->key_release_event = key_event;
2571 -       gtkwidget_class->enter_notify_event = enter_event;
2572 -       gtkwidget_class->leave_notify_event = leave_event;
2573 -       gtkwidget_class->focus_out_event = focus_event;
2574 -#if WITH_GTKGLEXT
2575 -       gtkwidget_class->realize = realize_event;
2576 -       gtkwidget_class->configure_event = configure_event;
2577 -#endif
2578 -
2579 -
2580 -       object_class->finalize = vnc_display_finalize;
2581 -       object_class->get_property = vnc_display_get_property;
2582 -       object_class->set_property = vnc_display_set_property;
2583 -
2584 -       gtkobject_class->destroy = vnc_display_destroy;
2585 -
2586 -       g_object_class_install_property (object_class,
2587 -                                        PROP_POINTER_LOCAL,
2588 -                                        g_param_spec_boolean ( "local-pointer",
2589 -                                                               "Local Pointer",
2590 -                                                               "Whether we should use the local pointer",
2591 -                                                               FALSE,
2592 -                                                               G_PARAM_READWRITE |
2593 -                                                               G_PARAM_CONSTRUCT |
2594 -                                                               G_PARAM_STATIC_NAME |
2595 -                                                               G_PARAM_STATIC_NICK |
2596 -                                                               G_PARAM_STATIC_BLURB));
2597 -       g_object_class_install_property (object_class,
2598 -                                        PROP_POINTER_GRAB,
2599 -                                        g_param_spec_boolean ( "grab-pointer",
2600 -                                                               "Grab Pointer",
2601 -                                                               "Whether we should grab the pointer",
2602 -                                                               FALSE,
2603 -                                                               G_PARAM_READWRITE |
2604 -                                                               G_PARAM_CONSTRUCT |
2605 -                                                               G_PARAM_STATIC_NAME |
2606 -                                                               G_PARAM_STATIC_NICK |
2607 -                                                               G_PARAM_STATIC_BLURB));
2608 -       g_object_class_install_property (object_class,
2609 -                                        PROP_KEYBOARD_GRAB,
2610 -                                        g_param_spec_boolean ( "grab-keyboard",
2611 -                                                               "Grab Keyboard",
2612 -                                                               "Whether we should grab the keyboard",
2613 -                                                               FALSE,
2614 -                                                               G_PARAM_READWRITE |
2615 -                                                               G_PARAM_CONSTRUCT |
2616 -                                                               G_PARAM_STATIC_NAME |
2617 -                                                               G_PARAM_STATIC_NICK |
2618 -                                                               G_PARAM_STATIC_BLURB));
2619 -       g_object_class_install_property (object_class,
2620 -                                        PROP_READ_ONLY,
2621 -                                        g_param_spec_boolean ( "read-only",
2622 -                                                               "Read Only",
2623 -                                                               "Whether this connection is read-only mode",
2624 -                                                               FALSE,
2625 -                                                               G_PARAM_READWRITE |
2626 -                                                               G_PARAM_CONSTRUCT |
2627 -                                                               G_PARAM_STATIC_NAME |
2628 -                                                               G_PARAM_STATIC_NICK |
2629 -                                                               G_PARAM_STATIC_BLURB));
2630 -       g_object_class_install_property (object_class,
2631 -                                        PROP_WIDTH,
2632 -                                        g_param_spec_int     ( "width",
2633 -                                                               "Width",
2634 -                                                               "The width of the remote screen",
2635 -                                                               0,
2636 -                                                               G_MAXINT,
2637 -                                                               0,
2638 -                                                               G_PARAM_READABLE |
2639 -                                                               G_PARAM_STATIC_NAME |
2640 -                                                               G_PARAM_STATIC_NICK |
2641 -                                                               G_PARAM_STATIC_BLURB));
2642 -       g_object_class_install_property (object_class,
2643 -                                        PROP_HEIGHT,
2644 -                                        g_param_spec_int     ( "height",
2645 -                                                               "Height",
2646 -                                                               "The height of the remote screen",
2647 -                                                               0,
2648 -                                                               G_MAXINT,
2649 -                                                               0,
2650 -                                                               G_PARAM_READABLE |
2651 -                                                               G_PARAM_STATIC_NAME |
2652 -                                                               G_PARAM_STATIC_NICK |
2653 -                                                               G_PARAM_STATIC_BLURB));
2654 -       g_object_class_install_property (object_class,
2655 -                                        PROP_NAME,
2656 -                                        g_param_spec_string  ( "name",
2657 -                                                               "Name",
2658 -                                                               "The screen name of the remote connection",
2659 -                                                               NULL,
2660 -                                                               G_PARAM_READABLE |
2661 -                                                               G_PARAM_STATIC_NAME |
2662 -                                                               G_PARAM_STATIC_NICK |
2663 -                                                               G_PARAM_STATIC_BLURB));
2664 -       g_object_class_install_property (object_class,
2665 -                                        PROP_LOSSY_ENCODING,
2666 -                                        g_param_spec_boolean ( "lossy-encoding",
2667 -                                                               "Lossy Encoding",
2668 -                                                               "Whether we should use a lossy encoding",
2669 -                                                               FALSE,
2670 -                                                               G_PARAM_READWRITE |
2671 -                                                               G_PARAM_CONSTRUCT |
2672 -                                                               G_PARAM_STATIC_NAME |
2673 -                                                               G_PARAM_STATIC_NICK |
2674 -                                                               G_PARAM_STATIC_BLURB));
2675 -       g_object_class_install_property (object_class,
2676 -                                        PROP_SCALING,
2677 -                                        g_param_spec_boolean ( "scaling",
2678 -                                                               "Scaling",
2679 -                                                               "Whether we should use scaling",
2680 -                                                               FALSE,
2681 -                                                               G_PARAM_READWRITE |
2682 -                                                               G_PARAM_CONSTRUCT |
2683 -                                                               G_PARAM_STATIC_NAME |
2684 -                                                               G_PARAM_STATIC_NICK |
2685 -                                                               G_PARAM_STATIC_BLURB));
2686 -       g_object_class_install_property (object_class,
2687 -                                        PROP_SHARED_FLAG,
2688 -                                        g_param_spec_boolean ( "shared-flag",
2689 -                                                               "Shared Flag",
2690 -                                                               "Whether we should leave other clients connected to the server",
2691 -                                                               FALSE,
2692 -                                                               G_PARAM_READWRITE |
2693 -                                                               G_PARAM_CONSTRUCT |
2694 -                                                               G_PARAM_STATIC_NAME |
2695 -                                                               G_PARAM_STATIC_NICK |
2696 -                                                               G_PARAM_STATIC_BLURB));
2697 -       g_object_class_install_property (object_class,
2698 -                                        PROP_FORCE_SIZE,
2699 -                                        g_param_spec_boolean ( "force-size",
2700 -                                                               "Force widget size",
2701 -                                                               "Whether we should define the widget size",
2702 -                                                               TRUE,
2703 -                                                               G_PARAM_READWRITE |
2704 -                                                               G_PARAM_CONSTRUCT |
2705 -                                                               G_PARAM_STATIC_NAME |
2706 -                                                               G_PARAM_STATIC_NICK |
2707 -                                                               G_PARAM_STATIC_BLURB));
2708 -
2709 -       signalCredParam = g_param_spec_enum("credential",
2710 -                                           "credential",
2711 -                                           "credential",
2712 -                                           vnc_display_credential_get_type(),
2713 -                                           0,
2714 -                                           G_PARAM_READABLE);
2715 -
2716 -       signals[VNC_CONNECTED] =
2717 -               g_signal_new ("vnc-connected",
2718 -                             G_OBJECT_CLASS_TYPE (object_class),
2719 -                             G_SIGNAL_RUN_FIRST,
2720 -                             G_STRUCT_OFFSET (VncDisplayClass, vnc_connected),
2721 -                             NULL, NULL,
2722 -                             g_cclosure_marshal_VOID__VOID,
2723 -                             G_TYPE_NONE,
2724 -                             0);
2725 -
2726 -       signals[VNC_INITIALIZED] =
2727 -               g_signal_new ("vnc-initialized",
2728 -                             G_OBJECT_CLASS_TYPE (object_class),
2729 -                             G_SIGNAL_RUN_FIRST,
2730 -                             G_STRUCT_OFFSET (VncDisplayClass, vnc_initialized),
2731 -                             NULL, NULL,
2732 -                             g_cclosure_marshal_VOID__VOID,
2733 -                             G_TYPE_NONE,
2734 -                             0);
2735 -
2736 -       signals[VNC_DISCONNECTED] =
2737 -               g_signal_new ("vnc-disconnected",
2738 -                             G_OBJECT_CLASS_TYPE (object_class),
2739 -                             G_SIGNAL_RUN_FIRST,
2740 -                             G_STRUCT_OFFSET (VncDisplayClass, vnc_disconnected),
2741 -                             NULL, NULL,
2742 -                             g_cclosure_marshal_VOID__VOID,
2743 -                             G_TYPE_NONE,
2744 -                             0);
2745 -
2746 -       signals[VNC_AUTH_CREDENTIAL] =
2747 -               g_signal_new ("vnc-auth-credential",
2748 -                             G_OBJECT_CLASS_TYPE (object_class),
2749 -                             G_SIGNAL_RUN_FIRST,
2750 -                             G_STRUCT_OFFSET (VncDisplayClass, vnc_auth_credential),
2751 -                             NULL, NULL,
2752 -                             g_cclosure_marshal_VOID__BOXED,
2753 -                             G_TYPE_NONE,
2754 -                             1,
2755 -                             G_TYPE_VALUE_ARRAY);
2756 -
2757 -
2758 -       signals[VNC_POINTER_GRAB] =
2759 -               g_signal_new("vnc-pointer-grab",
2760 -                            G_TYPE_FROM_CLASS(klass),
2761 -                            G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
2762 -                            0,
2763 -                            NULL,
2764 -                            NULL,
2765 -                            g_cclosure_marshal_VOID__VOID,
2766 -                            G_TYPE_NONE,
2767 -                            0);
2768 -
2769 -       signals[VNC_POINTER_UNGRAB] =
2770 -               g_signal_new("vnc-pointer-ungrab",
2771 -                            G_TYPE_FROM_CLASS(klass),
2772 -                            G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
2773 -                            0,
2774 -                            NULL,
2775 -                            NULL,
2776 -                            g_cclosure_marshal_VOID__VOID,
2777 -                            G_TYPE_NONE,
2778 -                            0);
2779 -
2780 -       signals[VNC_KEYBOARD_GRAB] =
2781 -               g_signal_new("vnc-keyboard-grab",
2782 -                            G_TYPE_FROM_CLASS(klass),
2783 -                            G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
2784 -                            0,
2785 -                            NULL,
2786 -                            NULL,
2787 -                            g_cclosure_marshal_VOID__VOID,
2788 -                            G_TYPE_NONE,
2789 -                            0);
2790 -
2791 -       signals[VNC_KEYBOARD_UNGRAB] =
2792 -               g_signal_new("vnc-keyboard-ungrab",
2793 -                            G_TYPE_FROM_CLASS(klass),
2794 -                            G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
2795 -                            0,
2796 -                            NULL,
2797 -                            NULL,
2798 -                            g_cclosure_marshal_VOID__VOID,
2799 -                            G_TYPE_NONE,
2800 -                            0);
2801 -
2802 -
2803 -       signals[VNC_DESKTOP_RESIZE] =
2804 -               g_signal_new("vnc-desktop-resize",
2805 -                            G_TYPE_FROM_CLASS(klass),
2806 -                            G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
2807 -                            0,
2808 -                            NULL,
2809 -                            NULL,
2810 -                            g_cclosure_user_marshal_VOID__INT_INT,
2811 -                            G_TYPE_NONE,
2812 -                            2,
2813 -                            G_TYPE_INT, G_TYPE_INT);
2814 -
2815 -       signals[VNC_AUTH_FAILURE] =
2816 -               g_signal_new("vnc-auth-failure",
2817 -                            G_TYPE_FROM_CLASS(klass),
2818 -                            G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
2819 -                            0,
2820 -                            NULL,
2821 -                            NULL,
2822 -                            g_cclosure_marshal_VOID__STRING,
2823 -                            G_TYPE_NONE,
2824 -                            1,
2825 -                            G_TYPE_STRING);
2826 -
2827 -       signals[VNC_AUTH_UNSUPPORTED] =
2828 -               g_signal_new("vnc-auth-unsupported",
2829 -                            G_TYPE_FROM_CLASS(klass),
2830 -                            G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
2831 -                            0,
2832 -                            NULL,
2833 -                            NULL,
2834 -                            g_cclosure_marshal_VOID__UINT,
2835 -                            G_TYPE_NONE,
2836 -                            1,
2837 -                            G_TYPE_UINT);
2838 -
2839 -       signals[VNC_SERVER_CUT_TEXT] =
2840 -               g_signal_new("vnc-server-cut-text",
2841 -                            G_TYPE_FROM_CLASS(klass),
2842 -                            G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
2843 -                            0,
2844 -                            NULL,
2845 -                            NULL,
2846 -                            g_cclosure_marshal_VOID__STRING,
2847 -                            G_TYPE_NONE,
2848 -                            1,
2849 -                            G_TYPE_STRING);
2850 -
2851 -       signals[VNC_BELL] =
2852 -               g_signal_new("vnc-bell",
2853 -                            G_TYPE_FROM_CLASS(klass),
2854 -                            G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
2855 -                            0,
2856 -                            NULL,
2857 -                            NULL,
2858 -                            g_cclosure_marshal_VOID__VOID,
2859 -                            G_TYPE_NONE,
2860 -                            0);
2861 -
2862 -       g_type_class_add_private(klass, sizeof(VncDisplayPrivate));
2863 -}
2864 -
2865 -static void vnc_display_init(VncDisplay *display)
2866 -{
2867 -       GtkObject *obj = GTK_OBJECT(display);
2868 -       GtkWidget *widget = GTK_WIDGET(display);
2869 -       VncDisplayPrivate *priv;
2870 -
2871 -       GTK_WIDGET_SET_FLAGS(obj, GTK_CAN_FOCUS);
2872 -
2873 -       gtk_widget_add_events(widget,
2874 -                             GDK_POINTER_MOTION_MASK |
2875 -                             GDK_BUTTON_PRESS_MASK |
2876 -                             GDK_BUTTON_RELEASE_MASK |
2877 -                             GDK_BUTTON_MOTION_MASK |
2878 -                             GDK_ENTER_NOTIFY_MASK |
2879 -                             GDK_LEAVE_NOTIFY_MASK |
2880 -                             GDK_SCROLL_MASK |
2881 -                             GDK_KEY_PRESS_MASK);
2882 -       gtk_widget_set_double_buffered(widget, FALSE);
2883 -
2884 -       priv = display->priv = VNC_DISPLAY_GET_PRIVATE(display);
2885 -       memset(priv, 0, sizeof(VncDisplayPrivate));
2886 -       priv->last_x = -1;
2887 -       priv->last_y = -1;
2888 -       priv->absolute = 1;
2889 -       priv->fd = -1;
2890 -       priv->read_only = FALSE;
2891 -       priv->allow_lossy = FALSE;
2892 -       priv->allow_scaling = FALSE;
2893 -       priv->grab_pointer = FALSE;
2894 -       priv->grab_keyboard = FALSE;
2895 -       priv->local_pointer = FALSE;
2896 -       priv->shared_flag = FALSE;
2897 -       priv->force_size = TRUE;
2898 -
2899 -       priv->preferable_auths = g_slist_append (priv->preferable_auths, GUINT_TO_POINTER (GVNC_AUTH_VENCRYPT));
2900 -       priv->preferable_auths = g_slist_append (priv->preferable_auths, GUINT_TO_POINTER (GVNC_AUTH_TLS));
2901 -       priv->preferable_auths = g_slist_append (priv->preferable_auths, GUINT_TO_POINTER (GVNC_AUTH_VNC));
2902 -       priv->preferable_auths = g_slist_append (priv->preferable_auths, GUINT_TO_POINTER (GVNC_AUTH_NONE));
2903 -
2904 -#if WITH_GTKGLEXT
2905 -       if (gtk_gl_init_check(NULL, NULL)) {
2906 -               priv->gl_config = gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB |
2907 -                                                           GDK_GL_MODE_DEPTH);
2908 -               if (!gtk_widget_set_gl_capability(widget,
2909 -                                                 priv->gl_config,
2910 -                                                 NULL,
2911 -                                                 TRUE,
2912 -                                                 GDK_GL_RGBA_TYPE)) {
2913 -                       g_warning("Could not enable OpenGL");
2914 -                       g_object_unref(G_OBJECT(priv->gl_config));
2915 -                       priv->gl_config = NULL;
2916 -               }
2917 -       } else
2918 -               priv->gl_config = NULL;
2919 -#endif
2920 -
2921 -       priv->gvnc = gvnc_new(&vnc_display_ops, obj);
2922 -}
2923 -
2924 -static int vnc_display_best_path(char *buf,
2925 -                                int buflen,
2926 -                                const char *basedir,
2927 -                                const char *basefile,
2928 -                                char **dirs,
2929 -                                unsigned int ndirs)
2930 -{
2931 -       unsigned int i;
2932 -       for (i = 0 ; i < ndirs ; i++) {
2933 -               struct stat sb;
2934 -               snprintf(buf, buflen-1, "%s/%s/%s", dirs[i], basedir, basefile);
2935 -               buf[buflen-1] = '\0';
2936 -               if (stat(buf, &sb) == 0)
2937 -                       return 0;
2938 -       }
2939 -       return -1;
2940 -}
2941 -
2942 -static int vnc_display_set_x509_credential(VncDisplay *obj, const char *name)
2943 -{
2944 -       char sysdir[PATH_MAX], userdir[PATH_MAX];
2945 -       struct passwd *pw;
2946 -       char file[PATH_MAX];
2947 -       char *dirs[] = { sysdir, userdir };
2948 -
2949 -       strncpy(sysdir, SYSCONFDIR "/pki", PATH_MAX-1);
2950 -       sysdir[PATH_MAX-1] = '\0';
2951 -
2952 -       if (!(pw = getpwuid(getuid())))
2953 -               return TRUE;
2954 -
2955 -       snprintf(userdir, PATH_MAX-1, "%s/.pki", pw->pw_dir);
2956 -       userdir[PATH_MAX-1] = '\0';
2957 -
2958 -       if (vnc_display_best_path(file, PATH_MAX, "CA", "cacert.pem", dirs, 2) < 0)
2959 -               return TRUE;
2960 -       gvnc_set_credential_x509_cacert(obj->priv->gvnc, file);
2961 -
2962 -       /* Don't mind failures of CRL */
2963 -       if (vnc_display_best_path(file, PATH_MAX, "CA", "cacrl.pem", dirs, 2) == 0)
2964 -               gvnc_set_credential_x509_cacert(obj->priv->gvnc, file);
2965 -
2966 -       /* Set client key & cert if we have them. Server will reject auth
2967 -        * if it decides it requires them*/
2968 -       if (vnc_display_best_path(file, PATH_MAX, name, "private/clientkey.pem", dirs, 2) == 0)
2969 -               gvnc_set_credential_x509_key(obj->priv->gvnc, file);
2970 -       if (vnc_display_best_path(file, PATH_MAX, name, "clientcert.pem", dirs, 2) == 0)
2971 -               gvnc_set_credential_x509_cert(obj->priv->gvnc, file);
2972 -
2973 -       return FALSE;
2974 -}
2975 -
2976 -gboolean vnc_display_set_credential(VncDisplay *obj, int type, const gchar *data)
2977 -{
2978 -       switch (type) {
2979 -       case VNC_DISPLAY_CREDENTIAL_PASSWORD:
2980 -               if (gvnc_set_credential_password(obj->priv->gvnc, data))
2981 -                       return FALSE;
2982 -               return TRUE;
2983 -
2984 -       case VNC_DISPLAY_CREDENTIAL_USERNAME:
2985 -               if (gvnc_set_credential_username(obj->priv->gvnc, data))
2986 -                       return FALSE;
2987 -               return TRUE;
2988 -
2989 -       case VNC_DISPLAY_CREDENTIAL_CLIENTNAME:
2990 -               return vnc_display_set_x509_credential(obj, data);
2991 -       }
2992 -
2993 -       return FALSE;
2994 -}
2995 -
2996 -void vnc_display_set_pointer_local(VncDisplay *obj, gboolean enable)
2997 -{
2998 -       if (obj->priv->gc) {
2999 -               if (enable)
3000 -                       do_pointer_show(obj);
3001 -               else if (obj->priv->in_pointer_grab || obj->priv->absolute)
3002 -                       do_pointer_hide(obj);
3003 -       }
3004 -       obj->priv->local_pointer = enable;
3005 -}
3006 -
3007 -void vnc_display_set_pointer_grab(VncDisplay *obj, gboolean enable)
3008 -{
3009 -       VncDisplayPrivate *priv = obj->priv;
3010 -
3011 -       priv->grab_pointer = enable;
3012 -       if (!enable && priv->absolute && priv->in_pointer_grab)
3013 -               do_pointer_ungrab(obj, FALSE);
3014 -}
3015 -
3016 -void vnc_display_set_keyboard_grab(VncDisplay *obj, gboolean enable)
3017 -{
3018 -       VncDisplayPrivate *priv = obj->priv;
3019 -
3020 -       priv->grab_keyboard = enable;
3021 -       if (!enable && priv->in_keyboard_grab && !priv->in_pointer_grab)
3022 -               do_keyboard_ungrab(obj, FALSE);
3023 -}
3024 -
3025 -void vnc_display_set_read_only(VncDisplay *obj, gboolean enable)
3026 -{
3027 -       obj->priv->read_only = enable;
3028 -}
3029 -
3030 -GType vnc_display_credential_get_type(void)
3031 -{
3032 -       static GType etype = 0;
3033 -
3034 -       if (etype == 0) {
3035 -               static const GEnumValue values[] = {
3036 -                       { VNC_DISPLAY_CREDENTIAL_PASSWORD, "VNC_DISPLAY_CREDENTIAL_PASSWORD", "password" },
3037 -                       { VNC_DISPLAY_CREDENTIAL_USERNAME, "VNC_DISPLAY_CREDENTIAL_USERNAME", "username" },
3038 -                       { VNC_DISPLAY_CREDENTIAL_CLIENTNAME, "VNC_DISPLAY_CREDENTIAL_CLIENTNAME", "clientname" },
3039 -                       { 0, NULL, NULL }
3040 -               };
3041 -               etype = g_enum_register_static ("VncDisplayCredentialType", values );
3042 -       }
3043 -
3044 -       return etype;
3045 -}
3046 -
3047 -GType vnc_display_key_event_get_type(void)
3048 -{
3049 -       static GType etype = 0;
3050 -
3051 -       if (etype == 0) {
3052 -               static const GEnumValue values[] = {
3053 -                       { VNC_DISPLAY_KEY_EVENT_PRESS, "VNC_DISPLAY_KEY_EVENT_PRESS", "press" },
3054 -                       { VNC_DISPLAY_KEY_EVENT_RELEASE, "VNC_DISPLAY_KEY_EVENT_RELEASE", "release" },
3055 -                       { VNC_DISPLAY_KEY_EVENT_CLICK, "VNC_DISPLAY_KEY_EVENT_CLICK", "click" },
3056 -                       { 0, NULL, NULL }
3057 -               };
3058 -               etype = g_enum_register_static ("VncDisplayKeyEvents", values );
3059 -       }
3060 -
3061 -       return etype;
3062 -}
3063 -
3064 -GdkPixbuf *vnc_display_get_pixbuf(VncDisplay *obj)
3065 -{
3066 -       VncDisplayPrivate *priv = obj->priv;
3067 -       GdkPixbuf *pixbuf;
3068 -
3069 -       if (!priv->gvnc ||
3070 -           !gvnc_is_initialized(priv->gvnc))
3071 -               return NULL;
3072 -
3073 -       pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
3074 -                               priv->image->width, priv->image->height);
3075 -
3076 -       if (!gdk_pixbuf_get_from_image(pixbuf,
3077 -                                      priv->image,
3078 -                                      gdk_colormap_get_system(),
3079 -                                      0, 0, 0, 0,
3080 -                                      priv->image->width,
3081 -                                      priv->image->height))
3082 -               return NULL;
3083 -
3084 -       return pixbuf;
3085 -}
3086 -
3087 -
3088 -int vnc_display_get_width(VncDisplay *obj)
3089 -{
3090 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), -1);
3091 -
3092 -       return gvnc_get_width (obj->priv->gvnc);
3093 -}
3094 -
3095 -int vnc_display_get_height(VncDisplay *obj)
3096 -{
3097 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), -1);
3098 -
3099 -       return gvnc_get_height (obj->priv->gvnc);
3100 -}
3101 -
3102 -const char * vnc_display_get_name(VncDisplay *obj)
3103 -{
3104 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), NULL);
3105 -
3106 -       return gvnc_get_name (obj->priv->gvnc);
3107 -}
3108 -
3109 -void vnc_display_client_cut_text(VncDisplay *obj, const gchar *text)
3110 -{
3111 -       g_return_if_fail (VNC_IS_DISPLAY (obj));
3112 -
3113 -       gvnc_client_cut_text(obj->priv->gvnc, text, strlen (text));
3114 -}
3115 -
3116 -void vnc_display_set_lossy_encoding(VncDisplay *obj, gboolean enable)
3117 -{
3118 -       g_return_if_fail (VNC_IS_DISPLAY (obj));
3119 -       obj->priv->allow_lossy = enable;
3120 -}
3121 -
3122 -void vnc_display_set_shared_flag(VncDisplay *obj, gboolean shared)
3123 -{
3124 -       g_return_if_fail (VNC_IS_DISPLAY (obj));
3125 -       obj->priv->shared_flag = shared;
3126 -}
3127 -
3128 -#if WITH_GTKGLEXT
3129 -gboolean vnc_display_set_scaling(VncDisplay *obj, gboolean enable)
3130 -{
3131 -       GtkWidget *widget = GTK_WIDGET(obj);
3132 -       gint width, height;
3133 -
3134 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
3135 -       if (obj->priv->gl_config == NULL)
3136 -               return FALSE;
3137 -       
3138 -       obj->priv->allow_scaling = enable;
3139 -       if (gvnc_is_open(obj->priv->gvnc) && widget->window) {
3140 -               gdk_drawable_get_size(widget->window, &width, &height);
3141 -               rescale_display(obj, width, height);
3142 -               gtk_widget_queue_draw_area(widget, 0, 0, width, height);
3143 -       }
3144 -
3145 -       return TRUE;
3146 -}
3147 -#else
3148 -gboolean vnc_display_set_scaling(VncDisplay *obj G_GNUC_UNUSED,
3149 -       gboolean enable G_GNUC_UNUSED)
3150 -{
3151 -       return FALSE;
3152 -}
3153 -#endif
3154 -
3155 -void vnc_display_set_force_size(VncDisplay *obj, gboolean enabled)
3156 -{
3157 -       g_return_if_fail (VNC_IS_DISPLAY (obj));
3158 -       obj->priv->force_size = enabled;
3159 -}
3160 -
3161 -gboolean vnc_display_get_force_size(VncDisplay *obj)
3162 -{
3163 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
3164 -
3165 -       return obj->priv->force_size;
3166 -}
3167 -
3168 -gboolean vnc_display_get_scaling(VncDisplay *obj)
3169 -{
3170 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
3171 -
3172 -       return obj->priv->allow_scaling;
3173 -}
3174 -
3175 -gboolean vnc_display_get_lossy_encoding(VncDisplay *obj)
3176 -{
3177 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
3178 -
3179 -       return obj->priv->allow_lossy;
3180 -}
3181 -
3182 -gboolean vnc_display_get_shared_flag(VncDisplay *obj)
3183 -{
3184 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
3185 -
3186 -       return obj->priv->shared_flag;
3187 -}
3188 -
3189 -gboolean vnc_display_get_pointer_local(VncDisplay *obj)
3190 -{
3191 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
3192 -
3193 -       return obj->priv->local_pointer;
3194 -}
3195 -
3196 -gboolean vnc_display_get_pointer_grab(VncDisplay *obj)
3197 -{
3198 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
3199 -
3200 -       return obj->priv->grab_pointer;
3201 -}
3202 -
3203 -gboolean vnc_display_get_keyboard_grab(VncDisplay *obj)
3204 -{
3205 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
3206 -
3207 -       return obj->priv->grab_keyboard;
3208 -}
3209 -
3210 -gboolean vnc_display_get_read_only(VncDisplay *obj)
3211 -{
3212 -       g_return_val_if_fail (VNC_IS_DISPLAY (obj), FALSE);
3213 -
3214 -       return obj->priv->read_only;
3215 -}
3216 -
3217 -gboolean vnc_display_is_pointer_absolute(VncDisplay *obj)
3218 -{
3219 -       return obj->priv->absolute;
3220 -}
3221 -
3222 -GOptionGroup *
3223 -vnc_display_get_option_group (void)
3224 -{
3225 -  GOptionGroup *group;
3226 -
3227 -  group = g_option_group_new ("gtk-vnc", "GTK-VNC Options", "Show GTK-VNC Options", NULL, NULL);
3228 -
3229 -  g_option_group_add_entries (group, gtk_vnc_args);
3230 -  
3231 -  return group;
3232 -}
3233 -
3234 -/*
3235 - * Local variables:
3236 - *  c-indent-level: 8
3237 - *  c-basic-offset: 8
3238 - *  tab-width: 8
3239 - * End:
3240 - */
3241 diff -urN gtk-vnc-0.3.7/vc-list-files gtk-vnc-0.3.7.mingw/vc-list-files
3242 --- gtk-vnc-0.3.7/vc-list-files 1970-01-01 01:00:00.000000000 +0100
3243 +++ gtk-vnc-0.3.7.mingw/vc-list-files   2008-10-09 12:19:03.000000000 +0100
3244 @@ -0,0 +1,107 @@
3245 +#!/bin/sh
3246 +# List version-controlled file names.
3247 +
3248 +# Print a version string.
3249 +scriptversion=2008-07-11.19
3250 +
3251 +# Copyright (C) 2006-2008 Free Software Foundation, Inc.
3252 +
3253 +# This program is free software: you can redistribute it and/or modify
3254 +# it under the terms of the GNU General Public License as published by
3255 +# the Free Software Foundation, either version 3 of the License, or
3256 +# (at your option) any later version.
3257 +
3258 +# This program is distributed in the hope that it will be useful,
3259 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
3260 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3261 +# GNU General Public License for more details.
3262 +
3263 +# You should have received a copy of the GNU General Public License
3264 +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
3265 +
3266 +
3267 +# List the specified version-controlled files.
3268 +# With no argument, list them all.  With a single DIRECTORY argument,
3269 +# list the version-controlled files in that directory.
3270 +
3271 +# If there's an argument, it must be a single, "."-relative directory name.
3272 +# cvsu is part of the cvsutils package: http://www.red-bean.com/cvsutils/
3273 +
3274 +postprocess=
3275 +case $1 in
3276 +  --help) cat <<EOF
3277 +Usage: $0 [-C SRCDIR] [DIR]
3278 +
3279 +Output a list of version-controlled files in DIR (default .), relative to
3280 +SRCDIR (default .).  SRCDIR must be the top directory of a checkout.
3281 +
3282 +Options:
3283 +  --help     print this help, then exit
3284 +  --version  print version number, then exit
3285 +  -C SRCDIR  change directory to SRCDIR before generating list
3286 +
3287 +Report bugs and patches to <bug-gnulib@gnu.org>.
3288 +EOF
3289 +    exit ;;
3290 +
3291 +  --version)
3292 +    year=`echo "$scriptversion" | sed 's/[^0-9].*//'`
3293 +    cat <<EOF
3294 +vc-list-files $scriptversion
3295 +Copyright (C) $year Free Software Foundation, Inc,
3296 +License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
3297 +This is free software: you are free to change and redistribute it.
3298 +There is NO WARRANTY, to the extent permitted by law.
3299 +EOF
3300 +    exit ;;
3301 +
3302 +  -C)
3303 +    test "$2" = . || postprocess="| sed 's|^|$2/|'"
3304 +    cd "$2" || exit 1
3305 +    shift; shift ;;
3306 +esac
3307 +
3308 +dir=
3309 +case $# in
3310 +  0) ;;
3311 +  1) dir=$1 ;;
3312 +  *) echo "$0: too many arguments" 1>&2
3313 +     echo "Usage: $0 [-C srcdir] [DIR]" 1>&2; exit 1;;
3314 +esac
3315 +
3316 +test "x$dir" = x && dir=.
3317 +
3318 +if test -d .git; then
3319 +  eval exec git ls-files '"$dir"' $postprocess
3320 +elif test -d .hg; then
3321 +  eval exec hg locate '"$dir/*"' $postprocess
3322 +elif test -d .bzr; then
3323 +  test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
3324 +  eval exec bzr ls --versioned '"$dir"' $postprocess
3325 +elif test -d CVS; then
3326 +  test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
3327 +  if test -x build-aux/cvsu; then
3328 +    eval build-aux/cvsu --find --types=AFGM '"$dir"' $postprocess
3329 +  elif (cvsu --help) >/dev/null 2>&1; then
3330 +    eval cvsu --find --types=AFGM '"$dir"' $postprocess
3331 +  else
3332 +    eval awk -F/ \''{                  \
3333 +       if (!$1 && $3 !~ /^-/) {        \
3334 +         f=FILENAME;                   \
3335 +         if (f ~ /CVS\/Entries$/)      \
3336 +           f = substr(f, 0, length(f)-11); \
3337 +         print f $2;                   \
3338 +       }}'\''                          \
3339 +      `find "$dir" -name Entries -print` /dev/null' $postprocess
3340 +  fi
3341 +else
3342 +  echo "$0: Failed to determine type of version control used in `pwd`" 1>&2
3343 +  exit 1
3344 +fi
3345 +
3346 +# Local variables:
3347 +# eval: (add-hook 'write-file-hooks 'time-stamp)
3348 +# time-stamp-start: "scriptversion="
3349 +# time-stamp-format: "%:y-%02m-%02d.%02H"
3350 +# time-stamp-end: "$"
3351 +# End: