]> Pileus Git - ~andy/gtk/commitdiff
Don't put output on stdin, instead do it on http connection
authorAlexander Larsson <alexl@redhat.com>
Thu, 18 Nov 2010 21:21:16 +0000 (22:21 +0100)
committerAlexander Larsson <alexl@redhat.com>
Thu, 25 Nov 2010 21:09:29 +0000 (22:09 +0100)
gdk/broadway/broadway.c
gdk/broadway/broadway.js
gdk/broadway/client.html
gdk/broadway/gdkdisplay-broadway.c
gdk/broadway/gdkdisplay-broadway.h
gdk/broadway/gdkprivate-broadway.h
gdk/broadway/gdkwindow-broadway.c

index 9d4fb35871e8f13faf5705fc5b8399a145887d20..6996f8f9a814b536db2db568b0e7d23d7fce2b3d 100644 (file)
@@ -670,6 +670,7 @@ broadway_client_write_header (BroadwayClient *client)
   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";
index de1ac3f0e776c02601f68af456600026872c3631..0d5749f638afb77a1880a72f96d1e5c9f04f1c4e 100644 (file)
@@ -280,7 +280,7 @@ function handleLoad(event)
   }
 }
 
-function connect(app)
+function connect()
 {
   var xhr = createXHR();
   if (xhr) {
@@ -290,13 +290,8 @@ function connect(app)
     }
 
     xhr.multipart = true;
-    xhr.open("GET", "/cgi-bin/" + app, true);
+    xhr.open("GET", "/output", true);
     xhr.onload = handleLoad;
     xhr.send(null);
   }
 }
-
-function startClient(app)
-{
-  connect(app);
-}
index 0bd4a7f058b8bafcc2b22840d77949223b7c273a..e74cdd999203adc67626dbbe6ee4d4184c6d08a3 100644 (file)
@@ -6,6 +6,6 @@
 <script type="text/javascript" src="broadway.js"></script>
 </head>
 
-<body onload="startClient('broadway')">
+<body onload="connect()">
 </body>
 </html>
index b2a15f5cc729f477dc8df0d2ad8f0eb5685bbf17..b31cdc2b65b6ee8a919c0c12863d7da8c0e2bb34 100644 (file)
@@ -138,6 +138,44 @@ http_request_free (HttpRequest *request)
   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 void
+start_output (HttpRequest *request)
+{
+  GSocket *socket;
+  GdkDisplayBroadway *display_broadway;
+  int fd;
+
+  g_print ("start_output\n");
+
+  socket = g_socket_connection_get_socket (request->connection);
+
+  display_broadway = GDK_DISPLAY_BROADWAY (request->display);
+  fd = g_socket_get_fd (socket);
+  set_fd_blocking (fd);
+  display_broadway->output = broadway_client_new (fd);
+  _gdk_broadway_resync_windows ();
+
+  /* TODO: This leaks the connection since we just keep the fd,
+     we want to avoid using the fd at all here */
+  g_object_ref (request->connection);
+  http_request_free (request);
+}
+
 static void
 send_error (HttpRequest *request,
            int error_code,
@@ -216,6 +254,8 @@ got_request (HttpRequest *request)
     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
     send_error (request, 404, "File not found");
 }
@@ -269,6 +309,7 @@ handle_incoming_connection (GSocketService    *service,
   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);
 
@@ -283,16 +324,12 @@ gdk_display_open (const gchar *display_name)
   GdkDisplay *display;
   GdkDisplayBroadway *display_broadway;
   const char *sm_client_id;
-  int fd;
   GError *error;
 
-  fd = dup(STDOUT_FILENO);
-  dup2(STDERR_FILENO, STDOUT_FILENO);
-
   display = g_object_new (GDK_TYPE_DISPLAY_BROADWAY, NULL);
   display_broadway = GDK_DISPLAY_BROADWAY (display);
 
-  display_broadway->connection = broadway_client_new (fd);
+  display_broadway->output = NULL;
 
   /* initialize the display's screens */
   display_broadway->screens = g_new (GdkScreen *, 1);
index 3317b5bce636dce7837e4f0b44240f8cbfc5d983..ec37e51e6d72a5b1fadc0a92d45ce99556494a34 100644 (file)
@@ -75,7 +75,7 @@ struct _GdkDisplayBroadway
   GdkWindow *active_offscreen_window;
 
   GSocketService *service;
