diff --git a/gdk/broadway/broadway-output.c b/gdk/broadway/broadway-output.c index 770fa438b5..89326c5994 100644 --- a/gdk/broadway/broadway-output.c +++ b/gdk/broadway/broadway-output.c @@ -297,6 +297,21 @@ broadway_output_window_update (BroadwayOutput *output, append_uint32 (output, texture); } +void +broadway_output_window_set_nodes (BroadwayOutput *output, + int id, + guint32 *data, + guint32 data_len) +{ + write_header (output, BROADWAY_OP_SET_NODES); + guint32 i; + + append_uint16 (output, id); + append_uint32 (output, data_len); + for (i = 0; i < data_len; i++) + append_uint32 (output, data[i]); +} + void broadway_output_upload_texture (BroadwayOutput *output, guint32 id, diff --git a/gdk/broadway/broadway-output.h b/gdk/broadway/broadway-output.h index 7c69e3bd8f..eb29c171ac 100644 --- a/gdk/broadway/broadway-output.h +++ b/gdk/broadway/broadway-output.h @@ -56,6 +56,10 @@ void broadway_output_set_transient_for (BroadwayOutput *output, void broadway_output_window_update (BroadwayOutput *output, int id, guint32 texture); +void broadway_output_window_set_nodes (BroadwayOutput *output, + int id, + guint32 *data, + guint32 data_len); void broadway_output_upload_texture (BroadwayOutput *output, guint32 id, GBytes *texture); diff --git a/gdk/broadway/broadway-protocol.h b/gdk/broadway/broadway-protocol.h index 3bf963f74e..7f7a5e9a5f 100644 --- a/gdk/broadway/broadway-protocol.h +++ b/gdk/broadway/broadway-protocol.h @@ -8,6 +8,11 @@ typedef struct { gint32 width, height; } BroadwayRect; +typedef enum { /* Sync changes with broadway.js */ + BROADWAY_NODE_TEXTURE, + BROADWAY_NODE_CONTAINER, +} BroadwayNodeType; + typedef enum { BROADWAY_EVENT_ENTER = 'e', BROADWAY_EVENT_LEAVE = 'l', @@ -45,6 +50,7 @@ typedef enum { BROADWAY_OP_SET_SHOW_KEYBOARD = 'k', BROADWAY_OP_UPLOAD_TEXTURE = 't', BROADWAY_OP_RELEASE_TEXTURE = 'T', + BROADWAY_OP_SET_NODES = 'n', } BroadwayOpType; typedef struct { @@ -162,6 +168,7 @@ typedef enum { BROADWAY_REQUEST_SET_SHOW_KEYBOARD, BROADWAY_REQUEST_UPLOAD_TEXTURE, BROADWAY_REQUEST_RELEASE_TEXTURE, + BROADWAY_REQUEST_SET_NODES, } BroadwayRequestType; typedef struct { @@ -181,15 +188,6 @@ typedef struct { guint32 parent; } BroadwayRequestSetTransientFor; -typedef struct { - BroadwayRequestBase base; - guint32 id; - gint32 dx; - gint32 dy; - guint32 n_rects; - BroadwayRect rects[1]; -} BroadwayRequestTranslate; - typedef struct { BroadwayRequestBase base; guint32 id; @@ -208,6 +206,13 @@ typedef struct { guint32 id; } BroadwayRequestReleaseTexture; +typedef struct { + BroadwayRequestBase base; + guint32 id; + guint32 data[1]; +} BroadwayRequestSetNodes; + + typedef struct { BroadwayRequestBase base; guint32 id; @@ -259,11 +264,11 @@ typedef union { BroadwayRequestMoveResize move_resize; BroadwayRequestGrabPointer grab_pointer; BroadwayRequestUngrabPointer ungrab_pointer; - BroadwayRequestTranslate translate; BroadwayRequestFocusWindow focus_window; BroadwayRequestSetShowKeyboard set_show_keyboard; BroadwayRequestUploadTexture upload_texture; BroadwayRequestReleaseTexture release_texture; + BroadwayRequestSetNodes set_nodes; } BroadwayRequest; typedef enum { diff --git a/gdk/broadway/broadway-server.c b/gdk/broadway/broadway-server.c index 8d86a9e069..4aa1b26b9f 100644 --- a/gdk/broadway/broadway-server.c +++ b/gdk/broadway/broadway-server.c @@ -117,6 +117,8 @@ struct BroadwayWindow { gboolean visible; gint32 transient_for; guint32 texture; + guint32 *nodes; + gint nodes_len; }; static void broadway_server_resync_windows (BroadwayServer *server); @@ -173,6 +175,13 @@ broadway_server_class_init (BroadwayServerClass * class) object_class->finalize = broadway_server_finalize; } +static void +broadway_window_free (BroadwayWindow *window) +{ + g_free (window->nodes); + g_free (window); +} + static void start (BroadwayInput *input); static void @@ -1375,9 +1384,8 @@ broadway_server_destroy_window (BroadwayServer *server, { server->toplevels = g_list_remove (server->toplevels, window); g_hash_table_remove (server->id_ht, - GINT_TO_POINTER (id)); - - g_free (window); + GINT_TO_POINTER (id)); + broadway_window_free (window); } } @@ -1512,13 +1520,12 @@ broadway_server_has_client (BroadwayServer *server) void broadway_server_window_update (BroadwayServer *server, - gint id, - guint32 texture) + gint id, + guint32 texture) { BroadwayWindow *window; - window = g_hash_table_lookup (server->id_ht, - GINT_TO_POINTER (id)); + window = g_hash_table_lookup (server->id_ht, GINT_TO_POINTER (id)); if (window == NULL) return; @@ -1526,7 +1533,28 @@ broadway_server_window_update (BroadwayServer *server, if (server->output != NULL) broadway_output_window_update (server->output, window->id, - window->texture); + window->texture); +} + +void +broadway_server_window_set_nodes (BroadwayServer *server, + gint id, + gint n_data, + guint32 *data) +{ + BroadwayWindow *window; + + window = g_hash_table_lookup (server->id_ht, GINT_TO_POINTER (id)); + if (window == NULL) + return; + + g_free (window->nodes); + window->nodes = g_memdup (data, sizeof (guint32)*n_data); + window->nodes_len = n_data; + + if (server->output != NULL) + broadway_output_window_set_nodes (server->output, window->id, + window->nodes, window->nodes_len); } guint32 @@ -1771,6 +1799,10 @@ broadway_server_resync_windows (BroadwayServer *server) broadway_output_set_transient_for (server->output, window->id, window->transient_for); + if (window->nodes) + broadway_output_window_set_nodes (server->output, window->id, + window->nodes, window->nodes_len); + broadway_output_window_update (server->output, window->id, window->texture); diff --git a/gdk/broadway/broadway-server.h b/gdk/broadway/broadway-server.h index 422488c038..1432a0a934 100644 --- a/gdk/broadway/broadway-server.h +++ b/gdk/broadway/broadway-server.h @@ -85,6 +85,10 @@ cairo_surface_t * broadway_server_create_surface (int void broadway_server_window_update (BroadwayServer *server, gint id, guint32 texture); +void broadway_server_window_set_nodes (BroadwayServer *server, + gint id, + gint n_data, + guint32 *data); gboolean broadway_server_window_move_resize (BroadwayServer *server, gint id, gboolean with_move, diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js index b268e0da6b..6192977056 100644 --- a/gdk/broadway/broadway.js +++ b/gdk/broadway/broadway.js @@ -2,10 +2,10 @@ var logDiv = null; function log(str) { if (!logDiv) { - logDiv = document.createElement('div'); - document.body.appendChild(logDiv); - logDiv.style["position"] = "absolute"; - logDiv.style["right"] = "0px"; + logDiv = document.createElement('div'); + document.body.appendChild(logDiv); + logDiv.style["position"] = "absolute"; + logDiv.style["right"] = "0px"; } logDiv.appendChild(document.createTextNode(str)); logDiv.appendChild(document.createElement('br')); @@ -16,44 +16,44 @@ function getStackTrace() var callstack = []; var isCallstackPopulated = false; try { - i.dont.exist+=0; + i.dont.exist+=0; } catch(e) { - if (e.stack) { // Firefox - var lines = e.stack.split("\n"); - for (var i=0, len=lines.length; i 0) - end = Math.min(len + 1, end); + end = Math.min(len + 1, end); for (var i = 1; i < end; i++) - log(callstack[i]); + log(callstack[i]); } var grab = new Object(); @@ -115,15 +115,15 @@ var GDK_RELEASE_MASK = 1 << 30; function getButtonMask (button) { if (button == 1) - return GDK_BUTTON1_MASK; + return GDK_BUTTON1_MASK; if (button == 2) - return GDK_BUTTON2_MASK; + return GDK_BUTTON2_MASK; if (button == 3) - return GDK_BUTTON3_MASK; + return GDK_BUTTON3_MASK; if (button == 4) - return GDK_BUTTON4_MASK; + return GDK_BUTTON4_MASK; if (button == 5) - return GDK_BUTTON5_MASK; + return GDK_BUTTON5_MASK; return 0; } @@ -141,25 +141,19 @@ function cmdCreateSurface(id, x, y, width, height, isTemp) surface.visible = false; surface.imageData = null; - var image = new Image(); - image.width = width; - image.height = height; - image.surface = surface; - surface.image = image; - var toplevelElement; + var div = document.createElement('div'); + div.surface = surface; + surface.div = div; - toplevelElement = image; - document.body.appendChild(image); + document.body.appendChild(div); - surface.toplevelElement = toplevelElement; - toplevelElement.style["position"] = "absolute"; - /* This positioning isn't strictly right for apps in another topwindow, - * but that will be fixed up when showing. */ - toplevelElement.style["left"] = surface.x + "px"; - toplevelElement.style["top"] = surface.y + "px"; - toplevelElement.style["display"] = "inline"; - - toplevelElement.style["visibility"] = "hidden"; + div.style["position"] = "absolute"; + div.style["left"] = surface.x + "px"; + div.style["top"] = surface.y + "px"; + div.style["width"] = surface.width + "px"; + div.style["height"] = surface.height + "px"; + div.style["display"] = "block"; + div.style["visibility"] = "hidden"; surfaces[id] = surface; stackingOrder.push(surface); @@ -172,15 +166,15 @@ function cmdShowSurface(id) var surface = surfaces[id]; if (surface.visible) - return; + return; surface.visible = true; var xOffset = surface.x; var yOffset = surface.y; - surface.toplevelElement.style["left"] = xOffset + "px"; - surface.toplevelElement.style["top"] = yOffset + "px"; - surface.toplevelElement.style["visibility"] = "visible"; + surface.div.style["left"] = xOffset + "px"; + surface.div.style["top"] = yOffset + "px"; + surface.div.style["visibility"] = "visible"; restackWindows(); } @@ -188,17 +182,14 @@ function cmdShowSurface(id) function cmdHideSurface(id) { if (grab.window == id) - doUngrab(); + doUngrab(); var surface = surfaces[id]; - if (!surface.visible) - return; + return; surface.visible = false; - var element = surface.toplevelElement; - - element.style["visibility"] = "hidden"; + surface.div.style["visibility"] = "hidden"; } function cmdSetTransientFor(id, parentId) @@ -206,22 +197,22 @@ function cmdSetTransientFor(id, parentId) var surface = surfaces[id]; if (surface.transientParent == parentId) - return; + return; surface.transientParent = parentId; if (parentId != 0 && surfaces[parentId]) { - moveToHelper(surface, stackingOrder.indexOf(surfaces[parentId])+1); + moveToHelper(surface, stackingOrder.indexOf(surfaces[parentId])+1); } if (surface.visible) { - restackWindows(); + restackWindows(); } } function restackWindows() { for (var i = 0; i < stackingOrder.length; i++) { - var surface = stackingOrder[i]; - surface.toplevelElement.style.zIndex = i; + var surface = stackingOrder[i]; + surface.div.style.zIndex = i; } } @@ -229,28 +220,28 @@ function moveToHelper(surface, position) { var i = stackingOrder.indexOf(surface); stackingOrder.splice(i, 1); if (position != undefined) - stackingOrder.splice(position, 0, surface); + stackingOrder.splice(position, 0, surface); else - stackingOrder.push(surface); + stackingOrder.push(surface); for (var cid in surfaces) { - var child = surfaces[cid]; - if (child.transientParent == surface.id) - moveToHelper(child, stackingOrder.indexOf(surface) + 1); + var child = surfaces[cid]; + if (child.transientParent == surface.id) + moveToHelper(child, stackingOrder.indexOf(surface) + 1); } } function cmdDeleteSurface(id) { if (grab.window == id) - doUngrab(); + doUngrab(); var surface = surfaces[id]; var i = stackingOrder.indexOf(surface); if (i >= 0) - stackingOrder.splice(i, 1); - var image = surface.image; - image.parentNode.removeChild(image); + stackingOrder.splice(i, 1); + var div = surface.div; + div.parentNode.removeChild(div); delete surfaces[id]; } @@ -258,30 +249,27 @@ function cmdMoveResizeSurface(id, has_pos, x, y, has_size, w, h) { var surface = surfaces[id]; if (has_pos) { - surface.positioned = true; - surface.x = x; - surface.y = y; - } - if (has_size) { - surface.width = w; - surface.height = h; + surface.positioned = true; + surface.x = x; + surface.y = y; } if (has_size) { - surface.image.width = w; - surface.image.height = h; + surface.width = w; + surface.height = h; + + surface.div.style["width"] = surface.width + "px"; + surface.div.style["height"] = surface.height + "px"; } if (surface.visible) { - if (has_pos) { - var xOffset = surface.x; - var yOffset = surface.y; + if (has_pos) { + var xOffset = surface.x; + var yOffset = surface.y; - var element = surface.image; - - element.style["left"] = xOffset + "px"; - element.style["top"] = yOffset + "px"; - } + surface.div.style["left"] = xOffset + "px"; + surface.div.style["top"] = yOffset + "px"; + } } sendConfigureNotify(surface); @@ -303,204 +291,70 @@ function cmdLowerSurface(id) restackWindows(); } -function copyRect(src, srcX, srcY, dest, destX, destY, width, height) -{ - // Clip to src - if (srcX + width > src.width) - width = src.width - srcX; - if (srcY + height > src.height) - height = src.height - srcY; - - // Clip to dest - if (destX + width > dest.width) - width = dest.width - destX; - if (destY + height > dest.height) - height = dest.height - destY; - - var srcRect = src.width * 4 * srcY + srcX * 4; - var destRect = dest.width * 4 * destY + destX * 4; - - for (var i = 0; i < height; i++) { - var line = src.data.subarray(srcRect, srcRect + width *4); - dest.data.set(line, destRect); - srcRect += src.width * 4; - destRect += dest.width * 4; - } -} - - -function markRun(dest, start, length, r, g, b) -{ - for (var i = start; i < start + length * 4; i += 4) { - dest[i+0] = dest[i+0] / 2 | 0 + r; - dest[i+1] = dest[i+1] / 2 | 0 + g; - dest[i+2] = dest[i+2] / 2 | 0 + b; - } -} - -function markRect(src, srcX, srcY, dest, destX, destY, width, height, r, g, b) -{ - // Clip to src - if (srcX + width > src.width) - width = src.width - srcX; - if (srcY + height > src.height) - height = src.height - srcY; - - // Clip to dest - if (destX + width > dest.width) - width = dest.width - destX; - if (destY + height > dest.height) - height = dest.height - destY; - - var destRect = dest.width * 4 * destY + destX * 4; - - for (var i = 0; i < height; i++) { - if (i == 0 || i == height-1) - markRun(dest.data, destRect, width, 0, 0, 0); - else { - markRun(dest.data, destRect, 1, 0 ,0, 0); - markRun(dest.data, destRect+4, width-2, r, g, b); - markRun(dest.data, destRect+4*width-4, 1, 0, 0, 0); - } - destRect += dest.width * 4; - } -} - -function decodeBuffer(context, oldData, w, h, data, debug) -{ - var i, j; - var imageData = context.createImageData(w, h); - - if (oldData != null) { - // Copy old frame into new buffer - copyRect(oldData, 0, 0, imageData, 0, 0, oldData.width, oldData.height); - } - - var src = 0; - var dest = 0; - - while (src < data.length) { - var b = data[src++]; - var g = data[src++]; - var r = data[src++]; - var alpha = data[src++]; - var len, start; - - if (alpha != 0) { - // Regular data is red - if (debug) { - r = r / 2 | 0 + 128; - g = g / 2 | 0; - b = r / 2 | 0; - } - - imageData.data[dest++] = r; - imageData.data[dest++] = g; - imageData.data[dest++] = b; - imageData.data[dest++] = alpha; - } else { - var cmd = r & 0xf0; - switch (cmd) { - case 0x00: // Transparent pixel - //log("Got transparent"); - imageData.data[dest++] = 0; - imageData.data[dest++] = 0; - imageData.data[dest++] = 0; - imageData.data[dest++] = 0; - break; - - case 0x10: // Delta 0 run - len = (r & 0xf) << 16 | g << 8 | b; - //log("Got delta0, len: " + len); - dest += len * 4; - break; - - case 0x20: // Block reference - var blockid = (r & 0xf) << 16 | g << 8 | b; - - var block_stride = (oldData.width + 32 - 1) / 32 | 0; - var srcY = (blockid / block_stride | 0) * 32; - var srcX = (blockid % block_stride | 0) * 32; - - b = data[src++]; - g = data[src++]; - r = data[src++]; - alpha = data[src++]; - - var destX = alpha << 8 | r; - var destY = g << 8 | b; - - copyRect(oldData, srcX, srcY, imageData, destX, destY, 32, 32); - if (debug) // blocks are green - markRect(oldData, srcX, srcY, imageData, destX, destY, 32, 32, 0x00, 128, 0x00); - - //log("Got block, id: " + blockid + "(" + srcX +"," + srcY + ") at " + destX + "," + destY); - - break; - - case 0x30: // Color run - len = (r & 0xf) << 16 | g << 8 | b; - //log("Got color run, len: " + len); - - b = data[src++]; - g = data[src++]; - r = data[src++]; - alpha = data[src++]; - - start = dest; - - for (i = 0; i < len; i++) { - imageData.data[dest++] = r; - imageData.data[dest++] = g; - imageData.data[dest++] = b; - imageData.data[dest++] = alpha; - } - - if (debug) // Color runs are blue - markRun(imageData.data, start, len, 0x00, 0x00, 128); - - break; - - case 0x40: // Delta run - len = (r & 0xf) << 16 | g << 8 | b; - //log("Got delta run, len: " + len); - - b = data[src++]; - g = data[src++]; - r = data[src++]; - alpha = data[src++]; - - start = dest; - - for (i = 0; i < len; i++) { - imageData.data[dest] = (imageData.data[dest] + r) & 0xff; - dest++; - imageData.data[dest] = (imageData.data[dest] + g) & 0xff; - dest++; - imageData.data[dest] = (imageData.data[dest] + b) & 0xff; - dest++; - imageData.data[dest] = (imageData.data[dest] + alpha) & 0xff; - dest++; - } - if (debug) // Delta runs are violet - markRun(imageData.data, start, len, 0xff, 0x00, 0xff); - break; - - default: - alert("Unknown buffer commend " + cmd); - } - } - } - - return imageData; -} - function cmdWindowUpdate(id, texture_id) { var surface = surfaces[id]; - var texture_url = textures[texture]; + var texture_url = textures[texture_id]; - surface.image.src = texture_url; + surface.div.src = texture_url; +} + +function handleNode(parent, node_data, data_pos) +{ + var type = node_data[data_pos++]; + switch (type) + { + case 0: // TEXTURE + var x = node_data[data_pos++]; + var y = node_data[data_pos++]; + var width = node_data[data_pos++]; + var height = node_data[data_pos++]; + var texture_id = node_data[data_pos++]; + var image = new Image(); + image.width = width; + image.height = height; + image.style["position"] = "absolute"; + image.style["left"] = x + "px"; + image.style["top"] = y + "px"; + var texture_url = textures[texture_id]; + image.src = texture_url; + parent.appendChild(image); + break; + + case 1: // CONTAINER + var len = node_data[data_pos++]; + for (var i = 0; i < len; i++) { + data_pos = handleNode(parent, node_data, data_pos); + } + break; + default: + alert("Unexpected node type " + type); + } + return data_pos; +} + +function cmdWindowSetNodes(id, node_data) +{ + var surface = surfaces[id]; + surface.node_data = node_data; + + var div = surface.div; + + /* We use a secondary div so that we can remove all previous children in one go */ + var oldDiv2 = null; + + if (div.hasChildNodes()) + oldDiv2 = div.lastChild; + + var div2 = document.createElement('div'); + + var end = handleNode(div2, node_data, 0); + if (end != node_data.length) + alert ("Did not consume entire array (len " + node_data.length + " end " + end + ")"); + + div.appendChild(div2); + if (oldDiv2) + div.removeChild(oldDiv2); } function cmdUploadTexture(id, data) @@ -527,7 +381,7 @@ function cmdUngrabPointer() { sendInput ("u", []); if (grab.window) - doUngrab(); + doUngrab(); } var active = false; @@ -539,108 +393,118 @@ function handleCommands(cmd) } while (cmd.pos < cmd.length) { - var id, x, y, w, h, q; - var command = cmd.get_char(); - lastSerial = cmd.get_32(); - switch (command) { - case 'D': - alert ("disconnected"); - inputSocket = null; - break; + var id, x, y, w, h, q; + var command = cmd.get_char(); + lastSerial = cmd.get_32(); + switch (command) { + case 'D': + alert ("disconnected"); + inputSocket = null; + break; - case 's': // create new surface - id = cmd.get_16(); - x = cmd.get_16s(); - y = cmd.get_16s(); - w = cmd.get_16(); - h = cmd.get_16(); - var isTemp = cmd.get_bool(); - cmdCreateSurface(id, x, y, w, h, isTemp); - break; + case 's': // create new surface + id = cmd.get_16(); + x = cmd.get_16s(); + y = cmd.get_16s(); + w = cmd.get_16(); + h = cmd.get_16(); + var isTemp = cmd.get_bool(); + cmdCreateSurface(id, x, y, w, h, isTemp); + break; - case 'S': // Show a surface - id = cmd.get_16(); - cmdShowSurface(id); - break; + case 'S': // Show a surface + id = cmd.get_16(); + cmdShowSurface(id); + break; - case 'H': // Hide a surface - id = cmd.get_16(); - cmdHideSurface(id); - break; + case 'H': // Hide a surface + id = cmd.get_16(); + cmdHideSurface(id); + break; - case 'p': // Set transient parent - id = cmd.get_16(); - var parentId = cmd.get_16(); - cmdSetTransientFor(id, parentId); - break; + case 'p': // Set transient parent + id = cmd.get_16(); + var parentId = cmd.get_16(); + cmdSetTransientFor(id, parentId); + break; - case 'd': // Delete surface - id = cmd.get_16(); - cmdDeleteSurface(id); - break; + case 'd': // Delete surface + id = cmd.get_16(); + cmdDeleteSurface(id); + break; - case 'm': // Move a surface - id = cmd.get_16(); - var ops = cmd.get_flags(); - var has_pos = ops & 1; - if (has_pos) { - x = cmd.get_16s(); - y = cmd.get_16s(); - } - var has_size = ops & 2; - if (has_size) { - w = cmd.get_16(); - h = cmd.get_16(); - } - cmdMoveResizeSurface(id, has_pos, x, y, has_size, w, h); - break; + case 'm': // Move a surface + id = cmd.get_16(); + var ops = cmd.get_flags(); + var has_pos = ops & 1; + if (has_pos) { + x = cmd.get_16s(); + y = cmd.get_16s(); + } + var has_size = ops & 2; + if (has_size) { + w = cmd.get_16(); + h = cmd.get_16(); + } + cmdMoveResizeSurface(id, has_pos, x, y, has_size, w, h); + break; - case 'r': // Raise a surface - id = cmd.get_16(); - cmdRaiseSurface(id); - break; + case 'r': // Raise a surface + id = cmd.get_16(); + cmdRaiseSurface(id); + break; - case 'R': // Lower a surface - id = cmd.get_16(); - cmdLowerSurface(id); - break; + case 'R': // Lower a surface + id = cmd.get_16(); + cmdLowerSurface(id); + break; - case 'b': // Update window - id = cmd.get_16(); - texture = cmd.get_32(); + case 'b': // Update window + id = cmd.get_16(); + var texture = cmd.get_32(); cmdWindowUpdate(id, texture); break; - case 't': // Upload texture - id = cmd.get_32(); + case 't': // Upload texture + id = cmd.get_32(); var data = cmd.get_data(); cmdUploadTexture(id, data); break; - case 'T': // Upload texture - id = cmd.get_32(); + case 'T': // Release texture + id = cmd.get_32(); cmdReleaseTexture(id); break; - case 'g': // Grab - id = cmd.get_16(); - var ownerEvents = cmd.get_bool (); + case 'n': // Set nodes + id = cmd.get_16(); + var len = cmd.get_32(); + var node_data = new Uint32Array(len); + for (var i = 0; i < len; i++) + node_data[i] = cmd.get_32(); - cmdGrabPointer(id, ownerEvents); - break; + cmdWindowSetNodes(id, node_data); + break; - case 'u': // Ungrab - cmdUngrabPointer(); - break; + case 'g': // Grab + id = cmd.get_16(); + var ownerEvents = cmd.get_bool (); + + cmdGrabPointer(id, ownerEvents); + break; + + case 'u': // Ungrab + cmdUngrabPointer(); + break; case 'k': // show keyboard showKeyboard = cmd.get_16() != 0; showKeyboardChanged = true; break; - default: - alert("Unknown op " + command); - } + default: + alert("Unknown op " + command); + } } return true; } @@ -648,11 +512,11 @@ function handleCommands(cmd) function handleOutstanding() { while (outstandingCommands.length > 0) { - var cmd = outstandingCommands.shift(); - if (!handleCommands(cmd)) { - outstandingCommands.unshift(cmd); - return; - } + var cmd = outstandingCommands.shift(); + if (!handleCommands(cmd)) { + outstandingCommands.unshift(cmd); + return; + } } } @@ -674,24 +538,24 @@ BinCommands.prototype.get_flags = function() { } BinCommands.prototype.get_16 = function() { var v = - this.u8[this.pos] + - (this.u8[this.pos+1] << 8); + 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; + return v - 65536; else - return v; + 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.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; }; @@ -707,14 +571,14 @@ function handleMessage(message) var cmd = new BinCommands(message); outstandingCommands.push(cmd); if (outstandingCommands.length == 1) { - handleOutstanding(); + handleOutstanding(); } } function getSurfaceId(ev) { var surface = ev.target.surface; if (surface != undefined) - return surface.id; + return surface.id; return 0; } @@ -741,9 +605,9 @@ function getPositionsFromAbsCoord(absX, absY, relativeId) { res.winX = absX; res.winY = absY; if (relativeId != 0) { - var surface = surfaces[relativeId]; - res.winX = res.winX - surface.x; - res.winY = res.winY - surface.y; + var surface = surfaces[relativeId]; + res.winX = res.winX - surface.x; + res.winY = res.winY - surface.y; } return res; @@ -763,10 +627,10 @@ function getPositionsFromEvent(ev, relativeId) { function getEffectiveEventTarget (id) { if (grab.window != null) { - if (!grab.ownerEvents) - return grab.window; - if (id == 0) - return grab.window; + if (!grab.ownerEvents) + return grab.window; + if (id == 0) + return grab.window; } return id; } @@ -784,11 +648,11 @@ function updateKeyboardStatus() { function updateForEvent(ev) { lastState &= ~(GDK_SHIFT_MASK|GDK_CONTROL_MASK|GDK_MOD1_MASK); if (ev.shiftKey) - lastState |= GDK_SHIFT_MASK; + lastState |= GDK_SHIFT_MASK; if (ev.ctrlKey) - lastState |= GDK_CONTROL_MASK; + lastState |= GDK_CONTROL_MASK; if (ev.altKey) - lastState |= GDK_MOD1_MASK; + lastState |= GDK_MOD1_MASK; lastTimeStamp = ev.timeStamp; } @@ -810,7 +674,7 @@ function onMouseOver (ev) { var pos = getPositionsFromEvent(ev, id); windowWithMouse = id; if (windowWithMouse != 0) { - sendInput ("e", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_NORMAL]); + sendInput ("e", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_NORMAL]); } } @@ -822,7 +686,7 @@ function onMouseOut (ev) { var pos = getPositionsFromEvent(ev, id); if (id != 0) { - sendInput ("l", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_NORMAL]); + sendInput ("l", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_NORMAL]); } realWindowWithMouse = 0; windowWithMouse = 0; @@ -832,13 +696,13 @@ function doGrab(id, ownerEvents, implicit) { var pos; if (windowWithMouse != id) { - if (windowWithMouse != 0) { - pos = getPositionsFromAbsCoord(lastX, lastY, windowWithMouse); - sendInput ("l", [realWindowWithMouse, windowWithMouse, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_GRAB]); - } - pos = getPositionsFromAbsCoord(lastX, lastY, id); - sendInput ("e", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_GRAB]); - windowWithMouse = id; + if (windowWithMouse != 0) { + pos = getPositionsFromAbsCoord(lastX, lastY, windowWithMouse); + sendInput ("l", [realWindowWithMouse, windowWithMouse, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_GRAB]); + } + pos = getPositionsFromAbsCoord(lastX, lastY, id); + sendInput ("e", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_GRAB]); + windowWithMouse = id; } grab.window = id; @@ -849,15 +713,15 @@ function doGrab(id, ownerEvents, implicit) { function doUngrab() { var pos; if (realWindowWithMouse != windowWithMouse) { - if (windowWithMouse != 0) { - pos = getPositionsFromAbsCoord(lastX, lastY, windowWithMouse); - sendInput ("l", [realWindowWithMouse, windowWithMouse, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_UNGRAB]); - } - if (realWindowWithMouse != 0) { - pos = getPositionsFromAbsCoord(lastX, lastY, realWindowWithMouse); - sendInput ("e", [realWindowWithMouse, realWindowWithMouse, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_UNGRAB]); - } - windowWithMouse = realWindowWithMouse; + if (windowWithMouse != 0) { + pos = getPositionsFromAbsCoord(lastX, lastY, windowWithMouse); + sendInput ("l", [realWindowWithMouse, windowWithMouse, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_UNGRAB]); + } + if (realWindowWithMouse != 0) { + pos = getPositionsFromAbsCoord(lastX, lastY, realWindowWithMouse); + sendInput ("e", [realWindowWithMouse, realWindowWithMouse, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_UNGRAB]); + } + windowWithMouse = realWindowWithMouse; } grab.window = null; } @@ -871,7 +735,7 @@ function onMouseDown (ev) { var pos = getPositionsFromEvent(ev, id); if (grab.window == null) - doGrab (id, false, true); + doGrab (id, false, true); sendInput ("b", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, button]); return false; } @@ -887,7 +751,7 @@ function onMouseUp (ev) { sendInput ("B", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, button]); if (grab.window != null && grab.implicit) - doUngrab(); + doUngrab(); return false; } @@ -2200,7 +2064,7 @@ var specialKeyTable = { function getEventKeySym(ev) { if (typeof ev.which !== "undefined" && ev.which > 0) - return ev.which; + return ev.which; return ev.keyCode; } @@ -2211,19 +2075,19 @@ function getEventKeySym(ev) { // translated keysym. function getKeysymSpecial(ev) { if (ev.keyCode in specialKeyTable) { - var r = specialKeyTable[ev.keyCode]; - var flags = 0; - if (typeof r != 'number') { - flags = r[1]; - r = r[0]; - } - if (ev.type === 'keydown' || flags & ON_KEYDOWN) - return r; + var r = specialKeyTable[ev.keyCode]; + var flags = 0; + if (typeof r != 'number') { + flags = r[1]; + r = r[0]; + } + if (ev.type === 'keydown' || flags & ON_KEYDOWN) + return r; } // If we don't hold alt or ctrl, then we should be safe to pass // on to keypressed and look at the translated data if (!ev.ctrlKey && !ev.altKey) - return null; + return null; var keysym = getEventKeySym(ev); @@ -2233,9 +2097,9 @@ function getKeysymSpecial(ev) { case 187 : keysym = 61; break; // = (IE) case 188 : keysym = 44; break; // , (Mozilla, IE) case 109 : // - (Mozilla, Opera) - if (true /* TODO: check if browser is firefox or opera */) - keysym = 45; - break; + if (true /* TODO: check if browser is firefox or opera */) + keysym = 45; + break; case 189 : keysym = 45; break; // - (IE) case 190 : keysym = 46; break; // . (Mozilla, IE) case 191 : keysym = 47; break; // / (Mozilla, IE) @@ -2248,49 +2112,49 @@ function getKeysymSpecial(ev) { /* Remap shifted and unshifted keys */ if (!!ev.shiftKey) { - switch (keysym) { - case 48 : keysym = 41 ; break; // ) (shifted 0) - case 49 : keysym = 33 ; break; // ! (shifted 1) - case 50 : keysym = 64 ; break; // @ (shifted 2) - case 51 : keysym = 35 ; break; // # (shifted 3) - case 52 : keysym = 36 ; break; // $ (shifted 4) - case 53 : keysym = 37 ; break; // % (shifted 5) - case 54 : keysym = 94 ; break; // ^ (shifted 6) - case 55 : keysym = 38 ; break; // & (shifted 7) - case 56 : keysym = 42 ; break; // * (shifted 8) - case 57 : keysym = 40 ; break; // ( (shifted 9) - case 59 : keysym = 58 ; break; // : (shifted `) - case 61 : keysym = 43 ; break; // + (shifted ;) - case 44 : keysym = 60 ; break; // < (shifted ,) - case 45 : keysym = 95 ; break; // _ (shifted -) - case 46 : keysym = 62 ; break; // > (shifted .) - case 47 : keysym = 63 ; break; // ? (shifted /) - case 96 : keysym = 126; break; // ~ (shifted `) - case 91 : keysym = 123; break; // { (shifted [) - case 92 : keysym = 124; break; // | (shifted \) - case 93 : keysym = 125; break; // } (shifted ]) - case 39 : keysym = 34 ; break; // " (shifted ') - } + switch (keysym) { + case 48 : keysym = 41 ; break; // ) (shifted 0) + case 49 : keysym = 33 ; break; // ! (shifted 1) + case 50 : keysym = 64 ; break; // @ (shifted 2) + case 51 : keysym = 35 ; break; // # (shifted 3) + case 52 : keysym = 36 ; break; // $ (shifted 4) + case 53 : keysym = 37 ; break; // % (shifted 5) + case 54 : keysym = 94 ; break; // ^ (shifted 6) + case 55 : keysym = 38 ; break; // & (shifted 7) + case 56 : keysym = 42 ; break; // * (shifted 8) + case 57 : keysym = 40 ; break; // ( (shifted 9) + case 59 : keysym = 58 ; break; // : (shifted `) + case 61 : keysym = 43 ; break; // + (shifted ;) + case 44 : keysym = 60 ; break; // < (shifted ,) + case 45 : keysym = 95 ; break; // _ (shifted -) + case 46 : keysym = 62 ; break; // > (shifted .) + case 47 : keysym = 63 ; break; // ? (shifted /) + case 96 : keysym = 126; break; // ~ (shifted `) + case 91 : keysym = 123; break; // { (shifted [) + case 92 : keysym = 124; break; // | (shifted \) + case 93 : keysym = 125; break; // } (shifted ]) + case 39 : keysym = 34 ; break; // " (shifted ') + } } else if ((keysym >= 65) && (keysym <=90)) { - /* Remap unshifted A-Z */ - keysym += 32; + /* Remap unshifted A-Z */ + keysym += 32; } else if (ev.keyLocation === 3) { - // numpad keys - switch (keysym) { - case 96 : keysym = 48; break; // 0 - case 97 : keysym = 49; break; // 1 - case 98 : keysym = 50; break; // 2 - case 99 : keysym = 51; break; // 3 - case 100: keysym = 52; break; // 4 - case 101: keysym = 53; break; // 5 - case 102: keysym = 54; break; // 6 - case 103: keysym = 55; break; // 7 - case 104: keysym = 56; break; // 8 - case 105: keysym = 57; break; // 9 - case 109: keysym = 45; break; // - - case 110: keysym = 46; break; // . - case 111: keysym = 47; break; // / - } + // numpad keys + switch (keysym) { + case 96 : keysym = 48; break; // 0 + case 97 : keysym = 49; break; // 1 + case 98 : keysym = 50; break; // 2 + case 99 : keysym = 51; break; // 3 + case 100: keysym = 52; break; // 4 + case 101: keysym = 53; break; // 5 + case 102: keysym = 54; break; // 6 + case 103: keysym = 55; break; // 7 + case 104: keysym = 56; break; // 8 + case 105: keysym = 57; break; // 9 + case 109: keysym = 45; break; // - + case 110: keysym = 46; break; // . + case 111: keysym = 47; break; // / + } } return keysym; @@ -2303,10 +2167,10 @@ function getKeysym(ev) { keysym = getEventKeySym(ev); if ((keysym > 255) && (keysym < 0xFF00)) { - // Map Unicode outside Latin 1 to gdk keysyms - keysym = unicodeTable[keysym]; - if (typeof keysym === 'undefined') - keysym = 0; + // Map Unicode outside Latin 1 to gdk keysyms + keysym = unicodeTable[keysym]; + if (typeof keysym === 'undefined') + keysym = 0; } return keysym; @@ -2314,11 +2178,11 @@ function getKeysym(ev) { function copyKeyEvent(ev) { var members = ['type', 'keyCode', 'charCode', 'which', - 'altKey', 'ctrlKey', 'shiftKey', - 'keyLocation', 'keyIdentifier'], i, obj = {}; + 'altKey', 'ctrlKey', 'shiftKey', + 'keyLocation', 'keyIdentifier'], i, obj = {}; for (i = 0; i < members.length; i++) { - if (typeof ev[members[i]] !== "undefined") - obj[members[i]] = ev[members[i]]; + if (typeof ev[members[i]] !== "undefined") + obj[members[i]] = ev[members[i]]; } return obj; } @@ -2330,13 +2194,13 @@ function pushKeyEvent(fev) { function getKeyEvent(keyCode, pop) { var i, fev = null; for (i = keyDownList.length-1; i >= 0; i--) { - if (keyDownList[i].keyCode === keyCode) { - if ((typeof pop !== "undefined") && pop) - fev = keyDownList.splice(i, 1)[0]; - else - fev = keyDownList[i]; - break; - } + if (keyDownList[i].keyCode === keyCode) { + if ((typeof pop !== "undefined") && pop) + fev = keyDownList.splice(i, 1)[0]; + else + fev = keyDownList[i]; + break; + } } return fev; } @@ -2344,10 +2208,10 @@ function getKeyEvent(keyCode, pop) { function ignoreKeyEvent(ev) { // Blarg. Some keys have a different keyCode on keyDown vs keyUp if (ev.keyCode === 229) { - // French AZERTY keyboard dead key. - // Lame thing is that the respective keyUp is 219 so we can't - // properly ignore the keyUp event - return true; + // French AZERTY keyboard dead key. + // Lame thing is that the respective keyUp is 219 so we can't + // properly ignore the keyUp event + return true; } return false; } @@ -2361,22 +2225,22 @@ function handleKeyDown(e) { // Save keysym decoding for use in keyUp fev.keysym = keysym; if (keysym) { - // If it is a key or key combination that might trigger - // browser behaviors or it has no corresponding keyPress - // event, then send it immediately - if (!ignoreKeyEvent(ev)) - sendInput("k", [keysym, lastState]); - suppress = true; + // If it is a key or key combination that might trigger + // browser behaviors or it has no corresponding keyPress + // event, then send it immediately + if (!ignoreKeyEvent(ev)) + sendInput("k", [keysym, lastState]); + suppress = true; } if (! ignoreKeyEvent(ev)) { - // Add it to the list of depressed keys - pushKeyEvent(fev); + // Add it to the list of depressed keys + pushKeyEvent(fev); } if (suppress) { - // Suppress bubbling/default actions - return cancelEvent(ev); + // Suppress bubbling/default actions + return cancelEvent(ev); } // Allow the event to bubble and become a keyPress event which @@ -2388,13 +2252,13 @@ function handleKeyPress(e) { var ev = (e ? e : window.event), kdlen = keyDownList.length, keysym = null; if (((ev.which !== "undefined") && (ev.which === 0)) || - getKeysymSpecial(ev)) { - // Firefox and Opera generate a keyPress event even if keyDown - // is suppressed. But the keys we want to suppress will have - // either: - // - the which attribute set to 0 - // - getKeysymSpecial() will identify it - return cancelEvent(ev); + getKeysymSpecial(ev)) { + // Firefox and Opera generate a keyPress event even if keyDown + // is suppressed. But the keys we want to suppress will have + // either: + // - the which attribute set to 0 + // - getKeysymSpecial() will identify it + return cancelEvent(ev); } keysym = getKeysym(ev); @@ -2403,14 +2267,14 @@ function handleKeyPress(e) { // that the keyUp event will be able to have the character code // translation available. if (kdlen > 0) { - keyDownList[kdlen-1].keysym = keysym; + keyDownList[kdlen-1].keysym = keysym; } else { - //log("keyDownList empty when keyPress triggered"); + //log("keyDownList empty when keyPress triggered"); } // Send the translated keysym if (keysym > 0) - sendInput ("k", [keysym, lastState]); + sendInput ("k", [keysym, lastState]); // Stop keypress events just in case return cancelEvent(ev); @@ -2422,14 +2286,14 @@ function handleKeyUp(e) { fev = getKeyEvent(ev.keyCode, true); if (fev) - keysym = fev.keysym; + keysym = fev.keysym; else { - //log("Key event (keyCode = " + ev.keyCode + ") not found on keyDownList"); - keysym = 0; + //log("Key event (keyCode = " + ev.keyCode + ") not found on keyDownList"); + keysym = 0; } if (keysym > 0) - sendInput ("K", [keysym, lastState]); + sendInput ("K", [keysym, lastState]); return cancelEvent(ev); } @@ -2452,9 +2316,9 @@ function cancelEvent(ev) { ev = ev ? ev : window.event; if (ev.stopPropagation) - ev.stopPropagation(); + ev.stopPropagation(); if (ev.preventDefault) - ev.preventDefault(); + ev.preventDefault(); ev.cancelBubble = true; ev.cancel = true; ev.returnValue = false; @@ -2472,7 +2336,7 @@ function onMouseWheel(ev) var offset = ev.detail ? ev.detail : -ev.wheelDelta; var dir = 0; if (offset > 0) - dir = 1; + dir = 1; sendInput ("s", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, dir]); return cancelEvent(ev); @@ -2588,10 +2452,10 @@ function start() w = window.innerWidth; h = window.innerHeight; window.onresize = function(ev) { - var w, h; - w = window.innerWidth; - h = window.innerHeight; - sendInput ("d", [w, h]); + var w, h; + w = window.innerWidth; + h = window.innerHeight; + sendInput ("d", [w, h]); }; sendInput ("d", [w, h]); } @@ -2601,7 +2465,7 @@ function connect() var url = window.location.toString(); var query_string = url.split("?"); if (query_string.length > 1) { - var params = query_string[1].split("&"); + var params = query_string[1].split("&"); for (var i=0; iupdate.id, global_id); break; + case BROADWAY_REQUEST_SET_NODES: + { + gsize array_size = request->base.size - sizeof (BroadwayRequestSetNodes) + sizeof(guint32); + int n_data = array_size / sizeof(guint32); + + broadway_server_window_set_nodes (server, + request->set_nodes.id, + n_data, + request->set_nodes.data); + } + break; case BROADWAY_REQUEST_UPLOAD_TEXTURE: if (client->fds == NULL) - g_warning ("FD passing mismatch"); + g_warning ("FD passing mismatch for texture upload %d", request->release_texture.id); else { char *data, *p; diff --git a/gdk/broadway/gdkbroadway-server.c b/gdk/broadway/gdkbroadway-server.c index 40238337ff..f873a77116 100644 --- a/gdk/broadway/gdkbroadway-server.c +++ b/gdk/broadway/gdkbroadway-server.c @@ -668,6 +668,7 @@ gdk_broadway_server_upload_texture (GdkBroadwayServer *server, return id; } + void gdk_broadway_server_release_texture (GdkBroadwayServer *server, guint32 id) @@ -680,6 +681,22 @@ gdk_broadway_server_release_texture (GdkBroadwayServer *server, BROADWAY_REQUEST_RELEASE_TEXTURE); } +void +gdk_broadway_server_window_set_nodes (GdkBroadwayServer *server, + guint32 id, + GArray *nodes) +{ + gsize size = sizeof(BroadwayRequestSetNodes) + sizeof(guint32) * (nodes->len - 1); + BroadwayRequestSetNodes *msg = g_alloca (size); + int i; + + for (i = 0; i < nodes->len; i++) + msg->data[i] = g_array_index (nodes, guint32, i); + + msg->id = id; + gdk_broadway_server_send_message_with_size (server, (BroadwayRequestBase *) msg, size, BROADWAY_REQUEST_SET_NODES, -1); +} + gboolean _gdk_broadway_server_window_move_resize (GdkBroadwayServer *server, gint id, diff --git a/gdk/broadway/gdkbroadway-server.h b/gdk/broadway/gdkbroadway-server.h index 91554e5eae..f679153b34 100644 --- a/gdk/broadway/gdkbroadway-server.h +++ b/gdk/broadway/gdkbroadway-server.h @@ -66,6 +66,9 @@ void gdk_broadway_server_release_texture (GdkBroadwaySer void _gdk_broadway_server_window_update (GdkBroadwayServer *server, gint id, guint32 texture); +void gdk_broadway_server_window_set_nodes (GdkBroadwayServer *server, + guint32 id, + GArray *nodes); gboolean _gdk_broadway_server_window_move_resize (GdkBroadwayServer *server, gint id, gboolean with_move, diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c index aa2c0f6257..1da5b7f63b 100644 --- a/gdk/broadway/gdkdisplay-broadway.c +++ b/gdk/broadway/gdkdisplay-broadway.c @@ -324,6 +324,45 @@ gdk_broadway_display_get_last_seen_time (GdkDisplay *display) return _gdk_broadway_server_get_last_seen_time (GDK_BROADWAY_DISPLAY (display)->server); } +typedef struct { + int id; + GdkDisplay *display; +} BroadwayTextureData; + +static void +broadway_texture_data_free (BroadwayTextureData *data) +{ + GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (data->display); + + gdk_broadway_server_release_texture (broadway_display->server, data->id); + g_object_unref (data->display); + g_free (data); +} + +guint32 +gdk_broadway_display_ensure_texture (GdkDisplay *display, + GdkTexture *texture) +{ + GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (display); + BroadwayTextureData *data; + guint32 id; + + data = gdk_texture_get_render_data (texture, display); + if (data != NULL) + return data->id; + + id = gdk_broadway_server_upload_texture (broadway_display->server, texture); + + data = g_new0 (BroadwayTextureData, 1); + data->id = id; + data->display = g_object_ref (display); + + if (!gdk_texture_set_render_data (texture, display, data, (GDestroyNotify)broadway_texture_data_free)) + g_warning ("Failed to set render data, will leak texture"); + + return id; +} + static void gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class) { diff --git a/gdk/broadway/gdkprivate-broadway.h b/gdk/broadway/gdkprivate-broadway.h index 8df551d00d..146ff378e2 100644 --- a/gdk/broadway/gdkprivate-broadway.h +++ b/gdk/broadway/gdkprivate-broadway.h @@ -39,6 +39,13 @@ void _gdk_broadway_resync_windows (void); +guint32 gdk_broadway_display_ensure_texture (GdkDisplay *display, + GdkTexture *texture); + +void gdk_broadway_window_set_nodes (GdkWindow *window, + GArray *nodes, + GPtrArray *node_textures); + void _gdk_broadway_window_register_dnd (GdkWindow *window); GdkDragContext * _gdk_broadway_window_drag_begin (GdkWindow *window, GdkDevice *device, diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c index 2f05c31ab9..f1fe25d799 100644 --- a/gdk/broadway/gdkwindow-broadway.c +++ b/gdk/broadway/gdkwindow-broadway.c @@ -71,8 +71,8 @@ gdk_broadway_window_init (GdkBroadwayWindow *broadway_window) } G_DEFINE_TYPE (GdkWindowImplBroadway, - gdk_window_impl_broadway, - GDK_TYPE_WINDOW_IMPL) + gdk_window_impl_broadway, + GDK_TYPE_WINDOW_IMPL) static GdkDisplay * find_broadway_display (void) @@ -112,28 +112,32 @@ update_dirty_windows_and_sync (void) GdkWindowImplBroadway *impl = l->data; if (impl->dirty) - { - GdkTexture *texture; - guint32 texture_id; + { + GdkTexture *texture; + guint32 texture_id; - impl->dirty = FALSE; - updated_surface = TRUE; + impl->dirty = FALSE; + updated_surface = TRUE; - if (impl->texture_id) - gdk_broadway_server_release_texture (display->server, impl->texture_id); - impl->texture_id = 0; + if (impl->texture_id) + gdk_broadway_server_release_texture (display->server, impl->texture_id); + impl->texture_id = 0; - texture = gdk_texture_new_for_surface (impl->surface); - texture_id = gdk_broadway_server_upload_texture (display->server, texture); - g_object_unref (texture); + texture = gdk_texture_new_for_surface (impl->surface); + texture_id = gdk_broadway_server_upload_texture (display->server, texture); + g_object_unref (texture); - impl->texture_id = texture_id; + impl->texture_id = texture_id; - _gdk_broadway_server_window_update (display->server, - impl->id, - texture_id); - } + if (impl->node_data) + gdk_broadway_server_window_set_nodes (display->server, impl->id, impl->node_data); + + _gdk_broadway_server_window_update (display->server, + impl->id, + texture_id); + + } } /* We sync here to ensure all references to the impl->surface memory @@ -223,10 +227,10 @@ connect_frame_clock (GdkWindow *window) void _gdk_broadway_display_create_window_impl (GdkDisplay *display, - GdkWindow *window, - GdkWindow *real_parent, - GdkEventMask event_mask, - GdkWindowAttr *attributes) + GdkWindow *window, + GdkWindow *real_parent, + GdkEventMask event_mask, + GdkWindowAttr *attributes) { GdkWindowImplBroadway *impl; GdkBroadwayDisplay *broadway_display; @@ -236,16 +240,16 @@ _gdk_broadway_display_create_window_impl (GdkDisplay *display, impl = g_object_new (GDK_TYPE_WINDOW_IMPL_BROADWAY, NULL); window->impl = (GdkWindowImpl *)impl; impl->id = _gdk_broadway_server_new_window (broadway_display->server, - window->x, - window->y, - window->width, - window->height, - window->window_type == GDK_WINDOW_TEMP); + window->x, + window->y, + window->width, + window->height, + window->window_type == GDK_WINDOW_TEMP); g_hash_table_insert (broadway_display->id_ht, GINT_TO_POINTER(impl->id), window); impl->wrapper = window; g_assert (window->window_type == GDK_WINDOW_TOPLEVEL || - window->window_type == GDK_WINDOW_TEMP); + window->window_type == GDK_WINDOW_TEMP); g_assert (window->parent == NULL); broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, impl); @@ -263,14 +267,14 @@ _gdk_broadway_window_resize_surface (GdkWindow *window) cairo_surface_destroy (impl->surface); impl->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - gdk_window_get_width (impl->wrapper), - gdk_window_get_height (impl->wrapper)); + gdk_window_get_width (impl->wrapper), + gdk_window_get_height (impl->wrapper)); } if (impl->ref_surface) { cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key, - NULL, NULL); + NULL, NULL); impl->ref_surface = NULL; } @@ -306,12 +310,12 @@ gdk_window_broadway_ref_cairo_surface (GdkWindow *window) if (!impl->ref_surface) { impl->ref_surface = - cairo_surface_create_for_rectangle (impl->surface, - 0, 0, - w, h); + 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); + cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key, + impl, ref_surface_destroyed); } else cairo_surface_reference (impl->ref_surface); @@ -321,8 +325,8 @@ gdk_window_broadway_ref_cairo_surface (GdkWindow *window) static void _gdk_broadway_window_destroy (GdkWindow *window, - gboolean recursing, - gboolean foreign_destroy) + gboolean recursing, + gboolean foreign_destroy) { GdkWindowImplBroadway *impl; GdkBroadwayDisplay *broadway_display; @@ -331,6 +335,11 @@ _gdk_broadway_window_destroy (GdkWindow *window, impl = GDK_WINDOW_IMPL_BROADWAY (window->impl); + if (impl->node_data) + g_array_unref (impl->node_data); + if (impl->node_data_textures) + g_ptr_array_unref (impl->node_data_textures); + _gdk_broadway_selection_window_destroyed (window); _gdk_broadway_window_grab_check_destroy (window); @@ -338,7 +347,7 @@ _gdk_broadway_window_destroy (GdkWindow *window, { cairo_surface_finish (impl->ref_surface); cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key, - NULL, NULL); + NULL, NULL); } if (impl->surface) @@ -356,6 +365,35 @@ _gdk_broadway_window_destroy (GdkWindow *window, } +void +gdk_broadway_window_set_nodes (GdkWindow *window, + GArray *nodes, + GPtrArray *node_textures) +{ + GdkWindowImplBroadway *impl; + GdkBroadwayDisplay *broadway_display; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + impl = GDK_WINDOW_IMPL_BROADWAY (window->impl); + + broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window)); + + if (nodes) + g_array_ref (nodes); + if (impl->node_data) + g_array_unref (impl->node_data); + impl->node_data = nodes; + + if (node_textures) + g_ptr_array_ref (node_textures); + if (impl->node_data_textures) + g_ptr_array_unref (impl->node_data_textures); + impl->node_data_textures = node_textures; + + gdk_broadway_server_window_set_nodes (broadway_display->server, impl->id, impl->node_data); +} + /* This function is called when the XWindow is really gone. */ static void @@ -406,7 +444,7 @@ gdk_window_broadway_hide (GdkWindow *window) broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window)); _gdk_broadway_window_grab_check_unmap (window, - _gdk_broadway_server_get_next_serial (broadway_display->server)); + _gdk_broadway_server_get_next_serial (broadway_display->server)); if (_gdk_broadway_server_window_hide (broadway_display->server, impl->id)) queue_flush (window); @@ -422,11 +460,11 @@ gdk_window_broadway_withdraw (GdkWindow *window) static void gdk_window_broadway_move_resize (GdkWindow *window, - gboolean with_move, - gint x, - gint y, - gint width, - gint height) + gboolean with_move, + gint x, + gint y, + gint width, + gint height) { GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl); GdkBroadwayDisplay *broadway_display; @@ -439,31 +477,31 @@ gdk_window_broadway_move_resize (GdkWindow *window, if (width > 0 || height > 0) { if (width < 1) - width = 1; + width = 1; if (height < 1) - height = 1; + height = 1; if (width != window->width || - height != window->height) - { - size_changed = TRUE; + height != window->height) + { + size_changed = TRUE; - /* Resize clears the content */ - impl->dirty = TRUE; - impl->last_synced = FALSE; + /* Resize clears the content */ + impl->dirty = TRUE; + impl->last_synced = FALSE; - window->width = width; - window->height = height; - _gdk_broadway_window_resize_surface (window); - } + window->width = width; + window->height = height; + _gdk_broadway_window_resize_surface (window); + } } _gdk_broadway_server_window_move_resize (broadway_display->server, - impl->id, - with_move, - x, y, - window->width, window->height); + impl->id, + with_move, + x, y, + window->width, window->height); queue_flush (window); if (size_changed) window->resize_count++; @@ -476,8 +514,8 @@ gdk_window_broadway_raise (GdkWindow *window) static void gdk_window_broadway_restack_toplevel (GdkWindow *window, - GdkWindow *sibling, - gboolean above) + GdkWindow *sibling, + gboolean above) { } @@ -489,7 +527,7 @@ gdk_window_broadway_lower (GdkWindow *window) static void gdk_broadway_window_focus (GdkWindow *window, - guint32 timestamp) + guint32 timestamp) { GdkWindowImplBroadway *impl; GdkBroadwayDisplay *broadway_display; @@ -503,12 +541,12 @@ gdk_broadway_window_focus (GdkWindow *window, impl = GDK_WINDOW_IMPL_BROADWAY (window->impl); broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window)); _gdk_broadway_server_window_focus (broadway_display->server, - impl->id); + impl->id); } static void gdk_broadway_window_set_type_hint (GdkWindow *window, - GdkWindowTypeHint hint) + GdkWindowTypeHint hint) { } @@ -520,32 +558,32 @@ gdk_broadway_window_get_type_hint (GdkWindow *window) static void gdk_broadway_window_set_modal_hint (GdkWindow *window, - gboolean modal) + gboolean modal) { } static void gdk_broadway_window_set_skip_taskbar_hint (GdkWindow *window, - gboolean skips_taskbar) + gboolean skips_taskbar) { } static void gdk_broadway_window_set_skip_pager_hint (GdkWindow *window, - gboolean skips_pager) + gboolean skips_pager) { } static void gdk_broadway_window_set_urgency_hint (GdkWindow *window, - gboolean urgent) + gboolean urgent) { } static void gdk_broadway_window_set_geometry_hints (GdkWindow *window, - const GdkGeometry *geometry, - GdkWindowHints geom_mask) + const GdkGeometry *geometry, + GdkWindowHints geom_mask) { GdkWindowImplBroadway *impl; @@ -557,25 +595,25 @@ gdk_broadway_window_set_geometry_hints (GdkWindow *window, static void gdk_broadway_window_set_title (GdkWindow *window, - const gchar *title) + const gchar *title) { } static void gdk_broadway_window_set_role (GdkWindow *window, - const gchar *role) + const gchar *role) { } static void gdk_broadway_window_set_startup_id (GdkWindow *window, - const gchar *startup_id) + const gchar *startup_id) { } static void gdk_broadway_window_set_transient_for (GdkWindow *window, - GdkWindow *parent) + GdkWindow *parent) { GdkBroadwayDisplay *display; GdkWindowImplBroadway *impl; @@ -595,10 +633,10 @@ gdk_broadway_window_set_transient_for (GdkWindow *window, static void gdk_window_broadway_get_geometry (GdkWindow *window, - gint *x, - gint *y, - gint *width, - gint *height) + gint *x, + gint *y, + gint *width, + gint *height) { GdkWindowImplBroadway *impl; @@ -621,10 +659,10 @@ gdk_window_broadway_get_geometry (GdkWindow *window, static void gdk_window_broadway_get_root_coords (GdkWindow *window, - gint x, - gint y, - gint *root_x, - gint *root_y) + gint x, + gint y, + gint *root_x, + gint *root_y) { GdkWindowImplBroadway *impl; @@ -638,7 +676,7 @@ gdk_window_broadway_get_root_coords (GdkWindow *window, static void gdk_broadway_window_get_frame_extents (GdkWindow *window, - GdkRectangle *rect) + GdkRectangle *rect) { g_return_if_fail (rect != NULL); @@ -652,10 +690,10 @@ gdk_broadway_window_get_frame_extents (GdkWindow *window, static gboolean gdk_window_broadway_get_device_state (GdkWindow *window, - GdkDevice *device, - gdouble *x, - gdouble *y, - GdkModifierType *mask) + GdkDevice *device, + gdouble *x, + gdouble *y, + GdkModifierType *mask) { GdkWindow *child; @@ -682,7 +720,7 @@ gdk_window_broadway_get_events (GdkWindow *window) static void gdk_window_broadway_set_events (GdkWindow *window, - GdkEventMask event_mask) + GdkEventMask event_mask) { if (!GDK_WINDOW_DESTROYED (window)) { @@ -691,23 +729,23 @@ gdk_window_broadway_set_events (GdkWindow *window, static void gdk_window_broadway_shape_combine_region (GdkWindow *window, - const cairo_region_t *shape_region, - gint offset_x, - gint offset_y) + 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) + const cairo_region_t *shape_region, + gint offset_x, + gint offset_y) { } static void gdk_broadway_window_set_accept_focus (GdkWindow *window, - gboolean accept_focus) + gboolean accept_focus) { accept_focus = accept_focus != FALSE; @@ -719,7 +757,7 @@ gdk_broadway_window_set_accept_focus (GdkWindow *window, static void gdk_broadway_window_set_focus_on_map (GdkWindow *window, - gboolean focus_on_map) + gboolean focus_on_map) { focus_on_map = focus_on_map != FALSE; @@ -732,20 +770,20 @@ gdk_broadway_window_set_focus_on_map (GdkWindow *window, static void gdk_broadway_window_set_icon_list (GdkWindow *window, - GList *surfaces) + GList *surfaces) { } static void gdk_broadway_window_set_icon_name (GdkWindow *window, - const gchar *name) + const gchar *name) { if (GDK_WINDOW_DESTROYED (window) || !WINDOW_IS_TOPLEVEL (window)) return; g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"), - GUINT_TO_POINTER (name != NULL)); + GUINT_TO_POINTER (name != NULL)); } static void @@ -836,10 +874,10 @@ gdk_broadway_window_unmaximize (GdkWindow *window) gdk_synthesize_window_state (window, GDK_WINDOW_STATE_MAXIMIZED, 0); gdk_window_move_resize (window, - impl->pre_maximize_x, - impl->pre_maximize_y, - impl->pre_maximize_width, - impl->pre_maximize_height); + impl->pre_maximize_x, + impl->pre_maximize_y, + impl->pre_maximize_width, + impl->pre_maximize_height); } static void @@ -862,7 +900,7 @@ gdk_broadway_window_unfullscreen (GdkWindow *window) static void gdk_broadway_window_set_keep_above (GdkWindow *window, - gboolean setting) + gboolean setting) { g_return_if_fail (GDK_IS_WINDOW (window)); @@ -895,13 +933,13 @@ gdk_broadway_window_get_group (GdkWindow *window) static void gdk_broadway_window_set_group (GdkWindow *window, - GdkWindow *leader) + GdkWindow *leader) { } static void gdk_broadway_window_set_decorations (GdkWindow *window, - GdkWMDecoration decorations) + GdkWMDecoration decorations) { if (GDK_WINDOW_DESTROYED (window) || !WINDOW_IS_TOPLEVEL (window)) @@ -911,7 +949,7 @@ gdk_broadway_window_set_decorations (GdkWindow *window, static gboolean gdk_broadway_window_get_decorations (GdkWindow *window, - GdkWMDecoration *decorations) + GdkWMDecoration *decorations) { gboolean result = FALSE; @@ -924,7 +962,7 @@ gdk_broadway_window_get_decorations (GdkWindow *window, static void gdk_broadway_window_set_functions (GdkWindow *window, - GdkWMFunction functions) + GdkWMFunction functions) { g_return_if_fail (GDK_IS_WINDOW (window)); @@ -966,7 +1004,7 @@ struct _MoveResizeData static MoveResizeData * get_move_resize_data (GdkDisplay *display, - gboolean create) + gboolean create) { GdkBroadwayDisplay *broadway_display; MoveResizeData *mv_resize; @@ -988,8 +1026,8 @@ get_move_resize_data (GdkDisplay *display, static void update_pos (MoveResizeData *mv_resize, - gint new_root_x, - gint new_root_y) + gint new_root_x, + gint new_root_y) { gint dx, dy; @@ -1007,44 +1045,44 @@ update_pos (MoveResizeData *mv_resize, h = mv_resize->moveresize_orig_height; switch (mv_resize->resize_edge) - { - case GDK_WINDOW_EDGE_NORTH_WEST: - x += dx; - y += dy; - w -= dx; - h -= dy; - break; - case GDK_WINDOW_EDGE_NORTH: - y += dy; - h -= dy; - break; - case GDK_WINDOW_EDGE_NORTH_EAST: - y += dy; - h -= dy; - w += dx; - break; - case GDK_WINDOW_EDGE_SOUTH_WEST: - h += dy; - x += dx; - w -= dx; - break; - case GDK_WINDOW_EDGE_SOUTH_EAST: - w += dx; - h += dy; - break; - case GDK_WINDOW_EDGE_SOUTH: - h += dy; - break; - case GDK_WINDOW_EDGE_EAST: - w += dx; - break; - case GDK_WINDOW_EDGE_WEST: - x += dx; - w -= dx; - break; + { + case GDK_WINDOW_EDGE_NORTH_WEST: + x += dx; + y += dy; + w -= dx; + h -= dy; + break; + case GDK_WINDOW_EDGE_NORTH: + y += dy; + h -= dy; + break; + case GDK_WINDOW_EDGE_NORTH_EAST: + y += dy; + h -= dy; + w += dx; + break; + case GDK_WINDOW_EDGE_SOUTH_WEST: + h += dy; + x += dx; + w -= dx; + break; + case GDK_WINDOW_EDGE_SOUTH_EAST: + w += dx; + h += dy; + break; + case GDK_WINDOW_EDGE_SOUTH: + h += dy; + break; + case GDK_WINDOW_EDGE_EAST: + w += dx; + break; + case GDK_WINDOW_EDGE_WEST: + x += dx; + w -= dx; + break; default: break; - } + } x = MAX (x, 0); y = MAX (y, 0); @@ -1052,11 +1090,11 @@ update_pos (MoveResizeData *mv_resize, h = MAX (h, 1); if (mv_resize->moveresize_geom_mask) - { - gdk_window_constrain_size (&mv_resize->moveresize_geometry, - mv_resize->moveresize_geom_mask, - w, h, &w, &h); - } + { + gdk_window_constrain_size (&mv_resize->moveresize_geometry, + mv_resize->moveresize_geom_mask, + w, h, &w, &h); + } gdk_window_move_resize (mv_resize->moveresize_window, x, y, w, h); } @@ -1083,8 +1121,8 @@ finish_drag (MoveResizeData *mv_resize) static gboolean moveresize_lookahead (GdkDisplay *display, - MoveResizeData *mv_resize, - BroadwayInputMsg *event) + MoveResizeData *mv_resize, + BroadwayInputMsg *event) { GdkBroadwayDisplay *broadway_display; @@ -1095,7 +1133,7 @@ moveresize_lookahead (GdkDisplay *display, gboolean _gdk_broadway_moveresize_handle_event (GdkDisplay *display, - BroadwayInputMsg *event) + BroadwayInputMsg *event) { guint button_mask = 0; MoveResizeData *mv_resize = get_move_resize_data (display, FALSE); @@ -1137,21 +1175,21 @@ _gdk_broadway_moveresize_handle_event (GdkDisplay *display, case BROADWAY_EVENT_POINTER_MOVE: if (mv_resize->moveresize_window->resize_count > 0) - { - if (mv_resize->moveresize_pending_event) - *mv_resize->moveresize_pending_event = *event; - else - mv_resize->moveresize_pending_event = - g_memdup (event, sizeof (BroadwayInputMsg)); + { + if (mv_resize->moveresize_pending_event) + *mv_resize->moveresize_pending_event = *event; + else + mv_resize->moveresize_pending_event = + g_memdup (event, sizeof (BroadwayInputMsg)); - break; - } + break; + } if (!moveresize_lookahead (display, mv_resize, event)) - break; + break; update_pos (mv_resize, - event->pointer.root_x, - event->pointer.root_y); + event->pointer.root_x, + event->pointer.root_y); /* This should never be triggered in normal cases, but in the * case where the drag started without an implicit grab being @@ -1160,16 +1198,16 @@ _gdk_broadway_moveresize_handle_event (GdkDisplay *display, * get a permanently stuck grab. */ if ((event->pointer.state & button_mask) == 0) - finish_drag (mv_resize); + finish_drag (mv_resize); break; case BROADWAY_EVENT_BUTTON_RELEASE: update_pos (mv_resize, - event->pointer.root_x, - event->pointer.root_y); + event->pointer.root_x, + event->pointer.root_y); if (event->button.button == mv_resize->moveresize_button) - finish_drag (mv_resize); + finish_drag (mv_resize); break; default: break; @@ -1179,7 +1217,7 @@ _gdk_broadway_moveresize_handle_event (GdkDisplay *display, gboolean _gdk_broadway_moveresize_configure_done (GdkDisplay *display, - GdkWindow *window) + GdkWindow *window) { BroadwayInputMsg *tmp_event; MoveResizeData *mv_resize = get_move_resize_data (display, FALSE); @@ -1200,7 +1238,7 @@ _gdk_broadway_moveresize_configure_done (GdkDisplay *display, static void create_moveresize_window (MoveResizeData *mv_resize, - guint32 timestamp) + guint32 timestamp) { GdkGrabStatus status; GdkSeat *seat; @@ -1217,13 +1255,13 @@ create_moveresize_window (MoveResizeData *mv_resize, G_GNUC_BEGIN_IGNORE_DEPRECATIONS; status = gdk_device_grab (pointer, - mv_resize->moveresize_emulation_window, - GDK_OWNERSHIP_APPLICATION, - FALSE, - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK, - NULL, - timestamp); + mv_resize->moveresize_emulation_window, + GDK_OWNERSHIP_APPLICATION, + FALSE, + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK, + NULL, + timestamp); G_GNUC_END_IGNORE_DEPRECATIONS; if (status != GDK_GRAB_SUCCESS) @@ -1247,70 +1285,70 @@ calculate_unmoving_origin (MoveResizeData *mv_resize) mv_resize->moveresize_geometry.win_gravity == GDK_GRAVITY_STATIC) { gdk_window_get_origin (mv_resize->moveresize_window, - &mv_resize->moveresize_orig_x, - &mv_resize->moveresize_orig_y); + &mv_resize->moveresize_orig_x, + &mv_resize->moveresize_orig_y); } else { gdk_window_get_frame_extents (mv_resize->moveresize_window, &rect); gdk_window_get_geometry (mv_resize->moveresize_window, - NULL, NULL, &width, &height); + NULL, NULL, &width, &height); switch (mv_resize->moveresize_geometry.win_gravity) - { - case GDK_GRAVITY_NORTH_WEST: - mv_resize->moveresize_orig_x = rect.x; - mv_resize->moveresize_orig_y = rect.y; - break; - case GDK_GRAVITY_NORTH: - mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2; - mv_resize->moveresize_orig_y = rect.y; - break; - case GDK_GRAVITY_NORTH_EAST: - mv_resize->moveresize_orig_x = rect.x + rect.width - width; - mv_resize->moveresize_orig_y = rect.y; - break; - case GDK_GRAVITY_WEST: - mv_resize->moveresize_orig_x = rect.x; - mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2; - break; - case GDK_GRAVITY_CENTER: - mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2; - mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2; - break; - case GDK_GRAVITY_EAST: - mv_resize->moveresize_orig_x = rect.x + rect.width - width; - mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2; - break; - case GDK_GRAVITY_SOUTH_WEST: - mv_resize->moveresize_orig_x = rect.x; - mv_resize->moveresize_orig_y = rect.y + rect.height - height; - break; - case GDK_GRAVITY_SOUTH: - mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2; - mv_resize->moveresize_orig_y = rect.y + rect.height - height; - break; - case GDK_GRAVITY_SOUTH_EAST: - mv_resize->moveresize_orig_x = rect.x + rect.width - width; - mv_resize->moveresize_orig_y = rect.y + rect.height - height; - break; + { + case GDK_GRAVITY_NORTH_WEST: + mv_resize->moveresize_orig_x = rect.x; + mv_resize->moveresize_orig_y = rect.y; + break; + case GDK_GRAVITY_NORTH: + mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2; + mv_resize->moveresize_orig_y = rect.y; + break; + case GDK_GRAVITY_NORTH_EAST: + mv_resize->moveresize_orig_x = rect.x + rect.width - width; + mv_resize->moveresize_orig_y = rect.y; + break; + case GDK_GRAVITY_WEST: + mv_resize->moveresize_orig_x = rect.x; + mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2; + break; + case GDK_GRAVITY_CENTER: + mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2; + mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2; + break; + case GDK_GRAVITY_EAST: + mv_resize->moveresize_orig_x = rect.x + rect.width - width; + mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2; + break; + case GDK_GRAVITY_SOUTH_WEST: + mv_resize->moveresize_orig_x = rect.x; + mv_resize->moveresize_orig_y = rect.y + rect.height - height; + break; + case GDK_GRAVITY_SOUTH: + mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2; + mv_resize->moveresize_orig_y = rect.y + rect.height - height; + break; + case GDK_GRAVITY_SOUTH_EAST: + mv_resize->moveresize_orig_x = rect.x + rect.width - width; + mv_resize->moveresize_orig_y = rect.y + rect.height - height; + break; case GDK_GRAVITY_STATIC: - default: - mv_resize->moveresize_orig_x = rect.x; - mv_resize->moveresize_orig_y = rect.y; - break; - } + default: + mv_resize->moveresize_orig_x = rect.x; + mv_resize->moveresize_orig_y = rect.y; + break; + } } } static void gdk_broadway_window_begin_resize_drag (GdkWindow *window, - GdkWindowEdge edge, + GdkWindowEdge edge, GdkDevice *device, - gint button, - gint root_x, - gint root_y, - guint32 timestamp) + gint button, + gint root_x, + gint root_y, + guint32 timestamp) { MoveResizeData *mv_resize; GdkWindowImplBroadway *impl; @@ -1347,10 +1385,10 @@ gdk_broadway_window_begin_resize_drag (GdkWindow *window, static void gdk_broadway_window_begin_move_drag (GdkWindow *window, GdkDevice *device, - gint button, - gint root_x, - gint root_y, - guint32 timestamp) + gint button, + gint root_x, + gint root_y, + guint32 timestamp) { MoveResizeData *mv_resize; GdkWindowImplBroadway *impl; @@ -1391,7 +1429,7 @@ gdk_broadway_window_beep (GdkWindow *window) static void gdk_broadway_window_set_opacity (GdkWindow *window, - gdouble opacity) + gdouble opacity) { g_return_if_fail (GDK_IS_WINDOW (window)); diff --git a/gdk/broadway/gdkwindow-broadway.h b/gdk/broadway/gdkwindow-broadway.h index 4a2a727976..925efbf89e 100644 --- a/gdk/broadway/gdkwindow-broadway.h +++ b/gdk/broadway/gdkwindow-broadway.h @@ -72,6 +72,9 @@ struct _GdkWindowImplBroadway GdkGeometry geometry_hints; GdkWindowHints geometry_hints_mask; + + GArray *node_data; + GPtrArray *node_data_textures; }; struct _GdkWindowImplBroadwayClass diff --git a/gsk/gskbroadwayrenderer.c b/gsk/gskbroadwayrenderer.c index 9cb67a565e..fcc85831ad 100644 --- a/gsk/gskbroadwayrenderer.c +++ b/gsk/gskbroadwayrenderer.c @@ -23,7 +23,7 @@ struct _GskBroadwayRendererClass G_DEFINE_TYPE (GskBroadwayRenderer, gsk_broadway_renderer, GSK_TYPE_RENDERER) static gboolean -gsk_broadway_renderer_realize (GskRenderer *renderer, +gsk_broadway_renderer_realize (GskRenderer *self, GdkWindow *window, GError **error) { @@ -31,13 +31,36 @@ gsk_broadway_renderer_realize (GskRenderer *renderer, } static void -gsk_broadway_renderer_unrealize (GskRenderer *renderer) +gsk_broadway_renderer_unrealize (GskRenderer *self) { } +static GdkDrawingContext * +gsk_broadway_renderer_begin_draw_frame (GskRenderer *renderer, + const cairo_region_t *update_area) +{ + cairo_region_t *region; + GdkDrawingContext *result; + cairo_rectangle_int_t whole_window; + GdkWindow *window; + + window = gsk_renderer_get_window (renderer); + whole_window = (cairo_rectangle_int_t) { + 0, 0, + gdk_window_get_width (window), + gdk_window_get_height (window) + }; + region = cairo_region_create_rectangle (&whole_window); + result = gdk_window_begin_draw_frame (window, NULL, region); + cairo_region_destroy (region); + + return result; +} + + static GdkTexture * -gsk_broadway_renderer_render_texture (GskRenderer *renderer, +gsk_broadway_renderer_render_texture (GskRenderer *self, GskRenderNode *root, const graphene_rect_t *viewport) { @@ -61,34 +84,80 @@ gsk_broadway_renderer_render_texture (GskRenderer *renderer, } static void -gsk_broadway_renderer_render (GskRenderer *renderer, +add_uint32 (GArray *nodes, guint32 v) +{ + g_array_append_val (nodes, v); +} + +static void +gsk_broadway_renderer_add_node (GskRenderer *self, + GArray *nodes, + GPtrArray *node_textures, + GskRenderNode *node) +{ + GdkDisplay *display = gsk_renderer_get_display (self); + + switch (gsk_render_node_get_node_type (node)) + { + case GSK_NOT_A_RENDER_NODE: + g_assert_not_reached (); + return; + case GSK_CONTAINER_NODE: + { + guint i; + + add_uint32 (nodes, BROADWAY_NODE_CONTAINER); + add_uint32 (nodes, gsk_container_node_get_n_children (node)); + + for (i = 0; i < gsk_container_node_get_n_children (node); i++) + gsk_broadway_renderer_add_node (self, nodes, node_textures, + gsk_container_node_get_child (node, i)); + } + return; + + default: + { + int x = floorf (node->bounds.origin.x); + int y = floorf (node->bounds.origin.y); + int width = ceil (node->bounds.origin.x + node->bounds.size.width) - x; + int height = ceil (node->bounds.origin.y + node->bounds.size.height) - y; + cairo_surface_t *surface; + GdkTexture *texture; + guint32 texture_id; + cairo_t *cr; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + cr = cairo_create (surface); + cairo_translate (cr, -x, -y); + gsk_render_node_draw (node, cr); + cairo_destroy (cr); + + texture = gdk_texture_new_for_surface (surface); + g_ptr_array_add (node_textures, texture); /* Transfers ownership to node_textures */ + texture_id = gdk_broadway_display_ensure_texture (display, texture); + add_uint32 (nodes, BROADWAY_NODE_TEXTURE); + add_uint32 (nodes, x); + add_uint32 (nodes, y); + add_uint32 (nodes, width); + add_uint32 (nodes, height); + add_uint32 (nodes, texture_id); + } + return; + } +} + +static void +gsk_broadway_renderer_render (GskRenderer *self, GskRenderNode *root) { - GdkDrawingContext *context = gsk_renderer_get_drawing_context (renderer); - graphene_rect_t viewport; - cairo_t *cr; + GdkWindow *window = gsk_renderer_get_window (self); + GArray *nodes = g_array_new (FALSE, FALSE, sizeof(guint32)); + GPtrArray *node_textures = g_ptr_array_new_with_free_func (g_object_unref); - cr = gdk_drawing_context_get_cairo_context (context); - - g_return_if_fail (cr != NULL); - - gsk_renderer_get_viewport (renderer, &viewport); - - if (GSK_RENDER_MODE_CHECK (GEOMETRY)) - { - cairo_save (cr); - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_rectangle (cr, - viewport.origin.x, - viewport.origin.y, - viewport.size.width, - viewport.size.height); - cairo_set_source_rgba (cr, 0, 0, 0.85, 0.5); - cairo_stroke (cr); - cairo_restore (cr); - } - - gsk_render_node_draw (root, cr); + gsk_broadway_renderer_add_node (self, nodes, node_textures, root); + gdk_broadway_window_set_nodes (window, nodes, node_textures); + g_array_unref (nodes); + g_ptr_array_unref (node_textures); } static void @@ -96,6 +165,7 @@ gsk_broadway_renderer_class_init (GskBroadwayRendererClass *klass) { GskRendererClass *renderer_class = GSK_RENDERER_CLASS (klass); + renderer_class->begin_draw_frame = gsk_broadway_renderer_begin_draw_frame; renderer_class->realize = gsk_broadway_renderer_realize; renderer_class->unrealize = gsk_broadway_renderer_unrealize; renderer_class->render = gsk_broadway_renderer_render;