Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 49e93f6ee4 | |||
| 4ec2234537 | |||
| 5a3755b233 |
+2
-7
@@ -26,7 +26,7 @@ variables:
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Ddemos=false -Dbuild-examples=false -Dbuild-tests=false -Dbuild-testsuite=true"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v42"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v41"
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
@@ -60,10 +60,6 @@ style-check-diff:
|
||||
- "${CI_PROJECT_DIR}/_build/report-x11_unstable.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_unstable.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_gles.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_gles_unstable.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_smalltexture.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_smalltexture_unstable.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-broadway_unstable.xml"
|
||||
name: "gtk-${CI_COMMIT_REF_NAME}"
|
||||
@@ -108,8 +104,7 @@ fedora-x86_64:
|
||||
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
- .gitlab-ci/run-tests.sh _build wayland_gles
|
||||
- .gitlab-ci/run-tests.sh _build wayland_smalltexture
|
||||
- .gitlab-ci/run-tests.sh _build waylandgles
|
||||
- .gitlab-ci/run-tests.sh _build broadway
|
||||
|
||||
release-build:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM fedora:38
|
||||
FROM fedora:37
|
||||
|
||||
RUN dnf -y install \
|
||||
adwaita-icon-theme \
|
||||
|
||||
@@ -20,7 +20,6 @@ flatpak build ${builddir} meson \
|
||||
-Dx11-backend=true \
|
||||
-Dwayland-backend=true \
|
||||
-Dbuild-tests=false \
|
||||
-Dbuild-testsuite=false \
|
||||
-Dbuild-examples=false \
|
||||
-Dintrospection=disabled \
|
||||
-Ddemos=true \
|
||||
|
||||
+28
-1
@@ -36,7 +36,7 @@ case "${backend}" in
|
||||
--suite=failing || true
|
||||
;;
|
||||
|
||||
wayland*)
|
||||
wayland)
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
|
||||
@@ -63,6 +63,33 @@ case "${backend}" in
|
||||
kill ${compositor}
|
||||
;;
|
||||
|
||||
waylandgles)
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
weston --backend=headless-backend.so --socket=wayland-6 --idle-time=0 &
|
||||
compositor=$!
|
||||
export WAYLAND_DISPLAY=wayland-6
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
--no-suite=failing \
|
||||
--no-suite=flaky \
|
||||
--no-suite=gsk-compare-broadway
|
||||
exit_code=$?
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend}_unstable \
|
||||
--suite=flaky \
|
||||
--suite=failing || true
|
||||
|
||||
kill ${compositor}
|
||||
;;
|
||||
|
||||
broadway)
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
|
||||
@@ -1,111 +1,5 @@
|
||||
Overview of Changes in 4.11.1, xx-xx-xxxx
|
||||
=========================================
|
||||
|
||||
Overview of Changes in 4.10.1, 14-03-2023
|
||||
=========================================
|
||||
|
||||
* GtkFileChooser
|
||||
- Improve search performance
|
||||
- Be safe against pathless files
|
||||
- Fix memory leaks
|
||||
- Only show local files in recent files
|
||||
- Show most recent files first
|
||||
- Make files non-selectable in selet_folder mode
|
||||
|
||||
* GtkListView / GtkColumnView / GtkGridView
|
||||
- Fix scrolling problems
|
||||
- Support CSS border-spacing
|
||||
|
||||
* GtkComboBox
|
||||
- Fix a size allocation problem
|
||||
|
||||
* gtk
|
||||
- Size allocation fixes
|
||||
|
||||
* Accessibility
|
||||
- Miscellaneous property fixes and improvements
|
||||
|
||||
* Wayland
|
||||
- Fix an ordering problem in surface disposal
|
||||
|
||||
* Windows
|
||||
- Fix Visual Studio build with older GLib
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Bulgarian
|
||||
Catalan
|
||||
Czech
|
||||
Danish
|
||||
Finnish
|
||||
Friulian
|
||||
Galician
|
||||
Georgian
|
||||
Hungarian
|
||||
Lithuanian
|
||||
Polish
|
||||
Portuguese
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.10.0, 04-03-2023
|
||||
=========================================
|
||||
|
||||
* GtkTextView
|
||||
- Document hanging indentation
|
||||
|
||||
* GtkListView
|
||||
- Fix a size allocation problem
|
||||
|
||||
* GtkFileChooser
|
||||
- Fix paned behavior
|
||||
- Fix a crash
|
||||
|
||||
* GtkText
|
||||
- Fix various problems with undo
|
||||
|
||||
* Accessibility
|
||||
- Make some getters transfer-full
|
||||
- Allow setting accessible parents and siblings
|
||||
- Add a role for toggle buttons
|
||||
- Miscellaneous property fixes and improvements
|
||||
|
||||
* gtk
|
||||
- Improve the handling resize-during-size-allocate
|
||||
|
||||
* gdk
|
||||
- Introduce GdkTextureDownloader and use it
|
||||
- Make gdk_texture_get_format public
|
||||
|
||||
* gsk
|
||||
- Make mask nodes more versatile
|
||||
- Improve the GL implementation for texture scale nodes
|
||||
|
||||
* X11
|
||||
- Fix key handling during DND
|
||||
|
||||
* Tools
|
||||
- gtk-builder-tool: Try harder to handle templates
|
||||
- gtk-builder-tool: Prefer properties over <child>
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Belarusian
|
||||
Bulgarian
|
||||
Indonesian
|
||||
Galician
|
||||
Georgian
|
||||
German
|
||||
Hebrew
|
||||
Lithuanian
|
||||
Portuguese
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
Overview of Changes in 4.9.5, xx-xx-xxxx
|
||||
========================================
|
||||
|
||||
Overview of Changes in 4.9.4, 12-02-2023
|
||||
========================================
|
||||
|
||||
@@ -9,7 +9,7 @@ constraint_editor_sources = [
|
||||
|
||||
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
|
||||
'constraint-editor.gresource.xml',
|
||||
source_dir: meson.current_source_dir(),
|
||||
source_dir: '.',
|
||||
)
|
||||
|
||||
executable('gtk4-constraint-editor',
|
||||
|
||||
+24
-171
@@ -5,8 +5,7 @@ enum
|
||||
{
|
||||
PROP_TEXTURE = 1,
|
||||
PROP_FILTER,
|
||||
PROP_SCALE,
|
||||
PROP_ANGLE,
|
||||
PROP_SCALE
|
||||
};
|
||||
|
||||
struct _Demo3Widget
|
||||
@@ -15,7 +14,6 @@ struct _Demo3Widget
|
||||
|
||||
GdkTexture *texture;
|
||||
float scale;
|
||||
float angle;
|
||||
GskScalingFilter filter;
|
||||
|
||||
GtkWidget *menu;
|
||||
@@ -28,85 +26,10 @@ struct _Demo3WidgetClass
|
||||
|
||||
G_DEFINE_TYPE (Demo3Widget, demo3_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
static gboolean
|
||||
query_tooltip (GtkWidget *widget,
|
||||
int x,
|
||||
int y,
|
||||
gboolean keyboard_mode,
|
||||
GtkTooltip *tooltip,
|
||||
gpointer data)
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
GtkWidget *grid;
|
||||
GtkWidget *label;
|
||||
char *s, *s2;
|
||||
const char *filter[] = { "Linear", "Nearest", "Trilinear" };
|
||||
int precision, l;
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
|
||||
label = gtk_label_new ("Texture");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
||||
s = g_strdup_printf ("%d\342\200\206\303\227\342\200\206%d",
|
||||
gdk_texture_get_width (self->texture),
|
||||
gdk_texture_get_height (self->texture));
|
||||
label = gtk_label_new (s);
|
||||
g_free (s);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Rotation");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
|
||||
s = g_strdup_printf ("%.1f", self->angle);
|
||||
if (g_str_has_suffix (s, ".0"))
|
||||
s[strlen (s) - 2] = '\0';
|
||||
s2 = g_strconcat (s, "\302\260", NULL);
|
||||
label = gtk_label_new (s2);
|
||||
g_free (s2);
|
||||
g_free (s);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Scale");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
|
||||
|
||||
precision = 1;
|
||||
do {
|
||||
s = g_strdup_printf ("%.*f", precision, self->scale);
|
||||
l = strlen (s) - 1;
|
||||
while (s[l] == '0')
|
||||
l--;
|
||||
if (s[l] == '.')
|
||||
s[l] = '\0';
|
||||
precision++;
|
||||
} while (strcmp (s, "0") == 0);
|
||||
|
||||
label = gtk_label_new (s);
|
||||
g_free (s);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 2, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Filter");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
|
||||
label = gtk_label_new (filter[self->filter]);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 3, 1, 1);
|
||||
|
||||
gtk_tooltip_set_custom (tooltip, grid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
demo3_widget_init (Demo3Widget *self)
|
||||
{
|
||||
self->scale = 1.f;
|
||||
self->angle = 0.f;
|
||||
self->filter = GSK_SCALING_FILTER_LINEAR;
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
@@ -129,35 +52,26 @@ demo3_widget_snapshot (GtkWidget *widget,
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
int x, y, width, height;
|
||||
double w, h, w2, h2;
|
||||
double w, h;
|
||||
GskRenderNode *node;
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
w2 = w = self->scale * gdk_texture_get_width (self->texture);
|
||||
h2 = h = self->scale * gdk_texture_get_height (self->texture);
|
||||
w = self->scale * gdk_texture_get_width (self->texture);
|
||||
h = self->scale * gdk_texture_get_height (self->texture);
|
||||
|
||||
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) ||
|
||||
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON))
|
||||
{
|
||||
double s = w2;
|
||||
w2 = h2;
|
||||
h2 = s;
|
||||
}
|
||||
|
||||
x = (width - ceil (w2)) / 2;
|
||||
y = (height - ceil (h2)) / 2;
|
||||
x = MAX (0, (width - ceil (w)) / 2);
|
||||
y = MAX (0, (height - ceil (h)) / 2);
|
||||
|
||||
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (w2 / 2, h2 / 2));
|
||||
gtk_snapshot_rotate (snapshot, self->angle);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- w / 2, - h / 2));
|
||||
gtk_snapshot_append_scaled_texture (snapshot,
|
||||
self->texture,
|
||||
self->filter,
|
||||
&GRAPHENE_RECT_INIT (0, 0, w, h));
|
||||
node = gsk_texture_scale_node_new (self->texture,
|
||||
&GRAPHENE_RECT_INIT (0, 0, w, h),
|
||||
self->filter);
|
||||
gtk_snapshot_append_node (snapshot, node);
|
||||
gsk_render_node_unref (node);
|
||||
gtk_snapshot_restore (snapshot);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
@@ -172,26 +86,14 @@ demo3_widget_measure (GtkWidget *widget,
|
||||
int *natural_baseline)
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
int width, height;
|
||||
int size;
|
||||
|
||||
width = gdk_texture_get_width (self->texture);
|
||||
height = gdk_texture_get_height (self->texture);
|
||||
|
||||
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) ||
|
||||
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON))
|
||||
{
|
||||
int s = width;
|
||||
width = height;
|
||||
height = s;
|
||||
}
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
size = width;
|
||||
size = gdk_texture_get_width (self->texture);
|
||||
else
|
||||
size = height;
|
||||
size = gdk_texture_get_height (self->texture);
|
||||
|
||||
*minimum = *natural = (int) ceil (self->scale * size);
|
||||
*minimum = *natural = self->scale * size;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -209,8 +111,6 @@ demo3_widget_size_allocate (GtkWidget *widget,
|
||||
gtk_popover_present (GTK_POPOVER (self->menu));
|
||||
}
|
||||
|
||||
static void update_actions (Demo3Widget *self);
|
||||
|
||||
static void
|
||||
demo3_widget_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -224,24 +124,11 @@ demo3_widget_set_property (GObject *object,
|
||||
case PROP_TEXTURE:
|
||||
g_clear_object (&self->texture);
|
||||
self->texture = g_value_dup_object (value);
|
||||
self->scale = 1.f;
|
||||
self->angle = 0.f;
|
||||
self->filter = GSK_SCALING_FILTER_LINEAR;
|
||||
update_actions (self);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
g_object_notify (object, "scale");
|
||||
g_object_notify (object, "angle");
|
||||
g_object_notify (object, "filter");
|
||||
break;
|
||||
|
||||
case PROP_SCALE:
|
||||
self->scale = g_value_get_float (value);
|
||||
update_actions (self);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
case PROP_ANGLE:
|
||||
self->angle = fmodf (g_value_get_float (value), 360.f);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
@@ -274,10 +161,6 @@ demo3_widget_get_property (GObject *object,
|
||||
g_value_set_float (value, self->scale);
|
||||
break;
|
||||
|
||||
case PROP_ANGLE:
|
||||
g_value_set_float (value, self->angle);
|
||||
break;
|
||||
|
||||
case PROP_FILTER:
|
||||
g_value_set_enum (value, self->filter);
|
||||
break;
|
||||
@@ -303,14 +186,6 @@ pressed_cb (GtkGestureClick *gesture,
|
||||
gtk_popover_popup (GTK_POPOVER (self->menu));
|
||||
}
|
||||
|
||||
static void
|
||||
update_actions (Demo3Widget *self)
|
||||
{
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.in", self->scale < 1024.);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.out", self->scale > 1./1024.);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.reset", self->scale != 1.);
|
||||
}
|
||||
|
||||
static void
|
||||
zoom_cb (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
@@ -320,30 +195,19 @@ zoom_cb (GtkWidget *widget,
|
||||
float scale;
|
||||
|
||||
if (g_str_equal (action_name, "zoom.in"))
|
||||
scale = MIN (1024., self->scale * M_SQRT2);
|
||||
scale = MIN (10, self->scale * M_SQRT2);
|
||||
else if (g_str_equal (action_name, "zoom.out"))
|
||||
scale = MAX (1./1024., self->scale / M_SQRT2);
|
||||
else if (g_str_equal (action_name, "zoom.reset"))
|
||||
scale = 1.0;
|
||||
scale = MAX (0.01, self->scale / M_SQRT2);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
scale = 1.0;
|
||||
|
||||
gtk_widget_action_set_enabled (widget, "zoom.in", scale < 10);
|
||||
gtk_widget_action_set_enabled (widget, "zoom.out", scale > 0.01);
|
||||
gtk_widget_action_set_enabled (widget, "zoom.reset", scale != 1);
|
||||
|
||||
g_object_set (widget, "scale", scale, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
rotate_cb (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
int angle;
|
||||
|
||||
g_variant_get (parameter, "i", &angle);
|
||||
|
||||
g_object_set (widget, "angle", fmodf (self->angle + angle, 360.f), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
demo3_widget_class_init (Demo3WidgetClass *class)
|
||||
{
|
||||
@@ -365,12 +229,7 @@ demo3_widget_class_init (Demo3WidgetClass *class)
|
||||
|
||||
g_object_class_install_property (object_class, PROP_SCALE,
|
||||
g_param_spec_float ("scale", NULL, NULL,
|
||||
1./1024., 1024., 1.0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ANGLE,
|
||||
g_param_spec_float ("angle", NULL, NULL,
|
||||
0.0, 360.0, 0.0,
|
||||
0.0, 10.0, 1.0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_FILTER,
|
||||
@@ -382,7 +241,6 @@ demo3_widget_class_init (Demo3WidgetClass *class)
|
||||
gtk_widget_class_install_action (widget_class, "zoom.in", NULL, zoom_cb);
|
||||
gtk_widget_class_install_action (widget_class, "zoom.out", NULL, zoom_cb);
|
||||
gtk_widget_class_install_action (widget_class, "zoom.reset", NULL, zoom_cb);
|
||||
gtk_widget_class_install_action (widget_class, "rotate", "i", rotate_cb);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/menu/demo3widget.ui");
|
||||
gtk_widget_class_bind_template_child (widget_class, Demo3Widget, menu);
|
||||
@@ -397,12 +255,7 @@ demo3_widget_new (const char *resource)
|
||||
|
||||
texture = gdk_texture_new_from_resource (resource);
|
||||
|
||||
self = g_object_new (DEMO3_TYPE_WIDGET,
|
||||
"texture", texture,
|
||||
"has-tooltip", TRUE,
|
||||
NULL);
|
||||
|
||||
g_signal_connect (self, "query-tooltip", G_CALLBACK (query_tooltip), NULL);
|
||||
self = g_object_new (DEMO3_TYPE_WIDGET, "texture", texture, NULL);
|
||||
|
||||
g_object_unref (texture);
|
||||
|
||||
|
||||
@@ -12,11 +12,6 @@
|
||||
<attribute name="label">1∶1</attribute>
|
||||
<attribute name="action">zoom.reset</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label">Rotate</attribute>
|
||||
<attribute name="action">rotate</attribute>
|
||||
<attribute name="target" type="i">90</attribute>
|
||||
</item>
|
||||
</menu>
|
||||
<template class="Demo3Widget">
|
||||
<child>
|
||||
|
||||
+203
-195
@@ -30,86 +30,90 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<signal name="row-activated" handler="row_activated"/>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
|
||||
<object class="GtkFrame">
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<property name="show-separators">1</property>
|
||||
<signal name="row-activated" handler="row_activated"/>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
</style>
|
||||
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkLabel" id="switch_label">
|
||||
<property name="label" translatable="yes">Switch</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switch">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="switch_label">
|
||||
<property name="label" translatable="yes">Switch</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switch">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkLabel" id="check_label">
|
||||
<property name="label" translatable="yes">Check</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="check">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="active">1</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="check_label">
|
||||
<property name="label" translatable="yes">Check</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="check">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkLabel" id="image_label">
|
||||
<property name="label" translatable="yes">Click here!</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image">
|
||||
<property name="icon-name">object-select-symbolic</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="opacity">0</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="image_label">
|
||||
<property name="label" translatable="yes">Click here!</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image">
|
||||
<property name="icon-name">object-select-symbolic</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="opacity">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -130,142 +134,146 @@
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<property name="show-separators">1</property>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
</style>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="scale_label">
|
||||
<property name="label" translatable="yes">Scale</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="draw-value">0</property>
|
||||
<property name="width-request">150</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="scale_label">
|
||||
<property name="label" translatable="yes">Scale</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="draw-value">0</property>
|
||||
<property name="width-request">150</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="spin_label">
|
||||
<property name="label" translatable="yes">Spinbutton</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="dropdown_label">
|
||||
<property name="label" translatable="yes">Dropdown</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Choice 1</item>
|
||||
<item>Choice 2</item>
|
||||
<item>Choice 3</item>
|
||||
<item>Choice 4</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="spin_label">
|
||||
<property name="label" translatable="yes">Spinbutton</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="dropdown_label">
|
||||
<property name="label" translatable="yes">Dropdown</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Choice 1</item>
|
||||
<item>Choice 2</item>
|
||||
<item>Choice 3</item>
|
||||
<item>Choice 4</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="entry_label">
|
||||
<property name="label" translatable="yes">Entry</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="placeholder-text">Type here…</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="entry_label">
|
||||
<property name="label" translatable="yes">Entry</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="placeholder-text">Type here…</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
+14
-133
@@ -1,120 +1,18 @@
|
||||
/* Image Scaling
|
||||
* #Keywords: zoom, scale, filter, action, menu
|
||||
/* Menu
|
||||
* #Keywords: action, zoom
|
||||
*
|
||||
* Demonstrates how to add a context menu to a custom widget
|
||||
* and connect it with widget actions.
|
||||
*
|
||||
* The custom widget we create here is similar to a GtkPicture,
|
||||
* but allows setting a zoom level and filtering mode for the
|
||||
* displayed paintable.
|
||||
* but allows setting a zoom level for the displayed paintable.
|
||||
*
|
||||
* It also demonstrates how to add a context menu to a custom
|
||||
* widget and connect it with widget actions.
|
||||
*
|
||||
* The context menu has items to change the zoom level.
|
||||
* Our context menu has items to change the zoom level.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "demo3widget.h"
|
||||
|
||||
static void
|
||||
file_opened (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *data)
|
||||
{
|
||||
GFile *file;
|
||||
GError *error = NULL;
|
||||
GdkTexture *texture;
|
||||
|
||||
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
texture = gdk_texture_new_from_file (file, &error);
|
||||
g_object_unref (file);
|
||||
if (!texture)
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_set (G_OBJECT (data), "texture", texture, NULL);
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
open_file (GtkWidget *picker,
|
||||
GtkWidget *demo)
|
||||
{
|
||||
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (picker));
|
||||
GtkFileDialog *dialog;
|
||||
GtkFileFilter *filter;
|
||||
GListStore *filters;
|
||||
|
||||
dialog = gtk_file_dialog_new ();
|
||||
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_set_name (filter, "Images");
|
||||
gtk_file_filter_add_pixbuf_formats (filter);
|
||||
filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
|
||||
g_list_store_append (filters, filter);
|
||||
g_object_unref (filter);
|
||||
|
||||
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
|
||||
g_object_unref (filters);
|
||||
|
||||
gtk_file_dialog_open (dialog, parent, NULL, file_opened, demo);
|
||||
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
rotate (GtkWidget *button,
|
||||
GtkWidget *demo)
|
||||
{
|
||||
float angle;
|
||||
|
||||
g_object_get (demo, "angle", &angle, NULL);
|
||||
|
||||
angle = fmodf (angle + 90.f, 360.f);
|
||||
|
||||
g_object_set (demo, "angle", angle, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
transform_to (GBinding *binding,
|
||||
const GValue *src,
|
||||
GValue *dest,
|
||||
gpointer user_data)
|
||||
{
|
||||
double from;
|
||||
float to;
|
||||
|
||||
from = g_value_get_double (src);
|
||||
to = (float) pow (2., from);
|
||||
g_value_set_float (dest, to);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
transform_from (GBinding *binding,
|
||||
const GValue *src,
|
||||
GValue *dest,
|
||||
gpointer user_data)
|
||||
{
|
||||
float to;
|
||||
double from;
|
||||
|
||||
to = g_value_get_float (src);
|
||||
from = log2 (to);
|
||||
g_value_set_double (dest, from);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_menu (GtkWidget *do_widget)
|
||||
@@ -129,10 +27,9 @@ do_menu (GtkWidget *do_widget)
|
||||
GtkWidget *widget;
|
||||
GtkWidget *scale;
|
||||
GtkWidget *dropdown;
|
||||
GtkWidget *button;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Image Scaling");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Menu");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
@@ -151,35 +48,19 @@ do_menu (GtkWidget *do_widget)
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_box_append (GTK_BOX (box), box2);
|
||||
|
||||
button = gtk_button_new_from_icon_name ("document-open-symbolic");
|
||||
gtk_widget_set_tooltip_text (button, "Open File");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (open_file), widget);
|
||||
gtk_box_append (GTK_BOX (box2), button);
|
||||
|
||||
button = gtk_button_new_from_icon_name ("object-rotate-right-symbolic");
|
||||
gtk_widget_set_tooltip_text (button, "Rotate");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (rotate), widget);
|
||||
gtk_box_append (GTK_BOX (box2), button);
|
||||
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10., 10., 0.1);
|
||||
gtk_scale_add_mark (GTK_SCALE (scale), 0., GTK_POS_TOP, NULL);
|
||||
gtk_widget_set_tooltip_text (scale, "Zoom");
|
||||
gtk_range_set_value (GTK_RANGE (scale), 0.);
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
|
||||
gtk_range_set_value (GTK_RANGE (scale), 1.0);
|
||||
gtk_widget_set_hexpand (scale, TRUE);
|
||||
gtk_box_append (GTK_BOX (box2), scale);
|
||||
|
||||
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
|
||||
gtk_widget_set_tooltip_text (dropdown, "Filter");
|
||||
gtk_box_append (GTK_BOX (box2), dropdown);
|
||||
|
||||
g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);
|
||||
|
||||
g_object_bind_property_full (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
|
||||
widget, "scale",
|
||||
G_BINDING_BIDIRECTIONAL,
|
||||
transform_to,
|
||||
transform_from,
|
||||
NULL, NULL);
|
||||
|
||||
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
|
||||
widget, "scale",
|
||||
G_BINDING_BIDIRECTIONAL);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -225,7 +225,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
|
||||
else
|
||||
gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
|
||||
'demo.gresource.xml',
|
||||
source_dir: meson.current_source_dir()
|
||||
source_dir: '.',
|
||||
)
|
||||
endif
|
||||
|
||||
|
||||
@@ -13,13 +13,20 @@
|
||||
static GtkWidget *app_picker;
|
||||
|
||||
static void
|
||||
set_file (GFile *file,
|
||||
gpointer data)
|
||||
file_opened (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *data)
|
||||
{
|
||||
GFile *file;
|
||||
GError *error = NULL;
|
||||
char *name;
|
||||
|
||||
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
gtk_widget_set_sensitive (app_picker, FALSE);
|
||||
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
|
||||
return;
|
||||
@@ -33,25 +40,6 @@ set_file (GFile *file,
|
||||
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
file_opened (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *data)
|
||||
{
|
||||
GFile *file;
|
||||
GError *error = NULL;
|
||||
|
||||
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
set_file (file, data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
abort_mission (gpointer data)
|
||||
{
|
||||
@@ -142,28 +130,11 @@ launch_uri (GtkButton *picker)
|
||||
g_object_unref (launcher);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_drop (GtkDropTarget *target,
|
||||
const GValue *value,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
set_file (g_value_get_object (value), data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_pickers (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *table, *label, *picker, *button;
|
||||
GtkDropTarget *drop_target;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
@@ -208,13 +179,7 @@ do_pickers (GtkWidget *do_widget)
|
||||
|
||||
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
button = gtk_button_new_from_icon_name ("document-open-symbolic");
|
||||
|
||||
label = gtk_label_new ("None");
|
||||
|
||||
drop_target = gtk_drop_target_new (G_TYPE_FILE, GDK_ACTION_COPY);
|
||||
g_signal_connect (drop_target, "drop", G_CALLBACK (on_drop), label);
|
||||
gtk_widget_add_controller (button, GTK_EVENT_CONTROLLER (drop_target));
|
||||
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
|
||||
@@ -22,7 +22,6 @@ show_shortcuts (GtkWidget *window,
|
||||
gtk_window_set_transient_for (GTK_WINDOW (overlay), GTK_WINDOW (window));
|
||||
g_object_set (overlay, "view-name", view, NULL);
|
||||
g_object_unref (builder);
|
||||
gtk_window_present (GTK_WINDOW (overlay));
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
|
||||
@@ -8,7 +8,7 @@ iconbrowser_sources = [
|
||||
|
||||
iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
|
||||
'iconbrowser.gresource.xml',
|
||||
source_dir: meson.current_source_dir(),
|
||||
source_dir: '.',
|
||||
)
|
||||
|
||||
executable('gtk4-icon-browser',
|
||||
|
||||
@@ -7,7 +7,7 @@ node_editor_sources = [
|
||||
|
||||
node_editor_resources = gnome.compile_resources('node_editor_resources',
|
||||
'node-editor.gresource.xml',
|
||||
source_dir: meson.current_source_dir(),
|
||||
source_dir: '.',
|
||||
)
|
||||
|
||||
executable('gtk4-node-editor',
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
#include "gsk/vulkan/gskvulkanrenderer.h"
|
||||
#endif
|
||||
|
||||
#include <cairo.h>
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
#include <cairo-svg.h>
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gsize start_chars;
|
||||
@@ -648,34 +643,23 @@ save_cb (GtkWidget *button,
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
create_node (NodeEditorWindow *self)
|
||||
static GdkTexture *
|
||||
create_texture (NodeEditorWindow *self)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
GtkSnapshot *snapshot;
|
||||
GskRenderer *renderer;
|
||||
GskRenderNode *node;
|
||||
GdkTexture *texture;
|
||||
|
||||
paintable = gtk_picture_get_paintable (GTK_PICTURE (self->picture));
|
||||
if (paintable == NULL ||
|
||||
gdk_paintable_get_intrinsic_width (paintable) <= 0 ||
|
||||
gdk_paintable_get_intrinsic_height (paintable) <= 0)
|
||||
return NULL;
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gdk_paintable_snapshot (paintable, snapshot, gdk_paintable_get_intrinsic_width (paintable), gdk_paintable_get_intrinsic_height (paintable));
|
||||
node = gtk_snapshot_free_to_node (snapshot);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
create_texture (NodeEditorWindow *self)
|
||||
{
|
||||
GskRenderer *renderer;
|
||||
GskRenderNode *node;
|
||||
GdkTexture *texture;
|
||||
|
||||
node = create_node (self);
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -686,58 +670,6 @@ create_texture (NodeEditorWindow *self)
|
||||
return texture;
|
||||
}
|
||||
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
static cairo_status_t
|
||||
cairo_serializer_write (gpointer user_data,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
g_byte_array_append (user_data, data, length);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
create_svg (GskRenderNode *node,
|
||||
GError **error)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
graphene_rect_t bounds;
|
||||
GByteArray *array;
|
||||
|
||||
gsk_render_node_get_bounds (node, &bounds);
|
||||
array = g_byte_array_new ();
|
||||
|
||||
surface = cairo_svg_surface_create_for_stream (cairo_serializer_write,
|
||||
array,
|
||||
bounds.size.width,
|
||||
bounds.size.height);
|
||||
cairo_svg_surface_set_document_unit (surface, CAIRO_SVG_UNIT_PX);
|
||||
cairo_surface_set_device_offset (surface, -bounds.origin.x, -bounds.origin.y);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
gsk_render_node_draw (node, cr);
|
||||
cairo_destroy (cr);
|
||||
|
||||
cairo_surface_finish (surface);
|
||||
if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
cairo_surface_destroy (surface);
|
||||
return g_byte_array_free_to_bytes (array);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"%s", cairo_status_to_string (cairo_surface_status (surface)));
|
||||
cairo_surface_destroy (surface);
|
||||
g_byte_array_unref (array);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static GdkTexture *
|
||||
create_cairo_texture (NodeEditorWindow *self)
|
||||
{
|
||||
@@ -770,140 +702,50 @@ create_cairo_texture (NodeEditorWindow *self)
|
||||
}
|
||||
|
||||
static void
|
||||
export_image_saved_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_file_replace_contents_finish (G_FILE (source), result, NULL, &error))
|
||||
{
|
||||
GtkAlertDialog *alert;
|
||||
|
||||
alert = gtk_alert_dialog_new ("Exporting to image failed");
|
||||
gtk_alert_dialog_set_detail (alert, error->message);
|
||||
gtk_alert_dialog_show (alert, NULL);
|
||||
g_object_unref (alert);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
export_image_response_cb (GObject *source,
|
||||
export_image_response_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *user_data)
|
||||
void *user_data)
|
||||
{
|
||||
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
|
||||
GskRenderNode *node = user_data;
|
||||
GdkTexture *texture = user_data;
|
||||
GFile *file;
|
||||
char *uri;
|
||||
GBytes *bytes;
|
||||
|
||||
file = gtk_file_dialog_save_finish (dialog, result, NULL);
|
||||
if (file == NULL)
|
||||
if (file)
|
||||
{
|
||||
gsk_render_node_unref (node);
|
||||
return;
|
||||
}
|
||||
|
||||
uri = g_file_get_uri (file);
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
if (g_str_has_suffix (uri, "svg"))
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
bytes = create_svg (node, &error);
|
||||
if (bytes == NULL)
|
||||
if (!gdk_texture_save_to_png (texture, g_file_peek_path (file)))
|
||||
{
|
||||
GtkAlertDialog *alert;
|
||||
|
||||
alert = gtk_alert_dialog_new ("Exporting to image failed");
|
||||
gtk_alert_dialog_set_detail (alert, error->message);
|
||||
gtk_alert_dialog_show (alert, NULL);
|
||||
gtk_alert_dialog_show (alert, GTK_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog))));
|
||||
g_object_unref (alert);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GskRenderer *renderer;
|
||||
|
||||
renderer = gsk_gl_renderer_new ();
|
||||
if (!gsk_renderer_realize (renderer, NULL, NULL))
|
||||
{
|
||||
g_object_unref (renderer);
|
||||
renderer = gsk_cairo_renderer_new ();
|
||||
if (!gsk_renderer_realize (renderer, NULL, NULL))
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
texture = gsk_renderer_render_texture (renderer, node, NULL);
|
||||
gsk_renderer_unrealize (renderer);
|
||||
g_object_unref (renderer);
|
||||
|
||||
if (g_str_has_suffix (uri, "tiff"))
|
||||
bytes = gdk_texture_save_to_tiff_bytes (texture);
|
||||
else
|
||||
bytes = gdk_texture_save_to_png_bytes (texture);
|
||||
g_object_unref (texture);
|
||||
g_object_unref (file);
|
||||
}
|
||||
g_free (uri);
|
||||
|
||||
if (bytes)
|
||||
{
|
||||
g_file_replace_contents_bytes_async (file,
|
||||
bytes,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
export_image_saved_cb,
|
||||
NULL);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
gsk_render_node_unref (node);
|
||||
g_object_unref (file);
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
export_image_cb (GtkWidget *button,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
GdkTexture *texture;
|
||||
GtkFileDialog *dialog;
|
||||
GtkFileFilter *filter;
|
||||
GListStore *filters;
|
||||
|
||||
node = create_node (self);
|
||||
if (node == NULL)
|
||||
texture = create_texture (self);
|
||||
if (texture == NULL)
|
||||
return;
|
||||
|
||||
filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_mime_type (filter, "image/png");
|
||||
g_list_store_append (filters, filter);
|
||||
g_object_unref (filter);
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_mime_type (filter, "image/svg+xml");
|
||||
g_list_store_append (filters, filter);
|
||||
g_object_unref (filter);
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_mime_type (filter, "image/tiff");
|
||||
g_list_store_append (filters, filter);
|
||||
g_object_unref (filter);
|
||||
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_set_title (dialog, "");
|
||||
gtk_file_dialog_set_initial_name (dialog, "example.png");
|
||||
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
|
||||
gtk_file_dialog_save (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
|
||||
NULL,
|
||||
export_image_response_cb, node);
|
||||
g_object_unref (filters);
|
||||
export_image_response_cb, texture);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
@@ -1017,19 +859,6 @@ testcase_save_clicked_cb (GtkWidget *button,
|
||||
}
|
||||
|
||||
text = get_current_text (self->text_buffer);
|
||||
{
|
||||
GBytes *bytes;
|
||||
GskRenderNode *node;
|
||||
gsize size;
|
||||
|
||||
bytes = g_bytes_new_take (text, strlen (text) + 1);
|
||||
node = gsk_render_node_deserialize (bytes, NULL, NULL);
|
||||
g_bytes_unref (bytes);
|
||||
bytes = gsk_render_node_serialize (node);
|
||||
gsk_render_node_unref (node);
|
||||
text = g_bytes_unref_to_data (bytes, &size);
|
||||
}
|
||||
|
||||
if (!g_file_set_contents (node_file, text, -1, &error))
|
||||
{
|
||||
gtk_label_set_label (GTK_LABEL (self->testcase_error_label), error->message);
|
||||
|
||||
@@ -69,7 +69,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
|
||||
else
|
||||
widgetfactory_resources = gnome.compile_resources('widgetfactory_resources',
|
||||
'widget-factory.gresource.xml',
|
||||
source_dir: meson.current_source_dir(),
|
||||
source_dir: '.',
|
||||
)
|
||||
endif
|
||||
|
||||
|
||||
@@ -678,10 +678,11 @@ Interfaces must have the following macros:
|
||||
|
||||
### Memory allocation
|
||||
|
||||
When dynamically allocating data on the heap use `g_new()`.
|
||||
When dynamically allocating data on the heap either use `g_new()` or,
|
||||
if allocating multiple small data structures, `g_slice_new()`.
|
||||
|
||||
Public structure types should always be returned after being zero-ed,
|
||||
either explicitly for each member, or by using `g_new0()`.
|
||||
either explicitly for each member, or by using `g_new0()` or `g_slice_new0()`.
|
||||
|
||||
### Macros
|
||||
|
||||
|
||||
@@ -6,15 +6,22 @@ Slug: broadway
|
||||
The GDK Broadway backend provides support for displaying GTK applications in
|
||||
a web browser, using HTML5 and web sockets.
|
||||
|
||||
To run your application in this way, first run the broadway server,
|
||||
`gtk-broadwayd`, that ships with GTK:
|
||||
To run your application in this way, select the Broadway backend by setting
|
||||
`GDK_BACKEND=broadway`. Then you can make your application appear in a web
|
||||
browser by pointing it at `http://127.0.0.1:8080`. Note that you need to
|
||||
enable web sockets in your web browser.
|
||||
|
||||
You can choose a different port from the default 8080 by setting the
|
||||
`BROADWAY_DISPLAY` environment variable to the port that you want to use.
|
||||
|
||||
It is also possible to use multiple GTK applications in the same web browser
|
||||
window, by using the Broadway server, `gtk4-broadwayd`, that ships with GTK.
|
||||
To start the Broadway server use:
|
||||
|
||||
```
|
||||
gtk4-broadwayd :5
|
||||
```
|
||||
|
||||
The server expects the colon-prefixed display number as a commandline argument.
|
||||
|
||||
Then point your web browser at `http://127.0.0.1:8085`.
|
||||
|
||||
Once the Broadway server is running, you can start your applications like
|
||||
@@ -24,8 +31,6 @@ this:
|
||||
GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 gtk4-demo
|
||||
```
|
||||
|
||||
Multiple applications can be presented in the same web browser window.
|
||||
|
||||
## Broadway-specific environment variables
|
||||
|
||||
### `BROADWAY_DISPLAY`
|
||||
|
||||
@@ -66,10 +66,6 @@ You can compile the program above with GCC using:
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-0 example-0.c $( pkg-config --libs gtk4 )
|
||||
```
|
||||
|
||||
**Note**: If the above compilation does not work due to an error regarding `G_APPLICATION_DEFAULT_FLAGS`
|
||||
this could be due to your OS providing an older version of GLib. For GLib versions older than 2.74 you
|
||||
will need to replace `G_APPLICATION_DEFAULT_FLAGS` with `G_APPLICATION_FLAGS_NONE` in this example, and
|
||||
others in this documentation.
|
||||
For more information on how to compile a GTK application, please
|
||||
refer to the [Compiling GTK Applications](compiling.html)
|
||||
section in this reference.
|
||||
|
||||
@@ -128,7 +128,6 @@ Each state name is part of the `GtkAccessibleState` enumeration.
|
||||
| %GTK_ACCESSIBLE_STATE_INVALID | “aria-invalid” | `GtkAccessibleInvalidState` | Set when a widget is showing an error |
|
||||
| %GTK_ACCESSIBLE_STATE_PRESSED | “aria-pressed” | `GtkAccessibleTristate` | Indicates the current state of a [class@Gtk.ToggleButton] |
|
||||
| %GTK_ACCESSIBLE_STATE_SELECTED | “aria-selected” | boolean or undefined | Set when a widget is selected |
|
||||
| %GTK_ACCESSIBLE_STATE_VISITED | N/A | boolean or undefined | Set when a link-like widget is visited |
|
||||
|
||||
#### List of accessible properties
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ Lists are intended to be used whenever developers want to display many objects
|
||||
in roughly the same way.
|
||||
|
||||
Lists are perfectly fine to be used for very short list of only 2 or 3 elements,
|
||||
but generally scale to millions of items. Of course, the larger the list grows,
|
||||
the more care needs to be taken to choose the right data structures to keep things
|
||||
running well.
|
||||
but generally scale fine to millions of items. Of course, the larger the list
|
||||
grows, the more care needs to be taken to choose the right data structures to
|
||||
keep things running well.
|
||||
|
||||
Lists are meant to be used with changing data, both with the items itself changing
|
||||
as well as the list adding and removing items. Of course, they work just as well
|
||||
@@ -26,14 +26,12 @@ have a specific meaning in this context.
|
||||
**_Views_** or **_list widgets_** are the widgets that hold and manage the lists.
|
||||
Examples of these widgets would be [`class@Gtk.ListView`] or [`class@Gtk.GridView`].
|
||||
|
||||
Views display data from a **_model_**. Models implement the [`iface@Gio.ListModel`]
|
||||
interface and can be provided in a variety of ways:
|
||||
Views display data from a **_model_**. A model is a [`iface@Gio.ListModel`] and
|
||||
models can be provided in 3 ways or combinations thereof:
|
||||
|
||||
* List model implementations for many specific types of data already exist, for
|
||||
example `GtkDirectoryList` or `GtkStringList`.
|
||||
|
||||
* There are generic list model implementations like`GListStore` that allow building
|
||||
lists of arbitrary objects.
|
||||
* Many list models implementations already exist. There are models that provide
|
||||
specific data, like `GtkDirectoryList`. And there are models like `GListStore`
|
||||
that allow building lists manually.
|
||||
|
||||
* Wrapping list models like `GtkFilterListModel` or `GtkSortListModel`
|
||||
modify, adapt or combine other models.
|
||||
@@ -49,8 +47,8 @@ The elements in a model are called **_items_**. All items are
|
||||
|
||||
Every item in a model has a **_position_** which is the unsigned integer that
|
||||
describes where in the model the item is located. The first item in a model is
|
||||
at position 0. The position of an item can change as other items are added or
|
||||
removed from the model.
|
||||
at position 0. The position of an item can of course change as other items are
|
||||
added or removed from the model.
|
||||
|
||||
It is important to be aware of the difference between items and positions
|
||||
because the mapping from position to item is not permanent, so developers
|
||||
@@ -73,10 +71,10 @@ with the item managed by the listitem. Finding a suitable factory implementation
|
||||
for the data displayed, the programming language and development environment
|
||||
is an important task that can simplify setting up the view tremendously.
|
||||
|
||||
Views support selections via a **_selection model_**. A selection model is
|
||||
an implementation of the [`iface@Gtk.SelectionModel`] interface on top of the
|
||||
[`iface@Gio.ListModel`] interface that allows marking each item in a model as
|
||||
either selected or not selected. Just like regular models, this can be implemented
|
||||
Views support selections via a **_selection model_**. A selection model is an
|
||||
implementation of the [`iface@Gtk.SelectionModel`] interface on top of the
|
||||
[`iface@Gio.ListModel`] interface that allows marking each item in a model as either
|
||||
selected or not selected. Just like regular models, this can be implemented
|
||||
either by implementing `GtkSelectionModel` directly or by wrapping a model with
|
||||
one of the GTK models provided for this purposes, such as [`class@Gtk.NoSelection`]
|
||||
or [`class@Gtk.SingleSelection`].
|
||||
@@ -89,18 +87,19 @@ item is exposed in the listitem via the [`property@Gtk.ListItem:selected`] prope
|
||||
|
||||
Views and listitems also support activation. Activation means that double
|
||||
clicking or pressing enter while inside a focused row will cause the view
|
||||
to emit a signal such as [`signal@Gtk.ListView::activate`]. This provides an
|
||||
easy way to set up lists, but can also be turned off on listitems if undesired.
|
||||
to emit and activation signal such as [`signal@Gtk.ListView::activate`]. This
|
||||
provides an easy way to set up lists, but can also be turned off on listitems
|
||||
if undesired.
|
||||
|
||||
Both selections and activation are supported among other things via widget
|
||||
[actions](#actions-overview). This allows developers to add widgets to their
|
||||
lists that cause selections to change or to trigger activation via the
|
||||
[`iface@Gtk.Actionable`] interface. For a list of all supported actions
|
||||
see the relevant documentation.
|
||||
lists that cause selections to change or to trigger activation via
|
||||
the [`iface@Gtk.Actionable`] interface. For a list of all supported actions see
|
||||
the relevant documentation.
|
||||
|
||||
## Behind the scenes
|
||||
|
||||
While it is not a problem for short lists to instantiate widgets for every
|
||||
While for short lists it is not a problem to instantiate widgets for every
|
||||
item in the model, once lists grow to thousands or millions of elements, this
|
||||
gets less feasible. Because of this, the views only create a limited amount of
|
||||
listitems and recycle them by binding them to new items. In general, views try
|
||||
@@ -108,7 +107,7 @@ to keep listitems available only for the items that can actually be seen on
|
||||
screen.
|
||||
|
||||
While this behavior allows views to scale effortlessly to huge lists, it has a
|
||||
few implications for what can be done with views. For example, it is not possible
|
||||
few implication on what can be done with views. For example, it is not possible
|
||||
to query a view for a listitem used for a certain position - there might not be
|
||||
one and even if there is, that listitem might soon be recycled for a new
|
||||
position.
|
||||
@@ -162,9 +161,9 @@ in particular `GListModel` do not. This was a design choice because the common
|
||||
use case is displaying lists and not trees and it greatly simplifies the API
|
||||
interface provided.
|
||||
|
||||
However, GTK provides functionality to make lists look and behave like trees
|
||||
for use cases that require trees. This is achieved by using the
|
||||
[`class@Gtk.TreeListModel`] model to flatten a tree into a list. The
|
||||
However, GTK provides functionality to make trees look and behave like lists
|
||||
for the people who still want to display lists. This is achieved by using
|
||||
the [`class@Gtk.TreeListModel`] model to flatten a tree into a list. The
|
||||
[`class@Gtk.TreeExpander`] widget can then be used inside a listitem to allow
|
||||
users to expand and collapse rows and provide a similar experience to
|
||||
`GtkTreeView`.
|
||||
@@ -175,26 +174,26 @@ on the topic.
|
||||
## List styles
|
||||
|
||||
One of the advantages of the new list widgets over `GtkTreeView` and cell
|
||||
renderers is that they are styleable using GTK CSS. This provides a lot of
|
||||
flexibility. The themes that ship with GTK provide a few predefined list
|
||||
styles that can be used in many situations:
|
||||
renderers is that they are fully themable using GTK CSS. This provides a
|
||||
lot of flexibility. The themes that ship with GTK provide a few predefined
|
||||
list styles that can be used in many situations:
|
||||
|
||||

|
||||
|
||||
This _rich list_ style is low density, spacious and uses an outline focus
|
||||
ring. It is suitable for lists of controls, e.g. in preference dialogs or
|
||||
This style of list is low density, spacious and uses an outline focus ring.
|
||||
It is suitable for lists of controls, e.g. in preference dialogs or
|
||||
settings panels. Use the `.rich-list` style class.
|
||||
|
||||

|
||||
|
||||
The _sidebar_ style of list is medium density, using a full background to
|
||||
indicate focus and selection. Use the `.navigation-sidebar` style class.
|
||||
This style of list is medium density, using a full background to indicate
|
||||
focus and selection. Use the `.navigation-sidebar` style class.
|
||||
|
||||

|
||||
|
||||
The _data table_ style of list is a high density table, similar in style to a
|
||||
traditional treeview. Individual cells can be selectable and editable. Use
|
||||
the `.data-table` style class.
|
||||
This style of list is a high density table, similar in style to a traditional
|
||||
treeview. Individual cells can be selectable and editable. Use the `.data-table`
|
||||
style class.
|
||||
|
||||
## Comparison to GtkTreeView
|
||||
|
||||
@@ -203,19 +202,20 @@ compares to the way they know. This section will try to outline the similarities
|
||||
and differences between the two.
|
||||
|
||||
This new approach tries to provide roughly the same functionality as the old
|
||||
approach but often uses a very different way to achieve these goals.
|
||||
approach but often uses a very different approach to achieve these goals.
|
||||
|
||||
The main difference and one of the primary reasons for this new development is
|
||||
that items can be displayed using regular widgets and the separate cell renderer
|
||||
machinery is no longer necessary. This allows all benefits that widgets provide,
|
||||
such as complex layout, animations and CSS styling.
|
||||
that items can be displayed using regular widgets and `GtkCellRenderer` is no
|
||||
longer necessary. This allows all benefits that widgets provide, such as complex
|
||||
layout and animating widgets and not only makes cell renderers obsolete, but
|
||||
also `GtkCellArea`.
|
||||
|
||||
The other big difference is the massive change to the data model. `GtkTreeModel`
|
||||
was a rather complex interface for a tree data structure. `GListModel` is
|
||||
deliberately designed to be a very simple data structure for lists only. (See
|
||||
was a rather complex interface for a tree data structure and `GListModel` was
|
||||
deliberately designed to be a simple data structure for lists only. (See
|
||||
[above](#displaying-trees)) for how to still do trees with this new model.)
|
||||
Another big change is that the new model allows for bulk changes via the
|
||||
`GListModel::items-changed` signal while `GtkTreeModel` only allows a single
|
||||
Another big change is that the new model allows for bulk changes via
|
||||
the `GListModel::items-changed` signal while `GtkTreeModel` only allows a single
|
||||
item to change at once. The goal here is of course to encourage implementation
|
||||
of custom list models.
|
||||
|
||||
@@ -231,8 +231,8 @@ via custom code in each widget, selection state is now meant to be managed by
|
||||
the selection models. In particular this allows for complex use cases with
|
||||
specialized requirements.
|
||||
|
||||
Finally here's a quick comparison chart of equivalent functionality to look for
|
||||
when transitioning code:
|
||||
Finally here's a quick list of equivalent functionality to look for when
|
||||
transitioning code for easy lookup:
|
||||
|
||||
| Old | New |
|
||||
| -------------------- | ------------------------------------------------------- |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app2_resources = gnome.compile_resources('exampleapp2_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: meson.current_source_dir())
|
||||
source_dir: '.')
|
||||
|
||||
executable('exampleapp2',
|
||||
'exampleapp.c', 'exampleappwin.c', 'main.c', app2_resources,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app3_resources = gnome.compile_resources('exampleapp3_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: meson.current_source_dir())
|
||||
source_dir: '.')
|
||||
|
||||
executable('exampleapp3',
|
||||
'exampleapp.c', 'exampleappwin.c', 'main.c', app3_resources,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app4_resources = gnome.compile_resources('exampleapp4_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: meson.current_source_dir())
|
||||
source_dir: '.')
|
||||
|
||||
executable('exampleapp4',
|
||||
'exampleapp.c', 'exampleappwin.c', 'main.c', app4_resources,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app5_resources = gnome.compile_resources('exampleapp5_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: meson.current_source_dir())
|
||||
source_dir: '.')
|
||||
|
||||
app5_schemas = gnome.compile_schemas()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app6_resources = gnome.compile_resources('exampleapp6_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: meson.current_source_dir())
|
||||
source_dir: '.')
|
||||
|
||||
app6_schemas = gnome.compile_schemas()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app7_resources = gnome.compile_resources('exampleapp7_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: meson.current_source_dir())
|
||||
source_dir: '.')
|
||||
|
||||
app7_schemas = gnome.compile_schemas()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app8_resources = gnome.compile_resources('exampleapp8 resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: meson.current_source_dir())
|
||||
source_dir: '.')
|
||||
|
||||
app8_schemas = gnome.compile_schemas()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app9_resources = gnome.compile_resources('exampleapp9_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: meson.current_source_dir())
|
||||
source_dir: '.')
|
||||
|
||||
app9_schemas = gnome.compile_schemas()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
bp_resources = gnome.compile_resources('bloatpad_resources',
|
||||
'bloatpad.gresources.xml',
|
||||
source_dir: meson.current_source_dir())
|
||||
source_dir: '.')
|
||||
|
||||
executable('bloatpad', 'bloatpad.c', bp_resources, dependencies: libgtk_dep, c_args: common_cflags)
|
||||
|
||||
@@ -1574,8 +1574,7 @@ broadway_server_query_mouse (BroadwayServer *server,
|
||||
|
||||
void
|
||||
broadway_server_destroy_surface (BroadwayServer *server,
|
||||
int id,
|
||||
gboolean disconnected)
|
||||
int id)
|
||||
{
|
||||
BroadwaySurface *surface;
|
||||
gint32 transient_for = -1;
|
||||
@@ -1590,7 +1589,8 @@ broadway_server_destroy_surface (BroadwayServer *server,
|
||||
server->pointer_grab_surface_id = -1;
|
||||
|
||||
if (server->output)
|
||||
broadway_output_destroy_surface (server->output, id);
|
||||
broadway_output_destroy_surface (server->output,
|
||||
id);
|
||||
|
||||
surface = broadway_server_lookup_surface (server, id);
|
||||
if (surface != NULL)
|
||||
@@ -1604,7 +1604,7 @@ broadway_server_destroy_surface (BroadwayServer *server,
|
||||
broadway_surface_free (server, surface);
|
||||
}
|
||||
|
||||
if (transient_for != -1 && !disconnected)
|
||||
if (transient_for != -1)
|
||||
{
|
||||
surface = broadway_server_lookup_surface (server, transient_for);
|
||||
if (surface != NULL)
|
||||
|
||||
@@ -93,8 +93,7 @@ guint32 broadway_server_new_surface (BroadwayServer *
|
||||
int width,
|
||||
int height);
|
||||
void broadway_server_destroy_surface (BroadwayServer *server,
|
||||
int id,
|
||||
gboolean disconnected);
|
||||
int id);
|
||||
gboolean broadway_server_surface_show (BroadwayServer *server,
|
||||
int id);
|
||||
gboolean broadway_server_surface_hide (BroadwayServer *server,
|
||||
|
||||
@@ -101,7 +101,8 @@ client_disconnected (BroadwayClient *client)
|
||||
}
|
||||
|
||||
for (l = client->surfaces; l != NULL; l = l->next)
|
||||
broadway_server_destroy_surface (server, GPOINTER_TO_UINT (l->data), TRUE);
|
||||
broadway_server_destroy_surface (server,
|
||||
GPOINTER_TO_UINT (l->data));
|
||||
g_list_free (client->surfaces);
|
||||
client->surfaces = NULL;
|
||||
|
||||
@@ -267,7 +268,7 @@ client_handle_request (BroadwayClient *client,
|
||||
client->surfaces =
|
||||
g_list_remove (client->surfaces,
|
||||
GUINT_TO_POINTER (request->destroy_surface.id));
|
||||
broadway_server_destroy_surface (server, request->destroy_surface.id, FALSE);
|
||||
broadway_server_destroy_surface (server, request->destroy_surface.id);
|
||||
break;
|
||||
case BROADWAY_REQUEST_SHOW_SURFACE:
|
||||
broadway_server_surface_show (server, request->show_surface.id);
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include <gdk/gdkdisplaymanager.h>
|
||||
#include <gdk/gdkdrag.h>
|
||||
#include <gdk/gdkdragsurface.h>
|
||||
#include <gdk/gdkdragsurfacesize.h>
|
||||
#include <gdk/gdkdrawcontext.h>
|
||||
#include <gdk/gdkdrop.h>
|
||||
#include <gdk/gdkenums.h>
|
||||
|
||||
+2
-2
@@ -750,7 +750,7 @@ static void
|
||||
free_value (gpointer value)
|
||||
{
|
||||
g_value_unset (value);
|
||||
g_free (value);
|
||||
g_slice_free (GValue, value);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -771,7 +771,7 @@ gdk_clipboard_read_value_internal (GdkClipboard *clipboard,
|
||||
task = g_task_new (clipboard, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, source_tag);
|
||||
value = g_new0 (GValue, 1);
|
||||
value = g_slice_new0 (GValue);
|
||||
g_value_init (value, type);
|
||||
g_task_set_task_data (task, value, free_value);
|
||||
|
||||
|
||||
@@ -410,7 +410,7 @@ gdk_content_register_deserializer (const char *mime_type,
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (deserialize != NULL);
|
||||
|
||||
deserializer = g_new0 (Deserializer, 1);
|
||||
deserializer = g_slice_new0 (Deserializer);
|
||||
|
||||
deserializer->mime_type = g_intern_string (mime_type);
|
||||
deserializer->type = type;
|
||||
|
||||
@@ -112,7 +112,7 @@ gdk_content_formats_new_take (GType * gtypes,
|
||||
const char **mime_types,
|
||||
gsize n_mime_types)
|
||||
{
|
||||
GdkContentFormats *result = g_new0 (GdkContentFormats, 1);
|
||||
GdkContentFormats *result = g_slice_new0 (GdkContentFormats);
|
||||
result->ref_count = 1;
|
||||
|
||||
result->gtypes = gtypes;
|
||||
@@ -287,7 +287,7 @@ gdk_content_formats_unref (GdkContentFormats *formats)
|
||||
|
||||
g_free (formats->gtypes);
|
||||
g_free (formats->mime_types);
|
||||
g_free (formats);
|
||||
g_slice_free (GdkContentFormats, formats);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -611,7 +611,7 @@ gdk_content_formats_builder_new (void)
|
||||
{
|
||||
GdkContentFormatsBuilder *builder;
|
||||
|
||||
builder = g_new0 (GdkContentFormatsBuilder, 1);
|
||||
builder = g_slice_new0 (GdkContentFormatsBuilder);
|
||||
builder->ref_count = 1;
|
||||
|
||||
return builder;
|
||||
@@ -665,7 +665,7 @@ gdk_content_formats_builder_unref (GdkContentFormatsBuilder *builder)
|
||||
return;
|
||||
|
||||
gdk_content_formats_builder_clear (builder);
|
||||
g_free (builder);
|
||||
g_slice_free (GdkContentFormatsBuilder, builder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -416,7 +416,7 @@ gdk_content_register_serializer (GType type,
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (serialize != NULL);
|
||||
|
||||
serializer = g_new0 (Serializer, 1);
|
||||
serializer = g_slice_new0 (Serializer);
|
||||
|
||||
serializer->mime_type = g_intern_string (mime_type);
|
||||
serializer->type = type;
|
||||
|
||||
+2
-2
@@ -322,7 +322,7 @@ static void
|
||||
free_pointer_info (GdkPointerSurfaceInfo *info)
|
||||
{
|
||||
g_clear_object (&info->surface_under_pointer);
|
||||
g_free (info);
|
||||
g_slice_free (GdkPointerSurfaceInfo, info);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -834,7 +834,7 @@ _gdk_display_get_pointer_info (GdkDisplay *display,
|
||||
|
||||
if (G_UNLIKELY (!info))
|
||||
{
|
||||
info = g_new0 (GdkPointerSurfaceInfo, 1);
|
||||
info = g_slice_new0 (GdkPointerSurfaceInfo);
|
||||
g_hash_table_insert (display->pointers_info, device, info);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,22 +37,6 @@
|
||||
|
||||
G_DEFINE_INTERFACE (GdkDragSurface, gdk_drag_surface, GDK_TYPE_SURFACE)
|
||||
|
||||
enum
|
||||
{
|
||||
COMPUTE_SIZE,
|
||||
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
void
|
||||
gdk_drag_surface_notify_compute_size (GdkDragSurface *surface,
|
||||
GdkDragSurfaceSize *size)
|
||||
{
|
||||
g_signal_emit (surface, signals[COMPUTE_SIZE], 0, size);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_drag_surface_default_present (GdkDragSurface *drag_surface,
|
||||
int width,
|
||||
@@ -65,35 +49,6 @@ static void
|
||||
gdk_drag_surface_default_init (GdkDragSurfaceInterface *iface)
|
||||
{
|
||||
iface->present = gdk_drag_surface_default_present;
|
||||
|
||||
/**
|
||||
* GdkDragSurface::compute-size:
|
||||
* @surface: a `GdkDragSurface`
|
||||
* @size: (type Gdk.DragSurfaceSize) (out caller-allocates): a
|
||||
* `GdkDragSurfaceSize`
|
||||
*
|
||||
* Emitted when the size for the surface needs to be computed, when it is
|
||||
* present.
|
||||
*
|
||||
* It will normally be emitted during the native surface layout cycle when the
|
||||
* surface size needs to be recomputed.
|
||||
*
|
||||
* It is the responsibility of the drag surface user to handle this signal and
|
||||
* compute the desired size of the surface, storing the computed size in the
|
||||
* [struct@Gdk.DragSurfaceSize] object. Failing to do so will result in an
|
||||
* arbitrary size being used as a result.
|
||||
*
|
||||
* Since: 4.12
|
||||
*/
|
||||
signals[COMPUTE_SIZE] =
|
||||
g_signal_new (I_("compute-size"),
|
||||
GDK_TYPE_DRAG_SURFACE,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DRAG_SURFACE_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define __GDK_DRAG_SURFACE_PRIVATE_H__
|
||||
|
||||
#include "gdkdragsurface.h"
|
||||
#include "gdkdragsurfacesize.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -16,9 +15,6 @@ struct _GdkDragSurfaceInterface
|
||||
int height);
|
||||
};
|
||||
|
||||
void gdk_drag_surface_notify_compute_size (GdkDragSurface *surface,
|
||||
GdkDragSurfaceSize *size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DRAG_SURFACE_PRIVATE_H__ */
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdragsurfacesizeprivate.h"
|
||||
|
||||
/**
|
||||
* GdkDragSurfaceSize:
|
||||
*
|
||||
* The `GdkDragSurfaceSize` struct contains information that is useful
|
||||
* to compute the size of a drag surface.
|
||||
*
|
||||
* Since: 4.12
|
||||
*/
|
||||
|
||||
G_DEFINE_POINTER_TYPE (GdkDragSurfaceSize, gdk_drag_surface_size)
|
||||
|
||||
void
|
||||
gdk_drag_surface_size_init (GdkDragSurfaceSize *size)
|
||||
{
|
||||
*size = (GdkDragSurfaceSize) { 0 };
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_surface_size_set_size:
|
||||
* @size: a `GdkDragSurfaceSize`
|
||||
* @width: the width
|
||||
* @height: the height
|
||||
*
|
||||
* Sets the size the drag surface prefers to be resized to.
|
||||
*
|
||||
* Since: 4.12
|
||||
*/
|
||||
void
|
||||
gdk_drag_surface_size_set_size (GdkDragSurfaceSize *size,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
size->width = width;
|
||||
size->height = height;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__GDK_H_INSIDE__) && !defined(GTK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkDragSurfaceSize GdkDragSurfaceSize;
|
||||
|
||||
#define GDK_TYPE_DRAG_SURFACE_SIZE (gdk_drag_surface_size_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_4_12
|
||||
GType gdk_drag_surface_size_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_12
|
||||
void gdk_drag_surface_size_set_size (GdkDragSurfaceSize *size,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,29 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gdkdragsurfacesize.h"
|
||||
|
||||
struct _GdkDragSurfaceSize
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
void gdk_drag_surface_size_init (GdkDragSurfaceSize *size);
|
||||
+2
-2
@@ -767,7 +767,7 @@ static void
|
||||
free_value (gpointer value)
|
||||
{
|
||||
g_value_unset (value);
|
||||
g_free (value);
|
||||
g_slice_free (GValue, value);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -790,7 +790,7 @@ gdk_drop_read_value_internal (GdkDrop *self,
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, source_tag);
|
||||
value = g_new0 (GValue, 1);
|
||||
value = g_slice_new0 (GValue);
|
||||
g_value_init (value, type);
|
||||
g_task_set_task_data (task, value, free_value);
|
||||
|
||||
|
||||
@@ -584,6 +584,8 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
{
|
||||
priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||
_gdk_frame_clock_emit_layout (clock);
|
||||
if (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT)
|
||||
g_print ("looping in layout %d\n", iter);
|
||||
}
|
||||
if (iter == 5)
|
||||
g_warning ("gdk-frame-clock: layout continuously requested, giving up after 4 tries");
|
||||
@@ -809,3 +811,12 @@ _gdk_frame_clock_idle_new (void)
|
||||
|
||||
return GDK_FRAME_CLOCK (clock);
|
||||
}
|
||||
|
||||
GdkFrameClockPhase
|
||||
gdk_frame_clock_get_current_phase (GdkFrameClock *clock)
|
||||
{
|
||||
GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock);
|
||||
GdkFrameClockIdlePrivate *priv = clock_idle->priv;
|
||||
|
||||
return priv->phase;
|
||||
}
|
||||
|
||||
@@ -127,6 +127,8 @@ void _gdk_frame_clock_emit_paint (GdkFrameClock *frame_clock);
|
||||
void _gdk_frame_clock_emit_after_paint (GdkFrameClock *frame_clock);
|
||||
void _gdk_frame_clock_emit_resume_events (GdkFrameClock *frame_clock);
|
||||
|
||||
GdkFrameClockPhase gdk_frame_clock_get_current_phase (GdkFrameClock *frame_clock);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_FRAME_CLOCK_PRIVATE_H__ */
|
||||
|
||||
@@ -43,7 +43,7 @@ _gdk_frame_timings_new (gint64 frame_counter)
|
||||
{
|
||||
GdkFrameTimings *timings;
|
||||
|
||||
timings = g_new0 (GdkFrameTimings, 1);
|
||||
timings = g_slice_new0 (GdkFrameTimings);
|
||||
timings->ref_count = 1;
|
||||
timings->frame_counter = frame_counter;
|
||||
|
||||
@@ -99,7 +99,9 @@ gdk_frame_timings_unref (GdkFrameTimings *timings)
|
||||
|
||||
timings->ref_count--;
|
||||
if (timings->ref_count == 0)
|
||||
g_free (timings);
|
||||
{
|
||||
g_slice_free (GdkFrameTimings, timings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+14
-22
@@ -1546,28 +1546,20 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
priv->has_half_float = gdk_gl_context_check_version (context, 3, 0, 3, 0) ||
|
||||
epoxy_has_gl_extension ("OES_vertex_half_float");
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{
|
||||
int max_texture_size;
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
GDK_DISPLAY_DEBUG (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), OPENGL,
|
||||
"%s version: %d.%d (%s)\n"
|
||||
"* GLSL version: %s\n"
|
||||
"* Max texture size: %d\n"
|
||||
"* Extensions checked:\n"
|
||||
" - GL_KHR_debug: %s\n"
|
||||
" - GL_EXT_unpack_subimage: %s\n"
|
||||
" - OES_vertex_half_float: %s",
|
||||
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
|
||||
priv->gl_version / 10, priv->gl_version % 10,
|
||||
priv->is_legacy ? "legacy" : "core",
|
||||
glGetString (GL_SHADING_LANGUAGE_VERSION),
|
||||
max_texture_size,
|
||||
priv->has_khr_debug ? "yes" : "no",
|
||||
priv->has_unpack_subimage ? "yes" : "no",
|
||||
priv->has_half_float ? "yes" : "no");
|
||||
}
|
||||
#endif
|
||||
GDK_DISPLAY_DEBUG (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), OPENGL,
|
||||
"%s version: %d.%d (%s)\n"
|
||||
"* GLSL version: %s\n"
|
||||
"* Extensions checked:\n"
|
||||
" - GL_KHR_debug: %s\n"
|
||||
" - GL_EXT_unpack_subimage: %s\n"
|
||||
" - OES_vertex_half_float: %s",
|
||||
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
|
||||
priv->gl_version / 10, priv->gl_version % 10,
|
||||
priv->is_legacy ? "legacy" : "core",
|
||||
glGetString (GL_SHADING_LANGUAGE_VERSION),
|
||||
priv->has_khr_debug ? "yes" : "no",
|
||||
priv->has_unpack_subimage ? "yes" : "no",
|
||||
priv->has_half_float ? "yes" : "no");
|
||||
|
||||
priv->extensions_checked = TRUE;
|
||||
}
|
||||
|
||||
@@ -335,7 +335,6 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
switch (internal_format)
|
||||
{
|
||||
case GL_RGB8:
|
||||
case GL_RGB:
|
||||
texture->format = GDK_MEMORY_R8G8B8;
|
||||
break;
|
||||
|
||||
|
||||
@@ -178,10 +178,10 @@ gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
|
||||
GBytes *bytes;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE (source), NULL);
|
||||
g_return_val_if_fail (x >= 0 && x < GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (y >= 0 && y < GDK_TEXTURE (source)->height, NULL);
|
||||
g_return_val_if_fail (width > 0 && x + width <= GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (height > 0 && y + height <= GDK_TEXTURE (source)->height, NULL);
|
||||
g_return_val_if_fail (x >= 0 || x < GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (y >= 0 || y < GDK_TEXTURE (source)->height, NULL);
|
||||
g_return_val_if_fail (width > 0 || x + width <= GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (height > 0 || y + height <= GDK_TEXTURE (source)->height, NULL);
|
||||
|
||||
texture = GDK_TEXTURE (source);
|
||||
bpp = gdk_memory_format_bytes_per_pixel (texture->format);
|
||||
|
||||
@@ -50,7 +50,7 @@ gdk_io_pipe_new (void)
|
||||
{
|
||||
GdkIOPipe *pipe;
|
||||
|
||||
pipe = g_new0 (GdkIOPipe, 1);
|
||||
pipe = g_slice_new0 (GdkIOPipe);
|
||||
pipe->ref_count = 1;
|
||||
|
||||
g_mutex_init (&pipe->mutex);
|
||||
@@ -76,7 +76,7 @@ gdk_io_pipe_unref (GdkIOPipe *pipe)
|
||||
g_cond_clear (&pipe->cond);
|
||||
g_mutex_clear (&pipe->mutex);
|
||||
|
||||
g_free (pipe);
|
||||
g_slice_free (GdkIOPipe, pipe);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+2
-7
@@ -67,12 +67,7 @@ G_DEFINE_BOXED_TYPE (GdkRGBA, gdk_rgba,
|
||||
GdkRGBA *
|
||||
gdk_rgba_copy (const GdkRGBA *rgba)
|
||||
{
|
||||
GdkRGBA *copy;
|
||||
|
||||
copy = g_new (GdkRGBA, 1);
|
||||
memcpy (copy, rgba, sizeof (GdkRGBA));
|
||||
|
||||
return copy;
|
||||
return g_slice_dup (GdkRGBA, rgba);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +79,7 @@ gdk_rgba_copy (const GdkRGBA *rgba)
|
||||
void
|
||||
gdk_rgba_free (GdkRGBA *rgba)
|
||||
{
|
||||
g_free (rgba);
|
||||
g_slice_free (GdkRGBA, rgba);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -395,7 +395,7 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
|
||||
bytes = g_bytes_new_with_free_func (gdk_pixbuf_get_pixels (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf)
|
||||
* (gsize) gdk_pixbuf_get_rowstride (pixbuf),
|
||||
* gdk_pixbuf_get_rowstride (pixbuf),
|
||||
g_object_unref,
|
||||
g_object_ref (pixbuf));
|
||||
texture = gdk_memory_texture_new (gdk_pixbuf_get_width (pixbuf),
|
||||
|
||||
@@ -76,7 +76,7 @@ gdk_texture_downloader_new (GdkTexture *texture)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
|
||||
|
||||
self = g_new (GdkTextureDownloader, 1);
|
||||
self = g_slice_new (GdkTextureDownloader);
|
||||
gdk_texture_downloader_init (self, texture);
|
||||
|
||||
return self;
|
||||
@@ -121,7 +121,7 @@ gdk_texture_downloader_free (GdkTextureDownloader *self)
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
gdk_texture_downloader_finish (self);
|
||||
g_free (self);
|
||||
g_slice_free (GdkTextureDownloader, self);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -128,16 +128,6 @@
|
||||
*/
|
||||
#define GDK_VERSION_4_10 (G_ENCODE_VERSION (4, 10))
|
||||
|
||||
/**
|
||||
* GDK_VERSION_4_12:
|
||||
*
|
||||
* A macro that evaluates to the 4.12 version of GDK, in a format
|
||||
* that can be used by the C pre-processor.
|
||||
*
|
||||
* Since: 4.12
|
||||
*/
|
||||
#define GDK_VERSION_4_12 (G_ENCODE_VERSION (4, 12))
|
||||
|
||||
|
||||
/* evaluates to the current stable version; for development cycles,
|
||||
* this means the next stable target, with a hard backstop to the
|
||||
@@ -307,18 +297,4 @@
|
||||
# define GDK_DEPRECATED_IN_4_10_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_4_12
|
||||
# define GDK_AVAILABLE_IN_4_12 GDK_UNAVAILABLE(4, 12)
|
||||
#else
|
||||
# define GDK_AVAILABLE_IN_4_12 _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_12
|
||||
# define GDK_DEPRECATED_IN_4_12 GDK_DEPRECATED
|
||||
# define GDK_DEPRECATED_IN_4_12_FOR(f) GDK_DEPRECATED_FOR(f)
|
||||
#else
|
||||
# define GDK_DEPRECATED_IN_4_12 _GDK_EXTERN
|
||||
# define GDK_DEPRECATED_IN_4_12_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#endif /* __GDK_VERSION_MACROS_H__ */
|
||||
|
||||
@@ -221,20 +221,6 @@ gdk_vulkan_strerror (VkResult result)
|
||||
#endif
|
||||
#if VK_HEADER_VERSION < 140
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 218
|
||||
case VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR:
|
||||
return "The requested VkImageUsageFlags are not supported. (VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR:
|
||||
return "The requested video picture layout is not supported. (VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR:
|
||||
return "A video profile operation specified via VkVideoProfileInfoKHR::videoCodecOperation is not supported. (VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR:
|
||||
return "Format parameters in a requested VkVideoProfileInfoKHR chain are not supported. (VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR:
|
||||
return "Codec-specific parameters in a requested (VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR:
|
||||
return "The specified video Std header version is not supported. (VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR)";
|
||||
#endif
|
||||
case VK_RESULT_MAX_ENUM:
|
||||
default:
|
||||
|
||||
@@ -283,7 +283,7 @@ static void
|
||||
push_nsevent (GdkEvent *gdk_event,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkToNSEventMap *map = g_new0 (GdkToNSEventMap, 1);
|
||||
GdkToNSEventMap *map = g_slice_new0 (GdkToNSEventMap);
|
||||
|
||||
map->link.data = map;
|
||||
map->gdk_event = gdk_event_ref (gdk_event);
|
||||
@@ -297,7 +297,7 @@ push_nsevent (GdkEvent *gdk_event,
|
||||
|
||||
gdk_event_unref (map->gdk_event);
|
||||
[map->nsevent release];
|
||||
g_free (map);
|
||||
g_slice_free (GdkToNSEventMap, map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ gdk_macos_zoomback_destroy (GdkMacosZoomback *zb)
|
||||
{
|
||||
gdk_surface_hide (GDK_SURFACE (zb->drag->drag_surface));
|
||||
g_clear_object (&zb->drag);
|
||||
g_free (zb);
|
||||
g_slice_free (GdkMacosZoomback, zb);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -157,7 +157,7 @@ gdk_macos_drag_drop_done (GdkDrag *drag,
|
||||
/* Apple HIG suggests doing a "zoomback" animation of the surface back
|
||||
* towards the original position.
|
||||
*/
|
||||
zb = g_new0 (GdkMacosZoomback, 1);
|
||||
zb = g_slice_new0 (GdkMacosZoomback);
|
||||
zb->drag = g_object_ref (self);
|
||||
zb->frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self->drag_surface));
|
||||
zb->start_time = gdk_frame_clock_get_frame_time (zb->frame_clock);
|
||||
|
||||
@@ -423,7 +423,7 @@ write_request_free (WriteRequest *wr)
|
||||
g_clear_pointer (&wr->main_context, g_main_context_unref);
|
||||
g_clear_object (&wr->stream);
|
||||
[wr->item release];
|
||||
g_free (wr);
|
||||
g_slice_free (WriteRequest, wr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -491,7 +491,7 @@ on_data_ready_cb (GObject *object,
|
||||
return;
|
||||
}
|
||||
|
||||
wr = g_new0 (WriteRequest, 1);
|
||||
wr = g_slice_new0 (WriteRequest);
|
||||
wr->item = [item retain];
|
||||
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
|
||||
wr->type = type;
|
||||
|
||||
+2
-4
@@ -16,8 +16,6 @@ gdk_public_sources = files([
|
||||
'gdkdisplay.c',
|
||||
'gdkdisplaymanager.c',
|
||||
'gdkdrag.c',
|
||||
'gdkdragsurface.c',
|
||||
'gdkdragsurfacesize.c',
|
||||
'gdkdrawcontext.c',
|
||||
'gdkdrop.c',
|
||||
'gdkevents.c',
|
||||
@@ -54,6 +52,7 @@ gdk_public_sources = files([
|
||||
'gdktoplevellayout.c',
|
||||
'gdktoplevelsize.c',
|
||||
'gdktoplevel.c',
|
||||
'gdkdragsurface.c',
|
||||
'loaders/gdkpng.c',
|
||||
'loaders/gdktiff.c',
|
||||
'loaders/gdkjpeg.c',
|
||||
@@ -77,7 +76,6 @@ gdk_public_headers = files([
|
||||
'gdkdisplay.h',
|
||||
'gdkdisplaymanager.h',
|
||||
'gdkdrag.h',
|
||||
'gdkdragsurfacesize.h',
|
||||
'gdkdrawcontext.h',
|
||||
'gdkdrop.h',
|
||||
'gdkenums.h',
|
||||
@@ -133,7 +131,7 @@ gdk_gresource_xml = configure_file(output: 'gdk.gresource.xml',
|
||||
|
||||
gdkresources = gnome.compile_resources('gdkresources',
|
||||
gdk_gresource_xml,
|
||||
source_dir: meson.current_source_dir(),
|
||||
source_dir: '.',
|
||||
c_name: '_gdk',
|
||||
extra_args: '--manual-register',
|
||||
)
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
#include "gdkdevice-wayland-private.h"
|
||||
#include "gdkdragsurfacesizeprivate.h"
|
||||
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
|
||||
@@ -79,17 +78,6 @@ gdk_wayland_drag_surface_compute_size (GdkSurface *surface)
|
||||
|
||||
if (impl->next_layout.surface_geometry_dirty)
|
||||
{
|
||||
GdkDragSurfaceSize size;
|
||||
|
||||
gdk_drag_surface_size_init (&size);
|
||||
size.width = impl->next_layout.configured_width;
|
||||
size.height = impl->next_layout.configured_height;
|
||||
|
||||
gdk_drag_surface_notify_compute_size (GDK_DRAG_SURFACE (surface), &size);
|
||||
|
||||
impl->next_layout.configured_width = size.width;
|
||||
impl->next_layout.configured_height = size.height;
|
||||
|
||||
gdk_wayland_surface_update_size (surface,
|
||||
impl->next_layout.configured_width,
|
||||
impl->next_layout.configured_height,
|
||||
|
||||
@@ -65,9 +65,6 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
int dx = impl->pending_buffer_offset_x;
|
||||
int dy = impl->pending_buffer_offset_y;
|
||||
|
||||
impl->pending_buffer_offset_x = 0;
|
||||
impl->pending_buffer_offset_y = 0;
|
||||
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
@@ -121,7 +118,7 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
|
||||
{
|
||||
GdkWaylandDisplay *self = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
if (!gdk_display_init_egl (display,
|
||||
if (!gdk_display_init_egl (display,
|
||||
EGL_PLATFORM_WAYLAND_EXT,
|
||||
self->wl_display,
|
||||
TRUE,
|
||||
|
||||
@@ -561,14 +561,8 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
|
||||
/* Attach this new buffer to the surface */
|
||||
wl_surface_attach (impl->display_server.wl_surface,
|
||||
_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface),
|
||||
0, 0);
|
||||
|
||||
if ((impl->pending_buffer_offset_x || impl->pending_buffer_offset_y) &&
|
||||
wl_surface_get_version (impl->display_server.wl_surface) >=
|
||||
WL_SURFACE_OFFSET_SINCE_VERSION)
|
||||
wl_surface_offset (impl->display_server.wl_surface,
|
||||
impl->pending_buffer_offset_x,
|
||||
impl->pending_buffer_offset_y);
|
||||
impl->pending_buffer_offset_x,
|
||||
impl->pending_buffer_offset_y);
|
||||
impl->pending_buffer_offset_x = 0;
|
||||
impl->pending_buffer_offset_y = 0;
|
||||
|
||||
@@ -977,15 +971,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
impl->display_server.egl_window = NULL;
|
||||
}
|
||||
|
||||
impl->awaiting_frame = FALSE;
|
||||
if (impl->awaiting_frame_frozen)
|
||||
{
|
||||
impl->awaiting_frame_frozen = FALSE;
|
||||
gdk_surface_thaw_updates (surface);
|
||||
}
|
||||
|
||||
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
|
||||
|
||||
if (impl->display_server.xdg_surface)
|
||||
{
|
||||
xdg_surface_destroy (impl->display_server.xdg_surface);
|
||||
@@ -1004,6 +989,15 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
impl->initial_configure_received = FALSE;
|
||||
}
|
||||
|
||||
impl->awaiting_frame = FALSE;
|
||||
if (impl->awaiting_frame_frozen)
|
||||
{
|
||||
impl->awaiting_frame_frozen = FALSE;
|
||||
gdk_surface_thaw_updates (surface);
|
||||
}
|
||||
|
||||
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
|
||||
|
||||
g_clear_pointer (&impl->display_server.wl_surface, wl_surface_destroy);
|
||||
|
||||
g_slist_free (impl->display_server.outputs);
|
||||
|
||||
@@ -1005,8 +1005,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
|
||||
} bmi;
|
||||
HDC hdc;
|
||||
uint8_t *pixels, *bits;
|
||||
int x, y, w, h;
|
||||
gsize rowstride;
|
||||
int rowstride, x, y, w, h;
|
||||
|
||||
if (!GDI_CALL (GetIconInfo, (hicon, &ii)))
|
||||
return NULL;
|
||||
@@ -1058,7 +1057,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
|
||||
no_alpha = FALSE;
|
||||
pixels += 4;
|
||||
}
|
||||
pixels += rowstride - w * 4;
|
||||
pixels += (w * 4 - rowstride);
|
||||
}
|
||||
|
||||
/* mask */
|
||||
@@ -1073,7 +1072,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
|
||||
pixels[3] = 255 - bits[(x + y * w) * 4];
|
||||
pixels += 4;
|
||||
}
|
||||
pixels += rowstride - w * 4;
|
||||
pixels += (w * 4 - rowstride);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1147,7 +1146,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
|
||||
xorp++;
|
||||
}
|
||||
}
|
||||
pixels += rowstride - w * 4;
|
||||
pixels += (w * 4 - rowstride);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1836,7 +1836,7 @@ static void
|
||||
gdk_drag_anim_destroy (GdkDragAnim *anim)
|
||||
{
|
||||
g_object_unref (anim->drag);
|
||||
g_free (anim);
|
||||
g_slice_free (GdkDragAnim, anim);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1936,7 +1936,7 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
|
||||
cairo_surface_destroy (surface);
|
||||
*/
|
||||
|
||||
anim = g_new0 (GdkDragAnim, 1);
|
||||
anim = g_slice_new0 (GdkDragAnim);
|
||||
g_set_object (&anim->drag, drag_win32);
|
||||
anim->frame_clock = gdk_surface_get_frame_clock (drag_win32->drag_surface);
|
||||
anim->start_time = gdk_frame_clock_get_frame_time (anim->frame_clock);
|
||||
|
||||
@@ -1975,7 +1975,7 @@ gdk_x11_display_finalize (GObject *object)
|
||||
if (trap->end_sequence == 0)
|
||||
g_warning ("Display finalized with an unpopped error trap");
|
||||
|
||||
g_free (trap);
|
||||
g_slice_free (GdkErrorTrap, trap);
|
||||
}
|
||||
|
||||
g_free (display_x11->program_class);
|
||||
@@ -2499,7 +2499,7 @@ delete_outdated_error_traps (GdkX11Display *display_x11)
|
||||
tmp_list = tmp_list->next;
|
||||
display_x11->error_traps =
|
||||
g_slist_delete_link (display_x11->error_traps, free_me);
|
||||
g_free (trap);
|
||||
g_slice_free (GdkErrorTrap, trap);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2531,7 +2531,7 @@ gdk_x11_display_error_trap_push (GdkDisplay *display)
|
||||
/* set up the Xlib callback to tell us about errors */
|
||||
_gdk_x11_error_handler_push ();
|
||||
|
||||
trap = g_new0 (GdkErrorTrap, 1);
|
||||
trap = g_slice_new0 (GdkErrorTrap);
|
||||
|
||||
trap->start_sequence = XNextRequest (display_x11->xdisplay);
|
||||
trap->error_code = Success;
|
||||
|
||||
@@ -1783,7 +1783,7 @@ gdk_drag_anim_destroy (GdkDragAnim *anim)
|
||||
{
|
||||
gdk_surface_hide (anim->drag->drag_surface);
|
||||
g_object_unref (anim->drag);
|
||||
g_free (anim);
|
||||
g_slice_free (GdkDragAnim, anim);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1882,7 +1882,7 @@ gdk_x11_drag_drop_done (GdkDrag *drag,
|
||||
cairo_surface_destroy (surface);
|
||||
*/
|
||||
|
||||
anim = g_new0 (GdkDragAnim, 1);
|
||||
anim = g_slice_new0 (GdkDragAnim);
|
||||
anim->drag = g_object_ref (x11_drag);
|
||||
anim->frame_clock = gdk_surface_get_frame_clock (x11_drag->drag_surface);
|
||||
anim->start_time = gdk_frame_clock_get_frame_time (anim->frame_clock);
|
||||
|
||||
@@ -79,7 +79,7 @@ gdk_x11_pending_selection_notify_new (Window window,
|
||||
{
|
||||
GdkX11PendingSelectionNotify *pending;
|
||||
|
||||
pending = g_new0 (GdkX11PendingSelectionNotify, 1);
|
||||
pending = g_slice_new0 (GdkX11PendingSelectionNotify);
|
||||
pending->n_pending = 1;
|
||||
|
||||
pending->xevent.type = SelectionNotify;
|
||||
@@ -97,7 +97,7 @@ gdk_x11_pending_selection_notify_new (Window window,
|
||||
static void
|
||||
gdk_x11_pending_selection_notify_free (GdkX11PendingSelectionNotify *notify)
|
||||
{
|
||||
g_free (notify);
|
||||
g_slice_free (GdkX11PendingSelectionNotify, notify);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -731,7 +731,7 @@ handle_timestamp_done (GObject *stream,
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_free (user_data);
|
||||
g_slice_free (gulong, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -747,7 +747,7 @@ handle_timestamp (GOutputStream *stream,
|
||||
{
|
||||
gulong *time_;
|
||||
|
||||
time_ = g_new (gulong, 1);
|
||||
time_ = g_slice_new (gulong);
|
||||
*time_ = timestamp;
|
||||
|
||||
g_output_stream_write_all_async (stream,
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "gdkglcontext-x11.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdkdragsurfacesizeprivate.h"
|
||||
|
||||
#include "gdkseatprivate.h"
|
||||
#include "gdkprivate.h"
|
||||
@@ -346,36 +345,6 @@ compute_toplevel_size (GdkSurface *surface,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compute_drag_surface_size (GdkSurface *surface,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
|
||||
GdkDragSurfaceSize size;
|
||||
|
||||
gdk_drag_surface_size_init (&size);
|
||||
size.width = impl->next_layout.configured_width;
|
||||
size.height = impl->next_layout.configured_height;
|
||||
|
||||
gdk_drag_surface_notify_compute_size (GDK_DRAG_SURFACE (surface), &size);
|
||||
|
||||
if ((impl->last_computed_width != size.width ||
|
||||
impl->last_computed_height != size.height) &&
|
||||
(impl->next_layout.configured_width != size.width ||
|
||||
impl->next_layout.configured_height != size.height))
|
||||
{
|
||||
*width = size.width;
|
||||
*height = size.height;
|
||||
impl->last_computed_width = size.width;
|
||||
impl->last_computed_height = size.height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compute_size_idle (gpointer user_data)
|
||||
{
|
||||
@@ -425,24 +394,6 @@ gdk_x11_surface_compute_size (GdkSurface *surface)
|
||||
impl->surface_scale);
|
||||
}
|
||||
|
||||
impl->next_layout.surface_geometry_dirty = FALSE;
|
||||
impl->next_layout.configure_pending = FALSE;
|
||||
}
|
||||
else if (GDK_IS_DRAG_SURFACE (surface))
|
||||
{
|
||||
int width, height;
|
||||
|
||||
if (compute_drag_surface_size (surface, &width, &height))
|
||||
gdk_x11_surface_toplevel_resize (surface, width, height);
|
||||
|
||||
if (surface->resize_count == 0)
|
||||
{
|
||||
gdk_x11_surface_update_size (impl,
|
||||
impl->next_layout.configured_width,
|
||||
impl->next_layout.configured_height,
|
||||
impl->surface_scale);
|
||||
}
|
||||
|
||||
impl->next_layout.surface_geometry_dirty = FALSE;
|
||||
impl->next_layout.configure_pending = FALSE;
|
||||
}
|
||||
@@ -836,7 +787,7 @@ free_pixmap (gpointer datap)
|
||||
}
|
||||
|
||||
g_object_unref (data->display);
|
||||
g_free (data);
|
||||
g_slice_free (FreePixmapData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -847,7 +798,7 @@ attach_free_pixmap_handler (cairo_surface_t *surface,
|
||||
static const cairo_user_data_key_t key;
|
||||
FreePixmapData *data;
|
||||
|
||||
data = g_new (FreePixmapData, 1);
|
||||
data = g_slice_new (FreePixmapData);
|
||||
data->display = g_object_ref (display);
|
||||
data->pixmap = pixmap;
|
||||
|
||||
@@ -1407,7 +1358,6 @@ gdk_x11_surface_destroy (GdkSurface *surface,
|
||||
|
||||
unhook_surface_changed (surface);
|
||||
disconnect_frame_clock (surface);
|
||||
g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
|
||||
|
||||
if (impl->cairo_surface)
|
||||
{
|
||||
|
||||
@@ -44,7 +44,6 @@ gsk_gl_attachment_state_new (void)
|
||||
self->textures[i].id = 0;
|
||||
self->textures[i].changed = FALSE;
|
||||
self->textures[i].initial = TRUE;
|
||||
self->textures[i].sampler = sampler_index (GL_LINEAR, GL_LINEAR);
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -66,12 +65,9 @@ void
|
||||
gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
|
||||
GLenum target,
|
||||
GLenum texture,
|
||||
guint id,
|
||||
GLint min_filter,
|
||||
GLint mag_filter)
|
||||
guint id)
|
||||
{
|
||||
GskGLBindTexture *attach;
|
||||
unsigned int sampler;
|
||||
|
||||
g_assert (self != NULL);
|
||||
g_assert (target == GL_TEXTURE_1D ||
|
||||
@@ -81,16 +77,12 @@ gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
|
||||
|
||||
attach = &self->textures[texture - GL_TEXTURE0];
|
||||
|
||||
sampler = sampler_index (min_filter, mag_filter);
|
||||
|
||||
if (attach->target != target || attach->texture != texture || attach->id != id ||
|
||||
attach->sampler != sampler)
|
||||
if (attach->target != target || attach->texture != texture || attach->id != id)
|
||||
{
|
||||
attach->target = target;
|
||||
attach->texture = texture;
|
||||
attach->id = id;
|
||||
attach->initial = FALSE;
|
||||
attach->sampler = sampler;
|
||||
|
||||
if (attach->changed == FALSE)
|
||||
{
|
||||
|
||||
@@ -29,37 +29,11 @@ typedef struct _GskGLAttachmentState GskGLAttachmentState;
|
||||
typedef struct _GskGLBindFramebuffer GskGLBindFramebuffer;
|
||||
typedef struct _GskGLBindTexture GskGLBindTexture;
|
||||
|
||||
#define GSK_GL_N_FILTERS 3
|
||||
|
||||
static inline guint
|
||||
filter_index (GLint filter)
|
||||
{
|
||||
switch (filter)
|
||||
{
|
||||
case GL_LINEAR:
|
||||
return 0;
|
||||
case GL_NEAREST:
|
||||
return 1;
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
return 2;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static inline guint
|
||||
sampler_index (GLint min_filter,
|
||||
GLint mag_filter)
|
||||
{
|
||||
return filter_index (min_filter) * GSK_GL_N_FILTERS + filter_index (mag_filter);
|
||||
}
|
||||
|
||||
struct _GskGLBindTexture
|
||||
{
|
||||
guint changed : 1;
|
||||
guint initial : 1;
|
||||
GLenum target : 26;
|
||||
guint sampler : 4;
|
||||
GLenum target : 30;
|
||||
GLenum texture;
|
||||
guint id;
|
||||
};
|
||||
@@ -88,9 +62,7 @@ void gsk_gl_attachment_state_unref (GskGLAttachmentS
|
||||
void gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
|
||||
GLenum target,
|
||||
GLenum texture,
|
||||
guint id,
|
||||
GLint min_filter,
|
||||
GLint mag_filter);
|
||||
guint id);
|
||||
void gsk_gl_attachment_state_bind_framebuffer (GskGLAttachmentState *self,
|
||||
guint id);
|
||||
|
||||
|
||||
+21
-75
@@ -247,16 +247,6 @@ will_ignore_batch (GskGLCommandQueue *self)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline GLint
|
||||
filter_from_index (guint index)
|
||||
{
|
||||
GLint filters[3] = { GL_LINEAR, GL_NEAREST, GL_LINEAR_MIPMAP_LINEAR };
|
||||
|
||||
g_assert (index < GSK_GL_N_FILTERS);
|
||||
|
||||
return filters[index];
|
||||
}
|
||||
|
||||
static inline guint
|
||||
snapshot_attachments (const GskGLAttachmentState *state,
|
||||
GskGLCommandBinds *array)
|
||||
@@ -270,7 +260,6 @@ snapshot_attachments (const GskGLAttachmentState *state,
|
||||
{
|
||||
bind[count].id = state->textures[i].id;
|
||||
bind[count].texture = state->textures[i].texture;
|
||||
bind[count].sampler = state->textures[i].sampler;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -411,9 +400,6 @@ gsk_gl_command_queue_dispose (GObject *object)
|
||||
g_clear_pointer (&self->attachments, gsk_gl_attachment_state_unref);
|
||||
g_clear_pointer (&self->uniforms, gsk_gl_uniform_state_unref);
|
||||
|
||||
if (self->has_samplers)
|
||||
glDeleteSamplers (G_N_ELEMENTS (self->samplers), self->samplers);
|
||||
|
||||
gsk_gl_command_batches_clear (&self->batches);
|
||||
gsk_gl_command_binds_clear (&self->batch_binds);
|
||||
gsk_gl_command_uniforms_clear (&self->batch_uniforms);
|
||||
@@ -448,7 +434,6 @@ gsk_gl_command_queue_new (GdkGLContext *context,
|
||||
GskGLUniformState *uniforms)
|
||||
{
|
||||
GskGLCommandQueue *self;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
|
||||
|
||||
@@ -464,37 +449,7 @@ gsk_gl_command_queue_new (GdkGLContext *context,
|
||||
|
||||
/* Determine max texture size immediately and restore context */
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &self->max_texture_size);
|
||||
if (g_getenv ("GSK_MAX_TEXTURE_SIZE"))
|
||||
{
|
||||
int max_texture_size = atoi (g_getenv ("GSK_MAX_TEXTURE_SIZE"));
|
||||
if (max_texture_size == 0)
|
||||
{
|
||||
g_warning ("Failed to parse GSK_MAX_TEXTURE_SIZE");
|
||||
}
|
||||
else
|
||||
{
|
||||
max_texture_size = MAX (max_texture_size, 512);
|
||||
GSK_DEBUG(OPENGL, "Limiting max texture size to %d", max_texture_size);
|
||||
self->max_texture_size = MIN (self->max_texture_size, max_texture_size);
|
||||
}
|
||||
}
|
||||
|
||||
self->has_samplers = gdk_gl_context_check_version (context, 3, 3, 3, 0);
|
||||
|
||||
/* create the samplers */
|
||||
if (self->has_samplers)
|
||||
{
|
||||
glGenSamplers (G_N_ELEMENTS (self->samplers), self->samplers);
|
||||
for (i = 0; i < G_N_ELEMENTS (self->samplers); i++)
|
||||
{
|
||||
glSamplerParameteri (self->samplers[i], GL_TEXTURE_MIN_FILTER, filter_from_index(i / GSK_GL_N_FILTERS));
|
||||
glSamplerParameteri (self->samplers[i], GL_TEXTURE_MAG_FILTER, filter_from_index(i % GSK_GL_N_FILTERS));
|
||||
glSamplerParameteri (self->samplers[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri (self->samplers[i], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
}
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
@@ -1017,7 +972,6 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
guint vao_id;
|
||||
guint vbo_id;
|
||||
int textures[4];
|
||||
int samplers[4];
|
||||
int framebuffer = -1;
|
||||
int next_batch_index;
|
||||
int active = -1;
|
||||
@@ -1030,8 +984,6 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (textures); i++)
|
||||
textures[i] = -1;
|
||||
for (guint i = 0; i < G_N_ELEMENTS (samplers); i++)
|
||||
samplers[i] = -1;
|
||||
|
||||
gsk_gl_command_queue_sort_batches (self);
|
||||
|
||||
@@ -1159,23 +1111,6 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, bind->id);
|
||||
textures[bind->texture] = bind->id;
|
||||
if (!self->has_samplers)
|
||||
{
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_from_index(bind->sampler / GSK_GL_N_FILTERS));
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_from_index(bind->sampler % GSK_GL_N_FILTERS));
|
||||
}
|
||||
}
|
||||
|
||||
if (samplers[bind->texture] != bind->sampler)
|
||||
{
|
||||
if (self->has_samplers)
|
||||
glBindSampler (bind->texture, self->samplers[bind->sampler]);
|
||||
else
|
||||
{
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_from_index(bind->sampler / GSK_GL_N_FILTERS));
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_from_index(bind->sampler % GSK_GL_N_FILTERS));
|
||||
}
|
||||
samplers[bind->texture] = bind->sampler;
|
||||
}
|
||||
|
||||
bind++;
|
||||
@@ -1311,6 +1246,8 @@ gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
guint *out_fbo_id,
|
||||
guint *out_texture_id)
|
||||
{
|
||||
@@ -1324,8 +1261,9 @@ gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
|
||||
g_assert (out_texture_id != NULL);
|
||||
|
||||
texture_id = gsk_gl_command_queue_create_texture (self,
|
||||
width, height,
|
||||
format);
|
||||
width, height,
|
||||
format,
|
||||
min_filter, mag_filter);
|
||||
|
||||
if (texture_id == -1)
|
||||
{
|
||||
@@ -1350,7 +1288,9 @@ int
|
||||
gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||
int width,
|
||||
int height,
|
||||
int format)
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter)
|
||||
{
|
||||
GLuint texture_id = 0;
|
||||
|
||||
@@ -1366,9 +1306,9 @@ gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
@@ -1494,7 +1434,9 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
|
||||
|
||||
int
|
||||
gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
GdkTexture *texture)
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
int mag_filter)
|
||||
{
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
cairo_surface_t *surface = NULL;
|
||||
@@ -1503,6 +1445,7 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
|
||||
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
|
||||
g_assert (!GDK_IS_GL_TEXTURE (texture));
|
||||
g_assert (mag_filter == GL_LINEAR || mag_filter == GL_NEAREST);
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
@@ -1511,10 +1454,10 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
g_warning ("Attempt to create texture of size %ux%u but max size is %d. "
|
||||
"Clipping will occur.",
|
||||
width, height, self->max_texture_size);
|
||||
width = MIN (width, self->max_texture_size);
|
||||
height = MIN (height, self->max_texture_size);
|
||||
width = MAX (width, self->max_texture_size);
|
||||
height = MAX (height, self->max_texture_size);
|
||||
}
|
||||
texture_id = gsk_gl_command_queue_create_texture (self, width, height, GL_RGBA8);
|
||||
texture_id = gsk_gl_command_queue_create_texture (self, width, height, GL_RGBA8, min_filter, mag_filter);
|
||||
if (texture_id == -1)
|
||||
return texture_id;
|
||||
|
||||
@@ -1526,6 +1469,9 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
|
||||
gsk_gl_command_queue_do_upload_texture (self, texture);
|
||||
|
||||
if (min_filter == GL_LINEAR_MIPMAP_LINEAR)
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
|
||||
/* Restore previous texture state if any */
|
||||
if (self->attachments->textures[0].id > 0)
|
||||
glBindTexture (self->attachments->textures[0].target,
|
||||
|
||||
@@ -53,12 +53,10 @@ typedef struct _GskGLCommandBind
|
||||
* texture will be placed into. We always use GL_TEXTURE_2D so we don't
|
||||
* waste any bits here to indicate that.
|
||||
*/
|
||||
guint texture : 4;
|
||||
|
||||
guint sampler : 4;
|
||||
guint texture : 5;
|
||||
|
||||
/* The identifier for the texture created with glGenTextures(). */
|
||||
guint id: 24;
|
||||
guint id : 27;
|
||||
} GskGLCommandBind;
|
||||
|
||||
G_STATIC_ASSERT (sizeof (GskGLCommandBind) == 4);
|
||||
@@ -227,13 +225,6 @@ struct _GskGLCommandQueue
|
||||
*/
|
||||
GskGLCommandUniforms batch_uniforms;
|
||||
|
||||
/* Array of samplers that we use for mag/min filter handling. It is indexed
|
||||
* by the sampler_index() function.
|
||||
* Note that when samplers are not supported (hello GLES), we fall back to
|
||||
* setting the texture filter, but that needs to be done for every texture.
|
||||
*/
|
||||
GLuint samplers[GSK_GL_N_FILTERS * GSK_GL_N_FILTERS];
|
||||
|
||||
/* Discovered max texture size when loading the command queue so that we
|
||||
* can either scale down or slice textures to fit within this size. Assumed
|
||||
* to be both height and width.
|
||||
@@ -266,9 +257,6 @@ struct _GskGLCommandQueue
|
||||
/* Counter for uploads on the frame */
|
||||
guint n_uploads;
|
||||
|
||||
/* If the GL context is new enough for sampler support */
|
||||
guint has_samplers : 1;
|
||||
|
||||
/* If we're inside a begin/end_frame pair */
|
||||
guint in_frame : 1;
|
||||
|
||||
@@ -293,16 +281,22 @@ void gsk_gl_command_queue_execute (GskGLCommandQueue
|
||||
const cairo_region_t *scissor,
|
||||
guint default_framebuffer);
|
||||
int gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
GdkTexture *texture);
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
int mag_filter);
|
||||
int gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||
int width,
|
||||
int height,
|
||||
int format);
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter);
|
||||
guint gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self);
|
||||
gboolean gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
guint *out_fbo_id,
|
||||
guint *out_texture_id);
|
||||
void gsk_gl_command_queue_delete_program (GskGLCommandQueue *self,
|
||||
|
||||
+71
-61
@@ -59,7 +59,8 @@ texture_key_hash (gconstpointer v)
|
||||
|
||||
return GPOINTER_TO_SIZE (k->pointer) ^
|
||||
((scale_x << 8) |
|
||||
(scale_y << 4) |
|
||||
(scale_y << 6) |
|
||||
(k->filter << 1) |
|
||||
k->pointer_is_child);
|
||||
}
|
||||
|
||||
@@ -73,6 +74,7 @@ texture_key_equal (gconstpointer v1,
|
||||
return k1->pointer == k2->pointer &&
|
||||
k1->scale_x == k2->scale_x &&
|
||||
k1->scale_y == k2->scale_y &&
|
||||
k1->filter == k2->filter &&
|
||||
k1->pointer_is_child == k2->pointer_is_child &&
|
||||
(!k1->pointer_is_child || memcmp (&k1->parent_rect, &k2->parent_rect, sizeof k1->parent_rect) == 0);
|
||||
}
|
||||
@@ -617,7 +619,7 @@ gsk_gl_driver_after_frame (GskGLDriver *self)
|
||||
|
||||
gsk_gl_driver_autorelease_framebuffer (self, render_target->framebuffer_id);
|
||||
gsk_gl_driver_autorelease_texture (self, render_target->texture_id);
|
||||
g_free (render_target);
|
||||
g_slice_free (GskGLRenderTarget, render_target);
|
||||
|
||||
self->render_targets->len--;
|
||||
}
|
||||
@@ -690,7 +692,8 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
|
||||
* gsk_gl_driver_load_texture:
|
||||
* @self: a `GdkTexture`
|
||||
* @texture: a `GdkTexture`
|
||||
* @ensure_mipmap: Mipmaps for this texture must exist for downscaling
|
||||
* @min_filter: GL_NEAREST or GL_LINEAR
|
||||
* @mag_filter: GL_NEAREST or GL_LINEAR
|
||||
*
|
||||
* Loads a `GdkTexture` by uploading the contents to the GPU when
|
||||
* necessary. If @texture is a `GdkGLTexture`, it can be used without
|
||||
@@ -711,7 +714,8 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
|
||||
guint
|
||||
gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
GdkTexture *texture,
|
||||
gboolean ensure_mipmap)
|
||||
int min_filter,
|
||||
int mag_filter)
|
||||
{
|
||||
GdkGLContext *context;
|
||||
GdkMemoryTexture *downloaded_texture;
|
||||
@@ -719,6 +723,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
guint texture_id;
|
||||
int height;
|
||||
int width;
|
||||
int format;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), 0);
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), 0);
|
||||
@@ -726,23 +731,9 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
|
||||
context = self->command_queue->context;
|
||||
|
||||
texture_id = 0;
|
||||
downloaded_texture = NULL;
|
||||
format = GL_RGBA8;
|
||||
|
||||
t = gdk_texture_get_render_data (texture, self);
|
||||
if (t && t->texture_id)
|
||||
{
|
||||
if (ensure_mipmap & !t->has_mipmap)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, t->texture_id);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
t->has_mipmap = TRUE;
|
||||
}
|
||||
|
||||
return t->texture_id;
|
||||
}
|
||||
|
||||
if (GDK_IS_GL_TEXTURE (texture) && !ensure_mipmap)
|
||||
if (GDK_IS_GL_TEXTURE (texture))
|
||||
{
|
||||
GdkGLTexture *gl_texture = (GdkGLTexture *) texture;
|
||||
GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
|
||||
@@ -752,32 +743,36 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
/* A GL texture from the same GL context is a simple task... */
|
||||
return gdk_gl_texture_get_id (gl_texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
downloaded_texture = gdk_memory_texture_from_texture (texture, gdk_texture_get_format (texture));
|
||||
}
|
||||
}
|
||||
|
||||
if (texture_id == 0)
|
||||
else
|
||||
{
|
||||
if ((t = gdk_texture_get_render_data (texture, self)))
|
||||
{
|
||||
if (t->min_filter == min_filter && t->mag_filter == mag_filter && t->texture_id)
|
||||
return t->texture_id;
|
||||
}
|
||||
|
||||
downloaded_texture = gdk_memory_texture_from_texture (texture, gdk_texture_get_format (texture));
|
||||
|
||||
/* The download_texture() call may have switched the GL context. Make sure
|
||||
* the right context is at work again.
|
||||
*/
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue, GDK_TEXTURE (downloaded_texture));
|
||||
}
|
||||
|
||||
/* The download_texture() call may have switched the GL context. Make sure
|
||||
* the right context is at work again. */
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
|
||||
GDK_TEXTURE (downloaded_texture),
|
||||
min_filter,
|
||||
mag_filter);
|
||||
|
||||
t = gsk_gl_texture_new (texture_id,
|
||||
width, height,
|
||||
self->current_frame_id);
|
||||
if (ensure_mipmap)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, t->texture_id);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
t->has_mipmap = TRUE;
|
||||
}
|
||||
width, height, format, min_filter, mag_filter,
|
||||
self->current_frame_id);
|
||||
|
||||
g_hash_table_insert (self->textures, GUINT_TO_POINTER (texture_id), t);
|
||||
|
||||
@@ -789,7 +784,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
|
||||
g_clear_object (&downloaded_texture);
|
||||
|
||||
return t->texture_id;
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -798,6 +793,8 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
* @width: the width of the texture
|
||||
* @height: the height of the texture
|
||||
* @format: format for the texture
|
||||
* @min_filter: GL_NEAREST or GL_LINEAR
|
||||
* @mag_filter: GL_NEAREST or GL_FILTER
|
||||
*
|
||||
* Creates a new texture immediately that can be used by the caller
|
||||
* to upload data, map to a framebuffer, or other uses which may
|
||||
@@ -815,7 +812,9 @@ GskGLTexture *
|
||||
gsk_gl_driver_create_texture (GskGLDriver *self,
|
||||
float width,
|
||||
float height,
|
||||
int format)
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter)
|
||||
{
|
||||
GskGLTexture *texture;
|
||||
guint texture_id;
|
||||
@@ -823,11 +822,14 @@ gsk_gl_driver_create_texture (GskGLDriver *self,
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), NULL);
|
||||
|
||||
texture_id = gsk_gl_command_queue_create_texture (self->command_queue,
|
||||
width, height,
|
||||
format);
|
||||
width, height,
|
||||
format,
|
||||
min_filter, mag_filter);
|
||||
texture = gsk_gl_texture_new (texture_id,
|
||||
width, height,
|
||||
self->current_frame_id);
|
||||
width, height,
|
||||
format,
|
||||
min_filter, mag_filter,
|
||||
self->current_frame_id);
|
||||
g_hash_table_insert (self->textures,
|
||||
GUINT_TO_POINTER (texture->texture_id),
|
||||
texture);
|
||||
@@ -873,6 +875,8 @@ gsk_gl_driver_release_texture (GskGLDriver *self,
|
||||
* @width: the width for the render target
|
||||
* @height: the height for the render target
|
||||
* @format: the format to use
|
||||
* @min_filter: the min filter to use for the texture
|
||||
* @mag_filter: the mag filter to use for the texture
|
||||
* @out_render_target: (out): a location for the render target
|
||||
*
|
||||
* Creates a new render target which contains a framebuffer and a texture
|
||||
@@ -893,6 +897,8 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
GskGLRenderTarget **out_render_target)
|
||||
{
|
||||
guint framebuffer_id;
|
||||
@@ -910,7 +916,9 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||
GskGLRenderTarget *render_target = g_ptr_array_index (self->render_targets, i-1);
|
||||
|
||||
if (render_target->width == width &&
|
||||
render_target->height == height)
|
||||
render_target->height == height &&
|
||||
render_target->min_filter == min_filter &&
|
||||
render_target->mag_filter == mag_filter)
|
||||
{
|
||||
*out_render_target = g_ptr_array_steal_index_fast (self->render_targets, i-1);
|
||||
return TRUE;
|
||||
@@ -922,11 +930,14 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||
if (gsk_gl_command_queue_create_render_target (self->command_queue,
|
||||
width, height,
|
||||
format,
|
||||
min_filter, mag_filter,
|
||||
&framebuffer_id, &texture_id))
|
||||
{
|
||||
GskGLRenderTarget *render_target;
|
||||
|
||||
render_target = g_new0 (GskGLRenderTarget, 1);
|
||||
render_target = g_slice_new0 (GskGLRenderTarget);
|
||||
render_target->min_filter = min_filter;
|
||||
render_target->mag_filter = mag_filter;
|
||||
render_target->format = format;
|
||||
render_target->width = width;
|
||||
render_target->height = height;
|
||||
@@ -987,13 +998,16 @@ gsk_gl_driver_release_render_target (GskGLDriver *self,
|
||||
texture = gsk_gl_texture_new (render_target->texture_id,
|
||||
render_target->width,
|
||||
render_target->height,
|
||||
render_target->format,
|
||||
render_target->min_filter,
|
||||
render_target->mag_filter,
|
||||
self->current_frame_id);
|
||||
g_hash_table_insert (self->textures,
|
||||
GUINT_TO_POINTER (texture_id),
|
||||
g_steal_pointer (&texture));
|
||||
|
||||
gsk_gl_driver_autorelease_framebuffer (self, render_target->framebuffer_id);
|
||||
g_free (render_target);
|
||||
g_slice_free (GskGLRenderTarget, render_target);
|
||||
|
||||
}
|
||||
|
||||
@@ -1180,7 +1194,8 @@ gsk_gl_driver_create_command_queue (GskGLDriver *self,
|
||||
void
|
||||
gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
GdkTexture *texture,
|
||||
gboolean ensure_mipmap,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
guint min_cols,
|
||||
guint min_rows,
|
||||
GskGLTextureSlice **out_slices,
|
||||
@@ -1212,12 +1227,9 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
|
||||
n_slices = cols * rows;
|
||||
|
||||
t = gdk_texture_get_render_data (texture, self);
|
||||
|
||||
if (t)
|
||||
if ((t = gdk_texture_get_render_data (texture, self)))
|
||||
{
|
||||
if (t->n_slices == n_slices &&
|
||||
(t->has_mipmap || !ensure_mipmap))
|
||||
if (t->n_slices == n_slices)
|
||||
{
|
||||
*out_slices = t->slices;
|
||||
*out_n_slices = t->n_slices;
|
||||
@@ -1245,13 +1257,10 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
subtex = gdk_memory_texture_new_subtexture (memtex,
|
||||
x, y,
|
||||
slice_width, slice_height);
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue, subtex);
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
|
||||
subtex,
|
||||
min_filter, mag_filter);
|
||||
g_object_unref (subtex);
|
||||
if (ensure_mipmap)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
slices[slice_index].rect.x = x;
|
||||
slices[slice_index].rect.y = y;
|
||||
@@ -1271,8 +1280,9 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
/* Allocate one Texture for the entire thing. */
|
||||
t = gsk_gl_texture_new (0,
|
||||
tex_width, tex_height,
|
||||
GL_RGBA8,
|
||||
GL_NEAREST, GL_NEAREST,
|
||||
self->current_frame_id);
|
||||
t->has_mipmap = ensure_mipmap;
|
||||
|
||||
/* Use gsk_gl_texture_free() as destroy notify here since we are
|
||||
* not inserting this GskGLTexture into self->textures!
|
||||
@@ -1331,7 +1341,7 @@ create_texture_from_texture_destroy (gpointer data)
|
||||
gdk_gl_context_make_current (state->context);
|
||||
glDeleteTextures (1, &state->texture_id);
|
||||
g_clear_object (&state->context);
|
||||
g_free (state);
|
||||
g_slice_free (GskGLTextureState, state);
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
@@ -1352,7 +1362,7 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
|
||||
if (!(texture = g_hash_table_lookup (self->textures, GUINT_TO_POINTER (texture_id))))
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
state = g_new0 (GskGLTextureState, 1);
|
||||
state = g_slice_new0 (GskGLTextureState);
|
||||
state->texture_id = texture_id;
|
||||
state->context = g_object_ref (self->command_queue->context);
|
||||
|
||||
|
||||
+22
-13
@@ -61,6 +61,7 @@ typedef struct {
|
||||
gconstpointer pointer;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
int filter;
|
||||
int pointer_is_child;
|
||||
graphene_rect_t parent_rect; /* Valid when pointer_is_child */
|
||||
} GskTextureKey;
|
||||
@@ -85,6 +86,8 @@ struct _GskGLRenderTarget
|
||||
{
|
||||
guint framebuffer_id;
|
||||
guint texture_id;
|
||||
int min_filter;
|
||||
int mag_filter;
|
||||
int format;
|
||||
int width;
|
||||
int height;
|
||||
@@ -141,6 +144,8 @@ gboolean gsk_gl_driver_create_render_target (GskGLDriver *s
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
GskGLRenderTarget **render_target);
|
||||
guint gsk_gl_driver_release_render_target (GskGLDriver *self,
|
||||
GskGLRenderTarget *render_target,
|
||||
@@ -156,11 +161,14 @@ void gsk_gl_driver_cache_texture (GskGLDriver *s
|
||||
guint texture_id);
|
||||
guint gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
GdkTexture *texture,
|
||||
gboolean ensure_mipmap);
|
||||
int min_filter,
|
||||
int mag_filter);
|
||||
GskGLTexture * gsk_gl_driver_create_texture (GskGLDriver *self,
|
||||
float width,
|
||||
float height,
|
||||
int format);
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter);
|
||||
void gsk_gl_driver_release_texture (GskGLDriver *self,
|
||||
GskGLTexture *texture);
|
||||
void gsk_gl_driver_release_texture_by_id (GskGLDriver *self,
|
||||
@@ -169,7 +177,8 @@ GskGLTexture * gsk_gl_driver_mark_texture_permanent (GskGLDriver *s
|
||||
guint texture_id);
|
||||
void gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
GdkTexture *texture,
|
||||
gboolean ensure_mipmap,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
guint min_cols,
|
||||
guint min_rows,
|
||||
GskGLTextureSlice **out_slices,
|
||||
@@ -223,7 +232,8 @@ gsk_gl_driver_lookup_texture (GskGLDriver *self,
|
||||
static inline void
|
||||
gsk_gl_driver_slice_texture (GskGLDriver *self,
|
||||
GdkTexture *texture,
|
||||
gboolean ensure_mipmap,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
guint min_cols,
|
||||
guint min_rows,
|
||||
GskGLTextureSlice **out_slices,
|
||||
@@ -231,18 +241,17 @@ gsk_gl_driver_slice_texture (GskGLDriver *self,
|
||||
{
|
||||
GskGLTexture *t;
|
||||
|
||||
t = gdk_texture_get_render_data (texture, self);
|
||||
|
||||
if (t && t->slices &&
|
||||
(t->has_mipmap || !ensure_mipmap) &&
|
||||
min_cols == 0 && min_rows == 0)
|
||||
if ((t = gdk_texture_get_render_data (texture, self)))
|
||||
{
|
||||
*out_slices = t->slices;
|
||||
*out_n_slices = t->n_slices;
|
||||
return;
|
||||
if (min_cols == 0 && min_rows == 0)
|
||||
{
|
||||
*out_slices = t->slices;
|
||||
*out_n_slices = t->n_slices;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gsk_gl_driver_add_texture_slices (self, texture, ensure_mipmap, min_cols, min_rows, out_slices, out_n_slices);
|
||||
gsk_gl_driver_add_texture_slices (self, texture, min_filter, mag_filter, min_cols, min_rows, out_slices, out_n_slices);
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -74,13 +74,13 @@ gsk_gl_glyph_key_free (gpointer data)
|
||||
GskGLGlyphKey *key = data;
|
||||
|
||||
g_clear_object (&key->font);
|
||||
g_free (key);
|
||||
g_slice_free (GskGLGlyphKey, key);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_glyph_value_free (gpointer data)
|
||||
{
|
||||
g_free (data);
|
||||
g_slice_free (GskGLGlyphValue, data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -88,9 +88,7 @@ gsk_gl_glyph_library_lookup_or_add (GskGLGlyphLibrary *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
GskGLGlyphKey *k;
|
||||
k = g_new (GskGLGlyphKey, 1);
|
||||
memcpy (k, key, sizeof (GskGLGlyphKey));
|
||||
GskGLGlyphKey *k = g_slice_copy (sizeof *key, key);
|
||||
g_object_ref (k->font);
|
||||
gsk_gl_glyph_library_add (self, k, out_value);
|
||||
self->front[front_index].key = *key;
|
||||
|
||||
@@ -52,7 +52,7 @@ gsk_gl_icon_data_free (gpointer data)
|
||||
GskGLIconData *icon_data = data;
|
||||
|
||||
g_clear_object (&icon_data->source_texture);
|
||||
g_free (icon_data);
|
||||
g_slice_free (GskGLIconData, icon_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -245,29 +245,6 @@ gsk_gl_program_set_uniform_color (GskGLProgram *self,
|
||||
color);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_program_set_uniform_texture_with_filter (GskGLProgram *self,
|
||||
guint key,
|
||||
guint stamp,
|
||||
GLenum texture_target,
|
||||
GLenum texture_slot,
|
||||
guint texture_id,
|
||||
GLint min_filter,
|
||||
GLint mag_filter)
|
||||
{
|
||||
gsk_gl_attachment_state_bind_texture (self->driver->command_queue->attachments,
|
||||
texture_target,
|
||||
texture_slot,
|
||||
texture_id,
|
||||
min_filter,
|
||||
mag_filter);
|
||||
gsk_gl_uniform_state_set_texture (self->uniforms,
|
||||
self->program_info,
|
||||
key,
|
||||
stamp,
|
||||
texture_slot);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_program_set_uniform_texture (GskGLProgram *self,
|
||||
guint key,
|
||||
@@ -276,14 +253,15 @@ gsk_gl_program_set_uniform_texture (GskGLProgram *self,
|
||||
GLenum texture_slot,
|
||||
guint texture_id)
|
||||
{
|
||||
gsk_gl_program_set_uniform_texture_with_filter (self,
|
||||
key,
|
||||
stamp,
|
||||
texture_target,
|
||||
texture_slot,
|
||||
texture_id,
|
||||
GL_LINEAR,
|
||||
GL_LINEAR);
|
||||
gsk_gl_attachment_state_bind_texture (self->driver->command_queue->attachments,
|
||||
texture_target,
|
||||
texture_slot,
|
||||
texture_id);
|
||||
gsk_gl_uniform_state_set_texture (self->uniforms,
|
||||
self->program_info,
|
||||
key,
|
||||
stamp,
|
||||
texture_slot);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
||||
@@ -379,6 +379,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
if (gsk_gl_driver_create_render_target (self->driver,
|
||||
width, height,
|
||||
format,
|
||||
GL_NEAREST, GL_NEAREST,
|
||||
&render_target))
|
||||
{
|
||||
gsk_gl_driver_begin_frame (self->driver, self->command_queue);
|
||||
|
||||
+139
-181
@@ -29,7 +29,6 @@
|
||||
#include <gsk/gskrendernodeprivate.h>
|
||||
#include <gsk/gskglshaderprivate.h>
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
#include <gdk/gdkmemorytextureprivate.h>
|
||||
#include <gsk/gsktransformprivate.h>
|
||||
#include <gsk/gskroundedrectprivate.h>
|
||||
#include <math.h>
|
||||
@@ -198,6 +197,7 @@ typedef struct _GskGLRenderOffscreen
|
||||
guint force_offscreen : 1;
|
||||
guint reset_clip : 1;
|
||||
guint do_not_cache : 1;
|
||||
guint linear_filter : 1;
|
||||
|
||||
/* Return location for whether we created a texture */
|
||||
guint was_offscreen : 1;
|
||||
@@ -260,7 +260,6 @@ node_supports_2d_transform (const GskRenderNode *node)
|
||||
case GSK_OPACITY_NODE:
|
||||
case GSK_COLOR_MATRIX_NODE:
|
||||
case GSK_TEXTURE_NODE:
|
||||
case GSK_TEXTURE_SCALE_NODE:
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
@@ -315,7 +314,6 @@ node_supports_transform (const GskRenderNode *node)
|
||||
case GSK_CAIRO_NODE:
|
||||
case GSK_BLEND_NODE:
|
||||
case GSK_BLUR_NODE:
|
||||
case GSK_MASK_NODE:
|
||||
return TRUE;
|
||||
|
||||
case GSK_SHADOW_NODE:
|
||||
@@ -874,21 +872,6 @@ gsk_gl_render_job_transform_bounds (GskGLRenderJob *job,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_untransform_bounds (GskGLRenderJob *job,
|
||||
const graphene_rect_t *rect,
|
||||
graphene_rect_t *out_rect)
|
||||
{
|
||||
GskTransform *transform;
|
||||
|
||||
transform = gsk_transform_invert (gsk_transform_ref (job->current_modelview->transform));
|
||||
|
||||
gsk_transform_transform_bounds (transform, rect, out_rect);
|
||||
|
||||
out_rect->origin.x -= job->offset_x;
|
||||
out_rect->origin.y -= job->offset_y;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_transform_rounded_rect (GskGLRenderJob *job,
|
||||
const GskRoundedRect *rect,
|
||||
@@ -1220,6 +1203,7 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
key.pointer_is_child = FALSE;
|
||||
key.scale_x = scale_x;
|
||||
key.scale_y = scale_y;
|
||||
key.filter = GL_NEAREST;
|
||||
|
||||
cached_id = gsk_gl_driver_lookup_texture (job->driver, &key);
|
||||
|
||||
@@ -1289,7 +1273,8 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
|
||||
/* Create texture to upload */
|
||||
texture = gdk_texture_new_for_surface (surface);
|
||||
texture_id = gsk_gl_driver_load_texture (job->driver, texture, FALSE);
|
||||
texture_id = gsk_gl_driver_load_texture (job->driver, texture,
|
||||
GL_NEAREST, GL_NEAREST);
|
||||
|
||||
if (gdk_gl_context_has_debug (job->command_queue->context))
|
||||
gdk_gl_context_label_object_printf (job->command_queue->context, GL_TEXTURE, texture_id,
|
||||
@@ -1338,6 +1323,7 @@ blur_offscreen (GskGLRenderJob *job,
|
||||
MAX (texture_to_blur_width, 1),
|
||||
MAX (texture_to_blur_height, 1),
|
||||
job->target_format,
|
||||
GL_NEAREST, GL_NEAREST,
|
||||
&pass1))
|
||||
return 0;
|
||||
|
||||
@@ -1348,6 +1334,7 @@ blur_offscreen (GskGLRenderJob *job,
|
||||
texture_to_blur_width,
|
||||
texture_to_blur_height,
|
||||
job->target_format,
|
||||
GL_NEAREST, GL_NEAREST,
|
||||
&pass2))
|
||||
return gsk_gl_driver_release_render_target (job->driver, pass1, FALSE);
|
||||
|
||||
@@ -2100,14 +2087,13 @@ gsk_gl_render_job_visit_transform_node (GskGLRenderJob *job,
|
||||
{
|
||||
GskGLRenderOffscreen offscreen = {0};
|
||||
float sx = 1, sy = 1;
|
||||
gboolean linear_filter = FALSE;
|
||||
|
||||
offscreen.bounds = &child->bounds;
|
||||
offscreen.force_offscreen = FALSE;
|
||||
offscreen.reset_clip = TRUE;
|
||||
|
||||
if (!result_is_axis_aligned (transform, &child->bounds))
|
||||
linear_filter = TRUE;
|
||||
offscreen.linear_filter = TRUE;
|
||||
|
||||
if (category == GSK_TRANSFORM_CATEGORY_2D)
|
||||
{
|
||||
@@ -2137,19 +2123,16 @@ gsk_gl_render_job_visit_transform_node (GskGLRenderJob *job,
|
||||
if (gsk_gl_render_job_visit_node_with_offscreen (job, child, &offscreen))
|
||||
{
|
||||
/* For non-trivial transforms, we draw everything on a texture and then
|
||||
* draw the texture transformed.
|
||||
*/
|
||||
* draw the texture transformed. */
|
||||
if (transform)
|
||||
gsk_gl_render_job_push_modelview (job, transform);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
offscreen.texture_id,
|
||||
linear_filter ? GL_LINEAR : GL_NEAREST,
|
||||
linear_filter ? GL_LINEAR : GL_NEAREST);
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
offscreen.texture_id);
|
||||
gsk_gl_render_job_draw_offscreen (job, &child->bounds, &offscreen);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
|
||||
@@ -2227,6 +2210,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
|
||||
key.pointer_is_child = FALSE;
|
||||
key.scale_x = scale_x;
|
||||
key.scale_y = scale_y;
|
||||
key.filter = GL_NEAREST;
|
||||
|
||||
blurred_texture_id = gsk_gl_driver_lookup_texture (job->driver, &key);
|
||||
|
||||
@@ -2270,6 +2254,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
|
||||
if (!gsk_gl_driver_create_render_target (job->driver,
|
||||
texture_width, texture_height,
|
||||
get_target_format (job, node),
|
||||
GL_NEAREST, GL_NEAREST,
|
||||
&render_target))
|
||||
g_assert_not_reached ();
|
||||
|
||||
@@ -2542,6 +2527,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
|
||||
gsk_gl_driver_create_render_target (job->driver,
|
||||
texture_width, texture_height,
|
||||
get_target_format (job, node),
|
||||
GL_NEAREST, GL_NEAREST,
|
||||
&render_target);
|
||||
|
||||
if (gdk_gl_context_has_debug (context))
|
||||
@@ -3202,6 +3188,7 @@ gsk_gl_render_job_visit_blur_node (GskGLRenderJob *job,
|
||||
key.pointer_is_child = FALSE;
|
||||
key.scale_x = job->scale_x;
|
||||
key.scale_y = job->scale_y;
|
||||
key.filter = GL_NEAREST;
|
||||
|
||||
offscreen.texture_id = gsk_gl_driver_lookup_texture (job->driver, &key);
|
||||
cache_texture = offscreen.texture_id == 0;
|
||||
@@ -3510,10 +3497,12 @@ gsk_gl_render_job_visit_gl_shader_node (GskGLRenderJob *job,
|
||||
static void
|
||||
gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
|
||||
GdkTexture *texture,
|
||||
gboolean ensure_mipmap,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
GskGLRenderOffscreen *offscreen)
|
||||
{
|
||||
if (!ensure_mipmap &&
|
||||
if (min_filter == GL_LINEAR &&
|
||||
mag_filter == GL_LINEAR &&
|
||||
gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
|
||||
texture->width,
|
||||
texture->height) &&
|
||||
@@ -3527,7 +3516,7 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
|
||||
}
|
||||
else
|
||||
{
|
||||
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, ensure_mipmap);
|
||||
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, min_filter, mag_filter);
|
||||
init_full_texture_region (offscreen);
|
||||
}
|
||||
}
|
||||
@@ -3538,28 +3527,23 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
|
||||
const graphene_rect_t *bounds)
|
||||
{
|
||||
int max_texture_size = job->command_queue->max_texture_size;
|
||||
gboolean use_mipmaps;
|
||||
|
||||
use_mipmaps = job->scale_x < 0.5 || job->scale_y < 0.5;
|
||||
|
||||
if G_LIKELY (texture->width <= max_texture_size &&
|
||||
texture->height <= max_texture_size)
|
||||
{
|
||||
GskGLRenderOffscreen offscreen = {0};
|
||||
|
||||
gsk_gl_render_job_upload_texture (job, texture, use_mipmaps, &offscreen);
|
||||
gsk_gl_render_job_upload_texture (job, texture, GL_LINEAR, GL_LINEAR, &offscreen);
|
||||
|
||||
g_assert (offscreen.texture_id);
|
||||
g_assert (offscreen.was_offscreen == FALSE);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
offscreen.texture_id,
|
||||
use_mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
|
||||
GL_LINEAR);
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
offscreen.texture_id);
|
||||
gsk_gl_render_job_draw_offscreen (job, bounds, &offscreen);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
@@ -3574,7 +3558,7 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
|
||||
GskGLTextureSlice *slices = NULL;
|
||||
guint n_slices = 0;
|
||||
|
||||
gsk_gl_driver_slice_texture (job->driver, texture, use_mipmaps, 0, 0, &slices, &n_slices);
|
||||
gsk_gl_driver_slice_texture (job->driver, texture, GL_NEAREST, GL_NEAREST, 0, 0, &slices, &n_slices);
|
||||
|
||||
g_assert (slices != NULL);
|
||||
g_assert (n_slices > 0);
|
||||
@@ -3593,13 +3577,11 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
|
||||
|
||||
if (i > 0)
|
||||
gsk_gl_render_job_split_draw (job);
|
||||
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
slice->texture_id,
|
||||
use_mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
|
||||
GL_LINEAR);
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
slice->texture_id);
|
||||
|
||||
gsk_gl_render_job_draw_coords (job,
|
||||
x1, y1, x2, y2,
|
||||
@@ -3627,164 +3609,133 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
|
||||
{
|
||||
GdkTexture *texture = gsk_texture_scale_node_get_texture (node);
|
||||
const graphene_rect_t *bounds = &node->bounds;
|
||||
GskScalingFilter filter = gsk_texture_scale_node_get_filter (node);
|
||||
GskScalingFilter scaling_filter = gsk_texture_scale_node_get_filter (node);
|
||||
int min_filters[] = { GL_LINEAR, GL_NEAREST, GL_LINEAR_MIPMAP_LINEAR };
|
||||
int mag_filters[] = { GL_LINEAR, GL_NEAREST, GL_LINEAR };
|
||||
int min_filter = min_filters[filter];
|
||||
int mag_filter = mag_filters[filter];
|
||||
int min_filter = min_filters[scaling_filter];
|
||||
int mag_filter = mag_filters[scaling_filter];
|
||||
int max_texture_size = job->command_queue->max_texture_size;
|
||||
graphene_rect_t clip_rect;
|
||||
GskGLRenderTarget *render_target;
|
||||
graphene_rect_t viewport;
|
||||
graphene_rect_t prev_viewport;
|
||||
graphene_matrix_t prev_projection;
|
||||
float prev_alpha;
|
||||
guint prev_fbo;
|
||||
float u0, u1, v0, v1;
|
||||
GskTextureKey key;
|
||||
guint texture_id;
|
||||
|
||||
if (filter == GSK_SCALING_FILTER_LINEAR)
|
||||
if (scaling_filter == GSK_SCALING_FILTER_LINEAR)
|
||||
{
|
||||
gsk_gl_render_job_visit_texture (job, texture, bounds);
|
||||
return;
|
||||
}
|
||||
|
||||
gsk_gl_render_job_untransform_bounds (job, &job->current_clip->rect.bounds, &clip_rect);
|
||||
|
||||
if (!graphene_rect_intersection (bounds, &clip_rect, &clip_rect))
|
||||
return;
|
||||
|
||||
key.pointer = node;
|
||||
key.pointer_is_child = TRUE;
|
||||
key.parent_rect = clip_rect;
|
||||
key.scale_x = 1.;
|
||||
key.scale_y = 1.;
|
||||
|
||||
texture_id = gsk_gl_driver_lookup_texture (job->driver, &key);
|
||||
|
||||
if (texture_id != 0)
|
||||
goto render_texture;
|
||||
|
||||
viewport = GRAPHENE_RECT_INIT (0, 0,
|
||||
clip_rect.size.width,
|
||||
clip_rect.size.height);
|
||||
|
||||
if (!gsk_gl_driver_create_render_target (job->driver,
|
||||
(int) ceilf (clip_rect.size.width),
|
||||
(int) ceilf (clip_rect.size.height),
|
||||
get_target_format (job, node),
|
||||
&render_target))
|
||||
{
|
||||
gsk_gl_render_job_visit_texture (job, texture, bounds);
|
||||
return;
|
||||
}
|
||||
|
||||
gsk_gl_render_job_set_viewport (job, &viewport, &prev_viewport);
|
||||
gsk_gl_render_job_set_projection_from_rect (job, &viewport, &prev_projection);
|
||||
gsk_gl_render_job_set_modelview (job, NULL);
|
||||
prev_alpha = gsk_gl_render_job_set_alpha (job, 1.0f);
|
||||
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (viewport));
|
||||
|
||||
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
|
||||
gsk_gl_command_queue_clear (job->command_queue, 0, &viewport);
|
||||
|
||||
if G_LIKELY (texture->width <= max_texture_size &&
|
||||
texture->height <= max_texture_size)
|
||||
{
|
||||
texture_id = gsk_gl_driver_load_texture (job->driver, texture, filter == GSK_SCALING_FILTER_TRILINEAR);
|
||||
GskGLRenderTarget *render_target;
|
||||
GskGLRenderOffscreen offscreen = {0};
|
||||
graphene_rect_t viewport;
|
||||
graphene_rect_t prev_viewport;
|
||||
graphene_matrix_t prev_projection;
|
||||
float prev_alpha;
|
||||
guint prev_fbo;
|
||||
guint texture_id;
|
||||
|
||||
u0 = (clip_rect.origin.x - bounds->origin.x) / bounds->size.width;
|
||||
v0 = (clip_rect.origin.y - bounds->origin.y) / bounds->size.height;
|
||||
u1 = (clip_rect.origin.x + clip_rect.size.width - bounds->origin.x) / bounds->size.width;
|
||||
v1 = (clip_rect.origin.y + clip_rect.size.height - bounds->origin.y) / bounds->size.height;
|
||||
viewport = GRAPHENE_RECT_INIT (0, 0,
|
||||
bounds->size.width,
|
||||
bounds->size.height);
|
||||
|
||||
if (!gsk_gl_driver_create_render_target (job->driver,
|
||||
(int) ceilf (viewport.size.width),
|
||||
(int) ceilf (viewport.size.height),
|
||||
get_target_format (job, node),
|
||||
GL_LINEAR, GL_LINEAR,
|
||||
&render_target))
|
||||
{
|
||||
/* viewport is too big, slice the texture and try again */
|
||||
goto slice;
|
||||
}
|
||||
|
||||
gsk_gl_render_job_upload_texture (job, texture, min_filter, mag_filter, &offscreen);
|
||||
|
||||
g_assert (offscreen.texture_id);
|
||||
g_assert (offscreen.was_offscreen == FALSE);
|
||||
|
||||
gsk_gl_render_job_set_viewport (job, &viewport, &prev_viewport);
|
||||
gsk_gl_render_job_set_projection_from_rect (job, &viewport, &prev_projection);
|
||||
gsk_gl_render_job_set_modelview (job, NULL);
|
||||
prev_alpha = gsk_gl_render_job_set_alpha (job, 1.0f);
|
||||
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (viewport));
|
||||
|
||||
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
|
||||
gsk_gl_command_queue_clear (job->command_queue, 0, &viewport);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
texture_id,
|
||||
min_filter,
|
||||
mag_filter);
|
||||
gsk_gl_render_job_draw_coords (job,
|
||||
0, 0, clip_rect.size.width, clip_rect.size.height,
|
||||
u0, v0, u1, v1,
|
||||
(guint16[]) { FP16_ZERO, FP16_ZERO, FP16_ZERO, FP16_ZERO });
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
offscreen.texture_id);
|
||||
gsk_gl_render_job_draw_offscreen (job, &viewport, &offscreen);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
|
||||
gsk_gl_render_job_pop_clip (job);
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
gsk_gl_render_job_set_viewport (job, &prev_viewport, NULL);
|
||||
gsk_gl_render_job_set_projection (job, &prev_projection);
|
||||
gsk_gl_render_job_set_alpha (job, prev_alpha);
|
||||
gsk_gl_command_queue_bind_framebuffer (job->command_queue, prev_fbo);
|
||||
|
||||
texture_id = gsk_gl_driver_release_render_target (job->driver, render_target, FALSE);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
texture_id);
|
||||
gsk_gl_render_job_draw_offscreen_rect (job, bounds);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
else
|
||||
slice:
|
||||
{
|
||||
float scale_x = bounds->size.width / texture->width;
|
||||
float scale_y = bounds->size.height / texture->height;
|
||||
float min_x = bounds->origin.x;
|
||||
float min_y = bounds->origin.y;
|
||||
float max_x = min_x + bounds->size.width;
|
||||
float max_y = min_y + bounds->size.height;
|
||||
float scale_x = (max_x - min_x) / texture->width;
|
||||
float scale_y = (max_y - min_y) / texture->height;
|
||||
GskGLTextureSlice *slices = NULL;
|
||||
guint n_slices = 0;
|
||||
GdkGLContext *context = gsk_gl_driver_get_context (job->driver);
|
||||
guint rows, cols;
|
||||
|
||||
gsk_gl_driver_slice_texture (job->driver, texture, filter == GSK_SCALING_FILTER_TRILINEAR, 0, 0, &slices, &n_slices);
|
||||
/* Slice enough that neither the original texture nor the scaled texture
|
||||
* exceed the texture size limit
|
||||
*/
|
||||
cols = (int)(MAX (bounds->size.width, texture->width) / (max_texture_size / 4)) + 1;
|
||||
rows = (int)(MAX (bounds->size.height, texture->height) / (max_texture_size / 4)) + 1;
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_driver_slice_texture (job->driver, texture, GL_NEAREST, GL_NEAREST, cols, rows, &slices, &n_slices);
|
||||
|
||||
for (guint i = 0; i < n_slices; i++)
|
||||
g_assert (slices != NULL);
|
||||
g_assert (n_slices > 0);
|
||||
|
||||
for (guint i = 0; i < n_slices; i ++)
|
||||
{
|
||||
const GskGLTextureSlice *slice = &slices[i];
|
||||
graphene_rect_t slice_bounds;
|
||||
float x1, x2, y1, y2;
|
||||
GdkTexture *sub_texture;
|
||||
GskRenderNode *sub_node;
|
||||
|
||||
slice_bounds.origin.x = bounds->origin.x - clip_rect.origin.x + slice->rect.x * scale_x;
|
||||
slice_bounds.origin.y = bounds->origin.y - clip_rect.origin.y + slice->rect.y * scale_y;
|
||||
slice_bounds.size.width = slice->rect.width * scale_x;
|
||||
slice_bounds.size.height = slice->rect.height * scale_y;
|
||||
x1 = min_x + (scale_x * slice->rect.x);
|
||||
x2 = x1 + (slice->rect.width * scale_x);
|
||||
y1 = min_y + (scale_y * slice->rect.y);
|
||||
y2 = y1 + (slice->rect.height * scale_y);
|
||||
|
||||
if (!graphene_rect_intersection (&slice_bounds, &viewport, NULL))
|
||||
continue;
|
||||
sub_texture = gdk_gl_texture_new (context, slice->texture_id, slice->rect.width, slice->rect.height, NULL, NULL);
|
||||
|
||||
if (i > 0)
|
||||
gsk_gl_render_job_split_draw (job);
|
||||
sub_node = gsk_texture_scale_node_new (sub_texture, &GRAPHENE_RECT_INIT (x1, y1, x2 - x1, y2 - y1), scaling_filter);
|
||||
|
||||
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
slice->texture_id,
|
||||
min_filter,
|
||||
mag_filter);
|
||||
gsk_gl_render_job_draw_coords (job,
|
||||
slice_bounds.origin.x,
|
||||
slice_bounds.origin.y,
|
||||
slice_bounds.origin.x + slice_bounds.size.width,
|
||||
slice_bounds.origin.y + slice_bounds.size.height,
|
||||
0, 0, 1, 1,
|
||||
(guint16[]){ FP16_ZERO, FP16_ZERO, FP16_ZERO, FP16_ZERO } );
|
||||
gsk_gl_render_job_visit_node (job, sub_node);
|
||||
gsk_render_node_unref (sub_node);
|
||||
g_object_unref (sub_texture);
|
||||
}
|
||||
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
|
||||
gsk_gl_render_job_pop_clip (job);
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
gsk_gl_render_job_set_viewport (job, &prev_viewport, NULL);
|
||||
gsk_gl_render_job_set_projection (job, &prev_projection);
|
||||
gsk_gl_render_job_set_alpha (job, prev_alpha);
|
||||
gsk_gl_command_queue_bind_framebuffer (job->command_queue, prev_fbo);
|
||||
|
||||
texture_id = gsk_gl_driver_release_render_target (job->driver, render_target, FALSE);
|
||||
gsk_gl_driver_cache_texture (job->driver, &key, texture_id);
|
||||
|
||||
render_texture:
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
texture_id);
|
||||
gsk_gl_render_job_draw_coords (job,
|
||||
job->offset_x + clip_rect.origin.x,
|
||||
job->offset_y + clip_rect.origin.y,
|
||||
job->offset_x + clip_rect.origin.x + clip_rect.size.width,
|
||||
job->offset_y + clip_rect.origin.y + clip_rect.size.height,
|
||||
0, clip_rect.size.width / ceilf (clip_rect.size.width),
|
||||
clip_rect.size.height / ceilf (clip_rect.size.height), 0,
|
||||
(guint16[]){ FP16_ZERO, FP16_ZERO, FP16_ZERO, FP16_ZERO } );
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -4047,6 +3998,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
{
|
||||
GskTextureKey key;
|
||||
guint cached_id;
|
||||
int filter;
|
||||
|
||||
g_assert (job != NULL);
|
||||
g_assert (node != NULL);
|
||||
@@ -4067,15 +4019,19 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
offscreen->force_offscreen == FALSE)
|
||||
{
|
||||
GdkTexture *texture = gsk_texture_node_get_texture (node);
|
||||
gsk_gl_render_job_upload_texture (job, texture, FALSE, offscreen);
|
||||
gsk_gl_render_job_upload_texture (job, texture, GL_LINEAR, GL_LINEAR, offscreen);
|
||||
g_assert (offscreen->was_offscreen == FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
filter = offscreen->linear_filter ? GL_LINEAR : GL_NEAREST;
|
||||
|
||||
key.pointer = node;
|
||||
key.pointer_is_child = TRUE; /* Don't conflict with the child using the cache too */
|
||||
key.parent_rect = *offscreen->bounds;
|
||||
key.scale_x = job->scale_x;
|
||||
key.scale_y = job->scale_y;
|
||||
key.filter = filter;
|
||||
|
||||
float offset_x = job->offset_x;
|
||||
float offset_y = job->offset_y;
|
||||
@@ -4183,6 +4139,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
if (!gsk_gl_driver_create_render_target (job->driver,
|
||||
texture_width, texture_height,
|
||||
get_target_format (job, node),
|
||||
filter, filter,
|
||||
&render_target))
|
||||
g_assert_not_reached ();
|
||||
|
||||
@@ -4270,6 +4227,7 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
|
||||
MAX (1, job->viewport.size.width),
|
||||
MAX (1, job->viewport.size.height),
|
||||
job->target_format,
|
||||
GL_NEAREST, GL_NEAREST,
|
||||
&framebuffer_id, &texture_id))
|
||||
return;
|
||||
|
||||
@@ -4412,7 +4370,7 @@ gsk_gl_render_job_new (GskGLDriver *driver,
|
||||
if (framebuffer == 0 && default_framebuffer != 0)
|
||||
framebuffer = default_framebuffer;
|
||||
|
||||
job = g_new0 (GskGLRenderJob, 1);
|
||||
job = g_slice_new0 (GskGLRenderJob);
|
||||
job->driver = g_object_ref (driver);
|
||||
job->command_queue = job->driver->command_queue;
|
||||
job->clip = g_array_sized_new (FALSE, FALSE, sizeof (GskGLRenderClip), 16);
|
||||
@@ -4477,5 +4435,5 @@ gsk_gl_render_job_free (GskGLRenderJob *job)
|
||||
g_clear_pointer (&job->region, cairo_region_destroy);
|
||||
g_clear_pointer (&job->modelview, g_array_unref);
|
||||
g_clear_pointer (&job->clip, g_array_unref);
|
||||
g_free (job);
|
||||
g_slice_free (GskGLRenderJob, job);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ gsk_gl_texture_free (GskGLTexture *texture)
|
||||
g_clear_pointer (&texture->slices, g_free);
|
||||
g_clear_pointer (&texture->nine_slice, g_free);
|
||||
|
||||
g_free (texture);
|
||||
g_slice_free (GskGLTexture, texture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,13 +59,19 @@ GskGLTexture *
|
||||
gsk_gl_texture_new (guint texture_id,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
gint64 frame_id)
|
||||
{
|
||||
GskGLTexture *texture;
|
||||
|
||||
texture = g_new0 (GskGLTexture, 1);
|
||||
texture = g_slice_new0 (GskGLTexture);
|
||||
texture->texture_id = texture_id;
|
||||
texture->link.data = texture;
|
||||
texture->min_filter = min_filter;
|
||||
texture->mag_filter = mag_filter;
|
||||
texture->format = format;
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
texture->last_used_in_frame = frame_id;
|
||||
|
||||
@@ -52,7 +52,7 @@ gsk_gl_texture_atlas_free (GskGLTextureAtlas *atlas)
|
||||
}
|
||||
|
||||
g_clear_pointer (&atlas->nodes, g_free);
|
||||
g_free (atlas);
|
||||
g_slice_free (GskGLTextureAtlas, atlas);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -320,7 +320,7 @@ gsk_gl_texture_library_pack_one (GskGLTextureLibrary *self,
|
||||
height = MIN (height, self->driver->command_queue->max_texture_size);
|
||||
}
|
||||
|
||||
texture = gsk_gl_driver_create_texture (self->driver, width, height, GL_RGBA8);
|
||||
texture = gsk_gl_driver_create_texture (self->driver, width, height, GL_RGBA8, GL_LINEAR, GL_LINEAR);
|
||||
texture->permanent = TRUE;
|
||||
|
||||
return texture;
|
||||
@@ -388,7 +388,7 @@ gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
|
||||
g_assert (out_packed_x != NULL);
|
||||
g_assert (out_packed_y != NULL);
|
||||
|
||||
entry = g_malloc0 (valuelen);
|
||||
entry = g_slice_alloc0 (valuelen);
|
||||
entry->n_pixels = width * height;
|
||||
entry->accessed = TRUE;
|
||||
entry->used = TRUE;
|
||||
@@ -542,7 +542,7 @@ gsk_gl_texture_library_acquire_atlas (GskGLTextureLibrary *self)
|
||||
g_return_val_if_fail (self->atlas_width > 0, NULL);
|
||||
g_return_val_if_fail (self->atlas_height > 0, NULL);
|
||||
|
||||
atlas = g_new0 (GskGLTextureAtlas, 1);
|
||||
atlas = g_slice_new0 (GskGLTextureAtlas);
|
||||
atlas->width = self->atlas_width;
|
||||
atlas->height = self->atlas_height;
|
||||
/* TODO: We might want to change the strategy about the amount of
|
||||
@@ -552,7 +552,9 @@ gsk_gl_texture_library_acquire_atlas (GskGLTextureLibrary *self)
|
||||
atlas->texture_id = gsk_gl_command_queue_create_texture (self->driver->command_queue,
|
||||
atlas->width,
|
||||
atlas->height,
|
||||
GL_RGBA8);
|
||||
GL_RGBA8,
|
||||
GL_LINEAR,
|
||||
GL_LINEAR);
|
||||
|
||||
gdk_gl_context_label_object_printf (gdk_gl_context_get_current (),
|
||||
GL_TEXTURE, atlas->texture_id,
|
||||
|
||||
@@ -65,16 +65,20 @@ struct _GskGLTexture
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int min_filter;
|
||||
int mag_filter;
|
||||
int format;
|
||||
|
||||
/* Set when used by an atlas so we don't drop the texture */
|
||||
guint permanent : 1;
|
||||
/* we called glGenerateMipmap() for this texture */
|
||||
guint has_mipmap : 1;
|
||||
};
|
||||
|
||||
GskGLTexture * gsk_gl_texture_new (guint texture_id,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
gint64 frame_id);
|
||||
const GskGLTextureNineSlice * gsk_gl_texture_get_nine_slice (GskGLTexture *texture,
|
||||
const GskRoundedRect *outline,
|
||||
|
||||
+2
-2
@@ -53,7 +53,7 @@ gsk_diff_settings_new (GCompareDataFunc compare_func,
|
||||
{
|
||||
GskDiffSettings *settings;
|
||||
|
||||
settings = g_new0 (GskDiffSettings, 1);
|
||||
settings = g_slice_new0 (GskDiffSettings);
|
||||
|
||||
settings->compare_func = compare_func;
|
||||
settings->keep_func = keep_func;
|
||||
@@ -73,7 +73,7 @@ gsk_diff_settings_set_allow_abort (GskDiffSettings *settings,
|
||||
void
|
||||
gsk_diff_settings_free (GskDiffSettings *settings)
|
||||
{
|
||||
g_free (settings);
|
||||
g_slice_free (GskDiffSettings, settings);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+6
-4
@@ -53,7 +53,8 @@ named_counter_free (gpointer data)
|
||||
return;
|
||||
|
||||
g_free (counter->description);
|
||||
g_free (counter);
|
||||
|
||||
g_slice_free (NamedCounter, counter);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -65,7 +66,8 @@ named_timer_free (gpointer data)
|
||||
return;
|
||||
|
||||
g_free (timer->description);
|
||||
g_free (timer);
|
||||
|
||||
g_slice_free (NamedTimer, timer);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -107,7 +109,7 @@ named_counter_new (GQuark id,
|
||||
const char *description,
|
||||
gboolean can_reset)
|
||||
{
|
||||
NamedCounter *res = g_new0 (NamedCounter, 1);
|
||||
NamedCounter *res = g_slice_new0 (NamedCounter);
|
||||
|
||||
res->id = id;
|
||||
res->description = g_strdup (description);
|
||||
@@ -154,7 +156,7 @@ named_timer_new (GQuark id,
|
||||
gboolean invert,
|
||||
gboolean can_reset)
|
||||
{
|
||||
NamedTimer *res = g_new0 (NamedTimer, 1);
|
||||
NamedTimer *res = g_slice_new0 (NamedTimer);
|
||||
|
||||
res->id = id;
|
||||
res->description = g_strdup (description);
|
||||
|
||||
+28
-160
@@ -21,10 +21,8 @@
|
||||
#include "gskrendernodeprivate.h"
|
||||
|
||||
#include "gskcairoblurprivate.h"
|
||||
#include "gskcairorenderer.h"
|
||||
#include "gskdebugprivate.h"
|
||||
#include "gskdiffprivate.h"
|
||||
#include "gl/gskglrenderer.h"
|
||||
#include "gskrendererprivate.h"
|
||||
#include "gskroundedrectprivate.h"
|
||||
#include "gsktransformprivate.h"
|
||||
@@ -33,10 +31,6 @@
|
||||
#include "gdk/gdkmemoryformatprivate.h"
|
||||
#include "gdk/gdkprivate.h"
|
||||
|
||||
#include <cairo.h>
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
#include <cairo-svg.h>
|
||||
#endif
|
||||
#include <hb-ot.h>
|
||||
|
||||
/* maximal number of rectangles we keep in a diff region before we throw
|
||||
@@ -64,16 +58,6 @@ rectangle_init_from_graphene (cairo_rectangle_int_t *cairo,
|
||||
cairo->height = ceilf (graphene->origin.y + graphene->size.height) - cairo->y;
|
||||
}
|
||||
|
||||
static void
|
||||
_graphene_rect_init_from_clip_extents (graphene_rect_t *rect,
|
||||
cairo_t *cr)
|
||||
{
|
||||
double x1c, y1c, x2c, y2c;
|
||||
|
||||
cairo_clip_extents (cr, &x1c, &y1c, &x2c, &y2c);
|
||||
graphene_rect_init (rect, x1c, y1c, x2c - x1c, y2c - y1c);
|
||||
}
|
||||
|
||||
/* {{{ GSK_COLOR_NODE */
|
||||
|
||||
/**
|
||||
@@ -1573,10 +1557,6 @@ gsk_texture_node_get_texture (const GskRenderNode *node)
|
||||
* Creates a `GskRenderNode` that will render the given
|
||||
* @texture into the area given by @bounds.
|
||||
*
|
||||
* Note that GSK applies linear filtering when textures are
|
||||
* scaled and transformed. See [class@Gsk.TextureScaleNode]
|
||||
* for a way to influence filtering.
|
||||
*
|
||||
* Returns: (transfer full) (type GskTextureNode): A new `GskRenderNode`
|
||||
*/
|
||||
GskRenderNode *
|
||||
@@ -1645,21 +1625,15 @@ gsk_texture_scale_node_draw (GskRenderNode *node,
|
||||
};
|
||||
cairo_t *cr2;
|
||||
cairo_surface_t *surface2;
|
||||
graphene_rect_t clip_rect;
|
||||
|
||||
/* Make sure we draw the minimum region by using the clip */
|
||||
gsk_cairo_rectangle (cr, &node->bounds);
|
||||
cairo_clip (cr);
|
||||
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
|
||||
if (clip_rect.size.width <= 0 || clip_rect.size.height <= 0)
|
||||
return;
|
||||
|
||||
surface2 = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
(int) ceilf (clip_rect.size.width),
|
||||
(int) ceilf (clip_rect.size.height));
|
||||
cairo_surface_set_device_offset (surface2, -clip_rect.origin.x, -clip_rect.origin.y);
|
||||
(int) ceilf (node->bounds.size.width),
|
||||
(int) ceilf (node->bounds.size.height));
|
||||
cr2 = cairo_create (surface2);
|
||||
|
||||
cairo_set_source_rgba (cr2, 0, 0, 0, 0);
|
||||
cairo_paint (cr2);
|
||||
|
||||
surface = gdk_texture_download_surface (self->texture);
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
|
||||
@@ -1758,11 +1732,7 @@ gsk_texture_scale_node_get_filter (const GskRenderNode *node)
|
||||
* @filter: how to scale the texture
|
||||
*
|
||||
* Creates a node that scales the texture to the size given by the
|
||||
* bounds using the filter and then places it at the bounds' position.
|
||||
*
|
||||
* Note that further scaling and other transformations which are
|
||||
* applied to the node will apply linear filtering to the resulting
|
||||
* texture, as usual.
|
||||
* bounds and the filter and then places it at the bounds' position.
|
||||
*
|
||||
* This node is intended for tight control over scaling applied
|
||||
* to a texture, such as in image editors and requires the
|
||||
@@ -2102,15 +2072,15 @@ gsk_inset_shadow_node_draw (GskRenderNode *node,
|
||||
GskInsetShadowNode *self = (GskInsetShadowNode *) node;
|
||||
GskRoundedRect box, clip_box;
|
||||
int clip_radius;
|
||||
graphene_rect_t clip_rect;
|
||||
double x1c, y1c, x2c, y2c;
|
||||
double blur_radius;
|
||||
|
||||
/* We don't need to draw invisible shadows */
|
||||
if (gdk_rgba_is_clear (&self->color))
|
||||
return;
|
||||
|
||||
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
|
||||
if (!gsk_rounded_rect_intersects_rect (&self->outline, &clip_rect))
|
||||
cairo_clip_extents (cr, &x1c, &y1c, &x2c, &y2c);
|
||||
if (!gsk_rounded_rect_intersects_rect (&self->outline, &GRAPHENE_RECT_INIT (x1c, y1c, x2c - x1c, y2c - y1c)))
|
||||
return;
|
||||
|
||||
blur_radius = self->blur_radius / 2;
|
||||
@@ -2398,7 +2368,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
|
||||
GskOutsetShadowNode *self = (GskOutsetShadowNode *) node;
|
||||
GskRoundedRect box, clip_box;
|
||||
int clip_radius;
|
||||
graphene_rect_t clip_rect;
|
||||
double x1c, y1c, x2c, y2c;
|
||||
float top, right, bottom, left;
|
||||
double blur_radius;
|
||||
|
||||
@@ -2406,8 +2376,8 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
|
||||
if (gdk_rgba_is_clear (&self->color))
|
||||
return;
|
||||
|
||||
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
|
||||
if (!gsk_rounded_rect_intersects_rect (&self->outline, &clip_rect))
|
||||
cairo_clip_extents (cr, &x1c, &y1c, &x2c, &y2c);
|
||||
if (gsk_rounded_rect_contains_rect (&self->outline, &GRAPHENE_RECT_INIT (x1c, y1c, x2c - x1c, y2c - y1c)))
|
||||
return;
|
||||
|
||||
blur_radius = self->blur_radius / 2;
|
||||
@@ -6241,9 +6211,9 @@ gsk_render_node_init_types_once (void)
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_render_node_serialize_bytes_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer serializer)
|
||||
gsk_render_node_content_serializer_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer serializer)
|
||||
{
|
||||
GOutputStream *stream = G_OUTPUT_STREAM (source);
|
||||
GError *error = NULL;
|
||||
@@ -6254,109 +6224,10 @@ gsk_render_node_serialize_bytes_finish (GObject *source,
|
||||
gdk_content_serializer_return_success (serializer);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_render_node_serialize_bytes (GdkContentSerializer *serializer,
|
||||
GBytes *bytes)
|
||||
{
|
||||
GInputStream *input;
|
||||
|
||||
input = g_memory_input_stream_new_from_bytes (bytes);
|
||||
|
||||
g_output_stream_splice_async (gdk_content_serializer_get_output_stream (serializer),
|
||||
input,
|
||||
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
|
||||
gdk_content_serializer_get_priority (serializer),
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
gsk_render_node_serialize_bytes_finish,
|
||||
serializer);
|
||||
g_object_unref (input);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
static cairo_status_t
|
||||
gsk_render_node_cairo_serializer_write (gpointer user_data,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
g_byte_array_append (user_data, data, length);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_render_node_svg_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
graphene_rect_t bounds;
|
||||
GByteArray *array;
|
||||
|
||||
node = gsk_value_get_render_node (gdk_content_serializer_get_value (serializer));
|
||||
gsk_render_node_get_bounds (node, &bounds);
|
||||
array = g_byte_array_new ();
|
||||
|
||||
surface = cairo_svg_surface_create_for_stream (gsk_render_node_cairo_serializer_write,
|
||||
array,
|
||||
bounds.size.width,
|
||||
bounds.size.height);
|
||||
cairo_svg_surface_set_document_unit (surface, CAIRO_SVG_UNIT_PX);
|
||||
cairo_surface_set_device_offset (surface, -bounds.origin.x, -bounds.origin.y);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
gsk_render_node_draw (node, cr);
|
||||
cairo_destroy (cr);
|
||||
|
||||
cairo_surface_finish (surface);
|
||||
if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
gsk_render_node_serialize_bytes (serializer, g_byte_array_free_to_bytes (array));
|
||||
}
|
||||
else
|
||||
{
|
||||
GError *error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
cairo_status_to_string (cairo_surface_status (surface)));
|
||||
gdk_content_serializer_return_error (serializer, error);
|
||||
g_byte_array_unref (array);
|
||||
}
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gsk_render_node_png_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
GdkTexture *texture;
|
||||
GskRenderer *renderer;
|
||||
GBytes *bytes;
|
||||
|
||||
node = gsk_value_get_render_node (gdk_content_serializer_get_value (serializer));
|
||||
|
||||
renderer = gsk_gl_renderer_new ();
|
||||
if (!gsk_renderer_realize (renderer, NULL, NULL))
|
||||
{
|
||||
g_object_unref (renderer);
|
||||
renderer = gsk_cairo_renderer_new ();
|
||||
if (!gsk_renderer_realize (renderer, NULL, NULL))
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
texture = gsk_renderer_render_texture (renderer, node, NULL);
|
||||
gsk_renderer_unrealize (renderer);
|
||||
g_object_unref (renderer);
|
||||
|
||||
bytes = gdk_texture_save_to_png_bytes (texture);
|
||||
g_object_unref (texture);
|
||||
|
||||
gsk_render_node_serialize_bytes (serializer, bytes);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_render_node_content_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
GInputStream *input;
|
||||
const GValue *value;
|
||||
GskRenderNode *node;
|
||||
GBytes *bytes;
|
||||
@@ -6364,14 +6235,23 @@ gsk_render_node_content_serializer (GdkContentSerializer *serializer)
|
||||
value = gdk_content_serializer_get_value (serializer);
|
||||
node = gsk_value_get_render_node (value);
|
||||
bytes = gsk_render_node_serialize (node);
|
||||
input = g_memory_input_stream_new_from_bytes (bytes);
|
||||
|
||||
gsk_render_node_serialize_bytes (serializer, bytes);
|
||||
g_output_stream_splice_async (gdk_content_serializer_get_output_stream (serializer),
|
||||
input,
|
||||
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
|
||||
gdk_content_serializer_get_priority (serializer),
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
gsk_render_node_content_serializer_finish,
|
||||
serializer);
|
||||
g_object_unref (input);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_render_node_content_deserializer_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer deserializer)
|
||||
GAsyncResult *result,
|
||||
gpointer deserializer)
|
||||
{
|
||||
GOutputStream *stream = G_OUTPUT_STREAM (source);
|
||||
GError *error = NULL;
|
||||
@@ -6435,18 +6315,6 @@ gsk_render_node_init_content_serializers (void)
|
||||
gsk_render_node_content_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
gdk_content_register_serializer (GSK_TYPE_RENDER_NODE,
|
||||
"image/svg+xml",
|
||||
gsk_render_node_svg_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
#endif
|
||||
gdk_content_register_serializer (GSK_TYPE_RENDER_NODE,
|
||||
"image/png",
|
||||
gsk_render_node_png_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
gdk_content_register_deserializer ("application/x-gtk-render-node",
|
||||
GSK_TYPE_RENDER_NODE,
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ gskenum_h = gsk_enums[1]
|
||||
gskresources = gnome.compile_resources('gskresources',
|
||||
gsk_resources_xml,
|
||||
dependencies: gsk_private_vulkan_compiled_shaders_deps,
|
||||
source_dir: meson.current_source_dir(),
|
||||
source_dir: '.',
|
||||
c_name: '_gsk',
|
||||
extra_args: [ '--manual-register', ],
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ gsk_vulkan_buffer_new_internal (GdkVulkanContext *context,
|
||||
VkMemoryRequirements requirements;
|
||||
GskVulkanBuffer *self;
|
||||
|
||||
self = g_new0 (GskVulkanBuffer, 1);
|
||||
self = g_slice_new0 (GskVulkanBuffer);
|
||||
|
||||
self->vulkan = g_object_ref (context);
|
||||
self->size = size;
|
||||
@@ -88,7 +88,7 @@ gsk_vulkan_buffer_free (GskVulkanBuffer *self)
|
||||
|
||||
g_object_unref (self->vulkan);
|
||||
|
||||
g_free (self);
|
||||
g_slice_free (GskVulkanBuffer, self);
|
||||
}
|
||||
|
||||
VkBuffer
|
||||
|
||||
@@ -16,7 +16,7 @@ gsk_vulkan_command_pool_new (GdkVulkanContext *context)
|
||||
{
|
||||
GskVulkanCommandPool *self;
|
||||
|
||||
self = g_new0 (GskVulkanCommandPool, 1);
|
||||
self = g_slice_new0 (GskVulkanCommandPool);
|
||||
|
||||
self->vulkan = g_object_ref (context);
|
||||
|
||||
@@ -56,7 +56,7 @@ gsk_vulkan_command_pool_free (GskVulkanCommandPool *self)
|
||||
self->vk_command_pool,
|
||||
NULL);
|
||||
|
||||
g_free (self);
|
||||
g_slice_free (GskVulkanCommandPool, self);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -49,7 +49,7 @@ gsk_vulkan_uploader_new (GdkVulkanContext *context,
|
||||
{
|
||||
GskVulkanUploader *self;
|
||||
|
||||
self = g_new0 (GskVulkanUploader, 1);
|
||||
self = g_slice_new0 (GskVulkanUploader);
|
||||
|
||||
self->vulkan = g_object_ref (context);
|
||||
self->command_pool = command_pool;
|
||||
@@ -75,7 +75,7 @@ gsk_vulkan_uploader_free (GskVulkanUploader *self)
|
||||
|
||||
g_object_unref (self->vulkan);
|
||||
|
||||
g_free (self);
|
||||
g_slice_free (GskVulkanUploader, self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -22,7 +22,7 @@ gsk_vulkan_memory_new (GdkVulkanContext *context,
|
||||
GskVulkanMemory *self;
|
||||
uint32_t i;
|
||||
|
||||
self = g_new0 (GskVulkanMemory, 1);
|
||||
self = g_slice_new0 (GskVulkanMemory);
|
||||
|
||||
self->vulkan = g_object_ref (context);
|
||||
self->size = size;
|
||||
@@ -62,7 +62,7 @@ gsk_vulkan_memory_free (GskVulkanMemory *self)
|
||||
|
||||
g_object_unref (self->vulkan);
|
||||
|
||||
g_free (self);
|
||||
g_slice_free (GskVulkanMemory, self);
|
||||
}
|
||||
|
||||
VkDeviceMemory
|
||||
|
||||
@@ -113,7 +113,7 @@ gsk_vulkan_render_new (GskRenderer *renderer,
|
||||
GskVulkanRender *self;
|
||||
VkDevice device;
|
||||
|
||||
self = g_new0 (GskVulkanRender, 1);
|
||||
self = g_slice_new0 (GskVulkanRender);
|
||||
|
||||
self->vulkan = context;
|
||||
self->renderer = renderer;
|
||||
@@ -281,7 +281,7 @@ gsk_vulkan_render_remove_framebuffer_from_image (gpointer data,
|
||||
fb->framebuffer,
|
||||
NULL);
|
||||
|
||||
g_free (fb);
|
||||
g_slice_free (HashFramebufferEntry, fb);
|
||||
}
|
||||
|
||||
VkFramebuffer
|
||||
@@ -294,7 +294,7 @@ gsk_vulkan_render_get_framebuffer (GskVulkanRender *self,
|
||||
if (fb)
|
||||
return fb->framebuffer;
|
||||
|
||||
fb = g_new0 (HashFramebufferEntry, 1);
|
||||
fb = g_slice_new0 (HashFramebufferEntry);
|
||||
GSK_VK_CHECK (vkCreateFramebuffer, gdk_vulkan_context_get_device (self->vulkan),
|
||||
&(VkFramebufferCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
@@ -705,7 +705,7 @@ gsk_vulkan_render_free (GskVulkanRender *self)
|
||||
vkDestroyFramebuffer (gdk_vulkan_context_get_device (self->vulkan),
|
||||
fb->framebuffer,
|
||||
NULL);
|
||||
g_free (fb);
|
||||
g_slice_free (HashFramebufferEntry, fb);
|
||||
g_object_weak_unref (G_OBJECT (key), gsk_vulkan_render_remove_framebuffer_from_image, self);
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
@@ -749,7 +749,7 @@ gsk_vulkan_render_free (GskVulkanRender *self)
|
||||
|
||||
gsk_vulkan_command_pool_free (self->command_pool);
|
||||
|
||||
g_free (self);
|
||||
g_slice_free (GskVulkanRender, self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
@@ -326,7 +326,7 @@ gsk_vulkan_renderer_clear_texture (gpointer p)
|
||||
|
||||
g_object_unref (data->image);
|
||||
|
||||
g_free (data);
|
||||
g_slice_free (GskVulkanTextureData, data);
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
@@ -350,7 +350,7 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
|
||||
cairo_image_surface_get_stride (surface));
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
data = g_new0 (GskVulkanTextureData, 1);
|
||||
data = g_slice_new0 (GskVulkanTextureData);
|
||||
data->image = image;
|
||||
data->texture = texture;
|
||||
data->renderer = self;
|
||||
@@ -362,7 +362,7 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (data);
|
||||
g_slice_free (GskVulkanTextureData, data);
|
||||
}
|
||||
|
||||
return image;
|
||||
|
||||
@@ -140,7 +140,7 @@ gsk_vulkan_render_pass_new (GdkVulkanContext *context,
|
||||
GskVulkanRenderPass *self;
|
||||
VkImageLayout final_layout;
|
||||
|
||||
self = g_new0 (GskVulkanRenderPass, 1);
|
||||
self = g_slice_new0 (GskVulkanRenderPass);
|
||||
self->vulkan = g_object_ref (context);
|
||||
self->render_ops = g_array_new (FALSE, FALSE, sizeof (GskVulkanOp));
|
||||
|
||||
@@ -231,7 +231,7 @@ gsk_vulkan_render_pass_free (GskVulkanRenderPass *self)
|
||||
g_array_unref (self->wait_semaphores);
|
||||
|
||||
|
||||
g_free (self);
|
||||
g_slice_free (GskVulkanRenderPass, self);
|
||||
}
|
||||
|
||||
#define FALLBACK(...) G_STMT_START { \
|
||||
|
||||
@@ -37,7 +37,7 @@ gsk_vulkan_shader_new_from_bytes (GdkVulkanContext *context,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self = g_new0 (GskVulkanShader, 1);
|
||||
self = g_slice_new0 (GskVulkanShader);
|
||||
|
||||
self->vulkan = g_object_ref (context);
|
||||
self->type = type;
|
||||
@@ -85,7 +85,7 @@ gsk_vulkan_shader_free (GskVulkanShader *self)
|
||||
|
||||
g_object_unref (self->vulkan);
|
||||
|
||||
g_free (self);
|
||||
g_slice_free (GskVulkanShader, self);
|
||||
}
|
||||
|
||||
GskVulkanShaderType
|
||||
|
||||
@@ -158,12 +158,9 @@ component_handle_method (GDBusConnection *connection,
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
|
||||
GtkAtSpiContext *ctx = GTK_AT_SPI_CONTEXT (context);
|
||||
GtkAtSpiContext *ctx = GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (child)));
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (ctx)));
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetExtents") == 0)
|
||||
|
||||
+33
-131
@@ -203,7 +203,6 @@ collect_states (GtkAtSpiContext *self,
|
||||
|
||||
if (gtk_at_context_has_accessible_state (ctx, GTK_ACCESSIBLE_STATE_CHECKED))
|
||||
{
|
||||
set_atspi_state (&states, ATSPI_STATE_CHECKABLE);
|
||||
value = gtk_at_context_get_accessible_state (ctx, GTK_ACCESSIBLE_STATE_CHECKED);
|
||||
switch (gtk_tristate_accessible_value_get (value))
|
||||
{
|
||||
@@ -247,7 +246,7 @@ collect_states (GtkAtSpiContext *self,
|
||||
case GTK_ACCESSIBLE_INVALID_TRUE:
|
||||
case GTK_ACCESSIBLE_INVALID_GRAMMAR:
|
||||
case GTK_ACCESSIBLE_INVALID_SPELLING:
|
||||
set_atspi_state (&states, ATSPI_STATE_INVALID_ENTRY);
|
||||
set_atspi_state (&states, ATSPI_STATE_INVALID);
|
||||
break;
|
||||
case GTK_ACCESSIBLE_INVALID_FALSE:
|
||||
default:
|
||||
@@ -283,44 +282,6 @@ collect_states (GtkAtSpiContext *self,
|
||||
}
|
||||
}
|
||||
|
||||
if (gtk_at_context_has_accessible_state (ctx, GTK_ACCESSIBLE_STATE_VISITED))
|
||||
{
|
||||
value = gtk_at_context_get_accessible_state (ctx, GTK_ACCESSIBLE_STATE_VISITED);
|
||||
if (value->value_class->type == GTK_ACCESSIBLE_VALUE_TYPE_BOOLEAN)
|
||||
{
|
||||
if (gtk_boolean_accessible_value_get (value))
|
||||
set_atspi_state (&states, ATSPI_STATE_VISITED);
|
||||
}
|
||||
}
|
||||
|
||||
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_REQUIRED))
|
||||
{
|
||||
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_REQUIRED);
|
||||
if (gtk_boolean_accessible_value_get (value))
|
||||
set_atspi_state (&states, ATSPI_STATE_REQUIRED);
|
||||
}
|
||||
|
||||
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE))
|
||||
{
|
||||
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE);
|
||||
if (gtk_boolean_accessible_value_get (value))
|
||||
set_atspi_state (&states, ATSPI_STATE_MULTISELECTABLE);
|
||||
}
|
||||
|
||||
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_HAS_POPUP))
|
||||
{
|
||||
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_HAS_POPUP);
|
||||
if (gtk_boolean_accessible_value_get (value))
|
||||
set_atspi_state (&states, ATSPI_STATE_HAS_POPUP);
|
||||
}
|
||||
|
||||
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE))
|
||||
{
|
||||
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE);
|
||||
if (gtk_autocomplete_accessible_value_get (value) != GTK_ACCESSIBLE_AUTOCOMPLETE_NONE)
|
||||
set_atspi_state (&states, ATSPI_STATE_SUPPORTS_AUTOCOMPLETION);
|
||||
}
|
||||
|
||||
g_variant_builder_add (builder, "u", (guint32) (states & 0xffffffff));
|
||||
g_variant_builder_add (builder, "u", (guint32) (states >> 32));
|
||||
}
|
||||
@@ -338,12 +299,11 @@ collect_relations (GtkAtSpiContext *self,
|
||||
{ GTK_ACCESSIBLE_RELATION_LABELLED_BY, ATSPI_RELATION_LABELLED_BY },
|
||||
{ GTK_ACCESSIBLE_RELATION_CONTROLS, ATSPI_RELATION_CONTROLLER_FOR },
|
||||
{ GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, ATSPI_RELATION_DESCRIBED_BY },
|
||||
{ GTK_ACCESSIBLE_RELATION_DETAILS, ATSPI_RELATION_DETAILS },
|
||||
{ GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE, ATSPI_RELATION_ERROR_MESSAGE},
|
||||
{ GTK_ACCESSIBLE_RELATION_FLOW_TO, ATSPI_RELATION_FLOWS_TO},
|
||||
};
|
||||
GtkAccessibleValue *value;
|
||||
GList *list, *l;
|
||||
GtkATContext *target_ctx;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (map); i++)
|
||||
@@ -358,16 +318,13 @@ collect_relations (GtkAtSpiContext *self,
|
||||
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
GtkATContext *target_ctx =
|
||||
gtk_accessible_get_at_context (GTK_ACCESSIBLE (l->data));
|
||||
target_ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (l->data));
|
||||
|
||||
/* Realize the ATContext of the target, so we can ask for its ref */
|
||||
gtk_at_context_realize (target_ctx);
|
||||
|
||||
g_variant_builder_add (&b, "@(so)",
|
||||
gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (target_ctx)));
|
||||
|
||||
g_object_unref (target_ctx);
|
||||
}
|
||||
|
||||
g_variant_builder_add (builder, "(ua(so))", map[i].s, &b);
|
||||
@@ -379,17 +336,17 @@ static int
|
||||
get_index_in (GtkAccessible *parent,
|
||||
GtkAccessible *child)
|
||||
{
|
||||
GtkAccessible *candidate;
|
||||
guint res;
|
||||
|
||||
if (parent == NULL)
|
||||
return -1;
|
||||
|
||||
guint res = 0;
|
||||
GtkAccessible *candidate;
|
||||
res = 0;
|
||||
for (candidate = gtk_accessible_get_first_accessible_child (parent);
|
||||
candidate != NULL;
|
||||
candidate = gtk_accessible_get_next_accessible_sibling (candidate))
|
||||
{
|
||||
g_object_unref (candidate);
|
||||
|
||||
if (candidate == child)
|
||||
return res;
|
||||
|
||||
@@ -408,13 +365,7 @@ get_index_in_parent (GtkAccessible *accessible)
|
||||
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
|
||||
if (parent != NULL)
|
||||
{
|
||||
int res = get_index_in (parent, accessible);
|
||||
|
||||
g_object_unref (parent);
|
||||
|
||||
return res;
|
||||
}
|
||||
return get_index_in (parent, accessible);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -450,6 +401,7 @@ static GVariant *
|
||||
get_parent_context_ref (GtkAccessible *accessible)
|
||||
{
|
||||
GVariant *res = NULL;
|
||||
|
||||
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
|
||||
if (parent == NULL)
|
||||
@@ -458,19 +410,13 @@ get_parent_context_ref (GtkAccessible *accessible)
|
||||
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
|
||||
|
||||
res = gtk_at_spi_root_to_ref (self->root);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkATContext *parent_context = gtk_accessible_get_at_context (parent);
|
||||
|
||||
gtk_at_context_realize (parent_context);
|
||||
|
||||
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
|
||||
|
||||
g_object_unref (parent_context);
|
||||
g_object_unref (parent);
|
||||
}
|
||||
|
||||
if (res == NULL)
|
||||
@@ -551,32 +497,31 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
{
|
||||
GtkATContext *context = NULL;
|
||||
GtkAccessible *accessible;
|
||||
GtkAccessible *child = NULL;
|
||||
int idx, presentable_idx;
|
||||
|
||||
g_variant_get (parameters, "(i)", &idx);
|
||||
|
||||
accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
|
||||
|
||||
presentable_idx = 0;
|
||||
GtkAccessible *child;
|
||||
|
||||
presentable_idx = 0;
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
{
|
||||
g_object_unref (child);
|
||||
|
||||
if (!gtk_accessible_should_present (child))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
if (presentable_idx == idx)
|
||||
break;
|
||||
presentable_idx++;
|
||||
|
||||
presentable_idx += 1;
|
||||
}
|
||||
|
||||
if (child != NULL)
|
||||
context = gtk_accessible_get_at_context (child);
|
||||
if (child)
|
||||
{
|
||||
context = gtk_accessible_get_at_context (child);
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
@@ -591,23 +536,20 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
gtk_at_context_realize (context);
|
||||
|
||||
GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", ref));
|
||||
|
||||
g_object_unref (context);
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", ref));
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetChildren") == 0)
|
||||
{
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a(so)"));
|
||||
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
|
||||
GtkAccessible *child = NULL;
|
||||
|
||||
GtkAccessible *child;
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
{
|
||||
g_object_unref (child);
|
||||
|
||||
{
|
||||
if (!gtk_accessible_should_present (child))
|
||||
continue;
|
||||
|
||||
@@ -620,8 +562,6 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
|
||||
if (ref != NULL)
|
||||
g_variant_builder_add (&builder, "@(so)", ref);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &builder));
|
||||
@@ -801,13 +741,8 @@ emit_property_changed (GtkAtSpiContext *self,
|
||||
const char *name,
|
||||
GVariant *value)
|
||||
{
|
||||
GVariant *value_owned = g_variant_ref_sink (value);
|
||||
|
||||
if (self->connection == NULL)
|
||||
{
|
||||
g_variant_unref (value_owned);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
g_dbus_connection_emit_signal (self->connection,
|
||||
NULL,
|
||||
@@ -815,9 +750,8 @@ emit_property_changed (GtkAtSpiContext *self,
|
||||
"org.a11y.atspi.Event.Object",
|
||||
"PropertyChange",
|
||||
g_variant_new ("(siiva{sv})",
|
||||
name, 0, 0, value_owned, NULL),
|
||||
name, 0, 0, value, NULL),
|
||||
NULL);
|
||||
g_variant_unref (value_owned);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -916,6 +850,8 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
|
||||
|
||||
if (changed_states & GTK_ACCESSIBLE_STATE_CHANGE_HIDDEN)
|
||||
{
|
||||
GtkAccessible *parent;
|
||||
GtkATContext *context;
|
||||
GtkAccessibleChildChange change;
|
||||
|
||||
value = gtk_accessible_attribute_set_get_value (states, GTK_ACCESSIBLE_STATE_HIDDEN);
|
||||
@@ -931,15 +867,10 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkAccessible *parent =
|
||||
gtk_accessible_get_accessible_parent (accessible);
|
||||
GtkATContext *context =
|
||||
gtk_accessible_get_at_context (parent);
|
||||
parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
|
||||
context = gtk_accessible_get_at_context (parent);
|
||||
gtk_at_context_child_changed (context, change, accessible);
|
||||
|
||||
g_object_unref (context);
|
||||
g_object_unref (parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1059,15 +990,6 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
|
||||
emit_state_changed (self, "selectable", FALSE);
|
||||
}
|
||||
|
||||
if (changed_states & GTK_ACCESSIBLE_STATE_CHANGE_VISITED)
|
||||
{
|
||||
value = gtk_accessible_attribute_set_get_value (states, GTK_ACCESSIBLE_STATE_VISITED);
|
||||
if (value->value_class->type == GTK_ACCESSIBLE_VALUE_TYPE_BOOLEAN)
|
||||
{
|
||||
emit_state_changed (self, "visited",gtk_boolean_accessible_value_get (value));
|
||||
}
|
||||
}
|
||||
|
||||
if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_READ_ONLY)
|
||||
{
|
||||
gboolean readonly;
|
||||
@@ -1115,18 +1037,10 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
|
||||
}
|
||||
|
||||
if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_DESCRIPTION)
|
||||
{
|
||||
char *label = gtk_at_context_get_description (GTK_AT_CONTEXT (self));
|
||||
GVariant *v = g_variant_new_take_string (label);
|
||||
emit_property_changed (self, "accessible-description", v);
|
||||
}
|
||||
|
||||
if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_VALUE_NOW)
|
||||
{
|
||||
value = gtk_accessible_attribute_set_get_value (properties, GTK_ACCESSIBLE_PROPERTY_VALUE_NOW);
|
||||
emit_property_changed (self,
|
||||
"accessible-value",
|
||||
g_variant_new_double (gtk_number_accessible_value_get (value)));
|
||||
char *label = gtk_at_context_get_description (GTK_AT_CONTEXT (self));
|
||||
GVariant *v = g_variant_new_take_string (label);
|
||||
emit_property_changed (self, "accessible-description", v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1205,18 +1119,9 @@ gtk_at_spi_context_child_change (GtkATContext *ctx,
|
||||
int idx = 0;
|
||||
|
||||
if (parent == NULL)
|
||||
{
|
||||
idx = -1;
|
||||
}
|
||||
idx = -1;
|
||||
else if (parent == accessible)
|
||||
{
|
||||
idx = get_index_in (accessible, child);
|
||||
g_object_unref (parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_unref (parent);
|
||||
}
|
||||
idx = get_index_in (accessible, child);
|
||||
|
||||
if (change & GTK_ACCESSIBLE_CHILD_CHANGE_ADDED)
|
||||
emit_children_changed (self,
|
||||
@@ -1228,8 +1133,6 @@ gtk_at_spi_context_child_change (GtkATContext *ctx,
|
||||
GTK_AT_SPI_CONTEXT (child_context),
|
||||
idx,
|
||||
GTK_ACCESSIBLE_CHILD_STATE_REMOVED);
|
||||
|
||||
g_object_unref (child_context);
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ D-Bus Registration */
|
||||
@@ -1798,16 +1701,15 @@ gtk_at_spi_context_get_child_count (GtkAtSpiContext *self)
|
||||
int n_children = 0;
|
||||
|
||||
GtkAccessible *child = NULL;
|
||||
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
{
|
||||
g_object_unref (child);
|
||||
|
||||
if (!gtk_accessible_should_present (child))
|
||||
continue;
|
||||
|
||||
n_children += 1;
|
||||
n_children++;
|
||||
}
|
||||
|
||||
return n_children;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user