broadway: Initial version of using actual render nodes

This commit is contained in:
Alexander Larsson 2017-11-21 19:33:12 +01:00
parent cc7423855b
commit f7d8ee041b
14 changed files with 924 additions and 812 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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 {

View File

@ -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);

View File

@ -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,

File diff suppressed because it is too large Load Diff

View File

@ -289,9 +289,20 @@ client_handle_request (BroadwayClient *client,
request->update.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;

View File

@ -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,

View File

@ -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,

View File

@ -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)
{

View File

@ -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,

View File

@ -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));

View File

@ -72,6 +72,9 @@ struct _GdkWindowImplBroadway
GdkGeometry geometry_hints;
GdkWindowHints geometry_hints_mask;
GArray *node_data;
GPtrArray *node_data_textures;
};
struct _GdkWindowImplBroadwayClass

View File

@ -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;