broadway: Deserialize node tree in server
This doesn't really change anything, but it is in preparation for diffing the trees.
This commit is contained in:
@@ -296,19 +296,42 @@ broadway_output_set_transient_for (BroadwayOutput *output,
|
||||
append_uint16 (output, parent_id);
|
||||
}
|
||||
|
||||
static void
|
||||
append_node (BroadwayOutput *output,
|
||||
BroadwayNode *node)
|
||||
{
|
||||
append_uint32 (output, node->type);
|
||||
guint32 i;
|
||||
|
||||
for (i = 0; i < node->n_data; i++)
|
||||
append_uint32 (output, node->data[i]);
|
||||
for (i = 0; i < node->n_children; i++)
|
||||
append_node (output, node->children[i]);
|
||||
}
|
||||
|
||||
guint32
|
||||
get_node_size (BroadwayNode *node)
|
||||
{
|
||||
guint32 size = 1 + node->n_data;
|
||||
guint32 i;
|
||||
|
||||
for (i = 0; i < node->n_children; i++)
|
||||
size += get_node_size (node->children[i]);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
broadway_output_window_set_nodes (BroadwayOutput *output,
|
||||
int id,
|
||||
guint32 *data,
|
||||
guint32 data_len)
|
||||
BroadwayNode *root)
|
||||
{
|
||||
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]);
|
||||
append_uint32 (output, get_node_size (root));
|
||||
append_node (output, root);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include "broadway-protocol.h"
|
||||
#include "broadway-server.h"
|
||||
|
||||
typedef struct BroadwayOutput BroadwayOutput;
|
||||
|
||||
@@ -58,8 +59,7 @@ void broadway_output_set_transient_for (BroadwayOutput *output,
|
||||
int parent_id);
|
||||
void broadway_output_window_set_nodes (BroadwayOutput *output,
|
||||
int id,
|
||||
guint32 *data,
|
||||
guint32 data_len);
|
||||
BroadwayNode *root);
|
||||
void broadway_output_upload_texture (BroadwayOutput *output,
|
||||
guint32 id,
|
||||
GBytes *texture);
|
||||
|
||||
@@ -125,8 +125,7 @@ struct BroadwayWindow {
|
||||
gboolean visible;
|
||||
gint32 transient_for;
|
||||
guint32 texture;
|
||||
guint32 *nodes;
|
||||
gint nodes_len;
|
||||
BroadwayNode *nodes;
|
||||
};
|
||||
|
||||
static void broadway_server_resync_windows (BroadwayServer *server);
|
||||
@@ -136,6 +135,17 @@ static GType broadway_server_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (BroadwayServer, broadway_server, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
broadway_node_free (BroadwayNode *node)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < node->n_children; i++)
|
||||
broadway_node_free (node->children[i]);
|
||||
|
||||
g_free (node);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
broadway_server_init (BroadwayServer *server)
|
||||
{
|
||||
@@ -187,7 +197,8 @@ broadway_server_class_init (BroadwayServerClass * class)
|
||||
static void
|
||||
broadway_window_free (BroadwayWindow *window)
|
||||
{
|
||||
g_free (window->nodes);
|
||||
if (window->nodes)
|
||||
broadway_node_free (window->nodes);
|
||||
g_free (window);
|
||||
}
|
||||
|
||||
@@ -1612,11 +1623,11 @@ broadway_server_has_client (BroadwayServer *server)
|
||||
return server->output != NULL;
|
||||
}
|
||||
|
||||
/* passes ownership of nodes */
|
||||
void
|
||||
broadway_server_window_set_nodes (BroadwayServer *server,
|
||||
gint id,
|
||||
gint n_data,
|
||||
guint32 *data)
|
||||
BroadwayNode *root)
|
||||
{
|
||||
BroadwayWindow *window;
|
||||
|
||||
@@ -1624,13 +1635,13 @@ broadway_server_window_set_nodes (BroadwayServer *server,
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
g_free (window->nodes);
|
||||
window->nodes = g_memdup (data, sizeof (guint32)*n_data);
|
||||
window->nodes_len = n_data;
|
||||
if (window->nodes)
|
||||
broadway_node_free (window->nodes);
|
||||
window->nodes = root;
|
||||
|
||||
if (server->output != NULL)
|
||||
broadway_output_window_set_nodes (server->output, window->id,
|
||||
window->nodes, window->nodes_len);
|
||||
window->nodes);
|
||||
}
|
||||
|
||||
guint32
|
||||
@@ -1877,7 +1888,7 @@ broadway_server_resync_windows (BroadwayServer *server)
|
||||
|
||||
if (window->nodes)
|
||||
broadway_output_window_set_nodes (server->output, window->id,
|
||||
window->nodes, window->nodes_len);
|
||||
window->nodes);
|
||||
|
||||
if (window->visible)
|
||||
broadway_output_show_surface (server->output, window->id);
|
||||
|
||||
@@ -18,6 +18,15 @@ typedef struct _BroadwayServerClass BroadwayServerClass;
|
||||
#define BROADWAY_IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BROADWAY_TYPE_SERVER))
|
||||
#define BROADWAY_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BROADWAY_TYPE_SERVER, BroadwayServerClass))
|
||||
|
||||
typedef struct _BroadwayNode BroadwayNode;
|
||||
|
||||
struct _BroadwayNode {
|
||||
guint32 type;
|
||||
guint32 n_children;
|
||||
BroadwayNode **children;
|
||||
guint32 n_data;
|
||||
guint32 data[1];
|
||||
};
|
||||
|
||||
BroadwayServer *broadway_server_new (char *address,
|
||||
int port,
|
||||
@@ -87,8 +96,7 @@ cairo_surface_t * broadway_server_create_surface (int
|
||||
int height);
|
||||
void broadway_server_window_set_nodes (BroadwayServer *server,
|
||||
gint id,
|
||||
gint n_data,
|
||||
guint32 *data);
|
||||
BroadwayNode *root);
|
||||
gboolean broadway_server_window_move_resize (BroadwayServer *server,
|
||||
gint id,
|
||||
gboolean with_move,
|
||||
|
||||
@@ -224,66 +224,88 @@ get_client_serial (BroadwayClient *client, guint32 daemon_serial)
|
||||
#define NODE_SIZE_COLOR_STOP (NODE_SIZE_FLOAT + NODE_SIZE_COLOR)
|
||||
#define NODE_SIZE_SHADOW (NODE_SIZE_COLOR + 3 * NODE_SIZE_FLOAT)
|
||||
|
||||
static int
|
||||
rewrite_node_textures (BroadwayClient *client,
|
||||
int len, guint32 data[], int pos)
|
||||
static BroadwayNode *
|
||||
decode_nodes (BroadwayClient *client,
|
||||
int len, guint32 data[], int *pos)
|
||||
{
|
||||
BroadwayNode *node;
|
||||
guint32 type;
|
||||
guint32 i, n_children, n_stops, n_shadows;
|
||||
guint32 i, n_stops, n_shadows;
|
||||
guint32 size, n_children;
|
||||
gint32 texture_offset;
|
||||
|
||||
g_assert (pos < len);
|
||||
g_assert (*pos < len);
|
||||
|
||||
type = data[pos++];
|
||||
size = 0;
|
||||
n_children = 0;
|
||||
texture_offset = -1;
|
||||
|
||||
type = data[(*pos)++];
|
||||
switch (type) {
|
||||
case BROADWAY_NODE_COLOR:
|
||||
pos += NODE_SIZE_RECT + NODE_SIZE_COLOR;
|
||||
size = NODE_SIZE_RECT + NODE_SIZE_COLOR;
|
||||
break;
|
||||
case BROADWAY_NODE_BORDER:
|
||||
pos += NODE_SIZE_RRECT + 4 * NODE_SIZE_FLOAT + 4 * NODE_SIZE_COLOR;
|
||||
size = NODE_SIZE_RRECT + 4 * NODE_SIZE_FLOAT + 4 * NODE_SIZE_COLOR;
|
||||
break;
|
||||
case BROADWAY_NODE_INSET_SHADOW:
|
||||
case BROADWAY_NODE_OUTSET_SHADOW:
|
||||
pos += NODE_SIZE_RRECT + NODE_SIZE_COLOR + 4 * NODE_SIZE_FLOAT;
|
||||
size = NODE_SIZE_RRECT + NODE_SIZE_COLOR + 4 * NODE_SIZE_FLOAT;
|
||||
break;
|
||||
case BROADWAY_NODE_TEXTURE:
|
||||
data[pos+4] = GPOINTER_TO_INT (g_hash_table_lookup (client->textures,
|
||||
GINT_TO_POINTER (data[pos+4])));
|
||||
pos += 5;
|
||||
texture_offset = 4;
|
||||
size = 5;
|
||||
break;
|
||||
case BROADWAY_NODE_CONTAINER:
|
||||
n_children = data[pos++];
|
||||
for (i = 0; i < n_children; i++)
|
||||
pos = rewrite_node_textures (client, len, data, pos);
|
||||
size = 1;
|
||||
n_children = data[*pos];
|
||||
break;
|
||||
case BROADWAY_NODE_ROUNDED_CLIP:
|
||||
pos += NODE_SIZE_RRECT;
|
||||
pos = rewrite_node_textures (client, len, data, pos);
|
||||
size = NODE_SIZE_RRECT;
|
||||
n_children = 1;
|
||||
break;
|
||||
case BROADWAY_NODE_CLIP:
|
||||
pos += NODE_SIZE_RECT;
|
||||
pos = rewrite_node_textures (client, len, data, pos);
|
||||
size = NODE_SIZE_RECT;
|
||||
n_children = 1;
|
||||
break;
|
||||
case BROADWAY_NODE_LINEAR_GRADIENT:
|
||||
pos += NODE_SIZE_RECT + 2 * NODE_SIZE_POINT;
|
||||
n_stops = data[pos++];
|
||||
pos += n_stops * NODE_SIZE_COLOR_STOP;
|
||||
size = NODE_SIZE_RECT + 2 * NODE_SIZE_POINT;
|
||||
n_stops = data[*pos + size++];
|
||||
size += n_stops * NODE_SIZE_COLOR_STOP;
|
||||
break;
|
||||
case BROADWAY_NODE_SHADOW:
|
||||
n_shadows = data[pos++];
|
||||
pos += n_shadows * NODE_SIZE_SHADOW;
|
||||
pos = rewrite_node_textures (client, len, data, pos);
|
||||
size = 1;
|
||||
n_shadows = data[*pos];
|
||||
size += n_shadows * NODE_SIZE_SHADOW;
|
||||
n_children = 1;
|
||||
break;
|
||||
case BROADWAY_NODE_OPACITY:
|
||||
pos += NODE_SIZE_FLOAT;
|
||||
pos = rewrite_node_textures (client, len, data, pos);
|
||||
size = NODE_SIZE_FLOAT;
|
||||
n_children = 1;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
node = g_malloc (sizeof(BroadwayNode) + (size - 1) * sizeof(guint32) + n_children * sizeof (BroadwayNode *));
|
||||
node->type = type;
|
||||
node->n_children = n_children;
|
||||
node->children = (BroadwayNode **)((char *)node + sizeof(BroadwayNode) + (size - 1) * sizeof(guint32));
|
||||
node->n_data = size;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
node->data[i] = data[(*pos)++];
|
||||
if (i == texture_offset)
|
||||
node->data[i] = GPOINTER_TO_INT (g_hash_table_lookup (client->textures,
|
||||
GINT_TO_POINTER (node->data[i])));
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < n_children; i++)
|
||||
node->children[i] = decode_nodes (client, len, data, pos);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static void
|
||||
client_handle_request (BroadwayClient *client,
|
||||
@@ -360,13 +382,13 @@ client_handle_request (BroadwayClient *client,
|
||||
{
|
||||
gsize array_size = request->base.size - sizeof (BroadwayRequestSetNodes) + sizeof(guint32);
|
||||
int n_data = array_size / sizeof(guint32);
|
||||
int pos = 0;
|
||||
BroadwayNode *node;
|
||||
|
||||
rewrite_node_textures (client, n_data, request->set_nodes.data, 0);
|
||||
node = decode_nodes (client, n_data, request->set_nodes.data, &pos);
|
||||
|
||||
broadway_server_window_set_nodes (server,
|
||||
request->set_nodes.id,
|
||||
n_data,
|
||||
request->set_nodes.data);
|
||||
broadway_server_window_set_nodes (server, request->set_nodes.id,
|
||||
node);
|
||||
}
|
||||
break;
|
||||
case BROADWAY_REQUEST_UPLOAD_TEXTURE:
|
||||
|
||||
Reference in New Issue
Block a user