From f11a7d2fde1e7872ac52c5a22e2b2bbdf3851f6b Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 18 Nov 2010 22:21:16 +0100 Subject: [PATCH] Don't put output on stdin, instead do it on http connection --- gdk/broadway/broadway.c | 1 + gdk/broadway/broadway.js | 9 +- gdk/broadway/client.html | 2 +- gdk/broadway/gdkdisplay-broadway.c | 47 ++++++++- gdk/broadway/gdkdisplay-broadway.h | 2 +- gdk/broadway/gdkprivate-broadway.h | 2 + gdk/broadway/gdkwindow-broadway.c | 154 ++++++++++++++++++++--------- 7 files changed, 155 insertions(+), 62 deletions(-) diff --git a/gdk/broadway/broadway.c b/gdk/broadway/broadway.c index 9d4fb35871..6996f8f9a8 100644 --- a/gdk/broadway/broadway.c +++ b/gdk/broadway/broadway.c @@ -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"; diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js index de1ac3f0e7..0d5749f638 100644 --- a/gdk/broadway/broadway.js +++ b/gdk/broadway/broadway.js @@ -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); -} diff --git a/gdk/broadway/client.html b/gdk/broadway/client.html index 0bd4a7f058..e74cdd9992 100644 --- a/gdk/broadway/client.html +++ b/gdk/broadway/client.html @@ -6,6 +6,6 @@ - + diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c index b2a15f5cc7..b31cdc2b65 100644 --- a/gdk/broadway/gdkdisplay-broadway.c +++ b/gdk/broadway/gdkdisplay-broadway.c @@ -138,6 +138,44 @@ http_request_free (HttpRequest *request) g_free (request); } +#include +#include +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); diff --git a/gdk/broadway/gdkdisplay-broadway.h b/gdk/broadway/gdkdisplay-broadway.h index 3317b5bce6..ec37e51e6d 100644 --- a/gdk/broadway/gdkdisplay-broadway.h +++ b/gdk/broadway/gdkdisplay-broadway.h @@ -75,7 +75,7 @@ struct _GdkDisplayBroadway GdkWindow *active_offscreen_window; GSocketService *service; - BroadwayClient *connection; + BroadwayClient *output; }; struct _GdkDisplayBroadwayClass diff --git a/gdk/broadway/gdkprivate-broadway.h b/gdk/broadway/gdkprivate-broadway.h index b91d716c51..49ed8032ef 100644 --- a/gdk/broadway/gdkprivate-broadway.h +++ b/gdk/broadway/gdkprivate-broadway.h @@ -40,6 +40,8 @@ typedef struct _GdkCursorPrivate GdkCursorPrivate; +void _gdk_broadway_resync_windows (void); + struct _GdkCursorPrivate { GdkCursor cursor; diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c index b72101430e..92e28eb1d9 100644 --- a/gdk/broadway/gdkwindow-broadway.c +++ b/gdk/broadway/gdkwindow-broadway.c @@ -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); } }