]> Pileus Git - ~andy/gtk/commitdiff
Merge branch 'master' into broadway
authorAlexander Larsson <alexl@redhat.com>
Fri, 11 Feb 2011 14:27:54 +0000 (15:27 +0100)
committerAlexander Larsson <alexl@redhat.com>
Fri, 11 Feb 2011 14:27:54 +0000 (15:27 +0100)
40 files changed:
Makefile.am
configure.ac
gdk/Makefile.am
gdk/broadway/Makefile.am [new file with mode: 0644]
gdk/broadway/broadway-demo.c [new file with mode: 0644]
gdk/broadway/broadway.c [new file with mode: 0644]
gdk/broadway/broadway.h [new file with mode: 0644]
gdk/broadway/broadway.js [new file with mode: 0644]
gdk/broadway/client.html [new file with mode: 0644]
gdk/broadway/gdkbroadwaycursor.h [new file with mode: 0644]
gdk/broadway/gdkbroadwaydisplaymanager.h [new file with mode: 0644]
gdk/broadway/gdkbroadwayvisual.h [new file with mode: 0644]
gdk/broadway/gdkbroadwaywindow.h [new file with mode: 0644]
gdk/broadway/gdkcursor-broadway.c [new file with mode: 0644]
gdk/broadway/gdkdevice-broadway.c [new file with mode: 0644]
gdk/broadway/gdkdevice-broadway.h [new file with mode: 0644]
gdk/broadway/gdkdevicemanager-broadway.c [new file with mode: 0644]
gdk/broadway/gdkdevicemanager-broadway.h [new file with mode: 0644]
gdk/broadway/gdkdisplay-broadway.c [new file with mode: 0644]
gdk/broadway/gdkdisplay-broadway.h [new file with mode: 0644]
gdk/broadway/gdkdisplaymanager-broadway.c [new file with mode: 0644]
gdk/broadway/gdkdnd-broadway.c [new file with mode: 0644]
gdk/broadway/gdkeventsource.c [new file with mode: 0644]
gdk/broadway/gdkeventsource.h [new file with mode: 0644]
gdk/broadway/gdkglobals-broadway.c [new file with mode: 0644]
gdk/broadway/gdkim-broadway.c [new file with mode: 0644]
gdk/broadway/gdkkeys-broadway.c [new file with mode: 0644]
gdk/broadway/gdkmain-broadway.c [new file with mode: 0644]
gdk/broadway/gdkprivate-broadway.h [new file with mode: 0644]
gdk/broadway/gdkproperty-broadway.c [new file with mode: 0644]
gdk/broadway/gdkscreen-broadway.c [new file with mode: 0644]
gdk/broadway/gdkscreen-broadway.h [new file with mode: 0644]
gdk/broadway/gdkselection-broadway.c [new file with mode: 0644]
gdk/broadway/gdktestutils-broadway.c [new file with mode: 0644]
gdk/broadway/gdkvisual-broadway.c [new file with mode: 0644]
gdk/broadway/gdkwindow-broadway.c [new file with mode: 0644]
gdk/broadway/gdkwindow-broadway.h [new file with mode: 0644]
gdk/broadway/toarray.pl [new file with mode: 0755]
gdk/gdkdisplaymanager.c
tests/testsocket_common.c

index 382837057ff8f10597c2bea8dc51fb80196fa791..df52bcc6b0d00674501bff4ac569d6f3c29107e0 100644 (file)
@@ -55,11 +55,11 @@ MAINTAINERCLEANFILES = \
 
 
 ## Copy .pc files to target-specific names
-gtk+-x11-3.0.pc gtk+-win32-3.0.pc gtk+-quartz-3.0.pc: gtk+-3.0.pc
+gtk+-x11-3.0.pc gtk+-win32-3.0.pc gtk+-quartz-3.0.pc gtk+-broadway-3.0.pc: gtk+-3.0.pc
        rm -f $@ && \
        cp gtk+-3.0.pc $@
 
-gdk-x11-3.0.pc gdk-win32-3.0.pc gdk-quartz-3.0.pc: gdk-3.0.pc
+gdk-x11-3.0.pc gdk-win32-3.0.pc gdk-quartz-3.0.pc gdk-broadway-3.0.pc: gdk-3.0.pc
        rm -f $@ && \
        cp gdk-3.0.pc $@
 
index d9fb2775ba1b3ef86c8c856ea4b997cbdd3cfa53..417c3f29f4d7b2e025d4de24e954fe80134ec2d4 100644 (file)
@@ -297,6 +297,10 @@ AC_ARG_ENABLE(quartz-backend,
               [AS_HELP_STRING([--enable-quartz-backend],
                               [enable the quartz gdk backend])],
                              [backend_set=yes])
+AC_ARG_ENABLE(broadway-backend,
+              [AC_HELP_STRING([--enable-broadway-backend],
+                              [enable the broadway (HTML5) gdk backend])],
+                             [backend_set=yes])
 
 if test -z "$backend_set"; then
   if test "$platform_win32" = yes; then
@@ -352,6 +356,17 @@ else
   AM_CONDITIONAL(USE_QUARTZ, false)
 fi
 