-  BroadwayClient *connection;
+  BroadwayClient *output;
 };
 
 struct _GdkDisplayBroadwayClass
index b91d716c51aa6a194fca8bd825cf94024af79ca3..49ed8032ef1716144fed940114868c677208b23b 100644 (file)
@@ -40,6 +40,8 @@
 
 typedef struct _GdkCursorPrivate       GdkCursorPrivate;
 
+void _gdk_broadway_resync_windows (void);
+
 struct _GdkCursorPrivate
 {
   GdkCursor cursor;
index b72101430efbd827894faa1daeea6cb057d2ffd5..92e28eb1d950b15e61ee76f10be1569db120ab77 100644 (file)
@@ -121,6 +121,38 @@ diff_surfaces (cairo_surface_t *surface,
 
 static guint dirty_flush_id = 0;
 
+static void
+window_data_send (BroadwayClient *client, GdkWindowImplBroadway *impl)
+{
+  GdkDrawableImplBroadway *drawable_impl = GDK_DRAWABLE_IMPL_BROADWAY (impl);
+  cairo_t *cr;
+
+  if (impl->last_synced)
+    {
+      diff_surfaces (drawable_impl->surface,
+                    drawable_impl->last_surface);
+      broadway_client_put_delta_rgb (client, impl->id, 0, 0,
+                                    cairo_image_surface_get_width (drawable_impl->last_surface),
+                                    cairo_image_surface_get_height (drawable_impl->last_surface),
+                                    cairo_image_surface_get_stride (drawable_impl->last_surface),
+                                    cairo_image_surface_get_data (drawable_impl->last_surface));
+    }
+  else
+    {
+      impl->last_synced = TRUE;
+      broadway_client_put_rgb (client, impl->id, 0, 0,
+                              cairo_image_surface_get_width (drawable_impl->surface),
+                              cairo_image_surface_get_height (drawable_impl->surface),
+                              cairo_image_surface_get_stride (drawable_impl->surface),
+                              cairo_image_surface_get_data (drawable_impl->surface));
+    }
+
+  cr = cairo_create (drawable_impl->last_surface);
+  cairo_set_source_surface (cr, drawable_impl->surface, 0, 0);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+}
+
 static gboolean
 dirty_flush_idle (gpointer data)
 {
@@ -128,60 +160,78 @@ dirty_flush_idle (gpointer data)
   GdkDisplayBroadway *display;
   BroadwayClient *client;
 
-  display = GDK_DISPLAY_BROADWAY (gdk_display_get_default ());
-  client = display->connection;
-
   dirty_flush_id = 0;
 
+  display = GDK_DISPLAY_BROADWAY (gdk_display_get_default ());
+  client = display->output;
+  if (client == NULL)
+    return FALSE;
+
   for (l = all_windows; l != NULL; l = l->next)
     {
       GdkWindowImplBroadway *impl = l->data;
-      GdkDrawableImplBroadway *drawable_impl = GDK_DRAWABLE_IMPL_BROADWAY (impl);
-      cairo_t *cr;
 
       if (impl->dirty)
        {
          impl->dirty = FALSE;
-
-         if (impl->last_synced)
-           {
-             diff_surfaces (drawable_impl->surface,
-                            drawable_impl->last_surface);
-             broadway_client_put_delta_rgb (client, impl->id, 0, 0,
-                                            cairo_image_surface_get_width (drawable_impl->last_surface),
-                                            cairo_image_surface_get_height (drawable_impl->last_surface),
-                                            cairo_image_surface_get_stride (drawable_impl->last_surface),
-                                            cairo_image_surface_get_data (drawable_impl->last_surface));
-           }
-         else
-           {
-             impl->last_synced = TRUE;
-             broadway_client_put_rgb (client, impl->id, 0, 0,
-                                      cairo_image_surface_get_width (drawable_impl->surface),
-                                      cairo_image_surface_get_height (drawable_impl->surface),
-                                      cairo_image_surface_get_stride (drawable_impl->surface),
-                                      cairo_image_surface_get_data (drawable_impl->surface));
-           }
-
-         cr = cairo_create (drawable_impl->last_surface);
-         cairo_set_source_surface (cr, drawable_impl->surface, 0, 0);
-         cairo_paint (cr);
-         cairo_destroy (cr);
+         window_data_send (display->output, impl);
        }
     }
 
-  broadway_client_flush (display->connection);
+  broadway_client_flush (client);
 
   return FALSE;
 }
 
 static void
-queue_dirty_flush (void)
+queue_dirty_flush (GdkDisplayBroadway *display)
 {
-  if (dirty_flush_id == 0)
+  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)
+{
+  GdkDisplayBroadway *display;
+  GList *l;
+
+  dirty_flush_id = 0;
+
+  display = GDK_DISPLAY_BROADWAY (gdk_display_get_default ());
+
+  for (l = all_windows; l != NULL; l = l->next)
+    {
+      GdkWindowImplBroadway *impl = l->data;
+      GdkWindowObject *private;
+
+      private = (GdkWindowObject*) GDK_DRAWABLE_IMPL_BROADWAY (impl)->wrapper;
+
+      impl->dirty = FALSE;
+      impl->last_synced = FALSE;
+      g_print ("creating new window %d at %d,%d %dx%d\n",
+              impl->id,
+              private->x,
+              private->y,
+              private->width,
+              private->height);
+      broadway_client_new_surface (display->output,
+                                  impl->id,
+                                  private->x,
+                                  private->y,
+                                  private->width,
+                                  private->height);
+      if (GDK_WINDOW_IS_MAPPED (private))
+       {
+         g_print ("showing window\n");
+         broadway_client_show_surface (display->output, impl->id);
+         g_print ("sending window data\n");
+         window_data_send (display->output, impl);
+       }
+    }
+
+  broadway_client_flush (display->output);
+}
 
 static void
 gdk_window_impl_broadway_init (GdkWindowImplBroadway *impl)
@@ -294,12 +344,13 @@ _gdk_window_impl_new (GdkWindow     *window,
            private->window_type == GDK_WINDOW_TEMP);
   g_assert (GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_ROOT);
 
-  broadway_client_new_surface (display_broadway->connection,
-                              impl->id,
-                              private->x,
-                              private->y,
-                              private->width,
-                              private->height);
+  if (display_broadway->output)
+    broadway_client_new_surface (display_broadway->output,
+                                impl->id,
+                                private->x,
+                                private->y,
+                                private->width,
+                                private->height);
 }
 
 
@@ -341,8 +392,9 @@ _gdk_broadway_window_destroy (GdkWindow *window,
   _gdk_broadway_drawable_finish (private->impl);
 
   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
-  broadway_client_destroy_surface (display_broadway->connection,
-                                  impl->id);
+  if (display_broadway->output)
+    broadway_client_destroy_surface (display_broadway->output,
+                                    impl->id);
 }
 
 static cairo_surface_t *
@@ -399,8 +451,11 @@ gdk_window_broadway_show (GdkWindow *window, gboolean already_mapped)
     _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
 
   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
-  broadway_client_show_surface (display_broadway->connection, impl->id);
-  queue_dirty_flush ();
+  if (display_broadway->output)
+    {
+      broadway_client_show_surface (display_broadway->output, impl->id);
+      queue_dirty_flush (display_broadway);
+    }
 }
 
 static void
