forked from AuroraMiddleware/gtk
mir: implement window properties
https://bugzilla.gnome.org/show_bug.cgi?id=775732
This commit is contained in:
parent
f3779b42c5
commit
ed0bd0bba2
@ -36,12 +36,45 @@
|
|||||||
|
|
||||||
#define MAX_EGL_ATTRS 30
|
#define MAX_EGL_ATTRS 30
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GdkAtom type;
|
||||||
|
GArray *array;
|
||||||
|
} GdkMirProperty;
|
||||||
|
|
||||||
|
static GdkMirProperty *
|
||||||
|
gdk_mir_property_new (GdkAtom type,
|
||||||
|
guint format,
|
||||||
|
guint capacity)
|
||||||
|
{
|
||||||
|
GdkMirProperty *property = g_slice_new (GdkMirProperty);
|
||||||
|
|
||||||
|
property->type = type;
|
||||||
|
property->array = g_array_sized_new (TRUE, FALSE, format, capacity);
|
||||||
|
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_mir_property_free (gpointer data)
|
||||||
|
{
|
||||||
|
GdkMirProperty *property = data;
|
||||||
|
|
||||||
|
if (!property)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_array_unref (property->array);
|
||||||
|
g_slice_free (GdkMirProperty, property);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct _GdkMirWindowImplClass GdkMirWindowImplClass;
|
typedef struct _GdkMirWindowImplClass GdkMirWindowImplClass;
|
||||||
|
|
||||||
struct _GdkMirWindowImpl
|
struct _GdkMirWindowImpl
|
||||||
{
|
{
|
||||||
GdkWindowImpl parent_instance;
|
GdkWindowImpl parent_instance;
|
||||||
|
|
||||||
|
GHashTable *properties;
|
||||||
|
|
||||||
/* Window we are temporary for */
|
/* Window we are temporary for */
|
||||||
GdkWindow *transient_for;
|
GdkWindow *transient_for;
|
||||||
gint transient_x;
|
gint transient_x;
|
||||||
@ -224,6 +257,7 @@ _gdk_mir_window_impl_get_cursor_state (GdkMirWindowImpl *impl,
|
|||||||
static void
|
static void
|
||||||
gdk_mir_window_impl_init (GdkMirWindowImpl *impl)
|
gdk_mir_window_impl_init (GdkMirWindowImpl *impl)
|
||||||
{
|
{
|
||||||
|
impl->properties = g_hash_table_new_full (NULL, NULL, NULL, gdk_mir_property_free);
|
||||||
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
|
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
|
||||||
impl->surface_state = mir_surface_state_unknown;
|
impl->surface_state = mir_surface_state_unknown;
|
||||||
impl->output_scale = 1;
|
impl->output_scale = 1;
|
||||||
@ -666,6 +700,8 @@ gdk_mir_window_impl_finalize (GObject *object)
|
|||||||
if (impl->cairo_surface)
|
if (impl->cairo_surface)
|
||||||
cairo_surface_destroy (impl->cairo_surface);
|
cairo_surface_destroy (impl->cairo_surface);
|
||||||
|
|
||||||
|
g_clear_pointer (&impl->properties, g_hash_table_unref);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gdk_mir_window_impl_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gdk_mir_window_impl_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1396,19 +1432,79 @@ gdk_mir_window_impl_simulate_button (GdkWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gdk_mir_window_impl_get_property (GdkWindow *window,
|
gdk_mir_window_impl_get_property (GdkWindow *window,
|
||||||
GdkAtom property,
|
GdkAtom property,
|
||||||
GdkAtom type,
|
GdkAtom type,
|
||||||
gulong offset,
|
gulong offset,
|
||||||
gulong length,
|
gulong length,
|
||||||
gint pdelete,
|
gint pdelete,
|
||||||
GdkAtom *actual_property_type,
|
GdkAtom *actual_type,
|
||||||
gint *actual_format_type,
|
gint *actual_format,
|
||||||
gint *actual_length,
|
gint *actual_length,
|
||||||
guchar **data)
|
guchar **data)
|
||||||
{
|
{
|
||||||
//g_printerr ("gdk_mir_window_impl_get_property window=%p\n", window);
|
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
|
||||||
return FALSE;
|
GdkMirProperty *mir_property;
|
||||||
|
GdkAtom dummy_actual_type;
|
||||||
|
gint dummy_actual_format;
|
||||||
|
gint dummy_actual_length;
|
||||||
|
guint width;
|
||||||
|
|
||||||
|
if (!actual_type)
|
||||||
|
actual_type = &dummy_actual_type;
|
||||||
|
if (!actual_format)
|
||||||
|
actual_format = &dummy_actual_format;
|
||||||
|
if (!actual_length)
|
||||||
|
actual_length = &dummy_actual_length;
|
||||||
|
|
||||||
|
*actual_type = GDK_NONE;
|
||||||
|
*actual_format = 0;
|
||||||
|
*actual_length = 0;
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
*data = NULL;
|
||||||
|
|
||||||
|
mir_property = g_hash_table_lookup (impl->properties, property);
|
||||||
|
|
||||||
|
if (!mir_property)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
width = g_array_get_element_size (mir_property->array);
|
||||||
|
*actual_type = mir_property->type;
|
||||||
|
*actual_format = 8 * width;
|
||||||
|
|
||||||
|
/* ICCCM 2.7: GdkAtoms can be 64-bit, but ATOMs and ATOM_PAIRs have format 32 */
|
||||||
|
if (*actual_type == GDK_SELECTION_TYPE_ATOM || *actual_type == gdk_atom_intern_static_string ("ATOM_PAIR"))
|
||||||
|
*actual_format = 32;
|
||||||
|
|
||||||
|
if (type != GDK_NONE && type != mir_property->type)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
offset *= 4;
|
||||||
|
|
||||||
|
/* round up to next nearest multiple of width */
|
||||||
|
if (length < G_MAXULONG - width + 1)
|
||||||
|
length = (length - 1 + width) / width * width;
|
||||||
|
else
|
||||||
|
length = G_MAXULONG / width * width;
|
||||||
|
|
||||||
|
/* we're skipping the first offset bytes */
|
||||||
|
if (length > mir_property->array->len * width - offset)
|
||||||
|
length = mir_property->array->len * width - offset;
|
||||||
|
|
||||||
|
/* leave room for null terminator */
|
||||||
|
if (length > G_MAXULONG - width)
|
||||||
|
length -= width;
|
||||||
|
|
||||||
|
*actual_length = length;
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
*data = g_memdup (mir_property->array->data + offset, length + width);
|
||||||
|
memset (*data + length, 0, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1418,16 +1514,67 @@ gdk_mir_window_impl_change_property (GdkWindow *window,
|
|||||||
gint format,
|
gint format,
|
||||||
GdkPropMode mode,
|
GdkPropMode mode,
|
||||||
const guchar *data,
|
const guchar *data,
|
||||||
gint nelements)
|
gint n_elements)
|
||||||
{
|
{
|
||||||
//g_printerr ("gdk_mir_window_impl_change_property window=%p\n", window);
|
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
|
||||||
|
GdkMirProperty *mir_property;
|
||||||
|
GdkEvent *event;
|
||||||
|
|
||||||
|
/* ICCCM 2.7: ATOMs and ATOM_PAIRs have format 32, but GdkAtoms can be 64-bit */
|
||||||
|
if (type == GDK_SELECTION_TYPE_ATOM || type == gdk_atom_intern_static_string ("ATOM_PAIR"))
|
||||||
|
format = 8 * sizeof (GdkAtom);
|
||||||
|
|
||||||
|
if (mode != GDK_PROP_MODE_REPLACE)
|
||||||
|
mir_property = g_hash_table_lookup (impl->properties, property);
|
||||||
|
else
|
||||||
|
mir_property = NULL;
|
||||||
|
|
||||||
|
if (!mir_property)
|
||||||
|
{
|
||||||
|
/* format is measured in bits, but we need to know this in bytes */
|
||||||
|
mir_property = gdk_mir_property_new (type, format / 8, n_elements);
|
||||||
|
g_hash_table_insert (impl->properties, property, mir_property);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* format is measured in bits, but we need to know this in bytes */
|
||||||
|
if (type != mir_property->type || format / 8 != g_array_get_element_size (mir_property->array))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mode == GDK_PROP_MODE_PREPEND)
|
||||||
|
g_array_prepend_vals (mir_property->array, data, n_elements);
|
||||||
|
else
|
||||||
|
g_array_append_vals (mir_property->array, data, n_elements);
|
||||||
|
|
||||||
|
event = gdk_event_new (GDK_PROPERTY_NOTIFY);
|
||||||
|
event->property.window = g_object_ref (window);
|
||||||
|
event->property.send_event = FALSE;
|
||||||
|
event->property.atom = property;
|
||||||
|
event->property.time = GDK_CURRENT_TIME;
|
||||||
|
event->property.state = GDK_PROPERTY_NEW_VALUE;
|
||||||
|
|
||||||
|
gdk_event_put (event);
|
||||||
|
gdk_event_free (event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_mir_window_impl_delete_property (GdkWindow *window,
|
gdk_mir_window_impl_delete_property (GdkWindow *window,
|
||||||
GdkAtom property)
|
GdkAtom property)
|
||||||
{
|
{
|
||||||
//g_printerr ("gdk_mir_window_impl_delete_property window=%p\n", window);
|
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
|
||||||
|
GdkEvent *event;
|
||||||
|
|
||||||
|
if (g_hash_table_remove (impl->properties, property))
|
||||||
|
{
|
||||||
|
event = gdk_event_new (GDK_PROPERTY_NOTIFY);
|
||||||
|
event->property.window = g_object_ref (window);
|
||||||
|
event->property.send_event = FALSE;
|
||||||
|
event->property.atom = property;
|
||||||
|
event->property.time = GDK_CURRENT_TIME;
|
||||||
|
event->property.state = GDK_PROPERTY_DELETE;
|
||||||
|
|
||||||
|
gdk_event_put (event);
|
||||||
|
gdk_event_free (event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
|
Loading…
Reference in New Issue
Block a user