Compare commits

..

3 Commits

Author SHA1 Message Date
Matthias Clasen 7e4745202c Add some more text rendering tests 2024-01-29 18:29:35 -05:00
Matthias Clasen 1564d768d3 Accept font options in node files
The goal is to fix all the context that influences the rendering
of text nodes in the node file. This includes the relevant parts
of cairo_font_options_t (via pango_cairo_context_set_font_options)
as well as the dpi (via pango_cairo_font_map_set_resolution).

The default values we use match the default of the gsettings backing
our GtkSettings:

hint-metrics: off;
hint-style: slight;
antialias: on;
dpi: 96;

This will help with better font testing.

Parser test included.
2024-01-29 18:29:35 -05:00
Matthias Clasen e80acf53fd node-editor: Drop a duplicated menu item 2024-01-29 18:29:35 -05:00
238 changed files with 7983 additions and 16999 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# See https://www.apertis.org/policies/coding_conventions/#code-formatting
# See https://wiki.apertis.org/Guidelines/Coding_conventions#Code_formatting
BasedOnStyle: GNU
AlwaysBreakAfterDefinitionReturnType: All
BreakBeforeBinaryOperators: None
+36 -32
View File
@@ -78,7 +78,6 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.node"
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.node"
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
- "${CI_PROJECT_DIR}/_build/testsuite/headless/*/*.log"
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
@@ -210,52 +209,51 @@ msys2-mingw64:
paths:
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
macos:
macos-x86_64:
rules:
# Do not run in forks as the runner is not available there.
# (except for dehesselle who maintains the runner)
- if: $CI_PROJECT_NAMESPACE != "GNOME" && $CI_PROJECT_NAMESPACE != "dehesselle"
when: never
- if: $RUNNER == "macosintel"
variables:
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
when: manual
allow_failure: true
- if: $RUNNER == "macosarm"
variables:
SDKROOT: /opt/sdks/MacOSX11.3.sdk
- if: $CI_PROJECT_NAMESPACE == "GNOME"
stage: build
parallel:
matrix:
- RUNNER: [ "macosintel", "macosarm" ]
tags:
- ${RUNNER}
- macosintel
needs: []
variables:
EXTRA_MESON_FLAGS: ""
BACKEND_FLAGS: "-Dx11-backend=false -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dmedia-gstreamer=disabled -Dintrospection=enabled -Dgobject-introspection:werror=false"
MESON_FORCE_BACKTRACKE: 1
TMPDIR: /Users/Shared/work/tmp
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
PIP_CACHE_DIR: /Users/Shared/build/cache
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
EXTRA_MESON_FLAGS: "-Dgobject-introspection:werror=false"
before_script:
- .gitlab-ci/show-info-macos.sh
- python3 -m venv .venv
# Building the introspection feature requires pkg-config and bison.
- curl -L $CI_API_V4_URL/projects/30437/packages/generic/pkgconfig/v0.29.2+10/pkg-config-0.29.2+10_$(uname -m).tar.xz | tar -C .venv -xJ
- curl -L $CI_API_V4_URL/projects/30438/packages/generic/bison/v3.8.2+3/bison-3.8.2+3_$(uname -m).tar.xz | tar -C .venv -xJ
# Not using ccache on purpose as it accelerates the build so much that it
# can trigger race conditions in the gobject-introspection subproject.
- bash .gitlab-ci/show-info-osx.sh
- /opt/macports/bin/python3.10 -m venv .venv
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
- ln -s /opt/pkg-config/bin/pkg-config .venv/bin
- ln -s /opt/bison/bin/bison .venv/bin
- source .venv/bin/activate
- pip3 install meson==1.3.2 ninja==1.11.1.1
# We're not setting up ccache here on purpose as it accelerates the build
# so much that it triggers race conditions in the gobject-introspection
# subproject.
- pip3 install meson==1.2.0
- pip3 install ninja==1.11.1
- pip3 install /Users/Shared/build/pkgs/PyGObject-3.44.0-cp310-cp310-macosx_10_13_x86_64.whl
/Users/Shared/build/pkgs/pycairo-1.23.0-cp310-cp310-macosx_10_13_x86_64.whl
script:
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
${BACKEND_FLAGS}
${FEATURE_FLAGS}
-Dx11-backend=false
-Dbroadway-backend=true
-Dmacos-backend=true
-Dmedia-gstreamer=disabled
-Dintrospection=enabled
-Dcpp_std=c++11
-Dpixman:tests=disabled
-Dlibjpeg-turbo:simd=disabled
-Dbuild-demos=false
-Dbuild-tests=false
-Dbuild-examples=false
-Dbuild-testsuite=false
_build
- meson compile -C _build
artifacts:
@@ -430,6 +428,13 @@ asan-build:
_build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland gtk
artifacts:
when: always
reports:
junit:
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
reference:
image: $FEDORA_IMAGE
@@ -479,4 +484,3 @@ publish-docs:
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
rules:
- if: $CI_COMMIT_REF_NAME == "main"
@@ -3,11 +3,6 @@
set -eux -o pipefail
xcodebuild -version || :
if [ -z "$SDKROOT" ]; then
xcodebuild -showsdks || :
else
echo "SDKROOT = $SDKROOT"
fi
xcodebuild -showsdks || :
system_profiler SPSoftwareDataType || :
+1 -99
View File
@@ -1,104 +1,6 @@
Overview of Changes in 4.13.9, xx-xx-xxxx
Overview of Changes in 4.13.7, xx-xx-xxxx
=========================================
Note: The new renderers and dmabuf support are using graphics drivers
in different ways than the old gl renderer, and trigger new driver bugs,
(see for example https://gitlab.gnome.org/GNOME/gtk/-/issues/6418 and
https://gitlab.gnome.org/GNOME/gtk/-/issues/6388). Therefore, it is
recommended to use the latest mesa release (24.0) with the new renderers.
Overview of Changes in 4.13.8, 20-02-2024
=========================================
* Accessibility:
- Add a GtkAccessibleText interface for allowing 3rd party
text widgets (notably vte) to be accessible
- Avoid duplicate accessible descriptions
- Fix GetAccessibleAtPoint
* GSK:
- Avoid offscreens for disjoint containers
- Don't use the gpu renderers with llvmpipe
- Fix various rendering issues found by tests
- Allow unnormalized node bounds again
- Fix a broken case of rounded-rect intersection
- Fix handling of external textures in gpu renderers
- Make gpu renderers work with WGL on Windows
* build:
- Allow building without dmabuf support on (old) Linux
* X11:
- Fix monitor enter/leave signals
* Translation updates:
Basque
Brazilian Portuguese
Catalan
Czech
Galician
Georgian
Hebrew
Lithuanian
Persian
Russian
Turkish
Ukrainian
Overview of Changes in 4.13.7, 11-02-2024
=========================================
* GtkFileChooser:
- Speed up opening
* GtkCalendar:
- Add some missing setters and getters
* Accessibility:
- Add socket support for webkit accessibility
- Implement AT-SPI text for GtkText
- Implement AT-SPI component generically
- Add an announce API
* GSK:
- Make the ngl renderer work on macOS
- Fix a crash in the vulkan renderer
- Make nodeparser allow aliases for fonts again
- Implement cache eviction for glyph and texture caches
- Fix ngl shaders to work on GL < 4.0
- Require GL 3.3 for the ngl renderer
- Fix problems with scaled shadows
- Fix problems with holes for underlaid subsurfaces
- Improve handling of scales and glyph cache efficiency
* Media:
- Support dmabufs in the gstreamer backend. This allows
zero-copy video playback on Wayland when paired with
hardware video decoding
- Drop the experimental ffmpeg backend. It hasn't been
building for a year
* Wayland:
- Commit empty frames if and double-buffered state is pending
- Fix monitor size information when using mutter without
the scale-monitor-framebuffer setting
- Clear the current tablet on tab leave, fixing a crash
* macOS:
- Propagate unhandled input events back to the OS
* Tools:
- Make the crash handling in gtk4-node-editor more robust
* Translation updates
Galician
Georgian
Occitan
Turkish
Overview of Changes in 4.13.6, 25-01-2024
=========================================
-1
View File
@@ -1,5 +1,4 @@
/* Lists/Selections
* #Keywords: suggestion, completion
*
* The GtkDropDown widget is a modern alternative to GtkComboBox.
* It uses list models instead of tree models, and the content is
+40 -53
View File
@@ -68,9 +68,8 @@ struct _NodeEditorWindow
GArray *errors;
guint update_timeout;
gboolean auto_reload;
gboolean mark_as_safe_pending;
gulong after_paint_handler;
};
struct _NodeEditorWindowClass
@@ -246,41 +245,6 @@ highlight_text (NodeEditorWindow *self)
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "no-hyphens", &start, &end);
}
static void
mark_autosave_as_unsafe (void)
{
char *path1 = NULL;
char *path2 = NULL;
path1 = get_autosave_path ("-unsafe");
path2 = get_autosave_path (NULL);
g_rename (path2, path1);
}
static void
mark_autosave_as_safe (void)
{
char *path1 = NULL;
char *path2 = NULL;
path1 = get_autosave_path ("-unsafe");
path2 = get_autosave_path (NULL);
g_rename (path1, path2);
}
static void
after_paint (GdkFrameClock *clock,
NodeEditorWindow *self)
{
if (self->mark_as_safe_pending)
{
self->mark_as_safe_pending = FALSE;
mark_autosave_as_safe ();
}
}
static void
reload (NodeEditorWindow *self)
{
@@ -289,8 +253,6 @@ reload (NodeEditorWindow *self)
float scale;
GskRenderNode *big_node;
mark_autosave_as_unsafe ();
text = get_current_text (self->text_buffer);
bytes = g_bytes_new_take (text, strlen (text));
@@ -352,8 +314,6 @@ reload (NodeEditorWindow *self)
}
g_clear_pointer (&big_node, gsk_render_node_unref);
self->mark_as_safe_pending = TRUE;
}
static void
@@ -1165,6 +1125,9 @@ node_editor_window_finalize (GObject *object)
{
NodeEditorWindow *self = (NodeEditorWindow *)object;
if (self->update_timeout)
g_source_remove (self->update_timeout);
g_array_free (self->errors, TRUE);
g_clear_pointer (&self->node, gsk_render_node_unref);
@@ -1209,7 +1172,6 @@ static void
node_editor_window_realize (GtkWidget *widget)
{
NodeEditorWindow *self = NODE_EDITOR_WINDOW (widget);
GdkFrameClock *frameclock;
GTK_WIDGET_CLASS (node_editor_window_parent_class)->realize (widget);
@@ -1237,24 +1199,14 @@ node_editor_window_realize (GtkWidget *widget)
node_editor_window_add_renderer (self,
gsk_cairo_renderer_new (),
"Cairo");
frameclock = gtk_widget_get_frame_clock (widget);
self->after_paint_handler = g_signal_connect (frameclock, "after-paint",
G_CALLBACK (after_paint), self);
}
static void
node_editor_window_unrealize (GtkWidget *widget)
{
NodeEditorWindow *self = NODE_EDITOR_WINDOW (widget);
GdkFrameClock *frameclock;
guint i;
frameclock = gtk_widget_get_frame_clock (widget);
g_signal_handler_disconnect (frameclock, self->after_paint_handler);
self->after_paint_handler = 0;
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->renderers)); i ++)
{
gpointer item = g_list_model_get_item (G_LIST_MODEL (self->renderers), i);
@@ -1854,6 +1806,41 @@ autosave_contents (NodeEditorWindow *self)
g_free (contents);
}
static void
mark_autosave_as_safe (void)
{
char *path1 = NULL;
char *path2 = NULL;
path1 = get_autosave_path ("-unsafe");
path2 = get_autosave_path (NULL);
g_rename (path1, path2);
}
static gboolean
update_timeout_cb (gpointer data)
{
NodeEditorWindow *self = data;
self->update_timeout = 0;
mark_autosave_as_safe ();
return G_SOURCE_REMOVE;
}
static void
initiate_autosave (NodeEditorWindow *self)
{
autosave_contents (self);
if (self->update_timeout != 0)
g_source_remove (self->update_timeout);
self->update_timeout = g_timeout_add (100, update_timeout_cb, self);
}
static void
node_editor_window_init (NodeEditorWindow *self)
{
@@ -1918,7 +1905,7 @@ node_editor_window_init (NodeEditorWindow *self)
set_initial_text (self);
g_signal_connect_swapped (self->text_buffer, "changed", G_CALLBACK (autosave_contents), self);
g_signal_connect_swapped (self->text_buffer, "changed", G_CALLBACK (initiate_autosave), self);
if (g_getenv ("GSK_RENDERER"))
{
-1
View File
@@ -209,7 +209,6 @@
<property name="halign">1</property>
<property name="label" translatable="1">The application may have crashed.
As a precaution, auto-loading has been turned off.
You can turn it back on in the menu.
</property>
</object>
</child>
+10 -6
View File
@@ -322,12 +322,16 @@ stroke bounds of the path.
### text
| property | syntax | default | printed |
| -------- | ------------------- | ------------------- | ----------- |
| color | `<color>` | black | non-default |
| font | `<string>` `<url>`? | "Cantarell 11" | always |
| glyphs | `<glyphs>` | "Hello" | always |
| offset | `<point>` | 0 0 | non-default |
| property | syntax | default | printed |
| ------------ | ------------------- | ------------------- | ----------- |
| color | `<color>` | black | non-default |
| font | `<string>` `<url>`? | "Cantarell 11" | always |
| glyphs | `<glyphs>` | "Hello" | always |
| offset | `<point>` | 0 0 | non-default |
| hint-metrics | `<hint metrics>` | off | non-default |
| hint-style | `<hint style>` | slight | non-default |
| antialias | `<antialias>` | on | non-default |
| dpi | `<number>` | 96 | non-default |
Creates a node like `gsk_text_node_new()` with the given properties.
+1 -1
View File
@@ -234,7 +234,7 @@ By default, GTK will try to build with support for the Vulkan graphics
API in addition to cairo and OpenGL. This option can be used to explicitly
control whether Vulkan should be used.
### `media-gstreamer`
### `media-gstreamer` and `media-ffmpeg`
By default, GTK will try to build the gstreamer backend for
media playback support. These options can be used to explicitly
+2 -2
View File
@@ -126,8 +126,8 @@ available on the system.
### `GTK_MEDIA`
Specifies what backend to load for [class@Gtk.MediaFile]. The possible values
depend on what options GTK was built with, and can include 'gstreamer'
and 'none'. If set to 'none', media playback will be unavailable.
depend on what options GTK was built with, and can include 'gstreamer',
'ffmpeg' and 'none'. If set to 'none', media playback will be unavailable.
The special value 'help' can be used to obtain a list of all supported
media backends.
+1 -1
View File
@@ -272,7 +272,7 @@ gdk_display_class_init (GdkDisplayClass *class)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDisplay:dmabuf-formats: (attributes org.gtk.Property.get=gdk_display_get_dmabuf_formats)
* GdkDisplay:dmabuf-formats:
*
* The dma-buf formats that are supported on this display
*
+1 -25
View File
@@ -2329,42 +2329,18 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest,
* @dmabuf: a sanitized GdkDmabuf
*
* A dmabuf is considered disjoint if it uses more than
* 1 inode.
* Multiple file descriptors may exist when the creator
* of the dmabuf just dup()ed once for every plane...
* 1 file descriptor.
*
* Returns: %TRUE if the dmabuf is disjoint
**/
gboolean
gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf)
{
struct stat first_stat;
unsigned i;
/* First, do a fast check */
for (i = 1; i < dmabuf->n_planes; i++)
{
if (dmabuf->planes[0].fd != dmabuf->planes[i].fd)
break;
}
if (i == dmabuf->n_planes)
return FALSE;
/* We have different fds, do the fancy check instead */
if (fstat (dmabuf->planes[0].fd, &first_stat) != 0)
return TRUE;
for (i = 1; i < dmabuf->n_planes; i++)
{
struct stat plane_stat;
if (fstat (dmabuf->planes[0].fd, &plane_stat) != 0)
return TRUE;
if (first_stat.st_ino != plane_stat.st_ino)
return TRUE;
}
+1 -12
View File
@@ -154,7 +154,6 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
gboolean retval = FALSE;
GError *error = NULL;
GskRenderer *renderer;
GdkGLContext *previous;
g_assert (display->egl_dmabuf_formats == NULL);
g_assert (display->egl_external_formats == NULL);
@@ -162,7 +161,6 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
if (!gdk_display_prepare_gl (display, NULL))
return NULL;
previous = gdk_gl_context_get_current ();
formats = gdk_dmabuf_formats_builder_new ();
external = gdk_dmabuf_formats_builder_new ();
@@ -174,11 +172,7 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
gdk_dmabuf_formats_builder_add_formats (builder, display->egl_dmabuf_formats);
if (!retval)
{
if (previous)
gdk_gl_context_make_current (previous);
return NULL;
}
return NULL;
renderer = gsk_gl_renderer_new ();
@@ -187,15 +181,10 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
g_warning ("Failed to realize GL renderer: %s", error->message);
g_error_free (error);
g_object_unref (renderer);
if (previous)
gdk_gl_context_make_current (previous);
return NULL;
}
if (previous)
gdk_gl_context_make_current (previous);
return GDK_DMABUF_DOWNLOADER (renderer);
}
-38
View File
@@ -217,41 +217,3 @@ gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self)
{
return self->formats;
}
/**
* gdk_dmabuf_formats_equal:
* @formats1: (nullable): a `GdkDmabufFormats`
* @formats2: (nullable): another `GdkDmabufFormats`
*
* Returns whether @formats1 and @formats2 contain the
* same dmabuf formats, in the same order.
*
* Returns: `TRUE` if @formats1 and @formats2 are equal
*
* Since: 4.14
*/
gboolean
gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
const GdkDmabufFormats *formats2)
{
if (formats1 == formats2)
return TRUE;
if (formats1 == NULL || formats2 == NULL)
return FALSE;
if (formats1->n_formats != formats2->n_formats)
return FALSE;
for (gsize i = 0; i < formats1->n_formats; i++)
{
GdkDmabufFormat *f1 = &formats1->formats[i];
GdkDmabufFormat *f2 = &formats2->formats[i];
if (f1->fourcc != f2->fourcc ||
f1->modifier != f2->modifier)
return FALSE;
}
return TRUE;
}
-4
View File
@@ -51,8 +51,4 @@ gboolean gdk_dmabuf_formats_contains (GdkDmabufFormats *formats
guint32 fourcc,
guint64 modifier) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
gboolean gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
const GdkDmabufFormats *formats2);
G_END_DECLS
+1 -2
View File
@@ -1,7 +1,6 @@
#pragma once
#include "config.h"
#ifdef HAVE_DRM_FOURCC_H
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#endif
+1 -1
View File
@@ -33,7 +33,7 @@
/**
* GdkDmabufTexture:
*
* A `GdkTexture` representing a DMA buffer.
* A `GdkTexture` representing a dma-buf object.
*
* To create a `GdkDmabufTexture`, use the auxiliary
* [class@Gdk.DmabufTextureBuilder] object.
+4 -4
View File
@@ -477,18 +477,18 @@ check_event_sanity (GdkEvent *event)
}
#endif
gboolean
void
_gdk_event_emit (GdkEvent *event)
{
#ifdef G_ENABLE_DEBUG
if (!check_event_sanity (event))
return FALSE;
return;
#endif
if (gdk_drag_handle_source_event (event))
return TRUE;
return;
return gdk_surface_handle_event (event);
gdk_surface_handle_event (event);
}
/*********************************************
+9 -9
View File
@@ -619,16 +619,16 @@ typedef enum
GdkEvent* _gdk_event_unqueue (GdkDisplay *display);
gboolean _gdk_event_emit (GdkEvent *event);
GList* _gdk_event_queue_find_first (GdkDisplay *display);
void _gdk_event_queue_remove_link (GdkDisplay *display,
GList *node);
GList* _gdk_event_queue_append (GdkDisplay *display,
GdkEvent *event);
void _gdk_event_emit (GdkEvent *event);
GList* _gdk_event_queue_find_first (GdkDisplay *display);
void _gdk_event_queue_remove_link (GdkDisplay *display,
GList *node);
GList* _gdk_event_queue_append (GdkDisplay *display,
GdkEvent *event);
void _gdk_event_queue_handle_motion_compression (GdkDisplay *display);
void gdk_event_queue_handle_scroll_compression (GdkDisplay *display);
void _gdk_event_queue_flush (GdkDisplay *display);
void _gdk_event_queue_handle_motion_compression (GdkDisplay *display);
void gdk_event_queue_handle_scroll_compression (GdkDisplay *display);
void _gdk_event_queue_flush (GdkDisplay *display);
double * gdk_event_dup_axes (GdkEvent *event);
+5 -2
View File
@@ -79,7 +79,6 @@
#include "gdkdebugprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkdmabufeglprivate.h"
#include "gdkdmabuffourccprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdkprofilerprivate.h"
@@ -99,6 +98,10 @@
#include <epoxy/egl.h>
#endif
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#endif
#include <math.h>
#define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES
@@ -1715,7 +1718,7 @@ 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 ("GL_OES_vertex_half_float");
epoxy_has_gl_extension ("OES_vertex_half_float");
priv->has_sync = gdk_gl_context_check_version (context, "3.2", "3.0") ||
epoxy_has_gl_extension ("GL_ARB_sync") ||
+2 -74
View File
@@ -26,8 +26,6 @@
#include "gdkenumtypes.h"
#include "gdkrectangle.h"
#include <math.h>
/**
* GdkMonitor:
*
@@ -48,7 +46,6 @@ enum {
PROP_MODEL,
PROP_CONNECTOR,
PROP_SCALE_FACTOR,
PROP_SCALE,
PROP_GEOMETRY,
PROP_WIDTH_MM,
PROP_HEIGHT_MM,
@@ -73,8 +70,6 @@ static void
gdk_monitor_init (GdkMonitor *monitor)
{
monitor->scale_factor = 1;
monitor->scale = 1.0;
monitor->scale_set = FALSE;
monitor->valid = TRUE;
}
@@ -112,10 +107,6 @@ gdk_monitor_get_property (GObject *object,
g_value_set_int (value, monitor->scale_factor);
break;
case PROP_SCALE:
g_value_set_double (value, monitor->scale);
break;
case PROP_GEOMETRY:
g_value_set_boxed (value, &monitor->geometry);
break;
@@ -242,28 +233,13 @@ gdk_monitor_class_init (GdkMonitorClass *class)
* GdkMonitor:scale-factor: (attributes org.gtk.Property.get=gdk_monitor_get_scale_factor)
*
* The scale factor.
*
* The scale factor is the next larger integer,
* compared to [property@Gdk.Surface:scale].
*/
props[PROP_SCALE_FACTOR] =
g_param_spec_int ("scale-factor", NULL, NULL,
1, G_MAXINT,
0, G_MAXINT,
1,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkMonitor:scale: (attributes org.gtk.Property.get=gdk_monitor_get_scale)
*
* The scale of the monitor.
*
* Since: 4.14
*/
props[PROP_SCALE] =
g_param_spec_double ("scale", NULL, NULL,
1., G_MAXDOUBLE, 1.,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkMonitor:geometry: (attributes org.gtk.Property.get=gdk_monitor_get_geometry)
*
@@ -370,7 +346,7 @@ gdk_monitor_get_display (GdkMonitor *monitor)
* display coordinate space.
*
* The returned geometry is in application pixels, not in
* device pixels (see [method@Gdk.Monitor.get_scale]).
* device pixels (see [method@Gdk.Monitor.get_scale_factor]).
*/
void
gdk_monitor_get_geometry (GdkMonitor *monitor,
@@ -496,29 +472,6 @@ gdk_monitor_get_scale_factor (GdkMonitor *monitor)
return monitor->scale_factor;
}
/**
* gdk_monitor_get_scale: (attributes org.gtk.Method.get_property=scale)
* @monitor: a `GdkMonitor`
*
* Gets the internal scale factor that maps from monitor coordinates
* to device pixels.
*
* This can be used if you want to create pixel based data for a
* particular monitor, but most of the time youre drawing to a surface
* where it is better to use [method@Gdk.Surface.get_scale] instead.
*
* Returns: the scale
*
* Since: 4.14
*/
double
gdk_monitor_get_scale (GdkMonitor *monitor)
{
g_return_val_if_fail (GDK_IS_MONITOR (monitor), 1.);
return monitor->scale;
}
/**
* gdk_monitor_get_refresh_rate: (attributes org.gtk.Method.get_property=refresh-rate)
* @monitor: a `GdkMonitor`
@@ -630,37 +583,12 @@ void
gdk_monitor_set_scale_factor (GdkMonitor *monitor,
int scale_factor)
{
g_return_if_fail (scale_factor >= 1);
if (monitor->scale_set)
return;
if (monitor->scale_factor == scale_factor)
return;
monitor->scale_factor = scale_factor;
monitor->scale = scale_factor;
g_object_notify (G_OBJECT (monitor), "scale-factor");
g_object_notify (G_OBJECT (monitor), "scale");
}
void
gdk_monitor_set_scale (GdkMonitor *monitor,
double scale)
{
g_return_if_fail (scale >= 1.);
monitor->scale_set = TRUE;
if (monitor->scale == scale)
return;
monitor->scale = scale;
monitor->scale_factor = (int) ceil (scale);
g_object_notify (G_OBJECT (monitor), "scale");
g_object_notify (G_OBJECT (monitor), "scale-factor");
}
void
-2
View File
@@ -77,8 +77,6 @@ GDK_AVAILABLE_IN_ALL
const char * gdk_monitor_get_connector (GdkMonitor *monitor);
GDK_AVAILABLE_IN_ALL
int gdk_monitor_get_scale_factor (GdkMonitor *monitor);
GDK_AVAILABLE_IN_4_14
double gdk_monitor_get_scale (GdkMonitor *monitor);
GDK_AVAILABLE_IN_ALL
int gdk_monitor_get_refresh_rate (GdkMonitor *monitor);
GDK_AVAILABLE_IN_ALL
+1 -5
View File
@@ -44,8 +44,6 @@ struct _GdkMonitor {
int refresh_rate;
GdkSubpixelLayout subpixel_layout;
gboolean valid;
double scale;
gboolean scale_set;
};
struct _GdkMonitorClass {
@@ -66,9 +64,7 @@ void gdk_monitor_set_physical_size (GdkMonitor *monitor,
int width_mm,
int height_mm);
void gdk_monitor_set_scale_factor (GdkMonitor *monitor,
int scale_factor);
void gdk_monitor_set_scale (GdkMonitor *monitor,
double scale);
int scale);
void gdk_monitor_set_refresh_rate (GdkMonitor *monitor,
int refresh_rate);
void gdk_monitor_set_subpixel_layout (GdkMonitor *monitor,
+8 -108
View File
@@ -20,7 +20,6 @@
#include "gdksubsurfaceprivate.h"
#include "gdksurfaceprivate.h"
#include "gdktexture.h"
#include "gsk/gskrectprivate.h"
G_DEFINE_TYPE (GdkSubsurface, gdk_subsurface, G_TYPE_OBJECT)
@@ -56,106 +55,19 @@ gdk_subsurface_get_parent (GdkSubsurface *subsurface)
return subsurface->parent;
}
static void
remove_subsurface (GdkSubsurface *subsurface)
{
GdkSurface *parent = subsurface->parent;
if (parent->subsurfaces_above == subsurface)
parent->subsurfaces_above = subsurface->sibling_above;
if (parent->subsurfaces_below == subsurface)
parent->subsurfaces_below = subsurface->sibling_below;
if (subsurface->sibling_above)
subsurface->sibling_above->sibling_below = subsurface->sibling_below;
if (subsurface->sibling_below)
subsurface->sibling_below->sibling_above = subsurface->sibling_above;
subsurface->sibling_above = NULL;
subsurface->sibling_below = NULL;
}
static void
insert_subsurface (GdkSubsurface *subsurface,
gboolean above,
GdkSubsurface *sibling)
{
GdkSurface *parent = subsurface->parent;
subsurface->above_parent = sibling->above_parent;
if (above)
{
subsurface->sibling_above = sibling->sibling_above;
sibling->sibling_above = subsurface;
subsurface->sibling_below = sibling;
if (subsurface->sibling_above)
subsurface->sibling_above->sibling_below = subsurface;
if (parent->subsurfaces_below == sibling)
parent->subsurfaces_below = subsurface;
}
else
{
subsurface->sibling_below = sibling->sibling_below;
sibling->sibling_below = subsurface;
subsurface->sibling_above = sibling;
if (subsurface->sibling_below)
subsurface->sibling_below->sibling_above = subsurface;
if (parent->subsurfaces_above == sibling)
parent->subsurfaces_above = subsurface;
}
}
gboolean
gdk_subsurface_attach (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *source,
const graphene_rect_t *dest,
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling)
{
GdkSurface *parent = subsurface->parent;
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), FALSE);
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
g_return_val_if_fail (source != NULL &&
gsk_rect_contains_rect (&GRAPHENE_RECT_INIT (0, 0,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture)),
source), FALSE);
g_return_val_if_fail (dest != NULL, FALSE);
g_return_val_if_fail (sibling != subsurface, FALSE);
g_return_val_if_fail (rect != NULL, FALSE);
g_return_val_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling), FALSE);
g_return_val_if_fail (sibling == NULL || sibling->parent == subsurface->parent, FALSE);
remove_subsurface (subsurface);
if (sibling)
{
insert_subsurface (subsurface, above, sibling);
}
else
{
sibling = above ? parent->subsurfaces_above : parent->subsurfaces_below;
if (sibling)
{
insert_subsurface (subsurface, !above, sibling);
}
else
{
subsurface->above_parent = above;
if (above)
parent->subsurfaces_above = subsurface;
else
parent->subsurfaces_below = subsurface;
}
}
return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, source, dest, above, sibling);
return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, rect, above, sibling);
}
void
@@ -163,8 +75,6 @@ gdk_subsurface_detach (GdkSubsurface *subsurface)
{
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
remove_subsurface (subsurface);
GDK_SUBSURFACE_GET_CLASS (subsurface)->detach (subsurface);
}
@@ -177,23 +87,13 @@ gdk_subsurface_get_texture (GdkSubsurface *subsurface)
}
void
gdk_subsurface_get_source (GdkSubsurface *subsurface,
graphene_rect_t *source)
gdk_subsurface_get_rect (GdkSubsurface *subsurface,
graphene_rect_t *rect)
{
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
g_return_if_fail (source != NULL);
g_return_if_fail (rect != NULL);
GDK_SUBSURFACE_GET_CLASS (subsurface)->get_source (subsurface, source);
}
void
gdk_subsurface_get_dest (GdkSubsurface *subsurface,
graphene_rect_t *dest)
{
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
g_return_if_fail (dest != NULL);
GDK_SUBSURFACE_GET_CLASS (subsurface)->get_dest (subsurface, dest);
GDK_SUBSURFACE_GET_CLASS (subsurface)->get_rect (subsurface, rect);
}
gboolean
@@ -201,5 +101,5 @@ gdk_subsurface_is_above_parent (GdkSubsurface *subsurface)
{
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), TRUE);
return subsurface->above_parent;
return GDK_SUBSURFACE_GET_CLASS (subsurface)->is_above_parent (subsurface);
}
+7 -16
View File
@@ -41,10 +41,6 @@ struct _GdkSubsurface
GdkSurface *parent;
int ref_count;
gboolean above_parent;
GdkSubsurface *sibling_above;
GdkSubsurface *sibling_below;
};
@@ -54,16 +50,14 @@ struct _GdkSubsurfaceClass
gboolean (* attach) (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *source,
const graphene_rect_t *dest,
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling);
void (* detach) (GdkSubsurface *subsurface);
GdkTexture * (* get_texture) (GdkSubsurface *subsurface);
void (* get_source) (GdkSubsurface *subsurface,
graphene_rect_t *source);
void (* get_dest) (GdkSubsurface *subsurface,
graphene_rect_t *dest);
void (* get_rect) (GdkSubsurface *subsurface,
graphene_rect_t *rect);
gboolean (* is_above_parent) (GdkSubsurface *subsurface);
};
GType gdk_subsurface_get_type (void) G_GNUC_CONST;
@@ -71,16 +65,13 @@ GType gdk_subsurface_get_type (void) G_GNUC_CONST;
GdkSurface * gdk_subsurface_get_parent (GdkSubsurface *subsurface);
gboolean gdk_subsurface_attach (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *source,
const graphene_rect_t *dest,
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling);
void gdk_subsurface_detach (GdkSubsurface *subsurface);
GdkTexture * gdk_subsurface_get_texture (GdkSubsurface *subsurface);
void gdk_subsurface_get_source (GdkSubsurface *subsurface,
graphene_rect_t *source);
void gdk_subsurface_get_dest (GdkSubsurface *subsurface,
graphene_rect_t *dest);
void gdk_subsurface_get_rect (GdkSubsurface *subsurface,
graphene_rect_t *rect);
gboolean gdk_subsurface_is_above_parent (GdkSubsurface *subsurface);
+2 -6
View File
@@ -99,12 +99,6 @@ struct _GdkSurface
GdkSeat *current_shortcuts_inhibited_seat;
GPtrArray *subsurfaces;
/* We keep the subsurfaces above and below the surface in two linked
* lists, which start here.
*/
GdkSubsurface *subsurfaces_above;
GdkSubsurface *subsurfaces_below;
};
struct _GdkSurfaceClass
@@ -351,6 +345,8 @@ void gdk_surface_request_motion (GdkSurface *surface);
gboolean gdk_surface_supports_edge_constraints (GdkSurface *surface);
GdkSubsurface * gdk_surface_create_subsurface (GdkSurface *surface);
void gdk_surface_destroy_subsurface (GdkSurface *surface,
GdkSubsurface *subsurface);
gsize gdk_surface_get_n_subsurfaces (GdkSurface *surface);
GdkSubsurface * gdk_surface_get_subsurface (GdkSurface *surface,
gsize idx);
+2 -23
View File
@@ -593,8 +593,7 @@ physical_device_check_features (VkPhysicalDevice device,
v12_features.shaderStorageBufferArrayNonUniformIndexing)
*out_features |= GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING;
if (ycbcr_features.samplerYcbcrConversion ||
physical_device_supports_extension (device, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME))
if (ycbcr_features.samplerYcbcrConversion)
*out_features |= GDK_VULKAN_FEATURE_YCBCR;
if (physical_device_supports_extension (device, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME) &&
@@ -1467,27 +1466,13 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SWAPCHAIN_EXTENSION_NAME);
if (features & GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING)
g_ptr_array_add (device_extensions, (gpointer) VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
if (features & GDK_VULKAN_FEATURE_YCBCR)
{
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
}
if (features & GDK_VULKAN_FEATURE_DMABUF)
{
g_assert (features & GDK_VULKAN_FEATURE_YCBCR);
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
g_ptr_array_add (device_extensions, (gpointer) VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME);
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
}
if (features & (GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT | GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT))
{
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
}
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
if (features & GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT)
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
@@ -1628,12 +1613,6 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
g_ptr_array_add (used_extensions, (gpointer) VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
have_debug_report = TRUE;
}
if (g_str_equal (extensions[i].extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
if (g_str_equal (extensions[i].extensionName, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME))
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
if (g_str_equal (extensions[i].extensionName, VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME))
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
}
uint32_t n_layers;
-6
View File
@@ -271,11 +271,6 @@ _gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
[CATransaction commit];
}
static void
_gdk_macos_cairo_context_empty_frame (GdkDrawContext *draw_context)
{
}
static void
_gdk_macos_cairo_context_surface_resized (GdkDrawContext *draw_context)
{
@@ -292,7 +287,6 @@ _gdk_macos_cairo_context_class_init (GdkMacosCairoContextClass *klass)
draw_context_class->begin_frame = _gdk_macos_cairo_context_begin_frame;
draw_context_class->end_frame = _gdk_macos_cairo_context_end_frame;
draw_context_class->empty_frame = _gdk_macos_cairo_context_empty_frame;
draw_context_class->surface_resized = _gdk_macos_cairo_context_surface_resized;
cairo_context_class->cairo_create = _gdk_macos_cairo_context_cairo_create;
+1 -8
View File
@@ -734,14 +734,7 @@ gdk_macos_event_source_dispatch (GSource *source,
if (event)
{
gboolean handled = _gdk_event_emit (event);
if (!handled)
{
NSEvent *nsevent = _gdk_macos_display_get_nsevent (event);
if (nsevent != NULL)
[NSApp sendEvent: nsevent];
}
_gdk_event_emit (event);
gdk_event_unref (event);
}
-6
View File
@@ -545,11 +545,6 @@ gdk_macos_gl_context_end_frame (GdkDrawContext *context,
[CATransaction commit];
}
static void
gdk_macos_gl_context_empty_frame (GdkDrawContext *draw_context)
{
}
static void
gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context)
{
@@ -672,7 +667,6 @@ gdk_macos_gl_context_class_init (GdkMacosGLContextClass *klass)
draw_context_class->begin_frame = gdk_macos_gl_context_begin_frame;
draw_context_class->end_frame = gdk_macos_gl_context_end_frame;
draw_context_class->empty_frame = gdk_macos_gl_context_empty_frame;
draw_context_class->surface_resized = gdk_macos_gl_context_surface_resized;
gl_class->get_damage = gdk_macos_gl_context_get_damage;
+1 -1
View File
@@ -219,7 +219,7 @@ gdk_deps = [
platform_gio_dep,
pangocairo_dep,
vulkan_dep,
libdrm_dep,
dmabuf_dep,
png_dep,
tiff_dep,
jpeg_dep,
+33 -47
View File
@@ -1795,7 +1795,7 @@ static TranslationEntry translations[] = {
{ FALSE, "org.gnome.desktop.wm.preferences", "action-middle-click-titlebar", "gtk-titlebar-middle-click", G_TYPE_STRING, { .s = "none" } },
{ FALSE, "org.gnome.desktop.wm.preferences", "action-right-click-titlebar", "gtk-titlebar-right-click", G_TYPE_STRING, { .s = "menu" } },
{ FALSE, "org.gnome.desktop.a11y", "always-show-text-caret", "gtk-keynav-use-caret", G_TYPE_BOOLEAN, { .b = FALSE } },
{ FALSE, "org.gnome.desktop.a11y.interface", "high-contrast", "high-contrast", G_TYPE_NONE, { .b = FALSE } },
{ FALSE, "org.gnome.desktop.a11y.interface", "high-contrast", "high-contast", G_TYPE_NONE, { .b = FALSE } },
{ FALSE, "org.gnome.desktop.a11y.interface", "show-status-shapes", "gtk-show-status-shapes", G_TYPE_BOOLEAN, { .b = FALSE } },
/* Note, this setting doesn't exist, the portal and gsd fake it */
{ FALSE, "org.gnome.fontconfig", "serial", "gtk-fontconfig-timestamp", G_TYPE_NONE, { .i = 0 } },
@@ -2430,47 +2430,15 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
{
GDK_DEBUG (MISC, "monitor %d changed position %d %d, size %d %d",
monitor->id,
monitor->output_geometry.x, monitor->output_geometry.y,
monitor->output_geometry.width, monitor->output_geometry.height);
monitor->x, monitor->y,
monitor->width, monitor->height);
GdkRectangle logical_geometry;
gboolean needs_scaling = FALSE;
double scale;
if (monitor->xdg_output_done)
{
logical_geometry = monitor->xdg_output_geometry;
needs_scaling =
logical_geometry.width == monitor->output_geometry.width ||
logical_geometry.height == monitor->output_geometry.height;
}
else
{
logical_geometry = monitor->output_geometry;
needs_scaling = TRUE;
}
if (needs_scaling)
{
int scale_factor = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
logical_geometry.y /= scale_factor;
logical_geometry.x /= scale_factor;
logical_geometry.width /= scale_factor;
logical_geometry.height /= scale_factor;
scale = scale_factor;
}
else
{
scale = MAX (monitor->output_geometry.width / (double) logical_geometry.width,
monitor->output_geometry.height / (double) logical_geometry.height);
}
gdk_monitor_set_geometry (GDK_MONITOR (monitor), &logical_geometry);
gdk_monitor_set_geometry (GDK_MONITOR (monitor),
&(GdkRectangle) {
monitor->x, monitor->y,
monitor->width, monitor->height });
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
gdk_monitor_set_description (GDK_MONITOR (monitor), monitor->description);
gdk_monitor_set_scale (GDK_MONITOR (monitor), scale);
monitor->wl_output_done = FALSE;
monitor->xdg_output_done = FALSE;
@@ -2488,8 +2456,8 @@ xdg_output_handle_logical_position (void *data,
GDK_DEBUG (MISC, "handle logical position xdg-output %d, position %d %d",
monitor->id, x, y);
monitor->xdg_output_geometry.x = x;
monitor->xdg_output_geometry.y = y;
monitor->x = x;
monitor->y = y;
}
static void
@@ -2503,8 +2471,8 @@ xdg_output_handle_logical_size (void *data,
GDK_DEBUG (MISC, "handle logical size xdg-output %d, size %d %d",
monitor->id, width, height);
monitor->xdg_output_geometry.width = width;
monitor->xdg_output_geometry.height = height;
monitor->width = width;
monitor->height = height;
}
static void
@@ -2590,8 +2558,8 @@ output_handle_geometry (void *data,
make, model,
transform_to_string (transform));
monitor->output_geometry.x = x;
monitor->output_geometry.y = y;
monitor->x = x;
monitor->y = y;
switch (transform)
{
@@ -2635,12 +2603,28 @@ output_handle_scale (void *data,
int32_t scale)
{
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
GdkRectangle previous_geometry;
int previous_scale;
int width;
int height;
GDK_DEBUG (MISC, "handle scale output %d, scale %d", monitor->id, scale);
gdk_monitor_get_geometry (GDK_MONITOR (monitor), &previous_geometry);
previous_scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
/* Set the scale from wl_output protocol, regardless of xdg-output support */
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), scale);
if (monitor_has_xdg_output (monitor))
return;
width = previous_geometry.width * previous_scale;
height = previous_geometry.height * previous_scale;
monitor->width = width / scale;
monitor->height = height / scale;
if (should_update_monitor (monitor))
apply_monitor_change (monitor);
}
@@ -2654,6 +2638,7 @@ output_handle_mode (void *data,
int refresh)
{
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
int scale;
GDK_DEBUG (MISC, "handle mode output %d, size %d %d, rate %d",
monitor->id, width, height, refresh);
@@ -2661,8 +2646,9 @@ output_handle_mode (void *data,
if ((flags & WL_OUTPUT_MODE_CURRENT) == 0)
return;
monitor->output_geometry.width = width;
monitor->output_geometry.height = height;
scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
monitor->width = width / scale;
monitor->height = height / scale;
gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh);
if (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))
+5 -4
View File
@@ -31,10 +31,11 @@ struct _GdkWaylandMonitor {
gboolean added;
struct zxdg_output_v1 *xdg_output;
/* Raw wl_output data */
GdkRectangle output_geometry;
/* Raw xdg_output data */
GdkRectangle xdg_output_geometry;
/* Size and position, can be either from wl_output or xdg_output */
int32_t x;
int32_t y;
int32_t width;
int32_t height;
char *name;
char *description;
gboolean wl_output_done;
+1 -4
View File
@@ -3629,10 +3629,7 @@ tablet_pad_handle_leave (void *data,
wp_tablet_pad, surface);
if (pad->current_tablet)
{
pad->current_tablet->pads = g_list_remove (pad->current_tablet->pads, pad);
pad->current_tablet = NULL;
}
pad->current_tablet->pads = g_list_remove (pad->current_tablet->pads, pad);
}
static void
+2 -1
View File
@@ -22,11 +22,12 @@ struct _GdkWaylandSubsurface
GdkTexture *texture;
cairo_rectangle_int_t dest;
graphene_rect_t source;
struct wl_region *opaque_region;
struct wl_callback *frame_callback;
gboolean above_parent;
};
struct _GdkWaylandSubsurfaceClass
+34 -46
View File
@@ -152,8 +152,7 @@ get_wl_buffer (GdkWaylandSubsurface *self,
static gboolean
gdk_wayland_subsurface_attach (GdkSubsurface *sub,
GdkTexture *texture,
const graphene_rect_t *source,
const graphene_rect_t *dest,
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling)
{
@@ -167,8 +166,8 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
graphene_rect_t device_rect;
cairo_rectangle_int_t device_dest;
if (sibling)
will_be_above = sibling->above_parent;
if (sib)
will_be_above = sib->above_parent;
else
will_be_above = above;
@@ -178,37 +177,30 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
return FALSE;
}
self->dest.x = dest->origin.x;
self->dest.y = dest->origin.y;
self->dest.width = dest->size.width;
self->dest.height = dest->size.height;
self->source.origin.x = source->origin.x;
self->source.origin.y = source->origin.y;
self->source.size.width = source->size.width;
self->source.size.height = source->size.height;
self->dest.x = rect->origin.x;
self->dest.y = rect->origin.y;
self->dest.width = rect->size.width;
self->dest.height = rect->size.height;
scale = gdk_fractional_scale_to_double (&parent->scale);
device_rect.origin.x = dest->origin.x * scale;
device_rect.origin.y = dest->origin.y * scale;
device_rect.size.width = dest->size.width * scale;
device_rect.size.height = dest->size.height * scale;
device_rect.origin.x = rect->origin.x * scale;
device_rect.origin.y = rect->origin.y * scale;
device_rect.size.width = rect->size.width * scale;
device_rect.size.height = rect->size.height * scale;
device_dest.x = device_rect.origin.x;
device_dest.y = device_rect.origin.y;
device_dest.width = device_rect.size.width;
device_dest.height = device_rect.size.height;
if (self->dest.x != dest->origin.x ||
self->dest.y != dest->origin.y ||
self->dest.width != dest->size.width ||
self->dest.height != dest->size.height)
if (self->dest.x != rect->origin.x ||
self->dest.y != rect->origin.y ||
self->dest.width != rect->size.width ||
self->dest.height != rect->size.height)
{
GDK_DISPLAY_DEBUG (gdk_surface_get_display (sub->parent), OFFLOAD,
"Non-integer coordinates %g %g %g %g for %dx%d texture, hiding subsurface %p",
dest->origin.x, dest->origin.y,
dest->size.width, dest->size.height,
rect->origin.x, rect->origin.y,
rect->size.width, rect->size.height,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
self);
@@ -304,11 +296,6 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
{
wl_subsurface_set_position (self->subsurface, self->dest.x, self->dest.y);
wp_viewport_set_destination (self->viewport, self->dest.width, self->dest.height);
wp_viewport_set_source (self->viewport,
wl_fixed_from_double (self->source.origin.x),
wl_fixed_from_double (self->source.origin.y),
wl_fixed_from_double (self->source.size.width),
wl_fixed_from_double (self->source.size.height));
if (buffer)
{
@@ -335,6 +322,8 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
wl_subsurface_place_above (self->subsurface, sib->surface);
else
wl_subsurface_place_below (self->subsurface, sib->surface);
self->above_parent = sib->above_parent;
}
else
{
@@ -344,6 +333,7 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
else
wl_subsurface_place_below (self->subsurface,
GDK_WAYLAND_SURFACE (sub->parent)->display_server.wl_surface);
self->above_parent = above;
}
wl_surface_commit (self->surface);
@@ -383,27 +373,23 @@ gdk_wayland_subsurface_get_texture (GdkSubsurface *sub)
}
static void
gdk_wayland_subsurface_get_dest (GdkSubsurface *sub,
graphene_rect_t *dest)
gdk_wayland_subsurface_get_rect (GdkSubsurface *sub,
graphene_rect_t *rect)
{
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
dest->origin.x = self->dest.x;
dest->origin.y = self->dest.y;
dest->size.width = self->dest.width;
dest->size.height = self->dest.height;
rect->origin.x = self->dest.x;
rect->origin.y = self->dest.y;
rect->size.width = self->dest.width;
rect->size.height = self->dest.height;
}
static void
gdk_wayland_subsurface_get_source (GdkSubsurface *sub,
graphene_rect_t *source)
static gboolean
gdk_wayland_subsurface_is_above_parent (GdkSubsurface *sub)
{
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
source->origin.x = self->source.origin.x;
source->origin.y = self->source.origin.y;
source->size.width = self->source.size.width;
source->size.height = self->source.size.height;
return self->above_parent;
}
static void
@@ -417,8 +403,8 @@ gdk_wayland_subsurface_class_init (GdkWaylandSubsurfaceClass *class)
subsurface_class->attach = gdk_wayland_subsurface_attach;
subsurface_class->detach = gdk_wayland_subsurface_detach;
subsurface_class->get_texture = gdk_wayland_subsurface_get_texture;
subsurface_class->get_source = gdk_wayland_subsurface_get_source;
subsurface_class->get_dest = gdk_wayland_subsurface_get_dest;
subsurface_class->get_rect = gdk_wayland_subsurface_get_rect;
subsurface_class->is_above_parent = gdk_wayland_subsurface_is_above_parent;
};
static void
@@ -492,6 +478,8 @@ gdk_wayland_surface_create_subsurface (GdkSurface *surface)
wl_region_add (sub->opaque_region, 0, 0, G_MAXINT, G_MAXINT);
wl_surface_set_opaque_region (sub->surface, sub->opaque_region);
sub->above_parent = TRUE;
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Subsurface %p of surface %p created", sub, impl);
return GDK_SUBSURFACE (sub);
+2 -5
View File
@@ -646,12 +646,9 @@ gdk_wayland_surface_sync_opaque_region (GdkSurface *surface)
cairo_region_t *region = cairo_region_copy (impl->opaque_region);
for (gsize i = 0; i < gdk_surface_get_n_subsurfaces (surface); i++)
{
GdkSubsurface *subsurface = gdk_surface_get_subsurface (surface, i);
GdkWaylandSubsurface *sub = (GdkWaylandSubsurface *) subsurface;
if (subsurface->above_parent)
GdkWaylandSubsurface *sub = (GdkWaylandSubsurface *)gdk_surface_get_subsurface (surface, i);
if (sub->above_parent)
continue;
if (sub->texture != NULL)
cairo_region_subtract_rectangle (region, &sub->dest);
}
-6
View File
@@ -153,11 +153,6 @@ gdk_win32_cairo_context_end_frame (GdkDrawContext *draw_context,
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
}
static void
gdk_win32_cairo_context_empty_frame (GdkDrawContext *draw_context)
{
}
static cairo_t *
gdk_win32_cairo_context_cairo_create (GdkCairoContext *context)
{
@@ -187,7 +182,6 @@ gdk_win32_cairo_context_class_init (GdkWin32CairoContextClass *klass)
draw_context_class->begin_frame = gdk_win32_cairo_context_begin_frame;
draw_context_class->end_frame = gdk_win32_cairo_context_end_frame;
draw_context_class->empty_frame = gdk_win32_cairo_context_empty_frame;
cairo_context_class->cairo_create = gdk_win32_cairo_context_cairo_create;
}
+10 -21
View File
@@ -892,11 +892,11 @@ pixbuf_to_hicon (GdkPixbuf *pixbuf,
int x,
int y);
HICON
_gdk_win32_create_hicon_for_texture (GdkTexture *texture,
gboolean is_icon,
int x,
int y)
static GdkWin32HCursor *
gdk_win32hcursor_create_for_texture (GdkWin32Display *display,
GdkTexture *texture,
int x,
int y)
{
cairo_surface_t *surface;
GdkPixbuf *pixbuf;
@@ -906,24 +906,13 @@ _gdk_win32_create_hicon_for_texture (GdkTexture *texture,
surface = gdk_texture_download_surface (texture);
width = cairo_image_surface_get_width (surface);
height = cairo_image_surface_get_height (surface);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
icon = pixbuf_to_hicon (pixbuf, is_icon, x, y);
icon = pixbuf_to_hicon (pixbuf, FALSE, x, y);
g_object_unref (pixbuf);
return icon;
}
static GdkWin32HCursor *
gdk_win32hcursor_create_for_texture (GdkWin32Display *display,
GdkTexture *texture,
int x,
int y)
{
HICON icon = _gdk_win32_create_hicon_for_texture (texture, FALSE, x, y);
return gdk_win32_hcursor_new (display, (HCURSOR) icon, TRUE);
}
-6
View File
@@ -117,11 +117,6 @@ gdk_win32_gl_context_egl_begin_frame (GdkDrawContext *draw_context,
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->begin_frame (draw_context, depth, update_area);
}
static void
gdk_win32_gl_context_egl_empty_frame (GdkDrawContext *draw_context)
{
}
static void
gdk_win32_gl_context_egl_class_init (GdkWin32GLContextClass *klass)
{
@@ -132,7 +127,6 @@ gdk_win32_gl_context_egl_class_init (GdkWin32GLContextClass *klass)
draw_context_class->begin_frame = gdk_win32_gl_context_egl_begin_frame;
draw_context_class->end_frame = gdk_win32_gl_context_egl_end_frame;
draw_context_class->empty_frame = gdk_win32_gl_context_egl_empty_frame;
}
static void
+4 -20
View File
@@ -116,11 +116,6 @@ gdk_win32_gl_context_wgl_end_frame (GdkDrawContext *draw_context,
SwapBuffers (hdc);
}
static void
gdk_win32_gl_context_wgl_empty_frame (GdkDrawContext *draw_context)
{
}
static void
gdk_win32_gl_context_wgl_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
@@ -131,7 +126,7 @@ gdk_win32_gl_context_wgl_begin_frame (GdkDrawContext *draw_context,
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_wgl_parent_class)->begin_frame (draw_context, depth, update_area);
}
#define PIXEL_ATTRIBUTES 21
#define PIXEL_ATTRIBUTES 17
static int
get_wgl_pfd (HDC hdc,
@@ -176,19 +171,10 @@ get_wgl_pfd (HDC hdc,
pixelAttribs[i++] = WGL_ALPHA_BITS_ARB;
pixelAttribs[i++] = 8;
pixelAttribs[i++] = WGL_DEPTH_BITS_ARB;
pixelAttribs[i++] = 0;
pixelAttribs[i++] = WGL_STENCIL_BITS_ARB;
pixelAttribs[i++] = 0;
pixelAttribs[i++] = WGL_ACCUM_BITS_ARB;
pixelAttribs[i++] = 0;
/* end of "Update PIXEL_ATTRIBUTES above if any groups are added here!" */
pixelAttribs[i++] = 0; /* end of pixelAttribs */
g_assert (i == PIXEL_ATTRIBUTES);
g_assert (i <= PIXEL_ATTRIBUTES);
if (!wglMakeCurrent (display_win32->dummy_context_wgl.hdc,
display_win32->dummy_context_wgl.hglrc))
@@ -214,7 +200,7 @@ get_wgl_pfd (HDC hdc,
pfd->iPixelType = PFD_TYPE_RGBA;
pfd->cColorBits = GetDeviceCaps (hdc, BITSPIXEL);
pfd->cAlphaBits = 8;
pfd->iLayerType = PFD_MAIN_PLANE;
pfd->dwLayerMask = PFD_MAIN_PLANE;
best_pf = ChoosePixelFormat (hdc, pfd);
}
@@ -613,7 +599,7 @@ set_wgl_pixformat_for_hdc (GdkWin32Display *display_win32,
{
gboolean skip_acquire = FALSE;
gboolean set_pixel_format_result = FALSE;
PIXELFORMATDESCRIPTOR pfd = {0};
PIXELFORMATDESCRIPTOR pfd;
/* one is only allowed to call SetPixelFormat(), and so ChoosePixelFormat()
* one single time per window HDC
@@ -823,8 +809,6 @@ gdk_win32_gl_context_wgl_class_init (GdkWin32GLContextWGLClass *klass)
draw_context_class->begin_frame = gdk_win32_gl_context_wgl_begin_frame;
draw_context_class->end_frame = gdk_win32_gl_context_wgl_end_frame;
draw_context_class->empty_frame = gdk_win32_gl_context_wgl_empty_frame;
gobject_class->dispose = gdk_win32_gl_context_wgl_dispose;
}
-5
View File
@@ -211,11 +211,6 @@ Win32Cursor * win32_cursor_theme_get_cursor (Win32CursorTheme *theme,
void win32_cursor_theme_destroy (Win32CursorTheme *theme);
Win32CursorTheme *_gdk_win32_display_get_cursor_theme (GdkWin32Display *win32_display);
HICON _gdk_win32_create_hicon_for_texture (GdkTexture *texture,
gboolean is_icon,
int x,
int y);
gboolean _gdk_win32_display_has_pending (GdkDisplay *display);
void _gdk_win32_display_queue_events (GdkDisplay *display);
-78
View File
@@ -4308,82 +4308,6 @@ gdk_win32_surface_set_shadow_width (GdkSurface *window,
impl->shadow_y = top + bottom;
}
static void
gdk_win32_surface_set_icon_list (GdkSurface *surface,
GList *textures)
{
GdkTexture *texture, *big_texture, *small_texture;
gint big_diff, small_diff;
gint big_w, big_h, small_w, small_h;
gint w, h;
gint dw, dh, diff;
HICON small_hicon, big_hicon;
GdkWin32Surface *impl;
if (GDK_SURFACE_DESTROYED (surface))
return;
impl = GDK_WIN32_SURFACE (surface);
/* ideal sizes for small and large icons */
big_w = GetSystemMetrics (SM_CXICON);
big_h = GetSystemMetrics (SM_CYICON);
small_w = GetSystemMetrics (SM_CXSMICON);
small_h = GetSystemMetrics (SM_CYSMICON);
/* find closest sized icons in the list */
big_texture = NULL;
small_texture = NULL;
big_diff = 0;
small_diff = 0;
while (textures)
{
texture = (GdkTexture*) textures->data;
w = gdk_texture_get_width (texture);
h = gdk_texture_get_height (texture);
dw = ABS (w - big_w);
dh = ABS (h - big_h);
diff = dw*dw + dh*dh;
if (big_texture == NULL || diff < big_diff)
{
big_texture = texture;
big_diff = diff;
}
dw = ABS (w - small_w);
dh = ABS (h - small_h);
diff = dw*dw + dh*dh;
if (small_texture == NULL || diff < small_diff)
{
small_texture = texture;
small_diff = diff;
}
textures = textures->next;
}
if (big_texture == NULL || small_texture == NULL)
return;
/* Create the icons */
big_hicon = big_texture ? _gdk_win32_create_hicon_for_texture (big_texture, TRUE, 0, 0) : NULL;
small_hicon = small_texture ? _gdk_win32_create_hicon_for_texture (small_texture, TRUE, 0, 0) : NULL;
/* Set the icons */
SendMessage (GDK_SURFACE_HWND (surface), WM_SETICON, ICON_BIG,
(LPARAM)big_hicon);
SendMessage (GDK_SURFACE_HWND (surface), WM_SETICON, ICON_SMALL,
(LPARAM)small_hicon);
/* Store the icons, destroying any previous icons */
if (impl->hicon_big)
GDI_CALL (DestroyIcon, (impl->hicon_big));
impl->hicon_big = big_hicon;
if (impl->hicon_small)
GDI_CALL (DestroyIcon, (impl->hicon_small));
impl->hicon_small = small_hicon;
}
double
_gdk_win32_surface_get_scale (GdkSurface *surface)
@@ -4814,8 +4738,6 @@ gdk_win32_toplevel_set_property (GObject *object,
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
gdk_win32_surface_set_icon_list (surface, g_value_get_pointer (value));
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_DECORATED:
-6
View File
@@ -74,11 +74,6 @@ gdk_win32_vulkan_context_begin_frame (GdkDrawContext *draw_context,
GDK_DRAW_CONTEXT_CLASS (gdk_win32_vulkan_context_parent_class)->begin_frame (draw_context, depth, update_area);
}
static void
gdk_win32_vulkan_context_empty_frame (GdkDrawContext *draw_context)
{
}
static void
gdk_win32_vulkan_context_class_init (GdkWin32VulkanContextClass *klass)
{
@@ -87,7 +82,6 @@ gdk_win32_vulkan_context_class_init (GdkWin32VulkanContextClass *klass)
context_class->create_surface = gdk_win32_vulkan_context_create_surface;
draw_context_class->begin_frame = gdk_win32_vulkan_context_begin_frame;
draw_context_class->empty_frame = gdk_win32_vulkan_context_empty_frame;
}
static void
+1 -4
View File
@@ -316,10 +316,7 @@ gdk_x11_gl_context_glx_get_damage (GdkGLContext *context)
for (i = 0; i < buffer_age - 1; i++)
{
if (context->old_updated_area[i] == NULL)
{
cairo_region_destroy (damage);
return GDK_GL_CONTEXT_CLASS (gdk_x11_gl_context_glx_parent_class)->get_damage (context);
}
return GDK_GL_CONTEXT_CLASS (gdk_x11_gl_context_glx_parent_class)->get_damage (context);
cairo_region_union (damage, context->old_updated_area[i]);
}
+1 -6
View File
@@ -2655,7 +2655,6 @@ gdk_x11_surface_get_geometry (GdkSurface *surface,
{
GdkX11Surface *impl;
Window root;
Window child;
int tx;
int ty;
guint twidth;
@@ -2670,11 +2669,7 @@ gdk_x11_surface_get_geometry (GdkSurface *surface,
XGetGeometry (GDK_SURFACE_XDISPLAY (surface),
GDK_SURFACE_XID (surface),
&root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
XTranslateCoordinates (GDK_SURFACE_XDISPLAY (surface),
GDK_SURFACE_XID (surface),
root, 0, 0, &tx, &ty, &child);
if (x)
*x = tx / impl->surface_scale;
if (y)
+2 -1
View File
@@ -1066,7 +1066,8 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
gsk_gl_profiler_begin_gpu_region (self->gl_profiler);
gsk_profiler_timer_begin (self->profiler, self->metrics.cpu_time);
glDisable (GL_DEPTH_TEST);
glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_LEQUAL);
/* Pre-multiplied alpha */
glEnable (GL_BLEND);
+2 -2
View File
@@ -4322,7 +4322,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
gsk_gl_render_job_push_modelview (job, transform);
gsk_transform_unref (transform);
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
gsk_rect_scale (&viewport, downscale_x, downscale_y, &viewport);
graphene_rect_scale (&viewport, downscale_x, downscale_y, &viewport);
}
if (downscale_x == 1)
@@ -4416,7 +4416,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
float scale_x = flipped_x ? - downscale_x : downscale_x;
float scale_y = flipped_y ? - downscale_y : downscale_y;
gsk_rect_scale (&job->current_clip->rect.bounds, scale_x, scale_y, &new_clip.bounds);
graphene_rect_scale (&job->current_clip->rect.bounds, scale_x, scale_y, &new_clip.bounds);
rounded_rect_scale_corners (&job->current_clip->rect, &new_clip, scale_x, scale_y);
gsk_gl_render_job_push_clip (job, &new_clip);
reset_clip = TRUE;
+1 -1
View File
@@ -242,7 +242,7 @@ gsk_gl_device_get_for_display (GdkDisplay *display,
if (!gdk_gl_context_check_version (context, "3.0", "3.0"))
{
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
_("OpenGL ES 3.0 is not supported by this renderer."));
_("OpenGL ES 2.0 is not supported by this renderer."));
return NULL;
}
+2 -1
View File
@@ -144,7 +144,8 @@ gsk_gl_frame_submit (GskGpuFrame *frame,
glEnable (GL_SCISSOR_TEST);
glDisable (GL_DEPTH_TEST);
glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_LEQUAL);
glEnable (GL_BLEND);
if (vertex_buffer)
-2
View File
@@ -195,8 +195,6 @@ gsk_gl_image_new_for_texture (GskGLDevice *device,
if (format != real_format)
flags = GSK_GPU_IMAGE_NO_BLIT |
(gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT ? GSK_GPU_IMAGE_STRAIGHT_ALPHA : 0);
else
flags &= ~(GSK_GPU_IMAGE_CAN_MIPMAP | GSK_GPU_IMAGE_MIPMAP);
gsk_gpu_image_setup (GSK_GPU_IMAGE (self),
flags | extra_flags,
-1
View File
@@ -28,7 +28,6 @@ gsk_gpu_blend_mode_op_print (GskGpuOp *op,
instance = (GskGpuBlendmodeInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "blend-mode");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_image_descriptor (string, shader->desc, instance->bottom_id);
gsk_gpu_print_enum (string, GSK_TYPE_BLEND_MODE, shader->variation);
-6
View File
@@ -36,9 +36,6 @@ gsk_gpu_blend_op_print (GskGpuOp *op,
case GSK_GPU_BLEND_ADD:
gsk_gpu_print_string (string, "add");
break;
case GSK_GPU_BLEND_CLEAR:
gsk_gpu_print_string (string, "clear");
break;
default:
g_assert_not_reached ();
break;
@@ -75,9 +72,6 @@ gsk_gpu_blend_op_gl_command (GskGpuOp *op,
case GSK_GPU_BLEND_ADD:
glBlendFunc (GL_ONE, GL_ONE);
break;
case GSK_GPU_BLEND_CLEAR:
glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
break;
default:
g_assert_not_reached ();
break;
+2
View File
@@ -85,6 +85,7 @@ gsk_gpu_blit_op_vk_command (GskGpuOp *op,
{
default:
g_assert_not_reached ();
G_GNUC_FALLTHROUGH;
case GSK_GPU_BLIT_LINEAR:
filter = VK_FILTER_LINEAR;
break;
@@ -159,6 +160,7 @@ gsk_gpu_blit_op_gl_command (GskGpuOp *op,
{
default:
g_assert_not_reached ();
G_GNUC_FALLTHROUGH;
case GSK_GPU_BLIT_LINEAR:
filter = GL_LINEAR;
break;
-2
View File
@@ -31,8 +31,6 @@ gsk_gpu_blur_op_print (GskGpuOp *op,
instance = (GskGpuBlurInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "blur");
gsk_gpu_print_shader_info (string, shader->clip);
g_string_append_printf (string, "%g,%g ", instance->blur_direction[0], instance->blur_direction[1]);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
gsk_gpu_print_newline (string);
-1
View File
@@ -36,7 +36,6 @@ gsk_gpu_border_op_print (GskGpuOp *op,
instance = (GskGpuBorderInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "border");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rounded_rect (string, instance->outline);
gsk_gpu_print_rgba (string, (const float *) &instance->border_colors[0]);
-1
View File
@@ -31,7 +31,6 @@ gsk_gpu_box_shadow_op_print (GskGpuOp *op,
instance = (GskGpuBoxshadowInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, shader->variation & VARIATION_INSET ? "inset-shadow" : "outset-shadow");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rounded_rect (string, instance->outline);
gsk_gpu_print_rgba (string, instance->color);
g_string_append_printf (string, "%g %g %g %g ",
-1
View File
@@ -27,7 +27,6 @@ gsk_gpu_colorize_op_print (GskGpuOp *op,
instance = (GskGpuColorizeInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "colorize");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
gsk_gpu_print_rgba (string, instance->color);
-1
View File
@@ -27,7 +27,6 @@ gsk_gpu_color_matrix_op_print (GskGpuOp *op,
instance = (GskGpuColormatrixInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "color-matrix");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
gsk_gpu_print_newline (string);
-1
View File
@@ -28,7 +28,6 @@ gsk_gpu_color_op_print (GskGpuOp *op,
instance = (GskGpuColorInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "color");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_rgba (string, instance->color);
gsk_gpu_print_newline (string);
-1
View File
@@ -29,7 +29,6 @@ gsk_gpu_conic_gradient_op_print (GskGpuOp *op,
instance = (GskGpuConicgradientInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "conic-gradient");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_newline (string);
}
-1
View File
@@ -27,7 +27,6 @@ gsk_gpu_cross_fade_op_print (GskGpuOp *op,
instance = (GskGpuCrossfadeInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "cross-fade");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_image_descriptor (string, shader->desc, instance->start_id);
gsk_gpu_print_image_descriptor (string, shader->desc, instance->end_id);
-6
View File
@@ -32,13 +32,7 @@ gsk_gpu_globals_op_print (GskGpuOp *op,
GString *string,
guint indent)
{
GskGpuGlobalsOp *globals = (GskGpuGlobalsOp *) op;
GskGpuGlobalsInstance *instance = &globals->instance;
gsk_gpu_print_op (string, indent, "globals");
g_string_append_printf (string, "scale %g %g ", instance->scale[0], instance->scale[1]);
g_string_append (string, "clip ");
gsk_gpu_print_rounded_rect (string, instance->clip);
gsk_gpu_print_newline (string);
}
-1
View File
@@ -33,7 +33,6 @@ gsk_gpu_linear_gradient_op_print (GskGpuOp *op,
gsk_gpu_print_op (string, indent, "repeating-linear-gradient");
else
gsk_gpu_print_op (string, indent, "linear-gradient");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_newline (string);
}
-1
View File
@@ -27,7 +27,6 @@ gsk_gpu_mask_op_print (GskGpuOp *op,
instance = (GskGpuMaskInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "mask");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_image_descriptor (string, shader->desc, instance->source_id);
gsk_gpu_print_image_descriptor (string, shader->desc, instance->mask_id);
+2 -2
View File
@@ -129,8 +129,8 @@ gsk_gpu_mipmap_op_vk_command (GskGpuOp *op,
.z = 0,
},
{
.x = MAX (1, width / 2),
.y = MAX (1, height / 2),
.x = width / 2,
.y = height / 2,
.z = 1,
}
},
+71 -115
View File
@@ -42,12 +42,6 @@
#include "gsktransformprivate.h"
#include "gdk/gdkrgbaprivate.h"
#include "gdk/gdksubsurfaceprivate.h"
/* the epsilon we allow pixels to be off due to rounding errors.
* Chosen rather randomly.
*/
#define EPSILON 0.001
/* A note about coordinate systems
*
@@ -344,8 +338,8 @@ gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self,
area.x = 0;
area.y = 0;
area.width = ceilf (graphene_vec2_get_x (scale) * viewport->size.width - EPSILON);
area.height = ceilf (graphene_vec2_get_y (scale) * viewport->size.height - EPSILON);
area.width = ceilf (graphene_vec2_get_x (scale) * viewport->size.width);
area.height = ceilf (graphene_vec2_get_y (scale) * viewport->size.height);
image = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame),
FALSE,
@@ -568,6 +562,7 @@ extract_scale_from_transform (GskTransform *transform,
{
default:
g_assert_not_reached ();
G_GNUC_FALLTHROUGH;
case GSK_TRANSFORM_CATEGORY_IDENTITY:
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
*out_scale_x = 1.0f;
@@ -738,30 +733,6 @@ gsk_gpu_node_processor_image_op (GskGpuNodeProcessor *self,
}
}
static GskGpuImage *
gsk_gpu_node_processor_create_offscreen (GskGpuFrame *frame,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
GskRenderNode *node)
{
GskGpuNodeProcessor self;
GskGpuImage *image;
image = gsk_gpu_node_processor_init_draw (&self,
frame,
gsk_render_node_get_preferred_depth (node),
scale,
viewport);
if (image == NULL)
return NULL;
gsk_gpu_node_processor_add_node (&self, node);
gsk_gpu_node_processor_finish_draw (&self, image);
return image;
}
/*
* gsk_gpu_get_node_as_image:
* @frame: frame to render in
@@ -791,6 +762,7 @@ gsk_gpu_get_node_as_image (GskGpuFrame *frame,
GskRenderNode *node,
graphene_rect_t *out_bounds)
{
graphene_rect_t clipped;
GskGpuImage *result;
switch ((guint) gsk_render_node_get_node_type (node))
@@ -813,29 +785,37 @@ gsk_gpu_get_node_as_image (GskGpuFrame *frame,
}
case GSK_CAIRO_NODE:
gsk_rect_intersection (clip_bounds, &node->bounds, &clipped);
if (gsk_rect_is_empty (&clipped))
return NULL;
result = gsk_gpu_upload_cairo_op (frame,
scale,
clip_bounds,
&clipped,
(GskGpuCairoFunc) gsk_render_node_draw_fallback,
gsk_render_node_ref (node),
(GDestroyNotify) gsk_render_node_unref);
g_object_ref (result);
*out_bounds = *clip_bounds;
*out_bounds = clipped;
return result;
default:
break;
}
GSK_DEBUG (FALLBACK, "Offscreening node '%s'", g_type_name_from_instance ((GTypeInstance *) node));
result = gsk_gpu_node_processor_create_offscreen (frame,
scale,
clip_bounds,
node);
gsk_rect_intersection (clip_bounds, &node->bounds, &clipped);
if (gsk_rect_is_empty (&clipped))
return NULL;
*out_bounds = *clip_bounds;
GSK_DEBUG (FALLBACK, "Offscreening node '%s'", g_type_name_from_instance ((GTypeInstance *) node));
result = gsk_gpu_render_pass_op_offscreen (frame,
scale,
&clipped,
node);
*out_bounds = clipped;
return result;
}
@@ -956,13 +936,9 @@ gsk_gpu_node_processor_get_node_as_image (GskGpuNodeProcessor *self,
{
if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clip))
return NULL;
clip_bounds = &clip;
}
else
{
if (!gsk_rect_intersection (clip_bounds, &node->bounds, &clip))
return NULL;
}
rect_round_to_pixels (&clip, &self->scale, &self->offset, &clip);
rect_round_to_pixels (clip_bounds, &self->scale, &self->offset, &clip);
image = gsk_gpu_get_node_as_image (self->frame,
&clip,
@@ -1007,25 +983,36 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
graphene_vec2_t direction;
graphene_rect_t clip_rect, intermediate_rect;
graphene_point_t real_offset;
int width, height;
float clip_radius;
clip_radius = gsk_cairo_blur_compute_pixels (blur_radius / 2.0);
/* FIXME: Handle clip radius growing the clip too much */
gsk_gpu_node_processor_get_clip_bounds (self, &clip_rect);
clip_rect.origin.x -= shadow_offset->x;
clip_rect.origin.y -= shadow_offset->y;
graphene_rect_inset (&clip_rect, 0.f, -clip_radius);
if (!gsk_rect_intersection (rect, &clip_rect, &intermediate_rect))
return;
rect_round_to_pixels (&intermediate_rect, &self->scale, &self->offset, &intermediate_rect);
width = ceilf (graphene_vec2_get_x (&self->scale) * intermediate_rect.size.width);
height = ceilf (graphene_vec2_get_y (&self->scale) * intermediate_rect.size.height);
intermediate = gsk_gpu_node_processor_init_draw (&other,
self->frame,
source_depth,
&self->scale,
&intermediate_rect);
intermediate = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (self->frame),
FALSE,
source_depth,
width, height);
gsk_gpu_node_processor_init (&other,
self->frame,
source_desc,
intermediate,
&(cairo_rectangle_int_t) { 0, 0, width, height },
&intermediate_rect);
gsk_gpu_render_pass_begin_op (other.frame,
intermediate,
&(cairo_rectangle_int_t) { 0, 0, width, height },
GSK_RENDER_PASS_OFFSCREEN);
gsk_gpu_node_processor_sync_globals (&other, 0);
@@ -1039,7 +1026,11 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
source_rect,
&direction);
gsk_gpu_node_processor_finish_draw (&other, intermediate);
gsk_gpu_render_pass_end_op (other.frame,
intermediate,
GSK_RENDER_PASS_OFFSCREEN);
gsk_gpu_node_processor_finish (&other);
real_offset = GRAPHENE_POINT_INIT (self->offset.x + shadow_offset->x,
self->offset.y + shadow_offset->y);
@@ -1327,8 +1318,7 @@ gsk_gpu_node_processor_add_node_clipped (GskGpuNodeProcessor *self,
gsk_gpu_clip_init_copy (&self->clip, &old_clip);
return;
}
else if (self->clip.type == GSK_GPU_CLIP_RECT &&
gsk_rect_contains_rect (&self->clip.rect.bounds, &clip))
else if (self->clip.type == GSK_GPU_CLIP_RECT)
{
self->clip.type = GSK_GPU_CLIP_NONE;
}
@@ -2062,21 +2052,13 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
GskGpuImage *offscreen;
graphene_rect_t clip_bounds;
gsk_gpu_node_processor_get_clip_bounds (self, &clip_bounds);
/* first round to pixel boundaries, so we make sure the full pixels are covered */
rect_round_to_pixels (&clip_bounds, &self->scale, &self->offset, &clip_bounds);
/* then expand by half a pixel so that pixels needed for eventual linear
* filtering are available */
graphene_rect_inset (&clip_bounds, -0.5, -0.5);
/* finally, round to full pixels */
gsk_rect_round_larger (&clip_bounds);
/* now intersect with actual node bounds */
if (!gsk_rect_intersection (&clip_bounds, &node->bounds, &clip_bounds))
if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clip_bounds))
return;
offscreen = gsk_gpu_node_processor_create_offscreen (self->frame,
graphene_vec2_one (),
&clip_bounds,
node);
gsk_rect_round_larger (&clip_bounds);
offscreen = gsk_gpu_render_pass_op_offscreen (self->frame,
graphene_vec2_one (),
&clip_bounds,
node);
descriptor = gsk_gpu_node_processor_add_image (self, offscreen, GSK_GPU_SAMPLER_DEFAULT);
gsk_gpu_texture_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
@@ -3269,10 +3251,10 @@ gsk_gpu_node_processor_repeat_tile (GskGpuNodeProcessor *self,
}
GSK_DEBUG (FALLBACK, "Offscreening node '%s' for tiling", g_type_name_from_instance ((GTypeInstance *) child));
image = gsk_gpu_node_processor_create_offscreen (self->frame,
&self->scale,
&clipped_child_bounds,
child);
image = gsk_gpu_render_pass_op_offscreen (self->frame,
&self->scale,
&clipped_child_bounds,
child);
g_return_if_fail (image);
@@ -3691,42 +3673,22 @@ gsk_gpu_node_processor_add_subsurface_node (GskGpuNodeProcessor *self,
if (!gdk_subsurface_is_above_parent (subsurface))
{
cairo_rectangle_int_t int_clipped;
graphene_rect_t rect, clipped;
cairo_rectangle_int_t int_rect;
graphene_rect_offset_r (&node->bounds,
self->offset.x, self->offset.y,
&rect);
gsk_rect_intersection (&self->clip.rect.bounds, &rect, &clipped);
if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_CLEAR) &&
node->bounds.size.width * node->bounds.size.height > 100 * 100 && /* not worth the effort for small images */
(self->clip.type != GSK_GPU_CLIP_ROUNDED ||
gsk_gpu_clip_contains_rect (&self->clip, &GRAPHENE_POINT_INIT(0,0), &clipped)) &&
gsk_gpu_node_processor_rect_is_integer (self, &clipped, &int_clipped))
if (!gsk_gpu_node_processor_rect_is_integer (self,
&GRAPHENE_RECT_INIT (
node->bounds.origin.x + self->offset.x,
node->bounds.origin.y + self->offset.y,
node->bounds.size.width,
node->bounds.size.height
),
&int_rect))
{
if (gdk_rectangle_intersect (&int_clipped, &self->scissor, &int_clipped))
{
gsk_gpu_clear_op (self->frame,
&int_clipped,
&GDK_RGBA_TRANSPARENT);
}
}
else
{
self->blend = GSK_GPU_BLEND_CLEAR;
self->pending_globals |= GSK_GPU_GLOBAL_BLEND;
gsk_gpu_node_processor_sync_globals (self, 0);
gsk_gpu_color_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
&node->bounds,
&self->offset,
&GDK_RGBA_WHITE);
self->blend = GSK_GPU_BLEND_OVER;
self->pending_globals |= GSK_GPU_GLOBAL_BLEND;
g_warning ("FIXME: non-integer aligned subsurface?!");
}
gsk_gpu_clear_op (self->frame,
&int_rect,
&GDK_RGBA_TRANSPARENT);
}
}
@@ -3745,12 +3707,6 @@ static void
gsk_gpu_node_processor_add_container_node (GskGpuNodeProcessor *self,
GskRenderNode *node)
{
if (self->opacity < 1.0 && !gsk_container_node_is_disjoint (node))
{
gsk_gpu_node_processor_add_without_opacity (self, node);
return;
}
for (guint i = 0; i < gsk_container_node_get_n_children (node); i++)
gsk_gpu_node_processor_add_node (self, gsk_container_node_get_child (node, i));
}
@@ -3790,7 +3746,7 @@ static const struct
},
[GSK_CONTAINER_NODE] = {
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR,
GSK_GPU_HANDLE_OPACITY,
0,
gsk_gpu_node_processor_add_container_node,
NULL,
},
-21
View File
@@ -12,27 +12,6 @@ gsk_gpu_print_indent (GString *string,
g_string_append_printf (string, "%*s", 2 * indent, "");
}
void
gsk_gpu_print_shader_info (GString *string,
GskGpuShaderClip clip)
{
switch (clip)
{
case GSK_GPU_SHADER_CLIP_NONE:
g_string_append (string, "🞨 ");
break;
case GSK_GPU_SHADER_CLIP_RECT:
g_string_append (string, "");
break;
case GSK_GPU_SHADER_CLIP_ROUNDED:
g_string_append (string, "");
break;
default:
g_assert_not_reached ();
break;
}
}
void
gsk_gpu_print_op (GString *string,
guint indent,
-2
View File
@@ -17,8 +17,6 @@ void gsk_gpu_print_newline (GString
void gsk_gpu_print_string (GString *string,
const char *s);
void gsk_gpu_print_shader_info (GString *string,
GskGpuShaderClip clip);
void gsk_gpu_print_enum (GString *string,
GType type,
int value);
-1
View File
@@ -33,7 +33,6 @@ gsk_gpu_radial_gradient_op_print (GskGpuOp *op,
gsk_gpu_print_op (string, indent, "repeating-radial-gradient");
else
gsk_gpu_print_op (string, indent, "radial-gradient");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_newline (string);
}
+4 -4
View File
@@ -391,7 +391,7 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
GskGpuFrame *frame;
GskGpuImage *backbuffer;
cairo_region_t *render_region;
double scale;
GdkSurface *surface;
if (cairo_region_is_empty (region))
{
@@ -411,7 +411,7 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
frame = gsk_gpu_renderer_get_frame (self);
render_region = get_render_region (self);
scale = gsk_gpu_renderer_get_scale (self);
surface = gdk_draw_context_get_surface (priv->context);
gsk_gpu_frame_render (frame,
g_get_monotonic_time (),
@@ -420,8 +420,8 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
root,
&GRAPHENE_RECT_INIT (
0, 0,
gsk_gpu_image_get_width (backbuffer) / scale,
gsk_gpu_image_get_height (backbuffer) / scale
gdk_surface_get_width (surface),
gdk_surface_get_height (surface)
),
NULL);
+36
View File
@@ -54,6 +54,7 @@ gsk_gpu_render_pass_type_to_vk_image_layout (GskRenderPassType type)
{
default:
g_assert_not_reached ();
G_GNUC_FALLTHROUGH;
case GSK_RENDER_PASS_PRESENT:
return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
case GSK_RENDER_PASS_OFFSCREEN:
@@ -332,3 +333,38 @@ gsk_gpu_render_pass_end_op (GskGpuFrame *frame,
self->target = g_object_ref (image);
self->pass_type = pass_type;
}
GskGpuImage *
gsk_gpu_render_pass_op_offscreen (GskGpuFrame *frame,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
GskRenderNode *node)
{
GskGpuImage *image;
int width, height;
width = ceil (graphene_vec2_get_x (scale) * viewport->size.width);
height = ceil (graphene_vec2_get_y (scale) * viewport->size.height);
image = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame),
FALSE,
gsk_render_node_get_preferred_depth (node),
width, height);
gsk_gpu_render_pass_begin_op (frame,
image,
&(cairo_rectangle_int_t) { 0, 0, width, height },
GSK_RENDER_PASS_OFFSCREEN);
gsk_gpu_node_processor_process (frame,
image,
&(cairo_rectangle_int_t) { 0, 0, width, height },
node,
viewport);
gsk_gpu_render_pass_end_op (frame,
image,
GSK_RENDER_PASS_OFFSCREEN);
return image;
}
+5
View File
@@ -23,5 +23,10 @@ void gsk_gpu_render_pass_end_op (GskGpuF
GskGpuImage *image,
GskRenderPassType pass_type);
GskGpuImage * gsk_gpu_render_pass_op_offscreen (GskGpuFrame *frame,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
GskRenderNode *node);
G_END_DECLS
-1
View File
@@ -28,7 +28,6 @@ gsk_gpu_rounded_color_op_print (GskGpuOp *op,
instance = (GskGpuRoundedcolorInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "rounded-color");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rounded_rect (string, instance->outline);
gsk_gpu_print_rgba (string, instance->color);
gsk_gpu_print_newline (string);
-1
View File
@@ -30,7 +30,6 @@ gsk_gpu_straight_alpha_op_print (GskGpuOp *op,
instance = (GskGpuStraightalphaInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "straight-alpha");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
gsk_gpu_print_newline (string);
-1
View File
@@ -27,7 +27,6 @@ gsk_gpu_texture_op_print (GskGpuOp *op,
instance = (GskGpuTextureInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "texture");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
gsk_gpu_print_newline (string);
+1 -2
View File
@@ -49,8 +49,7 @@ typedef enum {
typedef enum {
GSK_GPU_BLEND_OVER,
GSK_GPU_BLEND_ADD,
GSK_GPU_BLEND_CLEAR
GSK_GPU_BLEND_ADD
} GskGpuBlend;
typedef enum {
-1
View File
@@ -28,7 +28,6 @@ gsk_gpu_uber_op_print (GskGpuOp *op,
instance = (GskGpuUberInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
gsk_gpu_print_op (string, indent, "uber");
gsk_gpu_print_shader_info (string, shader->clip);
gsk_gpu_print_rect (string, instance->rect);
gsk_gpu_print_newline (string);
}
-11
View File
@@ -11,8 +11,6 @@
#include "gdk/gdkdisplayprivate.h"
#include "gdk/gdkglcontextprivate.h"
#include <glib/gi18n-lib.h>
struct _GskNglRenderer
{
GskGpuRenderer parent_instance;
@@ -55,15 +53,6 @@ gsk_ngl_renderer_create_context (GskGpuRenderer *renderer,
gdk_gl_context_make_current (context);
if (!gdk_gl_context_check_version (context, "3.3", "0.0"))
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("OpenGL 3.3 required"));
g_object_unref (context);
return NULL;
}
*supported = -1;
/* Shader compilation takes too long when texture() and get_float() calls
+1 -14
View File
@@ -892,7 +892,7 @@ struct _GskVulkanShaderSpecialization
guint32 variation;
};
static VkPipelineColorBlendAttachmentState blend_attachment_states[3] = {
static VkPipelineColorBlendAttachmentState blend_attachment_states[2] = {
[GSK_GPU_BLEND_OVER] = {
.blendEnable = VK_TRUE,
.colorBlendOp = VK_BLEND_OP_ADD,
@@ -919,19 +919,6 @@ static VkPipelineColorBlendAttachmentState blend_attachment_states[3] = {
| VK_COLOR_COMPONENT_G_BIT
| VK_COLOR_COMPONENT_B_BIT
},
[GSK_GPU_BLEND_CLEAR] = {
.blendEnable = VK_TRUE,
.colorBlendOp = VK_BLEND_OP_ADD,
.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO,
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.alphaBlendOp = VK_BLEND_OP_ADD,
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.colorWriteMask = VK_COLOR_COMPONENT_A_BIT
| VK_COLOR_COMPONENT_R_BIT
| VK_COLOR_COMPONENT_G_BIT
| VK_COLOR_COMPONENT_B_BIT
},
};
VkPipeline
+1 -1
View File
@@ -91,7 +91,7 @@ gsk_get_float (uint id)
#define gsk_get_int(id) (floatBitsToInt(gsk_get_float(id)))
#define gsk_get_uint(id) (floatBitsToUint(gsk_get_float(id)))
#if __VERSION__ < 400 || defined(GSK_GLES)
#ifdef GSK_GLES
vec4
gsk_texture (uint id,
+1 -1
View File
@@ -88,7 +88,7 @@ run (out vec2 pos)
vec4 border_widths = in_border_widths * GSK_GLOBAL_SCALE.yxyx;
RoundedRect outside = rounded_rect_from_gsk (in_outline);
RoundedRect inside = rounded_rect_shrink (outside, border_widths);
rounded_rect_offset (inside, in_offset * GSK_GLOBAL_SCALE);
rounded_rect_offset (inside, in_offset);
pos = border_get_position (outside, inside);
+60 -123
View File
@@ -58,12 +58,8 @@ struct _GskOffload
static GdkTexture *
find_texture_to_attach (GskOffload *self,
GdkSubsurface *subsurface,
const GskRenderNode *node,
graphene_rect_t *out_clip)
const GskRenderNode *node)
{
gboolean has_clip = FALSE;
graphene_rect_t clip;
for (;;)
{
switch ((int)GSK_RENDER_NODE_TYPE (node))
@@ -86,7 +82,6 @@ find_texture_to_attach (GskOffload *self,
case GSK_TRANSFORM_NODE:
{
GskTransform *t = gsk_transform_node_get_transform (node);
if (gsk_transform_get_category (t) < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
{
char *s = gsk_transform_to_string (t);
@@ -96,69 +91,12 @@ find_texture_to_attach (GskOffload *self,
g_free (s);
return NULL;
}
if (has_clip)
{
GskTransform *inv = gsk_transform_invert (gsk_transform_ref (t));
gsk_transform_transform_bounds (inv, &clip, &clip);
gsk_transform_unref (inv);
}
node = gsk_transform_node_get_child (node);
}
break;
case GSK_CLIP_NODE:
{
const graphene_rect_t *c = gsk_clip_node_get_clip (node);
if (has_clip)
{
if (!gsk_rect_intersection (c, &clip, &clip))
{
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
"Can't offload subsurface %p: empty clip", subsurface);
return NULL;
}
}
else
{
clip = *c;
has_clip = TRUE;
}
node = gsk_clip_node_get_child (node);
}
break;
break;
case GSK_TEXTURE_NODE:
{
GdkTexture *texture = gsk_texture_node_get_texture (node);
if (has_clip)
{
float dx = node->bounds.origin.x;
float dy = node->bounds.origin.y;
float sx = gdk_texture_get_width (texture) / node->bounds.size.width;
float sy = gdk_texture_get_height (texture) / node->bounds.size.height;
gsk_rect_intersection (&node->bounds, &clip, &clip);
out_clip->origin.x = (clip.origin.x - dx) * sx;
out_clip->origin.y = (clip.origin.y - dy) * sy;
out_clip->size.width = clip.size.width * sx;
out_clip->size.height = clip.size.height * sy;
}
else
{
out_clip->origin.x = 0;
out_clip->origin.y = 0;
out_clip->size.width = gdk_texture_get_width (texture);
out_clip->size.height = gdk_texture_get_height (texture);
}
return texture;
}
return gsk_texture_node_get_texture (node);
default:
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
@@ -203,8 +141,16 @@ transform_bounds (GskOffload *self,
graphene_rect_t *rect)
{
GskTransform *t = self->transforms ? self->transforms->data : NULL;
float sx, sy, dx, dy;
gsk_transform_transform_bounds (t, bounds, rect);
g_assert (gsk_transform_get_category (t) >= GSK_TRANSFORM_CATEGORY_2D_AFFINE);
gsk_transform_to_affine (t, &sx, &sy, &dx, &dy);
rect->origin.x = bounds->origin.x * sx + dx;
rect->origin.y = bounds->origin.y * sy + dy;
rect->size.width = bounds->size.width * sx;
rect->size.height = bounds->size.height * sy;
}
static inline void
@@ -314,8 +260,9 @@ interval_contains (float p1, float w1,
static gboolean
update_clip (GskOffload *self,
const graphene_rect_t *transformed_bounds)
const graphene_rect_t *bounds)
{
graphene_rect_t transformed_bounds;
gboolean no_clip = FALSE;
gboolean rect_clip = FALSE;
@@ -324,7 +271,9 @@ update_clip (GskOffload *self,
self->current_clip->is_complex)
return FALSE;
if (!gsk_rect_intersects (&self->current_clip->rect.bounds, transformed_bounds))
transform_bounds (self, bounds, &transformed_bounds);
if (!gsk_rect_intersects (&self->current_clip->rect.bounds, &transformed_bounds))
{
push_empty_clip (self);
return TRUE;
@@ -332,12 +281,12 @@ update_clip (GskOffload *self,
if (self->current_clip->is_rectilinear)
{
if (gsk_rect_contains_rect (&self->current_clip->rect.bounds, transformed_bounds))
if (gsk_rect_contains_rect (&self->current_clip->rect.bounds, &transformed_bounds))
no_clip = TRUE;
else
rect_clip = TRUE;
}
else if (gsk_rounded_rect_contains_rect (&self->current_clip->rect, transformed_bounds))
else if (gsk_rounded_rect_contains_rect (&self->current_clip->rect, &transformed_bounds))
{
no_clip = TRUE;
}
@@ -348,9 +297,9 @@ update_clip (GskOffload *self,
rounded_rect_get_inner (&self->current_clip->rect, &inner);
if (interval_contains (inner.origin.x, inner.size.width,
transformed_bounds->origin.x, transformed_bounds->size.width) ||
transformed_bounds.origin.x, transformed_bounds.size.width) ||
interval_contains (inner.origin.y, inner.size.height,
transformed_bounds->origin.y, transformed_bounds->size.height))
transformed_bounds.origin.y, transformed_bounds.size.height))
rect_clip = TRUE;
}
@@ -369,7 +318,7 @@ update_clip (GskOffload *self,
/* The clip gets simpler for this node */
gsk_rect_intersection (&self->current_clip->rect.bounds, transformed_bounds, &rect);
gsk_rect_intersection (&self->current_clip->rect.bounds, &transformed_bounds, &rect);
push_rect_clip (self, &GSK_ROUNDED_RECT_INIT_FROM_RECT (rect));
return TRUE;
}
@@ -396,9 +345,6 @@ visit_node (GskOffload *self,
GskRenderNode *node)
{
gboolean has_clip;
graphene_rect_t transformed_bounds;
transform_bounds (self, &node->bounds, &transformed_bounds);
for (gsize i = 0; i < self->n_subsurfaces; i++)
{
@@ -406,7 +352,10 @@ visit_node (GskOffload *self,
if (info->can_raise)
{
if (gsk_rect_intersects (&transformed_bounds, &info->dest))
graphene_rect_t transformed_bounds;
transform_bounds (self, &node->bounds, &transformed_bounds);
if (gsk_rect_intersects (&transformed_bounds, &info->rect))
{
GskRenderNodeType type = GSK_RENDER_NODE_TYPE (node);
@@ -426,7 +375,7 @@ visit_node (GskOffload *self,
}
}
has_clip = update_clip (self, &transformed_bounds);
has_clip = update_clip (self, &node->bounds);
switch (GSK_RENDER_NODE_TYPE (node))
{
@@ -534,9 +483,33 @@ complex_clip:
break;
case GSK_TRANSFORM_NODE:
push_transform (self, gsk_transform_node_get_transform (node));
visit_node (self, gsk_transform_node_get_child (node));
pop_transform (self);
{
GskTransform *transform = gsk_transform_node_get_transform (node);
const GskTransformCategory category = gsk_transform_get_category (transform);
switch (category)
{
case GSK_TRANSFORM_CATEGORY_IDENTITY:
visit_node (self, gsk_transform_node_get_child (node));
break;
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
push_transform (self, transform);
visit_node (self, gsk_transform_node_get_child (node));
pop_transform (self);
break;
case GSK_TRANSFORM_CATEGORY_2D:
case GSK_TRANSFORM_CATEGORY_3D:
case GSK_TRANSFORM_CATEGORY_ANY:
case GSK_TRANSFORM_CATEGORY_UNKNOWN:
break;
default:
g_assert_not_reached ();
}
}
break;
case GSK_CONTAINER_NODE:
@@ -566,24 +539,14 @@ complex_clip:
"Can't offload subsurface %p: clipped",
subsurface);
}
else if (self->transforms &&
gsk_transform_get_category ((GskTransform *)self->transforms->data) < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
{
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
"Can't offload subsurface %p: non-affine transform",
subsurface);
}
else
{
graphene_rect_t clip;
info->texture = find_texture_to_attach (self, subsurface, gsk_subsurface_node_get_child (node), &clip);
info->texture = find_texture_to_attach (self, subsurface, gsk_subsurface_node_get_child (node));
if (info->texture)
{
info->can_offload = TRUE;
info->can_raise = TRUE;
info->source = clip;
transform_bounds (self, &node->bounds, &info->dest);
transform_bounds (self, &node->bounds, &info->rect);
info->place_above = self->last_info ? self->last_info->subsurface : NULL;
self->last_info = info;
}
@@ -602,9 +565,8 @@ complex_clip:
}
GskOffload *
gsk_offload_new (GdkSurface *surface,
GskRenderNode *root,
cairo_region_t *diff)
gsk_offload_new (GdkSurface *surface,
GskRenderNode *root)
{
GdkDisplay *display = gdk_surface_get_display (surface);
GskOffload *self;
@@ -642,23 +604,18 @@ gsk_offload_new (GdkSurface *surface,
for (gsize i = 0; i < self->n_subsurfaces; i++)
{
GskOffloadInfo *info = &self->subsurfaces[i];
graphene_rect_t old_dest;
gdk_subsurface_get_dest (info->subsurface, &old_dest);
if (info->can_offload)
{
if (info->can_raise)
info->is_offloaded = gdk_subsurface_attach (info->subsurface,
info->texture,
&info->source,
&info->dest,
&info->rect,
TRUE, NULL);
else
info->is_offloaded = gdk_subsurface_attach (info->subsurface,
info->texture,
&info->source,
&info->dest,
&info->rect,
info->place_above != NULL,
info->place_above);
}
@@ -677,26 +634,6 @@ gsk_offload_new (GdkSurface *surface,
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Raising subsurface %p", info->subsurface);
info->is_above = TRUE;
}
if (info->is_offloaded != info->was_offloaded ||
info->is_above != info->was_above ||
(info->is_offloaded && !gsk_rect_equal (&info->dest, &old_dest)))
{
/* We changed things, need to invalidate everything */
cairo_rectangle_int_t int_dest;
if (info->is_offloaded)
{
gsk_rect_to_cairo_grow (&info->dest, &int_dest);
cairo_region_union_rectangle (diff, &int_dest);
}
if (info->was_offloaded)
{
gsk_rect_to_cairo_grow (&old_dest, &int_dest);
cairo_region_union_rectangle (diff, &int_dest);
}
}
}
return self;
+6 -8
View File
@@ -31,8 +31,7 @@ typedef struct
GdkSubsurface *subsurface;
GdkTexture *texture;
GdkSubsurface *place_above;
graphene_rect_t dest;
graphene_rect_t source;
graphene_rect_t rect;
guint was_offloaded : 1;
guint can_offload : 1;
@@ -43,10 +42,9 @@ typedef struct
guint is_above : 1;
} GskOffloadInfo;
GskOffload * gsk_offload_new (GdkSurface *surface,
GskRenderNode *root,
cairo_region_t *diff);
void gsk_offload_free (GskOffload *self);
GskOffload * gsk_offload_new (GdkSurface *surface,
GskRenderNode *root);
void gsk_offload_free (GskOffload *self);
GskOffloadInfo * gsk_offload_get_subsurface_info (GskOffload *self,
GdkSubsurface *subsurface);
GskOffloadInfo * gsk_offload_get_subsurface_info (GskOffload *self,
GdkSubsurface *subsurface);
-30
View File
@@ -101,16 +101,6 @@ gsk_rect_to_float (const graphene_rect_t *rect,
values[3] = rect->size.height;
}
static inline void
gsk_rect_to_cairo_grow (const graphene_rect_t *graphene,
cairo_rectangle_int_t *cairo)
{
cairo->x = floorf (graphene->origin.x);
cairo->y = floorf (graphene->origin.y);
cairo->width = ceilf (graphene->origin.x + graphene->size.width) - cairo->x;
cairo->height = ceilf (graphene->origin.y + graphene->size.height) - cairo->y;
}
static inline gboolean
gsk_rect_equal (const graphene_rect_t *r1,
const graphene_rect_t *r2)
@@ -159,23 +149,3 @@ gsk_rect_scale (const graphene_rect_t *r,
res->size.width = r->size.width * sx;
res->size.height = r->size.height * sy;
}
static inline void
gsk_rect_normalize (graphene_rect_t *r)
{
if (r->size.width < 0.f)
{
float size = fabsf (r->size.width);
r->origin.x -= size;
r->size.width = size;
}
if (r->size.height < 0.f)
{
float size = fabsf (r->size.height);
r->origin.y -= size;
r->size.height = size;
}
}
+9 -52
View File
@@ -46,8 +46,6 @@
#include "gl/gskglrenderer.h"
#include "gpu/gskvulkanrenderer.h"
#include "gdk/gdkvulkancontextprivate.h"
#include "gdk/gdkdisplayprivate.h"
#include <graphene-gobject.h>
#include <cairo-gobject.h>
@@ -486,26 +484,25 @@ gsk_renderer_render (GskRenderer *renderer,
renderer_class = GSK_RENDERER_GET_CLASS (renderer);
clip = cairo_region_copy (region);
if (renderer_class->supports_offload &&
!GSK_RENDERER_DEBUG_CHECK (renderer, OFFLOAD_DISABLE))
offload = gsk_offload_new (priv->surface, root, clip);
offload = gsk_offload_new (priv->surface, root);
else
offload = NULL;
if (region == NULL || priv->prev_node == NULL || GSK_RENDERER_DEBUG_CHECK (renderer, FULL_REDRAW))
{
cairo_region_union_rectangle (clip,
&(GdkRectangle) {
0, 0,
gdk_surface_get_width (priv->surface),
gdk_surface_get_height (priv->surface)
});
clip = cairo_region_create_rectangle (&(GdkRectangle) {
0, 0,
gdk_surface_get_width (priv->surface),
gdk_surface_get_height (priv->surface)
});
}
else
{
gsk_render_node_diff (priv->prev_node, root, &(GskDiffData) { clip, priv->surface });
clip = cairo_region_copy (region);
gsk_render_node_diff (priv->prev_node, root, clip, offload);
}
renderer_class->render (renderer, root, clip);
@@ -632,53 +629,16 @@ get_renderer_for_backend (GdkSurface *surface)
return G_TYPE_INVALID;
}
static gboolean
gl_software_rendering (GdkSurface *surface)
{
GdkDisplay *display = gdk_surface_get_display (surface);
GdkGLContext *context;
if (!gdk_display_prepare_gl (display, NULL))
return G_TYPE_INVALID;
context = gdk_display_get_gl_context (display);
gdk_gl_context_make_current (context);
return strstr ((const char *) glGetString (GL_RENDERER), "llvmpipe") != NULL;
}
static GType
get_renderer_for_gl (GdkSurface *surface)
{
if (gl_software_rendering (surface))
return G_TYPE_INVALID;
return gsk_ngl_renderer_get_type ();
}
#ifdef GDK_RENDERING_VULKAN
static gboolean
vulkan_software_rendering (GdkSurface *surface)
{
GdkDisplay *display = gdk_surface_get_display (surface);
VkPhysicalDeviceProperties props;
if (!gdk_display_init_vulkan (display, NULL))
return G_TYPE_INVALID;
vkGetPhysicalDeviceProperties (display->vk_physical_device, &props);
return props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU;
}
#endif
static GType
get_renderer_for_vulkan (GdkSurface *surface)
{
#ifdef GDK_RENDERING_VULKAN
if (vulkan_software_rendering (surface))
return G_TYPE_INVALID;
return GSK_TYPE_VULKAN_RENDERER;
#else
return G_TYPE_INVALID;
@@ -688,9 +648,6 @@ get_renderer_for_vulkan (GdkSurface *surface)
static GType
get_renderer_for_gles2 (GdkSurface *surface)
{
if (gl_software_rendering (surface))
return G_TYPE_INVALID;
return GSK_TYPE_GL_RENDERER;
}
+20 -2
View File
@@ -519,7 +519,8 @@ gsk_render_node_diff_impossible (GskRenderNode *node1,
* gsk_render_node_diff:
* @node1: a `GskRenderNode`
* @node2: the `GskRenderNode` to compare with
* @data: the diff data to use
* @region: a `cairo_region_t` to add the differences to
* @subsurfaces: (nullable): array to add offload info to
*
* Compares @node1 and @node2 trying to compute the minimal region of changes.
*
@@ -532,11 +533,28 @@ gsk_render_node_diff_impossible (GskRenderNode *node1,
*
* Note that the passed in @region may already contain previous results from
* previous node comparisons, so this function call will only add to it.
*
* If @subsurface_nodes is not `NULL`, then we treat subsurface nodes as
* identical if they refer to the same subsurface and have the same bounds.
* In this case, we collect subsurface nodes we see in @subsurface_nodes,
* for later updating of the attached textures.
*
* If @subsurface_area is not `NULL`, it will collect the full area of all
* subsurface nodes we meet.
*/
void
gsk_render_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region,
GskOffload *offload)
{
gsk_render_node_data_diff (node1, node2, &(GskDiffData) { region, offload });
}
void
gsk_render_node_data_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
if (node1 == node2)
return;
+156 -178
View File
@@ -31,6 +31,7 @@
#include "gskroundedrectprivate.h"
#include "gskstrokeprivate.h"
#include "gsktransformprivate.h"
#include "gskoffloadprivate.h"
#include "gdk/gdkmemoryformatprivate.h"
#include "gdk/gdkprivate.h"
@@ -108,6 +109,16 @@ gsk_cairo_rectangle_pixel_aligned (cairo_t *cr,
cairo_restore (cr);
}
static void
rectangle_init_from_graphene (cairo_rectangle_int_t *cairo,
const graphene_rect_t *graphene)
{
cairo->x = floorf (graphene->origin.x);
cairo->y = floorf (graphene->origin.y);
cairo->width = ceilf (graphene->origin.x + graphene->size.width) - cairo->x;
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)
@@ -164,9 +175,9 @@ gsk_color_node_draw (GskRenderNode *node,
}
static void
gsk_color_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_color_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskColorNode *self1 = (GskColorNode *) node1;
GskColorNode *self2 = (GskColorNode *) node2;
@@ -234,7 +245,6 @@ gsk_color_node_new (const GdkRGBA *rgba,
self->color = *rgba;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
return node;
}
@@ -321,9 +331,9 @@ gsk_linear_gradient_node_draw (GskRenderNode *node,
}
static void
gsk_linear_gradient_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_linear_gradient_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskLinearGradientNode *self1 = (GskLinearGradientNode *) node1;
GskLinearGradientNode *self2 = (GskLinearGradientNode *) node2;
@@ -421,7 +431,6 @@ gsk_linear_gradient_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
graphene_point_init_from_point (&self->start, start);
graphene_point_init_from_point (&self->end, end);
@@ -475,7 +484,6 @@ gsk_repeating_linear_gradient_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
graphene_point_init_from_point (&self->start, start);
graphene_point_init_from_point (&self->end, end);
@@ -652,9 +660,9 @@ gsk_radial_gradient_node_draw (GskRenderNode *node,
}
static void
gsk_radial_gradient_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_radial_gradient_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskRadialGradientNode *self1 = (GskRadialGradientNode *) node1;
GskRadialGradientNode *self2 = (GskRadialGradientNode *) node2;
@@ -768,7 +776,6 @@ gsk_radial_gradient_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
graphene_point_init_from_point (&self->center, center);
self->hradius = hradius;
@@ -838,7 +845,6 @@ gsk_repeating_radial_gradient_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
graphene_point_init_from_point (&self->center, center);
self->hradius = hradius;
@@ -1145,9 +1151,9 @@ gsk_conic_gradient_node_draw (GskRenderNode *node,
}
static void
gsk_conic_gradient_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_conic_gradient_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskConicGradientNode *self1 = (GskConicGradientNode *) node1;
GskConicGradientNode *self2 = (GskConicGradientNode *) node2;
@@ -1232,7 +1238,6 @@ gsk_conic_gradient_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
graphene_point_init_from_point (&self->center, center);
self->rotation = rotation;
@@ -1498,9 +1503,9 @@ gsk_border_node_draw (GskRenderNode *node,
}
static void
gsk_border_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_border_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskBorderNode *self1 = (GskBorderNode *) node1;
GskBorderNode *self2 = (GskBorderNode *) node2;
@@ -1789,9 +1794,9 @@ gsk_texture_node_draw (GskRenderNode *node,
}
static void
gsk_texture_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_texture_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskTextureNode *self1 = (GskTextureNode *) node1;
GskTextureNode *self2 = (GskTextureNode *) node2;
@@ -1878,7 +1883,6 @@ gsk_texture_node_new (GdkTexture *texture,
self->texture = g_object_ref (texture);
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
node->preferred_depth = gdk_memory_format_get_depth (gdk_texture_get_format (texture));
@@ -1976,9 +1980,9 @@ gsk_texture_scale_node_draw (GskRenderNode *node,
}
static void
gsk_texture_scale_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_texture_scale_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskTextureScaleNode *self1 = (GskTextureScaleNode *) node1;
GskTextureScaleNode *self2 = (GskTextureScaleNode *) node2;
@@ -2096,7 +2100,6 @@ gsk_texture_scale_node_new (GdkTexture *texture,
self->texture = g_object_ref (texture);
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
self->filter = filter;
node->preferred_depth = gdk_memory_format_get_depth (gdk_texture_get_format (texture));
@@ -2454,7 +2457,7 @@ gsk_inset_shadow_node_draw (GskRenderNode *node,
* We could remove the part of "box" where the blur doesn't
* reach, but computing that is a bit tricky since the
* rounded corners are on the "inside" of it. */
gsk_rect_to_cairo_grow (&clip_box.bounds, &r);
rectangle_init_from_graphene (&r, &clip_box.bounds);
remaining = cairo_region_create_rectangle (&r);
/* First do the corners of box */
@@ -2500,9 +2503,9 @@ gsk_inset_shadow_node_draw (GskRenderNode *node,
}
static void
gsk_inset_shadow_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_inset_shadow_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskInsetShadowNode *self1 = (GskInsetShadowNode *) node1;
GskInsetShadowNode *self2 = (GskInsetShadowNode *) node2;
@@ -2813,9 +2816,9 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
}
static void
gsk_outset_shadow_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_outset_shadow_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskOutsetShadowNode *self1 = (GskOutsetShadowNode *) node1;
GskOutsetShadowNode *self2 = (GskOutsetShadowNode *) node2;
@@ -3085,7 +3088,6 @@ gsk_cairo_node_new (const graphene_rect_t *bounds)
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
return node;
}
@@ -3194,26 +3196,27 @@ gsk_container_node_compare_func (gconstpointer elem1, gconstpointer elem2, gpoin
}
static GskDiffResult
gsk_container_node_keep_func (gconstpointer elem1, gconstpointer elem2, gpointer user_data)
gsk_container_node_keep_func (gconstpointer elem1, gconstpointer elem2, gpointer data)
{
GskDiffData *data = user_data;
gsk_render_node_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, data);
if (cairo_region_num_rectangles (data->region) > MAX_RECTS_IN_DIFF)
GskDiffData *gd = data;
gsk_render_node_data_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, gd);
if (cairo_region_num_rectangles (gd->region) > MAX_RECTS_IN_DIFF)
return GSK_DIFF_ABORTED;
return GSK_DIFF_OK;
}
static GskDiffResult
gsk_container_node_change_func (gconstpointer elem, gsize idx, gpointer user_data)
gsk_container_node_change_func (gconstpointer elem, gsize idx, gpointer data)
{
const GskRenderNode *node = elem;
GskDiffData *data = user_data;
GskDiffData *gd = data;
cairo_rectangle_int_t rect;
gsk_rect_to_cairo_grow (&node->bounds, &rect);
cairo_region_union_rectangle (data->region, &rect);
if (cairo_region_num_rectangles (data->region) > MAX_RECTS_IN_DIFF)
rectangle_init_from_graphene (&rect, &node->bounds);
cairo_region_union_rectangle (gd->region, &rect);
if (cairo_region_num_rectangles (gd->region) > MAX_RECTS_IN_DIFF)
return GSK_DIFF_ABORTED;
return GSK_DIFF_OK;
@@ -3250,9 +3253,9 @@ gsk_render_node_diff_multiple (GskRenderNode **nodes1,
}
void
gsk_container_node_diff_with (GskRenderNode *container,
GskRenderNode *other,
GskDiffData *data)
gsk_container_node_diff_with (GskRenderNode *container,
GskRenderNode *other,
GskDiffData *data)
{
GskContainerNode *self = (GskContainerNode *) container;
@@ -3267,9 +3270,9 @@ gsk_container_node_diff_with (GskRenderNode *container,
}
static void
gsk_container_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_container_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskContainerNode *self1 = (GskContainerNode *) node1;
GskContainerNode *self2 = (GskContainerNode *) node2;
@@ -3496,9 +3499,9 @@ gsk_transform_node_can_diff (const GskRenderNode *node1,
}
static void
gsk_transform_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_transform_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskTransformNode *self1 = (GskTransformNode *) node1;
GskTransformNode *self2 = (GskTransformNode *) node2;
@@ -3515,7 +3518,7 @@ gsk_transform_node_diff (GskRenderNode *node1,
switch (gsk_transform_get_category (self1->transform))
{
case GSK_TRANSFORM_CATEGORY_IDENTITY:
gsk_render_node_diff (self1->child, self2->child, data);
gsk_render_node_data_diff (self1->child, self2->child, data);
break;
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
@@ -3524,7 +3527,7 @@ gsk_transform_node_diff (GskRenderNode *node1,
float dx, dy;
gsk_transform_to_translate (self1->transform, &dx, &dy);
sub = cairo_region_create ();
gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface });
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload });
cairo_region_translate (sub, floorf (dx), floorf (dy));
if (floorf (dx) != dx)
{
@@ -3551,7 +3554,7 @@ gsk_transform_node_diff (GskRenderNode *node1,
float scale_x, scale_y, dx, dy;
gsk_transform_to_affine (self1->transform, &scale_x, &scale_y, &dx, &dy);
sub = cairo_region_create ();
gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface });
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload });
region_union_region_affine (data->region, sub, scale_x, scale_y, dx, dy);
cairo_region_destroy (sub);
}
@@ -3714,15 +3717,15 @@ gsk_opacity_node_draw (GskRenderNode *node,
}
static void
gsk_opacity_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_opacity_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskOpacityNode *self1 = (GskOpacityNode *) node1;
GskOpacityNode *self2 = (GskOpacityNode *) node2;
if (self1->opacity == self2->opacity)
gsk_render_node_diff (self1->child, self2->child, data);
gsk_render_node_data_diff (self1->child, self2->child, data);
else
gsk_render_node_diff_impossible (node1, node2, data);
}
@@ -3928,9 +3931,9 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
}
static void
gsk_color_matrix_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_color_matrix_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskColorMatrixNode *self1 = (GskColorMatrixNode *) node1;
GskColorMatrixNode *self2 = (GskColorMatrixNode *) node2;
@@ -3941,7 +3944,7 @@ gsk_color_matrix_node_diff (GskRenderNode *node1,
if (!graphene_matrix_equal_fast (&self1->color_matrix, &self2->color_matrix))
goto nope;
gsk_render_node_diff (self1->child, self2->child, data);
gsk_render_node_data_diff (self1->child, self2->child, data);
return;
nope:
@@ -4221,32 +4224,6 @@ gsk_repeat_node_draw (GskRenderNode *node,
}
}
static void
gsk_repeat_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskRepeatNode *self1 = (GskRepeatNode *) node1;
GskRepeatNode *self2 = (GskRepeatNode *) node2;
if (gsk_rect_equal (&node1->bounds, &node2->bounds) &&
gsk_rect_equal (&self1->child_bounds, &self2->child_bounds))
{
cairo_region_t *sub;
sub = cairo_region_create();
gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface });
if (cairo_region_is_empty (sub))
{
cairo_region_destroy (sub);
return;
}
cairo_region_destroy (sub);
}
gsk_render_node_diff_impossible (node1, node2, data);
}
static void
gsk_repeat_node_class_init (gpointer g_class,
gpointer class_data)
@@ -4257,7 +4234,6 @@ gsk_repeat_node_class_init (gpointer g_class,
node_class->finalize = gsk_repeat_node_finalize;
node_class->draw = gsk_repeat_node_draw;
node_class->diff = gsk_repeat_node_diff;
}
/**
@@ -4288,19 +4264,13 @@ gsk_repeat_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = TRUE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
self->child = gsk_render_node_ref (child);
if (child_bounds)
{
gsk_rect_init_from_rect (&self->child_bounds, child_bounds);
gsk_rect_normalize (&self->child_bounds);
}
gsk_rect_init_from_rect (&self->child_bounds, child_bounds);
else
{
gsk_rect_init_from_rect (&self->child_bounds, &child->bounds);
}
gsk_rect_init_from_rect (&self->child_bounds, &child->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
@@ -4383,9 +4353,9 @@ gsk_clip_node_draw (GskRenderNode *node,
}
static void
gsk_clip_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_clip_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskClipNode *self1 = (GskClipNode *) node1;
GskClipNode *self2 = (GskClipNode *) node2;
@@ -4396,8 +4366,8 @@ gsk_clip_node_diff (GskRenderNode *node1,
cairo_rectangle_int_t clip_rect;
sub = cairo_region_create();
gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface });
gsk_rect_to_cairo_grow (&self1->clip, &clip_rect);
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload });
rectangle_init_from_graphene (&clip_rect, &self1->clip);
cairo_region_intersect_rectangle (sub, &clip_rect);
cairo_region_union (data->region, sub);
cairo_region_destroy (sub);
@@ -4446,8 +4416,7 @@ gsk_clip_node_new (GskRenderNode *child,
node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
gsk_rect_init_from_rect (&self->clip, clip);
gsk_rect_normalize (&self->clip);
graphene_rect_normalize_r (clip, &self->clip);
gsk_rect_intersection (&self->clip, &child->bounds, &node->bounds);
@@ -4532,9 +4501,9 @@ gsk_rounded_clip_node_draw (GskRenderNode *node,
}
static void
gsk_rounded_clip_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_rounded_clip_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskRoundedClipNode *self1 = (GskRoundedClipNode *) node1;
GskRoundedClipNode *self2 = (GskRoundedClipNode *) node2;
@@ -4545,8 +4514,8 @@ gsk_rounded_clip_node_diff (GskRenderNode *node1,
cairo_rectangle_int_t clip_rect;
sub = cairo_region_create();
gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface });
gsk_rect_to_cairo_grow (&self1->clip.bounds, &clip_rect);
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload });
rectangle_init_from_graphene (&clip_rect, &self1->clip.bounds);
cairo_region_intersect_rectangle (sub, &clip_rect);
cairo_region_union (data->region, sub);
cairo_region_destroy (sub);
@@ -4702,9 +4671,9 @@ gsk_fill_node_draw (GskRenderNode *node,
}
static void
gsk_fill_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_fill_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskFillNode *self1 = (GskFillNode *) node1;
GskFillNode *self2 = (GskFillNode *) node2;
@@ -4715,8 +4684,8 @@ gsk_fill_node_diff (GskRenderNode *node1,
cairo_rectangle_int_t clip_rect;
sub = cairo_region_create();
gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface });
gsk_rect_to_cairo_grow (&node1->bounds, &clip_rect);
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload });
rectangle_init_from_graphene (&clip_rect, &node1->bounds);
cairo_region_intersect_rectangle (sub, &clip_rect);
cairo_region_union (data->region, sub);
cairo_region_destroy (sub);
@@ -4905,9 +4874,9 @@ gsk_stroke_node_draw (GskRenderNode *node,
}
static void
gsk_stroke_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_stroke_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskStrokeNode *self1 = (GskStrokeNode *) node1;
GskStrokeNode *self2 = (GskStrokeNode *) node2;
@@ -4919,8 +4888,8 @@ gsk_stroke_node_diff (GskRenderNode *node1,
cairo_rectangle_int_t clip_rect;
sub = cairo_region_create();
gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface });
gsk_rect_to_cairo_grow (&node1->bounds, &clip_rect);
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload });
rectangle_init_from_graphene (&clip_rect, &node1->bounds);
cairo_region_intersect_rectangle (sub, &clip_rect);
cairo_region_union (data->region, sub);
cairo_region_destroy (sub);
@@ -5122,9 +5091,9 @@ gsk_shadow_node_draw (GskRenderNode *node,
}
static void
gsk_shadow_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_shadow_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskShadowNode *self1 = (GskShadowNode *) node1;
GskShadowNode *self2 = (GskShadowNode *) node2;
@@ -5162,7 +5131,7 @@ gsk_shadow_node_diff (GskRenderNode *node1,
}
sub = cairo_region_create ();
gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface });
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload });
n = cairo_region_num_rectangles (sub);
for (i = 0; i < n; i++)
@@ -5398,17 +5367,17 @@ gsk_blend_node_draw (GskRenderNode *node,
}
static void
gsk_blend_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_blend_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskBlendNode *self1 = (GskBlendNode *) node1;
GskBlendNode *self2 = (GskBlendNode *) node2;
if (self1->blend_mode == self2->blend_mode)
{
gsk_render_node_diff (self1->top, self2->top, data);
gsk_render_node_diff (self1->bottom, self2->bottom, data);
gsk_render_node_data_diff (self1->top, self2->top, data);
gsk_render_node_data_diff (self1->bottom, self2->bottom, data);
}
else
{
@@ -5568,17 +5537,17 @@ gsk_cross_fade_node_draw (GskRenderNode *node,
}
static void
gsk_cross_fade_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_cross_fade_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskCrossFadeNode *self1 = (GskCrossFadeNode *) node1;
GskCrossFadeNode *self2 = (GskCrossFadeNode *) node2;
if (self1->progress == self2->progress)
{
gsk_render_node_diff (self1->start, self2->start, data);
gsk_render_node_diff (self1->end, self2->end, data);
gsk_render_node_data_diff (self1->start, self2->start, data);
gsk_render_node_data_diff (self1->end, self2->end, data);
return;
}
@@ -5741,9 +5710,9 @@ gsk_text_node_draw (GskRenderNode *node,
}
static void
gsk_text_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_text_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskTextNode *self1 = (GskTextNode *) node1;
GskTextNode *self2 = (GskTextNode *) node2;
@@ -5855,10 +5824,10 @@ gsk_text_node_new (PangoFont *font,
self->num_glyphs = n;
gsk_rect_init (&node->bounds,
offset->x + ink_rect.x,
offset->y + ink_rect.y,
ink_rect.width,
ink_rect.height);
offset->x + ink_rect.x - 1,
offset->y + ink_rect.y - 1,
ink_rect.width + 2,
ink_rect.height + 2);
return node;
}
@@ -6187,9 +6156,9 @@ gsk_blur_node_draw (GskRenderNode *node,
}
static void
gsk_blur_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_blur_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskBlurNode *self1 = (GskBlurNode *) node1;
GskBlurNode *self2 = (GskBlurNode *) node2;
@@ -6202,7 +6171,7 @@ gsk_blur_node_diff (GskRenderNode *node1,
clip_radius = ceil (gsk_cairo_blur_compute_pixels (self1->radius / 2.0));
sub = cairo_region_create ();
gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface });
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload });
n = cairo_region_num_rectangles (sub);
for (i = 0; i < n; i++)
@@ -6432,9 +6401,9 @@ gsk_mask_node_draw (GskRenderNode *node,
}
static void
gsk_mask_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_mask_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskMaskNode *self1 = (GskMaskNode *) node1;
GskMaskNode *self2 = (GskMaskNode *) node2;
@@ -6445,8 +6414,8 @@ gsk_mask_node_diff (GskRenderNode *node1,
return;
}
gsk_render_node_diff (self1->source, self2->source, data);
gsk_render_node_diff (self1->mask, self2->mask, data);
gsk_render_node_data_diff (self1->source, self2->source, data);
gsk_render_node_data_diff (self1->mask, self2->mask, data);
}
static void
@@ -6610,14 +6579,14 @@ gsk_debug_node_can_diff (const GskRenderNode *node1,
}
static void
gsk_debug_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_debug_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskDebugNode *self1 = (GskDebugNode *) node1;
GskDebugNode *self2 = (GskDebugNode *) node2;
gsk_render_node_diff (self1->child, self2->child, data);
gsk_render_node_data_diff (self1->child, self2->child, data);
}
static void
@@ -6746,9 +6715,9 @@ gsk_gl_shader_node_draw (GskRenderNode *node,
}
static void
gsk_gl_shader_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_gl_shader_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskGLShaderNode *self1 = (GskGLShaderNode *) node1;
GskGLShaderNode *self2 = (GskGLShaderNode *) node2;
@@ -6760,7 +6729,7 @@ gsk_gl_shader_node_diff (GskRenderNode *node1,
{
cairo_region_t *child_region = cairo_region_create();
for (guint i = 0; i < self1->n_children; i++)
gsk_render_node_diff (self1->children[i], self2->children[i], &(GskDiffData) { child_region, data->surface });
gsk_render_node_data_diff (self1->children[i], self2->children[i], &(GskDiffData) {child_region, data->offload });
if (!cairo_region_is_empty (child_region))
gsk_render_node_diff_impossible (node1, node2, data);
cairo_region_destroy (child_region);
@@ -6836,8 +6805,6 @@ gsk_gl_shader_node_new (GskGLShader *shader,
node->offscreen_for_opacity = TRUE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
self->shader = g_object_ref (shader);
self->args = g_bytes_ref (args);
@@ -6973,31 +6940,42 @@ gsk_subsurface_node_can_diff (const GskRenderNode *node1,
}
static void
gsk_subsurface_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
gsk_subsurface_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskSubsurfaceNode *self1 = (GskSubsurfaceNode *) node1;
GskSubsurfaceNode *self2 = (GskSubsurfaceNode *) node2;
GskOffloadInfo *info1, *info2;
if (self1->subsurface != self2->subsurface)
if (!data->offload)
{
gsk_render_node_data_diff (self1->child, self2->child, data);
return;
}
info1 = gsk_offload_get_subsurface_info (data->offload, self1->subsurface);
info2 = gsk_offload_get_subsurface_info (data->offload, self2->subsurface);
if (!info1 || !info2)
{
gsk_render_node_data_diff (self1->child, self2->child, data);
return;
}
if (info1->is_offloaded != info2->is_offloaded ||
info1->is_above != info2->is_above)
{
/* Shouldn't happen, can_diff() avoids this, but to be sure */
gsk_render_node_diff_impossible (node1, node2, data);
}
else if (self1->subsurface->parent != data->surface)
else if (info1->is_offloaded && !info1->is_above &&
!gsk_rect_equal (&info1->rect, &info2->rect))
{
/* The inspector case */
gsk_render_node_diff (self1->child, self2->child, data);
gsk_render_node_diff_impossible (node1, node2, data);
}
else if (self1->subsurface && gdk_subsurface_get_texture (self1->subsurface) != NULL)
else if (!info1->is_offloaded)
{
/* offloaded, no contents to compare */
}
else
{
/* not offloaded, diff the children */
gsk_render_node_diff (self1->child, self2->child, data);
gsk_render_node_data_diff (self1->child, self2->child, data);
}
}
+238 -61
View File
@@ -46,7 +46,9 @@
#include <cairo-script-interpreter.h>
#endif
#include <cairo-gobject.h>
#include <pango/pangocairo.h>
#ifdef HAVE_PANGOFT
#include <pango/pangofc-fontmap.h>
#endif
@@ -86,6 +88,39 @@ context_finish (Context *context)
g_clear_object (&context->fontmap);
}
static gboolean
parse_enum (GtkCssParser *parser,
GType type,
gpointer out_value)
{
GEnumClass *class;
GEnumValue *v;
char *enum_name;
enum_name = gtk_css_parser_consume_ident (parser);
if (enum_name == NULL)
return FALSE;
class = g_type_class_ref (type);
v = g_enum_get_value_by_nick (class, enum_name);
if (v == NULL)
{
gtk_css_parser_error_value (parser, "Unknown value \"%s\" for enum \"%s\"",
enum_name, g_type_name (type));
g_free (enum_name);
g_type_class_unref (class);
return FALSE;
}
*(int*)out_value = v->value;
g_free (enum_name);
g_type_class_unref (class);
return TRUE;
}
static gboolean
parse_rect (GtkCssParser *parser,
Context *context,
@@ -887,6 +922,77 @@ font_from_string (PangoFontMap *fontmap,
return font;
}
static double
font_get_dpi (PangoFont *font)
{
#ifdef HAVE_PANGOFT
if (PANGO_IS_FC_FONT (font))
{
FcPattern *pattern;
double dpi;
pattern = pango_fc_font_get_pattern (PANGO_FC_FONT (font));
if (FcPatternGetDouble (pattern, FC_DPI, 0, &dpi) == FcResultMatch)
return dpi;
}
#endif
/* FIXME, needs pango api */
return 96.0;
}
static PangoFont *
recreate_font_with_options (PangoFont *font,
cairo_hint_metrics_t hint_metrics,
cairo_hint_style_t hint_style,
cairo_antialias_t antialias,
double dpi)
{
PangoFontMap *fontmap;
PangoFontDescription *desc;
PangoContext *ctx;
cairo_scaled_font_t *sf;
cairo_font_options_t *options;
PangoFont *new_font;
options = cairo_font_options_create ();
sf = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font));
cairo_scaled_font_get_font_options (sf, options);
if (cairo_font_options_get_hint_metrics (options) == hint_metrics &&
cairo_font_options_get_hint_style (options) == hint_style &&
cairo_font_options_get_antialias (options) == antialias &&
font_get_dpi (font) == dpi)
{
cairo_font_options_destroy (options);
return font;
}
cairo_font_options_set_hint_metrics (options, hint_metrics);
cairo_font_options_set_hint_style (options, hint_style);
cairo_font_options_set_antialias (options, antialias);
desc = pango_font_describe (font);
fontmap = pango_font_get_font_map (font);
ctx = pango_font_map_create_context (fontmap);
pango_cairo_context_set_font_options (ctx, options);
pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (fontmap), dpi);
new_font = pango_font_map_load_font (fontmap, ctx, desc);
g_object_unref (ctx);
pango_font_description_free (desc);
cairo_font_options_destroy (options);
g_object_unref (font);
return new_font;
}
#define MIN_ASCII_GLYPH 32
#define MAX_ASCII_GLYPH 127 /* exclusive */
#define N_ASCII_GLYPHS (MAX_ASCII_GLYPH - MIN_ASCII_GLYPH)
@@ -2217,6 +2323,60 @@ unpack_glyphs (PangoFont *font,
return TRUE;
}
static gboolean
parse_hint_metrics (GtkCssParser *parser,
Context *context,
gpointer out)
{
if (!parse_enum (parser, CAIRO_GOBJECT_TYPE_HINT_METRICS, out))
return FALSE;
if (*(cairo_hint_metrics_t *) out == CAIRO_HINT_METRICS_DEFAULT)
{
gtk_css_parser_error_value (parser, "Unknown value \"default\" for enum \"%s\"",
g_type_name (CAIRO_GOBJECT_TYPE_HINT_METRICS));
return FALSE;
}
return TRUE;
}
static gboolean
parse_hint_style (GtkCssParser *parser,
Context *context,
gpointer out)
{
if (!parse_enum (parser, CAIRO_GOBJECT_TYPE_HINT_STYLE, out))
return FALSE;
if (*(cairo_hint_style_t *) out == CAIRO_HINT_STYLE_DEFAULT)
{
gtk_css_parser_error_value (parser, "Unknown value \"default\" for enum \"%s\"",
g_type_name (CAIRO_GOBJECT_TYPE_HINT_STYLE));
return FALSE;
}
return TRUE;
}
static gboolean
parse_antialias (GtkCssParser *parser,
Context *context,
gpointer out)
{
if (!parse_enum (parser, CAIRO_GOBJECT_TYPE_ANTIALIAS, out))
return FALSE;
if (*(cairo_antialias_t *) out == CAIRO_ANTIALIAS_DEFAULT)
{
gtk_css_parser_error_value (parser, "Unknown value \"default\" for enum \"%s\"",
g_type_name (CAIRO_GOBJECT_TYPE_ANTIALIAS));
return FALSE;
}
return TRUE;
}
static GskRenderNode *
parse_text_node (GtkCssParser *parser,
Context *context)
@@ -2225,11 +2385,19 @@ parse_text_node (GtkCssParser *parser,
graphene_point_t offset = GRAPHENE_POINT_INIT (0, 0);
GdkRGBA color = GDK_RGBA("000000");
PangoGlyphString *glyphs = NULL;
cairo_hint_metrics_t hint_metrics = CAIRO_HINT_METRICS_OFF;
cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_SLIGHT;
cairo_antialias_t antialias = CAIRO_ANTIALIAS_GRAY;
double dpi = 96.0;
const Declaration declarations[] = {
{ "font", parse_font, clear_font, &font },
{ "offset", parse_point, NULL, &offset },
{ "color", parse_color, NULL, &color },
{ "glyphs", parse_glyphs, clear_glyphs, &glyphs }
{ "glyphs", parse_glyphs, clear_glyphs, &glyphs },
{ "hint-metrics", parse_hint_metrics, NULL, &hint_metrics },
{ "hint-style", parse_hint_style, NULL, &hint_style },
{ "antialias", parse_antialias, NULL, &antialias },
{ "dpi", parse_positive_double, NULL, &dpi },
};
GskRenderNode *result;
@@ -2241,6 +2409,8 @@ parse_text_node (GtkCssParser *parser,
g_assert (font);
}
font = recreate_font_with_options (font, hint_metrics, hint_style, antialias, dpi);
if (!glyphs)
{
const char *text = "Hello";
@@ -2429,39 +2599,6 @@ clear_dash (gpointer inout_array)
g_clear_pointer ((GArray **) inout_array, g_array_unref);
}
static gboolean
parse_enum (GtkCssParser *parser,
GType type,
gpointer out_value)
{
GEnumClass *class;
GEnumValue *v;
char *enum_name;
enum_name = gtk_css_parser_consume_ident (parser);
if (enum_name == NULL)
return FALSE;
class = g_type_class_ref (type);
v = g_enum_get_value_by_nick (class, enum_name);
if (v == NULL)
{
gtk_css_parser_error_value (parser, "Unknown value \"%s\" for enum \"%s\"",
enum_name, g_type_name (type));
g_free (enum_name);
g_type_class_unref (class);
return FALSE;
}
*(int*)out_value = v->value;
g_free (enum_name);
g_type_class_unref (class);
return TRUE;
}
static gboolean
parse_fill_rule (GtkCssParser *parser,
Context *context,
@@ -3248,6 +3385,33 @@ append_string_param (Printer *p,
g_string_append_c (p->str, '\n');
}
static const char *
enum_to_nick (GType type,
int value)
{
GEnumClass *class;
GEnumValue *v;
class = g_type_class_ref (type);
v = g_enum_get_value (class, value);
g_type_class_unref (class);
return v->value_nick;
}
static void
append_enum_param (Printer *p,
const char *param_name,
GType type,
int value)
{
_indent (p);
g_string_append_printf (p->str, "%s: ", param_name);
g_string_append (p->str, enum_to_nick (type, value));
g_string_append_c (p->str, ';');
g_string_append_c (p->str, '\n');
}
static void
append_vec4_param (Printer *p,
const char *param_name,
@@ -3515,6 +3679,43 @@ gsk_text_node_serialize_font (GskRenderNode *node,
#endif
}
static void
gsk_text_node_serialize_font_options (GskRenderNode *node,
Printer *p)
{
PangoFont *font = gsk_text_node_get_font (node);
cairo_scaled_font_t *sf = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font));
cairo_font_options_t *options;
cairo_hint_metrics_t hint_metrics;
cairo_hint_style_t hint_style;
cairo_antialias_t antialias;
options = cairo_font_options_create ();
cairo_scaled_font_get_font_options (sf, options);
hint_metrics = cairo_font_options_get_hint_metrics (options);
hint_style = cairo_font_options_get_hint_style (options);
antialias = cairo_font_options_get_antialias (options);
cairo_font_options_destroy (options);
if (hint_metrics != CAIRO_HINT_METRICS_OFF && hint_metrics != CAIRO_HINT_METRICS_DEFAULT)
append_enum_param (p, "hint-metrics", CAIRO_GOBJECT_TYPE_HINT_METRICS, hint_metrics);
if (hint_style != CAIRO_HINT_STYLE_SLIGHT && hint_style != CAIRO_HINT_STYLE_DEFAULT)
append_enum_param (p, "hint-style", CAIRO_GOBJECT_TYPE_HINT_STYLE, hint_style);
if (antialias != CAIRO_ANTIALIAS_GRAY && antialias != CAIRO_ANTIALIAS_DEFAULT)
append_enum_param (p, "antialias", CAIRO_GOBJECT_TYPE_ANTIALIAS, antialias);
}
static void
gsk_text_node_serialize_font_dpi (GskRenderNode *node,
Printer *p)
{
PangoFont *font = gsk_text_node_get_font (node);
append_float_param (p, "dpi", font_get_dpi (font), 96.f);
}
void
gsk_text_node_serialize_glyphs (GskRenderNode *node,
GString *p)
@@ -3596,33 +3797,6 @@ gsk_text_node_serialize_glyphs (GskRenderNode *node,
pango_glyph_string_free (ascii);
}
static const char *
enum_to_nick (GType type,
int value)
{
GEnumClass *class;
GEnumValue *v;
class = g_type_class_ref (type);
v = g_enum_get_value (class, value);
g_type_class_unref (class);
return v->value_nick;
}
static void
append_enum_param (Printer *p,
const char *param_name,
GType type,
int value)
{
_indent (p);
g_string_append_printf (p->str, "%s: ", param_name);
g_string_append (p->str, enum_to_nick (type, value));
g_string_append_c (p->str, ';');
g_string_append_c (p->str, '\n');
}
static void
append_path_param (Printer *p,
const char *param_name,
@@ -4087,6 +4261,9 @@ render_node_print (Printer *p,
if (!graphene_point_equal (offset, graphene_point_zero ()))
append_point_param (p, "offset", offset);
gsk_text_node_serialize_font_options (node, p);
gsk_text_node_serialize_font_dpi (node, p);
end_node (p);
}
break;
+6 -1
View File
@@ -1,6 +1,7 @@
#pragma once
#include "gskrendernode.h"
#include "gskoffloadprivate.h"
#include <cairo.h>
#include "gdk/gdkmemoryformatprivate.h"
@@ -39,7 +40,7 @@ struct _GskRenderNode
typedef struct
{
cairo_region_t *region;
GdkSurface *surface;
GskOffload *offload;
} GskDiffData;
struct _GskRenderNodeClass
@@ -71,6 +72,10 @@ void _gsk_render_node_unref (GskRenderNode
gboolean gsk_render_node_can_diff (const GskRenderNode *node1,
const GskRenderNode *node2) G_GNUC_PURE;
void gsk_render_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
cairo_region_t *region,
GskOffload *offload);
void gsk_render_node_data_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data);
void gsk_render_node_diff_impossible (GskRenderNode *node1,
+6 -23
View File
@@ -308,7 +308,7 @@ gsk_rounded_rect_scale_affine (GskRoundedRect *dest,
g_assert (dest != src);
gsk_rect_scale (&src->bounds, scale_x, scale_y, &dest->bounds);
graphene_rect_scale (&src->bounds, scale_x, scale_y, &dest->bounds);
graphene_rect_offset (&dest->bounds, dx, dy);
scale_x = fabsf (scale_x);
@@ -584,7 +584,7 @@ gsk_rounded_rect_intersect_with_rect (const GskRoundedRect *self,
const graphene_rect_t *rect,
GskRoundedRect *result)
{
int px, py, qx, qy, rx, ry;
int px, py, qx, qy;
if (!gsk_rect_intersection (&self->bounds, rect, &result->bounds))
return GSK_INTERSECTION_EMPTY;
@@ -599,11 +599,7 @@ gsk_rounded_rect_intersect_with_rect (const GskRoundedRect *self,
return GSK_INTERSECTION_EMPTY;
else if (qx == INNER && qy == INNER &&
gsk_rounded_rect_locate_point (self, &rect_point2 (rect)) != INSIDE)
{
classify_point (&rect_point2 (rect), &rounded_rect_corner2 (self), &rx, &ry);
if (rx == BELOW || ry == BELOW)
return GSK_INTERSECTION_EMPTY;
}
return GSK_INTERSECTION_EMPTY;
else if (qx == ABOVE && qy == ABOVE)
result->corner[0] = self->corner[0];
else
@@ -630,11 +626,7 @@ gsk_rounded_rect_intersect_with_rect (const GskRoundedRect *self,
return GSK_INTERSECTION_EMPTY;
else if (qx == INNER && qy == INNER &&
gsk_rounded_rect_locate_point (self, &rect_point3 (rect)) != INSIDE)
{
classify_point (&rect_point3 (rect), &rounded_rect_corner3 (self), &rx, &ry);
if (rx == ABOVE || ry == BELOW)
return GSK_INTERSECTION_EMPTY;
}
return GSK_INTERSECTION_EMPTY;
else if (qx == BELOW && qy == ABOVE)
result->corner[1] = self->corner[1];
else
@@ -661,12 +653,7 @@ gsk_rounded_rect_intersect_with_rect (const GskRoundedRect *self,
return GSK_INTERSECTION_EMPTY;
else if (qx == INNER && qy == INNER &&
gsk_rounded_rect_locate_point (self, &rect_point0 (rect)) != INSIDE)
{
classify_point (&rect_point2 (rect), &rounded_rect_corner0 (self), &rx, &ry);
if (rx == ABOVE || ry == ABOVE)
return GSK_INTERSECTION_EMPTY;
}
return GSK_INTERSECTION_EMPTY;
else if (qx == BELOW && qy == BELOW)
result->corner[2] = self->corner[2];
else
@@ -693,11 +680,7 @@ gsk_rounded_rect_intersect_with_rect (const GskRoundedRect *self,
return GSK_INTERSECTION_EMPTY;
else if (qx == INNER && qy == INNER &&
gsk_rounded_rect_locate_point (self, &rect_point1 (rect)) != INSIDE)
{
classify_point (&rect_point1 (rect), &rounded_rect_corner1 (self), &rx, &ry);
if (rx == BELOW || ry == ABOVE)
return GSK_INTERSECTION_EMPTY;
}
return GSK_INTERSECTION_EMPTY;
else if (qx == ABOVE && qy == BELOW)
result->corner[3] = self->corner[3];
else
+7 -27
View File
@@ -382,35 +382,15 @@ gsk_matrix_transform_print (GskTransform *transform,
guint i;
float f[16];
if (transform->category >= GSK_TRANSFORM_CATEGORY_2D)
g_string_append (string, "matrix3d(");
graphene_matrix_to_float (&self->matrix, f);
for (i = 0; i < 16; i++)
{
g_string_append (string, "matrix(");
graphene_matrix_to_float (&self->matrix, f);
string_append_double (string, f[0]);
g_string_append (string, ", ");
string_append_double (string, f[1]);
g_string_append (string, ", ");
string_append_double (string, f[4]);
g_string_append (string, ", ");
string_append_double (string, f[5]);
g_string_append (string, ", ");
string_append_double (string, f[12]);
g_string_append (string, ", ");
string_append_double (string, f[13]);
g_string_append (string, ")");
}
else
{
g_string_append (string, "matrix3d(");
graphene_matrix_to_float (&self->matrix, f);
for (i = 0; i < 16; i++)
{
if (i > 0)
g_string_append (string, ", ");
string_append_double (string, f[i]);
}
g_string_append (string, ")");
if (i > 0)
g_string_append (string, ", ");
string_append_double (string, f[i]);
}
g_string_append (string, ")");
}
static GskTransform *
+76 -156
View File
@@ -25,158 +25,89 @@
#include "gtkatspicontextprivate.h"
#include "gtkatspiprivate.h"
#include "gtkatspiutilsprivate.h"
#include "gtkatspisocket.h"
#include "gtkaccessibleprivate.h"
#include "gtkpopover.h"
#include "gtkwidget.h"
#include "gtkwindow.h"
#include "a11y/atspi/atspi-component.h"
static GtkAccessible *
find_first_accessible_non_socket (GtkAccessible *accessible)
{
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
#include "gtkdebug.h"
while (parent != NULL)
{
g_object_unref (parent);
if (!GTK_IS_AT_SPI_SOCKET (parent))
return parent;
parent = gtk_accessible_get_accessible_parent (parent);
}
return NULL;
}
#include <gio/gio.h>
static void
translate_coordinates_to_accessible (GtkAccessible *accessible,
AtspiCoordType coordtype,
int xi,
int yi,
int *xo,
int *yo)
translate_coordinates_to_widget (GtkWidget *widget,
AtspiCoordType coordtype,
int xi,
int yi,
int *xo,
int *yo)
{
GtkAccessible *parent;
int x, y, width, height;
graphene_point_t p;
GtkWidget *source;
if (coordtype == ATSPI_COORD_TYPE_SCREEN)
switch (coordtype)
{
case ATSPI_COORD_TYPE_SCREEN:
*xo = 0;
*yo = 0;
return;
case ATSPI_COORD_TYPE_WINDOW:
source = GTK_WIDGET (gtk_widget_get_root (widget));
break;
case ATSPI_COORD_TYPE_PARENT:
source = gtk_widget_get_parent (widget);
break;
default:
g_assert_not_reached ();
}
if (!gtk_accessible_get_bounds (accessible, &x, &y, &width, &height))
{
*xo = xi;
*yo = yi;
return;
}
if (!gtk_widget_compute_point (source, widget, &GRAPHENE_POINT_INIT (xi, yi), &p))
graphene_point_init (&p, xi, yi);
// Transform coords to our parent, we will need that in any case
*xo = xi - x;
*yo = yi - y;
// If that's what the caller requested, we're done
if (coordtype == ATSPI_COORD_TYPE_PARENT)
return;
if (coordtype == ATSPI_COORD_TYPE_WINDOW)
{
parent = gtk_accessible_get_accessible_parent (accessible);
while (parent != NULL)
{
if (gtk_accessible_get_bounds (parent, &x, &y, &width, &height))
{
*xo = *xo - x;
*yo = *yo - y;
parent = gtk_accessible_get_accessible_parent (parent);
}
else
break;
}
}
else
g_assert_not_reached ();
*xo = (int)p.x;
*yo = (int)p.y;
}
static void
translate_coordinates_from_accessible (GtkAccessible *accessible,
AtspiCoordType coordtype,
int xi,
int yi,
int *xo,
int *yo)
translate_coordinates_from_widget (GtkWidget *widget,
AtspiCoordType coordtype,
int xi,
int yi,
int *xo,
int *yo)
{
GtkAccessible *parent;
int x, y, width, height;
graphene_point_t p;
GtkWidget *target;
if (coordtype == ATSPI_COORD_TYPE_SCREEN)
switch (coordtype)
{
case ATSPI_COORD_TYPE_SCREEN:
*xo = 0;
*yo = 0;
return;
case ATSPI_COORD_TYPE_WINDOW:
target = GTK_WIDGET (gtk_widget_get_root (widget));
break;
case ATSPI_COORD_TYPE_PARENT:
target = gtk_widget_get_parent (widget);
break;
default:
g_assert_not_reached ();
}
if (!gtk_accessible_get_bounds (accessible, &x, &y, &width, &height))
{
*xo = xi;
*yo = yi;
return;
}
if (!gtk_widget_compute_point (widget, target, &GRAPHENE_POINT_INIT (xi, yi), &p))
graphene_point_init (&p, xi, yi);
// Transform coords to our parent, we will need that in any case
*xo = xi + x;
*yo = yi + y;
// If that's what the caller requested, we're done
if (coordtype == ATSPI_COORD_TYPE_PARENT)
return;
if (coordtype == ATSPI_COORD_TYPE_WINDOW)
{
parent = gtk_accessible_get_accessible_parent (accessible);
while (parent != NULL)
{
if (gtk_accessible_get_bounds (parent, &x, &y, &width, &height))
{
*xo = *xo + x;
*yo = *yo + y;
parent = gtk_accessible_get_accessible_parent (parent);
}
else
break;
}
}
else
g_assert_not_reached ();
}
static GtkAccessible *
accessible_at_point (GtkAccessible *parent,
int x,
int y,
bool children_only)
{
GtkAccessible *result = NULL;
int px, py, width, height;
if (!gtk_accessible_get_bounds (parent, &px, &py, &width, &height))
return NULL;
if (!children_only && x >= px && x <= px + width && y >= py && y <= py + height)
result = parent;
for (GtkAccessible *child = gtk_accessible_get_first_accessible_child (parent);
child != NULL;
child = gtk_accessible_get_next_accessible_sibling (child))
{
GtkAccessible *found = accessible_at_point (child, x - px, y - py, FALSE);
if (found)
result = found;
}
return result;
*xo = (int)p.x;
*yo = (int)p.y;
}
static void
@@ -191,51 +122,41 @@ component_handle_method (GDBusConnection *connection,
{
GtkATContext *self = user_data;
GtkAccessible *accessible = gtk_at_context_get_accessible (self);
if (GTK_IS_AT_SPI_SOCKET (accessible))
accessible = find_first_accessible_non_socket (accessible);
GtkWidget *widget = GTK_WIDGET (accessible);
if (g_strcmp0 (method_name, "Contains") == 0)
{
int x, y;
int bounds_x, bounds_y, width, height;
AtspiCoordType coordtype;
gboolean ret;
g_variant_get (parameters, "(iiu)", &x, &y, &coordtype);
translate_coordinates_to_accessible (accessible, coordtype, x, y, &x, &y);
if (gtk_accessible_get_bounds (accessible, &bounds_x, &bounds_y, &width, &height))
ret = x >= 0 && x <= bounds_x && y >= 0 && y <= bounds_y;
else
ret = FALSE;
translate_coordinates_to_widget (widget, coordtype, x, y, &x, &y);
ret = gtk_widget_contains (widget, x, y);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
}
else if (g_strcmp0 (method_name, "GetAccessibleAtPoint") == 0)
{
int x, y;
AtspiCoordType coordtype;
GtkAccessible *child;
GtkWidget *child;
g_variant_get (parameters, "(iiu)", &x, &y, &coordtype);
translate_coordinates_to_accessible (accessible, coordtype, x, y, &x, &y);
translate_coordinates_to_widget (widget, coordtype, x, y, &x, &y);
child = accessible_at_point (accessible, x, y, TRUE);
child = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT);
if (!child)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_null_ref ()));
}
else
{
GtkATContext *context = gtk_accessible_get_at_context (child);
GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
GtkAtSpiContext *ctx = GTK_AT_SPI_CONTEXT (context);
/* Realize the ATContext in order to get its ref */
gtk_at_context_realize (context);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (ctx)));
g_object_unref (context);
@@ -244,13 +165,13 @@ component_handle_method (GDBusConnection *connection,
else if (g_strcmp0 (method_name, "GetExtents") == 0)
{
AtspiCoordType coordtype;
int x, y, width, height;
gtk_accessible_get_bounds (accessible, &x, &y, &width, &height);
int x, y;
int width = gtk_widget_get_width (widget);
int height = gtk_widget_get_height (widget);
g_variant_get (parameters, "(u)", &coordtype);
translate_coordinates_from_accessible (accessible, coordtype, 0, 0, &x, &y);
translate_coordinates_from_widget (widget, coordtype, 0, 0, &x, &y);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("((iiii))", x, y, width, height));
}
@@ -261,15 +182,14 @@ component_handle_method (GDBusConnection *connection,
g_variant_get (parameters, "(u)", &coordtype);
translate_coordinates_from_accessible (accessible, coordtype, 0, 0, &x, &y);
translate_coordinates_from_widget (widget, coordtype, 0, 0, &x, &y);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(ii)", x, y));
}
else if (g_strcmp0 (method_name, "GetSize") == 0)
{
int x, y, width, height;
gtk_accessible_get_bounds (accessible, &x, &y, &width, &height);
int width = gtk_widget_get_width (widget);
int height = gtk_widget_get_height (widget);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(ii)", width, height));
}
@@ -277,9 +197,9 @@ component_handle_method (GDBusConnection *connection,
{
AtspiComponentLayer layer;
if (self->accessible_role == GTK_ACCESSIBLE_ROLE_WINDOW)
if (GTK_IS_WINDOW (widget))
layer = ATSPI_COMPONENT_LAYER_WINDOW;
else if (GTK_IS_POPOVER (accessible))
else if (GTK_IS_POPOVER (widget))
layer = ATSPI_COMPONENT_LAYER_POPUP;
else
layer = ATSPI_COMPONENT_LAYER_WIDGET;
@@ -296,10 +216,7 @@ component_handle_method (GDBusConnection *connection,
}
else if (g_strcmp0 (method_name, "GetAlpha") == 0)
{
double opacity = 1.0;
if (GTK_IS_WIDGET (accessible))
opacity = gtk_widget_get_opacity (GTK_WIDGET (accessible));
double opacity = gtk_widget_get_opacity (widget);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(d)", opacity));
}
@@ -332,5 +249,8 @@ static const GDBusInterfaceVTable component_vtable = {
const GDBusInterfaceVTable *
gtk_atspi_get_component_vtable (GtkAccessible *accessible)
{
return &component_vtable;
if (GTK_IS_WIDGET (accessible))
return &component_vtable;
return NULL;
}
+2 -187
View File
@@ -23,14 +23,12 @@
#include "gtkatspicontextprivate.h"
#include "gtkaccessibleprivate.h"
#include "gtkaccessibletext-private.h"
#include "gtkatspiactionprivate.h"
#include "gtkatspieditabletextprivate.h"
#include "gtkatspiprivate.h"
#include "gtkatspirootprivate.h"
#include "gtkatspiselectionprivate.h"
#include "gtkatspisocketprivate.h"
#include "gtkatspitextprivate.h"
#include "gtkatspiutilsprivate.h"
#include "gtkatspivalueprivate.h"
@@ -578,15 +576,6 @@ handle_accessible_method (GDBusConnection *connection,
accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
if (GTK_IS_AT_SPI_SOCKET (accessible))
{
GtkAtSpiSocket *socket = GTK_AT_SPI_SOCKET (accessible);
GVariant *ref = gtk_at_spi_socket_to_ref (socket);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", ref));
return;
}
presentable_idx = 0;
for (child = gtk_accessible_get_first_accessible_child (accessible);
@@ -631,13 +620,6 @@ handle_accessible_method (GDBusConnection *connection,
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
GtkAccessible *child = NULL;
if (GTK_IS_AT_SPI_SOCKET (accessible))
{
GtkAtSpiSocket *socket = GTK_AT_SPI_SOCKET (accessible);
GVariant *ref = gtk_at_spi_socket_to_ref (socket);
g_variant_builder_add (&builder, "@(so)", ref);
}
for (child = gtk_accessible_get_first_accessible_child (accessible);
child != NULL;
child = gtk_accessible_get_next_accessible_sibling (child))
@@ -1155,8 +1137,8 @@ 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);
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);
}
@@ -1388,18 +1370,6 @@ gtk_at_spi_context_register_object (GtkAtSpiContext *self)
GTK_DEBUG (A11Y, "Registered %d interfaces on object path '%s'",
self->n_registered_objects,
self->context_path);
if (GTK_IS_AT_SPI_SOCKET (accessible))
{
GtkAtSpiSocket *socket = GTK_AT_SPI_SOCKET (accessible);
gtk_at_spi_socket_embed (socket, self->connection);
GTK_DEBUG (A11Y, "Embedded plug %s:%s in socket %s",
gtk_at_spi_socket_get_bus_name (socket),
gtk_at_spi_socket_get_object_path (socket),
self->context_path);
}
}
static void
@@ -1532,153 +1502,6 @@ gtk_at_spi_context_unrealize (GtkATContext *context)
g_clear_object (&self->root);
}
static void
gtk_at_spi_context_announce (GtkATContext *context,
const char *message,
GtkAccessibleAnnouncementPriority priority)
{
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
AtspiLive live;
if (self->connection == NULL)
return;
switch (priority)
{
case GTK_ACCESSIBLE_ANNOUNCEMENT_PRIORITY_LOW:
case GTK_ACCESSIBLE_ANNOUNCEMENT_PRIORITY_MEDIUM:
live = ATSPI_LIVE_POLITE;
break;
case GTK_ACCESSIBLE_ANNOUNCEMENT_PRIORITY_HIGH:
live = ATSPI_LIVE_ASSERTIVE;
break;
default:
g_assert_not_reached ();
}
g_dbus_connection_emit_signal (self->connection,
NULL,
self->context_path,
"org.a11y.atspi.Event.Object",
"Announcement",
g_variant_new ("(siiva{sv})",
"", live, 0,
g_variant_new_string (message),
NULL),
NULL);
}
static void
gtk_at_spi_context_update_caret_position (GtkATContext *context)
{
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
GtkAccessible *accessible = gtk_at_context_get_accessible (context);
GtkAccessibleText *accessible_text = GTK_ACCESSIBLE_TEXT (accessible);
guint offset;
if (self->connection == NULL)
return;
offset = gtk_accessible_text_get_caret_position (accessible_text);
g_dbus_connection_emit_signal (self->connection,
NULL,
self->context_path,
"org.a11y.atspi.Event.Object",
"TextCaretMoved",
g_variant_new ("(siiva{sv})",
"",
(int) offset,
0,
g_variant_new_string (""),
NULL),
NULL);
}
static void
gtk_at_spi_context_update_selection_bound (GtkATContext *context)
{
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
if (self->connection == NULL)
return;
g_dbus_connection_emit_signal (self->connection,
NULL,
self->context_path,
"org.a11y.atspi.Event.Object",
"TextSelectionChanged",
g_variant_new ("(siiva{sv})",
"",
0,
0,
g_variant_new_string (""),
NULL),
NULL);
}
static void
gtk_at_spi_context_update_text_contents (GtkATContext *context,
GtkAccessibleTextContentChange change,
unsigned int start,
unsigned int end)
{
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
if (self->connection == NULL)
return;
GtkAccessible *accessible = gtk_at_context_get_accessible (context);
if (!GTK_IS_ACCESSIBLE_TEXT (accessible))
return;
const char *kind = "";
switch (change)
{
case GTK_ACCESSIBLE_TEXT_CONTENT_CHANGE_INSERT:
kind = "insert";
break;
case GTK_ACCESSIBLE_TEXT_CONTENT_CHANGE_REMOVE:
kind = "delete";
break;
default:
g_assert_not_reached ();
}
/* Retrieve the text using the given range */
GBytes *contents = gtk_accessible_text_get_contents (GTK_ACCESSIBLE_TEXT (accessible),
start, end);
if (contents == NULL)
goto out;
const char *text = g_bytes_get_data (contents, NULL);
if (text == NULL)
goto out;
/* Using G_MAXUINT in GTK maps to the text length */
if (end == G_MAXUINT)
end = g_utf8_strlen (text, -1);
g_dbus_connection_emit_signal (self->connection,
NULL,
self->context_path,
"org.a11y.atspi.Event.Object",
"TextChanged",
g_variant_new ("(siiva{sv})",
kind,
start,
end - start,
g_variant_new_string (text),
NULL),
NULL);
out:
g_clear_pointer (&contents, g_bytes_unref);
}
static void
gtk_at_spi_context_class_init (GtkAtSpiContextClass *klass)
{
@@ -1693,10 +1516,6 @@ gtk_at_spi_context_class_init (GtkAtSpiContextClass *klass)
context_class->platform_change = gtk_at_spi_context_platform_change;
context_class->bounds_change = gtk_at_spi_context_bounds_change;
context_class->child_change = gtk_at_spi_context_child_change;
context_class->announce = gtk_at_spi_context_announce;
context_class->update_caret_position = gtk_at_spi_context_update_caret_position;
context_class->update_selection_bound = gtk_at_spi_context_update_selection_bound;
context_class->update_text_contents = gtk_at_spi_context_update_text_contents;
}
static void
@@ -1988,10 +1807,6 @@ gtk_at_spi_context_get_child_count (GtkAtSpiContext *self)
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
int n_children = 0;
/* A socket always has exactly one child: the remote plug */
if (GTK_IS_AT_SPI_SOCKET (accessible))
return 1;
GtkAccessible *child = NULL;
for (child = gtk_accessible_get_first_accessible_child (accessible);
child != NULL;
+332
View File
@@ -20,6 +20,266 @@
#include "gtkatspipangoprivate.h"
#include "gtkpangoprivate.h"
void
gtk_pango_get_font_attributes (PangoFontDescription *font,
GVariantBuilder *builder)
{
char buf[60];
g_variant_builder_add (builder, "{ss}", "style",
pango_style_to_string (pango_font_description_get_style (font)));
g_variant_builder_add (builder, "{ss}", "variant",
pango_variant_to_string (pango_font_description_get_variant (font)));
g_variant_builder_add (builder, "{ss}", "stretch",
pango_stretch_to_string (pango_font_description_get_stretch (font)));
g_variant_builder_add (builder, "{ss}", "family-name",
pango_font_description_get_family (font));
g_snprintf (buf, 60, "%d", pango_font_description_get_weight (font));
g_variant_builder_add (builder, "{ss}", "weight", buf);
g_snprintf (buf, 60, "%i", pango_font_description_get_size (font) / PANGO_SCALE);
g_variant_builder_add (builder, "{ss}", "size", buf);
}
/*
* gtk_pango_get_default_attributes:
* @layout: the `PangoLayout` from which to get attributes
* @builder: a `GVariantBuilder` to add to
*
* Adds the default text attributes from @layout to @builder,
* after translating them from Pango attributes to atspi
* attributes.
*
* This is a convenience function that can be used to implement
* support for the `AtkText` interface in widgets using Pango
* layouts.
*
* Returns: the modified @attributes
*/
void
gtk_pango_get_default_attributes (PangoLayout *layout,
GVariantBuilder *builder)
{
PangoContext *context;
context = pango_layout_get_context (layout);
if (context)
{
PangoLanguage *language;
PangoFontDescription *font;
language = pango_context_get_language (context);
if (language)
g_variant_builder_add (builder, "{ss}", "language",
pango_language_to_string (language));
font = pango_context_get_font_description (context);
if (font)
gtk_pango_get_font_attributes (font, builder);
}
g_variant_builder_add (builder, "{ss}", "justification",
pango_align_to_string (pango_layout_get_alignment (layout)));
g_variant_builder_add (builder, "{ss}", "wrap-mode",
pango_wrap_mode_to_string (pango_layout_get_wrap (layout)));
g_variant_builder_add (builder, "{ss}", "strikethrough", "false");
g_variant_builder_add (builder, "{ss}", "underline", "false");
g_variant_builder_add (builder, "{ss}", "rise", "0");
g_variant_builder_add (builder, "{ss}", "scale", "1");
g_variant_builder_add (builder, "{ss}", "bg-full-height", "0");
g_variant_builder_add (builder, "{ss}", "pixels-inside-wrap", "0");
g_variant_builder_add (builder, "{ss}", "pixels-below-lines", "0");
g_variant_builder_add (builder, "{ss}", "pixels-above-lines", "0");
g_variant_builder_add (builder, "{ss}", "editable", "false");
g_variant_builder_add (builder, "{ss}", "invisible", "false");
g_variant_builder_add (builder, "{ss}", "indent", "0");
g_variant_builder_add (builder, "{ss}", "right-margin", "0");
g_variant_builder_add (builder, "{ss}", "left-margin", "0");
}
/*
* gtk_pango_get_run_attributes:
* @layout: the `PangoLayout` to get the attributes from
* @builder: `GVariantBuilder` to add to
* @offset: the offset at which the attributes are wanted
* @start_offset: return location for the starting offset
* of the current run
* @end_offset: return location for the ending offset of the
* current run
*
* Finds the run around index (i.e. the maximal range of characters
* where the set of applicable attributes remains constant) and
* returns the starting and ending offsets for it.
*
* The attributes for the run are added to @attributes, after
* translating them from Pango attributes to atspi attributes.
*
* This is a convenience function that can be used to implement
* support for the #AtkText interface in widgets using Pango
* layouts.
*/
void
gtk_pango_get_run_attributes (PangoLayout *layout,
GVariantBuilder *builder,
int offset,
int *start_offset,
int *end_offset)
{
PangoAttrIterator *iter;
PangoAttrList *attr;
PangoAttrString *pango_string;
PangoAttrInt *pango_int;
PangoAttrColor *pango_color;
PangoAttrLanguage *pango_lang;
PangoAttrFloat *pango_float;
int index, start_index, end_index;
gboolean is_next;
glong len;
const char *text;
char *value;
const char *val;
text = pango_layout_get_text (layout);
len = g_utf8_strlen (text, -1);
/* Grab the attributes of the PangoLayout, if any */
attr = pango_layout_get_attributes (layout);
if (attr == NULL)
{
*start_offset = 0;
*end_offset = len;
return;
}
iter = pango_attr_list_get_iterator (attr);
/* Get invariant range offsets */
/* If offset out of range, set offset in range */
if (offset > len)
offset = len;
else if (offset < 0)
offset = 0;
index = g_utf8_offset_to_pointer (text, offset) - text;
pango_attr_iterator_range (iter, &start_index, &end_index);
is_next = TRUE;
while (is_next)
{
if (index >= start_index && index < end_index)
{
*start_offset = g_utf8_pointer_to_offset (text, text + start_index);
if (end_index == G_MAXINT) /* Last iterator */
end_index = len;
*end_offset = g_utf8_pointer_to_offset (text, text + end_index);
break;
}
is_next = pango_attr_iterator_next (iter);
pango_attr_iterator_range (iter, &start_index, &end_index);
}
/* Get attributes */
pango_string = (PangoAttrString *) pango_attr_iterator_get (iter, PANGO_ATTR_FAMILY);
if (pango_string != NULL)
{
value = g_strdup_printf ("%s", pango_string->value);
g_variant_builder_add (builder, "{ss}", "family-name", value);
g_free (value);
}
pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_STYLE);
if (pango_int != NULL)
g_variant_builder_add (builder, "{ss}", "style", pango_style_to_string (pango_int->value));
pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_WEIGHT);
if (pango_int != NULL)
{
value = g_strdup_printf ("%i", pango_int->value);
g_variant_builder_add (builder, "{ss}", "weight", value);
g_free (value);
}
pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_VARIANT);
if (pango_int != NULL)
g_variant_builder_add (builder, "{ss}", "variant",
pango_variant_to_string (pango_int->value));
pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_STRETCH);
if (pango_int != NULL)
g_variant_builder_add (builder, "{ss}", "stretch",
pango_stretch_to_string (pango_int->value));
pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_SIZE);
if (pango_int != NULL)
{
value = g_strdup_printf ("%i", pango_int->value / PANGO_SCALE);
g_variant_builder_add (builder, "{ss}", "size", value);
g_free (value);
}
pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_UNDERLINE);
if (pango_int != NULL)
g_variant_builder_add (builder, "{ss}", "underline",
pango_underline_to_string (pango_int->value));
pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_STRIKETHROUGH);
if (pango_int != NULL)
{
if (pango_int->value)
val = "true";
else
val = "false";
g_variant_builder_add (builder, "{ss}", "strikethrough", val);
}
pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_RISE);
if (pango_int != NULL)
{
value = g_strdup_printf ("%i", pango_int->value);
g_variant_builder_add (builder, "{ss}", "rise", value);
g_free (value);
}
pango_lang = (PangoAttrLanguage *) pango_attr_iterator_get (iter, PANGO_ATTR_LANGUAGE);
if (pango_lang != NULL)
{
g_variant_builder_add (builder, "{ss}", "language",
pango_language_to_string (pango_lang->value));
}
pango_float = (PangoAttrFloat *) pango_attr_iterator_get (iter, PANGO_ATTR_SCALE);
if (pango_float != NULL)
{
value = g_strdup_printf ("%g", pango_float->value);
g_variant_builder_add (builder, "{ss}", "scale", value);
g_free (value);
}
pango_color = (PangoAttrColor *) pango_attr_iterator_get (iter, PANGO_ATTR_FOREGROUND);
if (pango_color != NULL)
{
value = g_strdup_printf ("%u,%u,%u",
pango_color->color.red,
pango_color->color.green,
pango_color->color.blue);
g_variant_builder_add (builder, "{ss}", "fg-color", value);
g_free (value);
}
pango_color = (PangoAttrColor *) pango_attr_iterator_get (iter, PANGO_ATTR_BACKGROUND);
if (pango_color != NULL)
{
value = g_strdup_printf ("%u,%u,%u",
pango_color->color.red,
pango_color->color.green,
pango_color->color.blue);
g_variant_builder_add (builder, "{ss}", "bg-color", value);
g_free (value);
}
pango_attr_iterator_destroy (iter);
}
/*
* gtk_pango_move_chars:
* @layout: a `PangoLayout`
@@ -820,3 +1080,75 @@ gtk_pango_get_text_at (PangoLayout *layout,
return g_utf8_substring (text, start, end);
}
char *gtk_pango_get_string_at (PangoLayout *layout,
int offset,
AtspiTextGranularity granularity,
int *start_offset,
int *end_offset)
{
const char *text;
int start, end;
const PangoLogAttr *attrs;
int n_attrs;
text = pango_layout_get_text (layout);
if (text[0] == 0)
{
*start_offset = 0;
*end_offset = 0;
return g_strdup ("");
}
attrs = pango_layout_get_log_attrs_readonly (layout, &n_attrs);
start = offset;
end = start;
switch (granularity)
{
case ATSPI_TEXT_GRANULARITY_CHAR:
end = gtk_pango_move_chars (layout, end, 1);
break;
case ATSPI_TEXT_GRANULARITY_WORD:
if (!attrs[start].is_word_start)
start = gtk_pango_move_words (layout, start, -1);
if (gtk_pango_is_inside_word (layout, end))
end = gtk_pango_move_words (layout, end, 1);
while (!attrs[end].is_word_start && end < n_attrs - 1)
end = gtk_pango_move_chars (layout, end, 1);
break;
case ATSPI_TEXT_GRANULARITY_SENTENCE:
if (!attrs[start].is_sentence_start)
start = gtk_pango_move_sentences (layout, start, -1);
if (gtk_pango_is_inside_sentence (layout, end))
end = gtk_pango_move_sentences (layout, end, 1);
while (!attrs[end].is_sentence_start && end < n_attrs - 1)
end = gtk_pango_move_chars (layout, end, 1);
break;
case ATSPI_TEXT_GRANULARITY_LINE:
pango_layout_get_line_at (layout, offset, ATSPI_TEXT_BOUNDARY_LINE_START, &start, &end);
break;
case ATSPI_TEXT_GRANULARITY_PARAGRAPH:
/* FIXME: In theory, a layout can hold more than one paragraph */
start = 0;
end = g_utf8_strlen (text, -1);
break;
default:
g_assert_not_reached ();
break;
}
*start_offset = start;
*end_offset = end;
g_assert (start <= end);
return g_utf8_substring (text, start, end);
}
+15 -1
View File
@@ -19,10 +19,19 @@
#include <pango/pangocairo.h>
#include "gtkatspiprivate.h"
#include "gtkpangoprivate.h"
G_BEGIN_DECLS
void gtk_pango_get_font_attributes (PangoFontDescription *font,
GVariantBuilder *builder);
void gtk_pango_get_default_attributes (PangoLayout *layout,
GVariantBuilder *builder);
void gtk_pango_get_run_attributes (PangoLayout *layout,
GVariantBuilder *builder,
int offset,
int *start_offset,
int *end_offset);
char *gtk_pango_get_text_before (PangoLayout *layout,
int offset,
AtspiTextBoundaryType boundary_type,
@@ -38,5 +47,10 @@ char *gtk_pango_get_text_after (PangoLayout *layout,
AtspiTextBoundaryType boundary_type,
int *start_offset,
int *end_offset);
char *gtk_pango_get_string_at (PangoLayout *layout,
int offset,
AtspiTextGranularity granularity,
int *start_offset,
int *end_offset);
G_END_DECLS
-5
View File
@@ -277,11 +277,6 @@ typedef enum {
ATSPI_SCROLL_ANYWHERE
} AtspiScrollType;
typedef enum {
ATSPI_LIVE_POLITE = 1,
ATSPI_LIVE_ASSERTIVE = 2
} AtspiLive;
typedef struct _GtkAtSpiRoot GtkAtSpiRoot;
typedef struct _GtkAtSpiCache GtkAtSpiCache;
typedef struct _GtkAtSpiContext GtkAtSpiContext;
-480
View File
@@ -1,480 +0,0 @@
/* gtkatspisocket.c: AT-SPI socket object
*
* Copyright 2024 GNOME Foundation Inc.
* 2024 Igalia S.L.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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.1 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/>.
*/
/**
* GtkAtApiSocket:
*
* `GtkAtApiSocket` is an AT-SPI specific `GtkAccessible` interface for
* integrating remote accessible objects. It makes the accessible tree
* of the remote accessible object appear as part of the accessible tree
* that it belongs to itself.
*/
#include "config.h"
#include "gtkatspisocketprivate.h"
#include "gtkatspicontextprivate.h"
#include "gtktypebuiltins.h"
struct _GtkAtSpiSocket
{
GObject parent_instance;
char *bus_name;
char *object_path;
GtkATContext *at_context;
GtkAccessibleRole accessible_role;
GCancellable *cancellable;
gboolean embedded;
};
static void g_initable_interface_init (GInitableIface *iface);
static void gtk_accessible_interface_init (GtkAccessibleInterface *iface);
G_DEFINE_FINAL_TYPE_WITH_CODE (GtkAtSpiSocket, gtk_at_spi_socket, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
g_initable_interface_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACCESSIBLE,
gtk_accessible_interface_init))
enum {
PROP_0,
PROP_BUS_NAME,
PROP_OBJECT_PATH,
N_PROPS,
/* GtkAccessible */
PROP_ACCESSIBLE_ROLE,
};
static GParamSpec *properties [N_PROPS];
static void
set_accessible_role (GtkAtSpiSocket *self,
GtkAccessibleRole role)
{
g_return_if_fail (!gtk_accessible_role_is_abstract (role));
if (self->at_context == NULL || !gtk_at_context_is_realized (self->at_context))
{
self->accessible_role = role;
if (self->at_context != NULL)
gtk_at_context_set_accessible_role (self->at_context, role);
g_object_notify (G_OBJECT (self), "accessible-role");
}
else
{
char *role_str = g_enum_to_string (GTK_TYPE_ACCESSIBLE_ROLE, self->accessible_role);
g_critical ("%s already has an accessible role of type “%s”",
G_OBJECT_TYPE_NAME (self),
role_str);
g_free (role_str);
}
}
static gboolean
gtk_at_spi_socket_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
GtkAtSpiSocket *self = (GtkAtSpiSocket *) initable;
g_assert (GTK_IS_AT_SPI_SOCKET (initable));
if (self->bus_name == NULL || !g_dbus_is_name (self->bus_name))
{
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid bus name");
return FALSE;
}
if (self->object_path == NULL || !g_variant_is_object_path (self->object_path))
{
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid object path");
return FALSE;
}
self->at_context = gtk_at_context_create (self->accessible_role,
GTK_ACCESSIBLE (self),
gdk_display_get_default ());
/* Sockets are strictly specific to AT-SPI */
if (self->at_context != NULL && !GTK_IS_AT_SPI_CONTEXT (self->at_context))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"AT-SPI sockets can only be used with the AT-SPI backend");
g_clear_object (&self->at_context);
return FALSE;
}
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
GTK_ACCESSIBLE_STATE_HIDDEN, TRUE,
-1);
return TRUE;
}
static void
g_initable_interface_init (GInitableIface *iface)
{
iface->init = gtk_at_spi_socket_initable_init;
}
static GtkATContext *
gtk_at_spi_socket_get_at_context (GtkAccessible *accessible)
{
GtkAtSpiSocket *self = (GtkAtSpiSocket *) accessible;
g_assert (GTK_IS_AT_SPI_SOCKET (accessible));
if (self->at_context != NULL)
return g_object_ref (self->at_context);
return NULL;
}
static gboolean
gtk_at_spi_socket_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state)
{
return FALSE;
}
static GtkAccessible *
gtk_at_spi_socket_get_first_accessible_child (GtkAccessible *accessible)
{
return NULL;
}
static GtkAccessible *
gtk_at_spi_socket_get_next_accessible_sibling (GtkAccessible *accessible)
{
return NULL;
}
static gboolean
gtk_at_spi_socket_get_bounds (GtkAccessible *accessible,
int *x,
int *y,
int *width,
int *height)
{
GtkAccessible *accessible_parent;
g_assert (GTK_IS_AT_SPI_SOCKET (accessible));
accessible_parent = gtk_accessible_get_accessible_parent (accessible);
if (accessible_parent == NULL)
return FALSE;
return gtk_accessible_get_bounds (accessible_parent, x, y, width, height);
}
static void
gtk_accessible_interface_init (GtkAccessibleInterface *iface)
{
iface->get_at_context = gtk_at_spi_socket_get_at_context;
iface->get_platform_state = gtk_at_spi_socket_get_platform_state;
iface->get_first_accessible_child = gtk_at_spi_socket_get_first_accessible_child;
iface->get_next_accessible_sibling = gtk_at_spi_socket_get_next_accessible_sibling;
iface->get_bounds = gtk_at_spi_socket_get_bounds;
}
static void
gtk_at_spi_socket_dispose (GObject *object)
{
GtkAtSpiSocket *self = (GtkAtSpiSocket *)object;
g_cancellable_cancel (self->cancellable);
g_clear_pointer (&self->object_path, g_free);
g_clear_pointer (&self->bus_name, g_free);
g_clear_object (&self->cancellable);
g_clear_object (&self->at_context);
G_OBJECT_CLASS (gtk_at_spi_socket_parent_class)->dispose (object);
}
static void
gtk_at_spi_socket_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkAtSpiSocket *self = GTK_AT_SPI_SOCKET (object);
switch (prop_id)
{
case PROP_ACCESSIBLE_ROLE:
g_value_set_enum (value, self->accessible_role);
break;
case PROP_BUS_NAME:
g_value_set_string (value, self->bus_name);
break;
case PROP_OBJECT_PATH:
g_value_set_string (value, self->object_path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gtk_at_spi_socket_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkAtSpiSocket *self = GTK_AT_SPI_SOCKET (object);
switch (prop_id)
{
case PROP_ACCESSIBLE_ROLE:
set_accessible_role (self, g_value_get_enum (value));
break;
case PROP_BUS_NAME:
self->bus_name = g_value_dup_string (value);
break;
case PROP_OBJECT_PATH:
self->object_path = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gtk_at_spi_socket_class_init (GtkAtSpiSocketClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_at_spi_socket_dispose;
object_class->get_property = gtk_at_spi_socket_get_property;
object_class->set_property = gtk_at_spi_socket_set_property;
/**
* GtkAtSpiSocket:bus-name: (attributes org.gtk.Property.get=gtk_at_spi_socket_get_bus_name)
*
* The bus name of the remote accessible client.
*
* Since: 4.14
*/
properties[PROP_BUS_NAME] =
g_param_spec_string ("bus-name", NULL, NULL,
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkAtSpiSocket:height: (attributes org.gtk.Property.get=gtk_at_spi_socket_get_object_path)
*
* The object path of the remote accessible object that
* the socket connects to.
*
* Since: 4.14
*/
properties[PROP_OBJECT_PATH] =
g_param_spec_string ("object-path", NULL, NULL,
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (object_class, N_PROPS, properties);
g_object_class_override_property (object_class, PROP_ACCESSIBLE_ROLE, "accessible-role");
}
static void
gtk_at_spi_socket_init (GtkAtSpiSocket *self)
{
self->accessible_role = GTK_ACCESSIBLE_ROLE_GENERIC;
}
GVariant *
gtk_at_spi_socket_to_ref (GtkAtSpiSocket *self)
{
return g_variant_new ("(so)", self->bus_name, self->object_path);
}
static void
update_embedded_state (GtkAtSpiSocket *self,
gboolean embedded)
{
if (self->embedded == embedded)
return;
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
GTK_ACCESSIBLE_STATE_HIDDEN, !embedded,
-1);
self->embedded = embedded;
g_clear_object (&self->cancellable);
}
static void
socket_embedded_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GtkAtSpiSocket *self = (GtkAtSpiSocket *)user_data;
GVariant *res = NULL;
GError *error = NULL;
res = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
result,
&error);
g_clear_pointer (&res, g_variant_unref);
if (error)
{
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
g_warning ("Error embedding AT-SPI socket: %s", error->message);
update_embedded_state (self, FALSE);
}
g_clear_error (&error);
return;
}
update_embedded_state (self, TRUE);
}
void
gtk_at_spi_socket_embed (GtkAtSpiSocket *self,
GDBusConnection *connection)
{
const char *context_path = NULL;
if (self->at_context == NULL)
return;
if (self->embedded || self->cancellable != NULL)
return;
context_path = gtk_at_spi_context_get_context_path (GTK_AT_SPI_CONTEXT (self->at_context));
self->cancellable = g_cancellable_new ();
g_dbus_connection_call (connection,
self->bus_name,
self->object_path,
"org.a11y.atspi.Socket",
"Embedded",
g_variant_new ("(s)", context_path),
NULL,
G_DBUS_CALL_FLAGS_NO_AUTO_START,
-1,
self->cancellable,
socket_embedded_cb,
self);
}
/**
* gtk_at_spi_socket_new:
* @bus_name: the bus name of the remote accessible object
* @object_path: the object path of the remote accessible object
* @error: (nullable): return location for a #GError
*
* Creates an AT-SPI socket object that makes the accessible tree
* at the given @bus_name and @object_path appear as part of the
* accessible tree that it belongs to itself.
*
* It is up to the app to acquire @bus_name and @object_path. That's
* usually done through a side channel with the remote side, for
* example using sockets, or reading the output of a subprocess.
*
* The remote accessible object at @object_path must be a must
* have an `org.a11y.atspi.Socket` interface with the `Embedded()`
* method.
*
* This constructor can fail, most notably if the accessibility
* stack is not AT-SPI.
*
* Since: 4.14
*/
GtkAccessible *
gtk_at_spi_socket_new (const char *bus_name,
const char *object_path,
GError **error)
{
return g_initable_new (GTK_TYPE_AT_SPI_SOCKET,
NULL,
error,
"bus-name", bus_name,
"object-path", object_path,
NULL);
}
/**
* gtk_at_spi_socket_get_bus_name:
* @self: a #GtkAtSpiSocket
*
* Retrieves the bus name of the remote accessible object that the
* socket is connected to.
*
* Returns: (transfer none): the bus name of the remote accessible object
*
* Since: 4.14
*/
const char *
gtk_at_spi_socket_get_bus_name (GtkAtSpiSocket *self)
{
g_return_val_if_fail (GTK_IS_AT_SPI_SOCKET (self), NULL);
return self->bus_name;
}
/**
* gtk_at_spi_socket_get_object_path:
* @self: a #GtkAtSpiSocket
*
* Retrieves the object path of the remove accessible object that
* the socket is connected to.
*
* Returns: (transfer none): the object path of the socket remote
* accessible object
*
* Since: 4.14
*/
const char *
gtk_at_spi_socket_get_object_path (GtkAtSpiSocket *self)
{
g_return_val_if_fail (GTK_IS_AT_SPI_SOCKET (self), NULL);
return self->object_path;
}
-48
View File
@@ -1,48 +0,0 @@
/* gtkatspisocket.h: AT-SPI socket accessible object
*
* Copyright 2024 GNOME Foundation Inc.
* 2024 Igalia S.L.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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.1 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 (__GTKATSPI_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/a11y/gtkatspi.h> can be included directly."
#endif
#include <gtk/gtkaccessible.h>
G_BEGIN_DECLS
#define GTK_TYPE_AT_SPI_SOCKET (gtk_at_spi_socket_get_type())
GDK_AVAILABLE_IN_4_14
G_DECLARE_FINAL_TYPE (GtkAtSpiSocket, gtk_at_spi_socket, GTK, AT_SPI_SOCKET, GObject)
GDK_AVAILABLE_IN_4_14
GtkAccessible * gtk_at_spi_socket_new (const char *bus_name,
const char *object_path,
GError **error);
GDK_AVAILABLE_IN_4_14
const char * gtk_at_spi_socket_get_bus_name (GtkAtSpiSocket *self);
GDK_AVAILABLE_IN_4_14
const char * gtk_at_spi_socket_get_object_path (GtkAtSpiSocket *self);
G_END_DECLS
-34
View File
@@ -1,34 +0,0 @@
/* gtkatspisocketprivate.h: AT-SPI socket object
*
* Copyright 2024 GNOME Foundation Inc.
* 2024 Igalia S.L.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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.1 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 <gio/gio.h>
#include "gtkaccessible.h"
#include "gtkatspisocket.h"
G_BEGIN_DECLS
GVariant * gtk_at_spi_socket_to_ref (GtkAtSpiSocket *self);
void gtk_at_spi_socket_embed (GtkAtSpiSocket *self,
GDBusConnection *connection);
G_END_DECLS

Some files were not shown because too many files have changed in this diff Show More