@@ -420,8 +475,11 @@ gdk_window_broadway_hide (GdkWindow *window)
     _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
 
   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
-  broadway_client_hide_surface (display_broadway->connection, impl->id);
-  queue_dirty_flush ();
+  if (display_broadway->output)
+    {
+      broadway_client_hide_surface (display_broadway->output, impl->id);
+      queue_dirty_flush (display_broadway);
+    }
 
   _gdk_window_clear_update_area (window);
 }
@@ -1134,7 +1192,7 @@ _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
   private = (GdkWindowObject *)window;
   impl = GDK_WINDOW_IMPL_BROADWAY (private->impl);
   impl->dirty = TRUE;
-  queue_dirty_flush ();
+  queue_dirty_flush (GDK_DISPLAY_BROADWAY (gdk_window_get_display (window)));
 }
 
 void
@@ -1216,10 +1274,10 @@ _gdk_broadway_window_translate (GdkWindow      *window,
              rects[i].height = rect.height;
            }
          display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
-         broadway_client_copy_rectangles (display_broadway->connection,
+         broadway_client_copy_rectangles (display_broadway->output,
                                           GDK_WINDOW_IMPL_BROADWAY (impl)->id,
                                           rects, n_rects, dx, dy);
-         queue_dirty_flush ();
+         queue_dirty_flush (display_broadway);
          g_free (rects);
        }
     }