forked from AuroraMiddleware/gtk
broadway: Use binary websockets if available
This commit is contained in:
parent
86bcd1c22c
commit
db374a0a87
@ -57,6 +57,42 @@ base64_uint32 (guint32 v, char *c)
|
||||
* conversion of raw image data to png data: uris *
|
||||
***********************************************************/
|
||||
|
||||
static cairo_status_t
|
||||
write_png_data (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int data_len)
|
||||
{
|
||||
GString *buf = closure;
|
||||
|
||||
g_string_append_len (buf, (char *)data, data_len);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
to_png_rgb (GString *buf, int w, int h, int byte_stride, guint32 *data)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = cairo_image_surface_create_for_data ((guchar *)data,
|
||||
CAIRO_FORMAT_RGB24, w, h, byte_stride);
|
||||
|
||||
cairo_surface_write_to_png_stream (surface, write_png_data, buf);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
to_png_rgba (GString *buf, int w, int h, int byte_stride, guint32 *data)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = cairo_image_surface_create_for_data ((guchar *)data,
|
||||
CAIRO_FORMAT_ARGB32, w, h, byte_stride);
|
||||
|
||||
cairo_surface_write_to_png_stream (surface, write_png_data, buf);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
struct PngTarget {
|
||||
GString *buf;
|
||||
int state;
|
||||
@ -101,6 +137,7 @@ to_png_url_rgb (GString *buf, int w, int h, int byte_stride, guint32 *data)
|
||||
CAIRO_FORMAT_RGB24, w, h, byte_stride);
|
||||
|
||||
cairo_surface_write_to_png_stream (surface, write_png_url, &target);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
old_len = buf->len;
|
||||
|
||||
@ -128,6 +165,7 @@ to_png_url_rgba (GString *buf, int w, int h, int byte_stride, guint32 *data)
|
||||
CAIRO_FORMAT_ARGB32, w, h, byte_stride);
|
||||
|
||||
cairo_surface_write_to_png_stream (surface, write_png_url, &target);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
old_len = buf->len;
|
||||
|
||||
@ -177,6 +215,7 @@ struct BroadwayOutput {
|
||||
int error;
|
||||
guint32 serial;
|
||||
gboolean proto_v7_plus;
|
||||
gboolean binary;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -235,6 +274,9 @@ broadway_output_flush (BroadwayOutput *output)
|
||||
|
||||
if (!output->proto_v7_plus)
|
||||
broadway_output_send_cmd_pre_v7 (output, output->buf->str, output->buf->len);
|
||||
else if (output->binary)
|
||||
broadway_output_send_cmd (output, TRUE, BROADWAY_WS_BINARY,
|
||||
output->buf->str, output->buf->len);
|
||||
else
|
||||
broadway_output_send_cmd (output, TRUE, BROADWAY_WS_TEXT,
|
||||
output->buf->str, output->buf->len);
|
||||
@ -247,7 +289,7 @@ broadway_output_flush (BroadwayOutput *output)
|
||||
|
||||
BroadwayOutput *
|
||||
broadway_output_new (GOutputStream *out, guint32 serial,
|
||||
gboolean proto_v7_plus)
|
||||
gboolean proto_v7_plus, gboolean binary)
|
||||
{
|
||||
BroadwayOutput *output;
|
||||
|
||||
@ -257,6 +299,7 @@ broadway_output_new (GOutputStream *out, guint32 serial,
|
||||
output->buf = g_string_new ("");
|
||||
output->serial = serial;
|
||||
output->proto_v7_plus = proto_v7_plus;
|
||||
output->binary = binary;
|
||||
|
||||
return output;
|
||||
}
|
||||
@ -288,12 +331,18 @@ append_char (BroadwayOutput *output, char c)
|
||||
static void
|
||||
append_bool (BroadwayOutput *output, gboolean val)
|
||||
{
|
||||
if (output->binary)
|
||||
g_string_append_c (output->buf, val ? 1: 0);
|
||||
else
|
||||
g_string_append_c (output->buf, val ? '1': '0');
|
||||
}
|
||||
|
||||
static void
|
||||
append_flags (BroadwayOutput *output, guint32 val)
|
||||
{
|
||||
if (output->binary)
|
||||
g_string_append_c (output->buf, val);
|
||||
else
|
||||
g_string_append_c (output->buf, val + '0');
|
||||
}
|
||||
|
||||
@ -302,23 +351,61 @@ static void
|
||||
append_uint16 (BroadwayOutput *output, guint32 v)
|
||||
{
|
||||
gsize old_len = output->buf->len;
|
||||
|
||||
if (output->binary)
|
||||
{
|
||||
guint8 *buf = (guint8 *)output->buf->str + old_len;
|
||||
|
||||
g_string_set_size (output->buf, old_len + 2);
|
||||
buf[0] = (v >> 0) & 0xff;
|
||||
buf[1] = (v >> 8) & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_set_size (output->buf, old_len + 3);
|
||||
base64_uint16 (v, output->buf->str + old_len);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
append_uint32 (BroadwayOutput *output, guint32 v)
|
||||
{
|
||||
gsize old_len = output->buf->len;
|
||||
|
||||
if (output->binary)
|
||||
{
|
||||
guint8 *buf = (guint8 *)output->buf->str + old_len;
|
||||
|
||||
g_string_set_size (output->buf, old_len + 4);
|
||||
buf[0] = (v >> 0) & 0xff;
|
||||
buf[1] = (v >> 8) & 0xff;
|
||||
buf[2] = (v >> 16) & 0xff;
|
||||
buf[3] = (v >> 24) & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_set_size (output->buf, old_len + 6);
|
||||
base64_uint32 (v, output->buf->str + old_len);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
overwrite_uint32 (BroadwayOutput *output, gsize pos, guint32 v)
|
||||
{
|
||||
if (output->binary)
|
||||
{
|
||||
guint8 *buf = (guint8 *)output->buf->str + pos;
|
||||
|
||||
buf[0] = (v >> 0) & 0xff;
|
||||
buf[1] = (v >> 8) & 0xff;
|
||||
buf[2] = (v >> 16) & 0xff;
|
||||
buf[3] = (v >> 24) & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
base64_uint32 (v, output->buf->str + pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
@ -464,6 +551,9 @@ broadway_output_put_rgb (BroadwayOutput *output, int id, int x, int y,
|
||||
append_uint32 (output, 0);
|
||||
|
||||
image_start = output->buf->len;
|
||||
if (output->binary)
|
||||
to_png_rgb (output->buf, w, h, byte_stride, (guint32*)data);
|
||||
else
|
||||
to_png_url_rgb (output->buf, w, h, byte_stride, (guint32*)data);
|
||||
|
||||
len = output->buf->len - image_start;
|
||||
@ -719,6 +809,11 @@ broadway_output_put_rgba (BroadwayOutput *output, int id, int x, int y,
|
||||
image_start = output->buf->len;
|
||||
|
||||
subdata = (guint8 *)data + rects[i].x1 * 4 + rects[i].y1 * byte_stride;
|
||||
if (output->binary)
|
||||
to_png_rgba (output->buf, rects[i].x2 - rects[i].x1,
|
||||
rects[i].y2 - rects[i].y1,
|
||||
byte_stride, (guint32*)subdata);
|
||||
else
|
||||
to_png_url_rgba (output->buf, rects[i].x2 - rects[i].x1,
|
||||
rects[i].y2 - rects[i].y1,
|
||||
byte_stride, (guint32*)subdata);
|
||||
|
@ -19,7 +19,8 @@ typedef enum {
|
||||
|
||||
BroadwayOutput *broadway_output_new (GOutputStream *out,
|
||||
guint32 serial,
|
||||
gboolean proto_v7_plus);
|
||||
gboolean proto_v7_plus,
|
||||
gboolean binary);
|
||||
void broadway_output_free (BroadwayOutput *output);
|
||||
int broadway_output_flush (BroadwayOutput *output);
|
||||
int broadway_output_has_error (BroadwayOutput *output);
|
||||
|
@ -790,9 +790,10 @@ function handleCommands(cmd)
|
||||
q.img.src = url;
|
||||
surfaces[q.id].drawQueue.push(q);
|
||||
if (!q.img.complete) {
|
||||
q.img.onload = function() { handleOutstanding(); };
|
||||
q.img.onload = function() { cmd.free_image_url (url); handleOutstanding(); };
|
||||
return false;
|
||||
}
|
||||
cmd.free_image_url (url);
|
||||
break;
|
||||
|
||||
case 'b': // Copy rects
|
||||
@ -886,10 +887,66 @@ TextCommands.prototype.get_image_url = function() {
|
||||
this.pos = this.pos + size;
|
||||
return url;
|
||||
};
|
||||
TextCommands.prototype.free_image_url = function(url) {
|
||||
};
|
||||
|
||||
function BinCommands(message) {
|
||||
this.arraybuffer = message;
|
||||
this.u8 = new Uint8Array(message);
|
||||
this.length = this.u8.length;
|
||||
this.pos = 0;
|
||||
}
|
||||
|
||||
BinCommands.prototype.get_char = function() {
|
||||
return String.fromCharCode(this.u8[this.pos++]);
|
||||
};
|
||||
BinCommands.prototype.get_bool = function() {
|
||||
return this.u8[this.pos++] != 0;
|
||||
};
|
||||
BinCommands.prototype.get_flags = function() {
|
||||
return this.u8[this.pos++];
|
||||
}
|
||||
BinCommands.prototype.get_16 = function() {
|
||||
var v =
|
||||
this.u8[this.pos] +
|
||||
(this.u8[this.pos+1] << 8);
|
||||
this.pos = this.pos + 2;
|
||||
return v;
|
||||
};
|
||||
BinCommands.prototype.get_16s = function() {
|
||||
var v = this.get_16 ();
|
||||
if (v > 32767)
|
||||
return v - 65536;
|
||||
else
|
||||
return v;
|
||||
};
|
||||
BinCommands.prototype.get_32 = function() {
|
||||
var v =
|
||||
this.u8[this.pos] +
|
||||
(this.u8[this.pos+1] << 8) +
|
||||
(this.u8[this.pos+2] << 16) +
|
||||
(this.u8[this.pos+3] << 24);
|
||||
this.pos = this.pos + 4;
|
||||
return v;
|
||||
};
|
||||
BinCommands.prototype.get_image_url = function() {
|
||||
var size = this.get_32();
|
||||
var png_blob = new Blob ([this.arraybuffer.slice (this.pos, this.pos + size)], {type:"image/png"});
|
||||
var url = URL.createObjectURL(png_blob, {oneTimeOnly: true});
|
||||
this.pos = this.pos + size;
|
||||
return url;
|
||||
};
|
||||
BinCommands.prototype.free_image_url = function(url) {
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
|
||||
function handleMessage(message)
|
||||
{
|
||||
var cmd = new TextCommands(message);
|
||||
var cmd;
|
||||
if (message instanceof ArrayBuffer)
|
||||
cmd = new BinCommands(message);
|
||||
else
|
||||
cmd = new TextCommands(message);
|
||||
outstandingCommands.push(cmd);
|
||||
if (outstandingCommands.length == 1) {
|
||||
handleOutstanding();
|
||||
|
@ -130,7 +130,7 @@ typedef struct HttpRequest {
|
||||
GString *request;
|
||||
} HttpRequest;
|
||||
|
||||
static void start_output (HttpRequest *request, gboolean proto_v7_plus);
|
||||
static void start_output (HttpRequest *request, gboolean proto_v7_plus, gboolean binary);
|
||||
|
||||
static void
|
||||
http_request_free (HttpRequest *request)
|
||||
@ -876,7 +876,7 @@ start_input (HttpRequest *request, gboolean binary)
|
||||
|
||||
broadway_display->input = input;
|
||||
|
||||
start_output (request, proto_v7_plus);
|
||||
start_output (request, proto_v7_plus, binary);
|
||||
|
||||
/* This will free and close the data input stream, but we got all the buffered content already */
|
||||
http_request_free (request);
|
||||
@ -894,7 +894,7 @@ start_input (HttpRequest *request, gboolean binary)
|
||||
}
|
||||
|
||||
static void
|
||||
start_output (HttpRequest *request, gboolean proto_v7_plus)
|
||||
start_output (HttpRequest *request, gboolean proto_v7_plus, gboolean binary)
|
||||
{
|
||||
GSocket *socket;
|
||||
GdkBroadwayDisplay *broadway_display;
|
||||
@ -914,7 +914,7 @@ start_output (HttpRequest *request, gboolean proto_v7_plus)
|
||||
|
||||
broadway_display->output =
|
||||
broadway_output_new (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
|
||||
broadway_display->saved_serial, proto_v7_plus);
|
||||
broadway_display->saved_serial, proto_v7_plus, binary);
|
||||
|
||||
_gdk_broadway_resync_windows ();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user