+if test "x$enable_broadway_backend" == xyes; then
+  GDK_BACKENDS="$GDK_BACKENDS broadway"
+  cairo_backends="$cairo_backends cairo"
+  GDK_WINDOWING="$GDK_WINDOWING
+#define GDK_WINDOWING_BROADWAY"
+  GDK_EXTRA_LIBS="$GDK_EXTRA_LIBS -lz"
+  AM_CONDITIONAL(USE_BROADWAY, true)
+else
+  AM_CONDITIONAL(USE_BROADWAY, false)
+fi
+
 # strip leading space
 GDK_BACKENDS=${GDK_BACKENDS/# }
 
@@ -1648,6 +1663,7 @@ build/Makefile
 build/win32/Makefile
 build/win32/vs9/Makefile
 gdk/Makefile
+gdk/broadway/Makefile
 gdk/x11/Makefile
 gdk/win32/Makefile
 gdk/win32/rc/Makefile
index 1e51edd02b4e3cbe062042aebff09e58042d059d..01d3232ce6e5e186948ff2101616f7c5c477cf49 100644 (file)
@@ -11,7 +11,7 @@ INTROSPECTION_COMPILER_ARGS = \
 
 SUBDIRS = $(GDK_BACKENDS) . tests
 
-DIST_SUBDIRS = win32 x11 quartz tests
+DIST_SUBDIRS = win32 x11 quartz broadway tests
 
 CLEANFILES =
 
@@ -176,6 +176,10 @@ libgdk_3_la_DEPENDENCIES = win32/libgdk-win32.la win32/rc/gdk-win32-res.o gdk.de
 libgdk_3_la_LDFLAGS += -Wl,win32/rc/gdk-win32-res.o -export-symbols $(srcdir)/gdk.def
 endif # USE_WIN32
 
+if USE_BROADWAY
+libgdk_3_0_la_LIBADD += broadway/libgdk-broadway.la
+endif # USE_BROADWAY
+
 if HAVE_INTROSPECTION
 
 introspection_files =          \
diff --git a/gdk/broadway/Makefile.am b/gdk/broadway/Makefile.am
new file mode 100644 (file)
index 0000000..32ddb6a
--- /dev/null
@@ -0,0 +1,75 @@
+## Process this file with automake to produce Makefile.in
+include $(top_srcdir)/Makefile.decl
+
+libgdkincludedir = $(includedir)/gtk-3.0/gdk
+
+INCLUDES =                     \
+       -DG_LOG_DOMAIN=\"Gdk\"  \
+       -DGDK_COMPILATION       \
+       -I$(top_srcdir)         \
+       -I$(top_srcdir)/gdk     \
+       -I$(top_builddir)/gdk   \
+       $(GTK_DEBUG_FLAGS)      \
+       $(GDK_DEP_CFLAGS)
+
+LDADDS = $(GDK_DEP_LIBS)
+
+noinst_LTLIBRARIES = libbroadway.la libgdk-broadway.la
+
+libbroadway_la_SOURCES =               \
+       broadway.h                      \
+       broadway.c
+
+clienthtml.h: client.html
+       $(PERL) ./toarray.pl client.html client_html > $@
+
+broadwayjs.h: broadway.js
+       $(PERL) ./toarray.pl broadway.js broadway_js > $@
+
+# built headers that don't get installed
+broadway_built_private_headers =       \
+       clienthtml.h                    \
+       broadwayjs.h
+
+broadway_built_sources =               \
+       ${broadway_built_private_headers}
+
+libgdk_broadway_la_SOURCES =           \
+       ${broadway_built_private_headers}\
+       gdkbroadwaydisplaymanager.h     \
+       gdkcursor-broadway.c    \
+       gdkdevice-broadway.h    \
+       gdkdevice-broadway.c    \
+       gdkdevicemanager-broadway.h \
+       gdkdevicemanager-broadway.c \
+       gdkdisplay-broadway.c   \
+       gdkdisplay-broadway.h   \
+       gdkdisplaymanager-broadway.c    \
+       gdkdnd-broadway.c       \
+       gdkeventsource.c        \
+       gdkeventsource.h        \
+       gdkglobals-broadway.c   \
+       gdkim-broadway.c        \
+       gdkkeys-broadway.c      \
+       gdkmain-broadway.c      \
+       gdkproperty-broadway.c  \
+       gdkscreen-broadway.c    \
+       gdkscreen-broadway.h    \
+       gdkselection-broadway.c \
+       gdktestutils-broadway.c \
+       gdkvisual-broadway.c    \
+       gdkwindow-broadway.c    \
+       gdkwindow-broadway.h    \
+       gdkprivate-broadway.h
+
+libgdk_broadway_la_LIBADD = libbroadway.la
+
+MAINTAINERCLEANFILES = $(broadway_built_sources)
+EXTRA_DIST += $(broadway_built_sources)
+
+BUILT_SOURCES = $(broadway_built_sources)
+
+noinst_PROGRAMS = broadway-demo
+broadway_demo_LDADD = -lz -lcairo libbroadway.la -lglib-2.0
+
+-include $(top_srcdir)/git.mk
diff --git a/gdk/broadway/broadway-demo.c b/gdk/broadway/broadway-demo.c
new file mode 100644 (file)
index 0000000..96c177b
--- /dev/null
@@ -0,0 +1,230 @@
+/* Build with
+   gcc -lm -lz -O2 -Wall `pkg-config --libs --cflags cairo`  -o broadway broadway.c demo.c
+*/
+
+#include "broadway.h"
+#include <math.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <cairo.h>
+
+static void
+diff_surfaces (cairo_surface_t *surface,
+              cairo_surface_t *old_surface)
+{
+  uint8_t *data, *old_data;
+  uint32_t *line, *old_line;
+  int w, h, stride, old_stride;
+  int x, y;
+
+  data = cairo_image_surface_get_data (surface);
+  old_data = cairo_image_surface_get_data (old_surface);
+
+  w = cairo_image_surface_get_width (surface);
+  h = cairo_image_surface_get_height (surface);
+
+  stride = cairo_image_surface_get_stride (surface);
+  old_stride = cairo_image_surface_get_stride (old_surface);
+
+  for (y = 0; y < h; y++)
+    {
+      line = (uint32_t *)data;
+      old_line = (uint32_t *)old_data;
+
+      for (x = 0; x < w; x++)
+       {
+         if ((*line & 0xffffff) == (*old_line & 0xffffff))
+           *old_line = 0;
+         else
+           *old_line = *line | 0xff000000;
+         line ++;
+         old_line ++;
+       }
+
+      data += stride;
+      old_data += old_stride;
+    }
+}
+
+static void
+snippet(cairo_t *cr, int i)
+{
+  if (1)
+    {
+      cairo_save(cr);
+      cairo_rotate (cr, i * 0.002);
+      /* a custom shape that could be wrapped in a function */
+      double x0      = 25.6,   /* parameters like cairo_rectangle */
+       y0      = 25.6,
+       rect_width  = 204.8,
+       rect_height = 204.8,
+       radius = 102.4;   /* and an approximate curvature radius */
+
+      double x1,y1;
+
+      x1=x0+rect_width;
+      y1=y0+rect_height;
+      if (rect_width/2<radius) {
+       if (rect_height/2<radius) {
+         cairo_move_to  (cr, x0, (y0 + y1)/2);
+         cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
+         cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
+         cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
+         cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
+       } else {
+         cairo_move_to  (cr, x0, y0 + radius);
+         cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
+         cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
+         cairo_line_to (cr, x1 , y1 - radius);
+         cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
+         cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
+       }
+      } else {
+       if (rect_height/2<radius) {
+         cairo_move_to  (cr, x0, (y0 + y1)/2);
+         cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
+         cairo_line_to (cr, x1 - radius, y0);
+         cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
+         cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
+         cairo_line_to (cr, x0 + radius, y1);
+         cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
+       } else {
+         cairo_move_to  (cr, x0, y0 + radius);
+         cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
+         cairo_line_to (cr, x1 - radius, y0);
+         cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
+         cairo_line_to (cr, x1 , y1 - radius);
+         cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
+         cairo_line_to (cr, x0 + radius, y1);
+         cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
+       }
+      }
+      cairo_close_path (cr);
+
+      cairo_set_source_rgb (cr, 0.5, 0.5, 1);
+      cairo_fill_preserve (cr);
+      cairo_set_source_rgba (cr, 0.5, 0, 0, 0.5);
+      cairo_set_line_width (cr, 10.0);
+      cairo_stroke (cr);
+      cairo_restore(cr);
+    }
+  if (1)
+    {
+      double xc = 128.0;
+      double yc = 128.0;
+      double radius = 100.0;
+      double angle1 = (45.0 + i * 5)  * (M_PI/180.0);  /* angles are specified */
+      double angle2 = (180.0 + i * 5) * (M_PI/180.0);  /* in radians           */
+
+      cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+
+      cairo_set_line_width (cr, 10.0);
+      cairo_arc (cr, xc, yc, radius, angle1, angle2);
+      cairo_stroke (cr);
+
+      /* draw helping lines */
+      cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
+      cairo_set_line_width (cr, 6.0);
+
+      cairo_arc (cr, xc, yc, 10.0, 0, 2*M_PI);
+      cairo_fill (cr);
+
+      cairo_arc (cr, xc, yc, radius, angle1, angle1);
+      cairo_line_to (cr, xc, yc);
+      cairo_arc (cr, xc, yc, radius, angle2, angle2);
+      cairo_line_to (cr, xc, yc);
+      cairo_stroke (cr);
+    }
+}
+
+static void
+demo2 (BroadwayOutput *output)
+{
+  cairo_t *cr;
+  cairo_surface_t *surface, *old_surface;
+  BroadwayRect rects[2];
+  double da = 0;
+  int i;
+
+  broadway_output_new_surface(output,  0, 100, 100, 800, 600);
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                       800, 600);
+  old_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                           800, 600);
+
+  cr = cairo_create (old_surface);
+  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+  cairo_rectangle (cr, 0, 0, 800, 600);
+  cairo_fill (cr);
+  cairo_destroy (cr);
+
+  for (i = 0; i < 100; i++)
+    {
+      cr = cairo_create (surface);
+
+      cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
+
+      cairo_rectangle (cr, 0, 0, 800, 600);
+      cairo_fill (cr);
+
+      snippet(cr, i);
+
+      cairo_destroy (cr);
+
+      if (i == 0)
+       {
+         broadway_output_put_rgb (output, 0, 0, 0, 800, 600, 800*4,
+                                  cairo_image_surface_get_data(surface)
+                                  );
+         broadway_output_show_surface (output,  0);
+       }
+      else
+       {
+         diff_surfaces (surface,
+                        old_surface);
+         broadway_output_put_rgba (output, 0, 0, 0, 800, 600, 800*4,
+                                   cairo_image_surface_get_data(old_surface));
+       }
+      broadway_output_move_surface (output, 0, 100 + i, 100 + i);
+
+      rects[0].x = 500;
+      rects[0].y = 0;
+      rects[0].width = 100;
+      rects[0].height = 100;
+      rects[1].x = 600;
+      rects[1].y = 100;
+      rects[1].width = 100;
+      rects[1].height = 100;
+      broadway_output_copy_rectangles (output,
+                                      0,
+                                      rects, 2,
+                                      400, 0);
+
+      broadway_output_flush (output);
+
+      cr = cairo_create (old_surface);
+      cairo_set_source_surface (cr, surface, 0, 0);
+      cairo_paint (cr);
+      cairo_destroy (cr);
+
+      da += 10;
+      usleep (50 * 1000);
+  }
+
+
+  cairo_surface_destroy (surface);
+  broadway_output_destroy_surface(output,  0);
+  broadway_output_flush (output);
+}
+
+int
+main (int argc, char *argv[])
+{
+  BroadwayOutput *output;
+
+  output = broadway_output_new (STDOUT_FILENO);
+  demo2(output);
+
+  return 0;
+}
diff --git a/gdk/broadway/broadway.c b/gdk/broadway/broadway.c
new file mode 100644 (file)
index 0000000..009c481
--- /dev/null
@@ -0,0 +1,993 @@
+#include <glib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <zlib.h>
+
+#include "broadway.h"
+
+/************************************************************************
+ *                Base64 functions                                      *
+ ************************************************************************/
+
+static const char base64_alphabet[] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+#if 0
+static void
+base64_uint8 (guint8 v, char *c)
+{
+  c[0] = base64_alphabet[(v >> 0) & 0x3f];
+  c[1] = base64_alphabet[(v >> 6) & 0x3];
+}
+#endif
+
+static void
+base64_uint16 (guint32 v, char *c)
+{
+  c[0] = base64_alphabet[(v >> 0) & 0x3f];
+  c[1] = base64_alphabet[(v >> 6) & 0x3f];
+  c[2] = base64_alphabet[(v >> 12) & 0xf];
+}
+
+#if 0
+static void
+base64_uint24 (guint32 v, char *c)
+{
+  c[0] = base64_alphabet[(v >> 0) & 0x3f];
+  c[1] = base64_alphabet[(v >> 6) & 0x3f];
+  c[2] = base64_alphabet[(v >> 12) & 0x3f];
+  c[3] = base64_alphabet[(v >> 18) & 0x3f];
+}
+#endif
+
+static void
+base64_uint32 (guint32 v, char *c)
+{
+  c[0] = base64_alphabet[(v >> 0) & 0x3f];
+  c[1] = base64_alphabet[(v >> 6) & 0x3f];
+  c[2] = base64_alphabet[(v >> 12) & 0x3f];
+  c[3] = base64_alphabet[(v >> 18) & 0x3f];
+  c[4] = base64_alphabet[(v >> 24) & 0x3f];
+  c[5] = base64_alphabet[(v >> 30) & 0x2];
+}
+
+/************************************************************************
+ *  conversion of raw image data to uncompressed png data: uris         *
+ ************************************************************************/
+
+/* Table of CRCs of all 8-bit messages. */
+static unsigned long crc_table[256];
+
+/* Flag: has the table been computed? Initially false. */
+static int crc_table_computed = 0;
+
+/* Make the table for a fast CRC. */
+static void
+make_crc_table(void)
+{
+  unsigned long c;
+  int n, k;
+
+  for (n = 0; n < 256; n++) {
+    c = (unsigned long) n;
+    for (k = 0; k < 8; k++) {
+      if (c & 1)
+       c = 0xedb88320L ^ (c >> 1);
+      else
+       c = c >> 1;
+    }
+    crc_table[n] = c;
+  }
+  crc_table_computed = 1;
+}
+
+static unsigned long
+update_crc(unsigned long crc, unsigned char *buf, int len)
+{
+  unsigned long c = crc;
+  int n;
+
+  if (!crc_table_computed)
+    make_crc_table();
+  for (n = 0; n < len; n++) {
+    c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
+  }
+  return c;
+}
+
+static unsigned long
+crc(unsigned char *buf, int len)
+{
+  return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
+}
+
+#define BASE 65521 /* largest prime smaller than 65536 */
+static unsigned long
+update_adler32(unsigned long adler, unsigned char *buf, int len)
+{
+  unsigned long s1 = adler & 0xffff;
+  unsigned long s2 = (adler >> 16) & 0xffff;
+  int n;
+
+  for (n = 0; n < len; n++) {
+    s1 = (s1 + buf[n]) % BASE;
+    s2 = (s2 + s1)     % BASE;
+  }
+  return (s2 << 16) + s1;
+}
+
+static char *
+to_png_rgb (int w, int h, int byte_stride, guint32 *data)
+{
+  guchar header[] = {137, 80, 78, 71, 13, 10, 26, 10};
+  guchar ihdr[13+12] = {0, 0, 0, 13, 'I', 'H', 'D', 'R',
+                       /* w: */ 0, 0, 0, 0, /* h: */ 0,0,0,0,
+                       /* bpp: */ 8, /* color type: */ 2,
+                       0, 0, 0};
+  guchar idat_start[8] = { /* len: */0, 0, 0, 0,   'I', 'D', 'A', 'T' };
+  guchar iend[12] = {0, 0, 0, 0, 'I', 'E', 'N', 'D', 0xae, 0x42, 0x60, 0x82};
+  gsize data_size, row_size;
+  char row_header[6];
+  guint8 *png, *p, *p_row, *p_idat;
+  guint32 *row;
+  unsigned long adler;
+  guint32 pixel;
+  gsize png_size;
+  int x, y;
+  char *url, *url_base64;
+  int state = 0, outlen;
+  int save = 0;
+
+  *(guint32 *)&ihdr[8] = GUINT32_TO_BE(w);
+  *(guint32 *)&ihdr[12] = GUINT32_TO_BE(h);
+  *(guint32 *)&ihdr[21] = GUINT32_TO_BE(crc(&ihdr[4], 13 + 4));
+
+  row_size = 1 + w * 3;
+  row_header[0] = 0;
+  row_header[1] = row_size & 0xff;
+  row_header[2] = (row_size >> 8) & 0xff;
+  row_header[3] = ~row_header[1];
+  row_header[4] = ~row_header[2];
+  row_header[5] = 0;
+
+  data_size = 2 + (6 + w * 3) * h + 4;
+
+  *(guint32 *)&idat_start[0] = GUINT32_TO_BE(data_size);
+
+  png_size = sizeof(header) + sizeof(ihdr) + 12 + data_size + sizeof(iend);
+  png = g_malloc (png_size);
+
+  p = png;
+  memcpy (p, header, sizeof(header));
+  p += sizeof(header);
+  memcpy (p, ihdr, sizeof(ihdr));
+  p += sizeof(ihdr);
+  memcpy (p, idat_start, sizeof(idat_start));
+  p += sizeof(idat_start);
+
+  /* IDAT data:
+
+     zlib header:  0x78, 0x01 ,
+     h * scanline: row_header[] + width * r,g,b
+     checksum: adler32
+  */
+
+  p_idat = p - 4;
+
+  /* zlib header */
+  *p++ = 0x78;
+  *p++ = 0x01;
+
+  adler = 1;
+
+  /* scanline data */
+  for (y = 0; y < h; y++) {
+    if (y == h - 1)
+      row_header[0] = 1; /* final block */
+    memcpy (p, row_header, sizeof(row_header));
+    p += sizeof(row_header);
+    p_row = p - 1;
+    row = data;
+    data += byte_stride / 4;
+    for (x = 0; x < w; x++) {
+      pixel = *row++;
+      *p++ = (pixel >> 16) & 0xff; /* red */
+      *p++ = (pixel >> 8) & 0xff; /* green */
+      *p++ = (pixel >> 0) & 0xff; /* blue */
+    }
+    adler = update_adler32(adler, p_row, p - p_row);
+  }
+
+  /* adler32 */
+  *(guint32 *)p = GUINT32_TO_BE(adler);
+  p += 4;
+  *(guint32 *)p = GUINT32_TO_BE(crc(p_idat, p - p_idat));
+  p += 4;
+
+  memcpy (p, iend, sizeof(iend));
+  p += sizeof(iend);
+
+  assert(p - png == png_size);
+
+  url = g_malloc (strlen("data:image/png;base64,") +
+                  ((png_size / 3 + 1) * 4 + 4) + 1);
+  strcpy (url, "data:image/png;base64,");
+
+  url_base64 = url + strlen("data:image/png;base64,");
+  outlen = g_base64_encode_step (png, png_size, FALSE, url_base64, &state, &save);
+  outlen += g_base64_encode_close (FALSE, url_base64 + outlen, &state, &save);
+  url_base64[outlen] = 0;
+
+  free (png);
+
+  return url;
+}
+
+static char *
+to_png_rgba (int w, int h, int byte_stride, guint32 *data)
+{
+  guchar header[] = {137, 80, 78, 71, 13, 10, 26, 10};
+  guchar ihdr[13+12] = {0, 0, 0, 13, 'I', 'H', 'D', 'R',
+                       /* w: */ 0, 0, 0, 0, /* h: */ 0,0,0,0,
+                       /* bpp: */ 8, /* color type: */ 6,
+                       0, 0, 0};
+  guchar idat_start[8] = { /* len: */0, 0, 0, 0,   'I', 'D', 'A', 'T' };
+  guchar iend[12] = {0, 0, 0, 0, 'I', 'E', 'N', 'D', 0xae, 0x42, 0x60, 0x82};
+  gsize data_size, row_size;
+  char row_header[6];
+  guint8 *png, *p, *p_row, *p_idat;
+  guint32 *row;
+  unsigned long adler;
+  guint32 pixel;
+  gsize png_size;
+  int x, y;
+  char *url, *url_base64;
+  int state = 0, outlen;
+  int save = 0;
+
+  *(guint32 *)&ihdr[8] = GUINT32_TO_BE(w);
+  *(guint32 *)&ihdr[12] = GUINT32_TO_BE(h);
+  *(guint32 *)&ihdr[21] = GUINT32_TO_BE(crc(&ihdr[4], 13 + 4));
+
+  row_size = 1 + w * 4;
+  row_header[0] = 0;
+  row_header[1] = row_size & 0xff;
+  row_header[2] = (row_size >> 8) & 0xff;
+  row_header[3] = ~row_header[1];
+  row_header[4] = ~row_header[2];
+  row_header[5] = 0;
+
+  data_size = 2 + (6 + w * 4) * h + 4;
+
+  *(guint32 *)&idat_start[0] = GUINT32_TO_BE(data_size);
+
+  png_size = sizeof(header) + sizeof(ihdr) + 12 + data_size + sizeof(iend);
+  png = g_malloc (png_size);
+
+  p = png;
+  memcpy (p, header, sizeof(header));
+  p += sizeof(header);
+  memcpy (p, ihdr, sizeof(ihdr));
+  p += sizeof(ihdr);
+  memcpy (p, idat_start, sizeof(idat_start));
+  p += sizeof(idat_start);
+
+  /* IDAT data:
+
+     zlib header:  0x78, 0x01 ,
+     h * scanline: row_header[] + width * r,g,b,a
+     checksum: adler32
+  */
+
+  p_idat = p - 4;
+
+  /* zlib header */
+  *p++ = 0x78;
+  *p++ = 0x01;
+
+  adler = 1;
+
+  /* scanline data */
+  for (y = 0; y < h; y++) {
+    if (y == h - 1)
+      row_header[0] = 1; /* final block */
+    memcpy (p, row_header, sizeof(row_header));
+    p += sizeof(row_header);
+    p_row = p - 1;
+    row = data;
+    data += byte_stride / 4;
+    for (x = 0; x < w; x++) {
+      pixel = *row++;
+      *p++ = (pixel >> 16) & 0xff; /* red */
+      *p++ = (pixel >> 8) & 0xff; /* green */
+      *p++ = (pixel >> 0) & 0xff; /* blue */
+      *p++ = (pixel >> 24) & 0xff; /* alpha */
+    }
+    adler = update_adler32(adler, p_row, p - p_row);
+  }
+
+  /* adler32 */
+  *(guint32 *)p = GUINT32_TO_BE(adler);
+  p += 4;
+  *(guint32 *)p = GUINT32_TO_BE(crc(p_idat, p - p_idat));
+  p += 4;
+
+  memcpy (p, iend, sizeof(iend));
+  p += sizeof(iend);
+
+  assert(p - png == png_size);
+
+  url = g_malloc (strlen("data:image/png;base64,") +
+                  ((png_size / 3 + 1) * 4 + 4) + 1);
+  strcpy (url, "data:image/png;base64,");
+
+  url_base64 = url + strlen("data:image/png;base64,");
+  outlen = g_base64_encode_step (png, png_size, FALSE, url_base64, &state, &save);
+  outlen += g_base64_encode_close (FALSE, url_base64 + outlen, &state, &save);
+  url_base64[outlen] = 0;
+
+  free (png);
+
+  return url;
+}
+
+#if 0
+static char *
+to_png_a (int w, int h, int byte_stride, guint8 *data)
+{
+  guchar header[] = {137, 80, 78, 71, 13, 10, 26, 10};
+  guchar ihdr[13+12] = {0, 0, 0, 13, 'I', 'H', 'D', 'R',
+                       /* w: */ 0, 0, 0, 0, /* h: */ 0,0,0,0,
+                       /* bpp: */ 8, /* color type: */ 4,
+                       0, 0, 0};
+  guchar idat_start[8] = { /* len: */0, 0, 0, 0,   'I', 'D', 'A', 'T' };
+  guchar iend[12] = {0, 0, 0, 0, 'I', 'E', 'N', 'D', 0xae, 0x42, 0x60, 0x82};
+  gsize data_size, row_size;
+  char row_header[6];
+  guint8 *png, *p, *p_row, *p_idat;
+  guint8 *row;
+  unsigned long adler;
+  guint32 pixel;
+  gsize png_size;
+  int x, y;
+  char *url, *url_base64;
+  int state = 0, outlen;
+  int save = 0;
+
+  *(guint32 *)&ihdr[8] = GUINT32_TO_BE(w);
+  *(guint32 *)&ihdr[12] = GUINT32_TO_BE(h);
+  *(guint32 *)&ihdr[21] = GUINT32_TO_BE(crc(&ihdr[4], 13 + 4));
+
+  row_size = 1 + w * 2;
+  row_header[0] = 0;
+  row_header[1] = row_size & 0xff;
+  row_header[2] = (row_size >> 8) & 0xff;
+  row_header[3] = ~row_header[1];
+  row_header[4] = ~row_header[2];
+  row_header[5] = 0;
+
+  data_size = 2 + (6 + w * 2) * h + 4;
+
+  *(guint32 *)&idat_start[0] = GUINT32_TO_BE(data_size);
+
+  png_size = sizeof(header) + sizeof(ihdr) + 12 + data_size + sizeof(iend);
+  png = g_malloc (png_size);
+
+  p = png;
+  memcpy (p, header, sizeof(header));
+  p += sizeof(header);
+  memcpy (p, ihdr, sizeof(ihdr));
+  p += sizeof(ihdr);
+  memcpy (p, idat_start, sizeof(idat_start));
+  p += sizeof(idat_start);
+
+  /* IDAT data:
+
+     zlib header:  0x78, 0x01 ,
+     h * scanline: row_header[] + width * r,g,b,a
+     checksum: adler32
+  */
+
+  p_idat = p - 4;
+
+  /* zlib header */
+  *p++ = 0x78;
+  *p++ = 0x01;
+
+  adler = 1;
+
+  /* scanline data */
+  for (y = 0; y < h; y++) {
+    if (y == h - 1)
+      row_header[0] = 1; /* final block */
+    memcpy (p, row_header, sizeof(row_header));
+    p += sizeof(row_header);
+    p_row = p - 1;
+    row = data;
+    data += byte_stride / 4;
+    for (x = 0; x < w; x++) {
+      pixel = *row++;
+      *p++ = 0x00; /* gray */
+      *p++ = pixel; /* alpha */
+    }
+    adler = update_adler32(adler, p_row, p - p_row);
+  }
+
+  /* adler32 */
+  *(guint32 *)p = GUINT32_TO_BE(adler);
+  p += 4;
+  *(guint32 *)p = GUINT32_TO_BE(crc(p_idat, p - p_idat));
+  p += 4;
+
+  memcpy (p, iend, sizeof(iend));
+  p += sizeof(iend);
+
+  assert(p - png == png_size);
+
+  url = g_malloc (strlen("data:image/png;base64,") +
+                 ((png_size / 3 + 1) * 4 + 4) + 1);
+  strcpy (url, "data:image/png;base64,");
+
+  url_base64 = url + strlen("data:image/png;base64,");
+  outlen = g_base64_encode_step (png, png_size, FALSE, url_base64, &state, &save);
+  outlen += g_base64_encode_close (FALSE, url_base64 + outlen, &state, &save);
+  url_base64[outlen] = 0;
+
+  free (png);
+
+  return url;
+}
+#endif
+
+/************************************************************************
+ *                Basic I/O primitives                                  *
+ ************************************************************************/
+
+struct BroadwayOutput {
+  int fd;
+  gzFile *zfd;
+  int error;
+};
+
+static void
+broadway_output_write_raw (BroadwayOutput *output,
+                          const void *buf, gsize count)
+{
+  gssize res;
+  int errsave;
+  const char *ptr = (const char *)buf;
+
+  if (output->error)
+    return;
+
+  while (count > 0)
+    {
+      res = write(output->fd, ptr, count);
+      if (res == -1)
+       {
+         errsave = errno;
+         if (errsave == EINTR)
+           continue;
+         output->error = TRUE;
+         return;
+       }
+      if (res == 0)
+       {
+         output->error = TRUE;
+         return;
+       }
+      count -= res;
+      ptr += res;
+    }
+}
+
+static void
+broadway_output_write (BroadwayOutput *output,
+                      const void *buf, gsize count)
+{
+  gssize res;
+  const char *ptr = (const char *)buf;
+
+  if (output->error)
+    return;
+
+  while (count > 0)
+    {
+      res = gzwrite(output->zfd, ptr, count);
+      if (res == -1)
+       {
+         output->error = TRUE;
+         return;
+       }
+      if (res == 0)
+       {
+         output->error = TRUE;
+         return;
+       }
+      count -= res;
+      ptr += res;
+    }
+}
+
+static void
+broadway_output_write_header (BroadwayOutput *output)
+{
+  char *header;
+
+  header =
+    "HTTP/1.1 200 OK\r\n"
+    "Content-type: multipart/x-mixed-replace;boundary=x\r\n"
+    "Content-Encoding: gzip\r\n"
+    "\r\n";
+  broadway_output_write_raw (output,
+                            header, strlen (header));
+}
+
+static void
+send_boundary (BroadwayOutput *output)
+{
+  char *boundary =
+    "--x\r\n"
+    "\r\n";
+
+  broadway_output_write (output, boundary, strlen (boundary));
+}
+
+BroadwayOutput *
+broadway_output_new(int fd)
+{
+  BroadwayOutput *output;
+
+  output = g_new0 (BroadwayOutput, 1);
+
+  output->fd = fd;
+
+  broadway_output_write_header (output);
+
+  output->zfd = gzdopen(fd, "wb");
+
+  /* Need an initial multipart boundary */
+  send_boundary (output);
+
+  return output;
+}
+
+void
+broadway_output_free (BroadwayOutput *output)
+{
+  if (output->zfd)
+    gzclose (output->zfd);
+  else
+    close (output->fd);
+  free (output);
+}
+
+int
+broadway_output_flush (BroadwayOutput *output)
+{
+  send_boundary (output);
+  gzflush (output->zfd, Z_SYNC_FLUSH);
+  return !output->error;
+}
+
+
+/************************************************************************
+ *                     Core rendering operations                        *
+ ************************************************************************/
+
+void
+broadway_output_copy_rectangles (BroadwayOutput *output,  int id,
+                                BroadwayRect *rects, int n_rects,
+                                int dx, int dy)
+{
+  char *buf;
+  int len, i, p;
+
+  len = 1 + 3 + 3 + 3*4*n_rects + 3 + 3;
+
+  buf = g_malloc (len);
+  p = 0;
+  buf[p++] = 'b';
+  base64_uint16(id, &buf[p]); p +=3;
+  base64_uint16(n_rects, &buf[p]); p +=3;
+  for (i = 0; i < n_rects; i++)
+    {
+      base64_uint16(rects[i].x, &buf[p]); p +=3;
+      base64_uint16(rects[i].y, &buf[p]); p +=3;
+      base64_uint16(rects[i].width, &buf[p]); p +=3;
+      base64_uint16(rects[i].height, &buf[p]); p +=3;
+    }
+  base64_uint16(dx, &buf[p]); p +=3;
+  base64_uint16(dy, &buf[p]); p +=3;
+
+  broadway_output_write (output, buf, len);
+  free (buf);
+}
+
+void
+broadway_output_new_surface(BroadwayOutput *output,  int id, int x, int y, int w, int h)
+{
+  char buf[16];
+
+  buf[0] = 's';
+  base64_uint16(id, &buf[1]);
+  base64_uint16(x, &buf[4]);
+  base64_uint16(y, &buf[7]);
+  base64_uint16(w, &buf[10]);
+  base64_uint16(h, &buf[13]);
+
+  broadway_output_write (output, buf, 16);
+}
+
+void
+broadway_output_show_surface(BroadwayOutput *output,  int id)
+{
+  char buf[4];
+
+  buf[0] = 'S';
+  base64_uint16(id, &buf[1]);
+
+  broadway_output_write (output, buf, 4);
+}
+
+void
+broadway_output_hide_surface(BroadwayOutput *output,  int id)
+{
+  char buf[4];
+
+  buf[0] = 'H';
+  base64_uint16(id, &buf[1]);
+
+  broadway_output_write (output, buf, 4);
+}
+
+void
+broadway_output_destroy_surface(BroadwayOutput *output,  int id)
+{
+  char buf[4];
+
+  buf[0] = 'd';
+  base64_uint16(id, &buf[1]);
+
+  broadway_output_write (output, buf, 4);
+}
+
+void
+broadway_output_move_surface(BroadwayOutput *output,  int id, int x, int y)
+{
+  char buf[10];
+
+  buf[0] = 'm';
+  base64_uint16(id, &buf[1]);
+  base64_uint16(x, &buf[4]);
+  base64_uint16(y, &buf[7]);
+
+  broadway_output_write (output, buf, 10);
+}
+
+void
+broadway_output_resize_surface(BroadwayOutput *output,  int id, int w, int h)
+{
+  char buf[10];
+
+  buf[0] = 'r';
+  base64_uint16(id, &buf[1]);
+  base64_uint16(w, &buf[4]);
+  base64_uint16(h, &buf[7]);
+
+  broadway_output_write (output, buf, 10);
+}
+
+void
+broadway_output_put_rgb (BroadwayOutput *output,  int id, int x, int y,
+                        int w, int h, int byte_stride, void *data)
+{
+  char buf[16];
+  gsize len;
+  char *url;
+
+  buf[0] = 'i';
+  base64_uint16(id, &buf[1]);
+  base64_uint16(x, &buf[4]);
+  base64_uint16(y, &buf[7]);
+
+  url = to_png_rgb (w, h, byte_stride, (guint32*)data);
+  len = strlen (url);
+  base64_uint32(len, &buf[10]);
+
+  broadway_output_write (output, buf, 16);
+
+  broadway_output_write (output, url, len);
+
+  free (url);
+}
+
+typedef struct  {
+  int x1, y1;
+  int x2, y2;
+} BroadwayBox;
+
+static int
+is_any_x_set (unsigned char *data,
+             int box_x1, int box_x2,
+             int x1, int x2, int y, int *x_set,
+             int byte_stride)
+{
+  int w ;
+  guint32 *ptr;
+
+  if (x1 < box_x1)
+    x1 = box_x1;
+
+  if (x2 > box_x2)
+    x2 = box_x2;
+
+  w = x2 - x1;
+  if (w > 0)
+    {
+      ptr = (guint32 *)(data + y * byte_stride + x1 * 4);
+      while (w-- > 0)
+       {
+         if (*ptr != 0)
+           {
+             if (x_set)
+               *x_set = x1;
+             return 1;
+           }
+         ptr++;
+         x1++;
+       }
+    }
+  return 0;
+}
+
+
+#define EXTEND_X_FUZZ 10
+#define EXTEND_Y_FUZZ 10
+
+static int
+extend_x_range (unsigned char *data,
+               int box_x1, int box_y1,
+               int box_x2, int box_y2,
+               int *x1, int *x2, int y,
+               int byte_stride)
+{
+  int extended = 0;
+  int new_x;
+
+  while (is_any_x_set (data, box_x1, box_x2, *x1 - EXTEND_X_FUZZ, *x1, y, &new_x, byte_stride))
+    {
+      *x1 = new_x;
+      extended = 1;
+    }
+
+  while (is_any_x_set (data, box_x1, box_x2, *x2, *x2 + EXTEND_X_FUZZ, y, &new_x, byte_stride))
+    {
+      *x2 = new_x + 1;
+      extended = 1;
+    }
+
+  return extended;
+}
+
+static int
+extend_y_range (unsigned char *data,
+               int box_x1, int box_y1,
+               int box_x2, int box_y2,
+               int x1, int x2, int *y,
+               int byte_stride)
+{
+  int extended = 0;
+  int found_set;
+  int yy, y2;
+
+  while (*y < box_y2)
+    {
+      found_set = 0;
+
+      y2 = *y + EXTEND_Y_FUZZ;
+      if (y2 > box_y2)
+       y2 = box_y2;
+
+      for (yy = y2; yy > *y + 1; yy--)
+       {
+         if (is_any_x_set (data, box_x1, box_x2, x1, x2, yy - 1, NULL, byte_stride))
+           {
+             found_set = 1;
+             break;
+           }
+       }
+      if (!found_set)
+       break;
+      *y = yy;
+      extended = 1;
+    }
+
+  return extended;
+}
+
+
+static void
+rgba_find_rects_extents (unsigned char *data,
+                        int box_x1, int box_y1,
+                        int box_x2, int box_y2,
+                        int x, int y,
+                        BroadwayBox *rect,
+                        int byte_stride)
+{
+  int x1, x2, y1, y2, yy;
+  int extended;
+
+  x1 = x;
+  x2 = x + 1;
+  y1 = y;
+  y2 = y + 1;
+
+  do
+    {
+      /* Expand maximally for all known rows */
+      do
+       {
+         extended = 0;
+
+         for (yy = y1; yy < y2; yy++)
+           extended |= extend_x_range (data,
+                                       box_x1, box_y1,
+                                       box_x2, box_y2,
+                                       &x1, &x2, yy,
+                                       byte_stride);
+       }
+      while (extended);
+    }
+  while (extend_y_range(data,
+                       box_x1, box_y1,
+                       box_x2, box_y2,
+                       x1, x2, &y2,
+                       byte_stride));
+
+  rect->x1 = x1;
+  rect->x2 = x2;
+  rect->y1 = y1;
+  rect->y2 = y2;
+}
+
+static void
+rgba_find_rects_sub (unsigned char *data,
+                    int box_x1, int box_y1,
+                    int box_x2, int box_y2,
+                    int byte_stride,
+                    BroadwayBox **rects,
+                    int *n_rects, int *alloc_rects)
+{
+  guint32 *line;
+  BroadwayBox rect;
+  int x, y;
+
+  if (box_x1 == box_x2 || box_y1 == box_y2)
+    return;
+
+  for (y = box_y1; y < box_y2; y++)
+    {
+      line = (guint32 *)(data + y * byte_stride + box_x1 * 4);
+
+      for (x = box_x1; x < box_x2; x++)
+       {
+         if (*line != 0)
+           {
+             rgba_find_rects_extents (data,
+                                      box_x1, box_y1, box_x2, box_y2,
+                                      x, y, &rect, byte_stride);
+             if (*n_rects == *alloc_rects)
+               {
+                 (*alloc_rects) *= 2;
+                 *rects = g_renew (BroadwayBox, *rects, *alloc_rects);
+               }
+             (*rects)[*n_rects] = rect;
+             (*n_rects)++;
+             rgba_find_rects_sub (data,
+                                  box_x1, rect.y1,
+                                  rect.x1, rect.y2,
+                                  byte_stride,
+                                  rects, n_rects, alloc_rects);
+             rgba_find_rects_sub (data,
+                                  rect.x2, rect.y1,
+                                  box_x2, rect.y2,
+                                  byte_stride,
+                                  rects, n_rects, alloc_rects);
+             rgba_find_rects_sub (data,
+                                  box_x1, rect.y2,
+                                  box_x2, box_y2,
+                                  byte_stride,
+                                  rects, n_rects, alloc_rects);
+             return;
+           }
+         line++;
+       }
+    }
+}
+
+static BroadwayBox *
+rgba_find_rects (unsigned char *data,
+                int w, int h, int byte_stride,
+                int *n_rects)
+{
+  BroadwayBox *rects;
+  int alloc_rects;
+
+  alloc_rects = 20;
+  rects = g_new (BroadwayBox, alloc_rects);
+
+  *n_rects = 0;
+  rgba_find_rects_sub (data,
+                      0, 0, w, h, byte_stride,
+                      &rects, n_rects, &alloc_rects);
+
+  return rects;
+}
+
+void
+broadway_output_put_rgba (BroadwayOutput *output,  int id, int x, int y,
+                         int w, int h, int byte_stride, void *data)
+{
+  char buf[16];
+  gsize len;
+  char *url;
+  BroadwayBox *rects;
+  int i, n_rects;
+  guint8 *subdata;
+
+  rects = rgba_find_rects (data, w, h, byte_stride, &n_rects);
+
+  for (i = 0; i < n_rects; i++)
+    {
+      subdata = (guint8 *)data + rects[i].x1 * 4 + rects[i].y1 * byte_stride;
+
+      buf[0] = 'i';
+      base64_uint16(id, &buf[1]);
+      base64_uint16(x + rects[i].x1, &buf[4]);
+      base64_uint16(y + rects[i].y1, &buf[7]);
+
+      url = to_png_rgba (rects[i].x2 - rects[i].x1,
+                        rects[i].y2 - rects[i].y1,
+                        byte_stride, (guint32*)subdata);
+      len = strlen (url);
+      base64_uint32(len, &buf[10]);
+
+      broadway_output_write (output, buf, 16);
+
+      broadway_output_write (output, url, len);
+
+      free (url);
+    }
+
+  free (rects);
+}
+
+#if 0
+static void
+send_image_a (BroadwayOutput *output,  int id, int x, int y,
+             int w, int h, int byte_stride, guint8 *data)
+{
+  char buf[16];
+  gsize len;
+  char *url;
+
+  buf[0] = 'i';
+  base64_uint16(id, &buf[1]);
+  base64_uint16(x, &buf[4]);
+  base64_uint16(y, &buf[7]);
+
+  url = to_png_a (w, h, byte_stride, data);
+  len = strlen (url);
+  base64_uint32(len, &buf[10]);
+
+  broadway_output_write (output, buf, 16);
+
+  broadway_output_write (output, url, len);
+
+  free (url);
+}
+#endif
diff --git a/gdk/broadway/broadway.h b/gdk/broadway/broadway.h
new file mode 100644 (file)
index 0000000..0f7a7eb
--- /dev/null
@@ -0,0 +1,53 @@
+typedef struct BroadwayOutput BroadwayOutput;
+
+typedef struct  {
+    int x, y;
+    int width, height;
+} BroadwayRect;
+
+BroadwayOutput *broadway_output_new             (int             fd);
+void            broadway_output_free            (BroadwayOutput *output);
+int             broadway_output_flush           (BroadwayOutput *output);
+int             broadway_output_has_error       (BroadwayOutput *output);
+void            broadway_output_new_surface     (BroadwayOutput *output,
+                                                int             id,
+                                                int             x,
+                                                int             y,
+                                                int             w,
+                                                int             h);
+void            broadway_output_show_surface    (BroadwayOutput *output,
+                                                int             id);
+void            broadway_output_hide_surface    (BroadwayOutput *output,
+                                                int             id);
+void            broadway_output_destroy_surface (BroadwayOutput *output,
+                                                int             id);
+void            broadway_output_move_surface    (BroadwayOutput *output,
+                                                int             id,
+                                                int             x,
+                                                int             y);
+void            broadway_output_resize_surface  (BroadwayOutput *output,
+                                                int             id,
+                                                int             w,
+                                                int             h);
+void            broadway_output_put_rgb         (BroadwayOutput *output,
+                                                int             id,
+                                                int             x,
+                                                int             y,
+                                                int             w,
+                                                int             h,
+                                                int             byte_stride,
+                                                void           *data);
+void            broadway_output_put_rgba        (BroadwayOutput *output,
+                                                int             id,
+                                                int             x,
+                                                int             y,
+                                                int             w,
+                                                int             h,
+                                                int             byte_stride,
+                                                void           *data);
+void            broadway_output_copy_rectangles (BroadwayOutput *output,
+                                                int             id,
+                                                BroadwayRect   *rects,
+                                                int             n_rects,
+                                                int             dx,
+                                                int             dy);
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
new file mode 100644 (file)
index 0000000..85f5448
--- /dev/null
@@ -0,0 +1,378 @@
+var base64_val = [
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
+   52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,  0,255,255,
+  255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
+  255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255
+]
+
+function base64_8(str, index) {
+  var v =
+    (base64_val[str.charCodeAt(index)]) +
+    (base64_val[str.charCodeAt(index+1)] << 6);
+  return v;
+}
+
+function base64_16(str, index) {
+  var v =
+    (base64_val[str.charCodeAt(index)]) +
+    (base64_val[str.charCodeAt(index+1)] << 6) +
+    (base64_val[str.charCodeAt(index+2)] << 12);
+  return v;
+}
+
+function base64_16s(str, index) {
+  var v = base64_16(str, index);
+  if (v > 32767)
+    return v - 65536;
+  else
+    return v;
+}
+
+function base64_24(str, index) {
+  var v =
+    (base64_val[str.charCodeAt(index)]) +
+    (base64_val[str.charCodeAt(index+1)] << 6) +
+    (base64_val[str.charCodeAt(index+2)] << 12) +
+    (base64_val[str.charCodeAt(index+3)] << 18);
+  return v;
+}
+
+function base64_32(str, index) {
+  var v =
+    (base64_val[str.charCodeAt(index)]) +
+    (base64_val[str.charCodeAt(index+1)] << 6) +
+    (base64_val[str.charCodeAt(index+2)] << 12) +
+    (base64_val[str.charCodeAt(index+3)] << 18) +
+    (base64_val[str.charCodeAt(index+4)] << 24) +
+    (base64_val[str.charCodeAt(index+5)] << 30);
+  return v;
+}
+
+function createXHR()
+{
+  try { return new XMLHttpRequest(); } catch(e) {}
+  try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) {}
+  try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e) {}
+  try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
+  try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
+
+  return null;
+}
+
+var surfaces = {};
+var outstanding_commands = new Array();
+var input_socket = null;
+
+function initContext(canvas, x, y, id)
+{
+  canvas.surface_id = id;
+  canvas.style["position"] = "absolute"
+  canvas.style["left"] = x + "px"
+  canvas.style["top"] = y + "px"
+  canvas.style["display"] = "none"
+  context = canvas.getContext("2d")
+  context.globalCompositeOperation = "src-over"
+  context.fillRect(0, 0, canvas.width, canvas.height);
+  document.body.appendChild(canvas)
+
+  return context
+}
+
+function handleCommands(cmd_obj)
+{
+  var cmd = cmd_obj.data;
+  var i = cmd_obj.pos;
+
+  while (i < cmd.length) {
+    var command = cmd[i++];
+    switch (command) {
+      /* create new surface */
+      case 's':
+        var id = base64_16(cmd, i);
+        i = i + 3;
+        var x = base64_16(cmd, i);
+        i = i + 3;
+        var y = base64_16(cmd, i);
+        i = i + 3;
+        var w = base64_16(cmd, i);
+        i = i + 3;
+        var h = base64_16(cmd, i);
+        i = i + 3;
+        var surface = document.createElement("canvas");
+       surface.width = w;
+       surface.height = h;
+       surfaces[id] = initContext(surface, x, y, id);
+        break;
+
+      /* show a surface */
+      case 'S':
+        var id = base64_16(cmd, i);
+        i = i + 3;
+       surfaces[id].canvas.style["display"] = "inline";
+        break;
+
+      /* hide a surface */
+      case 'H':
+        var id = base64_16(cmd, i);
+        i = i + 3;
+       surfaces[id].canvas.style["display"] = "inline";
+        break;
+
+      /* delete surface */
+      case 'd':
+        var id = base64_16(cmd, i);
+        i = i + 3;
+       var canvas = surfaces[id].canvas
+       delete surfaces[id]
+       canvas.parentNode.removeChild(canvas);
+
+        break;
+
+      /* move a surface */
+      case 'm':
+        var id = base64_16(cmd, i);
+        i = i + 3;
+        var x = base64_16(cmd, i);
+        i = i + 3;
+        var y = base64_16(cmd, i);
+        i = i + 3;
+       surfaces[id].canvas.style["left"] = x + "px";
+       surfaces[id].canvas.style["top"] = y + "px";
+        break;
+
+      /* resize a surface */
+      case 'r':
+        var id = base64_16(cmd, i);
+        i = i + 3;
+        var w = base64_16(cmd, i);
+        i = i + 3;
+        var h = base64_16(cmd, i);
+        i = i + 3;
+       surfaces[id].canvas.width = w;
+       surfaces[id].canvas.height = h;
+        break;
+
+      /* put image data surface */
+      case 'i':
+        var id = base64_16(cmd, i);
+        i = i + 3;
+        var x = base64_16(cmd, i);
+        i = i + 3;
+        var y = base64_16(cmd, i);
+        i = i + 3;
+        var size = base64_32(cmd, i);
+        i = i + 6;
+       var url = cmd.slice(i, i + size);
+       i = i + size;
+        var img = new Image();
+       img.src = url
+       if (img.complete) {
+          surfaces[id].drawImage(img, x, y);
+       } else {
+         cmd_obj.pos = i;
+         img.onload = function() { surfaces[id].drawImage(img, x, y); handleOutstanding(); }
+         return false
+       }
+
+        break;
+
+      /* copy rects */
+      case 'b':
+        var id = base64_16(cmd, i);
+        i = i + 3;
+
+       var nrects = base64_16(cmd, i);
+        i = i + 3;
+
+       var context = surfaces[id];
+       context.save();
+
+       var minx;
+       var miny;
+       var maxx;
+       var maxy;
+       for (var r = 0; r < nrects; r++) {
+         var x = base64_16(cmd, i);
+          i = i + 3;
+          var y = base64_16(cmd, i);
+          i = i + 3;
+          var w = base64_16(cmd, i);
+          i = i + 3;
+          var h = base64_16(cmd, i);
+          i = i + 3;
+         context.rect(x, y, w, h);
+
+         if (r == 0) {
+             minx = x;
+             miny = y;
+             maxx = x + w;
+             maxy = y + h;
+         } else {
+             if (x < minx)
+                 minx = x;
+             if (y < miny)
+                 miny = y;
+             if (x + w > maxx)
+                 maxx = x + w;
+             if (y + h > maxy)
+                 maxy = y + h;
+         }
+       }
+
+       context.clip()
+
+        var dx = base64_16s(cmd, i);
+        i = i + 3;
+        var dy = base64_16s(cmd, i);
+        i = i + 3;
+
+        context.drawImage(context.canvas,
+                         minx - dx, miny - dy, maxx - minx, maxy - miny,
+                         minx, miny, maxx - minx, maxy - miny);
+
+       context.restore();
+        break;
+
+      default:
+        alert("Unknown op " + command);
+    }
+  }
+  return true;
+}
+
+function handleOutstanding()
+{
+  while (outstanding_commands.length > 0) {
+    var cmd = outstanding_commands.shift();
+    if (!handleCommands(cmd)) {
+      outstanding_commands.unshift(cmd);
+      return;
+    }
+  }
+}
+
+function handleLoad(event)
+{
+  var cmd_obj = {};
+  cmd_obj.data = event.target.responseText;
+  cmd_obj.pos = 0;
+
+  outstanding_commands.push(cmd_obj);
+  if (outstanding_commands.length == 1) {
+    handleOutstanding()
+  }
+}
+
+function get_surface_id(ev) {
+  var id = ev.target.surface_id;
+  if (id != undefined)
+    return id;
+  return 0;
+}
+
+function send_input(cmd, args)
+{
+  if (input_socket != null) {
+      input_socket.send(cmd + args.join(","));
+  }
+}
+
+function on_mouse_move (ev) {
+  send_input ("m", [get_surface_id(ev), ev.pageX, ev.pageY, ev.timeStamp])
+}
+
+function on_mouse_down (ev) {
+  send_input ("b", [get_surface_id(ev), ev.pageX, ev.pageY, ev.button, ev.timeStamp])
+}
+
+function on_mouse_up (ev) {
+  send_input ("B", [get_surface_id(ev), ev.pageX, ev.pageY, ev.button, ev.timeStamp])
+}
+
+var last_key_down = 0;
+function on_key_down (ev) {
+  var key_code = ev.keyCode;
+  if (key_code != last_key_down) {
+    send_input ("k", [key_code, ev.timeStamp]);
+    last_key_down = key_code;
+  }
+}
+
+function on_key_up (ev) {
+  var key_code = ev.keyCode;
+  send_input ("K", [key_code, ev.timeStamp]);
+  last_key_down = 0;
+}
+
+function cancel_event(ev)
+{
+  ev = ev ? ev : window.event;
+  if (ev.stopPropagation)
+    ev.stopPropagation();
+  if (ev.preventDefault)
+    ev.preventDefault();
+  ev.cancelBubble = true;
+  ev.cancel = true;
+  ev.returnValue = false;
+  return false;
+}
+
+function on_mouse_wheel(ev)
+{
+  ev = ev ? ev : window.event;
+  var offset = ev.detail ? ev.detail : ev.wheelDelta;
+  var dir = 0
+  if (offset > 0)
+    dir = 1;
+  send_input ("s", [get_surface_id(ev), ev.pageX, ev.pageY, dir, ev.timeStamp])
+
+  return cancel_event(ev);
+}
+
+function connect()
+{
+  var xhr = createXHR();
+  if (xhr) {
+    if (typeof xhr.multipart == 'undefined') {
+      alert("Sorry, this example only works in browsers that support multipart.");
+      return;
+    }
+
+    xhr.multipart = true;
+    xhr.open("GET", "/output", true);
+    xhr.onload = handleLoad;
+    xhr.send(null);
+  }
+
+  if ("WebSocket" in window) {
+    var loc = window.location.toString().replace("http:", "ws:");
+    loc = loc.substr(0, loc.lastIndexOf('/')) + "/input";
+    var ws = new WebSocket(loc, "broadway");
+    ws.onopen = function() {
+      input_socket = ws;
+    };
+    ws.onclose = function() {
+      input_socket = null;
+    };
+  } else {
+     alert("WebSocket not supported, input will not work!");
+  }
+  document.oncontextmenu = function () { return false; }
+  document.onmousemove = on_mouse_move;
+  document.onmousedown = on_mouse_down;
+  document.onmouseup = on_mouse_up;
+  document.onkeydown = on_key_down;
+  document.onkeyup = on_key_up;
+
+  if (document.addEventListener) {
+    document.addEventListener('DOMMouseScroll', on_mouse_wheel, false);
+    document.addEventListener('mousewheel', on_mouse_wheel, false);
+  } else if (document.attachEvent) {
+    element.attachEvent("onmousewheel", on_mouse_wheel);
+  }
+
+}
diff --git a/gdk/broadway/client.html b/gdk/broadway/client.html
new file mode 100644 (file)
index 0000000..e74cdd9
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
+<title>broadway 2.0</title>
+<script type="text/javascript" src="broadway.js"></script>
+</head>
+
+<body onload="connect()">
+</body>
+</html>
diff --git a/gdk/broadway/gdkbroadwaycursor.h b/gdk/broadway/gdkbroadwaycursor.h
new file mode 100644 (file)
index 0000000..36afb5e
--- /dev/null
@@ -0,0 +1,56 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#if !defined (__GDKX_H_INSIDE__) && !defined (GDK_COMPILATION)
+#error "Only <gdk/gdkx.h> can be included directly."
+#endif
+
+#ifndef __GDK_BROADWAY_CURSOR_H__
+#define __GDK_BROADWAY_CURSOR_H__
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_BROADWAY_CURSOR              (gdk_broadway_cursor_get_type ())
+#define GDK_BROADWAY_CURSOR(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_CURSOR, GdkBroadwayCursor))
+#define GDK_BROADWAY_CURSOR_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_CURSOR, GdkBroadwayCursorClass))
+#define GDK_IS_BROADWAY_CURSOR(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_CURSOR))
+#define GDK_IS_BROADWAY_CURSOR_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_CURSOR))
+#define GDK_BROADWAY_CURSOR_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_CURSOR, GdkBroadwayCursorClass))
+
+#ifdef GDK_COMPILATION
+typedef struct _GdkBroadwayCursor GdkBroadwayCursor;
+#else
+typedef GdkCursor GdkBroadwayCursor;
+#endif
+typedef struct _GdkBroadwayCursorClass GdkBroadwayCursorClass;
+
+GType    gdk_broadway_cursor_get_type          (void);
+
+G_END_DECLS
+
+#endif /* __GDK_BROADWAY_CURSOR_H__ */
diff --git a/gdk/broadway/gdkbroadwaydisplaymanager.h b/gdk/broadway/gdkbroadwaydisplaymanager.h
new file mode 100644 (file)
index 0000000..df47ccd
--- /dev/null
@@ -0,0 +1,47 @@
+/* gdkbroadwaydisplaymanager.h
+ *
+ * Copyright (C) 2005-2007  Imendio AB
+ * Copyright 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined(__GDKBROADWAY_H_INSIDE__) && !defined (GDK_COMPILATION)
+#error "Only <gdk/gdkbroadway.h> can be included directly."
+#endif
+
+#ifndef __GDK_BROADWAY_DISPLAY_MANAGER_H__
+#define __GDK_BROADWAY_DISPLAY_MANAGER_H__
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_BROADWAY_DISPLAY_MANAGER    (gdk_broadway_display_manager_get_type ())
+#define GDK_BROADWAY_DISPLAY_MANAGER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_DISPLAY_MANAGER, GdkBroadwayDisplayManager))
+
+#ifdef GDK_COMPILATION
+typedef struct _GdkBroadwayDisplayManager GdkBroadwayDisplayManager;
+#else
+typedef GdkDisplayManager _GdkBroadwayDisplayManager;
+#endif
+typedef struct _GdkDisplayManagerClass GdkBroadwayDisplayManagerClass;
+
+GType gdk_broadway_display_manager_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GDK_BROADWAY_DISPLAY_MANAGER_H__ */
diff --git a/gdk/broadway/gdkbroadwayvisual.h b/gdk/broadway/gdkbroadwayvisual.h
new file mode 100644 (file)
index 0000000..4890b82
--- /dev/null
@@ -0,0 +1,47 @@
+/* gdkbroadwayvisual.h
+ *
+ * Copyright (C) 2011  Alexander Larsson  <alexl@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_BROADWAY_VISUAL_H__
+#define __GDK_BROADWAY_VISUAL_H__
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_BROADWAY_VISUAL              (gdk_broadway_visual_get_type ())
+#define GDK_BROADWAY_VISUAL(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_VISUAL, GdkBroadwayVisual))
+#define GDK_BROADWAY_VISUAL_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_VISUAL, GdkBroadwayVisualClass))
+#define GDK_IS_BROADWAY_VISUAL(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_VISUAL))
+#define GDK_IS_BROADWAY_VISUAL_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_VISUAL))
+#define GDK_BROADWAY_VISUAL_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_VISUAL, GdkBroadwayVisualClass))
+
+#ifdef GDK_COMPILATION
+typedef struct _GdkBroadwayVisual GdkBroadwayVisual;
+#else
+typedef GdkVisual GdkBroadwayVisual;
+#endif
+typedef struct _GdkBroadwayVisualClass GdkBroadwayVisualClass;
+
+
+GType gdk_broadway_visual_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GDK_BROADWAY_VISUAL_H__ */
diff --git a/gdk/broadway/gdkbroadwaywindow.h b/gdk/broadway/gdkbroadwaywindow.h
new file mode 100644 (file)
index 0000000..7bb7299
--- /dev/null
@@ -0,0 +1,52 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __GDK_BROADWAY_WINDOW_H__
+#define __GDK_BROADWAY_WINDOW_H__
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_BROADWAY_WINDOW              (gdk_broadway_window_get_type ())
+#define GDK_BROADWAY_WINDOW(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_WINDOW, GdkBroadwayWindow))
+#define GDK_BROADWAY_WINDOW_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_WINDOW, GdkBroadwayWindowClass))
+#define GDK_IS_BROADWAY_WINDOW(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_WINDOW))
+#define GDK_IS_BROADWAY_WINDOW_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_WINDOW))
+#define GDK_BROADWAY_WINDOW_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_WINDOW, GdkBroadwayWindowClass))
+
+#ifdef GDK_COMPILATION
+typedef struct _GdkBroadwayWindow GdkBroadwayWindow;
+#else
+typedef GdkWindow GdkBroadwayWindow;
+#endif
+typedef struct _GdkBroadwayWindowClass GdkBroadwayWindowClass;
+
+GType    gdk_broadway_window_get_type          (void);
+
+G_END_DECLS
+
+#endif /* __GDK_BROADWAY_WINDOW_H__ */
diff --git a/gdk/broadway/gdkcursor-broadway.c b/gdk/broadway/gdkcursor-broadway.c
new file mode 100644 (file)
index 0000000..3e947de
--- /dev/null
@@ -0,0 +1,185 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+/* needs to be first because any header might include gdk-pixbuf.h otherwise */
+#define GDK_PIXBUF_ENABLE_BACKEND
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "gdkcursor.h"
+#include "gdkcursorprivate.h"
+
+#include "gdkprivate-broadway.h"
+#include "gdkdisplay-broadway.h"
+
+#include <string.h>
+#include <errno.h>
+
+struct _GdkBroadwayCursor
+{
+  GdkCursor cursor;
+};
+
+struct _GdkBroadwayCursorClass
+{
+  GdkCursorClass cursor_class;
+};
+
+/*** GdkBroadwayCursor ***/
+
+G_DEFINE_TYPE (GdkBroadwayCursor, gdk_broadway_cursor, GDK_TYPE_CURSOR)
+
+static GdkPixbuf* gdk_broadway_cursor_get_image (GdkCursor *cursor);
+
+static void
+gdk_broadway_cursor_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (gdk_broadway_cursor_parent_class)->finalize (object);
+}
+
+static void
+gdk_broadway_cursor_class_init (GdkBroadwayCursorClass *xcursor_class)
+{
+  GdkCursorClass *cursor_class = GDK_CURSOR_CLASS (xcursor_class);
+  GObjectClass *object_class = G_OBJECT_CLASS (xcursor_class);
+
+  object_class->finalize = gdk_broadway_cursor_finalize;
+
+  cursor_class->get_image = gdk_broadway_cursor_get_image;
+}
+
+static void
+gdk_broadway_cursor_init (GdkBroadwayCursor *cursor)
+{
+}
+
+/* Called by gdk_display_broadway_finalize to flush any cached cursors
+ * for a dead display.
+ */
+void
+_gdk_broadway_cursor_display_finalize (GdkDisplay *display)
+{
+}
+
+GdkCursor*
+_gdk_broadway_display_get_cursor_for_type (GdkDisplay    *display,
+                                          GdkCursorType  cursor_type)
+{
+  GdkBroadwayCursor *private;
+
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+  private = g_object_new (GDK_TYPE_BROADWAY_CURSOR,
+                          "cursor-type", cursor_type,
+                          "display", display,
+                         NULL);
+
+  return GDK_CURSOR (private);
+}
+
+static GdkPixbuf*
+gdk_broadway_cursor_get_image (GdkCursor *cursor)
+{
+  g_return_val_if_fail (cursor != NULL, NULL);
+
+  return NULL;
+}
+
+void
+_gdk_broadway_cursor_update_theme (GdkCursor *cursor)
+{
+  g_return_if_fail (cursor != NULL);
+}
+
+GdkCursor *
+_gdk_broadway_display_get_cursor_for_pixbuf (GdkDisplay *display,
+                                            GdkPixbuf  *pixbuf,
+                                            gint        x,
+                                            gint        y)
+{
+  GdkBroadwayCursor *private;
+  GdkCursor *cursor;
+
+  private = g_object_new (GDK_TYPE_BROADWAY_CURSOR, 
+                          "cursor-type", GDK_CURSOR_IS_PIXMAP,
+                          "display", display,
+                          NULL);
+  cursor = (GdkCursor *) private;
+
+  return cursor;
+}
+
+GdkCursor*
+_gdk_broadway_display_get_cursor_for_name (GdkDisplay  *display,
+                                          const gchar *name)
+{
+  GdkBroadwayCursor *private;
+
+  private = g_object_new (GDK_TYPE_BROADWAY_CURSOR,
+                          "cursor-type", GDK_CURSOR_IS_PIXMAP,
+                          "display", display,
+                          NULL);
+
+  return GDK_CURSOR (private);
+}
+
+gboolean
+_gdk_broadway_display_supports_cursor_alpha (GdkDisplay *display)
+{
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+
+  return TRUE;
+}
+
+gboolean
+_gdk_broadway_display_supports_cursor_color (GdkDisplay *display)
+{
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+
+  return TRUE;
+}
+
+void
+_gdk_broadway_display_get_default_cursor_size (GdkDisplay *display,
+                                              guint      *width,
+                                              guint      *height)
+{
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+
+  *width = *height = 20;
+}
+
+void
+_gdk_broadway_display_get_maximal_cursor_size (GdkDisplay *display,
+                                              guint       *width,
+                                              guint       *height)
+{
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+
+  *width = 128;
+  *height = 128;
+}
diff --git a/gdk/broadway/gdkdevice-broadway.c b/gdk/broadway/gdkdevice-broadway.c
new file mode 100644 (file)
index 0000000..a3dcab0
--- /dev/null
@@ -0,0 +1,191 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdkdevice-broadway.h"
+
+#include "gdkwindow.h"
+#include "gdkprivate-broadway.h"
+
+static gboolean gdk_broadway_device_get_history (GdkDevice      *device,
+                                                GdkWindow      *window,
+                                                guint32         start,
+                                                guint32         stop,
+                                                GdkTimeCoord ***events,
+                                                gint           *n_events);
+static void gdk_broadway_device_get_state (GdkDevice       *device,
+                                          GdkWindow       *window,
+                                          gdouble         *axes,
+                                          GdkModifierType *mask);
+static void gdk_broadway_device_set_window_cursor (GdkDevice *device,
+                                                  GdkWindow *window,
+                                                  GdkCursor *cursor);
+static void gdk_broadway_device_warp (GdkDevice *device,
+                                     GdkScreen *screen,
+                                     gint       x,
+                                     gint       y);
+static gboolean gdk_broadway_device_query_state (GdkDevice        *device,
+                                                GdkWindow        *window,
+                                                GdkWindow       **root_window,
+                                                GdkWindow       **child_window,
+                                                gint             *root_x,
+                                                gint             *root_y,
+                                                gint             *win_x,
+                                                gint             *win_y,
+                                                GdkModifierType  *mask);
+static GdkGrabStatus gdk_broadway_device_grab   (GdkDevice     *device,
+                                                GdkWindow     *window,
+                                                gboolean       owner_events,
+                                                GdkEventMask   event_mask,
+                                                GdkWindow     *confine_to,
+                                                GdkCursor     *cursor,
+                                                guint32        time_);
+static void          gdk_broadway_device_ungrab (GdkDevice     *device,
+                                                guint32        time_);
+static GdkWindow * gdk_broadway_device_window_at_position (GdkDevice       *device,
+                                                          gint            *win_x,
+                                                          gint            *win_y,
+                                                          GdkModifierType *mask,
+                                                          gboolean         get_toplevel);
+static void      gdk_broadway_device_select_window_events (GdkDevice       *device,
+                                                          GdkWindow       *window,
+                                                          GdkEventMask     event_mask);
+
+
+G_DEFINE_TYPE (GdkBroadwayDevice, gdk_broadway_device, GDK_TYPE_DEVICE)
+
+static void
+gdk_broadway_device_class_init (GdkBroadwayDeviceClass *klass)
+{
+  GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
+
+  device_class->get_history = gdk_broadway_device_get_history;
+  device_class->get_state = gdk_broadway_device_get_state;
+  device_class->set_window_cursor = gdk_broadway_device_set_window_cursor;
+  device_class->warp = gdk_broadway_device_warp;
+  device_class->query_state = gdk_broadway_device_query_state;
+  device_class->grab = gdk_broadway_device_grab;
+  device_class->ungrab = gdk_broadway_device_ungrab;
+  device_class->window_at_position = gdk_broadway_device_window_at_position;
+  device_class->select_window_events = gdk_broadway_device_select_window_events;
+}
+
+static void
+gdk_broadway_device_init (GdkBroadwayDevice *device_core)
+{
+  GdkDevice *device;
+
+  device = GDK_DEVICE (device_core);
+
+  _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
+  _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
+}
+
+static gboolean
+gdk_broadway_device_get_history (GdkDevice      *device,
+                                GdkWindow      *window,
+                                guint32         start,
+                                guint32         stop,
+                                GdkTimeCoord ***events,
+                                gint           *n_events)
+{
+  return FALSE;
+}
+
+static void
+gdk_broadway_device_get_state (GdkDevice       *device,
+                              GdkWindow       *window,
+                              gdouble         *axes,
+                              GdkModifierType *mask)
+{
+  gint x_int, y_int;
+
+  gdk_window_get_pointer (window, &x_int, &y_int, mask);
+
+  if (axes)
+    {
+      axes[0] = x_int;
+      axes[1] = y_int;
+    }
+}
+
+static void
+gdk_broadway_device_set_window_cursor (GdkDevice *device,
+                                      GdkWindow *window,
+                                      GdkCursor *cursor)
+{
+}
+
+static void
+gdk_broadway_device_warp (GdkDevice *device,
+                         GdkScreen *screen,
+                         gint       x,
+                         gint       y)
+{
+}
+
+static gboolean
+gdk_broadway_device_query_state (GdkDevice        *device,
+                                GdkWindow        *window,
+                                GdkWindow       **root_window,
+                                GdkWindow       **child_window,
+                                gint             *root_x,
+                                gint             *root_y,
+                                gint             *win_x,
+                                gint             *win_y,
+                                GdkModifierType  *mask)
+{
+  return FALSE;
+}
+
+static GdkGrabStatus
+gdk_broadway_device_grab (GdkDevice    *device,
+                         GdkWindow    *window,
+                         gboolean      owner_events,
+                         GdkEventMask  event_mask,
+                         GdkWindow    *confine_to,
+                         GdkCursor    *cursor,
+                         guint32       time_)
+{
+  return GDK_GRAB_NOT_VIEWABLE;
+}
+
+static void
+gdk_broadway_device_ungrab (GdkDevice *device,
+                           guint32    time_)
+{
+}
+
+static GdkWindow *
+gdk_broadway_device_window_at_position (GdkDevice       *device,
+                                       gint            *win_x,
+                                       gint            *win_y,
+                                       GdkModifierType *mask,
+                                       gboolean         get_toplevel)
+{
+  return NULL;
+}
+
+static void
+gdk_broadway_device_select_window_events (GdkDevice    *device,
+                                         GdkWindow    *window,
+                                         GdkEventMask  event_mask)
+{
+}
diff --git a/gdk/broadway/gdkdevice-broadway.h b/gdk/broadway/gdkdevice-broadway.h
new file mode 100644 (file)
index 0000000..6ae48d3
--- /dev/null
@@ -0,0 +1,52 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_DEVICE_BROADWAY_H__
+#define __GDK_DEVICE_BROADWAY_H__
+
+#include <gdk/gdkdeviceprivate.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_BROADWAY_DEVICE         (gdk_broadway_device_get_type ())
+#define GDK_BROADWAY_DEVICE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_BROADWAY_DEVICE, GdkBroadwayDevice))
+#define GDK_BROADWAY_DEVICE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_BROADWAY_DEVICE, GdkBroadwayDeviceClass))
+#define GDK_IS_BROADWAY_DEVICE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_BROADWAY_DEVICE))
+#define GDK_IS_BROADWAY_DEVICE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_BROADWAY_DEVICE))
+#define GDK_BROADWAY_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_BROADWAY_DEVICE, GdkBroadwayDeviceClass))
+
+typedef struct _GdkBroadwayDevice GdkBroadwayDevice;
+typedef struct _GdkBroadwayDeviceClass GdkBroadwayDeviceClass;
+
+struct _GdkBroadwayDevice
+{
+  GdkDevice parent_instance;
+};
+
+struct _GdkBroadwayDeviceClass
+{
+  GdkDeviceClass parent_class;
+};
+
+G_GNUC_INTERNAL
+GType gdk_broadway_device_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GDK_DEVICE_BROADWAY_H__ */
diff --git a/gdk/broadway/gdkdevicemanager-broadway.c b/gdk/broadway/gdkdevicemanager-broadway.c
new file mode 100644 (file)
index 0000000..27f37a4
--- /dev/null
@@ -0,0 +1,148 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdkdevicemanager-broadway.h"
+
+#include "gdktypes.h"
+#include "gdkdevicemanager.h"
+#include "gdkdevice-broadway.h"
+#include "gdkkeysyms.h"
+#include "gdkprivate-broadway.h"
+
+#define HAS_FOCUS(toplevel)                           \
+  ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
+
+static void    gdk_broadway_device_manager_finalize    (GObject *object);
+static void    gdk_broadway_device_manager_constructed (GObject *object);
+
+static GList * gdk_broadway_device_manager_list_devices (GdkDeviceManager *device_manager,
+                                                        GdkDeviceType     type);
+static GdkDevice * gdk_broadway_device_manager_get_client_pointer (GdkDeviceManager *device_manager);
+
+G_DEFINE_TYPE (GdkBroadwayDeviceManager, gdk_broadway_device_manager, GDK_TYPE_DEVICE_MANAGER)
+
+static void
+gdk_broadway_device_manager_class_init (GdkBroadwayDeviceManagerClass *klass)
+{
+  GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gdk_broadway_device_manager_finalize;
+  object_class->constructed = gdk_broadway_device_manager_constructed;
+  device_manager_class->list_devices = gdk_broadway_device_manager_list_devices;
+  device_manager_class->get_client_pointer = gdk_broadway_device_manager_get_client_pointer;
+}
+
+static GdkDevice *
+create_core_pointer (GdkDeviceManager *device_manager,
+                     GdkDisplay       *display)
+{
+  return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
+                       "name", "Core Pointer",
+                       "type", GDK_DEVICE_TYPE_MASTER,
+                       "input-source", GDK_SOURCE_MOUSE,
+                       "input-mode", GDK_MODE_SCREEN,
+                       "has-cursor", TRUE,
+                       "display", display,
+                       "device-manager", device_manager,
+                       NULL);
+}
+
+static GdkDevice *
+create_core_keyboard (GdkDeviceManager *device_manager,
+                      GdkDisplay       *display)
+{
+  return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
+                       "name", "Core Keyboard",
+                       "type", GDK_DEVICE_TYPE_MASTER,
+                       "input-source", GDK_SOURCE_KEYBOARD,
+                       "input-mode", GDK_MODE_SCREEN,
+                       "has-cursor", FALSE,
+                       "display", display,
+                       "device-manager", device_manager,
+                       NULL);
+}
+
+static void
+gdk_broadway_device_manager_init (GdkBroadwayDeviceManager *device_manager)
+{
+}
+
+static void
+gdk_broadway_device_manager_finalize (GObject *object)
+{
+  GdkBroadwayDeviceManager *device_manager;
+
+  device_manager = GDK_BROADWAY_DEVICE_MANAGER (object);
+
+  g_object_unref (device_manager->core_pointer);
+  g_object_unref (device_manager->core_keyboard);
+
+  G_OBJECT_CLASS (gdk_broadway_device_manager_parent_class)->finalize (object);
+}
+
+static void
+gdk_broadway_device_manager_constructed (GObject *object)
+{
+  GdkBroadwayDeviceManager *device_manager;
+  GdkDisplay *display;
+
+  device_manager = GDK_BROADWAY_DEVICE_MANAGER (object);
+  display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
+  device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
+  device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);
+
+  _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
+  _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
+}
+
+
+static GList *
+gdk_broadway_device_manager_list_devices (GdkDeviceManager *device_manager,
+                                         GdkDeviceType     type)
+{
+  GdkBroadwayDeviceManager *broadway_device_manager = (GdkBroadwayDeviceManager *) device_manager;
+  GList *devices = NULL;
+
+  if (type == GDK_DEVICE_TYPE_MASTER)
+    {
+      devices = g_list_prepend (devices, broadway_device_manager->core_keyboard);
+      devices = g_list_prepend (devices, broadway_device_manager->core_pointer);
+    }
+
+  return devices;
+}
+
+static GdkDevice *
+gdk_broadway_device_manager_get_client_pointer (GdkDeviceManager *device_manager)
+{
+  GdkBroadwayDeviceManager *broadway_device_manager = (GdkBroadwayDeviceManager *) device_manager;
+
+  return broadway_device_manager->core_pointer;
+}
+
+GdkDeviceManager *
+_gdk_broadway_device_manager_new (GdkDisplay *display)
+{
+  return g_object_new (GDK_TYPE_BROADWAY_DEVICE_MANAGER,
+                      "display", display,
+                      NULL);
+}
diff --git a/gdk/broadway/gdkdevicemanager-broadway.h b/gdk/broadway/gdkdevicemanager-broadway.h
new file mode 100644 (file)
index 0000000..be584e3
--- /dev/null
@@ -0,0 +1,54 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_DEVICE_MANAGER_BROADWAY_H__
+#define __GDK_DEVICE_MANAGER_BROADWAY_H__
+
+#include <gdk/gdkdevicemanagerprivate.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_BROADWAY_DEVICE_MANAGER         (gdk_broadway_device_manager_get_type ())
+#define GDK_BROADWAY_DEVICE_MANAGER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_BROADWAY_DEVICE_MANAGER, GdkBroadwayDeviceManager))
+#define GDK_BROADWAY_DEVICE_MANAGER_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_BROADWAY_DEVICE_MANAGER, GdkBroadwayDeviceManagerClass))
+#define GDK_IS_BROADWAY_DEVICE_MANAGER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_BROADWAY_DEVICE_MANAGER))
+#define GDK_IS_BROADWAY_DEVICE_MANAGER_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_BROADWAY_DEVICE_MANAGER))
+#define GDK_BROADWAY_DEVICE_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_BROADWAY_DEVICE_MANAGER, GdkBroadwayDeviceManagerClass))
+
+typedef struct _GdkBroadwayDeviceManager GdkBroadwayDeviceManager;
+typedef struct _GdkBroadwayDeviceManagerClass GdkBroadwayDeviceManagerClass;
+
+struct _GdkBroadwayDeviceManager
+{
+  GdkDeviceManager parent_object;
+  GdkDevice *core_pointer;
+  GdkDevice *core_keyboard;
+};
+
+struct _GdkBroadwayDeviceManagerClass
+{
+  GdkDeviceManagerClass parent_class;
+};
+
+GType gdk_broadway_device_manager_get_type (void) G_GNUC_CONST;
+GdkDeviceManager *_gdk_broadway_device_manager_new (GdkDisplay *display);
+
+G_END_DECLS
+
+#endif /* __GDK_DEVICE_MANAGER_BROADWAY_H__ */
diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c
new file mode 100644 (file)
index 0000000..c71118e
--- /dev/null
@@ -0,0 +1,807 @@
+/* GDK - The GIMP Drawing Kit
+ * gdkdisplay-broadway.c
+ * 
+ * Copyright 2001 Sun Microsystems Inc.
+ * Copyright (C) 2004 Nokia Corporation
+ *
+ * Erwann Chenede <erwann.chenede@sun.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdkdisplay-broadway.h"
+
+#include "gdkdisplay.h"
+#include "gdkeventsource.h"
+#include "gdkscreen.h"
+#include "gdkscreen-broadway.h"
+#include "gdkinternals.h"
+#include "gdkdeviceprivate.h"
+#include "gdkdevicemanager-broadway.h"
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+static void   gdk_broadway_display_dispose            (GObject            *object);
+static void   gdk_broadway_display_finalize           (GObject            *object);
+
+G_DEFINE_TYPE (GdkBroadwayDisplay, gdk_broadway_display, GDK_TYPE_DISPLAY)
+
+static void
+gdk_broadway_display_init (GdkBroadwayDisplay *display)
+{
+  _gdk_broadway_display_manager_add_display (gdk_display_manager_get (),
+                                            GDK_DISPLAY_OBJECT (display));
+  display->id_ht = g_hash_table_new (NULL, NULL);
+}
+
+static void
+gdk_event_init (GdkDisplay *display)
+{
+  GdkBroadwayDisplay *broadway_display;
+
+  broadway_display = GDK_BROADWAY_DISPLAY (display);
+  broadway_display->event_source = _gdk_broadway_event_source_new (display);
+}
+
+static void
+gdk_broadway_display_init_input (GdkDisplay *display)
+{
+  GdkBroadwayDisplay *broadway_display;
+  GdkDeviceManager *device_manager;
+  GdkDevice *device;
+  GList *list, *l;
+
+  broadway_display = GDK_BROADWAY_DISPLAY (display);
+  device_manager = gdk_display_get_device_manager (display);
+
+  /* For backwards compatibility, just add
+   * floating devices that are not keyboards.
+   */
+  list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING);
+
+  for (l = list; l; l = l->next)
+    {
+      device = l->data;
+
+      if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+        continue;
+
+      broadway_display->input_devices = g_list_prepend (broadway_display->input_devices,
+                                                   g_object_ref (l->data));
+    }
+
+  g_list_free (list);
+
+  /* Now set "core" pointer to the first
+   * master device that is a pointer.
+   */
+  list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+  for (l = list; l; l = l->next)
+    {
+      device = list->data;
+
+      if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
+        continue;
+
+      display->core_pointer = device;
+      break;
+    }
+
+  /* Add the core pointer to the devices list */
+  broadway_display->input_devices = g_list_prepend (broadway_display->input_devices,
+                                               g_object_ref (display->core_pointer));
+
+  g_list_free (list);
+}
+
+struct HttpRequest {
+  GdkDisplay *display;
+  GSocketConnection *connection;
+  GDataInputStream *data;
+  GString *request;
+};
+
+static void
+http_request_free (HttpRequest *request)
+{
+  g_object_unref (request->connection);
+  g_object_unref (request->data);
+  g_string_free (request->request, TRUE);
+  g_free (request);
+}
+
+#include <unistd.h>
+#include <fcntl.h>
+static void
+set_fd_blocking (int fd)
+{
+  glong arg;
+
+  if ((arg = fcntl (fd, F_GETFL, NULL)) < 0)
+    arg = 0;
+
+  arg = arg & ~O_NONBLOCK;
+
+  fcntl (fd, F_SETFL, arg);
+}
+
+static char *
+parse_line (char *line, char *key)
+{
+  char *p;
+
+  if (!g_str_has_prefix (line, key))
+    return NULL;
+  p = line + strlen (key);
+  if (*p != ':')
+    return NULL;
+  p++;
+  /* Skip optional initial space */
+  if (*p == ' ')
+    p++;
+  return p;
+}
+
+static void
+got_input (GInputStream *stream,
+          GAsyncResult *result,
+          HttpRequest *request)
+{
+  GError *error;
+  char *message;
+  gsize len;
+
+  error = NULL;
+  message = g_data_input_stream_read_upto_finish (G_DATA_INPUT_STREAM (stream), result, &len, &error);
+  if (message == NULL)
+    {
+      GDK_BROADWAY_DISPLAY (request->display)->input = NULL;
+      http_request_free (request);
+      return;
+    }
+
+  g_assert (message[0] == 0);
+  _gdk_broadway_events_got_input (request->display, message + 1);
+
+  /* Skip past ending 0xff */
+  g_data_input_stream_read_byte (request->data, NULL, NULL);
+  g_data_input_stream_read_upto_async (request->data, "\xff", 1, 0, NULL,
+                                      (GAsyncReadyCallback)got_input, request);
+}
+
+static void
+send_error (HttpRequest *request,
+           int error_code,
+           const char *reason)
+{
+  char *res;
+
+  res = g_strdup_printf ("HTTP/1.0 %d %s\r\n\r\n"
+                        "<html><head><title>%d %s</title></head>"
+                        "<body>%s</body></html>",
+                        error_code, reason,
+                        error_code, reason,
+                        reason);
+  /* TODO: This should really be async */
+  g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+                            res, strlen (res), NULL, NULL, NULL);
+  g_free (res);
+  http_request_free (request);
+}
+
+static void
+start_input (HttpRequest *request)
+{
+  char **lines;
+  char *p;
+  int num_key1, num_key2;
+  guint64 key1, key2;
+  int num_space;
+  int i;
+  guint8 challenge[16];
+  char *res;
+  gsize len;
+  GChecksum *checksum;
+  char *origin, *host;
+  GdkBroadwayDisplay *broadway_display;
+
+  broadway_display = GDK_BROADWAY_DISPLAY (request->display);
+
+  if (broadway_display->input != NULL)
+    {
+      send_error (request, 409, "Input already handled");
+      return;
+    }
+
+  lines = g_strsplit (request->request->str, "\n", 0);
+
+  num_key1 = 0;
+  num_key2 = 0;
+  key1 = 0;
+  key2 = 0;
+  origin = NULL;
+  host = NULL;
+  for (i = 0; lines[i] != NULL; i++)
+    {
+      if ((p = parse_line (lines[i], "Sec-WebSocket-Key1")))
+       {
+         num_space = 0;
+         while (*p != 0)
+           {
+             if (g_ascii_isdigit (*p))
+               key1 = key1 * 10 + g_ascii_digit_value (*p);
+             else if (*p == ' ')
+               num_space++;
+
+             p++;
+           }
+         key1 /= num_space;
+         num_key1++;
+       }
+      else if ((p = parse_line (lines[i], "Sec-WebSocket-Key2")))
+       {
+         num_space = 0;
+         while (*p != 0)
+           {
+             if (g_ascii_isdigit (*p))
+               key2 = key2 * 10 + g_ascii_digit_value (*p);
+             else if (*p == ' ')
+               num_space++;
+
+             p++;
+           }
+         key2 /= num_space;
+         num_key2++;
+       }
+      else if ((p = parse_line (lines[i], "Origin")))
+       {
+         origin = p;
+       }
+      else if ((p = parse_line (lines[i], "Host")))
+       {
+         host = p;
+       }
+    }
+
+  if (num_key1 != 1 || num_key2 != 1 || origin == NULL || host == NULL)
+    {
+      g_strfreev (lines);
+      send_error (request, 400, "Bad websocket request");
+      return;
+    }
+
+  challenge[0] = (key1 >> 24) & 0xff;
+  challenge[1] = (key1 >> 16) & 0xff;
+  challenge[2] = (key1 >>  8) & 0xff;
+  challenge[3] = (key1 >>  0) & 0xff;
+  challenge[4] = (key2 >> 24) & 0xff;
+  challenge[5] = (key2 >> 16) & 0xff;
+  challenge[6] = (key2 >>  8) & 0xff;
+  challenge[7] = (key2 >>  0) & 0xff;
+
+  if (!g_input_stream_read_all (G_INPUT_STREAM (request->data), challenge+8, 8, NULL, NULL, NULL))
+    {
+      g_strfreev (lines);
+      send_error (request, 400, "Bad websocket request");
+      return;
+    }
+
+  checksum = g_checksum_new (G_CHECKSUM_MD5);
+  g_checksum_update (checksum, challenge, 16);
+  len = 16;
+  g_checksum_get_digest (checksum, challenge, &len);
+  g_checksum_free (checksum);
+
+  res = g_strdup_printf ("HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
+                        "Upgrade: WebSocket\r\n"
+                        "Connection: Upgrade\r\n"
+                        "Sec-WebSocket-Origin: %s\r\n"
+                        "Sec-WebSocket-Location: ws://%s/input\r\n"
+                        "Sec-WebSocket-Protocol: broadway\r\n"
+                        "\r\n",
+                        origin, host);
+
+  /* TODO: This should really be async */
+  g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+                            res, strlen (res), NULL, NULL, NULL);
+  g_free (res);
+  g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+                            challenge, 16, NULL, NULL, NULL);
+
+  broadway_display->input = request;
+
+  g_data_input_stream_read_upto_async (request->data, "\xff", 1, 0, NULL,
+                                      (GAsyncReadyCallback)got_input, request);
+
+  g_strfreev (lines);
+}
+
+static void
+start_output (HttpRequest *request)
+{
+  GSocket *socket;
+  GdkBroadwayDisplay *broadway_display;
+  int fd;
+
+  socket = g_socket_connection_get_socket (request->connection);
+
+  broadway_display = GDK_BROADWAY_DISPLAY (request->display);
+  fd = g_socket_get_fd (socket);
+  set_fd_blocking (fd);
+  /* We dup this because otherwise it'll be closed with the request SocketConnection */
+  broadway_display->output = broadway_output_new (dup(fd));
+  _gdk_broadway_resync_windows ();
+  http_request_free (request);
+}
+
+static void
+send_data (HttpRequest *request,
+            const char *mimetype,
+            const char *data, gsize len)
+{
+  char *res;
+
+  res = g_strdup_printf ("HTTP/1.0 200 OK\r\n"
+                        "Content-Type: %s\r\n"
+                        "Content-Length: %"G_GSIZE_FORMAT"\r\n"
+                        "\r\n",
+                        mimetype, len);
+  /* TODO: This should really be async */
+  g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+                            res, strlen (res), NULL, NULL, NULL);
+  g_free (res);
+  g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+                            data, len, NULL, NULL, NULL);
+  http_request_free (request);
+}
+
+#include "clienthtml.h"
+#include "broadwayjs.h"
+
+static void
+got_request (HttpRequest *request)
+{
+  char *start, *escaped, *tmp, *version;
+
+  if (!g_str_has_prefix (request->request->str, "GET "))
+    {
+      send_error (request, 501, "Only GET implemented");
+      return;
+    }
+
+  start = request->request->str + 4; /* Skip "GET " */
+
+  while (*start == ' ')
+    start++;
+
+  for (tmp = start; *tmp != 0 && *tmp != ' ' && *tmp != '\n'; tmp++)
+    ;
+  escaped = g_strndup (start, tmp - start);
+  version = NULL;
+  if (*tmp == ' ')
+    {
+      start = tmp;
+      while (*start == ' ')
+       start++;
+      for (tmp = start; *tmp != 0 && *tmp != ' ' && *tmp != '\n'; tmp++)
+       ;
+      version = g_strndup (start, tmp - start);
+    }
+
+  if (strcmp (escaped, "/client.html") == 0 || strcmp (escaped, "/") == 0)
+    send_data (request, "text/html", client_html, G_N_ELEMENTS(client_html) - 1);
+  else if (strcmp (escaped, "/broadway.js") == 0)
+    send_data (request, "text/javascript", broadway_js, G_N_ELEMENTS(broadway_js) - 1);
+  else if (strcmp (escaped, "/output") == 0)
+    start_output (request);
+  else if (strcmp (escaped, "/input") == 0)
+    start_input (request);
+  else
+    send_error (request, 404, "File not found");
+}
+
+static void
+got_http_request_line (GInputStream *stream,
+                      GAsyncResult *result,
+                      HttpRequest *request)
+{
+  char *line;
+
+  line = g_data_input_stream_read_line_finish (G_DATA_INPUT_STREAM (stream), result, NULL, NULL);
+  if (line == NULL)
+    {
+      http_request_free (request);
+      g_printerr ("Error reading request lines\n");
+      return;
+    }
+  if (strlen (line) == 0)
+    got_request (request);
+  else
+    {
+      /* Protect against overflow in request length */
+      if (request->request->len > 1024 * 5)
+       {
+         send_error (request, 400, "Request to long");
+       }
+      else
+       {
+         g_string_append_printf (request->request, "%s\n", line);
+         g_data_input_stream_read_line_async (request->data, 0, NULL,
+                                              (GAsyncReadyCallback)got_http_request_line, request);
+       }
+    }
+  g_free (line);
+}
+
+static gboolean
+handle_incoming_connection (GSocketService    *service,
+                           GSocketConnection *connection,
+                           GObject           *source_object)
+{
+  HttpRequest *request;
+  GInputStream *in;
+
+  request = g_new0 (HttpRequest, 1);
+  request->connection = g_object_ref (connection);
+  request->display = (GdkDisplay *) source_object;
+  request->request = g_string_new ("");
+
+  in = g_io_stream_get_input_stream (G_IO_STREAM (connection));
+
+  request->data = g_data_input_stream_new (in);
+  g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (request->data), FALSE);
+  /* Be tolerant of input */
+  g_data_input_stream_set_newline_type (request->data, G_DATA_STREAM_NEWLINE_TYPE_ANY);
+
+  g_data_input_stream_read_line_async (request->data, 0, NULL,
+                                      (GAsyncReadyCallback)got_http_request_line, request);
+  return TRUE;
+}
+
+GdkDisplay *
+_gdk_broadway_display_open (const gchar *display_name)
+{
+  GdkDisplay *display;
+  GdkBroadwayDisplay *broadway_display;
+  GError *error;
+
+  display = g_object_new (GDK_TYPE_BROADWAY_DISPLAY, NULL);
+  broadway_display = GDK_BROADWAY_DISPLAY (display);
+
+  broadway_display->output = NULL;
+
+  /* initialize the display's screens */
+  broadway_display->screens = g_new (GdkScreen *, 1);
+  broadway_display->screens[0] = _gdk_broadway_screen_new (display, 0);
+
+  /* We need to initialize events after we have the screen
+   * structures in places
+   */
+  _gdk_broadway_screen_events_init (broadway_display->screens[0]);
+
+  /*set the default screen */
+  broadway_display->default_screen = broadway_display->screens[0];
+
+  display->device_manager = _gdk_broadway_device_manager_new (display);
+
+  gdk_event_init (display);
+
+  gdk_broadway_display_init_input (display);
+  _gdk_broadway_display_init_dnd (display);
+
+  _gdk_broadway_screen_setup (broadway_display->screens[0]);
+
+  broadway_display->service = g_socket_service_new ();
+  if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (broadway_display->service),
+                                       8080,
+                                       G_OBJECT (display),
+                                       &error))
+    {
+      g_printerr ("Unable to listen to port %d: %s\n", 8080, error->message);
+      g_error_free (error);
+      return NULL;
+    }
+  g_signal_connect (broadway_display->service, "incoming", G_CALLBACK (handle_incoming_connection), NULL);
+
+  g_signal_emit_by_name (display, "opened");
+  g_signal_emit_by_name (gdk_display_manager_get (), "display-opened", display);
+
+  return display;
+}
+
+
+static G_CONST_RETURN gchar *
+gdk_broadway_display_get_name (GdkDisplay *display)
+{
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+  return (gchar *) "Broadway";
+}
+
+static gint
+gdk_broadway_display_get_n_screens (GdkDisplay *display)
+{
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
+
+  return 1;
+}
+
+static GdkScreen *
+gdk_broadway_display_get_screen (GdkDisplay *display,
+                                gint        screen_num)
+{
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+  g_return_val_if_fail (screen_num == 0, NULL);
+
+  return GDK_BROADWAY_DISPLAY (display)->screens[screen_num];
+}
+
+static GdkScreen *
+gdk_broadway_display_get_default_screen (GdkDisplay *display)
+{
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+  return GDK_BROADWAY_DISPLAY (display)->default_screen;
+}
+
+static void
+gdk_broadway_display_beep (GdkDisplay *display)
+{
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+}
+
+static void
+gdk_broadway_display_sync (GdkDisplay *display)
+{
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+
+}
+
+static void
+gdk_broadway_display_flush (GdkDisplay *display)
+{
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+
+}
+
+static gboolean
+gdk_broadway_display_has_pending (GdkDisplay *display)
+{
+  return FALSE;
+}
+
+static GdkWindow *
+gdk_broadway_display_get_default_group (GdkDisplay *display)
+{
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+  return NULL;
+}
+
+static void
+gdk_broadway_display_dispose (GObject *object)
+{
+  GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (object);
+
+  _gdk_broadway_display_manager_remove_display (gdk_display_manager_get (),
+                                               GDK_DISPLAY_OBJECT (object));
+
+  g_list_foreach (broadway_display->input_devices, (GFunc) g_object_run_dispose, NULL);
+
+  _gdk_screen_close (broadway_display->screens[0]);
+
+  if (broadway_display->event_source)
+    {
+      g_source_destroy (broadway_display->event_source);
+      g_source_unref (broadway_display->event_source);
+      broadway_display->event_source = NULL;
+    }
+
+  G_OBJECT_CLASS (gdk_broadway_display_parent_class)->dispose (object);
+}
+
+static void
+gdk_broadway_display_finalize (GObject *object)
+{
+  GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (object);
+
+  /* Keymap */
+  if (broadway_display->keymap)
+    g_object_unref (broadway_display->keymap);
+
+  _gdk_broadway_cursor_display_finalize (GDK_DISPLAY_OBJECT(broadway_display));
+
+  /* Atom Hashtable */
+  g_hash_table_destroy (broadway_display->atom_from_virtual);
+  g_hash_table_destroy (broadway_display->atom_to_virtual);
+
+  /* input GdkDevice list */
+  g_list_foreach (broadway_display->input_devices, (GFunc) g_object_unref, NULL);
+  g_list_free (broadway_display->input_devices);
+  /* Free all GdkScreens */
+  g_object_unref (broadway_display->screens[0]);
+  g_free (broadway_display->screens);
+
+  G_OBJECT_CLASS (gdk_broadway_display_parent_class)->finalize (object);
+}
+
+void
+_gdk_broadway_display_make_default (GdkDisplay *display)
+{
+}
+
+static void
+gdk_broadway_display_notify_startup_complete (GdkDisplay  *display,
+                                             const gchar *startup_id)
+{
+}
+
+static gboolean
+gdk_broadway_display_supports_selection_notification (GdkDisplay *display)
+{
+  return FALSE;
+}
+
+static gboolean
+gdk_broadway_display_request_selection_notification (GdkDisplay *display,
+                                                    GdkAtom     selection)
+
+{
+    return FALSE;
+}
+
+static gboolean
+gdk_broadway_display_supports_clipboard_persistence (GdkDisplay *display)
+{
+  return FALSE;
+}
+
+static void
+gdk_broadway_display_store_clipboard (GdkDisplay    *display,
+                                     GdkWindow     *clipboard_window,
+                                     guint32        time_,
+                                     const GdkAtom *targets,
+                                     gint           n_targets)
+{
+}
+
+static gboolean
+gdk_broadway_display_supports_shapes (GdkDisplay *display)
+{
+  return FALSE;
+}
+
+static gboolean
+gdk_broadway_display_supports_input_shapes (GdkDisplay *display)
+{
+  return FALSE;
+}
+
+static gboolean
+gdk_broadway_display_supports_composite (GdkDisplay *display)
+{
+  return FALSE;
+}
+
+static GList *
+gdk_broadway_display_list_devices (GdkDisplay *display)
+{
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+  return GDK_BROADWAY_DISPLAY (display)->input_devices;
+}
+
+static gboolean
+gdk_broadway_display_send_client_message (GdkDisplay     *display,
+                                         GdkEvent       *event,
+                                         GdkNativeWindow winid)
+{
+  return FALSE;
+}
+
+static void
+gdk_broadway_display_add_client_message_filter (GdkDisplay   *display,
+                                               GdkAtom       message_type,
+                                               GdkFilterFunc func,
+                                               gpointer      data)
+{
+}
+
+static gulong
+gdk_broadway_display_get_next_serial (GdkDisplay *display)
+{
+  return 0;
+}
+
+
+static void
+gdk_broadway_display_event_data_copy (GdkDisplay    *display,
+                                     const GdkEvent *src,
+                                     GdkEvent       *dst)
+{
+}
+
+static void
+gdk_broadway_display_event_data_free (GdkDisplay    *display,
+                                     GdkEvent *event)
+{
+}
+
+static void
+gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  GdkDisplayClass *display_class = GDK_DISPLAY_CLASS (class);
+
+  object_class->dispose = gdk_broadway_display_dispose;
+  object_class->finalize = gdk_broadway_display_finalize;
+
+  display_class->window_type = GDK_TYPE_BROADWAY_WINDOW;
+
+  display_class->get_name = gdk_broadway_display_get_name;
+  display_class->get_n_screens = gdk_broadway_display_get_n_screens;
+  display_class->get_screen = gdk_broadway_display_get_screen;
+  display_class->get_default_screen = gdk_broadway_display_get_default_screen;
+  display_class->beep = gdk_broadway_display_beep;
+  display_class->sync = gdk_broadway_display_sync;
+  display_class->flush = gdk_broadway_display_flush;
+  display_class->has_pending = gdk_broadway_display_has_pending;
+  display_class->queue_events = _gdk_broadway_display_queue_events;
+  display_class->get_default_group = gdk_broadway_display_get_default_group;
+  display_class->supports_selection_notification = gdk_broadway_display_supports_selection_notification;
+  display_class->request_selection_notification = gdk_broadway_display_request_selection_notification;
+  display_class->supports_clipboard_persistence = gdk_broadway_display_supports_clipboard_persistence;
+  display_class->store_clipboard = gdk_broadway_display_store_clipboard;
+  display_class->supports_shapes = gdk_broadway_display_supports_shapes;
+  display_class->supports_input_shapes = gdk_broadway_display_supports_input_shapes;
+  display_class->supports_composite = gdk_broadway_display_supports_composite;
+  display_class->list_devices = gdk_broadway_display_list_devices;
+  display_class->send_client_message = gdk_broadway_display_send_client_message;
+  display_class->add_client_message_filter = gdk_broadway_display_add_client_message_filter;
+  display_class->get_drag_protocol = _gdk_broadway_display_get_drag_protocol;
+  display_class->get_cursor_for_type = _gdk_broadway_display_get_cursor_for_type;
+  display_class->get_cursor_for_name = _gdk_broadway_display_get_cursor_for_name;
+  display_class->get_cursor_for_pixbuf = _gdk_broadway_display_get_cursor_for_pixbuf;
+  display_class->get_default_cursor_size = _gdk_broadway_display_get_default_cursor_size;
+  display_class->get_maximal_cursor_size = _gdk_broadway_display_get_maximal_cursor_size;
+  display_class->supports_cursor_alpha = _gdk_broadway_display_supports_cursor_alpha;
+  display_class->supports_cursor_color = _gdk_broadway_display_supports_cursor_color;
+
+  display_class->before_process_all_updates = _gdk_broadway_display_before_process_all_updates;
+  display_class->after_process_all_updates = _gdk_broadway_display_after_process_all_updates;
+  display_class->get_next_serial = gdk_broadway_display_get_next_serial;
+  display_class->notify_startup_complete = gdk_broadway_display_notify_startup_complete;
+  display_class->event_data_copy = gdk_broadway_display_event_data_copy;
+  display_class->event_data_free = gdk_broadway_display_event_data_free;
+  display_class->create_window_impl = _gdk_broadway_display_create_window_impl;
+  display_class->get_keymap = _gdk_broadway_display_get_keymap;
+  display_class->get_selection_owner = _gdk_broadway_display_get_selection_owner;
+  display_class->set_selection_owner = _gdk_broadway_display_set_selection_owner;
+  display_class->send_selection_notify = _gdk_broadway_display_send_selection_notify;
+  display_class->get_selection_property = _gdk_broadway_display_get_selection_property;
+  display_class->convert_selection = _gdk_broadway_display_convert_selection;
+  display_class->text_property_to_utf8_list = _gdk_broadway_display_text_property_to_utf8_list;
+  display_class->utf8_to_string_target = _gdk_broadway_display_utf8_to_string_target;
+}
+
diff --git a/gdk/broadway/gdkdisplay-broadway.h b/gdk/broadway/gdkdisplay-broadway.h
new file mode 100644 (file)
index 0000000..c335fee
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * gdkdisplay-broadway.h
+ * 
+ * Copyright 2001 Sun Microsystems Inc. 
+ *
+ * Erwann Chenede <erwann.chenede@sun.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_BROADWAY_DISPLAY__
+#define __GDK_BROADWAY_DISPLAY__
+
+#include "gdkdisplayprivate.h"
+#include "gdkkeys.h"
+#include "gdkwindow.h"
+#include "gdkinternals.h"
+#include "gdkmain.h"
+#include "broadway.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GdkBroadwayDisplay GdkBroadwayDisplay;
+typedef struct _GdkBroadwayDisplayClass GdkBroadwayDisplayClass;
+
+typedef  struct HttpRequest HttpRequest;
+
+#define GDK_TYPE_BROADWAY_DISPLAY              (gdk_broadway_display_get_type())
+#define GDK_BROADWAY_DISPLAY(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_DISPLAY, GdkBroadwayDisplay))
+#define GDK_BROADWAY_DISPLAY_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_DISPLAY, GdkBroadwayDisplayClass))
+#define GDK_IS_BROADWAY_DISPLAY(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_DISPLAY))
+#define GDK_IS_BROADWAY_DISPLAY_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_DISPLAY))
+#define GDK_BROADWAY_DISPLAY_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_DISPLAY, GdkBroadwayDisplayClass))
+
+struct _GdkBroadwayDisplay
+{
+  GdkDisplay parent_instance;
+  GdkScreen *default_screen;
+  GdkScreen **screens;
+
+  GHashTable *id_ht;
+  GList *toplevels;
+
+  GSource *event_source;
+  GdkWindow *mouse_in_toplevel;
+  int last_x, last_y;
+
+  /* Keyboard related information */
+  GdkKeymap *keymap;
+
+  /* drag and drop information */
+  GdkDragContext *current_dest_drag;
+
+  /* Mapping to/from virtual atoms */
+
+  GHashTable *atom_from_virtual;
+  GHashTable *atom_to_virtual;
+
+  /* Input device */
+  /* input GdkDevice list */
+  GList *input_devices;
+
+  /* Time of most recent user interaction. */
+  gulong user_time;
+
+  /* The offscreen window that has the pointer in it (if any) */
+  GdkWindow *active_offscreen_window;
+
+  GSocketService *service;
+  BroadwayOutput *output;
+  HttpRequest *input;
+};
+
+struct _GdkBroadwayDisplayClass
+{
+  GdkDisplayClass parent_class;
+};
+
+GType      gdk_broadway_display_get_type            (void);
+
+G_END_DECLS
+
+#endif                         /* __GDK_BROADWAY_DISPLAY__ */
diff --git a/gdk/broadway/gdkdisplaymanager-broadway.c b/gdk/broadway/gdkdisplaymanager-broadway.c
new file mode 100644 (file)
index 0000000..2c52a6d
--- /dev/null
@@ -0,0 +1,162 @@
+/* GDK - The GIMP Drawing Kit
+ * gdkdisplaymanager-broadway.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ * Copyright 2010 Red Hat, Inc.
+ *
+ * Author: Matthias clasen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdkdisplay-broadway.h"
+#include "gdkbroadwaydisplaymanager.h"
+#include "gdkprivate-broadway.h"
+
+#include "gdkdisplaymanagerprivate.h"
+#include "gdkinternals.h"
+
+struct _GdkBroadwayDisplayManager
+{
+  GdkDisplayManager parent;
+
+  GdkDisplay *default_display;
+  GSList *displays;
+};
+
+G_DEFINE_TYPE (GdkBroadwayDisplayManager, gdk_broadway_display_manager, GDK_TYPE_DISPLAY_MANAGER)
+
+static GdkDisplay *
+gdk_broadway_display_manager_open_display (GdkDisplayManager *manager,
+                                         const gchar       *name)
+{
+  return _gdk_broadway_display_open (name);
+}
+
+static GSList *
+gdk_broadway_display_manager_list_displays (GdkDisplayManager *manager)
+{
+  GdkBroadwayDisplayManager *manager_broadway = GDK_BROADWAY_DISPLAY_MANAGER (manager);
+
+  return g_slist_copy (manager_broadway->displays);
+}
+
+static GdkDisplay *
+gdk_broadway_display_manager_get_default_display (GdkDisplayManager *manager)
+{
+  return GDK_BROADWAY_DISPLAY_MANAGER (manager)->default_display;
+}
+
+static void
+gdk_broadway_display_manager_set_default_display (GdkDisplayManager *manager,
+                                                GdkDisplay        *display)
+{
+  GdkBroadwayDisplayManager *manager_broadway = GDK_BROADWAY_DISPLAY_MANAGER (manager);
+
+  manager_broadway->default_display = display;
+}
+
+#include "../gdkkeynames.c"
+
+static gchar *
+gdk_broadway_display_manager_get_keyval_name (GdkDisplayManager *manager,
+                                            guint              keyval)
+{
+  return _gdk_keyval_name (keyval);
+}
+
+static guint
+gdk_broadway_display_manager_lookup_keyval (GdkDisplayManager *manager,
+                                          const gchar       *name)
+{
+  return _gdk_keyval_from_name (name);
+}
+
+static void
+gdk_broadway_display_manager_keyval_convert_case (GdkDisplayManager *manager,
+                                                guint              symbol,
+                                                guint             *lower,
+                                                guint             *upper)
+{
+  /* FIXME implement this */
+  if (lower)
+    *lower = symbol;
+  if (upper)
+    *upper = symbol;
+}
+
+static void
+gdk_broadway_display_manager_init (GdkBroadwayDisplayManager *manager)
+{
+  _gdk_broadway_windowing_init ();
+}
+
+static void
+gdk_broadway_display_manager_finalize (GObject *object)
+{
+  g_error ("A GdkBroadwayDisplayManager object was finalized. This should not happen");
+  G_OBJECT_CLASS (gdk_broadway_display_manager_parent_class)->finalize (object);
+}
+
+static void
+gdk_broadway_display_manager_class_init (GdkBroadwayDisplayManagerClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  GdkDisplayManagerClass *manager_class = GDK_DISPLAY_MANAGER_CLASS (class);
+
+  object_class->finalize = gdk_broadway_display_manager_finalize;
+
+  manager_class->open_display = gdk_broadway_display_manager_open_display;
+  manager_class->list_displays = gdk_broadway_display_manager_list_displays;
+  manager_class->set_default_display = gdk_broadway_display_manager_set_default_display;
+  manager_class->get_default_display = gdk_broadway_display_manager_get_default_display;
+  manager_class->atom_intern = _gdk_broadway_display_manager_atom_intern;
+  manager_class->get_atom_name = _gdk_broadway_display_manager_get_atom_name;
+  manager_class->lookup_keyval = gdk_broadway_display_manager_lookup_keyval;
+  manager_class->get_keyval_name = gdk_broadway_display_manager_get_keyval_name;
+  manager_class->keyval_convert_case = gdk_broadway_display_manager_keyval_convert_case;
+}
+
+void
+_gdk_broadway_display_manager_add_display (GdkDisplayManager *manager,
+                                          GdkDisplay        *display)
+{
+  GdkBroadwayDisplayManager *manager_broadway = GDK_BROADWAY_DISPLAY_MANAGER (manager);
+
+  if (manager_broadway->displays == NULL)
+    gdk_display_manager_set_default_display (manager, display);
+
+  manager_broadway->displays = g_slist_prepend (manager_broadway->displays, display);
+}
+
+void
+_gdk_broadway_display_manager_remove_display (GdkDisplayManager *manager,
+                                             GdkDisplay        *display)
+{
+  GdkBroadwayDisplayManager *manager_broadway = GDK_BROADWAY_DISPLAY_MANAGER (manager);
+
+  manager_broadway->displays = g_slist_remove (manager_broadway->displays, display);
+
+  if (manager_broadway->default_display == display)
+    {
+      if (manager_broadway->displays)
+        gdk_display_manager_set_default_display (manager, manager_broadway->displays->data);
+      else
+        gdk_display_manager_set_default_display (manager, NULL);
+    }
+}
diff --git a/gdk/broadway/gdkdnd-broadway.c b/gdk/broadway/gdkdnd-broadway.c
new file mode 100644 (file)
index 0000000..b5e5850
--- /dev/null
@@ -0,0 +1,225 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "config.h"
+
+#include "gdkdndprivate.h"
+
+#include "gdkinternals.h"
+#include "gdkproperty.h"
+#include "gdkprivate-broadway.h"
+#include "gdkinternals.h"
+#include "gdkscreen-broadway.h"
+#include "gdkdisplay-broadway.h"
+
+#include <string.h>
+
+#define GDK_TYPE_BROADWAY_DRAG_CONTEXT              (gdk_broadway_drag_context_get_type ())
+#define GDK_BROADWAY_DRAG_CONTEXT(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_DRAG_CONTEXT, GdkBroadwayDragContext))
+#define GDK_BROADWAY_DRAG_CONTEXT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_DRAG_CONTEXT, GdkBroadwayDragContextClass))
+#define GDK_IS_BROADWAY_DRAG_CONTEXT(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_DRAG_CONTEXT))
+#define GDK_IS_BROADWAY_DRAG_CONTEXT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_DRAG_CONTEXT))
+#define GDK_BROADWAY_DRAG_CONTEXT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_DRAG_CONTEXT, GdkBroadwayDragContextClass))
+
+#ifdef GDK_COMPILATION
+typedef struct _GdkBroadwayDragContext GdkBroadwayDragContext;
+#else
+typedef GdkDragContext GdkBroadwayDragContext;
+#endif
+typedef struct _GdkBroadwayDragContextClass GdkBroadwayDragContextClass;
+
+GType     gdk_broadway_drag_context_get_type (void);
+
+struct _GdkBroadwayDragContext {
+  GdkDragContext context;
+};
+
+struct _GdkBroadwayDragContextClass
+{
+  GdkDragContextClass parent_class;
+};
+
+static void gdk_broadway_drag_context_finalize (GObject *object);
+
+static GList *contexts;
+
+G_DEFINE_TYPE (GdkBroadwayDragContext, gdk_broadway_drag_context, GDK_TYPE_DRAG_CONTEXT)
+
+static void
+gdk_broadway_drag_context_init (GdkBroadwayDragContext *dragcontext)
+{
+  contexts = g_list_prepend (contexts, dragcontext);
+}
+
+static void
+gdk_broadway_drag_context_finalize (GObject *object)
+{
+  GdkDragContext *context = GDK_DRAG_CONTEXT (object);
+
+  contexts = g_list_remove (contexts, context);
+
+  G_OBJECT_CLASS (gdk_broadway_drag_context_parent_class)->finalize (object);
+}
+
+/* Drag Contexts */
+
+GdkDragContext *
+_gdk_broadway_window_drag_begin (GdkWindow *window,
+                                GdkDevice *device,
+                                GList     *targets)
+{
+  GdkDragContext *new_context;
+
+  g_return_val_if_fail (window != NULL, NULL);
+  g_return_val_if_fail (GDK_WINDOW_IS_BROADWAY (window), NULL);
+
+  new_context = g_object_new (GDK_TYPE_BROADWAY_DRAG_CONTEXT,
+                             NULL);
+
+  return new_context;
+}
+
+GdkNativeWindow
+_gdk_broadway_display_get_drag_protocol (GdkDisplay      *display,
+                                        GdkNativeWindow  xid,
+                                        GdkDragProtocol *protocol,
+                                        guint           *version)
+{
+  return 0;
+}
+
+static GdkWindow *
+gdk_broadway_drag_context_find_window (GdkDragContext  *context,
+                                      GdkWindow       *drag_window,
+                                      GdkScreen       *screen,
+                                      gint             x_root,
+                                      gint             y_root,
+                                      GdkDragProtocol *protocol)
+{
+  g_return_val_if_fail (context != NULL, NULL);
+  return NULL;
+}
+
+static gboolean
+gdk_broadway_drag_context_drag_motion (GdkDragContext *context,
+                                      GdkWindow      *dest_window,
+                                      GdkDragProtocol protocol,
+                                      gint            x_root,
+                                      gint            y_root,
+                                      GdkDragAction   suggested_action,
+                                      GdkDragAction   possible_actions,
+                                      guint32         time)
+{
+  g_return_val_if_fail (context != NULL, FALSE);
+  g_return_val_if_fail (dest_window == NULL || GDK_WINDOW_IS_BROADWAY (dest_window), FALSE);
+
+  return FALSE;
+}
+
+static void
+gdk_broadway_drag_context_drag_drop (GdkDragContext *context,
+                                    guint32         time)
+{
+  g_return_if_fail (context != NULL);
+}
+
+static void
+gdk_broadway_drag_context_drag_abort (GdkDragContext *context,
+                                     guint32         time)
+{
+  g_return_if_fail (context != NULL);
+}
+
+/* Destination side */
+
+static void
+gdk_broadway_drag_context_drag_status (GdkDragContext   *context,
+                                      GdkDragAction     action,
+                                      guint32           time)
+{
+  g_return_if_fail (context != NULL);
+}
+
+static void
+gdk_broadway_drag_context_drop_reply (GdkDragContext   *context,
+                                     gboolean          ok,
+                                     guint32           time)
+{
+  g_return_if_fail (context != NULL);
+}
+
+static void
+gdk_broadway_drag_context_drop_finish (GdkDragContext   *context,
+                                      gboolean          success,
+                                      guint32           time)
+{
+  g_return_if_fail (context != NULL);
+}
+
+void
+_gdk_broadway_window_register_dnd (GdkWindow      *window)
+{
+}
+
+static GdkAtom
+gdk_broadway_drag_context_get_selection (GdkDragContext *context)
+{
+  g_return_val_if_fail (context != NULL, GDK_NONE);
+
+  return GDK_NONE;
+}
+
+static gboolean
+gdk_broadway_drag_context_drop_status (GdkDragContext *context)
+{
+  g_return_val_if_fail (context != NULL, FALSE);
+
+  return FALSE;
+}
+
+void
+_gdk_broadway_display_init_dnd (GdkDisplay *display)
+{
+}
+
+static void
+gdk_broadway_drag_context_class_init (GdkBroadwayDragContextClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GdkDragContextClass *context_class = GDK_DRAG_CONTEXT_CLASS (klass);
+
+  object_class->finalize = gdk_broadway_drag_context_finalize;
+
+  context_class->find_window = gdk_broadway_drag_context_find_window;
+  context_class->drag_status = gdk_broadway_drag_context_drag_status;
+  context_class->drag_motion = gdk_broadway_drag_context_drag_motion;
+  context_class->drag_abort = gdk_broadway_drag_context_drag_abort;
+  context_class->drag_drop = gdk_broadway_drag_context_drag_drop;
+  context_class->drop_reply = gdk_broadway_drag_context_drop_reply;
+  context_class->drop_finish = gdk_broadway_drag_context_drop_finish;
+  context_class->drop_status = gdk_broadway_drag_context_drop_status;
+  context_class->get_selection = gdk_broadway_drag_context_get_selection;
+}
diff --git a/gdk/broadway/gdkeventsource.c b/gdk/broadway/gdkeventsource.c
new file mode 100644 (file)
index 0000000..c4e2002
--- /dev/null
@@ -0,0 +1,349 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdkeventsource.h"
+
+#include "gdkinternals.h"
+
+#include <stdlib.h>
+
+static gboolean gdk_event_source_prepare  (GSource     *source,
+                                           gint        *timeout);
+static gboolean gdk_event_source_check    (GSource     *source);
+static gboolean gdk_event_source_dispatch (GSource     *source,
+                                           GSourceFunc  callback,
+                                           gpointer     user_data);
+static void     gdk_event_source_finalize (GSource     *source);
+
+#define HAS_FOCUS(toplevel)                           \
+  ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
+
+struct _GdkEventSource
+{
+  GSource source;
+
+  GdkDisplay *display;
+  GPollFD event_poll_fd;
+};
+
+static GSourceFuncs event_funcs = {
+  gdk_event_source_prepare,
+  gdk_event_source_check,
+  gdk_event_source_dispatch,
+  gdk_event_source_finalize
+};
+
+static GList *event_sources = NULL;
+
+static gboolean
+gdk_event_source_prepare (GSource *source,
+                          gint    *timeout)
+{
+  GdkDisplay *display = ((GdkEventSource*) source)->display;
+  gboolean retval;
+
+  GDK_THREADS_ENTER ();
+
+  *timeout = -1;
+  retval = (_gdk_event_queue_find_first (display) != NULL);
+
+  GDK_THREADS_LEAVE ();
+
+  return retval;
+}
+
+static gboolean
+gdk_event_source_check (GSource *source)
+{
+  GdkEventSource *event_source = (GdkEventSource*) source;
+  gboolean retval;
+
+  GDK_THREADS_ENTER ();
+
+  if (event_source->event_poll_fd.revents & G_IO_IN)
+    retval = (_gdk_event_queue_find_first (event_source->display) != NULL);
+  else
+    retval = FALSE;
+
+  GDK_THREADS_LEAVE ();
+
+  return retval;
+}
+
+void
+_gdk_broadway_events_got_input (GdkDisplay *display,
+                               const char *message)
+{
+  GdkBroadwayDisplay *display_broadway = GDK_BROADWAY_DISPLAY (display);
+  GdkScreen *screen;
+  GdkWindow *root, *window;
+  char *p;
+  int x, y, button, id, dir,key;
+  guint64 time;
+  GdkEvent *event = NULL;
+  char cmd;
+  GList *node;
+
+  screen = gdk_display_get_default_screen (display);
+  root = gdk_screen_get_root_window (screen);
+
+  p = (char *)message;
+  cmd = *p++;
+  switch (cmd) {
+  case 'm':
+    id = strtol(p, &p, 10);
+    p++; /* Skip , */
+    x = strtol(p, &p, 10);
+    p++; /* Skip , */
+    y = strtol(p, &p, 10);
+    p++; /* Skip , */
+    time = strtol(p, &p, 10);
+    display_broadway->last_x = x;
+    display_broadway->last_y = y;
+
+    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (id));
+
+    if (display_broadway->mouse_in_toplevel != window)
+      {
+       if (display_broadway->mouse_in_toplevel != NULL)
+         {
+           event = gdk_event_new (GDK_LEAVE_NOTIFY);
+           event->crossing.window = g_object_ref (display_broadway->mouse_in_toplevel);
+           event->crossing.time = time;
+           event->crossing.x = x - display_broadway->mouse_in_toplevel->x;
+           event->crossing.y = y - display_broadway->mouse_in_toplevel->y;
+           event->crossing.x_root = x;
+           event->crossing.y_root = y;
+           event->crossing.mode = GDK_CROSSING_NORMAL;
+           event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+           gdk_event_set_device (event, display->core_pointer);
+
+           node = _gdk_event_queue_append (display, event);
+           _gdk_windowing_got_event (display, node, event, 0);
+
+           event = gdk_event_new (GDK_FOCUS_CHANGE);
+           event->focus_change.window = g_object_ref (display_broadway->mouse_in_toplevel);
+           event->focus_change.in = FALSE;
+           gdk_event_set_device (event, display->core_pointer);
+
+           node = _gdk_event_queue_append (display, event);
+           _gdk_windowing_got_event (display, node, event, 0);
+         }
+
+       /* TODO: Unset when it dies */
+       display_broadway->mouse_in_toplevel = window;
+
+       if (window)
+         {
+           event = gdk_event_new (GDK_ENTER_NOTIFY);
+           event->crossing.window = g_object_ref (window);
+           event->crossing.time = time;
+           event->crossing.x = x - window->x;
+           event->crossing.y = y - window->y;
+           event->crossing.x_root = x;
+           event->crossing.y_root = y;
+           event->crossing.mode = GDK_CROSSING_NORMAL;
+           event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+           gdk_event_set_device (event, display->core_pointer);
+
+           node = _gdk_event_queue_append (display, event);
+           _gdk_windowing_got_event (display, node, event, 0);
+
+           event = gdk_event_new (GDK_FOCUS_CHANGE);
+           event->focus_change.window = g_object_ref (window);
+           event->focus_change.in = TRUE;
+           gdk_event_set_device (event, display->core_pointer);
+
+           node = _gdk_event_queue_append (display, event);
+           _gdk_windowing_got_event (display, node, event, 0);
+
+         }
+      }
+
+    if (window)
+      {
+       event = gdk_event_new (GDK_MOTION_NOTIFY);
+       event->motion.window = g_object_ref (window);
+       event->motion.time = time;
+       event->motion.x = x - window->x;
+       event->motion.y = y - window->y;
+       event->motion.x_root = x;
+       event->motion.y_root = y;
+       gdk_event_set_device (event, display->core_pointer);
+
+       node = _gdk_event_queue_append (display, event);
+       _gdk_windowing_got_event (display, node, event, 0);
+      }
+
+    break;
+  case 'b':
+  case 'B':
+    id = strtol(p, &p, 10);
+    p++; /* Skip , */
+    x = strtol(p, &p, 10);
+    p++; /* Skip , */
+    y = strtol(p, &p, 10);
+    p++; /* Skip , */
+    button = strtol(p, &p, 10);
+    p++; /* Skip , */
+    time = strtol(p, &p, 10);
+    display_broadway->last_x = x;
+    display_broadway->last_y = y;
+
+    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (id));
+
+    if (window)
+      {
+       event = gdk_event_new (cmd == 'b' ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
+       event->button.window = g_object_ref (window);
+       event->button.time = time;
+       event->button.x = x - window->x;
+       event->button.y = y - window->y;
+       event->button.x_root = x;
+       event->button.y_root = y;
+       event->button.button = button + 1;
+       gdk_event_set_device (event, display->core_pointer);
+
+       node = _gdk_event_queue_append (display, event);
+       _gdk_windowing_got_event (display, node, event, 0);
+      }
+
+    break;
+  case 's':
+    id = strtol(p, &p, 10);
+    p++; /* Skip , */
+    x = strtol(p, &p, 10);
+    p++; /* Skip , */
+    y = strtol(p, &p, 10);
+    p++; /* Skip , */
+    dir = strtol(p, &p, 10);
+    p++; /* Skip , */
+    time = strtol(p, &p, 10);
+    display_broadway->last_x = x;
+    display_broadway->last_y = y;
+
+    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (id));
+
+    if (window)
+      {
+       event = gdk_event_new (GDK_SCROLL);
+       event->scroll.window = g_object_ref (window);
+       event->scroll.time = time;
+       event->scroll.x = x - window->x;
+       event->scroll.y = y - window->y;
+       event->scroll.x_root = x;
+       event->scroll.y_root = y;
+       event->scroll.direction = dir == 0 ? GDK_SCROLL_UP : GDK_SCROLL_DOWN;
+       gdk_event_set_device (event, display->core_pointer);
+
+       node = _gdk_event_queue_append (display, event);
+       _gdk_windowing_got_event (display, node, event, 0);
+      }
+
+    break;
+  case 'k':
+  case 'K':
+    key = strtol(p, &p, 10);
+    p++; /* Skip , */
+    time = strtol(p, &p, 10);
+
+    window = display_broadway->mouse_in_toplevel;
+
+    if (window)
+      {
+       event = gdk_event_new (cmd == 'k' ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
+       event->key.window = g_object_ref (window);
+       event->key.time = time;
+       event->key.keyval = key;
+       event->key.length = 0;
+       gdk_event_set_device (event, display->core_pointer);
+
+       node = _gdk_event_queue_append (display, event);
+       _gdk_windowing_got_event (display, node, event, 0);
+      }
+
+    break;
+  default:
+    g_print ("Unknown input command %s\n", message);
+    break;
+  }
+}
+
+void
+_gdk_broadway_display_queue_events (GdkDisplay *display)
+{
+}
+
+static gboolean
+gdk_event_source_dispatch (GSource     *source,
+                           GSourceFunc  callback,
+                           gpointer     user_data)
+{
+  GdkDisplay *display = ((GdkEventSource*) source)->display;
+  GdkEvent *event;
+
+  GDK_THREADS_ENTER ();
+
+  event = gdk_display_get_event (display);
+
+  if (event)
+    {
+      _gdk_event_emit (event);
+
+      gdk_event_free (event);
+    }
+
+  GDK_THREADS_LEAVE ();
+
+  return TRUE;
+}
+
+static void
+gdk_event_source_finalize (GSource *source)
+{
+  GdkEventSource *event_source = (GdkEventSource *)source;
+
+  event_sources = g_list_remove (event_sources, event_source);
+}
+
+GSource *
+_gdk_broadway_event_source_new (GdkDisplay *display)
+{
+  GSource *source;
+  GdkEventSource *event_source;
+  char *name;
+
+  source = g_source_new (&event_funcs, sizeof (GdkEventSource));
+  name = g_strdup_printf ("GDK Broadway Event source (%s)",
+                         gdk_display_get_name (display));
+  g_source_set_name (source, name);
+  g_free (name);
+  event_source = (GdkEventSource *) source;
+  event_source->display = display;
+
+  g_source_set_priority (source, GDK_PRIORITY_EVENTS);
+  g_source_set_can_recurse (source, TRUE);
+  g_source_attach (source, NULL);
+
+  event_sources = g_list_prepend (event_sources, source);
+
+  return source;
+}
diff --git a/gdk/broadway/gdkeventsource.h b/gdk/broadway/gdkeventsource.h
new file mode 100644 (file)
index 0000000..2d7c9fb
--- /dev/null
@@ -0,0 +1,34 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_EVENT_SOURCE_H__
+#define __GDK_EVENT_SOURCE_H__
+
+#include "gdkprivate-broadway.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GdkEventSource GdkEventSource;
+
+G_GNUC_INTERNAL
+GSource * _gdk_broadway_event_source_new            (GdkDisplay *display);
+
+G_END_DECLS
+
+#endif /* __GDK_EVENT_SOURCE_H__ */
diff --git a/gdk/broadway/gdkglobals-broadway.c b/gdk/broadway/gdkglobals-broadway.c
new file mode 100644 (file)
index 0000000..d2026ea
--- /dev/null
@@ -0,0 +1,33 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "config.h"
+
+#include "gdktypes.h"
+#include "gdkprivate-broadway.h"
+
+#include <stdio.h>
+
diff --git a/gdk/broadway/gdkim-broadway.c b/gdk/broadway/gdkim-broadway.c
new file mode 100644 (file)
index 0000000..25d845e
--- /dev/null
@@ -0,0 +1,40 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "config.h"
+
+#include "gdkmain.h"
+#include "gdkinternals.h"
+#include "gdkdisplay-broadway.h"
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+void
+_gdk_broadway_initialize_locale (void)
+{
+}
diff --git a/gdk/broadway/gdkkeys-broadway.c b/gdk/broadway/gdkkeys-broadway.c
new file mode 100644 (file)
index 0000000..1d5f41a
--- /dev/null
@@ -0,0 +1,190 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include "gdkprivate-broadway.h"
+#include "gdkinternals.h"
+#include "gdkdisplay-broadway.h"
+#include "gdkkeysprivate.h"
+#include "gdkkeysyms.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+typedef struct _GdkBroadwayKeymap   GdkBroadwayKeymap;
+typedef struct _GdkKeymapClass GdkBroadwayKeymapClass;
+
+#define GDK_TYPE_BROADWAY_KEYMAP          (gdk_broadway_keymap_get_type ())
+#define GDK_BROADWAY_KEYMAP(object)       (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_KEYMAP, GdkBroadwayKeymap))
+#define GDK_IS_BROADWAY_KEYMAP(object)    (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_KEYMAP))
+
+typedef struct _DirectionCacheEntry DirectionCacheEntry;
+
+struct _GdkBroadwayKeymap
+{
+  GdkKeymap     parent_instance;
+};
+
+struct _GdkBroadwayKeymapClass
+{
+  GdkKeymapClass keymap_class;
+};
+
+G_DEFINE_TYPE (GdkBroadwayKeymap, gdk_broadway_keymap, GDK_TYPE_KEYMAP)
+
+static void  gdk_broadway_keymap_finalize   (GObject           *object);
+
+static void
+gdk_broadway_keymap_init (GdkBroadwayKeymap *keymap)
+{
+}
+
+static void
+gdk_broadway_keymap_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (gdk_broadway_keymap_parent_class)->finalize (object);
+}
+
+GdkKeymap*
+_gdk_broadway_display_get_keymap (GdkDisplay *display)
+{
+  GdkBroadwayDisplay *broadway_display;
+
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+  broadway_display = GDK_BROADWAY_DISPLAY (display);
+
+  if (!broadway_display->keymap)
+    broadway_display->keymap = g_object_new (gdk_broadway_keymap_get_type (), NULL);
+
+  broadway_display->keymap->display = display;
+
+  return broadway_display->keymap;
+}
+
+static PangoDirection
+gdk_broadway_keymap_get_direction (GdkKeymap *keymap)
+{
+  return PANGO_DIRECTION_NEUTRAL;
+}
+
+static gboolean
+gdk_broadway_keymap_have_bidi_layouts (GdkKeymap *keymap)
+{
+  return FALSE;
+}
+
+static gboolean
+gdk_broadway_keymap_get_caps_lock_state (GdkKeymap *keymap)
+{
+  return FALSE;
+}
+
+static gboolean
+gdk_broadway_keymap_get_num_lock_state (GdkKeymap *keymap)
+{
+  return FALSE;
+}
+
+static gboolean
+gdk_broadway_keymap_get_entries_for_keyval (GdkKeymap     *keymap,
+                                           guint          keyval,
+                                           GdkKeymapKey **keys,
+                                           gint          *n_keys)
+{
+  *n_keys = 0;
+  return FALSE;
+}
+
+static gboolean
+gdk_broadway_keymap_get_entries_for_keycode (GdkKeymap     *keymap,
+                                            guint          hardware_keycode,
+                                            GdkKeymapKey **keys,
+                                            guint        **keyvals,
+                                            gint          *n_entries)
+{
+  *n_entries = 0;
+  return FALSE;
+}
+
+static guint
+gdk_broadway_keymap_lookup_key (GdkKeymap          *keymap,
+                               const GdkKeymapKey *key)
+{
+  return 0;
+}
+
+
+static gboolean
+gdk_broadway_keymap_translate_keyboard_state (GdkKeymap       *keymap,
+                                             guint            hardware_keycode,
+                                             GdkModifierType  state,
+                                             gint             group,
+                                             guint           *keyval,
+                                             gint            *effective_group,
+                                             gint            *level,
+                                             GdkModifierType *consumed_modifiers)
+{
+  return FALSE;
+}
+
+static void
+gdk_broadway_keymap_add_virtual_modifiers (GdkKeymap       *keymap,
+                                          GdkModifierType *state)
+{
+}
+
+static gboolean
+gdk_broadway_keymap_map_virtual_modifiers (GdkKeymap       *keymap,
+                                          GdkModifierType *state)
+{
+  return FALSE;
+}
+
+static void
+gdk_broadway_keymap_class_init (GdkBroadwayKeymapClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass);
+
+  object_class->finalize = gdk_broadway_keymap_finalize;
+
+  keymap_class->get_direction = gdk_broadway_keymap_get_direction;
+  keymap_class->have_bidi_layouts = gdk_broadway_keymap_have_bidi_layouts;
+  keymap_class->get_caps_lock_state = gdk_broadway_keymap_get_caps_lock_state;
+  keymap_class->get_num_lock_state = gdk_broadway_keymap_get_num_lock_state;
+  keymap_class->get_entries_for_keyval = gdk_broadway_keymap_get_entries_for_keyval;
+  keymap_class->get_entries_for_keycode = gdk_broadway_keymap_get_entries_for_keycode;
+  keymap_class->lookup_key = gdk_broadway_keymap_lookup_key;
+  keymap_class->translate_keyboard_state = gdk_broadway_keymap_translate_keyboard_state;
+  keymap_class->add_virtual_modifiers = gdk_broadway_keymap_add_virtual_modifiers;
+  keymap_class->map_virtual_modifiers = gdk_broadway_keymap_map_virtual_modifiers;
+}
+
diff --git a/gdk/broadway/gdkmain-broadway.c b/gdk/broadway/gdkmain-broadway.c
new file mode 100644 (file)
index 0000000..f7a2817
--- /dev/null
@@ -0,0 +1,46 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "config.h"
+
+#include "gdkdisplay-broadway.h"
+#include "gdkinternals.h"
+#include "gdkprivate-broadway.h"
+#include "gdkintl.h"
+#include "gdkdeviceprivate.h"
+
+#include <glib/gprintf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+void
+_gdk_broadway_windowing_init (void)
+{
+  _gdk_broadway_initialize_locale ();
+}
diff --git a/gdk/broadway/gdkprivate-broadway.h b/gdk/broadway/gdkprivate-broadway.h
new file mode 100644 (file)
index 0000000..efc0f77
--- /dev/null
@@ -0,0 +1,216 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/*
+ * Private uninstalled header defining things local to X windowing code
+ */
+
+#ifndef __GDK_PRIVATE_BROADWAY_H__
+#define __GDK_PRIVATE_BROADWAY_H__
+
+#include <gdk/gdkcursor.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkinternals.h>
+#include "gdkwindow-broadway.h"
+#include "gdkdisplay-broadway.h"
+
+#include "gdkbroadwaycursor.h"
+#include "gdkbroadwayvisual.h"
+#include "gdkbroadwaywindow.h"
+
+void _gdk_broadway_resync_windows (void);
+void _gdk_broadway_windowing_init (void);
+
+gchar * _gdk_broadway_display_manager_get_atom_name (GdkDisplayManager *manager,
+                                                    GdkAtom atom);
+void _gdk_broadway_display_manager_add_display (GdkDisplayManager *manager,
+                                               GdkDisplay        *display);
+void _gdk_broadway_display_manager_remove_display (GdkDisplayManager *manager,
+                                                  GdkDisplay        *display);
+GdkAtom _gdk_broadway_display_manager_atom_intern_static_string (GdkDisplayManager *manager,
+                                                                const gchar *atom_name);
+GdkAtom _gdk_broadway_display_manager_atom_intern (GdkDisplayManager *manager,
+                                                  const gchar *atom_name, 
+                                                  gboolean     only_if_exists);
+
+
+void     _gdk_broadway_window_register_dnd (GdkWindow      *window);
+GdkDragContext * _gdk_broadway_window_drag_begin (GdkWindow *window,
+                                                 GdkDevice *device,
+                                                 GList     *targets);
+gboolean _gdk_broadway_window_queue_antiexpose  (GdkWindow *window,
+                                                cairo_region_t *area);
+void     _gdk_broadway_window_translate         (GdkWindow *window,
+                                                cairo_region_t *area,
+                                                gint       dx,
+                                                gint       dy);
+gboolean _gdk_broadway_window_get_property (GdkWindow   *window,
+                                           GdkAtom      property,
+                                           GdkAtom      type,
+                                           gulong       offset,
+                                           gulong       length,
+                                           gint         pdelete,
+                                           GdkAtom     *actual_property_type,
+                                           gint        *actual_format_type,
+                                           gint        *actual_length,
+                                           guchar     **data);
+void _gdk_broadway_window_change_property (GdkWindow    *window,
+                                          GdkAtom       property,
+                                          GdkAtom       type,
+                                          gint          format,
+                                          GdkPropMode   mode,
+                                          const guchar *data,
+                                          gint          nelements);
+void _gdk_broadway_window_delete_property (GdkWindow *window,
+                                          GdkAtom    property);
+
+void     _gdk_broadway_selection_window_destroyed   (GdkWindow            *window);
+
+void _gdk_keymap_keys_changed     (GdkDisplay      *display);
+gint _gdk_broadway_get_group_for_state (GdkDisplay      *display,
+                                       GdkModifierType  state);
+void _gdk_keymap_add_virtual_modifiers_compat (GdkKeymap       *keymap,
+                                               GdkModifierType *modifiers);
+gboolean _gdk_keymap_key_is_modifier   (GdkKeymap       *keymap,
+                                       guint            keycode);
+
+void _gdk_broadway_initialize_locale (void);
+
+void _gdk_broadway_screen_events_init   (GdkScreen *screen);
+GdkVisual *_gdk_broadway_screen_get_system_visual (GdkScreen * screen);
+gint _gdk_broadway_screen_visual_get_best_depth (GdkScreen * screen);
+GdkVisualType _gdk_broadway_screen_visual_get_best_type (GdkScreen * screen);
+GdkVisual *_gdk_broadway_screen_get_system_visual (GdkScreen * screen);
+GdkVisual*_gdk_broadway_screen_visual_get_best (GdkScreen * screen);
+GdkVisual*_gdk_broadway_screen_visual_get_best_with_depth (GdkScreen * screen,
+                                                          gint depth);
+GdkVisual*_gdk_broadway_screen_visual_get_best_with_type (GdkScreen * screen,
+                                                         GdkVisualType visual_type);
+GdkVisual*_gdk_broadway_screen_visual_get_best_with_both (GdkScreen * screen,
+                                                         gint          depth,
+                                                         GdkVisualType visual_type);
+void _gdk_broadway_screen_query_depths  (GdkScreen * screen,
+                                        gint **depths,
+                                        gint  *count);
+void _gdk_broadway_screen_query_visual_types (GdkScreen * screen,
+                                             GdkVisualType **visual_types,
+                                             gint           *count);
+GList *_gdk_broadway_screen_list_visuals (GdkScreen *screen);
+
+void _gdk_broadway_events_got_input      (GdkDisplay *display,
+                                         const char *message);
+
+void _gdk_broadway_screen_init_root_window (GdkScreen *screen);
+void _gdk_broadway_screen_init_visuals (GdkScreen *screen);
+void _gdk_broadway_display_init_dnd (GdkDisplay *display);
+GdkDisplay * _gdk_broadway_display_open (const gchar *display_name);
+void _gdk_broadway_display_queue_events (GdkDisplay *display);
+GdkNativeWindow _gdk_broadway_display_get_drag_protocol (GdkDisplay      *display,
+                                                        GdkNativeWindow  xid,
+                                                        GdkDragProtocol *protocol,
+                                                        guint           *version);
+GdkCursor*_gdk_broadway_display_get_cursor_for_type (GdkDisplay    *display,
+                                                    GdkCursorType  cursor_type);
+GdkCursor*_gdk_broadway_display_get_cursor_for_name (GdkDisplay  *display,
+                                                    const gchar *name);
+GdkCursor *_gdk_broadway_display_get_cursor_for_pixbuf (GdkDisplay *display,
+                                                       GdkPixbuf  *pixbuf,
+                                                       gint        x,
+                                                       gint        y);
+gboolean _gdk_broadway_display_supports_cursor_alpha (GdkDisplay *display);
+gboolean _gdk_broadway_display_supports_cursor_color (GdkDisplay *display);
+void _gdk_broadway_display_get_default_cursor_size (GdkDisplay *display,
+                                                   guint       *width,
+                                                   guint       *height);
+void _gdk_broadway_display_get_maximal_cursor_size (GdkDisplay *display,
+                                                   guint       *width,
+                                                   guint       *height);
+void       _gdk_broadway_display_before_process_all_updates (GdkDisplay *display);
+void       _gdk_broadway_display_after_process_all_updates  (GdkDisplay *display);
+void       _gdk_broadway_display_create_window_impl     (GdkDisplay    *display,
+                                                        GdkWindow     *window,
+                                                        GdkWindow     *real_parent,
+                                                        GdkScreen     *screen,
+                                                        GdkEventMask   event_mask,
+                                                        GdkWindowAttr *attributes,
+                                                        gint           attributes_mask);
+gboolean _gdk_broadway_display_set_selection_owner (GdkDisplay *display,
+                                                   GdkWindow  *owner,
+                                                   GdkAtom     selection,
+                                                   guint32     time,
+                                                   gboolean    send_event);
+GdkWindow * _gdk_broadway_display_get_selection_owner (GdkDisplay *display,
+                                                      GdkAtom     selection);
+gint _gdk_broadway_display_get_selection_property (GdkDisplay *display,
+                                                  GdkWindow  *requestor,
+                                                  guchar    **data,
+                                                  GdkAtom    *ret_type,
+                                                  gint       *ret_format);
+void _gdk_broadway_display_send_selection_notify (GdkDisplay       *display,
+                                                 GdkNativeWindow  requestor,
+                                                 GdkAtom          selection,
+                                                 GdkAtom          target,
+                                                 GdkAtom          property, 
+                                                 guint32          time);
+void _gdk_broadway_display_convert_selection (GdkDisplay *display,
+                                             GdkWindow *requestor,
+                                             GdkAtom    selection,
+                                             GdkAtom    target,
+                                             guint32    time);
+gint _gdk_broadway_display_text_property_to_utf8_list (GdkDisplay    *display,
+                                                      GdkAtom        encoding,
+                                                      gint           format,
+                                                      const guchar  *text,
+                                                      gint           length,
+                                                      gchar       ***list);
+gchar *_gdk_broadway_display_utf8_to_string_target (GdkDisplay  *display,
+                                                   const gchar *str);
+GdkKeymap* _gdk_broadway_display_get_keymap (GdkDisplay *display);
+
+/* Window methods - testing */
+void     _gdk_broadway_window_sync_rendering    (GdkWindow       *window);
+gboolean _gdk_broadway_window_simulate_key      (GdkWindow       *window,
+                                                gint             x,
+                                                gint             y,
+                                                guint            keyval,
+                                                GdkModifierType  modifiers,
+                                                GdkEventType     key_pressrelease);
+gboolean _gdk_broadway_window_simulate_button   (GdkWindow       *window,
+                                                gint             x,
+                                                gint             y,
+                                                guint            button,
+                                                GdkModifierType  modifiers,
+                                                GdkEventType     button_pressrelease);
+
+void _gdk_broadway_cursor_update_theme (GdkCursor *cursor);
+void _gdk_broadway_cursor_display_finalize (GdkDisplay *display);
+
+#define GDK_SCREEN_DISPLAY(screen)    (GDK_BROADWAY_SCREEN (screen)->display)
+#define GDK_WINDOW_SCREEN(win)       (GDK_WINDOW_IMPL_BROADWAY (((GdkWindow *)win)->impl)->screen)
+#define GDK_WINDOW_DISPLAY(win)       (GDK_BROADWAY_SCREEN (GDK_WINDOW_SCREEN (win))->display)
+#define GDK_WINDOW_IS_BROADWAY(win)   (GDK_IS_WINDOW_IMPL_BROADWAY (((GdkWindow *)win)->impl))
+
+#endif /* __GDK_PRIVATE_BROADWAY_H__ */
diff --git a/gdk/broadway/gdkproperty-broadway.c b/gdk/broadway/gdkproperty-broadway.c
new file mode 100644 (file)
index 0000000..d3e8306
--- /dev/null
@@ -0,0 +1,100 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "config.h"
+
+#include "gdkproperty.h"
+
+#include "gdkmain.h"
+#include "gdkprivate.h"
+#include "gdkinternals.h"
+#include "gdkdisplay-broadway.h"
+#include "gdkscreen-broadway.h"
+#include "gdkselection.h"
+
+#include <string.h>
+
+GdkAtom
+_gdk_broadway_display_manager_atom_intern (GdkDisplayManager *manager,
+                                          const gchar *atom_name, 
+                                          gboolean     only_if_exists)
+{
+  return _GDK_MAKE_ATOM (g_quark_from_string (atom_name));
+}
+
+GdkAtom
+_gdk_broadway_display_manager_atom_intern_static_string (GdkDisplayManager *manager,
+                                                        const gchar *atom_name)
+{
+  return _GDK_MAKE_ATOM (g_quark_from_static_string (atom_name));
+}
+
+static G_CONST_RETURN char *
+get_atom_name (GdkAtom atom)
+{
+  return g_quark_to_string (GPOINTER_TO_UINT(atom));
+}
+
+gchar *
+_gdk_broadway_display_manager_get_atom_name (GdkDisplayManager *manager,
+                                            GdkAtom atom)
+{
+  return g_strdup (get_atom_name (atom));
+}
+
+gboolean
+_gdk_broadway_window_get_property (GdkWindow   *window,
+                                  GdkAtom      property,
+                                  GdkAtom      type,
+                                  gulong       offset,
+                                  gulong       length,
+                                  gint         pdelete,
+                                  GdkAtom     *actual_property_type,
+                                  gint        *actual_format_type,
+                                  gint        *actual_length,
+                                  guchar     **data)
+{
+  return FALSE;
+}
+
+void
+_gdk_broadway_window_change_property (GdkWindow    *window,
+                                     GdkAtom       property,
+                                     GdkAtom       type,
+                                     gint          format,
+                                     GdkPropMode   mode,
+                                     const guchar *data,
+                                     gint          nelements)
+{
+  g_return_if_fail (!window || GDK_WINDOW_IS_BROADWAY (window));
+}
+
+void
+_gdk_broadway_window_delete_property (GdkWindow *window,
+                                     GdkAtom    property)
+{
+  g_return_if_fail (!window || GDK_WINDOW_IS_BROADWAY (window));
+}
diff --git a/gdk/broadway/gdkscreen-broadway.c b/gdk/broadway/gdkscreen-broadway.c
new file mode 100644 (file)
index 0000000..9df7199
--- /dev/null
@@ -0,0 +1,329 @@
+ /*
+ * gdkscreen-broadway.c
+ * 
+ * Copyright 2001 Sun Microsystems Inc. 
+ *
+ * Erwann Chenede <erwann.chenede@sun.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdkscreen-broadway.h"
+
+#include "gdkscreen.h"
+#include "gdkdisplay.h"
+#include "gdkdisplay-broadway.h"
+
+#include <glib.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+static void         gdk_broadway_screen_dispose     (GObject             *object);
+static void         gdk_broadway_screen_finalize    (GObject             *object);
+
+G_DEFINE_TYPE (GdkBroadwayScreen, gdk_broadway_screen, GDK_TYPE_SCREEN)
+
+static void
+gdk_broadway_screen_init (GdkBroadwayScreen *screen)
+{
+  screen->width = 1024;
+  screen->height = 768;
+}
+
+static GdkDisplay *
+gdk_broadway_screen_get_display (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+  return GDK_BROADWAY_SCREEN (screen)->display;
+}
+
+static gint
+gdk_broadway_screen_get_width (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+  return GDK_BROADWAY_SCREEN (screen)->width;
+}
+
+static gint
+gdk_broadway_screen_get_height (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+  return GDK_BROADWAY_SCREEN (screen)->height;
+}
+
+static gint
+gdk_broadway_screen_get_width_mm (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+  return gdk_screen_get_width (screen) * 25.4 / 96;
+}
+
+static gint
+gdk_broadway_screen_get_height_mm (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+  return gdk_screen_get_height (screen) * 25.4 / 96;
+}
+
+static gint
+gdk_broadway_screen_get_number (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+  return 0;
+}
+
+static GdkWindow *
+gdk_broadway_screen_get_root_window (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+  return GDK_BROADWAY_SCREEN (screen)->root_window;
+}
+
+static void
+gdk_broadway_screen_dispose (GObject *object)
+{
+  GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (object);
+
+  if (broadway_screen->root_window)
+    _gdk_window_destroy (broadway_screen->root_window, TRUE);
+
+  G_OBJECT_CLASS (gdk_broadway_screen_parent_class)->dispose (object);
+}
+
+static void
+gdk_broadway_screen_finalize (GObject *object)
+{
+  GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (object);
+  gint          i;
+
+  if (broadway_screen->root_window)
+    g_object_unref (broadway_screen->root_window);
+
+  /* Visual Part */
+  for (i = 0; i < broadway_screen->nvisuals; i++)
+    g_object_unref (broadway_screen->visuals[i]);
+  g_free (broadway_screen->visuals);
+
+  G_OBJECT_CLASS (gdk_broadway_screen_parent_class)->finalize (object);
+}
+
+static gint
+gdk_broadway_screen_get_n_monitors (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+  return 1;
+}
+
+static gint
+gdk_broadway_screen_get_primary_monitor (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+  return 0;
+}
+
+static gint
+gdk_broadway_screen_get_monitor_width_mm (GdkScreen *screen,
+                                         gint       monitor_num)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
+  g_return_val_if_fail (monitor_num == 0, -1);
+
+  return gdk_screen_get_width_mm (screen);
+}
+
+static gint
+gdk_broadway_screen_get_monitor_height_mm (GdkScreen *screen,
+                                          gint       monitor_num)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
+  g_return_val_if_fail (monitor_num == 0, -1);
+
+  return gdk_screen_get_height_mm (screen);
+}
+
+static gchar *
+gdk_broadway_screen_get_monitor_plug_name (GdkScreen *screen,
+                                          gint       monitor_num)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+  g_return_val_if_fail (monitor_num == 0, NULL);
+
+  return g_strdup ("browser");
+}
+
+static void
+gdk_broadway_screen_get_monitor_geometry (GdkScreen    *screen,
+                                         gint          monitor_num,
+                                         GdkRectangle *dest)
+{
+  GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (screen);
+
+  g_return_if_fail (GDK_IS_SCREEN (screen));
+  g_return_if_fail (monitor_num == 0);
+
+  if (dest)
+    {
+      dest->x = 0;
+      dest->y = 0;
+      dest->width = broadway_screen->width;
+      dest->height = broadway_screen->height;
+    }
+}
+
+static GdkVisual *
+gdk_broadway_screen_get_rgba_visual (GdkScreen *screen)
+{
+  GdkBroadwayScreen *broadway_screen;
+
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+  broadway_screen = GDK_BROADWAY_SCREEN (screen);
+
+  return broadway_screen->rgba_visual;
+}
+
+GdkScreen *
+_gdk_broadway_screen_new (GdkDisplay *display,
+                         gint   screen_number)
+{
+  GdkScreen *screen;
+  GdkBroadwayScreen *broadway_screen;
+
+  screen = g_object_new (GDK_TYPE_BROADWAY_SCREEN, NULL);
+
+  broadway_screen = GDK_BROADWAY_SCREEN (screen);
+  broadway_screen->display = display;
+  _gdk_broadway_screen_init_visuals (screen);
+  _gdk_broadway_screen_init_root_window (screen);
+
+  return screen;
+}
+
+/*
+ * It is important that we first request the selection
+ * notification, and then setup the initial state of
+ * is_composited to avoid a race condition here.
+ */
+void
+_gdk_broadway_screen_setup (GdkScreen *screen)
+{
+}
+
+static gboolean
+gdk_broadway_screen_is_composited (GdkScreen *screen)
+{
+  GdkBroadwayScreen *broadway_screen;
+
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+  broadway_screen = GDK_BROADWAY_SCREEN (screen);
+
+  return FALSE;
+}
+
+
+static gchar *
+gdk_broadway_screen_make_display_name (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+  return g_strdup ("browser");
+}
+
+static GdkWindow *
+gdk_broadway_screen_get_active_window (GdkScreen *screen)
+{
+  return NULL;
+}
+
+static GList *
+gdk_broadway_screen_get_window_stack (GdkScreen *screen)
+{
+  return NULL;
+}
+
+static void
+gdk_broadway_screen_broadcast_client_message (GdkScreen *screen,
+                                             GdkEvent  *event)
+{
+}
+
+static gboolean
+gdk_broadway_screen_get_setting (GdkScreen   *screen,
+                                const gchar *name,
+                                GValue      *value)
+{
+  return FALSE;
+}
+
+void
+_gdk_broadway_screen_events_init (GdkScreen *screen)
+{
+}
+
+static void
+gdk_broadway_screen_class_init (GdkBroadwayScreenClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GdkScreenClass *screen_class = GDK_SCREEN_CLASS (klass);
+
+  object_class->dispose = gdk_broadway_screen_dispose;
+  object_class->finalize = gdk_broadway_screen_finalize;
+
+  screen_class->get_display = gdk_broadway_screen_get_display;
+  screen_class->get_width = gdk_broadway_screen_get_width;
+  screen_class->get_height = gdk_broadway_screen_get_height;
+  screen_class->get_width_mm = gdk_broadway_screen_get_width_mm;
+  screen_class->get_height_mm = gdk_broadway_screen_get_height_mm;
+  screen_class->get_number = gdk_broadway_screen_get_number;
+  screen_class->get_root_window = gdk_broadway_screen_get_root_window;
+  screen_class->get_n_monitors = gdk_broadway_screen_get_n_monitors;
+  screen_class->get_primary_monitor = gdk_broadway_screen_get_primary_monitor;
+  screen_class->get_monitor_width_mm = gdk_broadway_screen_get_monitor_width_mm;
+  screen_class->get_monitor_height_mm = gdk_broadway_screen_get_monitor_height_mm;
+  screen_class->get_monitor_plug_name = gdk_broadway_screen_get_monitor_plug_name;
+  screen_class->get_monitor_geometry = gdk_broadway_screen_get_monitor_geometry;
+  screen_class->is_composited = gdk_broadway_screen_is_composited;
+  screen_class->make_display_name = gdk_broadway_screen_make_display_name;
+  screen_class->get_active_window = gdk_broadway_screen_get_active_window;
+  screen_class->get_window_stack = gdk_broadway_screen_get_window_stack;
+  screen_class->broadcast_client_message = gdk_broadway_screen_broadcast_client_message;
+  screen_class->get_setting = gdk_broadway_screen_get_setting;
+  screen_class->get_rgba_visual = gdk_broadway_screen_get_rgba_visual;
+  screen_class->get_system_visual = _gdk_broadway_screen_get_system_visual;
+  screen_class->visual_get_best_depth = _gdk_broadway_screen_visual_get_best_depth;
+  screen_class->visual_get_best_type = _gdk_broadway_screen_visual_get_best_type;
+  screen_class->visual_get_best = _gdk_broadway_screen_visual_get_best;
+  screen_class->visual_get_best_with_depth = _gdk_broadway_screen_visual_get_best_with_depth;
+  screen_class->visual_get_best_with_type = _gdk_broadway_screen_visual_get_best_with_type;
+  screen_class->visual_get_best_with_both = _gdk_broadway_screen_visual_get_best_with_both;
+  screen_class->query_depths = _gdk_broadway_screen_query_depths;
+  screen_class->query_visual_types = _gdk_broadway_screen_query_visual_types;
+  screen_class->list_visuals = _gdk_broadway_screen_list_visuals;
+}
+
diff --git a/gdk/broadway/gdkscreen-broadway.h b/gdk/broadway/gdkscreen-broadway.h
new file mode 100644 (file)
index 0000000..df1f865
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * gdkscreen-broadway.h
+ * 
+ * Copyright 2001 Sun Microsystems Inc. 
+ *
+ * Erwann Chenede <erwann.chenede@sun.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_BROADWAY_SCREEN_H__
+#define __GDK_BROADWAY_SCREEN_H__
+
+#include <gdk/gdkscreenprivate.h>
+#include <gdk/gdkvisual.h>
+#include "gdkprivate-broadway.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GdkBroadwayScreen GdkBroadwayScreen;
+typedef struct _GdkBroadwayScreenClass GdkBroadwayScreenClass;
+
+#define GDK_TYPE_BROADWAY_SCREEN              (gdk_broadway_screen_get_type ())
+#define GDK_BROADWAY_SCREEN(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_SCREEN, GdkBroadwayScreen))
+#define GDK_BROADWAY_SCREEN_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_SCREEN, GdkBroadwayScreenClass))
+#define GDK_IS_BROADWAY_SCREEN(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_SCREEN))
+#define GDK_IS_BROADWAY_SCREEN_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_SCREEN))
+#define GDK_BROADWAY_SCREEN_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_SCREEN, GdkBroadwayScreenClass))
+
+typedef struct _GdkBroadwayMonitor GdkBroadwayMonitor;
+
+struct _GdkBroadwayScreen
+{
+  GdkScreen parent_instance;
+
+  GdkDisplay *display;
+  GdkWindow *root_window;
+
+  int width;
+  int height;
+
+  /* Visual Part */
+  GdkVisual **visuals;
+  gint nvisuals;
+  GdkVisual *system_visual;
+  GdkVisual *rgba_visual;
+  gint available_depths[7];
+  gint navailable_depths;
+  GdkVisualType available_types[6];
+  gint navailable_types;
+};
+
+struct _GdkBroadwayScreenClass
+{
+  GdkScreenClass parent_class;
+
+  void (* window_manager_changed) (GdkBroadwayScreen *screen);
+};
+
+GType       gdk_broadway_screen_get_type (void);
+GdkScreen * _gdk_broadway_screen_new      (GdkDisplay *display,
+                                          gint   screen_number);
+void _gdk_broadway_screen_setup           (GdkScreen *screen);
+
+G_END_DECLS
+
+#endif /* __GDK_BROADWAY_SCREEN_H__ */
diff --git a/gdk/broadway/gdkselection-broadway.c b/gdk/broadway/gdkselection-broadway.c
new file mode 100644 (file)
index 0000000..4ff9621
--- /dev/null
@@ -0,0 +1,146 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "config.h"
+
+#include "gdkselection.h"
+
+#include "gdkproperty.h"
+#include "gdkprivate.h"
+#include "gdkprivate-broadway.h"
+#include "gdkdisplay-broadway.h"
+
+#include <string.h>
+
+
+typedef struct _OwnerInfo OwnerInfo;
+
+struct _OwnerInfo
+{
+  GdkAtom    selection;
+  GdkWindow *owner;
+  gulong     serial;
+};
+
+static GSList *owner_list;
+
+/* When a window is destroyed we check if it is the owner
+ * of any selections. This is somewhat inefficient, but
+ * owner_list is typically short, and it is a low memory,
+ * low code solution
+ */
+void
+_gdk_broadway_selection_window_destroyed (GdkWindow *window)
+{
+  GSList *tmp_list = owner_list;
+  while (tmp_list)
+    {
+      OwnerInfo *info = tmp_list->data;
+      tmp_list = tmp_list->next;
+
+      if (info->owner == window)
+       {
+         owner_list = g_slist_remove (owner_list, info);
+         g_free (info);
+       }
+    }
+}
+
+gboolean
+_gdk_broadway_display_set_selection_owner (GdkDisplay *display,
+                                          GdkWindow  *owner,
+                                          GdkAtom     selection,
+                                          guint32     time,
+                                          gboolean    send_event)
+{
+  return FALSE;
+}
+
+GdkWindow *
+_gdk_broadway_display_get_selection_owner (GdkDisplay *display,
+                                          GdkAtom     selection)
+{
+  return NULL;
+}
+
+void
+_gdk_broadway_display_convert_selection (GdkDisplay *display,
+                                        GdkWindow *requestor,
+                                        GdkAtom    selection,
+                                        GdkAtom    target,
+                                        guint32    time)
+{
+}
+
+gint
+_gdk_broadway_display_get_selection_property (GdkDisplay *display,
+                                             GdkWindow  *requestor,
+                                             guchar    **data,
+                                             GdkAtom    *ret_type,
+                                             gint       *ret_format)
+{
+  if (ret_type)
+    *ret_type = GDK_NONE;
+  if (ret_format)
+    *ret_format = 0;
+  if (data)
+    *data = NULL;
+
+  return 0;
+}
+
+void
+_gdk_broadway_display_send_selection_notify (GdkDisplay       *display,
+                                            GdkNativeWindow  requestor,
+                                            GdkAtom          selection,
+                                            GdkAtom          target,
+                                            GdkAtom          property, 
+                                            guint32          time)
+{
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+}
+
+gint 
+_gdk_broadway_display_text_property_to_utf8_list (GdkDisplay    *display,
+                                                 GdkAtom        encoding,
+                                                 gint           format,
+                                                 const guchar  *text,
+                                                 gint           length,
+                                                 gchar       ***list)
+{
+  g_return_val_if_fail (text != NULL, 0);
+  g_return_val_if_fail (length >= 0, 0);
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
+
+  return 0;
+}
+
+gchar *
+_gdk_broadway_display_utf8_to_string_target (GdkDisplay  *display,
+                                            const gchar *str)
+{
+  return g_strdup (str);
+}
diff --git a/gdk/broadway/gdktestutils-broadway.c b/gdk/broadway/gdktestutils-broadway.c
new file mode 100644 (file)
index 0000000..ed6f25b
--- /dev/null
@@ -0,0 +1,67 @@
+/* Gtk+ testing utilities
+ * Copyright (C) 2007 Imendio AB
+ * Authors: Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "config.h"
+#include <gdk/gdktestutils.h>
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdkinternals.h>
+
+void
+_gdk_broadway_window_sync_rendering (GdkWindow *window)
+{
+  /* FIXME: Find out if there is a way to implement this on broadway. */
+}
+
+gboolean
+_gdk_broadway_window_simulate_key (GdkWindow      *window,
+                                  gint            x,
+                                  gint            y,
+                                  guint           keyval,
+                                  GdkModifierType modifiers,
+                                  GdkEventType    key_pressrelease)
+{
+  g_return_val_if_fail (key_pressrelease == GDK_KEY_PRESS || key_pressrelease == GDK_KEY_RELEASE, FALSE);
+  g_return_val_if_fail (window != NULL, FALSE);
+
+  if (!GDK_WINDOW_IS_MAPPED (window))
+    return FALSE;
+
+  /* FIXME: Implement. */
+
+  return FALSE;
+}
+
+gboolean
+_gdk_broadway_window_simulate_button (GdkWindow      *window,
+                                     gint            x,
+                                     gint            y,
+                                     guint           button, /*1..3*/
+                                     GdkModifierType modifiers,
+                                     GdkEventType    button_pressrelease)
+{
+  g_return_val_if_fail (button_pressrelease == GDK_BUTTON_PRESS || button_pressrelease == GDK_BUTTON_RELEASE, FALSE);
+  g_return_val_if_fail (window != NULL, FALSE);
+
+  if (!GDK_WINDOW_IS_MAPPED (window))
+    return FALSE;
+
+  /* FIXME: Implement. */
+
+  return FALSE;
+}
diff --git a/gdk/broadway/gdkvisual-broadway.c b/gdk/broadway/gdkvisual-broadway.c
new file mode 100644 (file)
index 0000000..26df16f
--- /dev/null
@@ -0,0 +1,290 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include "gdkvisualprivate.h"
+
+#include "gdkprivate-broadway.h"
+#include "gdkscreen-broadway.h"
+#include "gdkinternals.h"
+
+struct _GdkBroadwayVisual
+{
+  GdkVisual visual;
+};
+
+struct _GdkBroadwayVisualClass
+{
+  GObjectClass parent_class;
+};
+
+static void     gdk_visual_decompose_mask (gulong     mask,
+                                          gint      *shift,
+                                          gint      *prec);
+
+
+G_DEFINE_TYPE (GdkBroadwayVisual, gdk_broadway_visual, GDK_TYPE_VISUAL)
+
+static void
+gdk_broadway_visual_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (gdk_broadway_visual_parent_class)->finalize (object);
+}
+
+static void
+gdk_broadway_visual_class_init (GdkBroadwayVisualClass *visual_class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (visual_class);
+
+  object_class->finalize = gdk_broadway_visual_finalize;
+}
+
+static void
+gdk_broadway_visual_init (GdkBroadwayVisual *visual)
+{
+}
+
+void
+_gdk_broadway_screen_init_visuals (GdkScreen *screen)
+{
+  GdkBroadwayScreen *broadway_screen;
+  GdkVisual **visuals;
+  int nvisuals;
+
+  g_return_if_fail (GDK_IS_SCREEN (screen));
+  broadway_screen = GDK_BROADWAY_SCREEN (screen);
+
+  nvisuals = 2;
+  visuals = g_new (GdkVisual *, nvisuals);
+
+  visuals[0] = g_object_new (GDK_TYPE_BROADWAY_VISUAL, NULL);
+  visuals[0]->screen = screen;
+  visuals[0]->type = GDK_VISUAL_TRUE_COLOR;
+  visuals[0]->depth = 32;
+  visuals[0]->byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? GDK_LSB_FIRST : GDK_MSB_FIRST;
+  visuals[0]->red_mask = 0xff0000;
+  visuals[0]->green_mask = 0xff00;
+  visuals[0]->blue_mask = 0xff;
+  visuals[0]->colormap_size = 256;
+  visuals[0]->bits_per_rgb = 8;
+  gdk_visual_decompose_mask (visuals[0]->red_mask,
+                            &visuals[0]->red_shift,
+                            &visuals[0]->red_prec);
+  gdk_visual_decompose_mask (visuals[0]->green_mask,
+                            &visuals[0]->green_shift,
+                            &visuals[0]->green_prec);
+  gdk_visual_decompose_mask (visuals[0]->blue_mask,
+                            &visuals[0]->blue_shift,
+                            &visuals[0]->blue_prec);
+
+  visuals[1] = g_object_new (GDK_TYPE_BROADWAY_VISUAL, NULL);
+  visuals[1]->screen = screen;
+  visuals[1]->type = GDK_VISUAL_TRUE_COLOR;
+  visuals[1]->depth = 24;
+  visuals[1]->byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? GDK_LSB_FIRST : GDK_MSB_FIRST;
+  visuals[1]->red_mask = 0xff0000;
+  visuals[1]->green_mask = 0xff00;
+  visuals[1]->blue_mask = 0xff;
+  visuals[1]->colormap_size = 256;
+  visuals[1]->bits_per_rgb = 8;
+  gdk_visual_decompose_mask (visuals[1]->red_mask,
+                            &visuals[1]->red_shift,
+                            &visuals[1]->red_prec);
+  gdk_visual_decompose_mask (visuals[1]->green_mask,
+                            &visuals[1]->green_shift,
+                            &visuals[1]->green_prec);
+  gdk_visual_decompose_mask (visuals[1]->blue_mask,
+                            &visuals[1]->blue_shift,
+                            &visuals[1]->blue_prec);
+
+  broadway_screen->system_visual = visuals[1];
+  broadway_screen->rgba_visual = visuals[0];
+
+  broadway_screen->navailable_depths = 2;
+  broadway_screen->available_depths[0] = 32;
+  broadway_screen->available_depths[1] = 24;
+
+  broadway_screen->navailable_types = 1;
+  broadway_screen->available_types[0] = GDK_VISUAL_TRUE_COLOR;
+
+  broadway_screen->visuals = visuals;
+  broadway_screen->nvisuals = nvisuals;
+}
+
+gint
+_gdk_broadway_screen_visual_get_best_depth (GdkScreen * screen)
+{
+  return GDK_BROADWAY_SCREEN (screen)->available_depths[0];
+}
+
+GdkVisualType
+_gdk_broadway_screen_visual_get_best_type (GdkScreen * screen)
+{
+  return GDK_BROADWAY_SCREEN (screen)->available_types[0];
+}
+
+GdkVisual *
+_gdk_broadway_screen_get_system_visual (GdkScreen * screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+  return ((GdkVisual *) GDK_BROADWAY_SCREEN (screen)->system_visual);
+}
+
+GdkVisual*
+_gdk_broadway_screen_visual_get_best (GdkScreen * screen)
+{
+  GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (screen);
+
+  return (GdkVisual *)broadway_screen->visuals[0];
+}
+
+GdkVisual*
+_gdk_broadway_screen_visual_get_best_with_depth (GdkScreen * screen,
+                                                gint depth)
+{
+  GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (screen);
+  GdkVisual *return_val;
+  int i;
+
+  return_val = NULL;
+  for (i = 0; i < broadway_screen->nvisuals; i++)
+    if (depth == broadway_screen->visuals[i]->depth)
+      {
+       return_val = (GdkVisual *) broadway_screen->visuals[i];
+       break;
+      }
+
+  return return_val;
+}
+
+GdkVisual*
+_gdk_broadway_screen_visual_get_best_with_type (GdkScreen * screen,
+                                               GdkVisualType visual_type)
+{
+  GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (screen);
+  GdkVisual *return_val;
+  int i;
+
+  return_val = NULL;
+  for (i = 0; i < broadway_screen->nvisuals; i++)
+    if (visual_type == broadway_screen->visuals[i]->type)
+      {
+       return_val = (GdkVisual *) broadway_screen->visuals[i];
+       break;
+      }
+
+  return return_val;
+}
+
+GdkVisual*
+_gdk_broadway_screen_visual_get_best_with_both (GdkScreen * screen,
+                                               gint          depth,
+                                               GdkVisualType visual_type)
+{
+  GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (screen);
+  GdkVisual *return_val;
+  int i;
+
+  return_val = NULL;
+  for (i = 0; i < broadway_screen->nvisuals; i++)
+    if ((depth == broadway_screen->visuals[i]->depth) &&
+       (visual_type == broadway_screen->visuals[i]->type))
+      {
+       return_val = (GdkVisual *) broadway_screen->visuals[i];
+       break;
+      }
+
+  return return_val;
+}
+
+void
+_gdk_broadway_screen_query_depths  (GdkScreen * screen,
+                                   gint **depths,
+                                   gint  *count)
+{
+  GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (screen);
+
+  *count = broadway_screen->navailable_depths;
+  *depths = broadway_screen->available_depths;
+}
+
+void
+_gdk_broadway_screen_query_visual_types (GdkScreen * screen,
+                                        GdkVisualType **visual_types,
+                                        gint           *count)
+{
+  GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (screen);
+
+  *count = broadway_screen->navailable_types;
+  *visual_types = broadway_screen->available_types;
+}
+
+GList *
+_gdk_broadway_screen_list_visuals (GdkScreen *screen)
+{
+  GList *list;
+  GdkBroadwayScreen *broadway_screen;
+  guint i;
+
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+  broadway_screen = GDK_BROADWAY_SCREEN (screen);
+
+  list = NULL;
+
+  for (i = 0; i < broadway_screen->nvisuals; ++i)
+    list = g_list_append (list, broadway_screen->visuals[i]);
+
+  return list;
+}
+
+static void
+gdk_visual_decompose_mask (gulong  mask,
+                          gint   *shift,
+                          gint   *prec)
+{
+  *shift = 0;
+  *prec = 0;
+
+  if (mask == 0)
+    {
+      g_warning ("Mask is 0 in visual. Server bug ?");
+      return;
+    }
+
+  while (!(mask & 0x1))
+    {
+      (*shift)++;
+      mask >>= 1;
+    }
+
+  while (mask & 0x1)
+    {
+      (*prec)++;
+      mask >>= 1;
+    }
+}
diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c
new file mode 100644 (file)
index 0000000..438d953
--- /dev/null
@@ -0,0 +1,1390 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
+ * Josh MacDonald, Ryan Lortie
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "config.h"
+
+#include "gdkwindow-broadway.h"
+#include "gdkscreen-broadway.h"
+
+#include "gdkwindow.h"
+#include "gdkwindowimpl.h"
+#include "gdkdisplay-broadway.h"
+#include "gdkprivate-broadway.h"
+#include "gdkinternals.h"
+#include "gdkdeviceprivate.h"
+#include "gdkeventsource.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+/* Forward declarations */
+static void     gdk_window_broadway_set_background     (GdkWindow      *window,
+                                                   cairo_pattern_t *pattern);
+
+static void        gdk_window_impl_broadway_finalize   (GObject            *object);
+
+static const cairo_user_data_key_t gdk_broadway_cairo_key;
+
+#define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \
+  (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
+   GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
+
+#define WINDOW_IS_TOPLEVEL(window)                  \
+  (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
+   GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
+   GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
+
+struct _GdkBroadwayWindow {
+  GdkWindow parent;
+};
+
+struct _GdkBroadwayWindowClass {
+  GdkWindowClass parent_class;
+};
+
+G_DEFINE_TYPE (GdkBroadwayWindow, gdk_broadway_window, GDK_TYPE_WINDOW)
+
+static void
+gdk_broadway_window_class_init (GdkBroadwayWindowClass *broadway_window_class)
+{
+}
+
+static void
+gdk_broadway_window_init (GdkBroadwayWindow *broadway_window)
+{
+}
+
+G_DEFINE_TYPE (GdkWindowImplBroadway,
+              gdk_window_impl_broadway,
+              GDK_TYPE_WINDOW_IMPL)
+
+static void
+diff_surfaces (cairo_surface_t *surface,
+              cairo_surface_t *old_surface)
+{
+  guint8 *data, *old_data;
+  guint32 *line, *old_line;
+  int w, h, stride, old_stride;
+  int x, y;
+
+  data = cairo_image_surface_get_data (surface);
+  old_data = cairo_image_surface_get_data (old_surface);
+
+  w = cairo_image_surface_get_width (surface);
+  h = cairo_image_surface_get_height (surface);
+
+  stride = cairo_image_surface_get_stride (surface);
+  old_stride = cairo_image_surface_get_stride (old_surface);
+
+  for (y = 0; y < h; y++)
+    {
+      line = (guint32 *)data;
+      old_line = (guint32 *)old_data;
+
+      for (x = 0; x < w; x++)
+       {
+         if ((*line & 0xffffff) == (*old_line & 0xffffff))
+           *old_line = 0;
+         else
+           *old_line = *line | 0xff000000;
+         line ++;
+         old_line ++;
+       }
+
+      data += stride;
+      old_data += old_stride;
+    }
+}
+
+static guint dirty_flush_id = 0;
+
+static void
+window_data_send (BroadwayOutput *output, GdkWindowImplBroadway *impl)
+{
+  cairo_t *cr;
+
+  if (impl->surface == NULL)
+    return;
+
+  if (impl->last_synced)
+    {
+      diff_surfaces (impl->surface,
+                    impl->last_surface);
+      broadway_output_put_rgba (output, impl->id, 0, 0,
+                               cairo_image_surface_get_width (impl->last_surface),
+                               cairo_image_surface_get_height (impl->last_surface),
+                               cairo_image_surface_get_stride (impl->last_surface),
+                               cairo_image_surface_get_data (impl->last_surface));
+    }
+  else
+    {
+      impl->last_synced = TRUE;
+      broadway_output_put_rgb (output, impl->id, 0, 0,
+                              cairo_image_surface_get_width (impl->surface),
+                              cairo_image_surface_get_height (impl->surface),
+                              cairo_image_surface_get_stride (impl->surface),
+                              cairo_image_surface_get_data (impl->surface));
+    }
+
+  cr = cairo_create (impl->last_surface);
+  cairo_set_source_surface (cr, impl->surface, 0, 0);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+}
+
+static gboolean
+dirty_flush_idle (gpointer data)
+{
+  GList *l;
+  GdkBroadwayDisplay *display;
+  BroadwayOutput *output;
+
+  dirty_flush_id = 0;
+
+  display = GDK_BROADWAY_DISPLAY (gdk_display_get_default ());
+  output = display->output;
+  if (output == NULL)
+    return FALSE;
+
+  for (l = display->toplevels; l != NULL; l = l->next)
+    {
+      GdkWindowImplBroadway *impl = l->data;
+
+      if (impl->dirty)
+       {
+         impl->dirty = FALSE;
+         window_data_send (display->output, impl);
+       }
+    }
+
+  if (!broadway_output_flush (display->output))
+    {
+      broadway_output_free (display->output);
+      display->output = NULL;
+    }
+
+  return FALSE;
+}
+
+static void
+queue_dirty_flush (GdkBroadwayDisplay *display)
+{
+  if (dirty_flush_id == 0 && display->output != NULL)
+    dirty_flush_id = gdk_threads_add_idle (dirty_flush_idle, NULL);
+}
+
+void
+_gdk_broadway_resync_windows (void)
+{
+  GdkBroadwayDisplay *display;
+  GList *l;
+
+  dirty_flush_id = 0;
+
+  display = GDK_BROADWAY_DISPLAY (gdk_display_get_default ());
+
+  for (l = display->toplevels; l != NULL; l = l->next)
+    {
+      GdkWindowImplBroadway *impl = l->data;
+      GdkWindow *window;
+
+      window = impl->wrapper;
+
+      if (impl->id == 0)
+       continue; /* Skip root */
+
+      impl->dirty = FALSE;
+      impl->last_synced = FALSE;
+      broadway_output_new_surface (display->output,
+                                  impl->id,
+                                  window->x,
+                                  window->y,
+                                  window->width,
+                                  window->height);
+      if (GDK_WINDOW_IS_MAPPED (window))
+       {
+         broadway_output_show_surface (display->output, impl->id);
+         window_data_send (display->output, impl);
+       }
+    }
+
+  broadway_output_flush (display->output);
+}
+
+static void
+gdk_window_impl_broadway_init (GdkWindowImplBroadway *impl)
+{
+  impl->toplevel_window_type = -1;
+  impl->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
+                                               (GDestroyNotify) gdk_cursor_unref);
+}
+
+static void
+gdk_window_impl_broadway_finalize (GObject *object)
+{
+  GdkWindow *wrapper;
+  GdkWindowImplBroadway *impl;
+  GdkBroadwayDisplay *broadway_display;
+
+  g_return_if_fail (GDK_IS_WINDOW_IMPL_BROADWAY (object));
+
+  impl = GDK_WINDOW_IMPL_BROADWAY (object);
+
+  wrapper = impl->wrapper;
+
+  broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (impl->wrapper));
+
+  if (broadway_display->mouse_in_toplevel == GDK_WINDOW (wrapper))
+    {
+      /* TODO: Send leave + enter event, update cursors, etc */
+      broadway_display->mouse_in_toplevel = NULL;
+    }
+
+  g_hash_table_remove (broadway_display->id_ht, GINT_TO_POINTER(impl->id));
+
+  if (impl->cursor)
+    gdk_cursor_unref (impl->cursor);
+
+  g_hash_table_destroy (impl->device_cursor);
+
+  broadway_display->toplevels = g_list_remove (broadway_display->toplevels, impl);
+
+  G_OBJECT_CLASS (gdk_window_impl_broadway_parent_class)->finalize (object);
+}
+
+void
+_gdk_broadway_screen_init_root_window (GdkScreen * screen)
+{
+  GdkWindow *window;
+  GdkWindowImplBroadway *impl;
+  GdkBroadwayScreen *broadway_screen;
+
+  broadway_screen = GDK_BROADWAY_SCREEN (screen);
+
+  g_assert (broadway_screen->root_window == NULL);
+
+  broadway_screen->root_window = g_object_new (GDK_TYPE_BROADWAY_WINDOW, NULL);
+
+  window = broadway_screen->root_window;
+  window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_BROADWAY, NULL);
+  window->impl_window = window;
+  window->visual = gdk_screen_get_system_visual (screen);
+
+  impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+
+  impl->screen = screen;
+  impl->wrapper = window;
+
+  window->window_type = GDK_WINDOW_ROOT;
+  window->depth = 24;
+
+  window->x = 0;
+  window->y = 0;
+  window->abs_x = 0;
+  window->abs_y = 0;
+  window->width = gdk_screen_get_width (screen);
+  window->height = gdk_screen_get_height (screen);
+  window->viewable = TRUE;
+
+  _gdk_window_update_size (broadway_screen->root_window);
+}
+
+void
+_gdk_broadway_display_create_window_impl (GdkDisplay    *display,
+                                         GdkWindow     *window,
+                                         GdkWindow     *real_parent,
+                                         GdkScreen     *screen,
+                                         GdkEventMask   event_mask,
+                                         GdkWindowAttr *attributes,
+                                         gint           attributes_mask)
+{
+  GdkWindowImplBroadway *impl;
+  GdkBroadwayScreen *broadway_screen;
+  GdkBroadwayDisplay *broadway_display;
+  static int current_id = 1; /* 0 is the root window */
+
+  broadway_display = GDK_BROADWAY_DISPLAY (display);
+  broadway_screen = GDK_BROADWAY_SCREEN (screen);
+
+  impl = g_object_new (GDK_TYPE_WINDOW_IMPL_BROADWAY, NULL);
+  window->impl = (GdkWindowImpl *)impl;
+  impl->id = current_id++;
+  g_hash_table_insert (broadway_display->id_ht, GINT_TO_POINTER(impl->id), window);
+  impl->wrapper = window;
+
+  impl->screen = screen;
+
+  g_assert (window->window_type == GDK_WINDOW_TOPLEVEL ||
+           window->window_type == GDK_WINDOW_TEMP);
+  g_assert (GDK_WINDOW_TYPE (window->parent) == GDK_WINDOW_ROOT);
+
+  broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, impl);
+
+  /* Instead of window manager placement we have this mini hack
+     so that the main/first window is not covered in the demos. */
+  if (impl->id > 1 && window->window_type == GDK_WINDOW_TOPLEVEL)
+    {
+      window->x = 100;
+      window->y = 20;
+    }
+
+  if (broadway_display->output)
+    broadway_output_new_surface (broadway_display->output,
+                                impl->id,
+                                window->x,
+                                window->y,
+                                window->width,
+                                window->height);
+}
+
+static void
+resize_surface (GdkWindow *window)
+{
+  GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+  cairo_surface_t *old, *last_old;
+
+  if (impl->surface)
+    {
+      old = impl->surface;
+      last_old = impl->last_surface;
+
+      impl->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+                                                 gdk_window_get_width (impl->wrapper),
+                                                 gdk_window_get_height (impl->wrapper));
+      impl->last_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+                                                      gdk_window_get_width (impl->wrapper),
+                                                      gdk_window_get_height (impl->wrapper));
+
+      { cairo_t *cr;
+      cr = cairo_create (impl->surface);
+      cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+      cairo_rectangle (cr, 0, 0, 1000, 1000);
+      cairo_fill (cr);
+      cairo_destroy (cr);
+      }
+
+      cairo_surface_destroy (old);
+      cairo_surface_destroy (last_old);
+    }
+
+  if (impl->ref_surface)
+    {
+      cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
+                                  NULL, NULL);
+      impl->ref_surface = NULL;
+    }
+}
+
+static void
+ref_surface_destroyed (void *data)
+{
+  GdkWindowImplBroadway *impl = data;
+
+  impl->ref_surface = NULL;
+}
+
+static cairo_surface_t *
+gdk_window_broadway_ref_cairo_surface (GdkWindow *window)
+{
+  GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+  cairo_t *cr;
+  int w, h;
+
+  if (GDK_IS_WINDOW_IMPL_BROADWAY (window) &&
+      GDK_WINDOW_DESTROYED (impl->wrapper))
+    return NULL;
+
+  w = gdk_window_get_width (impl->wrapper);
+  h = gdk_window_get_height (impl->wrapper);
+
+  /* Create actual backing store if missing */
+  if (!impl->surface)
+    {
+      impl->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
+      impl->last_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
+
+      cr = cairo_create (impl->surface);
+      cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+      cairo_rectangle (cr, 0, 0, w, h);
+      cairo_fill (cr);
+      cairo_destroy (cr);
+
+      cr = cairo_create (impl->last_surface);
+      cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+      cairo_rectangle (cr, 0, 0, w, h);
+      cairo_fill (cr);
+      cairo_destroy (cr);
+    }
+
+  /* Create a destroyable surface referencing the real one */
+  if (!impl->ref_surface)
+    {
+      impl->ref_surface =
+       cairo_surface_create_for_rectangle (impl->surface,
+                                           0, 0,
+                                           w, h);
+      if (impl->ref_surface)
+       cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
+                                    impl, ref_surface_destroyed);
+    }
+  else
+    cairo_surface_reference (impl->ref_surface);
+
+  return impl->ref_surface;
+}
+
+static void
+_gdk_broadway_window_destroy (GdkWindow *window,
+                             gboolean   recursing,
+                             gboolean   foreign_destroy)
+{
+  GdkWindowImplBroadway *impl;
+  GdkBroadwayDisplay *broadway_display;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+
+  _gdk_broadway_selection_window_destroyed (window);
+
+  if (impl->ref_surface)
+    {
+      cairo_surface_finish (impl->ref_surface);
+      cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
+                                  NULL, NULL);
+    }
+
+  if (impl->surface)
+    {
+      cairo_surface_destroy (impl->surface);
+      impl->surface = NULL;
+      cairo_surface_destroy (impl->last_surface);
+      impl->last_surface = NULL;
+    }
+
+  broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
+  if (broadway_display->output)
+    broadway_output_destroy_surface (broadway_display->output,
+                                    impl->id);
+}
+
+static cairo_surface_t *
+gdk_window_broadway_resize_cairo_surface (GdkWindow       *window,
+                                         cairo_surface_t *surface,
+                                         gint             width,
+                                         gint             height)
+{
+  /* Image surfaces cannot be resized */
+  cairo_surface_destroy (surface);
+
+  return NULL;
+}
+
+static void
+gdk_broadway_window_destroy_foreign (GdkWindow *window)
+{
+}
+
+/* This function is called when the XWindow is really gone.
+ */
+static void
+gdk_broadway_window_destroy_notify (GdkWindow *window)
+{
+  GdkWindowImplBroadway *window_impl;
+
+  window_impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+
+  if (!GDK_WINDOW_DESTROYED (window))
+    {
+      if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
+       g_warning ("GdkWindow %p unexpectedly destroyed", window);
+
+      _gdk_window_destroy (window, TRUE);
+    }
+
+  g_object_unref (window);
+}
+
+static void
+gdk_window_broadway_show (GdkWindow *window, gboolean already_mapped)
+{
+  GdkWindowImplBroadway *impl;
+  GdkBroadwayDisplay *broadway_display;
+
+  impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+
+  if (window->event_mask & GDK_STRUCTURE_MASK)
+    _gdk_make_event (GDK_WINDOW (window), GDK_MAP, NULL, FALSE);
+
+  if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
+    _gdk_make_event (GDK_WINDOW (window), GDK_MAP, NULL, FALSE);
+
+  broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
+  if (broadway_display->output)
+    {
+      broadway_output_show_surface (broadway_display->output, impl->id);
+      queue_dirty_flush (broadway_display);
+    }
+}
+
+static void
+gdk_window_broadway_hide (GdkWindow *window)
+{
+  GdkWindowImplBroadway *impl;
+  GdkBroadwayDisplay *broadway_display;
+
+  impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+
+  if (window->event_mask & GDK_STRUCTURE_MASK)
+    _gdk_make_event (GDK_WINDOW (window), GDK_UNMAP, NULL, FALSE);
+
+  if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
+    _gdk_make_event (GDK_WINDOW (window), GDK_UNMAP, NULL, FALSE);
+
+  broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
+  if (broadway_display->output)
+    {
+      broadway_output_hide_surface (broadway_display->output, impl->id);
+      queue_dirty_flush (broadway_display);
+    }
+
+  if (broadway_display->mouse_in_toplevel == window)
+    {
+      /* TODO: Send leave + enter event, update cursors, etc */
+      broadway_display->mouse_in_toplevel = NULL;
+    }
+
+  _gdk_window_clear_update_area (window);
+}
+
+static void
+gdk_window_broadway_withdraw (GdkWindow *window)
+{
+  gdk_window_broadway_hide (window);
+}
+
+static void
+gdk_window_broadway_move_resize (GdkWindow *window,
+                                gboolean   with_move,
+                                gint       x,
+                                gint       y,
+                                gint       width,
+                                gint       height)
+{
+  GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+  GdkBroadwayDisplay *broadway_display;
+  gboolean changed;
+
+  changed = FALSE;
+
+  broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
+  if (with_move)
+    {
+      changed = TRUE;
+      window->x = x;
+      window->y = y;
+      if (broadway_display->output != NULL)
+       {
+         broadway_output_move_surface (broadway_display->output,
+                                       impl->id, x, y);
+         queue_dirty_flush (broadway_display);
+       }
+    }
+
+
+  if (width > 0 || height > 0)
+    {
+      if (width < 1)
+       width = 1;
+
+      if (height < 1)
+       height = 1;
+
+      if (width != window->width ||
+         height != window->height)
+       {
+         changed = TRUE;
+
+         /* Resize clears the content */
+         impl->dirty = TRUE;
+         impl->last_synced = FALSE;
+
+         broadway_output_resize_surface (broadway_display->output,
+                                         impl->id, width, height);
+         queue_dirty_flush (broadway_display);
+
+         window->width = width;
+         window->height = height;
+         resize_surface (window);
+         gdk_window_invalidate_rect (window, NULL, TRUE);
+       }
+    }
+
+  if (changed)
+    {
+      GdkEvent *event;
+      GList *node;
+
+      event = gdk_event_new (GDK_CONFIGURE);
+      event->configure.window = g_object_ref (window);
+      event->configure.x = window->x;
+      event->configure.y = window->y;
+      event->configure.width = window->width;
+      event->configure.height = window->height;
+
+      gdk_event_set_device (event, GDK_DISPLAY_OBJECT (broadway_display)->core_pointer);
+
+      node = _gdk_event_queue_append (GDK_DISPLAY_OBJECT (broadway_display), event);
+      _gdk_windowing_got_event (GDK_DISPLAY_OBJECT (broadway_display), node, event, 0);
+    }
+}
+
+static gboolean
+gdk_window_broadway_reparent (GdkWindow *window,
+                         GdkWindow *new_parent,
+                         gint       x,
+                         gint       y)
+{
+  return FALSE;
+}
+
+static void
+gdk_window_broadway_raise (GdkWindow *window)
+{
+}
+
+static void
+gdk_window_broadway_restack_under (GdkWindow *window,
+                             GList *native_siblings /* in requested order, first is bottom-most */)
+{
+}
+
+static void
+gdk_window_broadway_restack_toplevel (GdkWindow *window,
+                                GdkWindow *sibling,
+                                gboolean   above)
+{
+}
+
+static void
+gdk_window_broadway_lower (GdkWindow *window)
+{
+}
+
+
+static void
+gdk_broadway_window_focus (GdkWindow *window,
+                          guint32    timestamp)
+{
+}
+
+static void
+gdk_broadway_window_set_type_hint (GdkWindow        *window,
+                                  GdkWindowTypeHint hint)
+{
+}
+
+static GdkWindowTypeHint
+gdk_broadway_window_get_type_hint (GdkWindow *window)
+{
+  return GDK_WINDOW_TYPE_HINT_NORMAL;
+}
+
+static void
+gdk_broadway_window_set_modal_hint (GdkWindow *window,
+                                   gboolean   modal)
+{
+}
+
+static void
+gdk_broadway_window_set_skip_taskbar_hint (GdkWindow *window,
+                                          gboolean   skips_taskbar)
+{
+}
+
+static void
+gdk_broadway_window_set_skip_pager_hint (GdkWindow *window,
+                                        gboolean   skips_pager)
+{
+}
+
+static void
+gdk_broadway_window_set_urgency_hint (GdkWindow *window,
+                                     gboolean   urgent)
+{
+}
+
+static void
+gdk_broadway_window_set_geometry_hints (GdkWindow         *window,
+                                       const GdkGeometry *geometry,
+                                       GdkWindowHints     geom_mask)
+{
+}
+
+static void
+gdk_broadway_window_set_title (GdkWindow   *window,
+                              const gchar *title)
+{
+}
+
+static void
+gdk_broadway_window_set_role (GdkWindow   *window,
+                             const gchar *role)
+{
+}
+
+static void
+gdk_broadway_window_set_startup_id (GdkWindow   *window,
+                                   const gchar *startup_id)
+{
+}
+
+static void
+gdk_broadway_window_set_transient_for (GdkWindow *window,
+                                      GdkWindow *parent)
+{
+}
+
+static void
+gdk_window_broadway_set_background (GdkWindow      *window,
+                                   cairo_pattern_t *pattern)
+{
+  return;
+}
+
+static void
+gdk_window_broadway_set_device_cursor (GdkWindow *window,
+                                      GdkDevice *device,
+                                      GdkCursor *cursor)
+{
+  GdkWindowImplBroadway *impl;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DEVICE (device));
+
+  impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+
+  if (!cursor)
+    g_hash_table_remove (impl->device_cursor, device);
+  else
+    {
+      _gdk_broadway_cursor_update_theme (cursor);
+      g_hash_table_replace (impl->device_cursor,
+                            device, gdk_cursor_ref (cursor));
+    }
+
+  if (!GDK_WINDOW_DESTROYED (window))
+    GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
+}
+
+GdkCursor *
+_gdk_broadway_window_get_cursor (GdkWindow *window)
+{
+  GdkWindowImplBroadway *impl;
+
+  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+
+  impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+
+  return impl->cursor;
+}
+
+static void
+gdk_window_broadway_get_geometry (GdkWindow *window,
+                                 gint      *x,
+                                 gint      *y,
+                                 gint      *width,
+                                 gint      *height)
+{
+}
+
+static gint
+gdk_window_broadway_get_root_coords (GdkWindow *window,
+                               gint       x,
+                               gint       y,
+                               gint      *root_x,
+                               gint      *root_y)
+{
+  if (root_x)
+    *root_x = x;
+  if (root_y)
+    *root_y = y;
+
+  return 1;
+}
+
+static void
+gdk_broadway_window_get_root_origin (GdkWindow *window,
+                                    gint      *x,
+                                    gint      *y)
+{
+  if (x)
+    *x = 0;
+
+  if (y)
+    *y = 0;
+}
+
+static void
+gdk_broadway_window_get_frame_extents (GdkWindow    *window,
+                                      GdkRectangle *rect)
+{
+  g_return_if_fail (rect != NULL);
+
+  rect->x = window->x;
+  rect->y = window->y;
+  rect->width = window->width;
+  rect->height = window->height;
+}
+
+static gboolean
+gdk_window_broadway_get_device_state (GdkWindow       *window,
+                                     GdkDevice       *device,
+                                     gint            *x,
+                                     gint            *y,
+                                     GdkModifierType *mask)
+{
+  *x = 0;
+  *y = 0;
+  *mask = 0;
+  return FALSE;
+}
+
+static GdkEventMask
+gdk_window_broadway_get_events (GdkWindow *window)
+{
+  if (GDK_WINDOW_DESTROYED (window))
+    return 0;
+
+  return 0;
+}
+
+static void
+gdk_window_broadway_set_events (GdkWindow    *window,
+                               GdkEventMask  event_mask)
+{
+  if (!GDK_WINDOW_DESTROYED (window))
+    {
+    }
+}
+
+static void
+gdk_window_broadway_shape_combine_region (GdkWindow       *window,
+                                         const cairo_region_t *shape_region,
+                                         gint             offset_x,
+                                         gint             offset_y)
+{
+}
+
+static void
+gdk_window_broadway_input_shape_combine_region (GdkWindow       *window,
+                                               const cairo_region_t *shape_region,
+                                               gint             offset_x,
+                                               gint             offset_y)
+{
+}
+
+
+static void
+gdk_broadway_window_set_override_redirect (GdkWindow *window,
+                                          gboolean override_redirect)
+{
+}
+
+static void
+gdk_broadway_window_set_accept_focus (GdkWindow *window,
+                                     gboolean accept_focus)
+{
+  accept_focus = accept_focus != FALSE;
+
+  if (window->accept_focus != accept_focus)
+    {
+      window->accept_focus = accept_focus;
+    }
+}
+
+static void
+gdk_broadway_window_set_focus_on_map (GdkWindow *window,
+                                     gboolean focus_on_map)
+{
+  focus_on_map = focus_on_map != FALSE;
+
+  if (window->focus_on_map != focus_on_map)
+    {
+      window->focus_on_map = focus_on_map;
+    }
+}
+
+
+static void
+gdk_broadway_window_set_icon_list (GdkWindow *window,
+                                  GList     *pixbufs)
+{
+}
+
+static void
+gdk_broadway_window_set_icon_name (GdkWindow   *window, 
+                                  const gchar *name)
+{
+  GdkDisplay *display;
+
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+  display = gdk_window_get_display (window);
+
+  g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
+                      GUINT_TO_POINTER (name != NULL));
+}
+
+static void
+gdk_broadway_window_iconify (GdkWindow *window)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+}
+
+static void
+gdk_broadway_window_deiconify (GdkWindow *window)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+}
+
+static void
+gdk_broadway_window_stick (GdkWindow *window)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+}
+
+static void
+gdk_broadway_window_unstick (GdkWindow *window)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+}
+
+static void
+gdk_broadway_window_maximize (GdkWindow *window)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+}
+
+static void
+gdk_broadway_window_unmaximize (GdkWindow *window)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+}
+
+static void
+gdk_broadway_window_fullscreen (GdkWindow *window)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+}
+
+static void
+gdk_broadway_window_unfullscreen (GdkWindow *window)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+}
+
+static void
+gdk_broadway_window_set_keep_above (GdkWindow *window,
+                                   gboolean   setting)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+}
+
+static void
+gdk_broadway_window_set_keep_below (GdkWindow *window, gboolean setting)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+}
+
+static GdkWindow *
+gdk_broadway_window_get_group (GdkWindow *window)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL (window))
+    return NULL;
+
+  return window;
+}
+
+static void
+gdk_broadway_window_set_group (GdkWindow *window,
+                              GdkWindow *leader)
+{
+}
+
+static void
+gdk_broadway_window_set_decorations (GdkWindow      *window,
+                                    GdkWMDecoration decorations)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+}
+
+static gboolean
+gdk_broadway_window_get_decorations (GdkWindow       *window,
+                                    GdkWMDecoration *decorations)
+{
+  gboolean result = FALSE;
+
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return FALSE;
+
+  return result;
+}
+
+static void
+gdk_broadway_window_set_functions (GdkWindow    *window,
+                                  GdkWMFunction functions)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+}
+
+static cairo_region_t *
+gdk_broadway_window_get_shape (GdkWindow *window)
+{
+  return NULL;
+}
+
+static cairo_region_t *
+gdk_broadway_window_get_input_shape (GdkWindow *window)
+{
+  return NULL;
+}
+
+
+static gboolean
+gdk_window_broadway_set_static_gravities (GdkWindow *window,
+                                         gboolean   use_static)
+{
+  return TRUE;
+}
+
+static void
+gdk_broadway_window_begin_resize_drag (GdkWindow     *window,
+                              GdkWindowEdge  edge,
+                              gint           button,
+                              gint           root_x,
+                              gint           root_y,
+                              guint32        timestamp)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
+    return;
+
+}
+
+static void
+gdk_broadway_window_begin_move_drag (GdkWindow *window,
+                                    gint       button,
+                                    gint       root_x,
+                                    gint       root_y,
+                                    guint32    timestamp)
+{
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL (window))
+    return;
+
+}
+
+static void
+gdk_broadway_window_enable_synchronized_configure (GdkWindow *window)
+{
+  if (!GDK_IS_WINDOW_IMPL_BROADWAY (window->impl))
+    return;
+}
+
+static void
+gdk_broadway_window_configure_finished (GdkWindow *window)
+{
+  if (!WINDOW_IS_TOPLEVEL (window))
+    return;
+}
+
+static gboolean
+gdk_broadway_window_beep (GdkWindow *window)
+{
+  return FALSE;
+}
+
+static void
+gdk_broadway_window_set_opacity (GdkWindow *window,
+                                gdouble    opacity)
+{
+  GdkDisplay *display;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL (window))
+    return;
+
+  display = gdk_window_get_display (window);
+
+  if (opacity < 0)
+    opacity = 0;
+  else if (opacity > 1)
+    opacity = 1;
+
+}
+
+static void
+gdk_broadway_window_set_composited (GdkWindow *window,
+                                    gboolean   composited)
+{
+}
+
+static void
+gdk_broadway_window_process_updates_recurse (GdkWindow *window,
+                                            cairo_region_t *region)
+{
+  GdkWindowImplBroadway *impl;
+
+  _gdk_window_process_updates_recurse (window, region);
+
+  impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+  impl->dirty = TRUE;
+  queue_dirty_flush (GDK_BROADWAY_DISPLAY (gdk_window_get_display (window)));
+}
+
+void
+_gdk_broadway_display_before_process_all_updates (GdkDisplay *display)
+{
+}
+
+void
+_gdk_broadway_display_after_process_all_updates (GdkDisplay *display)
+{
+}
+
+gboolean
+_gdk_broadway_window_queue_antiexpose (GdkWindow *window,
+                                      cairo_region_t *area)
+{
+  return TRUE;
+}
+
+static void
+copy_region (cairo_surface_t *surface,
+            cairo_region_t *area,
+            gint            dx,
+            gint            dy)
+{
+  cairo_t *cr;
+
+  cr = cairo_create (surface);
+
+  gdk_cairo_region (cr, area);
+  cairo_clip (cr);
+
+  /* NB: This is a self-copy and Cairo doesn't support that yet.
+   * So we do a litle trick.
+   */
+  cairo_push_group (cr);
+
+  cairo_set_source_surface (cr, surface, dx, dy);
+  cairo_paint (cr);
+
+  cairo_pop_group_to_source (cr);
+  cairo_paint (cr);
+
+  cairo_destroy (cr);
+}
+
+void
+_gdk_broadway_window_translate (GdkWindow      *window,
+                               cairo_region_t *area,
+                               gint            dx,
+                               gint            dy)
+{
+  GdkWindowImplBroadway *impl;
+  GdkBroadwayDisplay *broadway_display;
+  int n_rects, i;
+  BroadwayRect *rects;
+  cairo_rectangle_int_t rect;
+
+  impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+
+  if (impl->surface)
+    {
+      copy_region (impl->surface, area, dx, dy);
+      if (GDK_WINDOW_IMPL_BROADWAY (impl)->last_synced)
+       {
+         copy_region (impl->last_surface, area, dx, dy);
+         n_rects = cairo_region_num_rectangles (area);
+         rects = g_new (BroadwayRect, n_rects);
+         for (i = 0; i < n_rects; i++)
+           {
+             cairo_region_get_rectangle (area, i, &rect);
+             rects[i].x = rect.x;
+             rects[i].y = rect.y;
+             rects[i].width = rect.width;
+             rects[i].height = rect.height;
+           }
+         broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
+         broadway_output_copy_rectangles (broadway_display->output,
+                                          GDK_WINDOW_IMPL_BROADWAY (impl)->id,
+                                          rects, n_rects, dx, dy);
+         queue_dirty_flush (broadway_display);
+         g_free (rects);
+       }
+    }
+}
+
+static void
+gdk_window_impl_broadway_class_init (GdkWindowImplBroadwayClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
+
+  object_class->finalize = gdk_window_impl_broadway_finalize;
+
+  impl_class->ref_cairo_surface = gdk_window_broadway_ref_cairo_surface;
+  impl_class->show = gdk_window_broadway_show;
+  impl_class->hide = gdk_window_broadway_hide;
+  impl_class->withdraw = gdk_window_broadway_withdraw;
+  impl_class->set_events = gdk_window_broadway_set_events;
+  impl_class->get_events = gdk_window_broadway_get_events;
+  impl_class->raise = gdk_window_broadway_raise;
+  impl_class->lower = gdk_window_broadway_lower;
+  impl_class->restack_under = gdk_window_broadway_restack_under;
+  impl_class->restack_toplevel = gdk_window_broadway_restack_toplevel;
+  impl_class->move_resize = gdk_window_broadway_move_resize;
+  impl_class->set_background = gdk_window_broadway_set_background;
+  impl_class->reparent = gdk_window_broadway_reparent;
+  impl_class->set_device_cursor = gdk_window_broadway_set_device_cursor;
+  impl_class->get_geometry = gdk_window_broadway_get_geometry;
+  impl_class->get_root_coords = gdk_window_broadway_get_root_coords;
+  impl_class->get_device_state = gdk_window_broadway_get_device_state;
+  impl_class->shape_combine_region = gdk_window_broadway_shape_combine_region;
+  impl_class->input_shape_combine_region = gdk_window_broadway_input_shape_combine_region;
+  impl_class->set_static_gravities = gdk_window_broadway_set_static_gravities;
+  impl_class->queue_antiexpose = _gdk_broadway_window_queue_antiexpose;
+  impl_class->translate = _gdk_broadway_window_translate;
+  impl_class->destroy = _gdk_broadway_window_destroy;
+  impl_class->destroy_foreign = gdk_broadway_window_destroy_foreign;
+  impl_class->resize_cairo_surface = gdk_window_broadway_resize_cairo_surface;
+  impl_class->get_shape = gdk_broadway_window_get_shape;
+  impl_class->get_input_shape = gdk_broadway_window_get_input_shape;
+  impl_class->beep = gdk_broadway_window_beep;
+
+  impl_class->focus = gdk_broadway_window_focus;
+  impl_class->set_type_hint = gdk_broadway_window_set_type_hint;
+  impl_class->get_type_hint = gdk_broadway_window_get_type_hint;
+  impl_class->set_modal_hint = gdk_broadway_window_set_modal_hint;
+  impl_class->set_skip_taskbar_hint = gdk_broadway_window_set_skip_taskbar_hint;
+  impl_class->set_skip_pager_hint = gdk_broadway_window_set_skip_pager_hint;
+  impl_class->set_urgency_hint = gdk_broadway_window_set_urgency_hint;
+  impl_class->set_geometry_hints = gdk_broadway_window_set_geometry_hints;
+  impl_class->set_title = gdk_broadway_window_set_title;
+  impl_class->set_role = gdk_broadway_window_set_role;
+  impl_class->set_startup_id = gdk_broadway_window_set_startup_id;
+  impl_class->set_transient_for = gdk_broadway_window_set_transient_for;
+  impl_class->get_root_origin = gdk_broadway_window_get_root_origin;
+  impl_class->get_frame_extents = gdk_broadway_window_get_frame_extents;
+  impl_class->set_override_redirect = gdk_broadway_window_set_override_redirect;
+  impl_class->set_accept_focus = gdk_broadway_window_set_accept_focus;
+  impl_class->set_focus_on_map = gdk_broadway_window_set_focus_on_map;
+  impl_class->set_icon_list = gdk_broadway_window_set_icon_list;
+  impl_class->set_icon_name = gdk_broadway_window_set_icon_name;
+  impl_class->iconify = gdk_broadway_window_iconify;
+  impl_class->deiconify = gdk_broadway_window_deiconify;
+  impl_class->stick = gdk_broadway_window_stick;
+  impl_class->unstick = gdk_broadway_window_unstick;
+  impl_class->maximize = gdk_broadway_window_maximize;
+  impl_class->unmaximize = gdk_broadway_window_unmaximize;
+  impl_class->fullscreen = gdk_broadway_window_fullscreen;
+  impl_class->unfullscreen = gdk_broadway_window_unfullscreen;
+  impl_class->set_keep_above = gdk_broadway_window_set_keep_above;
+  impl_class->set_keep_below = gdk_broadway_window_set_keep_below;
+  impl_class->get_group = gdk_broadway_window_get_group;
+  impl_class->set_group = gdk_broadway_window_set_group;
+  impl_class->set_decorations = gdk_broadway_window_set_decorations;
+  impl_class->get_decorations = gdk_broadway_window_get_decorations;
+  impl_class->set_functions = gdk_broadway_window_set_functions;
+  impl_class->set_functions = gdk_broadway_window_set_functions;
+  impl_class->begin_resize_drag = gdk_broadway_window_begin_resize_drag;
+  impl_class->begin_move_drag = gdk_broadway_window_begin_move_drag;
+  impl_class->enable_synchronized_configure = gdk_broadway_window_enable_synchronized_configure;
+  impl_class->configure_finished = gdk_broadway_window_configure_finished;
+  impl_class->set_opacity = gdk_broadway_window_set_opacity;
+  impl_class->set_composited = gdk_broadway_window_set_composited;
+  impl_class->destroy_notify = gdk_broadway_window_destroy_notify;
+  impl_class->register_dnd = _gdk_broadway_window_register_dnd;
+  impl_class->drag_begin = _gdk_broadway_window_drag_begin;
+  impl_class->process_updates_recurse = gdk_broadway_window_process_updates_recurse;
+  impl_class->sync_rendering = _gdk_broadway_window_sync_rendering;
+  impl_class->simulate_key = _gdk_broadway_window_simulate_key;
+  impl_class->simulate_button = _gdk_broadway_window_simulate_button;
+  impl_class->get_property = _gdk_broadway_window_get_property;
+  impl_class->change_property = _gdk_broadway_window_change_property;
+  impl_class->delete_property = _gdk_broadway_window_delete_property;
+}
diff --git a/gdk/broadway/gdkwindow-broadway.h b/gdk/broadway/gdkwindow-broadway.h
new file mode 100644 (file)
index 0000000..bed2c82
--- /dev/null
@@ -0,0 +1,77 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __GDK_WINDOW_BROADWAY_H__
+#define __GDK_WINDOW_BROADWAY_H__
+
+#include <gdk/gdkwindowimpl.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GdkWindowImplBroadway GdkWindowImplBroadway;
+typedef struct _GdkWindowImplBroadwayClass GdkWindowImplBroadwayClass;
+
+/* Window implementation for Broadway
+ */
+
+#define GDK_TYPE_WINDOW_IMPL_BROADWAY              (gdk_window_impl_broadway_get_type ())
+#define GDK_WINDOW_IMPL_BROADWAY(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL_BROADWAY, GdkWindowImplBroadway))
+#define GDK_WINDOW_IMPL_BROADWAY_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_BROADWAY, GdkWindowImplBroadwayClass))
+#define GDK_IS_WINDOW_IMPL_BROADWAY(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_IMPL_BROADWAY))
+#define GDK_IS_WINDOW_IMPL_BROADWAY_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_BROADWAY))
+#define GDK_WINDOW_IMPL_BROADWAY_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW_IMPL_BROADWAY, GdkWindowImplBroadwayClass))
+
+struct _GdkWindowImplBroadway
+{
+  GdkWindowImpl parent_instance;
+
+  GdkWindow *wrapper;
+  GdkScreen *screen;
+
+  cairo_surface_t *surface;
+  cairo_surface_t *last_surface;
+  cairo_surface_t *ref_surface;
+
+  GdkCursor *cursor;
+  GHashTable *device_cursor;
+
+  int id;
+
+  gint8 toplevel_window_type;
+  gboolean dirty;
+  gboolean last_synced;
+};
+
+struct _GdkWindowImplBroadwayClass
+{
+  GdkWindowImplClass parent_class;
+};
+
+GType gdk_window_impl_broadway_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GDK_WINDOW_BROADWAY_H__ */
diff --git a/gdk/broadway/toarray.pl b/gdk/broadway/toarray.pl
new file mode 100755 (executable)
index 0000000..e430885
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/bin/perl -w
+
+my $FILENAME = $ARGV[0];
+
+open FILE, $FILENAME or die "Cannot open $FILENAME";
+
+my $ARRAYNAME = $ARGV[1];
+print "static const char $ARRAYNAME\[\] =";
+while (<FILE>) {
+    s@\\@\\\\@g;
+    s@"@\\"@g;
+    chomp ($_);
+    print "\n  \"$_\\n\"";
+}
+print ";\n";
index 508d60910b7abe5284c05800fdcd93270d7ef2fd..43dff5b68bd66eec2b0df20feca076f289a959ab 100644 (file)
 #include "quartz/gdkquartzdisplaymanager.h"
 #endif
 
+#ifdef GDK_WINDOWING_BROADWAY
+#include "broadway/gdkbroadwaydisplaymanager.h"
+#endif
+
 #ifdef GDK_WINDOWING_WIN32
 #include "win32/gdkwin32.h"
 #endif
@@ -239,6 +243,11 @@ gdk_display_manager_get (void)
       if (backend == NULL || strcmp (backend, "win32") == 0)
         manager = g_object_new (gdk_win32_display_manager_get_type (), NULL);
       else
+#endif
+#ifdef GDK_WINDOWING_BROADWAY
+      if (backend == NULL || strcmp (backend, "broadway") == 0)
+        manager = g_object_new (gdk_broadway_display_manager_get_type (), NULL);
+      else
 #endif
       if (backend != NULL)
         g_error ("Unsupported GDK backend: %s", backend);
index 510d6ffdbe8e0b94c76d29f82b179d94ccc9f4d3..84faa146729f0e4dcdb47535044b4c18206b3cd5 100644 (file)
@@ -280,6 +280,8 @@ create_child_plug (guint32  xid,
     return GDK_WINDOW_XID (gtk_widget_get_window (window));
 #elif defined (GDK_WINDOWING_WIN32)
     return (guint32) GDK_WINDOW_HWND (gtk_widget_get_window (window));
+#elif defined (GDK_WINDOWING_BROADWAY)
+    return (guint32) 0; /* Child windows not supported */
 #endif
   else
     return 0;