Compare commits
1 Commits
css-style-
...
matthiasc/
Author | SHA1 | Date | |
---|---|---|---|
|
459309d8cd |
@@ -13,7 +13,7 @@ stages:
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64: &fedora-x86_64-defaults
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v9
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v8
|
||||
stage: build
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
@@ -29,7 +29,6 @@ fedora-x86_64: &fedora-x86_64-defaults
|
||||
- "${CI_PROJECT_DIR}/_build/report.html"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*.syscap"
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
<<: *cache-paths
|
||||
|
@@ -67,7 +67,6 @@ RUN dnf -y install \
|
||||
python3-wheel \
|
||||
redhat-rpm-config \
|
||||
sassc \
|
||||
sysprof-devel \
|
||||
systemtap-sdt-devel \
|
||||
vulkan-devel \
|
||||
wayland-devel \
|
||||
|
@@ -16,7 +16,6 @@ meson \
|
||||
-Dwayland-backend=true \
|
||||
-Dbroadway-backend=true \
|
||||
-Dvulkan=yes \
|
||||
-Dprofiler=true \
|
||||
--werror \
|
||||
${EXTRA_MESON_FLAGS:-} \
|
||||
_build $srcdir
|
||||
|
@@ -262,7 +262,7 @@ draw_menu (GtkWidget *widget,
|
||||
gint toggle_x, toggle_y, toggle_width, toggle_height;
|
||||
|
||||
/* This information is taken from the GtkMenu docs, see "CSS nodes" */
|
||||
menu_context = get_style (NULL, "menu");
|
||||
menu_context = get_style (gtk_widget_get_style_context(widget), "menu");
|
||||
hovermenuitem_context = get_style (menu_context, "menuitem:hover");
|
||||
hoveredarrowmenuitem_context = get_style (hovermenuitem_context, "arrow.right:dir(ltr)");
|
||||
menuitem_context = get_style (menu_context, "menuitem");
|
||||
|
@@ -2000,13 +2000,6 @@ toggle_action (GSimpleAction *action,
|
||||
g_variant_new_boolean (!g_variant_get_boolean (state)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
quit_timeout (gpointer data)
|
||||
{
|
||||
exit (0);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -2072,9 +2065,6 @@ main (int argc, char *argv[])
|
||||
|
||||
g_application_add_main_option (G_APPLICATION (app), "version", 0, 0, G_OPTION_ARG_NONE, "Show program version", NULL);
|
||||
|
||||
if (g_getenv ("GTK_DEBUG_AUTO_QUIT"))
|
||||
g_timeout_add (500, quit_timeout, NULL);
|
||||
|
||||
g_signal_connect (app, "handle-local-options", G_CALLBACK (local_options), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
|
@@ -183,7 +183,6 @@ gsk_transform_perspective
|
||||
gsk_transform_equal
|
||||
<SUBSECTION>
|
||||
gsk_transform_transform_bounds
|
||||
gsk_transform_transform_point
|
||||
<SUBSECTION Private>
|
||||
GSK_TYPE_TRANSFORM
|
||||
gsk_transform_get_type
|
||||
|
@@ -775,6 +775,7 @@ gtk_container_add
|
||||
gtk_container_remove
|
||||
gtk_container_foreach
|
||||
gtk_container_get_children
|
||||
gtk_container_get_path_for_child
|
||||
gtk_container_get_focus_vadjustment
|
||||
gtk_container_set_focus_vadjustment
|
||||
gtk_container_get_focus_hadjustment
|
||||
@@ -4411,6 +4412,7 @@ gtk_widget_get_layout_manager
|
||||
gtk_widget_should_layout
|
||||
|
||||
<SUBSECTION>
|
||||
gtk_widget_get_path
|
||||
gtk_widget_get_style_context
|
||||
gtk_widget_reset_style
|
||||
gtk_widget_class_get_css_name
|
||||
@@ -4895,6 +4897,7 @@ gtk_border_free
|
||||
<SUBSECTION>
|
||||
gtk_render_arrow
|
||||
gtk_render_background
|
||||
gtk_render_background_get_clip
|
||||
gtk_render_check
|
||||
gtk_render_expander
|
||||
gtk_render_focus
|
||||
|
10
gdk/gdk.c
10
gdk/gdk.c
@@ -212,14 +212,14 @@ gdk_pre_parse (void)
|
||||
_gdk_debug_flags = g_parse_debug_string (debug_string,
|
||||
(GDebugKey *) gdk_debug_keys,
|
||||
G_N_ELEMENTS (gdk_debug_keys));
|
||||
|
||||
if (g_getenv ("GTK_TRACE_FD"))
|
||||
gdk_profiler_start (atoi (g_getenv ("GTK_TRACE_FD")));
|
||||
else if (g_getenv ("GTK_TRACE"))
|
||||
gdk_profiler_start (-1);
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
if (g_getenv ("GTK_TRACE_FD"))
|
||||
gdk_profiler_start (atoi (g_getenv ("GTK_TRACE_FD")));
|
||||
else if (g_getenv ("GTK_TRACE"))
|
||||
gdk_profiler_start (-1);
|
||||
|
||||
#ifndef G_HAS_CONSTRUCTORS
|
||||
stash_desktop_startup_notification_id ();
|
||||
#endif
|
||||
|
@@ -649,94 +649,46 @@ gdk_frame_clock_get_refresh_info (GdkFrameClock *frame_clock,
|
||||
void
|
||||
_gdk_frame_clock_emit_flush_events (GdkFrameClock *frame_clock)
|
||||
{
|
||||
guint64 before = g_get_monotonic_time ();
|
||||
|
||||
g_signal_emit (frame_clock, signals[FLUSH_EVENTS], 0);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000,
|
||||
(g_get_monotonic_time () - before) * 1000,
|
||||
"frameclock ::flush-events", "");
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_frame_clock_emit_before_paint (GdkFrameClock *frame_clock)
|
||||
{
|
||||
guint64 before = g_get_monotonic_time ();
|
||||
|
||||
g_signal_emit (frame_clock, signals[BEFORE_PAINT], 0);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000,
|
||||
(g_get_monotonic_time () - before) * 1000,
|
||||
"frameclock ::before-paint", "");
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_frame_clock_emit_update (GdkFrameClock *frame_clock)
|
||||
{
|
||||
guint64 before = g_get_monotonic_time ();
|
||||
|
||||
g_signal_emit (frame_clock, signals[UPDATE], 0);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000,
|
||||
(g_get_monotonic_time () - before) * 1000,
|
||||
"frameclock ::update", "");
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_frame_clock_emit_layout (GdkFrameClock *frame_clock)
|
||||
{
|
||||
guint64 before = g_get_monotonic_time ();
|
||||
|
||||
g_signal_emit (frame_clock, signals[LAYOUT], 0);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000,
|
||||
(g_get_monotonic_time () - before) * 1000,
|
||||
"frameclock ::layout", "");
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_frame_clock_emit_paint (GdkFrameClock *frame_clock)
|
||||
{
|
||||
guint64 before = g_get_monotonic_time ();
|
||||
|
||||
g_signal_emit (frame_clock, signals[PAINT], 0);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000,
|
||||
(g_get_monotonic_time () - before) * 1000,
|
||||
"frameclock ::paint", "");
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_frame_clock_emit_after_paint (GdkFrameClock *frame_clock)
|
||||
{
|
||||
guint64 before = g_get_monotonic_time ();
|
||||
|
||||
g_signal_emit (frame_clock, signals[AFTER_PAINT], 0);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000,
|
||||
(g_get_monotonic_time () - before) * 1000,
|
||||
"frameclock ::after-paint", "");
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_frame_clock_emit_resume_events (GdkFrameClock *frame_clock)
|
||||
{
|
||||
guint64 before = g_get_monotonic_time ();
|
||||
|
||||
g_signal_emit (frame_clock, signals[RESUME_EVENTS], 0);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000,
|
||||
(g_get_monotonic_time () - before) * 1000,
|
||||
"frameclock ::resume-events", "");
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static gint64
|
||||
guess_refresh_interval (GdkFrameClock *frame_clock)
|
||||
{
|
||||
@@ -806,17 +758,34 @@ frame_clock_get_fps (GdkFrameClock *frame_clock)
|
||||
|
||||
return ((double) end_counter - start_counter) * G_USEC_PER_SEC / (end_timestamp - start_timestamp);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_gdk_frame_clock_add_timings_to_profiler (GdkFrameClock *clock,
|
||||
GdkFrameTimings *timings)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
gdk_profiler_add_mark (timings->frame_time * 1000,
|
||||
(timings->frame_end_time - timings->frame_time) * 1000,
|
||||
"frame", "");
|
||||
|
||||
if (timings->layout_start_time != 0)
|
||||
gdk_profiler_add_mark (timings->layout_start_time * 1000,
|
||||
(timings->paint_start_time - timings->layout_start_time) * 1000,
|
||||
"layout", "");
|
||||
|
||||
if (timings->paint_start_time != 0)
|
||||
gdk_profiler_add_mark (timings->paint_start_time * 1000,
|
||||
(timings->frame_end_time - timings->paint_start_time) * 1000,
|
||||
"paint", "");
|
||||
|
||||
if (timings->presentation_time != 0)
|
||||
gdk_profiler_add_mark (timings->presentation_time * 1000,
|
||||
0,
|
||||
"presentation", "");
|
||||
|
||||
gdk_profiler_set_counter (fps_counter,
|
||||
timings->presentation_time * 1000,
|
||||
timings->frame_end_time * 1000,
|
||||
frame_clock_get_fps (clock));
|
||||
#endif
|
||||
}
|
||||
|
@@ -42,7 +42,9 @@ struct _GdkFrameClockIdlePrivate
|
||||
gint64 frame_time;
|
||||
gint64 min_next_frame_time;
|
||||
gint64 sleep_serial;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
gint64 freeze_time;
|
||||
#endif
|
||||
|
||||
guint flush_idle_id;
|
||||
guint paint_idle_id;
|
||||
@@ -317,7 +319,6 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
GdkFrameClockIdlePrivate *priv = clock_idle->priv;
|
||||
gboolean skip_to_resume_events;
|
||||
GdkFrameTimings *timings = NULL;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
|
||||
priv->paint_idle_id = 0;
|
||||
priv->in_paint_idle = TRUE;
|
||||
@@ -408,13 +409,13 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
{
|
||||
int iter;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ())
|
||||
{
|
||||
if (priv->phase != GDK_FRAME_CLOCK_PHASE_LAYOUT &&
|
||||
(priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT))
|
||||
timings->layout_start_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||
/* We loop in the layout phase, because we don't want to progress
|
||||
@@ -438,13 +439,13 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
if (priv->freeze_count == 0)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ())
|
||||
{
|
||||
if (priv->phase != GDK_FRAME_CLOCK_PHASE_PAINT &&
|
||||
(priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT))
|
||||
timings->paint_start_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_PAINT;
|
||||
if (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT)
|
||||
@@ -465,7 +466,7 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
|
||||
}
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ())
|
||||
timings->frame_end_time = g_get_monotonic_time ();
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
@@ -501,9 +502,6 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
if (priv->freeze_count == 0)
|
||||
priv->sleep_serial = get_sleep_serial ();
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000, (g_get_monotonic_time () - before) * 1000, "frameclock", "paint_idle");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -563,11 +561,13 @@ gdk_frame_clock_idle_freeze (GdkFrameClock *clock)
|
||||
GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock);
|
||||
GdkFrameClockIdlePrivate *priv = clock_idle->priv;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (priv->freeze_count == 0)
|
||||
{
|
||||
if (gdk_profiler_is_running ())
|
||||
priv->freeze_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif
|
||||
|
||||
priv->freeze_count++;
|
||||
maybe_stop_idle (clock_idle);
|
||||
@@ -594,6 +594,7 @@ gdk_frame_clock_idle_thaw (GdkFrameClock *clock)
|
||||
|
||||
priv->sleep_serial = get_sleep_serial ();
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (gdk_profiler_is_running ())
|
||||
{
|
||||
if (priv->freeze_time != 0)
|
||||
@@ -601,10 +602,11 @@ gdk_frame_clock_idle_thaw (GdkFrameClock *clock)
|
||||
gint64 thaw_time = g_get_monotonic_time ();
|
||||
gdk_profiler_add_mark (priv->freeze_time * 1000,
|
||||
(thaw_time - priv->freeze_time) * 1000,
|
||||
"frameclock freeze", "");
|
||||
"freeze", "");
|
||||
priv->freeze_time = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -53,15 +53,15 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gdk_rgba_free (GdkRGBA *rgba);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_rgba_is_clear (const GdkRGBA *rgba) G_GNUC_PURE;
|
||||
gboolean gdk_rgba_is_clear (const GdkRGBA *rgba);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_rgba_is_opaque (const GdkRGBA *rgba) G_GNUC_PURE;
|
||||
gboolean gdk_rgba_is_opaque (const GdkRGBA *rgba);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gdk_rgba_hash (gconstpointer p) G_GNUC_PURE;
|
||||
guint gdk_rgba_hash (gconstpointer p);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_rgba_equal (gconstpointer p1,
|
||||
gconstpointer p2) G_GNUC_PURE;
|
||||
gconstpointer p2);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_rgba_parse (GdkRGBA *rgba,
|
||||
|
@@ -4005,6 +4005,7 @@ rewrite_event_for_toplevel (GdkEvent *event)
|
||||
g_set_object (&event->any.surface, surface);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static void
|
||||
add_event_mark (GdkEvent *event,
|
||||
gint64 time,
|
||||
@@ -4071,9 +4072,6 @@ add_event_mark (GdkEvent *event,
|
||||
|
||||
case GDK_ENTER_NOTIFY:
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
message = g_strdup ("");
|
||||
break;
|
||||
|
||||
case GDK_TOUCHPAD_SWIPE:
|
||||
case GDK_TOUCHPAD_PINCH:
|
||||
case GDK_SCROLL:
|
||||
@@ -4115,11 +4113,14 @@ add_event_mark (GdkEvent *event,
|
||||
|
||||
g_free (message);
|
||||
}
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
gdk_surface_handle_event (GdkEvent *event)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
gint64 begin_time = g_get_monotonic_time ();
|
||||
#endif
|
||||
gboolean handled = FALSE;
|
||||
|
||||
if (check_autohide (event))
|
||||
@@ -4138,8 +4139,10 @@ gdk_surface_handle_event (GdkEvent *event)
|
||||
g_signal_emit (gdk_event_get_surface (event), signals[EVENT], 0, event, &handled);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (gdk_profiler_is_running ())
|
||||
add_event_mark (event, begin_time, g_get_monotonic_time () - begin_time);
|
||||
#endif
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
@@ -51,9 +51,9 @@ GdkTexture * gdk_texture_new_from_file (GFile
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_texture_get_width (GdkTexture *texture) G_GNUC_PURE;
|
||||
int gdk_texture_get_width (GdkTexture *texture);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_texture_get_height (GdkTexture *texture) G_GNUC_PURE;
|
||||
int gdk_texture_get_height (GdkTexture *texture);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_texture_download (GdkTexture *texture,
|
||||
|
@@ -1,12 +0,0 @@
|
||||
wayland_cursor_sources = files([
|
||||
'wayland-cursor.c',
|
||||
'xcursor.c',
|
||||
'os-compatibility.c'
|
||||
])
|
||||
|
||||
libwayland_cursor = static_library('wayland+cursor',
|
||||
sources: wayland_cursor_sources,
|
||||
include_directories: [ confinc, ],
|
||||
dependencies: [ glib_dep, ],
|
||||
c_args: common_cflags,
|
||||
link_args: common_ldflags)
|
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Collabora, Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define HAVE_MEMFD_CREATE
|
||||
#ifdef HAVE_MEMFD_CREATE
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "os-compatibility.h"
|
||||
|
||||
#ifndef HAVE_MKOSTEMP
|
||||
static int
|
||||
set_cloexec_or_close(int fd)
|
||||
{
|
||||
long flags;
|
||||
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
flags = fcntl(fd, F_GETFD);
|
||||
if (flags == -1)
|
||||
goto err;
|
||||
|
||||
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
|
||||
goto err;
|
||||
|
||||
return fd;
|
||||
|
||||
err:
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
create_tmpfile_cloexec(char *tmpname)
|
||||
{
|
||||
int fd;
|
||||
|
||||
#ifdef HAVE_MKOSTEMP
|
||||
fd = mkostemp(tmpname, O_CLOEXEC);
|
||||
if (fd >= 0)
|
||||
unlink(tmpname);
|
||||
#else
|
||||
fd = mkstemp(tmpname);
|
||||
if (fd >= 0) {
|
||||
fd = set_cloexec_or_close(fd);
|
||||
unlink(tmpname);
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new, unique, anonymous file of the given size, and
|
||||
* return the file descriptor for it. The file descriptor is set
|
||||
* CLOEXEC. The file is immediately suitable for mmap()'ing
|
||||
* the given size at offset zero.
|
||||
*
|
||||
* The file should not have a permanent backing store like a disk,
|
||||
* but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
|
||||
*
|
||||
* The file name is deleted from the file system.
|
||||
*
|
||||
* The file is suitable for buffer sharing between processes by
|
||||
* transmitting the file descriptor over Unix sockets using the
|
||||
* SCM_RIGHTS methods.
|
||||
*
|
||||
* If the C library implements posix_fallocate(), it is used to
|
||||
* guarantee that disk space is available for the file at the
|
||||
* given size. If disk space is insufficent, errno is set to ENOSPC.
|
||||
* If posix_fallocate() is not supported, program may receive
|
||||
* SIGBUS on accessing mmap()'ed file contents instead.
|
||||
*
|
||||
* If the C library implements memfd_create(), it is used to create the
|
||||
* file purely in memory, without any backing file name on the file
|
||||
* system, and then sealing off the possibility of shrinking it. This
|
||||
* can then be checked before accessing mmap()'ed file contents, to
|
||||
* make sure SIGBUS can't happen. It also avoids requiring
|
||||
* XDG_RUNTIME_DIR.
|
||||
*/
|
||||
int
|
||||
os_create_anonymous_file(off_t size)
|
||||
{
|
||||
static const char template[] = "/wayland-cursor-shared-XXXXXX";
|
||||
const char *path;
|
||||
char *name;
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
#ifdef HAVE_MEMFD_CREATE
|
||||
fd = memfd_create("wayland-cursor", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
if (fd >= 0) {
|
||||
/* We can add this seal before calling posix_fallocate(), as
|
||||
* the file is currently zero-sized anyway.
|
||||
*
|
||||
* There is also no need to check for the return value, we
|
||||
* couldn't do anything with it anyway.
|
||||
*/
|
||||
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
path = getenv("XDG_RUNTIME_DIR");
|
||||
if (!path) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
name = malloc(strlen(path) + sizeof(template));
|
||||
if (!name)
|
||||
return -1;
|
||||
|
||||
strcpy(name, path);
|
||||
strcat(name, template);
|
||||
|
||||
fd = create_tmpfile_cloexec(name);
|
||||
|
||||
free(name);
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POSIX_FALLOCATE
|
||||
ret = posix_fallocate(fd, 0, size);
|
||||
if (ret != 0) {
|
||||
close(fd);
|
||||
errno = ret;
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
ret = ftruncate(fd, size);
|
||||
if (ret < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Collabora, Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef OS_COMPATIBILITY_H
|
||||
#define OS_COMPATIBILITY_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
int
|
||||
os_create_anonymous_file(off_t size);
|
||||
|
||||
#endif /* OS_COMPATIBILITY_H */
|
@@ -1,385 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "xcursor.h"
|
||||
#include "wayland-cursor.h"
|
||||
#include "wayland-client.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <os-compatibility.h>
|
||||
#include <glib.h>
|
||||
|
||||
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
||||
|
||||
struct shm_pool {
|
||||
struct wl_shm_pool *pool;
|
||||
int fd;
|
||||
unsigned int size;
|
||||
unsigned int used;
|
||||
char *data;
|
||||
};
|
||||
|
||||
static struct shm_pool *
|
||||
shm_pool_create(struct wl_shm *shm, int size)
|
||||
{
|
||||
struct shm_pool *pool;
|
||||
|
||||
pool = malloc(sizeof *pool);
|
||||
if (!pool)
|
||||
return NULL;
|
||||
|
||||
pool->fd = os_create_anonymous_file (size);
|
||||
if (pool->fd < 0)
|
||||
goto err_free;
|
||||
|
||||
pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
pool->fd, 0);
|
||||
|
||||
if (pool->data == MAP_FAILED)
|
||||
goto err_close;
|
||||
|
||||
pool->pool = wl_shm_create_pool(shm, pool->fd, size);
|
||||
pool->size = size;
|
||||
pool->used = 0;
|
||||
|
||||
return pool;
|
||||
|
||||
err_close:
|
||||
close(pool->fd);
|
||||
err_free:
|
||||
free(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
shm_pool_resize(struct shm_pool *pool, int size)
|
||||
{
|
||||
if (ftruncate(pool->fd, size) < 0)
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_POSIX_FALLOCATE
|
||||
errno = posix_fallocate(pool->fd, 0, size);
|
||||
if (errno != 0)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
wl_shm_pool_resize(pool->pool, size);
|
||||
|
||||
munmap(pool->data, pool->size);
|
||||
|
||||
pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
pool->fd, 0);
|
||||
if (pool->data == (void *)-1)
|
||||
return 0;
|
||||
pool->size = size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
shm_pool_allocate(struct shm_pool *pool, int size)
|
||||
{
|
||||
int offset;
|
||||
|
||||
if (pool->used + size > pool->size)
|
||||
if (!shm_pool_resize(pool, 2 * pool->size + size))
|
||||
return -1;
|
||||
|
||||
offset = pool->used;
|
||||
pool->used += size;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void
|
||||
shm_pool_destroy(struct shm_pool *pool)
|
||||
{
|
||||
munmap(pool->data, pool->size);
|
||||
wl_shm_pool_destroy(pool->pool);
|
||||
close(pool->fd);
|
||||
free(pool);
|
||||
}
|
||||
|
||||
|
||||
struct wl_cursor_theme {
|
||||
unsigned int cursor_count;
|
||||
struct wl_cursor **cursors;
|
||||
struct wl_shm *shm;
|
||||
struct shm_pool *pool;
|
||||
int size;
|
||||
char *path;
|
||||
};
|
||||
|
||||
struct cursor_image {
|
||||
struct wl_cursor_image image;
|
||||
struct wl_cursor_theme *theme;
|
||||
struct wl_buffer *buffer;
|
||||
int offset; /* data offset of this image in the shm pool */
|
||||
};
|
||||
|
||||
struct cursor {
|
||||
struct wl_cursor cursor;
|
||||
uint32_t total_delay; /* length of the animation in ms */
|
||||
};
|
||||
|
||||
/** Get an shm buffer for a cursor image
|
||||
*
|
||||
* \param image The cursor image
|
||||
* \return An shm buffer for the cursor image. The user should not destroy
|
||||
* the returned buffer.
|
||||
*/
|
||||
struct wl_buffer *
|
||||
wl_cursor_image_get_buffer(struct wl_cursor_image *_img)
|
||||
{
|
||||
struct cursor_image *image = (struct cursor_image *) _img;
|
||||
struct wl_cursor_theme *theme = image->theme;
|
||||
|
||||
if (!image->buffer) {
|
||||
image->buffer =
|
||||
wl_shm_pool_create_buffer(theme->pool->pool,
|
||||
image->offset,
|
||||
_img->width, _img->height,
|
||||
_img->width * 4,
|
||||
WL_SHM_FORMAT_ARGB8888);
|
||||
};
|
||||
|
||||
return image->buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
wl_cursor_image_destroy(struct wl_cursor_image *_img)
|
||||
{
|
||||
struct cursor_image *image = (struct cursor_image *) _img;
|
||||
|
||||
if (image->buffer)
|
||||
wl_buffer_destroy(image->buffer);
|
||||
|
||||
free(image);
|
||||
}
|
||||
|
||||
static void
|
||||
wl_cursor_destroy(struct wl_cursor *cursor)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < cursor->image_count; i++)
|
||||
wl_cursor_image_destroy(cursor->images[i]);
|
||||
|
||||
free(cursor->images);
|
||||
free(cursor->name);
|
||||
free(cursor);
|
||||
}
|
||||
|
||||
static struct wl_cursor *
|
||||
wl_cursor_create_from_xcursor_images(XcursorImages *images,
|
||||
struct wl_cursor_theme *theme,
|
||||
const char *name,
|
||||
unsigned int load_size)
|
||||
{
|
||||
struct cursor *cursor;
|
||||
struct cursor_image *image;
|
||||
int i, size;
|
||||
|
||||
cursor = malloc(sizeof *cursor);
|
||||
if (!cursor)
|
||||
return NULL;
|
||||
|
||||
cursor->cursor.images =
|
||||
malloc(images->nimage * sizeof cursor->cursor.images[0]);
|
||||
if (!cursor->cursor.images) {
|
||||
free(cursor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cursor->cursor.name = strdup(name);
|
||||
cursor->cursor.size = load_size;
|
||||
cursor->total_delay = 0;
|
||||
|
||||
for (i = 0; i < images->nimage; i++) {
|
||||
image = malloc(sizeof *image);
|
||||
if (image == NULL)
|
||||
break;
|
||||
|
||||
image->theme = theme;
|
||||
image->buffer = NULL;
|
||||
|
||||
image->image.width = images->images[i]->width;
|
||||
image->image.height = images->images[i]->height;
|
||||
image->image.hotspot_x = images->images[i]->xhot;
|
||||
image->image.hotspot_y = images->images[i]->yhot;
|
||||
image->image.delay = images->images[i]->delay;
|
||||
|
||||
size = image->image.width * image->image.height * 4;
|
||||
image->offset = shm_pool_allocate(theme->pool, size);
|
||||
if (image->offset < 0) {
|
||||
free(image);
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy pixels to shm pool */
|
||||
memcpy(theme->pool->data + image->offset,
|
||||
images->images[i]->pixels, size);
|
||||
cursor->total_delay += image->image.delay;
|
||||
cursor->cursor.images[i] = (struct wl_cursor_image *) image;
|
||||
}
|
||||
cursor->cursor.image_count = i;
|
||||
|
||||
if (cursor->cursor.image_count == 0) {
|
||||
free(cursor->cursor.name);
|
||||
free(cursor->cursor.images);
|
||||
free(cursor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &cursor->cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
load_cursor(struct wl_cursor_theme *theme, const char *name, unsigned int size)
|
||||
{
|
||||
XcursorImages *images;
|
||||
struct wl_cursor *cursor;
|
||||
char *path;
|
||||
|
||||
path = g_strconcat (theme->path, "/", name, NULL);
|
||||
images = xcursor_load_images (path, size);
|
||||
g_free (path);
|
||||
|
||||
if (!images)
|
||||
return;
|
||||
|
||||
cursor = wl_cursor_create_from_xcursor_images(images, theme, name, size);
|
||||
|
||||
if (cursor) {
|
||||
theme->cursor_count++;
|
||||
theme->cursors =
|
||||
realloc(theme->cursors,
|
||||
theme->cursor_count * sizeof theme->cursors[0]);
|
||||
|
||||
if (theme->cursors == NULL) {
|
||||
theme->cursor_count--;
|
||||
free(cursor);
|
||||
} else {
|
||||
theme->cursors[theme->cursor_count - 1] = cursor;
|
||||
}
|
||||
}
|
||||
|
||||
xcursor_images_destroy (images);
|
||||
}
|
||||
|
||||
/** Load a cursor theme to memory shared with the compositor
|
||||
*
|
||||
* \param name The name of the cursor theme to load. If %NULL, the default
|
||||
* theme will be loaded.
|
||||
* \param size Desired size of the cursor images.
|
||||
* \param shm The compositor's shm interface.
|
||||
*
|
||||
* \return An object representing the theme that should be destroyed with
|
||||
* wl_cursor_theme_destroy() or %NULL on error. If no theme with the given
|
||||
* name exists, a default theme will be loaded.
|
||||
*/
|
||||
struct wl_cursor_theme *
|
||||
wl_cursor_theme_create(const char *path, int size, struct wl_shm *shm)
|
||||
{
|
||||
struct wl_cursor_theme *theme;
|
||||
|
||||
theme = malloc(sizeof *theme);
|
||||
if (!theme)
|
||||
return NULL;
|
||||
|
||||
theme->path = strdup (path);
|
||||
theme->size = size;
|
||||
theme->cursor_count = 0;
|
||||
theme->cursors = NULL;
|
||||
|
||||
theme->pool = shm_pool_create(shm, size * size * 4);
|
||||
if (!theme->pool) {
|
||||
free (theme->path);
|
||||
free (theme);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
/** Destroys a cursor theme object
|
||||
*
|
||||
* \param theme The cursor theme to be destroyed
|
||||
*/
|
||||
void
|
||||
wl_cursor_theme_destroy(struct wl_cursor_theme *theme)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < theme->cursor_count; i++)
|
||||
wl_cursor_destroy(theme->cursors[i]);
|
||||
|
||||
shm_pool_destroy(theme->pool);
|
||||
|
||||
free(theme->cursors);
|
||||
free(theme->path);
|
||||
free(theme);
|
||||
}
|
||||
|
||||
/** Get the cursor for a given name from a cursor theme
|
||||
*
|
||||
* \param theme The cursor theme
|
||||
* \param name Name of the desired cursor
|
||||
* \return The theme's cursor of the given name or %NULL if there is no
|
||||
* such cursor
|
||||
*/
|
||||
struct wl_cursor *
|
||||
wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
|
||||
const char *name,
|
||||
unsigned int scale)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int size;
|
||||
|
||||
size = theme->size * scale;
|
||||
|
||||
for (i = 0; i < theme->cursor_count; i++) {
|
||||
if (size == theme->cursors[i]->size &&
|
||||
strcmp(name, theme->cursors[i]->name) == 0)
|
||||
return theme->cursors[i];
|
||||
}
|
||||
|
||||
load_cursor (theme, name, size);
|
||||
|
||||
if (i < theme->cursor_count) {
|
||||
if (size == theme->cursors[i]->size &&
|
||||
strcmp (name, theme->cursors[theme->cursor_count - 1]->name) == 0)
|
||||
return theme->cursors[theme->cursor_count - 1];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WAYLAND_CURSOR_H
|
||||
#define WAYLAND_CURSOR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct wl_cursor_theme;
|
||||
struct wl_buffer;
|
||||
struct wl_shm;
|
||||
|
||||
struct wl_cursor_image {
|
||||
uint32_t width; /* actual width */
|
||||
uint32_t height; /* actual height */
|
||||
uint32_t hotspot_x; /* hot spot x (must be inside image) */
|
||||
uint32_t hotspot_y; /* hot spot y (must be inside image) */
|
||||
uint32_t delay; /* animation delay to next frame (ms) */
|
||||
};
|
||||
|
||||
struct wl_cursor {
|
||||
unsigned int image_count;
|
||||
struct wl_cursor_image **images;
|
||||
char *name;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
struct wl_cursor_theme *
|
||||
wl_cursor_theme_create(const char *name, int size, struct wl_shm *shm);
|
||||
|
||||
void
|
||||
wl_cursor_theme_destroy(struct wl_cursor_theme *theme);
|
||||
|
||||
struct wl_cursor *
|
||||
wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
|
||||
const char *name,
|
||||
unsigned int scale);
|
||||
|
||||
struct wl_buffer *
|
||||
wl_cursor_image_get_buffer(struct wl_cursor_image *image);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1,612 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "xcursor.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
|
||||
/*
|
||||
* From libXcursor/include/X11/extensions/Xcursor.h
|
||||
*/
|
||||
|
||||
#define XcursorTrue 1
|
||||
#define XcursorFalse 0
|
||||
|
||||
/*
|
||||
* Cursor files start with a header. The header
|
||||
* contains a magic number, a version number and a
|
||||
* table of contents which has type and offset information
|
||||
* for the remaining tables in the file.
|
||||
*
|
||||
* File minor versions increment for compatible changes
|
||||
* File major versions increment for incompatible changes (never, we hope)
|
||||
*
|
||||
* Chunks of the same type are always upward compatible. Incompatible
|
||||
* changes are made with new chunk types; the old data can remain under
|
||||
* the old type. Upward compatible changes can add header data as the
|
||||
* header lengths are specified in the file.
|
||||
*
|
||||
* File:
|
||||
* FileHeader
|
||||
* LISTofChunk
|
||||
*
|
||||
* FileHeader:
|
||||
* CARD32 magic magic number
|
||||
* CARD32 header bytes in file header
|
||||
* CARD32 version file version
|
||||
* CARD32 ntoc number of toc entries
|
||||
* LISTofFileToc toc table of contents
|
||||
*
|
||||
* FileToc:
|
||||
* CARD32 type entry type
|
||||
* CARD32 subtype entry subtype (size for images)
|
||||
* CARD32 position absolute file position
|
||||
*/
|
||||
|
||||
#define XCURSOR_MAGIC 0x72756358 /* "Xcur" LSBFirst */
|
||||
|
||||
/*
|
||||
* Current Xcursor version number. Will be substituted by configure
|
||||
* from the version in the libXcursor configure.ac file.
|
||||
*/
|
||||
|
||||
#define XCURSOR_LIB_MAJOR 1
|
||||
#define XCURSOR_LIB_MINOR 1
|
||||
#define XCURSOR_LIB_REVISION 13
|
||||
#define XCURSOR_LIB_VERSION ((XCURSOR_LIB_MAJOR * 10000) + \
|
||||
(XCURSOR_LIB_MINOR * 100) + \
|
||||
(XCURSOR_LIB_REVISION))
|
||||
|
||||
/*
|
||||
* This version number is stored in cursor files; changes to the
|
||||
* file format require updating this version number
|
||||
*/
|
||||
#define XCURSOR_FILE_MAJOR 1
|
||||
#define XCURSOR_FILE_MINOR 0
|
||||
#define XCURSOR_FILE_VERSION ((XCURSOR_FILE_MAJOR << 16) | (XCURSOR_FILE_MINOR))
|
||||
#define XCURSOR_FILE_HEADER_LEN (4 * 4)
|
||||
#define XCURSOR_FILE_TOC_LEN (3 * 4)
|
||||
|
||||
typedef struct _XcursorFileToc {
|
||||
XcursorUInt type; /* chunk type */
|
||||
XcursorUInt subtype; /* subtype (size for images) */
|
||||
XcursorUInt position; /* absolute position in file */
|
||||
} XcursorFileToc;
|
||||
|
||||
typedef struct _XcursorFileHeader {
|
||||
XcursorUInt magic; /* magic number */
|
||||
XcursorUInt header; /* byte length of header */
|
||||
XcursorUInt version; /* file version number */
|
||||
XcursorUInt ntoc; /* number of toc entries */
|
||||
XcursorFileToc *tocs; /* table of contents */
|
||||
} XcursorFileHeader;
|
||||
|
||||
/*
|
||||
* The rest of the file is a list of chunks, each tagged by type
|
||||
* and version.
|
||||
*
|
||||
* Chunk:
|
||||
* ChunkHeader
|
||||
* <extra type-specific header fields>
|
||||
* <type-specific data>
|
||||
*
|
||||
* ChunkHeader:
|
||||
* CARD32 header bytes in chunk header + type header
|
||||
* CARD32 type chunk type
|
||||
* CARD32 subtype chunk subtype
|
||||
* CARD32 version chunk type version
|
||||
*/
|
||||
|
||||
#define XCURSOR_CHUNK_HEADER_LEN (4 * 4)
|
||||
|
||||
typedef struct _XcursorChunkHeader {
|
||||
XcursorUInt header; /* bytes in chunk header */
|
||||
XcursorUInt type; /* chunk type */
|
||||
XcursorUInt subtype; /* chunk subtype (size for images) */
|
||||
XcursorUInt version; /* version of this type */
|
||||
} XcursorChunkHeader;
|
||||
|
||||
/*
|
||||
* Here's a list of the known chunk types
|
||||
*/
|
||||
|
||||
/*
|
||||
* Comments consist of a 4-byte length field followed by
|
||||
* UTF-8 encoded text
|
||||
*
|
||||
* Comment:
|
||||
* ChunkHeader header chunk header
|
||||
* CARD32 length bytes in text
|
||||
* LISTofCARD8 text UTF-8 encoded text
|
||||
*/
|
||||
|
||||
#define XCURSOR_COMMENT_TYPE 0xfffe0001
|
||||
#define XCURSOR_COMMENT_VERSION 1
|
||||
#define XCURSOR_COMMENT_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (1 *4))
|
||||
#define XCURSOR_COMMENT_COPYRIGHT 1
|
||||
#define XCURSOR_COMMENT_LICENSE 2
|
||||
#define XCURSOR_COMMENT_OTHER 3
|
||||
#define XCURSOR_COMMENT_MAX_LEN 0x100000
|
||||
|
||||
typedef struct _XcursorComment {
|
||||
XcursorUInt version;
|
||||
XcursorUInt comment_type;
|
||||
char *comment;
|
||||
} XcursorComment;
|
||||
|
||||
/*
|
||||
* Each cursor image occupies a separate image chunk.
|
||||
* The length of the image header follows the chunk header
|
||||
* so that future versions can extend the header without
|
||||
* breaking older applications
|
||||
*
|
||||
* Image:
|
||||
* ChunkHeader header chunk header
|
||||
* CARD32 width actual width
|
||||
* CARD32 height actual height
|
||||
* CARD32 xhot hot spot x
|
||||
* CARD32 yhot hot spot y
|
||||
* CARD32 delay animation delay
|
||||
* LISTofCARD32 pixels ARGB pixels
|
||||
*/
|
||||
|
||||
#define XCURSOR_IMAGE_TYPE 0xfffd0002
|
||||
#define XCURSOR_IMAGE_VERSION 1
|
||||
#define XCURSOR_IMAGE_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (5*4))
|
||||
#define XCURSOR_IMAGE_MAX_SIZE 0x7fff /* 32767x32767 max cursor size */
|
||||
|
||||
typedef struct _XcursorFile XcursorFile;
|
||||
|
||||
struct _XcursorFile {
|
||||
void *closure;
|
||||
int (*read) (XcursorFile *file, unsigned char *buf, int len);
|
||||
int (*write) (XcursorFile *file, unsigned char *buf, int len);
|
||||
int (*seek) (XcursorFile *file, long offset, int whence);
|
||||
};
|
||||
|
||||
typedef struct _XcursorComments {
|
||||
int ncomment; /* number of comments */
|
||||
XcursorComment **comments; /* array of XcursorComment pointers */
|
||||
} XcursorComments;
|
||||
|
||||
/*
|
||||
* From libXcursor/src/file.c
|
||||
*/
|
||||
|
||||
static XcursorImage *
|
||||
XcursorImageCreate (int width, int height)
|
||||
{
|
||||
XcursorImage *image;
|
||||
|
||||
if (width < 0 || height < 0)
|
||||
return NULL;
|
||||
if (width > XCURSOR_IMAGE_MAX_SIZE || height > XCURSOR_IMAGE_MAX_SIZE)
|
||||
return NULL;
|
||||
|
||||
image = malloc (sizeof (XcursorImage) +
|
||||
width * height * sizeof (XcursorPixel));
|
||||
if (!image)
|
||||
return NULL;
|
||||
image->version = XCURSOR_IMAGE_VERSION;
|
||||
image->pixels = (XcursorPixel *) (image + 1);
|
||||
image->size = width > height ? width : height;
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
image->delay = 0;
|
||||
return image;
|
||||
}
|
||||
|
||||
static void
|
||||
XcursorImageDestroy (XcursorImage *image)
|
||||
{
|
||||
free (image);
|
||||
}
|
||||
|
||||
static XcursorImages *
|
||||
XcursorImagesCreate (int size)
|
||||
{
|
||||
XcursorImages *images;
|
||||
|
||||
images = malloc (sizeof (XcursorImages) +
|
||||
size * sizeof (XcursorImage *));
|
||||
if (!images)
|
||||
return NULL;
|
||||
images->nimage = 0;
|
||||
images->images = (XcursorImage **) (images + 1);
|
||||
images->name = NULL;
|
||||
return images;
|
||||
}
|
||||
|
||||
static void
|
||||
XcursorImagesDestroy (XcursorImages *images)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (!images)
|
||||
return;
|
||||
|
||||
for (n = 0; n < images->nimage; n++)
|
||||
XcursorImageDestroy (images->images[n]);
|
||||
if (images->name)
|
||||
free (images->name);
|
||||
free (images);
|
||||
}
|
||||
|
||||
static XcursorBool
|
||||
_XcursorReadUInt (XcursorFile *file, XcursorUInt *u)
|
||||
{
|
||||
unsigned char bytes[4];
|
||||
|
||||
if (!file || !u)
|
||||
return XcursorFalse;
|
||||
|
||||
if ((*file->read) (file, bytes, 4) != 4)
|
||||
return XcursorFalse;
|
||||
*u = ((bytes[0] << 0) |
|
||||
(bytes[1] << 8) |
|
||||
(bytes[2] << 16) |
|
||||
(bytes[3] << 24));
|
||||
return XcursorTrue;
|
||||
}
|
||||
|
||||
static void
|
||||
_XcursorFileHeaderDestroy (XcursorFileHeader *fileHeader)
|
||||
{
|
||||
free (fileHeader);
|
||||
}
|
||||
|
||||
static XcursorFileHeader *
|
||||
_XcursorFileHeaderCreate (int ntoc)
|
||||
{
|
||||
XcursorFileHeader *fileHeader;
|
||||
|
||||
if (ntoc > 0x10000)
|
||||
return NULL;
|
||||
fileHeader = malloc (sizeof (XcursorFileHeader) +
|
||||
ntoc * sizeof (XcursorFileToc));
|
||||
if (!fileHeader)
|
||||
return NULL;
|
||||
fileHeader->magic = XCURSOR_MAGIC;
|
||||
fileHeader->header = XCURSOR_FILE_HEADER_LEN;
|
||||
fileHeader->version = XCURSOR_FILE_VERSION;
|
||||
fileHeader->ntoc = ntoc;
|
||||
fileHeader->tocs = (XcursorFileToc *) (fileHeader + 1);
|
||||
return fileHeader;
|
||||
}
|
||||
|
||||
static XcursorFileHeader *
|
||||
_XcursorReadFileHeader (XcursorFile *file)
|
||||
{
|
||||
XcursorFileHeader head, *fileHeader;
|
||||
XcursorUInt skip;
|
||||
unsigned int n;
|
||||
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
if (!_XcursorReadUInt (file, &head.magic))
|
||||
return NULL;
|
||||
if (head.magic != XCURSOR_MAGIC)
|
||||
return NULL;
|
||||
if (!_XcursorReadUInt (file, &head.header))
|
||||
return NULL;
|
||||
if (!_XcursorReadUInt (file, &head.version))
|
||||
return NULL;
|
||||
if (!_XcursorReadUInt (file, &head.ntoc))
|
||||
return NULL;
|
||||
skip = head.header - XCURSOR_FILE_HEADER_LEN;
|
||||
if (skip)
|
||||
if ((*file->seek) (file, skip, SEEK_CUR) == EOF)
|
||||
return NULL;
|
||||
fileHeader = _XcursorFileHeaderCreate (head.ntoc);
|
||||
if (!fileHeader)
|
||||
return NULL;
|
||||
fileHeader->magic = head.magic;
|
||||
fileHeader->header = head.header;
|
||||
fileHeader->version = head.version;
|
||||
fileHeader->ntoc = head.ntoc;
|
||||
for (n = 0; n < fileHeader->ntoc; n++)
|
||||
{
|
||||
if (!_XcursorReadUInt (file, &fileHeader->tocs[n].type))
|
||||
break;
|
||||
if (!_XcursorReadUInt (file, &fileHeader->tocs[n].subtype))
|
||||
break;
|
||||
if (!_XcursorReadUInt (file, &fileHeader->tocs[n].position))
|
||||
break;
|
||||
}
|
||||
if (n != fileHeader->ntoc)
|
||||
{
|
||||
_XcursorFileHeaderDestroy (fileHeader);
|
||||
return NULL;
|
||||
}
|
||||
return fileHeader;
|
||||
}
|
||||
|
||||
static XcursorBool
|
||||
_XcursorSeekToToc (XcursorFile *file,
|
||||
XcursorFileHeader *fileHeader,
|
||||
int toc)
|
||||
{
|
||||
if (!file || !fileHeader || \
|
||||
(*file->seek) (file, fileHeader->tocs[toc].position, SEEK_SET) == EOF)
|
||||
return XcursorFalse;
|
||||
return XcursorTrue;
|
||||
}
|
||||
|
||||
static XcursorBool
|
||||
_XcursorFileReadChunkHeader (XcursorFile *file,
|
||||
XcursorFileHeader *fileHeader,
|
||||
int toc,
|
||||
XcursorChunkHeader *chunkHeader)
|
||||
{
|
||||
if (!file || !fileHeader || !chunkHeader)
|
||||
return XcursorFalse;
|
||||
if (!_XcursorSeekToToc (file, fileHeader, toc))
|
||||
return XcursorFalse;
|
||||
if (!_XcursorReadUInt (file, &chunkHeader->header))
|
||||
return XcursorFalse;
|
||||
if (!_XcursorReadUInt (file, &chunkHeader->type))
|
||||
return XcursorFalse;
|
||||
if (!_XcursorReadUInt (file, &chunkHeader->subtype))
|
||||
return XcursorFalse;
|
||||
if (!_XcursorReadUInt (file, &chunkHeader->version))
|
||||
return XcursorFalse;
|
||||
/* sanity check */
|
||||
if (chunkHeader->type != fileHeader->tocs[toc].type ||
|
||||
chunkHeader->subtype != fileHeader->tocs[toc].subtype)
|
||||
return XcursorFalse;
|
||||
return XcursorTrue;
|
||||
}
|
||||
|
||||
#define dist(a,b) ((a) > (b) ? (a) - (b) : (b) - (a))
|
||||
|
||||
static XcursorDim
|
||||
_XcursorFindBestSize (XcursorFileHeader *fileHeader,
|
||||
XcursorDim size,
|
||||
int *nsizesp)
|
||||
{
|
||||
unsigned int n;
|
||||
int nsizes = 0;
|
||||
XcursorDim bestSize = 0;
|
||||
XcursorDim thisSize;
|
||||
|
||||
if (!fileHeader || !nsizesp)
|
||||
return 0;
|
||||
|
||||
for (n = 0; n < fileHeader->ntoc; n++)
|
||||
{
|
||||
if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
|
||||
continue;
|
||||
thisSize = fileHeader->tocs[n].subtype;
|
||||
if (!bestSize || dist (thisSize, size) < dist (bestSize, size))
|
||||
{
|
||||
bestSize = thisSize;
|
||||
nsizes = 1;
|
||||
}
|
||||
else if (thisSize == bestSize)
|
||||
nsizes++;
|
||||
}
|
||||
*nsizesp = nsizes;
|
||||
return bestSize;
|
||||
}
|
||||
|
||||
static int
|
||||
_XcursorFindImageToc (XcursorFileHeader *fileHeader,
|
||||
XcursorDim size,
|
||||
int count)
|
||||
{
|
||||
unsigned int toc;
|
||||
XcursorDim thisSize;
|
||||
|
||||
if (!fileHeader)
|
||||
return 0;
|
||||
|
||||
for (toc = 0; toc < fileHeader->ntoc; toc++)
|
||||
{
|
||||
if (fileHeader->tocs[toc].type != XCURSOR_IMAGE_TYPE)
|
||||
continue;
|
||||
thisSize = fileHeader->tocs[toc].subtype;
|
||||
if (thisSize != size)
|
||||
continue;
|
||||
if (!count)
|
||||
break;
|
||||
count--;
|
||||
}
|
||||
if (toc == fileHeader->ntoc)
|
||||
return -1;
|
||||
return toc;
|
||||
}
|
||||
|
||||
static XcursorImage *
|
||||
_XcursorReadImage (XcursorFile *file,
|
||||
XcursorFileHeader *fileHeader,
|
||||
int toc)
|
||||
{
|
||||
XcursorChunkHeader chunkHeader;
|
||||
XcursorImage head;
|
||||
XcursorImage *image;
|
||||
int n;
|
||||
XcursorPixel *p;
|
||||
|
||||
if (!file || !fileHeader)
|
||||
return NULL;
|
||||
|
||||
if (!_XcursorFileReadChunkHeader (file, fileHeader, toc, &chunkHeader))
|
||||
return NULL;
|
||||
if (!_XcursorReadUInt (file, &head.width))
|
||||
return NULL;
|
||||
if (!_XcursorReadUInt (file, &head.height))
|
||||
return NULL;
|
||||
if (!_XcursorReadUInt (file, &head.xhot))
|
||||
return NULL;
|
||||
if (!_XcursorReadUInt (file, &head.yhot))
|
||||
return NULL;
|
||||
if (!_XcursorReadUInt (file, &head.delay))
|
||||
return NULL;
|
||||
/* sanity check data */
|
||||
if (head.width > XCURSOR_IMAGE_MAX_SIZE ||
|
||||
head.height > XCURSOR_IMAGE_MAX_SIZE)
|
||||
return NULL;
|
||||
if (head.width == 0 || head.height == 0)
|
||||
return NULL;
|
||||
if (head.xhot > head.width || head.yhot > head.height)
|
||||
return NULL;
|
||||
|
||||
/* Create the image and initialize it */
|
||||
image = XcursorImageCreate (head.width, head.height);
|
||||
if (image == NULL)
|
||||
return NULL;
|
||||
if (chunkHeader.version < image->version)
|
||||
image->version = chunkHeader.version;
|
||||
image->size = chunkHeader.subtype;
|
||||
image->xhot = head.xhot;
|
||||
image->yhot = head.yhot;
|
||||
image->delay = head.delay;
|
||||
n = image->width * image->height;
|
||||
p = image->pixels;
|
||||
while (n--)
|
||||
{
|
||||
if (!_XcursorReadUInt (file, p))
|
||||
{
|
||||
XcursorImageDestroy (image);
|
||||
return NULL;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
static XcursorImages *
|
||||
XcursorXcFileLoadImages (XcursorFile *file, int size)
|
||||
{
|
||||
XcursorFileHeader *fileHeader;
|
||||
XcursorDim bestSize;
|
||||
int nsize;
|
||||
XcursorImages *images;
|
||||
int n;
|
||||
int toc;
|
||||
|
||||
if (!file || size < 0)
|
||||
return NULL;
|
||||
fileHeader = _XcursorReadFileHeader (file);
|
||||
if (!fileHeader)
|
||||
return NULL;
|
||||
bestSize = _XcursorFindBestSize (fileHeader, (XcursorDim) size, &nsize);
|
||||
if (!bestSize)
|
||||
{
|
||||
_XcursorFileHeaderDestroy (fileHeader);
|
||||
return NULL;
|
||||
}
|
||||
images = XcursorImagesCreate (nsize);
|
||||
if (!images)
|
||||
{
|
||||
_XcursorFileHeaderDestroy (fileHeader);
|
||||
return NULL;
|
||||
}
|
||||
for (n = 0; n < nsize; n++)
|
||||
{
|
||||
toc = _XcursorFindImageToc (fileHeader, bestSize, n);
|
||||
if (toc < 0)
|
||||
break;
|
||||
images->images[images->nimage] = _XcursorReadImage (file, fileHeader,
|
||||
toc);
|
||||
if (!images->images[images->nimage])
|
||||
break;
|
||||
images->nimage++;
|
||||
}
|
||||
_XcursorFileHeaderDestroy (fileHeader);
|
||||
if (images->nimage != nsize)
|
||||
{
|
||||
XcursorImagesDestroy (images);
|
||||
images = NULL;
|
||||
}
|
||||
return images;
|
||||
}
|
||||
|
||||
static int
|
||||
_XcursorStdioFileRead (XcursorFile *file, unsigned char *buf, int len)
|
||||
{
|
||||
FILE *f = file->closure;
|
||||
return fread (buf, 1, len, f);
|
||||
}
|
||||
|
||||
static int
|
||||
_XcursorStdioFileWrite (XcursorFile *file, unsigned char *buf, int len)
|
||||
{
|
||||
FILE *f = file->closure;
|
||||
return fwrite (buf, 1, len, f);
|
||||
}
|
||||
|
||||
static int
|
||||
_XcursorStdioFileSeek (XcursorFile *file, long offset, int whence)
|
||||
{
|
||||
FILE *f = file->closure;
|
||||
return fseek (f, offset, whence);
|
||||
}
|
||||
|
||||
static void
|
||||
_XcursorStdioFileInitialize (FILE *stdfile, XcursorFile *file)
|
||||
{
|
||||
file->closure = stdfile;
|
||||
file->read = _XcursorStdioFileRead;
|
||||
file->write = _XcursorStdioFileWrite;
|
||||
file->seek = _XcursorStdioFileSeek;
|
||||
}
|
||||
|
||||
static XcursorImages *
|
||||
XcursorFileLoadImages (FILE *file, int size)
|
||||
{
|
||||
XcursorFile f;
|
||||
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
_XcursorStdioFileInitialize (file, &f);
|
||||
return XcursorXcFileLoadImages (&f, size);
|
||||
}
|
||||
|
||||
XcursorImages *
|
||||
xcursor_load_images (const char *path, int size)
|
||||
{
|
||||
FILE *f;
|
||||
XcursorImages *images;
|
||||
|
||||
f = fopen (path, "r");
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
images = XcursorFileLoadImages (f, size);
|
||||
fclose (f);
|
||||
|
||||
return images;
|
||||
}
|
||||
|
||||
void
|
||||
xcursor_images_destroy (XcursorImages *images)
|
||||
{
|
||||
XcursorImagesDestroy (images);
|
||||
}
|
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XCURSOR_H
|
||||
#define XCURSOR_H
|
||||
|
||||
typedef int XcursorBool;
|
||||
typedef unsigned int XcursorUInt;
|
||||
|
||||
typedef XcursorUInt XcursorDim;
|
||||
typedef XcursorUInt XcursorPixel;
|
||||
|
||||
typedef struct _XcursorImage {
|
||||
XcursorUInt version; /* version of the image data */
|
||||
XcursorDim size; /* nominal size for matching */
|
||||
XcursorDim width; /* actual width */
|
||||
XcursorDim height; /* actual height */
|
||||
XcursorDim xhot; /* hot spot x (must be inside image) */
|
||||
XcursorDim yhot; /* hot spot y (must be inside image) */
|
||||
XcursorUInt delay; /* animation delay to next frame (ms) */
|
||||
XcursorPixel *pixels; /* pointer to pixels */
|
||||
} XcursorImage;
|
||||
|
||||
/*
|
||||
* Other data structures exposed by the library API
|
||||
*/
|
||||
typedef struct _XcursorImages {
|
||||
int nimage; /* number of images */
|
||||
XcursorImage **images; /* array of XcursorImage pointers */
|
||||
char *name; /* name used to load images */
|
||||
} XcursorImages;
|
||||
|
||||
void
|
||||
xcursor_images_destroy (XcursorImages *images);
|
||||
|
||||
XcursorImages *
|
||||
xcursor_load_images (const char *path, int size);
|
||||
|
||||
#endif
|
@@ -33,7 +33,8 @@
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkwayland.h"
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include "cursor/wayland-cursor.h"
|
||||
|
||||
#include <wayland-cursor.h>
|
||||
|
||||
static void
|
||||
gdk_wayland_cursor_remove_from_cache (gpointer data, GObject *cursor)
|
||||
@@ -118,12 +119,11 @@ name_fallback (const gchar *name)
|
||||
static struct wl_cursor *
|
||||
gdk_wayland_cursor_load_for_name (GdkWaylandDisplay *display_wayland,
|
||||
struct wl_cursor_theme *theme,
|
||||
int scale,
|
||||
const char *name)
|
||||
{
|
||||
struct wl_cursor *c;
|
||||
|
||||
c = wl_cursor_theme_get_cursor (theme, name, scale);
|
||||
c = wl_cursor_theme_get_cursor (theme, name);
|
||||
if (!c)
|
||||
{
|
||||
const char *fallback;
|
||||
@@ -131,7 +131,7 @@ gdk_wayland_cursor_load_for_name (GdkWaylandDisplay *display_wayland,
|
||||
fallback = name_fallback (name);
|
||||
if (fallback)
|
||||
{
|
||||
c = wl_cursor_theme_get_cursor (theme, fallback, scale);
|
||||
c = wl_cursor_theme_get_cursor (theme, fallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,8 +172,7 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
goto none;
|
||||
|
||||
c = gdk_wayland_cursor_load_for_name (display,
|
||||
_gdk_wayland_display_get_cursor_theme (display),
|
||||
desired_scale,
|
||||
_gdk_wayland_display_get_scaled_cursor_theme (display, desired_scale),
|
||||
gdk_cursor_get_name (cursor));
|
||||
if (c)
|
||||
{
|
||||
@@ -271,8 +270,7 @@ _gdk_wayland_cursor_get_next_image_index (GdkWaylandDisplay *display,
|
||||
}
|
||||
|
||||
c = gdk_wayland_cursor_load_for_name (display,
|
||||
_gdk_wayland_display_get_cursor_theme (display),
|
||||
scale,
|
||||
_gdk_wayland_display_get_scaled_cursor_theme (display, scale),
|
||||
gdk_cursor_get_name (cursor));
|
||||
|
||||
if (c)
|
||||
|
@@ -47,7 +47,6 @@
|
||||
#include "gdkglcontext-wayland.h"
|
||||
#include "gdkvulkancontext-wayland.h"
|
||||
#include "gdkwaylandmonitor.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include <wayland/pointer-gestures-unstable-v1-client-protocol.h>
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
@@ -726,6 +725,7 @@ static void
|
||||
gdk_wayland_display_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (object);
|
||||
guint i;
|
||||
|
||||
_gdk_wayland_display_finalize_cursors (display_wayland);
|
||||
|
||||
@@ -733,10 +733,13 @@ gdk_wayland_display_finalize (GObject *object)
|
||||
g_free (display_wayland->cursor_theme_name);
|
||||
xkb_context_unref (display_wayland->xkb_context);
|
||||
|
||||
if (display_wayland->cursor_theme)
|
||||
for (i = 0; i < GDK_WAYLAND_THEME_SCALES_COUNT; i++)
|
||||
{
|
||||
wl_cursor_theme_destroy (display_wayland->cursor_theme);
|
||||
display_wayland->cursor_theme = NULL;
|
||||
if (display_wayland->scaled_cursor_themes[i])
|
||||
{
|
||||
wl_cursor_theme_destroy (display_wayland->scaled_cursor_themes[i]);
|
||||
display_wayland->scaled_cursor_themes[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_ptr_array_free (display_wayland->monitors, TRUE);
|
||||
@@ -1056,33 +1059,6 @@ gdk_wayland_display_get_toplevel_surfaces (GdkDisplay *display)
|
||||
return GDK_WAYLAND_DISPLAY (display)->toplevels;
|
||||
}
|
||||
|
||||
static struct wl_cursor_theme *
|
||||
get_cursor_theme (GdkWaylandDisplay *display_wayland,
|
||||
const char *name,
|
||||
int size)
|
||||
{
|
||||
const char * const *xdg_data_dirs;
|
||||
struct wl_cursor_theme *theme = NULL;
|
||||
int i;
|
||||
|
||||
xdg_data_dirs = g_get_system_data_dirs ();
|
||||
for (i = 0; xdg_data_dirs[i]; i++)
|
||||
{
|
||||
char *path = g_build_filename (xdg_data_dirs[i], "icons", name, "cursors", NULL);
|
||||
|
||||
if (g_file_test (path, G_FILE_TEST_IS_DIR))
|
||||
theme = wl_cursor_theme_create (path, size, display_wayland->shm);
|
||||
|
||||
g_free (path);
|
||||
|
||||
if (theme)
|
||||
return theme;
|
||||
}
|
||||
|
||||
/* This may fall back to builtin cursors */
|
||||
return wl_cursor_theme_create ("/usr/share/icons/default/cursors", size, display_wayland->shm);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
|
||||
const gchar *name,
|
||||
@@ -1090,6 +1066,7 @@ gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY(display);
|
||||
struct wl_cursor_theme *theme;
|
||||
int i;
|
||||
|
||||
g_assert (display_wayland);
|
||||
g_assert (display_wayland->shm);
|
||||
@@ -1098,20 +1075,22 @@ gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
|
||||
display_wayland->cursor_theme_size == size)
|
||||
return;
|
||||
|
||||
theme = get_cursor_theme (display_wayland, name, size);
|
||||
|
||||
theme = wl_cursor_theme_load (name, size, display_wayland->shm);
|
||||
if (theme == NULL)
|
||||
{
|
||||
g_warning ("Failed to load cursor theme %s", name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (display_wayland->cursor_theme)
|
||||
for (i = 0; i < GDK_WAYLAND_THEME_SCALES_COUNT; i++)
|
||||
{
|
||||
wl_cursor_theme_destroy (display_wayland->cursor_theme);
|
||||
display_wayland->cursor_theme = NULL;
|
||||
if (display_wayland->scaled_cursor_themes[i])
|
||||
{
|
||||
wl_cursor_theme_destroy (display_wayland->scaled_cursor_themes[i]);
|
||||
display_wayland->scaled_cursor_themes[i] = NULL;
|
||||
}
|
||||
}
|
||||
display_wayland->cursor_theme = theme;
|
||||
display_wayland->scaled_cursor_themes[0] = theme;
|
||||
if (display_wayland->cursor_theme_name != NULL)
|
||||
g_free (display_wayland->cursor_theme_name);
|
||||
display_wayland->cursor_theme_name = g_strdup (name);
|
||||
@@ -1119,11 +1098,31 @@ gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
|
||||
}
|
||||
|
||||
struct wl_cursor_theme *
|
||||
_gdk_wayland_display_get_cursor_theme (GdkWaylandDisplay *display_wayland)
|
||||
_gdk_wayland_display_get_scaled_cursor_theme (GdkWaylandDisplay *display_wayland,
|
||||
guint scale)
|
||||
{
|
||||
g_assert (display_wayland->cursor_theme_name);
|
||||
struct wl_cursor_theme *theme;
|
||||
|
||||
return display_wayland->cursor_theme;
|
||||
g_assert (display_wayland->cursor_theme_name);
|
||||
g_assert (scale <= GDK_WAYLAND_MAX_THEME_SCALE);
|
||||
g_assert (scale >= 1);
|
||||
|
||||
theme = display_wayland->scaled_cursor_themes[scale - 1];
|
||||
if (!theme)
|
||||
{
|
||||
theme = wl_cursor_theme_load (display_wayland->cursor_theme_name,
|
||||
display_wayland->cursor_theme_size * scale,
|
||||
display_wayland->shm);
|
||||
if (theme == NULL)
|
||||
{
|
||||
g_warning ("Failed to load cursor theme %s with scale %u",
|
||||
display_wayland->cursor_theme_name, scale);
|
||||
return NULL;
|
||||
}
|
||||
display_wayland->scaled_cursor_themes[scale - 1] = theme;
|
||||
}
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1132,7 +1131,6 @@ _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland)
|
||||
guint size;
|
||||
const gchar *name;
|
||||
GValue v = G_VALUE_INIT;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
|
||||
g_assert (display_wayland);
|
||||
g_assert (display_wayland->shm);
|
||||
@@ -1152,12 +1150,6 @@ _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland)
|
||||
|
||||
gdk_wayland_display_set_cursor_theme (GDK_DISPLAY (display_wayland), name, size);
|
||||
g_value_unset (&v);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
{
|
||||
gdk_profiler_add_mark (before * 1000, (g_get_monotonic_time () - before) * 1000, "wayland", "load cursor theme");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
guint32
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-cursor.h>
|
||||
#include <wayland-egl.h>
|
||||
#include <gdk/wayland/tablet-unstable-v2-client-protocol.h>
|
||||
#include <gdk/wayland/gtk-shell-client-protocol.h>
|
||||
@@ -44,7 +45,6 @@
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkwaylanddevice.h"
|
||||
#include "cursor/wayland-cursor.h"
|
||||
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
@@ -126,7 +126,7 @@ struct _GdkWaylandDisplay
|
||||
|
||||
GList *current_popups;
|
||||
|
||||
struct wl_cursor_theme *cursor_theme;
|
||||
struct wl_cursor_theme *scaled_cursor_themes[GDK_WAYLAND_THEME_SCALES_COUNT];
|
||||
gchar *cursor_theme_name;
|
||||
int cursor_theme_size;
|
||||
GHashTable *cursor_surface_cache;
|
||||
|
@@ -31,7 +31,6 @@
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
|
||||
#include "gdkintl.h"
|
||||
|
||||
@@ -239,7 +238,6 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
gdk_profiler_add_mark (g_get_monotonic_time () * 1000, 0, "wayland", "swap buffers");
|
||||
if (display_wayland->have_egl_swap_buffers_with_damage)
|
||||
{
|
||||
int i, j, n_rects = cairo_region_num_rectangles (painted);
|
||||
|
@@ -57,7 +57,8 @@ gboolean _gdk_wayland_keymap_key_is_modifier (GdkKeymap *keymap,
|
||||
void _gdk_wayland_display_init_cursors (GdkWaylandDisplay *display);
|
||||
void _gdk_wayland_display_finalize_cursors (GdkWaylandDisplay *display);
|
||||
|
||||
struct wl_cursor_theme * _gdk_wayland_display_get_cursor_theme (GdkWaylandDisplay *display_wayland);
|
||||
struct wl_cursor_theme * _gdk_wayland_display_get_scaled_cursor_theme (GdkWaylandDisplay *display_wayland,
|
||||
guint scale);
|
||||
|
||||
void _gdk_wayland_display_get_default_cursor_size (GdkDisplay *display,
|
||||
guint *width,
|
||||
|
@@ -357,7 +357,6 @@ frame_callback (void *data,
|
||||
GdkFrameClock *clock = gdk_surface_get_frame_clock (surface);
|
||||
GdkFrameTimings *timings;
|
||||
|
||||
gdk_profiler_add_mark (g_get_monotonic_time () * 1000, 0, "wayland", "frame event");
|
||||
GDK_DISPLAY_NOTE (GDK_DISPLAY (display_wayland), EVENTS, g_message ("frame %p", surface));
|
||||
|
||||
wl_callback_destroy (callback);
|
||||
@@ -396,10 +395,10 @@ frame_callback (void *data,
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
|
||||
_gdk_frame_clock_debug_print_timings (clock, timings);
|
||||
#endif
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
_gdk_frame_clock_add_timings_to_profiler (clock, timings);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener frame_listener = {
|
||||
@@ -478,7 +477,6 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||
* before we need to stage any changes, then we can take it back and
|
||||
* use it again.
|
||||
*/
|
||||
gdk_profiler_add_mark (g_get_monotonic_time () * 1000, 0, "wayland", "surface commit");
|
||||
wl_surface_commit (impl->display_server.wl_surface);
|
||||
|
||||
impl->pending_commit = FALSE;
|
||||
@@ -1510,7 +1508,6 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface)
|
||||
if (impl->hint == GDK_SURFACE_TYPE_HINT_DIALOG)
|
||||
_gdk_wayland_screen_add_orphan_dialog (surface);
|
||||
|
||||
gdk_profiler_add_mark (g_get_monotonic_time () * 1000, 0, "wayland", "surface commit");
|
||||
wl_surface_commit (impl->display_server.wl_surface);
|
||||
}
|
||||
|
||||
@@ -2305,7 +2302,6 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
gdk_profiler_add_mark (g_get_monotonic_time () * 1000, 0, "wayland", "surface commit");
|
||||
wl_surface_commit (impl->display_server.wl_surface);
|
||||
|
||||
impl->popup_parent = parent;
|
||||
|
@@ -1,5 +1,3 @@
|
||||
subdir('cursor')
|
||||
|
||||
gdk_wayland_sources = files([
|
||||
'gdkapplaunchcontext-wayland.c',
|
||||
'gdkcairocontext-wayland.c',
|
||||
@@ -35,6 +33,7 @@ gdk_wayland_deps = [
|
||||
xkbdep,
|
||||
wlclientdep,
|
||||
wlprotocolsdep,
|
||||
wlcursordep,
|
||||
wlegldep,
|
||||
]
|
||||
|
||||
@@ -106,5 +105,4 @@ libgdk_wayland = static_library('gdk-wayland',
|
||||
'-DG_LOG_DOMAIN="Gdk"',
|
||||
] + common_cflags,
|
||||
link_args: common_ldflags,
|
||||
link_with: [libwayland_cursor, ],
|
||||
dependencies: [ gdk_deps, gdk_wayland_deps])
|
||||
dependencies: [ gdk_deps, gdk_wayland_deps, ])
|
||||
|
@@ -196,7 +196,7 @@ dump_node (GskRenderNode *node,
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
static inline gboolean
|
||||
node_is_invisible (const GskRenderNode *node)
|
||||
{
|
||||
return node->bounds.size.width == 0.0f ||
|
||||
@@ -237,7 +237,7 @@ sort_border_sides (const GdkRGBA *colors,
|
||||
}
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
static inline gboolean
|
||||
color_matrix_modifies_alpha (GskRenderNode *node)
|
||||
{
|
||||
const graphene_matrix_t *matrix = gsk_color_matrix_node_peek_color_matrix (node);
|
||||
@@ -261,7 +261,7 @@ gsk_rounded_rect_shrink_to_minimum (GskRoundedRect *self)
|
||||
MAX (self->corner[2].height, self->corner[3].height)) * 2);
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
static inline gboolean
|
||||
node_supports_transform (GskRenderNode *node)
|
||||
{
|
||||
/* Some nodes can't handle non-trivial transforms without being
|
||||
@@ -535,16 +535,17 @@ transform_rect (GskGLRenderer *self,
|
||||
RenderOpBuilder *builder,
|
||||
const GskRoundedRect *rect)
|
||||
{
|
||||
const float scale = ops_get_scale (builder);
|
||||
GskRoundedRect r;
|
||||
int i;
|
||||
|
||||
r.bounds.origin.x = builder->dx + rect->bounds.origin.x;
|
||||
r.bounds.origin.y = builder->dy + rect->bounds.origin.y;
|
||||
r.bounds.size = rect->bounds.size;
|
||||
ops_transform_bounds_modelview (builder, &rect->bounds, &r.bounds);
|
||||
|
||||
r.corner[0] = rect->corner[0];
|
||||
r.corner[1] = rect->corner[1];
|
||||
r.corner[2] = rect->corner[2];
|
||||
r.corner[3] = rect->corner[3];
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
r.corner[i].width = rect->corner[i].width * scale;
|
||||
r.corner[i].height = rect->corner[i].height * scale;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -611,7 +612,7 @@ render_fallback_node (GskGLRenderer *self,
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
#if G_ENABLE_DEBUG
|
||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
||||
{
|
||||
cairo_move_to (cr, 0, 0);
|
||||
@@ -744,18 +745,24 @@ render_border_node (GskGLRenderer *self,
|
||||
GskRenderNode *node,
|
||||
RenderOpBuilder *builder)
|
||||
{
|
||||
const float scale = ops_get_scale (builder);
|
||||
const float min_x = builder->dx + node->bounds.origin.x;
|
||||
const float min_y = builder->dy + node->bounds.origin.y;
|
||||
const float max_x = min_x + node->bounds.size.width;
|
||||
const float max_y = min_y + node->bounds.size.height;
|
||||
const GdkRGBA *colors = gsk_border_node_peek_colors (node);
|
||||
const GskRoundedRect *rounded_outline = gsk_border_node_peek_outline (node);
|
||||
const float *widths = gsk_border_node_peek_widths (node);
|
||||
const float *og_widths = gsk_border_node_peek_widths (node);
|
||||
float widths[4];
|
||||
int i;
|
||||
struct {
|
||||
float w;
|
||||
float h;
|
||||
} sizes[4];
|
||||
|
||||
if (widths[0] == widths[1] &&
|
||||
widths[0] == widths[2] &&
|
||||
widths[0] == widths[3] &&
|
||||
if (og_widths[0] == og_widths[1] &&
|
||||
og_widths[0] == og_widths[2] &&
|
||||
og_widths[0] == og_widths[3] &&
|
||||
gdk_rgba_equal (&colors[0], &colors[1]) &&
|
||||
gdk_rgba_equal (&colors[0], &colors[2]) &&
|
||||
gdk_rgba_equal (&colors[0], &colors[3]))
|
||||
@@ -766,7 +773,7 @@ render_border_node (GskGLRenderer *self,
|
||||
op = ops_begin (builder, OP_CHANGE_INSET_SHADOW);
|
||||
op->color = &colors[0];
|
||||
op->outline = transform_rect (self, builder, rounded_outline);
|
||||
op->spread = widths[0];
|
||||
op->spread = og_widths[0] * scale;
|
||||
op->offset[0] = 0;
|
||||
op->offset[1] = 0;
|
||||
|
||||
@@ -774,6 +781,9 @@ render_border_node (GskGLRenderer *self,
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i ++)
|
||||
widths[i] = og_widths[i];
|
||||
|
||||
/* Top left */
|
||||
if (widths[3] > 0)
|
||||
sizes[0].w = MAX (widths[3], rounded_outline->corner[0].width);
|
||||
@@ -819,11 +829,10 @@ render_border_node (GskGLRenderer *self,
|
||||
else
|
||||
sizes[3].h = 0;
|
||||
|
||||
for (i = 0; i < 4; i ++)
|
||||
widths[i] *= scale;
|
||||
|
||||
{
|
||||
const float min_x = builder->dx + node->bounds.origin.x;
|
||||
const float min_y = builder->dy + node->bounds.origin.y;
|
||||
const float max_x = min_x + node->bounds.size.width;
|
||||
const float max_y = min_y + node->bounds.size.height;
|
||||
const GskQuadVertex side_data[4][6] = {
|
||||
/* Top */
|
||||
{
|
||||
@@ -1180,16 +1189,17 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
RenderOpBuilder *builder)
|
||||
{
|
||||
const float scale = ops_get_scale (builder);
|
||||
const GskRoundedRect *clip = gsk_rounded_clip_node_peek_clip (node);
|
||||
GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
|
||||
GskRoundedRect child_clip = *gsk_rounded_clip_node_peek_clip (node);
|
||||
GskRoundedRect transformed_clip;
|
||||
GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
|
||||
gboolean need_offscreen;
|
||||
int i;
|
||||
|
||||
if (node_is_invisible (child))
|
||||
return;
|
||||
|
||||
ops_transform_bounds_modelview (builder, &clip->bounds, &transformed_clip.bounds);
|
||||
transformed_clip = child_clip;
|
||||
ops_transform_bounds_modelview (builder, &child_clip.bounds, &transformed_clip.bounds);
|
||||
|
||||
if (!ops_has_clip (builder))
|
||||
need_offscreen = FALSE;
|
||||
@@ -1205,8 +1215,8 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
* the new clip and add the render ops */
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
transformed_clip.corner[i].width = clip->corner[i].width * scale;
|
||||
transformed_clip.corner[i].height = clip->corner[i].height * scale;
|
||||
transformed_clip.corner[i].width *= scale;
|
||||
transformed_clip.corner[i].height *= scale;
|
||||
}
|
||||
|
||||
ops_push_clip (builder, &transformed_clip);
|
||||
@@ -1215,7 +1225,7 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
GskRoundedRect scaled_clip;
|
||||
graphene_matrix_t scale_matrix;
|
||||
gboolean is_offscreen;
|
||||
TextureRegion region;
|
||||
/* NOTE: We are *not* transforming the clip by the current modelview here.
|
||||
@@ -1224,19 +1234,18 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
*
|
||||
* We do, however, apply the scale factor to the child clip of course.
|
||||
*/
|
||||
scaled_clip.bounds.origin.x = clip->bounds.origin.x * scale;
|
||||
scaled_clip.bounds.origin.y = clip->bounds.origin.y * scale;
|
||||
scaled_clip.bounds.size.width = clip->bounds.size.width * scale;
|
||||
scaled_clip.bounds.size.height = clip->bounds.size.height * scale;
|
||||
|
||||
graphene_matrix_init_scale (&scale_matrix, scale, scale, 1.0f);
|
||||
graphene_matrix_transform_bounds (&scale_matrix, &child_clip.bounds, &child_clip.bounds);
|
||||
|
||||
/* Increase corner radius size by scale factor */
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
scaled_clip.corner[i].width = clip->corner[i].width * scale;
|
||||
scaled_clip.corner[i].height = clip->corner[i].height * scale;
|
||||
child_clip.corner[i].width *= scale;
|
||||
child_clip.corner[i].height *= scale;
|
||||
}
|
||||
|
||||
ops_push_clip (builder, &scaled_clip);
|
||||
ops_push_clip (builder, &child_clip);
|
||||
if (!add_offscreen_ops (self, builder, &node->bounds,
|
||||
child,
|
||||
®ion, &is_offscreen,
|
||||
@@ -1446,9 +1455,6 @@ render_blur_node (GskGLRenderer *self,
|
||||
GskRenderNode *child = gsk_blur_node_get_child (node);
|
||||
TextureRegion blurred_region;
|
||||
|
||||
if (node_is_invisible (child))
|
||||
return;
|
||||
|
||||
if (blur_radius <= 0)
|
||||
{
|
||||
gsk_gl_renderer_add_render_ops (self, child, builder);
|
||||
@@ -1475,6 +1481,7 @@ render_unblurred_inset_shadow_node (GskGLRenderer *self,
|
||||
GskRenderNode *node,
|
||||
RenderOpBuilder *builder)
|
||||
{
|
||||
const float scale = ops_get_scale (builder);
|
||||
const float blur_radius = gsk_inset_shadow_node_get_blur_radius (node);
|
||||
const float dx = gsk_inset_shadow_node_get_dx (node);
|
||||
const float dy = gsk_inset_shadow_node_get_dy (node);
|
||||
@@ -1487,9 +1494,9 @@ render_unblurred_inset_shadow_node (GskGLRenderer *self,
|
||||
op = ops_begin (builder, OP_CHANGE_INSET_SHADOW);
|
||||
op->color = gsk_inset_shadow_node_peek_color (node);
|
||||
op->outline = transform_rect (self, builder, gsk_inset_shadow_node_peek_outline (node));
|
||||
op->spread = spread;
|
||||
op->offset[0] = dx;
|
||||
op->offset[1] = dy;
|
||||
op->spread = spread * scale;
|
||||
op->offset[0] = dx * scale;
|
||||
op->offset[1] = dy * scale;
|
||||
|
||||
load_vertex_data (ops_draw (builder, NULL), node, builder);
|
||||
}
|
||||
@@ -1640,6 +1647,7 @@ render_unblurred_outset_shadow_node (GskGLRenderer *self,
|
||||
GskRenderNode *node,
|
||||
RenderOpBuilder *builder)
|
||||
{
|
||||
const float scale = ops_get_scale (builder);
|
||||
const GskRoundedRect *outline = gsk_outset_shadow_node_peek_outline (node);
|
||||
const float spread = gsk_outset_shadow_node_get_spread (node);
|
||||
const float dx = gsk_outset_shadow_node_get_dx (node);
|
||||
@@ -1650,9 +1658,9 @@ render_unblurred_outset_shadow_node (GskGLRenderer *self,
|
||||
op = ops_begin (builder, OP_CHANGE_UNBLURRED_OUTSET_SHADOW);
|
||||
op->color = gsk_outset_shadow_node_peek_color (node);
|
||||
op->outline = transform_rect (self, builder, outline);
|
||||
op->spread = spread;
|
||||
op->offset[0] = dx;
|
||||
op->offset[1] = dy;
|
||||
op->spread = spread * scale;
|
||||
op->offset[0] = dx * scale;
|
||||
op->offset[1] = dy * scale;
|
||||
|
||||
load_vertex_data (ops_draw (builder, NULL), node, builder);
|
||||
}
|
||||
@@ -2155,24 +2163,14 @@ render_cross_fade_node (GskGLRenderer *self,
|
||||
start_node,
|
||||
&start_region, &is_offscreen1,
|
||||
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY))
|
||||
{
|
||||
gsk_gl_renderer_add_render_ops (self, end_node, builder);
|
||||
return;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
|
||||
if (!add_offscreen_ops (self, builder,
|
||||
&node->bounds,
|
||||
end_node,
|
||||
&end_region, &is_offscreen2,
|
||||
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY))
|
||||
{
|
||||
load_vertex_data_with_region (ops_draw (builder, NULL),
|
||||
node,
|
||||
builder,
|
||||
&start_region,
|
||||
TRUE);
|
||||
return;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
|
||||
ops_set_program (builder, &self->cross_fade_program);
|
||||
|
||||
@@ -2578,7 +2576,6 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
|
||||
gboolean success = TRUE;
|
||||
|
||||
gsk_gl_shader_builder_init (&shader_builder,
|
||||
"/org/gtk/libgsk/glsl/preamble.glsl",
|
||||
"/org/gtk/libgsk/glsl/preamble.vs.glsl",
|
||||
"/org/gtk/libgsk/glsl/preamble.fs.glsl");
|
||||
|
||||
@@ -2773,7 +2770,6 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
GError **error)
|
||||
{
|
||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
|
||||
/* If we didn't get a GdkGLContext before realization, try creating
|
||||
* one now, for our exclusive use.
|
||||
@@ -2803,9 +2799,6 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
self->icon_cache = get_icon_cache_for_display (gdk_surface_get_display (surface), self->atlases);
|
||||
gsk_gl_shadow_cache_init (&self->shadow_cache);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000, (g_get_monotonic_time () - before) * 1000, "gl renderer realize", NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -3492,7 +3485,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
gsk_profiler_push_samples (profiler);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (start_time, cpu_time, "GL render", "");
|
||||
gdk_profiler_add_mark (start_time, cpu_time, "render", "");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ rect_equal (const graphene_rect_t *a,
|
||||
return memcmp (a, b, sizeof (graphene_rect_t)) == 0;
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
static inline gboolean
|
||||
rounded_rect_equal (const GskRoundedRect *r1,
|
||||
const GskRoundedRect *r2)
|
||||
{
|
||||
@@ -31,7 +31,7 @@ rounded_rect_equal (const GskRoundedRect *r1,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
static inline gboolean
|
||||
rounded_rect_corners_equal (const GskRoundedRect *r1,
|
||||
const GskRoundedRect *r2)
|
||||
{
|
||||
@@ -180,15 +180,13 @@ ops_transform_bounds_modelview (const RenderOpBuilder *builder,
|
||||
const graphene_rect_t *src,
|
||||
graphene_rect_t *dst)
|
||||
{
|
||||
graphene_rect_t r = *src;
|
||||
|
||||
g_assert (builder->mv_stack != NULL);
|
||||
g_assert (builder->mv_stack->len >= 1);
|
||||
|
||||
r.origin.x += builder->dx;
|
||||
r.origin.y += builder->dy;
|
||||
gsk_transform_transform_bounds (builder->current_modelview, src, dst);
|
||||
|
||||
gsk_transform_transform_bounds (builder->current_modelview, &r, dst);
|
||||
dst->origin.x += builder->dx * builder->scale_x;
|
||||
dst->origin.y += builder->dy * builder->scale_y;
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -9,17 +9,14 @@
|
||||
|
||||
void
|
||||
gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
|
||||
const char *common_preamble_resource_path,
|
||||
const char *vs_preamble_resource_path,
|
||||
const char *fs_preamble_resource_path)
|
||||
{
|
||||
memset (self, 0, sizeof (*self));
|
||||
|
||||
self->preamble = g_resources_lookup_data (common_preamble_resource_path, 0, NULL);
|
||||
self->vs_preamble = g_resources_lookup_data (vs_preamble_resource_path, 0, NULL);
|
||||
self->fs_preamble = g_resources_lookup_data (fs_preamble_resource_path, 0, NULL);
|
||||
|
||||
g_assert (self->preamble);
|
||||
g_assert (self->vs_preamble);
|
||||
g_assert (self->fs_preamble);
|
||||
}
|
||||
@@ -27,7 +24,6 @@ gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
|
||||
void
|
||||
gsk_gl_shader_builder_finish (GskGLShaderBuilder *self)
|
||||
{
|
||||
g_bytes_unref (self->preamble);
|
||||
g_bytes_unref (self->vs_preamble);
|
||||
g_bytes_unref (self->fs_preamble);
|
||||
}
|
||||
@@ -106,14 +102,13 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
"#version %d\n", self->version);
|
||||
|
||||
vertex_id = glCreateShader (GL_VERTEX_SHADER);
|
||||
glShaderSource (vertex_id, 8,
|
||||
glShaderSource (vertex_id, 7,
|
||||
(const char *[]) {
|
||||
version_buffer,
|
||||
self->debugging ? "#define GSK_DEBUG 1\n" : "",
|
||||
self->legacy ? "#define GSK_LEGACY 1\n" : "",
|
||||
self->gl3 ? "#define GSK_GL3 1\n" : "",
|
||||
self->gles ? "#define GSK_GLES 1\n" : "",
|
||||
g_bytes_get_data (self->preamble, NULL),
|
||||
g_bytes_get_data (self->vs_preamble, NULL),
|
||||
vertex_shader_start
|
||||
},
|
||||
@@ -124,7 +119,6 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
fragment_shader_start - vertex_shader_start
|
||||
});
|
||||
glCompileShader (vertex_id);
|
||||
@@ -136,14 +130,13 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
}
|
||||
|
||||
fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
|
||||
glShaderSource (fragment_id, 8,
|
||||
glShaderSource (fragment_id, 7,
|
||||
(const char *[]) {
|
||||
version_buffer,
|
||||
self->debugging ? "#define GSK_DEBUG 1\n" : "",
|
||||
self->legacy ? "#define GSK_LEGACY 1\n" : "",
|
||||
self->gl3 ? "#define GSK_GL3 1\n" : "",
|
||||
self->gles ? "#define GSK_GLES 1\n" : "",
|
||||
g_bytes_get_data (self->preamble, NULL),
|
||||
g_bytes_get_data (self->fs_preamble, NULL),
|
||||
fragment_shader_start
|
||||
},
|
||||
@@ -155,7 +148,6 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
});
|
||||
glCompileShader (fragment_id);
|
||||
|
||||
|
@@ -8,7 +8,6 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GBytes *preamble;
|
||||
GBytes *vs_preamble;
|
||||
GBytes *fs_preamble;
|
||||
|
||||
@@ -23,7 +22,6 @@ typedef struct
|
||||
|
||||
|
||||
void gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
|
||||
const char *common_preamble_resource_path,
|
||||
const char *vs_preamble_resource_path,
|
||||
const char *fs_preamble_resource_path);
|
||||
void gsk_gl_shader_builder_finish (GskGLShaderBuilder *self);
|
||||
|
@@ -145,9 +145,9 @@ gsk_render_node_get_node_type (GskRenderNode *node)
|
||||
return node->node_class->node_type;
|
||||
}
|
||||
|
||||
G_GNUC_PURE static inline
|
||||
static inline
|
||||
GskRenderNodeType
|
||||
_gsk_render_node_get_node_type (const GskRenderNode *node)
|
||||
_gsk_render_node_get_node_type (GskRenderNode *node)
|
||||
{
|
||||
return node->node_class->node_type;
|
||||
}
|
||||
@@ -248,8 +248,8 @@ gsk_render_node_draw (GskRenderNode *node,
|
||||
* Returns: %TRUE if @node1 and @node2 can be expected to be compared
|
||||
**/
|
||||
gboolean
|
||||
gsk_render_node_can_diff (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2)
|
||||
gsk_render_node_can_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2)
|
||||
{
|
||||
if (node1 == node2)
|
||||
return TRUE;
|
||||
@@ -314,6 +314,9 @@ gsk_render_node_diff (GskRenderNode *node1,
|
||||
return node1->node_class->diff (node1, node2, region);
|
||||
}
|
||||
|
||||
#define GSK_RENDER_NODE_SERIALIZATION_VERSION 0
|
||||
#define GSK_RENDER_NODE_SERIALIZATION_ID "GskRenderNode"
|
||||
|
||||
/**
|
||||
* gsk_render_node_write_to_file:
|
||||
* @node: a #GskRenderNode
|
||||
|
@@ -41,8 +41,8 @@ rectangle_init_from_graphene (cairo_rectangle_int_t *cairo,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_render_node_can_diff_true (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2)
|
||||
gsk_render_node_can_diff_true (GskRenderNode *node1,
|
||||
GskRenderNode *node2)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1707,8 +1707,8 @@ gsk_container_node_draw (GskRenderNode *node,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_container_node_can_diff (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2)
|
||||
gsk_container_node_can_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1726,7 +1726,7 @@ gsk_render_node_add_to_region (GskRenderNode *node,
|
||||
static int
|
||||
gsk_container_node_compare_func (gconstpointer elem1, gconstpointer elem2, gpointer data)
|
||||
{
|
||||
return gsk_render_node_can_diff ((const GskRenderNode *) elem1, (const GskRenderNode *) elem2) ? 0 : 1;
|
||||
return gsk_render_node_can_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2) ? 0 : 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1918,8 +1918,8 @@ gsk_transform_node_draw (GskRenderNode *node,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_transform_node_can_diff (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2)
|
||||
gsk_transform_node_can_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2)
|
||||
{
|
||||
GskTransformNode *self1 = (GskTransformNode *) node1;
|
||||
GskTransformNode *self2 = (GskTransformNode *) node2;
|
||||
@@ -2092,8 +2092,8 @@ gsk_debug_node_draw (GskRenderNode *node,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_debug_node_can_diff (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2)
|
||||
gsk_debug_node_can_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2)
|
||||
{
|
||||
GskDebugNode *self1 = (GskDebugNode *) node1;
|
||||
GskDebugNode *self2 = (GskDebugNode *) node2;
|
||||
|
@@ -28,8 +28,8 @@ struct _GskRenderNodeClass
|
||||
void (* finalize) (GskRenderNode *node);
|
||||
void (* draw) (GskRenderNode *node,
|
||||
cairo_t *cr);
|
||||
gboolean (* can_diff) (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2);
|
||||
gboolean (* can_diff) (GskRenderNode *node1,
|
||||
GskRenderNode *node2);
|
||||
void (* diff) (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
@@ -38,8 +38,8 @@ struct _GskRenderNodeClass
|
||||
GskRenderNode * gsk_render_node_new (const GskRenderNodeClass *node_class,
|
||||
gsize extra_size);
|
||||
|
||||
gboolean gsk_render_node_can_diff (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2) G_GNUC_PURE;
|
||||
gboolean gsk_render_node_can_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2);
|
||||
void gsk_render_node_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
|
@@ -98,16 +98,16 @@ GskRoundedRect * gsk_rounded_rect_shrink (GskRoundedRect
|
||||
float left);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_rounded_rect_is_rectilinear (const GskRoundedRect *self) G_GNUC_PURE;
|
||||
gboolean gsk_rounded_rect_is_rectilinear (const GskRoundedRect *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_rounded_rect_contains_point (const GskRoundedRect *self,
|
||||
const graphene_point_t *point) G_GNUC_PURE;
|
||||
const graphene_point_t *point);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_rounded_rect_contains_rect (const GskRoundedRect *self,
|
||||
const graphene_rect_t *rect) G_GNUC_PURE;
|
||||
const graphene_rect_t *rect);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_rounded_rect_intersects_rect (const GskRoundedRect *self,
|
||||
const graphene_rect_t *rect) G_GNUC_PURE;
|
||||
const graphene_rect_t *rect);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -15,7 +15,7 @@ void gsk_rounded_rect_to_float (const GskRounde
|
||||
float rect[12]);
|
||||
|
||||
gboolean gsk_rounded_rect_equal (gconstpointer rect1,
|
||||
gconstpointer rect2) G_GNUC_PURE;
|
||||
gconstpointer rect2);
|
||||
char * gsk_rounded_rect_to_string (const GskRoundedRect *self);
|
||||
|
||||
|
||||
|
@@ -1773,62 +1773,6 @@ gsk_transform_transform_bounds (GskTransform *self,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_transform_transform_point:
|
||||
* @self: a #GskTransform
|
||||
* @point: a #graphene_point_t
|
||||
* @out_point: (out caller-allocates): return location for
|
||||
* the transformed point
|
||||
*
|
||||
* Transforms a #graphene_point_t using the given transform @self.
|
||||
*/
|
||||
void
|
||||
gsk_transform_transform_point (GskTransform *self,
|
||||
const graphene_point_t *point,
|
||||
graphene_point_t *out_point)
|
||||
{
|
||||
switch (gsk_transform_get_category (self))
|
||||
{
|
||||
case GSK_TRANSFORM_CATEGORY_IDENTITY:
|
||||
*out_point = *point;
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
{
|
||||
float dx, dy;
|
||||
|
||||
gsk_transform_to_translate (self, &dx, &dy);
|
||||
out_point->x = point->x + dx;
|
||||
out_point->y = point->y + dy;
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
{
|
||||
float dx, dy, scale_x, scale_y;
|
||||
|
||||
gsk_transform_to_affine (self, &scale_x, &scale_y, &dx, &dy);
|
||||
|
||||
out_point->x = (point->x * scale_x) + dx;
|
||||
out_point->y = (point->y * scale_y) + dy;
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_UNKNOWN:
|
||||
case GSK_TRANSFORM_CATEGORY_ANY:
|
||||
case GSK_TRANSFORM_CATEGORY_3D:
|
||||
case GSK_TRANSFORM_CATEGORY_2D:
|
||||
default:
|
||||
{
|
||||
graphene_matrix_t mat;
|
||||
|
||||
gsk_transform_to_matrix (self, &mat);
|
||||
graphene_matrix_transform_point (&mat, point, out_point);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_transform_parse_float (GtkCssParser *parser,
|
||||
guint n,
|
||||
|
@@ -116,11 +116,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gsk_transform_transform_bounds (GskTransform *self,
|
||||
const graphene_rect_t *rect,
|
||||
graphene_rect_t *out_rect);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_transform_transform_point (GskTransform *self,
|
||||
const graphene_point_t *point,
|
||||
graphene_point_t *out_point);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -1,5 +1,4 @@
|
||||
gsk_private_gl_shaders = [
|
||||
'resources/glsl/preamble.glsl',
|
||||
'resources/glsl/preamble.fs.glsl',
|
||||
'resources/glsl/preamble.vs.glsl',
|
||||
'resources/glsl/border.glsl',
|
||||
|
@@ -1,11 +1,7 @@
|
||||
// VERTEX_SHADER:
|
||||
uniform vec4 u_color;
|
||||
uniform vec4 u_widths;
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_OUT_ vec4 final_color;
|
||||
_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
|
||||
_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
@@ -13,32 +9,25 @@ void main() {
|
||||
final_color = u_color;
|
||||
final_color.rgb *= final_color.a; // pre-multiply
|
||||
final_color *= u_alpha;
|
||||
|
||||
RoundedRect outside = create_rect(u_outline_rect);
|
||||
RoundedRect inside = rounded_rect_shrink (outside, u_widths);
|
||||
|
||||
rounded_rect_transform(outside, u_modelview);
|
||||
rounded_rect_transform(inside, u_modelview);
|
||||
|
||||
rounded_rect_encode(outside, transformed_outside_outline);
|
||||
rounded_rect_encode(inside, transformed_inside_outline);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform vec4 u_widths;
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_IN_ vec4 final_color;
|
||||
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
|
||||
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) -
|
||||
rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy),
|
||||
0.0, 1.0);
|
||||
RoundedRect outside = create_rect(u_outline_rect);
|
||||
RoundedRect inside = rounded_rect_shrink (outside, u_widths);
|
||||
|
||||
float alpha = clamp (rounded_rect_coverage (outside, f.xy) -
|
||||
rounded_rect_coverage (inside, f.xy),
|
||||
0.0, 1.0);
|
||||
|
||||
setOutputColor(final_color * alpha);
|
||||
}
|
||||
|
@@ -1,12 +1,7 @@
|
||||
// VERTEX_SHADER:
|
||||
uniform vec4 u_color;
|
||||
uniform float u_spread;
|
||||
uniform vec2 u_offset;
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_OUT_ vec4 final_color;
|
||||
_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
|
||||
_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
@@ -14,33 +9,26 @@ void main() {
|
||||
final_color = u_color;
|
||||
final_color.rgb *= final_color.a;
|
||||
final_color *= u_alpha;
|
||||
|
||||
RoundedRect outside = create_rect(u_outline_rect);
|
||||
RoundedRect inside = rounded_rect_shrink(outside, vec4(u_spread));
|
||||
|
||||
rounded_rect_offset(inside, u_offset);
|
||||
|
||||
rounded_rect_transform(outside, u_modelview);
|
||||
rounded_rect_transform(inside, u_modelview);
|
||||
|
||||
rounded_rect_encode(outside, transformed_outside_outline);
|
||||
rounded_rect_encode(inside, transformed_inside_outline);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform float u_spread;
|
||||
uniform vec2 u_offset;
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_IN_ vec4 final_color;
|
||||
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
|
||||
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
vec4 color;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
float alpha = clamp (rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) -
|
||||
rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy),
|
||||
0.0, 1.0);
|
||||
|
||||
setOutputColor(final_color * alpha);
|
||||
RoundedRect outside = create_rect(u_outline_rect);
|
||||
RoundedRect inside = rounded_rect_shrink(outside, vec4(u_spread));
|
||||
color = final_color * clamp (rounded_rect_coverage (outside, f.xy) -
|
||||
rounded_rect_coverage (inside, f.xy - u_offset),
|
||||
0.0, 1.0);
|
||||
setOutputColor(color);
|
||||
}
|
||||
|
@@ -1,9 +1,7 @@
|
||||
// VERTEX_SHADER:
|
||||
uniform vec4 u_color;
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_OUT_ vec4 final_color;
|
||||
_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_outline;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
@@ -14,15 +12,12 @@ void main() {
|
||||
// pre-multiply
|
||||
final_color.rgb *= final_color.a;
|
||||
final_color *= u_alpha;
|
||||
|
||||
RoundedRect outline = create_rect(u_outline_rect);
|
||||
rounded_rect_transform(outline, u_modelview);
|
||||
rounded_rect_encode(outline, transformed_outline);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_IN_ vec4 final_color;
|
||||
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_outline;
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
@@ -30,8 +25,10 @@ void main() {
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
RoundedRect outline = create_rect(u_outline_rect);
|
||||
|
||||
float alpha = Texture(u_source, vUv).a;
|
||||
alpha *= (1.0 - clamp(rounded_rect_coverage(decode_rect(transformed_outline), f.xy), 0.0, 1.0));
|
||||
alpha *= (1.0 - clamp(rounded_rect_coverage(outline, f.xy), 0.0, 1.0));
|
||||
|
||||
vec4 color = final_color * alpha;
|
||||
|
||||
|
@@ -1,3 +1,12 @@
|
||||
#ifdef GSK_GL3
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#ifdef GSK_GLES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
|
||||
uniform sampler2D u_source;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
@@ -6,23 +15,36 @@ uniform vec4 u_viewport;
|
||||
uniform vec4[3] u_clip_rect;
|
||||
|
||||
#if GSK_GLES
|
||||
#define _OUT_ varying
|
||||
#define _IN_ varying
|
||||
#elif GSK_LEGACY
|
||||
#define _OUT_ varying
|
||||
#define _IN_ varying
|
||||
_OUT_ vec4 outputColor;
|
||||
#else
|
||||
#define _OUT_ out
|
||||
#define _IN_ in
|
||||
_OUT_ vec4 outputColor;
|
||||
#endif
|
||||
|
||||
_IN_ vec2 vUv;
|
||||
|
||||
|
||||
|
||||
RoundedRect decode_rect(_ROUNDED_RECT_UNIFORM_ r)
|
||||
struct RoundedRect
|
||||
{
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
return RoundedRect(r[0], r[1], r[2]);
|
||||
#else
|
||||
return r;
|
||||
#endif
|
||||
vec4 bounds;
|
||||
vec4 corner_widths;
|
||||
vec4 corner_heights;
|
||||
};
|
||||
|
||||
// Transform from a GskRoundedRect to a RoundedRect as we need it.
|
||||
RoundedRect
|
||||
create_rect(vec4 data[3])
|
||||
{
|
||||
vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
|
||||
vec4 widths = vec4(data[1].x, data[1].z, data[2].x, data[2].z);
|
||||
vec4 heights = vec4(data[1].y, data[1].w, data[2].y, data[2].w);
|
||||
return RoundedRect(bounds, widths, heights);
|
||||
}
|
||||
|
||||
float
|
||||
@@ -51,15 +73,15 @@ rounded_rect_coverage (RoundedRect r, vec2 p)
|
||||
p.x >= r.bounds.z || p.y >= r.bounds.w)
|
||||
return 0.0;
|
||||
|
||||
vec2 rad_tl = r.corner_points1.xy - r.bounds.xy;
|
||||
vec2 rad_tr = r.corner_points1.zw - r.bounds.zy;
|
||||
vec2 rad_br = r.corner_points2.xy - r.bounds.zw;
|
||||
vec2 rad_bl = r.corner_points2.zw - r.bounds.xw;
|
||||
vec2 rad_tl = vec2(r.corner_widths.x, r.corner_heights.x);
|
||||
vec2 rad_tr = vec2(r.corner_widths.y, r.corner_heights.y);
|
||||
vec2 rad_br = vec2(r.corner_widths.z, r.corner_heights.z);
|
||||
vec2 rad_bl = vec2(r.corner_widths.w, r.corner_heights.w);
|
||||
|
||||
vec2 ref_tl = r.corner_points1.xy;
|
||||
vec2 ref_tr = r.corner_points1.zw;
|
||||
vec2 ref_br = r.corner_points2.xy;
|
||||
vec2 ref_bl = r.corner_points2.zw;
|
||||
vec2 ref_tl = r.bounds.xy + vec2( r.corner_widths.x, r.corner_heights.x);
|
||||
vec2 ref_tr = r.bounds.zy + vec2(-r.corner_widths.y, r.corner_heights.y);
|
||||
vec2 ref_br = r.bounds.zw + vec2(-r.corner_widths.z, -r.corner_heights.z);
|
||||
vec2 ref_bl = r.bounds.xw + vec2( r.corner_widths.w, -r.corner_heights.w);
|
||||
|
||||
float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
|
||||
float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
|
||||
@@ -76,8 +98,37 @@ rounded_rect_coverage (RoundedRect r, vec2 p)
|
||||
return 1.0 - dot(vec4(is_out), corner_coverages);
|
||||
}
|
||||
|
||||
// amount is: top, right, bottom, left
|
||||
RoundedRect
|
||||
rounded_rect_shrink (RoundedRect r, vec4 amount)
|
||||
{
|
||||
vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
|
||||
vec4 new_widths = vec4(0);
|
||||
vec4 new_heights = vec4(0);
|
||||
|
||||
// Left top
|
||||
if (r.corner_widths.x > 0.0) new_widths.x = r.corner_widths.x - amount.w;
|
||||
if (r.corner_heights.x > 0.0) new_heights.x = r.corner_heights.x - amount.x;
|
||||
|
||||
// Top right
|
||||
if (r.corner_widths.y > 0.0) new_widths.y = r.corner_widths.y - amount.y;
|
||||
if (r.corner_heights.y > 0.0) new_heights.y = r.corner_heights.y - amount.x;
|
||||
|
||||
// Bottom right
|
||||
if (r.corner_widths.z > 0.0) new_widths.z = r.corner_widths.z - amount.y;
|
||||
if (r.corner_heights.z > 0.0) new_heights.z = r.corner_heights.z - amount.z;
|
||||
|
||||
// Bottom left
|
||||
if (r.corner_widths.w > 0.0) new_widths.w = r.corner_widths.w - amount.w;
|
||||
if (r.corner_heights.w > 0.0) new_heights.w = r.corner_heights.w - amount.z;
|
||||
|
||||
return RoundedRect (new_bounds, new_widths, new_heights);
|
||||
}
|
||||
|
||||
vec4 Texture(sampler2D sampler, vec2 texCoords) {
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
#if GSK_GLES
|
||||
return texture2D(sampler, texCoords);
|
||||
#elif GSK_LEGACY
|
||||
return texture2D(sampler, texCoords);
|
||||
#else
|
||||
return texture(sampler, texCoords);
|
||||
@@ -90,10 +141,9 @@ void setOutputColor(vec4 color) {
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
|
||||
// We do *NOT* transform the clip rect here since we already
|
||||
// need to do that on the CPU.
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
#if GSK_GLES
|
||||
gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
|
||||
#elif GSK_LEGACY
|
||||
gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
|
||||
#else
|
||||
outputColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
|
||||
|
@@ -1,37 +0,0 @@
|
||||
#ifndef GSK_LEGACY
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
#define _OUT_ varying
|
||||
#define _IN_ varying
|
||||
#define _ROUNDED_RECT_UNIFORM_ vec4[3]
|
||||
#else
|
||||
#define _OUT_ out
|
||||
#define _IN_ in
|
||||
#define _ROUNDED_RECT_UNIFORM_ RoundedRect
|
||||
#endif
|
||||
|
||||
|
||||
struct RoundedRect
|
||||
{
|
||||
vec4 bounds;
|
||||
// Look, arrays can't be in structs if you want to return the struct
|
||||
// from a function in gles or whatever. Just kill me.
|
||||
vec4 corner_points1; // xy = top left, zw = top right
|
||||
vec4 corner_points2; // xy = bottom right, zw = bottom left
|
||||
};
|
||||
|
||||
// Transform from a GskRoundedRect to a RoundedRect as we need it.
|
||||
RoundedRect
|
||||
create_rect(vec4[3] data)
|
||||
{
|
||||
vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
|
||||
|
||||
vec4 corner_points1 = vec4(bounds.xy + data[1].xy,
|
||||
bounds.zy + vec2(data[1].zw * vec2(-1, 1)));
|
||||
vec4 corner_points2 = vec4(bounds.zw + (data[2].xy * vec2(-1, -1)),
|
||||
bounds.xw + vec2(data[2].zw * vec2(1, -1)));
|
||||
|
||||
return RoundedRect(bounds, corner_points1, corner_points2);
|
||||
}
|
@@ -2,68 +2,26 @@ uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
uniform float u_alpha;
|
||||
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
#ifdef GSK_GLES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#if GSK_GLES
|
||||
#define _OUT_ varying
|
||||
#define _IN_ varying
|
||||
attribute vec2 aPosition;
|
||||
attribute vec2 aUv;
|
||||
_OUT_ vec2 vUv;
|
||||
#elif GSK_LEGACY
|
||||
#define _OUT_ varying
|
||||
#define _IN_ varying
|
||||
attribute vec2 aPosition;
|
||||
attribute vec2 aUv;
|
||||
_OUT_ vec2 vUv;
|
||||
#else
|
||||
#define _OUT_ out
|
||||
#define _IN_ in
|
||||
_IN_ vec2 aPosition;
|
||||
_IN_ vec2 aUv;
|
||||
_OUT_ vec2 vUv;
|
||||
#endif
|
||||
|
||||
// amount is: top, right, bottom, left
|
||||
RoundedRect
|
||||
rounded_rect_shrink (RoundedRect r, vec4 amount)
|
||||
{
|
||||
vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
|
||||
vec4 new_corner_points1 = r.corner_points1;
|
||||
vec4 new_corner_points2 = r.corner_points2;
|
||||
|
||||
if (r.corner_points1.xy == r.bounds.xy) new_corner_points1.xy = new_bounds.xy;
|
||||
if (r.corner_points1.zw == r.bounds.zy) new_corner_points1.zw = new_bounds.zy;
|
||||
if (r.corner_points2.xy == r.bounds.zw) new_corner_points2.xy = new_bounds.zw;
|
||||
if (r.corner_points2.zw == r.bounds.xw) new_corner_points2.zw = new_bounds.xw;
|
||||
|
||||
return RoundedRect (new_bounds, new_corner_points1, new_corner_points2);
|
||||
}
|
||||
|
||||
void
|
||||
rounded_rect_offset(inout RoundedRect r, vec2 offset)
|
||||
{
|
||||
r.bounds.xy += offset;
|
||||
r.bounds.zw += offset;
|
||||
r.corner_points1.xy += offset;
|
||||
r.corner_points1.zw += offset;
|
||||
r.corner_points2.xy += offset;
|
||||
r.corner_points2.zw += offset;
|
||||
}
|
||||
|
||||
void rounded_rect_transform(inout RoundedRect r, mat4 mat)
|
||||
{
|
||||
r.bounds.xy = (mat * vec4(r.bounds.xy, 0.0, 1.0)).xy;
|
||||
r.bounds.zw = (mat * vec4(r.bounds.zw, 0.0, 1.0)).xy;
|
||||
|
||||
r.corner_points1.xy = (mat * vec4(r.corner_points1.xy, 0.0, 1.0)).xy;
|
||||
r.corner_points1.zw = (mat * vec4(r.corner_points1.zw, 0.0, 1.0)).xy;
|
||||
|
||||
r.corner_points2.xy = (mat * vec4(r.corner_points2.xy, 0.0, 1.0)).xy;
|
||||
r.corner_points2.zw = (mat * vec4(r.corner_points2.zw, 0.0, 1.0)).xy;
|
||||
}
|
||||
|
||||
#if defined(GSK_LEGACY)
|
||||
// Can't have out or inout array parameters...
|
||||
#define rounded_rect_encode(r, uni) uni[0] = r.bounds; uni[1] = r.corner_points1; uni[2] = r.corner_points2;
|
||||
#else
|
||||
void rounded_rect_encode(RoundedRect r, out _ROUNDED_RECT_UNIFORM_ out_r)
|
||||
{
|
||||
#if defined(GSK_GLES)
|
||||
out_r[0] = r.bounds;
|
||||
out_r[1] = r.corner_points1;
|
||||
out_r[2] = r.corner_points2;
|
||||
#else
|
||||
out_r = r;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,12 +1,7 @@
|
||||
// VERTEX_SHADER:
|
||||
uniform vec4 u_color;
|
||||
uniform float u_spread;
|
||||
uniform vec2 u_offset;
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_OUT_ vec4 final_color;
|
||||
_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
|
||||
_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
@@ -14,33 +9,26 @@ void main() {
|
||||
final_color = u_color;
|
||||
final_color.rgb *= final_color.a;
|
||||
final_color *= u_alpha;
|
||||
|
||||
RoundedRect inside = create_rect(u_outline_rect);
|
||||
RoundedRect outside = rounded_rect_shrink(inside, vec4(- u_spread));
|
||||
|
||||
rounded_rect_offset(outside, u_offset);
|
||||
|
||||
rounded_rect_transform(outside, u_modelview);
|
||||
rounded_rect_transform(inside, u_modelview);
|
||||
|
||||
rounded_rect_encode(outside, transformed_outside_outline);
|
||||
rounded_rect_encode(inside, transformed_inside_outline);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform float u_spread;
|
||||
uniform vec2 u_offset;
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_IN_ vec4 final_color;
|
||||
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
|
||||
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
vec4 color;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) -
|
||||
rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy),
|
||||
0.0, 1.0);
|
||||
|
||||
setOutputColor(final_color * alpha);
|
||||
RoundedRect inside = create_rect(u_outline_rect);
|
||||
RoundedRect outside = rounded_rect_shrink(inside, vec4(- u_spread));
|
||||
color = final_color * clamp (rounded_rect_coverage (outside, f.xy - u_offset) -
|
||||
rounded_rect_coverage (inside, f.xy),
|
||||
0.0, 1.0);
|
||||
setOutputColor(color);
|
||||
}
|
||||
|
@@ -261,14 +261,14 @@ gtk_css_parser_get_end_location (GtkCssParser *self)
|
||||
const GtkCssLocation *
|
||||
gtk_css_parser_get_block_location (GtkCssParser *self)
|
||||
{
|
||||
const GtkCssParserBlock *block;
|
||||
GtkCssParserBlock *block;
|
||||
|
||||
if (self->blocks->len == 0)
|
||||
{
|
||||
static const GtkCssLocation start_of_document = { 0, };
|
||||
return &start_of_document;
|
||||
}
|
||||
|
||||
|
||||
block = &g_array_index (self->blocks, GtkCssParserBlock, self->blocks->len - 1);
|
||||
return &block->start_location;
|
||||
}
|
||||
@@ -301,7 +301,7 @@ gtk_css_parser_peek_token (GtkCssParser *self)
|
||||
|
||||
if (self->blocks->len)
|
||||
{
|
||||
const GtkCssParserBlock *block = &g_array_index (self->blocks, GtkCssParserBlock, self->blocks->len - 1);
|
||||
GtkCssParserBlock *block = &g_array_index (self->blocks, GtkCssParserBlock, self->blocks->len - 1);
|
||||
if (gtk_css_token_is (&self->token, block->end_token) ||
|
||||
gtk_css_token_is (&self->token, block->inherited_end_token) ||
|
||||
gtk_css_token_is (&self->token, block->alternative_token))
|
||||
|
@@ -109,16 +109,16 @@ union _GtkCssToken {
|
||||
|
||||
void gtk_css_token_clear (GtkCssToken *token);
|
||||
|
||||
gboolean gtk_css_token_is_finite (const GtkCssToken *token) G_GNUC_PURE;
|
||||
gboolean gtk_css_token_is_finite (const GtkCssToken *token);
|
||||
gboolean gtk_css_token_is_preserved (const GtkCssToken *token,
|
||||
GtkCssTokenType *out_closing) G_GNUC_PURE;
|
||||
GtkCssTokenType *out_closing);
|
||||
#define gtk_css_token_is(token, _type) ((token)->type == (_type))
|
||||
gboolean gtk_css_token_is_ident (const GtkCssToken *token,
|
||||
const char *ident) G_GNUC_PURE;
|
||||
const char *ident);
|
||||
gboolean gtk_css_token_is_function (const GtkCssToken *token,
|
||||
const char *ident) G_GNUC_PURE;
|
||||
const char *ident);
|
||||
gboolean gtk_css_token_is_delim (const GtkCssToken *token,
|
||||
gunichar delim) G_GNUC_PURE;
|
||||
gunichar delim);
|
||||
|
||||
void gtk_css_token_print (const GtkCssToken *token,
|
||||
GString *string);
|
||||
|
@@ -23,11 +23,9 @@
|
||||
#include "gsk/gskrendernodeprivate.h"
|
||||
#include "gskpango.h"
|
||||
#include "gtksnapshotprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtktextlayoutprivate.h"
|
||||
#include "gtktextviewprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -309,6 +307,7 @@ static void
|
||||
gsk_pango_renderer_prepare_run (PangoRenderer *renderer,
|
||||
PangoLayoutRun *run)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GskPangoRenderer *crenderer = GSK_PANGO_RENDERER (renderer);
|
||||
GdkRGBA *bg_rgba = NULL;
|
||||
GdkRGBA *fg_rgba = NULL;
|
||||
@@ -321,6 +320,8 @@ gsk_pango_renderer_prepare_run (PangoRenderer *renderer,
|
||||
if (appearance == NULL)
|
||||
return;
|
||||
|
||||
context = gtk_widget_get_style_context (crenderer->widget);
|
||||
|
||||
if (appearance->draw_bg && crenderer->state == GSK_PANGO_RENDERER_NORMAL)
|
||||
bg_rgba = appearance->bg_rgba;
|
||||
else
|
||||
@@ -331,21 +332,22 @@ gsk_pango_renderer_prepare_run (PangoRenderer *renderer,
|
||||
if (crenderer->state == GSK_PANGO_RENDERER_SELECTED &&
|
||||
GTK_IS_TEXT_VIEW (crenderer->widget))
|
||||
{
|
||||
GtkCssNode *node;
|
||||
GtkCssValue *value;
|
||||
GtkCssNode *selection_node;
|
||||
|
||||
node = gtk_text_view_get_selection_node ((GtkTextView *)crenderer->widget);
|
||||
value = gtk_css_style_get_value (gtk_css_node_get_style (node), GTK_CSS_PROPERTY_COLOR);
|
||||
fg_rgba = (GdkRGBA *)gtk_css_color_value_get_rgba (value);
|
||||
selection_node = gtk_text_view_get_selection_node ((GtkTextView *)crenderer->widget);
|
||||
gtk_style_context_save_to_node (context, selection_node);
|
||||
|
||||
gtk_style_context_get (context,
|
||||
"color", &fg_rgba,
|
||||
NULL);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
else if (crenderer->state == GSK_PANGO_RENDERER_CURSOR && gtk_widget_has_focus (crenderer->widget))
|
||||
{
|
||||
GtkCssNode *node;
|
||||
GtkCssValue *value;
|
||||
|
||||
node = gtk_widget_get_css_node (crenderer->widget);
|
||||
value = gtk_css_style_get_value (gtk_css_node_get_style (node), GTK_CSS_PROPERTY_BACKGROUND_COLOR);
|
||||
fg_rgba = (GdkRGBA *)gtk_css_color_value_get_rgba (value);
|
||||
gtk_style_context_get (context,
|
||||
"background-color", &fg_rgba,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
fg_rgba = appearance->fg_rgba;
|
||||
|
@@ -297,25 +297,17 @@ gtk_application_startup (GApplication *g_application)
|
||||
{
|
||||
GtkApplication *application = GTK_APPLICATION (g_application);
|
||||
GtkApplicationPrivate *priv = gtk_application_get_instance_private (application);
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before2;
|
||||
|
||||
G_APPLICATION_CLASS (gtk_application_parent_class)->startup (g_application);
|
||||
|
||||
gtk_action_muxer_insert (priv->muxer, "app", G_ACTION_GROUP (application));
|
||||
|
||||
before2 = g_get_monotonic_time ();
|
||||
gtk_init ();
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before2 * 1000, (g_get_monotonic_time () - before2) * 1000, "gtk init", NULL);
|
||||
|
||||
priv->impl = gtk_application_impl_new (application, gdk_display_get_default ());
|
||||
gtk_application_impl_startup (priv->impl, priv->register_session);
|
||||
|
||||
gtk_application_load_resources (application);
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000, (g_get_monotonic_time () - before) * 1000, "gtk application startup", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
103
gtk/gtkbox.c
103
gtk/gtkbox.c
@@ -109,6 +109,9 @@ static void gtk_box_forall (GtkContainer *container,
|
||||
GtkCallback callback,
|
||||
gpointer callback_data);
|
||||
static GType gtk_box_child_type (GtkContainer *container);
|
||||
static GtkWidgetPath * gtk_box_get_path_for_child
|
||||
(GtkContainer *container,
|
||||
GtkWidget *child);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkBox, gtk_box, GTK_TYPE_CONTAINER,
|
||||
G_ADD_PRIVATE (GtkBox)
|
||||
@@ -128,6 +131,7 @@ gtk_box_class_init (GtkBoxClass *class)
|
||||
container_class->remove = gtk_box_remove;
|
||||
container_class->forall = gtk_box_forall;
|
||||
container_class->child_type = gtk_box_child_type;
|
||||
container_class->get_path_for_child = gtk_box_get_path_for_child;
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
PROP_ORIENTATION,
|
||||
@@ -238,6 +242,105 @@ gtk_box_child_type (GtkContainer *container)
|
||||
return GTK_TYPE_WIDGET;
|
||||
}
|
||||
|
||||
typedef struct _CountingData CountingData;
|
||||
struct _CountingData {
|
||||
GtkWidget *widget;
|
||||
gboolean found;
|
||||
guint before;
|
||||
guint after;
|
||||
};
|
||||
|
||||
static void
|
||||
count_widget_position (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
CountingData *count = data;
|
||||
|
||||
if (!_gtk_widget_get_visible (widget))
|
||||
return;
|
||||
|
||||
if (count->widget == widget)
|
||||
count->found = TRUE;
|
||||
else if (count->found)
|
||||
count->after++;
|
||||
else
|
||||
count->before++;
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_box_get_visible_position (GtkBox *box,
|
||||
GtkWidget *child)
|
||||
{
|
||||
CountingData count = { child, FALSE, 0, 0 };
|
||||
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
|
||||
|
||||
/* foreach iterates in visible order */
|
||||
gtk_container_foreach (GTK_CONTAINER (box),
|
||||
count_widget_position,
|
||||
&count);
|
||||
|
||||
/* the child wasn't found, it's likely an internal child of some
|
||||
* subclass, return -1 to indicate that there is no sibling relation
|
||||
* to the regular box children
|
||||
*/
|
||||
if (!count.found)
|
||||
return -1;
|
||||
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
gtk_widget_get_direction (GTK_WIDGET (box)) == GTK_TEXT_DIR_RTL)
|
||||
return count.after;
|
||||
else
|
||||
return count.before;
|
||||
}
|
||||
|
||||
static GtkWidgetPath *
|
||||
gtk_box_get_path_for_child (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkWidgetPath *path, *sibling_path;
|
||||
GtkBox *box = GTK_BOX (container);
|
||||
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
|
||||
GList *list, *children;
|
||||
|
||||
path = _gtk_widget_create_path (GTK_WIDGET (container));
|
||||
|
||||
if (_gtk_widget_get_visible (child))
|
||||
{
|
||||
gint position;
|
||||
|
||||
sibling_path = gtk_widget_path_new ();
|
||||
|
||||
/* get_children works in visible order */
|
||||
children = gtk_container_get_children (container);
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
_gtk_widget_get_direction (GTK_WIDGET (box)) == GTK_TEXT_DIR_RTL)
|
||||
children = g_list_reverse (children);
|
||||
|
||||
for (list = children; list; list = list->next)
|
||||
{
|
||||
if (!_gtk_widget_get_visible (list->data))
|
||||
continue;
|
||||
|
||||
gtk_widget_path_append_for_widget (sibling_path, list->data);
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
position = gtk_box_get_visible_position (box, child);
|
||||
|
||||
if (position >= 0)
|
||||
gtk_widget_path_append_with_siblings (path, sibling_path, position);
|
||||
else
|
||||
gtk_widget_path_append_for_widget (path, child);
|
||||
|
||||
gtk_widget_path_unref (sibling_path);
|
||||
}
|
||||
else
|
||||
gtk_widget_path_append_for_widget (path, child);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_init (GtkBox *box)
|
||||
{
|
||||
|
@@ -229,7 +229,6 @@ gtk_color_button_class_init (GtkColorButtonClass *klass)
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_set_css_name (widget_class, "colorbutton");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -115,6 +115,9 @@ static void gtk_container_children_callback (GtkWidget *widget,
|
||||
gpointer client_data);
|
||||
static GtkSizeRequestMode gtk_container_get_request_mode (GtkWidget *widget);
|
||||
|
||||
static GtkWidgetPath * gtk_container_real_get_path_for_child (GtkContainer *container,
|
||||
GtkWidget *child);
|
||||
|
||||
/* GtkBuildable */
|
||||
static void gtk_container_buildable_init (GtkBuildableIface *iface);
|
||||
static GtkBuildableIface *parent_buildable_iface;
|
||||
@@ -146,6 +149,7 @@ gtk_container_class_init (GtkContainerClass *class)
|
||||
class->forall = NULL;
|
||||
class->set_focus_child = gtk_container_real_set_focus_child;
|
||||
class->child_type = NULL;
|
||||
class->get_path_for_child = gtk_container_real_get_path_for_child;
|
||||
|
||||
container_signals[ADD] =
|
||||
g_signal_new (I_("add"),
|
||||
@@ -371,7 +375,9 @@ gtk_container_idle_sizer (GdkFrameClock *clock,
|
||||
*/
|
||||
if (gtk_widget_needs_allocate (GTK_WIDGET (container)))
|
||||
{
|
||||
if (GTK_IS_ROOT (container))
|
||||
if (GTK_IS_WINDOW (container))
|
||||
gtk_window_check_resize (GTK_WINDOW (container));
|
||||
else if (GTK_IS_ROOT (container))
|
||||
gtk_native_check_resize (GTK_NATIVE (container));
|
||||
else
|
||||
g_warning ("gtk_container_idle_sizer() called on a non-native non-window");
|
||||
@@ -645,6 +651,18 @@ gtk_container_real_set_focus_child (GtkContainer *container,
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidgetPath *
|
||||
gtk_container_real_get_path_for_child (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkWidgetPath *path;
|
||||
|
||||
path = _gtk_widget_create_path (GTK_WIDGET (container));
|
||||
gtk_widget_path_append_for_widget (path, child);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_children_callback (GtkWidget *widget,
|
||||
gpointer client_data)
|
||||
@@ -765,3 +783,35 @@ gtk_container_get_focus_hadjustment (GtkContainer *container)
|
||||
return hadjustment;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_get_path_for_child:
|
||||
* @container: a #GtkContainer
|
||||
* @child: a child of @container
|
||||
*
|
||||
* Returns a newly created widget path representing all the widget hierarchy
|
||||
* from the toplevel down to and including @child.
|
||||
*
|
||||
* Returns: A newly created #GtkWidgetPath
|
||||
**/
|
||||
GtkWidgetPath *
|
||||
gtk_container_get_path_for_child (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkWidgetPath *path;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CONTAINER (container), NULL);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (child), NULL);
|
||||
g_return_val_if_fail (container == (GtkContainer *) _gtk_widget_get_parent (child), NULL);
|
||||
|
||||
path = GTK_CONTAINER_GET_CLASS (container)->get_path_for_child (container, child);
|
||||
if (gtk_widget_path_get_object_type (path) != G_OBJECT_TYPE (child))
|
||||
{
|
||||
g_critical ("%s %p returned a widget path for type %s, but child is %s",
|
||||
G_OBJECT_TYPE_NAME (container),
|
||||
container,
|
||||
g_type_name (gtk_widget_path_get_object_type (path)),
|
||||
G_OBJECT_TYPE_NAME (child));
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
@@ -62,6 +62,8 @@ struct _GtkContainer
|
||||
* @child_type: Returns the type of the children supported by the container.
|
||||
* @set_child_property: Set a property on a child of container.
|
||||
* @get_child_property: Get a property from a child of container.
|
||||
* @get_path_for_child: Get path representing entire widget hierarchy
|
||||
* from the toplevel down to and including @child.
|
||||
*
|
||||
* Base class for containers.
|
||||
*/
|
||||
@@ -81,6 +83,8 @@ struct _GtkContainerClass
|
||||
void (*set_focus_child) (GtkContainer *container,
|
||||
GtkWidget *child);
|
||||
GType (*child_type) (GtkContainer *container);
|
||||
GtkWidgetPath * (*get_path_for_child) (GtkContainer *container,
|
||||
GtkWidget *child);
|
||||
|
||||
|
||||
/*< private >*/
|
||||
@@ -128,6 +132,10 @@ void gtk_container_forall (GtkContainer *container,
|
||||
GtkCallback callback,
|
||||
gpointer callback_data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidgetPath * gtk_container_get_path_for_child (GtkContainer *container,
|
||||
GtkWidget *child);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkContainer, g_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -299,7 +299,7 @@ gtk_css_value_array_transition (GtkCssValue *start,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_value_array_is_dynamic (const GtkCssValue *value)
|
||||
gtk_css_value_array_is_dynamic (GtkCssValue *value)
|
||||
{
|
||||
guint i;
|
||||
|
||||
|
@@ -34,7 +34,7 @@ GtkCssValue * _gtk_css_array_value_parse (GtkCssParser *
|
||||
|
||||
GtkCssValue * _gtk_css_array_value_get_nth (GtkCssValue *value,
|
||||
guint i);
|
||||
guint _gtk_css_array_value_get_n_values (const GtkCssValue *value) G_GNUC_PURE;
|
||||
guint _gtk_css_array_value_get_n_values (const GtkCssValue *value);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -23,7 +23,6 @@
|
||||
#include "gtkcsscornervalueprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssdimensionvalueprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
/* This file is included from gtkcssboxesprivate.h */
|
||||
@@ -80,50 +79,15 @@ gtk_css_boxes_rect_grow (GskRoundedRect *dest,
|
||||
int bottom_property,
|
||||
int left_property)
|
||||
{
|
||||
GtkCssValue *top = gtk_css_style_get_value (style, top_property);
|
||||
GtkCssValue *right = gtk_css_style_get_value (style, right_property);
|
||||
GtkCssValue *bottom = gtk_css_style_get_value (style, bottom_property);
|
||||
GtkCssValue *left = gtk_css_style_get_value (style, left_property);
|
||||
double top = _gtk_css_number_value_get (gtk_css_style_get_value (style, top_property), 100);
|
||||
double right = _gtk_css_number_value_get (gtk_css_style_get_value (style, right_property), 100);
|
||||
double bottom = _gtk_css_number_value_get (gtk_css_style_get_value (style, bottom_property), 100);
|
||||
double left = _gtk_css_number_value_get (gtk_css_style_get_value (style, left_property), 100);
|
||||
|
||||
if (gtk_css_dimension_value_is_zero (left))
|
||||
{
|
||||
dest->bounds.origin.x = src->bounds.origin.x;
|
||||
if (gtk_css_dimension_value_is_zero (right))
|
||||
dest->bounds.size.width = src->bounds.size.width;
|
||||
else
|
||||
dest->bounds.size.width = src->bounds.size.width + _gtk_css_number_value_get (right, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
const double left_value = _gtk_css_number_value_get (left, 100);
|
||||
|
||||
dest->bounds.origin.x = src->bounds.origin.x - left_value;
|
||||
if (gtk_css_dimension_value_is_zero (right))
|
||||
dest->bounds.size.width = src->bounds.size.width + left_value;
|
||||
else
|
||||
dest->bounds.size.width = src->bounds.size.width + left_value + _gtk_css_number_value_get (right, 100);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (gtk_css_dimension_value_is_zero (top))
|
||||
{
|
||||
dest->bounds.origin.y = src->bounds.origin.y;
|
||||
if (gtk_css_dimension_value_is_zero (bottom))
|
||||
dest->bounds.size.height = src->bounds.size.height;
|
||||
else
|
||||
dest->bounds.size.height = src->bounds.size.height + _gtk_css_number_value_get (bottom, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
const double top_value = _gtk_css_number_value_get (top, 100);
|
||||
|
||||
dest->bounds.origin.y = src->bounds.origin.y - top_value;
|
||||
if (gtk_css_dimension_value_is_zero (bottom))
|
||||
dest->bounds.size.height = src->bounds.size.height + top_value;
|
||||
else
|
||||
dest->bounds.size.height = src->bounds.size.height + top_value + _gtk_css_number_value_get (bottom, 100);
|
||||
}
|
||||
dest->bounds.origin.x = src->bounds.origin.x - left;
|
||||
dest->bounds.origin.y = src->bounds.origin.y - top;
|
||||
dest->bounds.size.width = src->bounds.size.width + left + right;
|
||||
dest->bounds.size.height = src->bounds.size.height + top + bottom;
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -359,38 +323,19 @@ gtk_css_boxes_apply_border_radius (GskRoundedRect *box,
|
||||
const GtkCssValue *bottom_right,
|
||||
const GtkCssValue *bottom_left)
|
||||
{
|
||||
gboolean has_border_radius = FALSE;
|
||||
box->corner[GSK_CORNER_TOP_LEFT].width = _gtk_css_corner_value_get_x (top_left, box->bounds.size.width);
|
||||
box->corner[GSK_CORNER_TOP_LEFT].height = _gtk_css_corner_value_get_y (top_left, box->bounds.size.height);
|
||||
|
||||
if (!gtk_css_corner_value_is_zero (top_left))
|
||||
{
|
||||
box->corner[GSK_CORNER_TOP_LEFT].width = _gtk_css_corner_value_get_x (top_left, box->bounds.size.width);
|
||||
box->corner[GSK_CORNER_TOP_LEFT].height = _gtk_css_corner_value_get_y (top_left, box->bounds.size.height);
|
||||
has_border_radius = TRUE;
|
||||
}
|
||||
box->corner[GSK_CORNER_TOP_RIGHT].width = _gtk_css_corner_value_get_x (top_right, box->bounds.size.width);
|
||||
box->corner[GSK_CORNER_TOP_RIGHT].height = _gtk_css_corner_value_get_y (top_right, box->bounds.size.height);
|
||||
|
||||
if (!gtk_css_corner_value_is_zero (top_right))
|
||||
{
|
||||
box->corner[GSK_CORNER_TOP_RIGHT].width = _gtk_css_corner_value_get_x (top_right, box->bounds.size.width);
|
||||
box->corner[GSK_CORNER_TOP_RIGHT].height = _gtk_css_corner_value_get_y (top_right, box->bounds.size.height);
|
||||
has_border_radius = TRUE;
|
||||
}
|
||||
box->corner[GSK_CORNER_BOTTOM_RIGHT].width = _gtk_css_corner_value_get_x (bottom_right, box->bounds.size.width);
|
||||
box->corner[GSK_CORNER_BOTTOM_RIGHT].height = _gtk_css_corner_value_get_y (bottom_right, box->bounds.size.height);
|
||||
|
||||
if (!gtk_css_corner_value_is_zero (bottom_right))
|
||||
{
|
||||
box->corner[GSK_CORNER_BOTTOM_RIGHT].width = _gtk_css_corner_value_get_x (bottom_right, box->bounds.size.width);
|
||||
box->corner[GSK_CORNER_BOTTOM_RIGHT].height = _gtk_css_corner_value_get_y (bottom_right, box->bounds.size.height);
|
||||
has_border_radius = TRUE;
|
||||
}
|
||||
box->corner[GSK_CORNER_BOTTOM_LEFT].width = _gtk_css_corner_value_get_x (bottom_left, box->bounds.size.width);
|
||||
box->corner[GSK_CORNER_BOTTOM_LEFT].height = _gtk_css_corner_value_get_y (bottom_left, box->bounds.size.height);
|
||||
|
||||
if (!gtk_css_corner_value_is_zero (bottom_left))
|
||||
{
|
||||
box->corner[GSK_CORNER_BOTTOM_LEFT].width = _gtk_css_corner_value_get_x (bottom_left, box->bounds.size.width);
|
||||
box->corner[GSK_CORNER_BOTTOM_LEFT].height = _gtk_css_corner_value_get_y (bottom_left, box->bounds.size.height);
|
||||
has_border_radius = TRUE;
|
||||
}
|
||||
|
||||
if (has_border_radius)
|
||||
gtk_css_boxes_clamp_border_radius (box);
|
||||
gtk_css_boxes_clamp_border_radius (box);
|
||||
}
|
||||
|
||||
/* NB: width and height must be >= 0 */
|
||||
|
@@ -24,18 +24,18 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
GtkCssValue * gtk_css_color_value_new_transparent (void) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_white (void) G_GNUC_PURE;
|
||||
GtkCssValue * _gtk_css_color_value_new_literal (const GdkRGBA *color) G_GNUC_PURE;
|
||||
GtkCssValue * _gtk_css_color_value_new_name (const gchar *name) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_transparent (void);
|
||||
GtkCssValue * gtk_css_color_value_new_white (void);
|
||||
GtkCssValue * _gtk_css_color_value_new_literal (const GdkRGBA *color);
|
||||
GtkCssValue * _gtk_css_color_value_new_name (const gchar *name);
|
||||
GtkCssValue * _gtk_css_color_value_new_shade (GtkCssValue *color,
|
||||
gdouble factor) G_GNUC_PURE;
|
||||
gdouble factor);
|
||||
GtkCssValue * _gtk_css_color_value_new_alpha (GtkCssValue *color,
|
||||
gdouble factor) G_GNUC_PURE;
|
||||
gdouble factor);
|
||||
GtkCssValue * _gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
GtkCssValue *color2,
|
||||
gdouble factor) G_GNUC_PURE;
|
||||
GtkCssValue * _gtk_css_color_value_new_current_color (void) G_GNUC_PURE;
|
||||
gdouble factor);
|
||||
GtkCssValue * _gtk_css_color_value_new_current_color (void);
|
||||
|
||||
gboolean gtk_css_color_value_can_parse (GtkCssParser *parser);
|
||||
GtkCssValue * _gtk_css_color_value_parse (GtkCssParser *parser);
|
||||
@@ -44,7 +44,7 @@ GtkCssValue * _gtk_css_color_value_resolve (GtkCssValue *color
|
||||
GtkStyleProvider *provider,
|
||||
GtkCssValue *current,
|
||||
GSList *cycle_list);
|
||||
const GdkRGBA * gtk_css_color_value_get_rgba (const GtkCssValue *color) G_GNUC_CONST;
|
||||
const GdkRGBA * gtk_css_color_value_get_rgba (const GtkCssValue *color);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -18,8 +18,8 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcsscornervalueprivate.h"
|
||||
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssdimensionvalueprivate.h"
|
||||
|
||||
struct _GtkCssValue {
|
||||
GTK_CSS_VALUE_BASE
|
||||
@@ -184,12 +184,3 @@ _gtk_css_corner_value_get_y (const GtkCssValue *corner,
|
||||
return _gtk_css_number_value_get (corner->y, one_hundred_percent);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_corner_value_is_zero (const GtkCssValue *corner)
|
||||
{
|
||||
if (corner->class != >K_CSS_VALUE_CORNER)
|
||||
return gtk_css_dimension_value_is_zero (corner);
|
||||
|
||||
return gtk_css_dimension_value_is_zero (corner->x) &&
|
||||
gtk_css_dimension_value_is_zero (corner->y);
|
||||
}
|
||||
|
@@ -30,10 +30,9 @@ GtkCssValue * _gtk_css_corner_value_new (GtkCssValue *x,
|
||||
GtkCssValue * _gtk_css_corner_value_parse (GtkCssParser *parser);
|
||||
|
||||
double _gtk_css_corner_value_get_x (const GtkCssValue *corner,
|
||||
double one_hundred_percent) G_GNUC_PURE;
|
||||
double one_hundred_percent);
|
||||
double _gtk_css_corner_value_get_y (const GtkCssValue *corner,
|
||||
double one_hundred_percent) G_GNUC_PURE;
|
||||
gboolean gtk_css_corner_value_is_zero (const GtkCssValue *corner) G_GNUC_PURE;
|
||||
double one_hundred_percent);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -497,14 +497,3 @@ gtk_css_dimension_value_parse (GtkCssParser *parser,
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_dimension_value_is_zero (const GtkCssValue *value)
|
||||
{
|
||||
if (!value)
|
||||
return TRUE;
|
||||
|
||||
if (value->class != >K_CSS_VALUE_DIMENSION.value_class)
|
||||
return FALSE;
|
||||
|
||||
return value->value == 0;
|
||||
}
|
||||
|
@@ -26,12 +26,10 @@ G_BEGIN_DECLS
|
||||
|
||||
GtkCssValue * gtk_css_dimension_value_new (double value,
|
||||
GtkCssUnit unit);
|
||||
|
||||
/* This function implemented in gtkcssparser.c */
|
||||
GtkCssValue * gtk_css_dimension_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags);
|
||||
|
||||
gboolean gtk_css_dimension_value_is_zero (const GtkCssValue *value) G_GNUC_PURE;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_DIMENSION_VALUE_PRIVATE_H__ */
|
||||
|
@@ -340,17 +340,6 @@ _gtk_css_image_print (GtkCssImage *image,
|
||||
klass->print (image, string);
|
||||
}
|
||||
|
||||
char *
|
||||
gtk_css_image_to_string (GtkCssImage *image)
|
||||
{
|
||||
GString *str = g_string_new ("");
|
||||
|
||||
_gtk_css_image_print (image, str);
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/* Applies the algorithm outlined in
|
||||
* http://dev.w3.org/csswg/css3-images/#default-sizing
|
||||
*/
|
||||
|
@@ -94,22 +94,21 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
|
||||
|
||||
if (symbolic)
|
||||
{
|
||||
const GdkRGBA *fg = &icon_theme->color;
|
||||
const GdkRGBA *sc = &icon_theme->success;
|
||||
const GdkRGBA *wc = &icon_theme->warning;
|
||||
const GdkRGBA *ec = &icon_theme->error;
|
||||
graphene_matrix_t matrix;
|
||||
graphene_vec4_t offset;
|
||||
|
||||
GdkRGBA fg = icon_theme->color;
|
||||
GdkRGBA sc = icon_theme->success;
|
||||
GdkRGBA wc = icon_theme->warning;
|
||||
GdkRGBA ec = icon_theme->error;
|
||||
|
||||
graphene_matrix_init_from_float (&matrix,
|
||||
(float[16]) {
|
||||
sc->red - fg->red, sc->green - fg->green, sc->blue - fg->blue, 0,
|
||||
wc->red - fg->red, wc->green - fg->green, wc->blue - fg->blue, 0,
|
||||
ec->red - fg->red, ec->green - fg->green, ec->blue - fg->blue, 0,
|
||||
0, 0, 0, fg->alpha
|
||||
sc.red - fg.red, sc.green - fg.green, sc.blue - fg.blue, 0,
|
||||
wc.red - fg.red, wc.green - fg.green, wc.blue - fg.blue, 0,
|
||||
ec.red - fg.red, ec.green - fg.green, ec.blue - fg.blue, 0,
|
||||
0, 0, 0, fg.alpha
|
||||
});
|
||||
graphene_vec4_init (&offset, fg->red, fg->green, fg->blue, 0);
|
||||
graphene_vec4_init (&offset, fg.red, fg.green, fg.blue, 0);
|
||||
|
||||
gtk_snapshot_push_color_matrix (snapshot, &matrix, &offset);
|
||||
}
|
||||
|
@@ -150,14 +150,6 @@ gtk_css_image_paintable_dispose (GObject *object)
|
||||
G_OBJECT_CLASS (gtk_css_image_paintable_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_paintable_is_computed (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImagePaintable *self = GTK_CSS_IMAGE_PAINTABLE (image);
|
||||
|
||||
return (gdk_paintable_get_flags (self->paintable) & GDK_PAINTABLE_IMMUTABLE) == GDK_PAINTABLE_IMMUTABLE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_paintable_class_init (GtkCssImagePaintableClass *klass)
|
||||
{
|
||||
@@ -172,7 +164,6 @@ gtk_css_image_paintable_class_init (GtkCssImagePaintableClass *klass)
|
||||
image_class->compute = gtk_css_image_paintable_compute;
|
||||
image_class->equal = gtk_css_image_paintable_equal;
|
||||
image_class->is_dynamic = gtk_css_image_paintable_is_dynamic;
|
||||
image_class->is_computed = gtk_css_image_paintable_is_computed;
|
||||
image_class->get_dynamic_image = gtk_css_image_paintable_get_dynamic_image;
|
||||
|
||||
object_class->dispose = gtk_css_image_paintable_dispose;
|
||||
|
@@ -97,9 +97,9 @@ GType _gtk_css_image_get_type (void) G_GNUC_CONST;
|
||||
gboolean _gtk_css_image_can_parse (GtkCssParser *parser);
|
||||
GtkCssImage * _gtk_css_image_new_parse (GtkCssParser *parser);
|
||||
|
||||
int _gtk_css_image_get_width (GtkCssImage *image) G_GNUC_PURE;
|
||||
int _gtk_css_image_get_height (GtkCssImage *image) G_GNUC_PURE;
|
||||
double _gtk_css_image_get_aspect_ratio (GtkCssImage *image) G_GNUC_PURE;
|
||||
int _gtk_css_image_get_width (GtkCssImage *image);
|
||||
int _gtk_css_image_get_height (GtkCssImage *image);
|
||||
double _gtk_css_image_get_aspect_ratio (GtkCssImage *image);
|
||||
|
||||
GtkCssImage * _gtk_css_image_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
@@ -107,7 +107,7 @@ GtkCssImage * _gtk_css_image_compute (GtkCssImage *
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style);
|
||||
gboolean _gtk_css_image_equal (GtkCssImage *image1,
|
||||
GtkCssImage *image2) G_GNUC_PURE;
|
||||
GtkCssImage *image2);
|
||||
GtkCssImage * _gtk_css_image_transition (GtkCssImage *start,
|
||||
GtkCssImage *end,
|
||||
guint property_id,
|
||||
@@ -121,13 +121,12 @@ void gtk_css_image_snapshot (GtkCssImage *
|
||||
GtkSnapshot *snapshot,
|
||||
double width,
|
||||
double height);
|
||||
gboolean gtk_css_image_is_invalid (GtkCssImage *image) G_GNUC_PURE;
|
||||
gboolean gtk_css_image_is_dynamic (GtkCssImage *image) G_GNUC_PURE;
|
||||
gboolean gtk_css_image_is_invalid (GtkCssImage *image);
|
||||
gboolean gtk_css_image_is_dynamic (GtkCssImage *image);
|
||||
GtkCssImage * gtk_css_image_get_dynamic_image (GtkCssImage *image,
|
||||
gint64 monotonic_time);
|
||||
void _gtk_css_image_print (GtkCssImage *image,
|
||||
GString *string);
|
||||
char * gtk_css_image_to_string (GtkCssImage *image);
|
||||
|
||||
void _gtk_css_image_get_concrete_size (GtkCssImage *image,
|
||||
double specified_width,
|
||||
@@ -141,7 +140,7 @@ cairo_surface_t *
|
||||
cairo_surface_t *target,
|
||||
int surface_width,
|
||||
int surface_height);
|
||||
gboolean gtk_css_image_is_computed (GtkCssImage *image) G_GNUC_PURE;
|
||||
gboolean gtk_css_image_is_computed (GtkCssImage *image);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -308,15 +308,6 @@ gtk_css_image_recolor_get_height (GtkCssImage *image)
|
||||
return gdk_texture_get_height (recolor->texture);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_recolor_is_computed (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageRecolor *recolor = GTK_CSS_IMAGE_RECOLOR (image);
|
||||
|
||||
return recolor->texture &&
|
||||
(!recolor->palette || gtk_css_value_is_computed (recolor->palette));
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_recolor_class_init (GtkCssImageRecolorClass *klass)
|
||||
{
|
||||
@@ -329,7 +320,6 @@ _gtk_css_image_recolor_class_init (GtkCssImageRecolorClass *klass)
|
||||
image_class->snapshot = gtk_css_image_recolor_snapshot;
|
||||
image_class->parse = gtk_css_image_recolor_parse;
|
||||
image_class->print = gtk_css_image_recolor_print;
|
||||
image_class->is_computed = gtk_css_image_recolor_is_computed;
|
||||
|
||||
object_class->dispose = gtk_css_image_recolor_dispose;
|
||||
}
|
||||
|
@@ -203,15 +203,6 @@ gtk_css_image_scaled_parse (GtkCssImage *image,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_scaled_is_computed (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageScaled *self = GTK_CSS_IMAGE_SCALED (image);
|
||||
|
||||
return self->n_images == 1 &&
|
||||
gtk_css_image_is_computed (self->images[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_scaled_class_init (GtkCssImageScaledClass *klass)
|
||||
{
|
||||
@@ -225,7 +216,6 @@ _gtk_css_image_scaled_class_init (GtkCssImageScaledClass *klass)
|
||||
image_class->parse = gtk_css_image_scaled_parse;
|
||||
image_class->compute = gtk_css_image_scaled_compute;
|
||||
image_class->print = gtk_css_image_scaled_print;
|
||||
image_class->is_computed = gtk_css_image_scaled_is_computed;
|
||||
|
||||
object_class->dispose = gtk_css_image_scaled_dispose;
|
||||
}
|
||||
|
@@ -161,12 +161,6 @@ gtk_css_image_url_is_invalid (GtkCssImage *image)
|
||||
return gtk_css_image_is_invalid (gtk_css_image_url_load_image (url, NULL));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_url_is_computed (GtkCssImage *image)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_url_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
@@ -255,7 +249,6 @@ _gtk_css_image_url_class_init (GtkCssImageUrlClass *klass)
|
||||
image_class->print = gtk_css_image_url_print;
|
||||
image_class->equal = gtk_css_image_url_equal;
|
||||
image_class->is_invalid = gtk_css_image_url_is_invalid;
|
||||
image_class->is_computed = gtk_css_image_url_is_computed;
|
||||
|
||||
object_class->dispose = gtk_css_image_url_dispose;
|
||||
}
|
||||
|
@@ -82,7 +82,7 @@ gtk_css_value_image_transition (GtkCssValue *start,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_value_image_is_dynamic (const GtkCssValue *value)
|
||||
gtk_css_value_image_is_dynamic (GtkCssValue *value)
|
||||
{
|
||||
GtkCssImage *image = _gtk_css_image_value_get_image (value);
|
||||
|
||||
|
@@ -41,7 +41,7 @@ GtkCssKeyframes * _gtk_css_keyframes_compute (GtkCssKeyframes
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style);
|
||||
|
||||
guint _gtk_css_keyframes_get_n_properties (GtkCssKeyframes *keyframes) G_GNUC_PURE;
|
||||
guint _gtk_css_keyframes_get_n_properties (GtkCssKeyframes *keyframes);
|
||||
guint _gtk_css_keyframes_get_property_id (GtkCssKeyframes *keyframes,
|
||||
guint id);
|
||||
GtkCssValue * _gtk_css_keyframes_get_value (GtkCssKeyframes *keyframes,
|
||||
|
@@ -28,14 +28,11 @@ void
|
||||
_gtk_css_lookup_init (GtkCssLookup *lookup)
|
||||
{
|
||||
memset (lookup, 0, sizeof (*lookup));
|
||||
|
||||
lookup->set_values = _gtk_bitmask_new ();
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_lookup_destroy (GtkCssLookup *lookup)
|
||||
{
|
||||
_gtk_bitmask_free (lookup->set_values);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -44,7 +41,13 @@ _gtk_css_lookup_is_missing (const GtkCssLookup *lookup,
|
||||
{
|
||||
gtk_internal_return_val_if_fail (lookup != NULL, FALSE);
|
||||
|
||||
return !_gtk_bitmask_get (lookup->set_values, id);
|
||||
return lookup->values[id].value == NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_lookup_all_set (const GtkCssLookup *lookup)
|
||||
{
|
||||
return lookup->n_set_values == GTK_CSS_PROPERTY_N_PROPERTIES;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,5 +75,41 @@ _gtk_css_lookup_set (GtkCssLookup *lookup,
|
||||
|
||||
lookup->values[id].value = value;
|
||||
lookup->values[id].section = section;
|
||||
lookup->set_values = _gtk_bitmask_set (lookup->set_values, id, TRUE);
|
||||
lookup->n_set_values ++;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_css_lookup_resolve:
|
||||
* @lookup: the lookup
|
||||
* @context: the context the values are resolved for
|
||||
* @values: a new #GtkCssStyle to be filled with the new properties
|
||||
*
|
||||
* Resolves the current lookup into a styleproperties object. This is done
|
||||
* by converting from the “winning declaration” to the “computed value”.
|
||||
*
|
||||
* XXX: This bypasses the notion of “specified value”. If this ever becomes
|
||||
* an issue, go fix it.
|
||||
**/
|
||||
void
|
||||
_gtk_css_lookup_resolve (GtkCssLookup *lookup,
|
||||
GtkStyleProvider *provider,
|
||||
GtkCssStaticStyle *style,
|
||||
GtkCssStyle *parent_style)
|
||||
{
|
||||
guint i;
|
||||
|
||||
gtk_internal_return_if_fail (lookup != NULL);
|
||||
gtk_internal_return_if_fail (GTK_IS_STYLE_PROVIDER (provider));
|
||||
gtk_internal_return_if_fail (GTK_IS_CSS_STATIC_STYLE (style));
|
||||
gtk_internal_return_if_fail (parent_style == NULL || GTK_IS_CSS_STYLE (parent_style));
|
||||
|
||||
for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++)
|
||||
{
|
||||
gtk_css_static_style_compute_value (style,
|
||||
provider,
|
||||
parent_style,
|
||||
i,
|
||||
lookup->values[i].value,
|
||||
lookup->values[i].section);
|
||||
}
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ typedef struct {
|
||||
} GtkCssLookupValue;
|
||||
|
||||
struct _GtkCssLookup {
|
||||
GtkBitmask *set_values;
|
||||
guint n_set_values;
|
||||
GtkCssLookupValue values[GTK_CSS_PROPERTY_N_PROPERTIES];
|
||||
};
|
||||
|
||||
@@ -44,16 +44,15 @@ void _gtk_css_lookup_init (GtkCssLookup
|
||||
void _gtk_css_lookup_destroy (GtkCssLookup *lookup);
|
||||
gboolean _gtk_css_lookup_is_missing (const GtkCssLookup *lookup,
|
||||
guint id);
|
||||
gboolean _gtk_css_lookup_all_set (const GtkCssLookup *lookup);
|
||||
void _gtk_css_lookup_set (GtkCssLookup *lookup,
|
||||
guint id,
|
||||
GtkCssSection *section,
|
||||
GtkCssValue *value);
|
||||
|
||||
static inline const GtkBitmask *
|
||||
_gtk_css_lookup_get_set_values (const GtkCssLookup *lookup)
|
||||
{
|
||||
return lookup->set_values;
|
||||
}
|
||||
void _gtk_css_lookup_resolve (GtkCssLookup *lookup,
|
||||
GtkStyleProvider *provider,
|
||||
GtkCssStaticStyle *style,
|
||||
GtkCssStyle *parent_style);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -27,7 +27,6 @@
|
||||
#include "gtksettingsprivate.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
|
||||
/*
|
||||
* CSS nodes are the backbone of the GtkStyleContext implementation and
|
||||
@@ -123,11 +122,6 @@ gtk_css_node_get_style_provider_or_null (GtkCssNode *cssnode)
|
||||
return GTK_CSS_NODE_GET_CLASS (cssnode)->get_style_provider (cssnode);
|
||||
}
|
||||
|
||||
static int invalidated_nodes;
|
||||
static int created_styles;
|
||||
static guint invalidated_nodes_counter;
|
||||
static guint created_styles_counter;
|
||||
|
||||
static void
|
||||
gtk_css_node_set_invalid (GtkCssNode *node,
|
||||
gboolean invalid)
|
||||
@@ -137,9 +131,6 @@ gtk_css_node_set_invalid (GtkCssNode *node,
|
||||
|
||||
node->invalid = invalid;
|
||||
|
||||
if (invalid)
|
||||
invalidated_nodes++;
|
||||
|
||||
if (node->visible)
|
||||
{
|
||||
if (node->parent)
|
||||
@@ -378,8 +369,6 @@ gtk_css_node_create_style (GtkCssNode *cssnode,
|
||||
if (style)
|
||||
return g_object_ref (style);
|
||||
|
||||
created_styles++;
|
||||
|
||||
parent = cssnode->parent ? cssnode->parent->style : NULL;
|
||||
|
||||
if (change & GTK_CSS_CHANGE_NEEDS_RECOMPUTE)
|
||||
@@ -506,6 +495,18 @@ gtk_css_node_real_init_matcher (GtkCssNode *cssnode,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkWidgetPath *
|
||||
gtk_css_node_real_create_widget_path (GtkCssNode *cssnode)
|
||||
{
|
||||
return gtk_widget_path_new ();
|
||||
}
|
||||
|
||||
static const GtkWidgetPath *
|
||||
gtk_css_node_real_get_widget_path (GtkCssNode *cssnode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkStyleProvider *
|
||||
gtk_css_node_real_get_style_provider (GtkCssNode *cssnode)
|
||||
{
|
||||
@@ -586,6 +587,8 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
|
||||
klass->queue_validate = gtk_css_node_real_queue_validate;
|
||||
klass->dequeue_validate = gtk_css_node_real_dequeue_validate;
|
||||
klass->init_matcher = gtk_css_node_real_init_matcher;
|
||||
klass->create_widget_path = gtk_css_node_real_create_widget_path;
|
||||
klass->get_widget_path = gtk_css_node_real_get_widget_path;
|
||||
klass->get_style_provider = gtk_css_node_real_get_style_provider;
|
||||
klass->get_frame_clock = gtk_css_node_real_get_frame_clock;
|
||||
|
||||
@@ -662,12 +665,6 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
|
||||
| G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, cssnode_properties);
|
||||
|
||||
if (invalidated_nodes_counter == 0)
|
||||
{
|
||||
invalidated_nodes_counter = gdk_profiler_define_int_counter ("invalidated-nodes", "CSS Node Invalidations");
|
||||
created_styles_counter = gdk_profiler_define_int_counter ("created-styles", "CSS Style Creations");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1382,24 +1379,10 @@ void
|
||||
gtk_css_node_validate (GtkCssNode *cssnode)
|
||||
{
|
||||
gint64 timestamp;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
|
||||
timestamp = gtk_css_node_get_timestamp (cssnode);
|
||||
|
||||
gtk_css_node_validate_internal (cssnode, timestamp);
|
||||
|
||||
if (cssnode->parent == NULL)
|
||||
{
|
||||
if (gdk_profiler_is_running ())
|
||||
{
|
||||
gint64 after = g_get_monotonic_time ();
|
||||
gdk_profiler_add_mark (before * 1000, (after - before) * 1000, "css validation", "");
|
||||
gdk_profiler_set_int_counter (invalidated_nodes_counter, after * 1000, invalidated_nodes);
|
||||
gdk_profiler_set_int_counter (created_styles_counter, after * 1000, created_styles);
|
||||
invalidated_nodes = 0;
|
||||
created_styles = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -1409,6 +1392,18 @@ gtk_css_node_init_matcher (GtkCssNode *cssnode,
|
||||
return GTK_CSS_NODE_GET_CLASS (cssnode)->init_matcher (cssnode, matcher);
|
||||
}
|
||||
|
||||
GtkWidgetPath *
|
||||
gtk_css_node_create_widget_path (GtkCssNode *cssnode)
|
||||
{
|
||||
return GTK_CSS_NODE_GET_CLASS (cssnode)->create_widget_path (cssnode);
|
||||
}
|
||||
|
||||
const GtkWidgetPath *
|
||||
gtk_css_node_get_widget_path (GtkCssNode *cssnode)
|
||||
{
|
||||
return GTK_CSS_NODE_GET_CLASS (cssnode)->get_widget_path (cssnode);
|
||||
}
|
||||
|
||||
GtkStyleProvider *
|
||||
gtk_css_node_get_style_provider (GtkCssNode *cssnode)
|
||||
{
|
||||
|
@@ -78,6 +78,8 @@ struct _GtkCssNodeClass
|
||||
|
||||
gboolean (* init_matcher) (GtkCssNode *cssnode,
|
||||
GtkCssMatcher *matcher);
|
||||
GtkWidgetPath * (* create_widget_path) (GtkCssNode *cssnode);
|
||||
const GtkWidgetPath * (* get_widget_path) (GtkCssNode *cssnode);
|
||||
/* get style provider to use or NULL to use parent's */
|
||||
GtkStyleProvider * (* get_style_provider) (GtkCssNode *cssnode);
|
||||
/* get frame clock or NULL (only relevant for root node) */
|
||||
@@ -155,6 +157,8 @@ void gtk_css_node_validate (GtkCssNode *
|
||||
|
||||
gboolean gtk_css_node_init_matcher (GtkCssNode *cssnode,
|
||||
GtkCssMatcher *matcher);
|
||||
GtkWidgetPath * gtk_css_node_create_widget_path (GtkCssNode *cssnode);
|
||||
const GtkWidgetPath * gtk_css_node_get_widget_path (GtkCssNode *cssnode) G_GNUC_PURE;
|
||||
GtkStyleProvider * gtk_css_node_get_style_provider (GtkCssNode *cssnode) G_GNUC_PURE;
|
||||
|
||||
void gtk_css_node_print (GtkCssNode *cssnode,
|
||||
|
@@ -59,6 +59,37 @@ gtk_css_path_node_real_init_matcher (GtkCssNode *node,
|
||||
gtk_css_node_get_declaration (node));
|
||||
}
|
||||
|
||||
static GtkWidgetPath *
|
||||
gtk_css_path_node_real_create_widget_path (GtkCssNode *node)
|
||||
{
|
||||
GtkCssPathNode *path_node = GTK_CSS_PATH_NODE (node);
|
||||
GtkWidgetPath *path;
|
||||
guint length;
|
||||
|
||||
if (path_node->path == NULL)
|
||||
path = gtk_widget_path_new ();
|
||||
else
|
||||
path = gtk_widget_path_copy (path_node->path);
|
||||
|
||||
length = gtk_widget_path_length (path);
|
||||
if (length > 0)
|
||||
{
|
||||
gtk_css_node_declaration_add_to_widget_path (gtk_css_node_get_declaration (node),
|
||||
path,
|
||||
length - 1);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static const GtkWidgetPath *
|
||||
gtk_css_path_node_real_get_widget_path (GtkCssNode *node)
|
||||
{
|
||||
GtkCssPathNode *path_node = GTK_CSS_PATH_NODE (node);
|
||||
|
||||
return path_node->path;
|
||||
}
|
||||
|
||||
static GtkCssStyle *
|
||||
gtk_css_path_node_update_style (GtkCssNode *cssnode,
|
||||
GtkCssChange change,
|
||||
@@ -91,6 +122,8 @@ gtk_css_path_node_class_init (GtkCssPathNodeClass *klass)
|
||||
node_class->invalidate = gtk_css_path_node_invalidate;
|
||||
node_class->update_style = gtk_css_path_node_update_style;
|
||||
node_class->init_matcher = gtk_css_path_node_real_init_matcher;
|
||||
node_class->create_widget_path = gtk_css_path_node_real_create_widget_path;
|
||||
node_class->get_widget_path = gtk_css_path_node_real_get_widget_path;
|
||||
node_class->get_style_provider = gtk_css_path_node_get_style_provider;
|
||||
}
|
||||
|
||||
|
@@ -42,7 +42,6 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
/**
|
||||
@@ -74,8 +73,6 @@
|
||||
* way back to 4.0.
|
||||
*/
|
||||
|
||||
#define MAX_SELECTOR_LIST_LENGTH 64
|
||||
|
||||
struct _GtkCssProviderClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
@@ -489,6 +486,9 @@ gtk_css_style_provider_lookup (GtkStyleProvider *provider,
|
||||
ruleset->styles[j].section,
|
||||
ruleset->styles[j].value);
|
||||
}
|
||||
|
||||
if (_gtk_css_lookup_all_set (lookup))
|
||||
break;
|
||||
}
|
||||
|
||||
g_ptr_array_free (tree_rules, TRUE);
|
||||
@@ -549,28 +549,29 @@ gtk_css_provider_new (void)
|
||||
}
|
||||
|
||||
static void
|
||||
css_provider_commit (GtkCssProvider *css_provider,
|
||||
GtkCssSelector **selectors,
|
||||
guint n_selectors,
|
||||
GtkCssRuleset *ruleset)
|
||||
css_provider_commit (GtkCssProvider *css_provider,
|
||||
GSList *selectors,
|
||||
GtkCssRuleset *ruleset)
|
||||
{
|
||||
GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (css_provider);
|
||||
guint i;
|
||||
GSList *l;
|
||||
|
||||
if (ruleset->styles == NULL)
|
||||
{
|
||||
g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_selectors; i ++)
|
||||
for (l = selectors; l; l = l->next)
|
||||
{
|
||||
GtkCssRuleset *new;
|
||||
GtkCssRuleset new;
|
||||
|
||||
g_array_set_size (priv->rulesets, priv->rulesets->len + 1);
|
||||
gtk_css_ruleset_init_copy (&new, ruleset, l->data);
|
||||
|
||||
new = &g_array_index (priv->rulesets, GtkCssRuleset, priv->rulesets->len - 1);
|
||||
gtk_css_ruleset_init_copy (new, ruleset, selectors[i]);
|
||||
g_array_append_val (priv->rulesets, new);
|
||||
}
|
||||
|
||||
g_slist_free (selectors);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -755,32 +756,22 @@ parse_at_keyword (GtkCssScanner *scanner)
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_selector_list (GtkCssScanner *scanner,
|
||||
GtkCssSelector *out_selectors[MAX_SELECTOR_LIST_LENGTH])
|
||||
static GSList *
|
||||
parse_selector_list (GtkCssScanner *scanner)
|
||||
{
|
||||
guint n_selectors = 0;
|
||||
GSList *selectors = NULL;
|
||||
|
||||
do {
|
||||
GtkCssSelector *select = _gtk_css_selector_parse (scanner->parser);
|
||||
|
||||
if (select == NULL)
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
out_selectors[n_selectors] = select;
|
||||
n_selectors++;
|
||||
|
||||
if (G_UNLIKELY (n_selectors > MAX_SELECTOR_LIST_LENGTH))
|
||||
{
|
||||
gtk_css_parser_error_syntax (scanner->parser,
|
||||
"Only %u selectors per ruleset allowed",
|
||||
MAX_SELECTOR_LIST_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
selectors = g_slist_prepend (selectors, select);
|
||||
}
|
||||
while (gtk_css_parser_try_token (scanner->parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
return n_selectors;
|
||||
return selectors;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -899,12 +890,11 @@ parse_declarations (GtkCssScanner *scanner,
|
||||
static void
|
||||
parse_ruleset (GtkCssScanner *scanner)
|
||||
{
|
||||
GtkCssSelector *selectors[MAX_SELECTOR_LIST_LENGTH];
|
||||
guint n_selectors;
|
||||
GSList *selectors;
|
||||
GtkCssRuleset ruleset = { 0, };
|
||||
|
||||
n_selectors = parse_selector_list (scanner, selectors);
|
||||
if (n_selectors == 0)
|
||||
selectors = parse_selector_list (scanner);
|
||||
if (selectors == NULL)
|
||||
{
|
||||
gtk_css_parser_skip_until (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
gtk_css_parser_skip (scanner->parser);
|
||||
@@ -913,10 +903,8 @@ parse_ruleset (GtkCssScanner *scanner)
|
||||
|
||||
if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY))
|
||||
{
|
||||
guint i;
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Expected '{' after selectors");
|
||||
for (i = 0; i < n_selectors; i ++)
|
||||
_gtk_css_selector_free (selectors[i]);
|
||||
g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free);
|
||||
gtk_css_parser_skip_until (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
gtk_css_parser_skip (scanner->parser);
|
||||
return;
|
||||
@@ -928,7 +916,7 @@ parse_ruleset (GtkCssScanner *scanner)
|
||||
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
|
||||
css_provider_commit (scanner->provider, selectors, n_selectors, &ruleset);
|
||||
css_provider_commit (scanner->provider, selectors, &ruleset);
|
||||
gtk_css_ruleset_clear (&ruleset);
|
||||
}
|
||||
|
||||
@@ -978,7 +966,6 @@ gtk_css_provider_postprocess (GtkCssProvider *css_provider)
|
||||
GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (css_provider);
|
||||
GtkCssSelectorTreeBuilder *builder;
|
||||
guint i;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
|
||||
g_array_sort (priv->rulesets, gtk_css_provider_compare_rule);
|
||||
|
||||
@@ -1009,9 +996,6 @@ gtk_css_provider_postprocess (GtkCssProvider *css_provider)
|
||||
ruleset->selector = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000, (g_get_monotonic_time () - before) * 1000, "create selector tree", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1020,8 +1004,6 @@ gtk_css_provider_load_internal (GtkCssProvider *self,
|
||||
GFile *file,
|
||||
GBytes *bytes)
|
||||
{
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
|
||||
if (bytes == NULL)
|
||||
{
|
||||
GError *load_error = NULL;
|
||||
@@ -1068,13 +1050,6 @@ gtk_css_provider_load_internal (GtkCssProvider *self,
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
gdk_profiler_add_mark (before * 1000, (g_get_monotonic_time () - before) * 1000, "theme load", uri);
|
||||
g_free (uri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -30,23 +30,6 @@
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @GTK_CSS_SELECTOR_CATEGORY_SIMPLE: A simple selector
|
||||
* @GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL: A simple selector that matches
|
||||
* what change tracking considers a "radical change"
|
||||
* @GTK_CSS_SELECTOR_SIBLING: A selector matching siblings
|
||||
* @GTK_CSS_SELECTOR_CATEGORY_PARENT: A selector matching a parent or other
|
||||
* ancestor
|
||||
*
|
||||
* Categorize the selectors. This helps in various loops when matching.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_CSS_SELECTOR_CATEGORY_SIMPLE,
|
||||
GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL,
|
||||
GTK_CSS_SELECTOR_CATEGORY_PARENT,
|
||||
GTK_CSS_SELECTOR_CATEGORY_SIBLING,
|
||||
} GtkCssSelectorCategory;
|
||||
|
||||
typedef struct _GtkCssSelectorClass GtkCssSelectorClass;
|
||||
typedef gboolean (* GtkCssSelectorForeachFunc) (const GtkCssSelector *selector,
|
||||
const GtkCssMatcher *matcher,
|
||||
@@ -54,7 +37,6 @@ typedef gboolean (* GtkCssSelectorForeachFunc) (const GtkCssSelector *selector,
|
||||
|
||||
struct _GtkCssSelectorClass {
|
||||
const char *name;
|
||||
GtkCssSelectorCategory category;
|
||||
|
||||
void (* print) (const GtkCssSelector *selector,
|
||||
GString *string);
|
||||
@@ -79,6 +61,9 @@ struct _GtkCssSelectorClass {
|
||||
guint (* hash_one) (const GtkCssSelector *selector);
|
||||
int (* compare_one) (const GtkCssSelector *a,
|
||||
const GtkCssSelector *b);
|
||||
|
||||
guint is_simple : 1;
|
||||
guint ignore_for_change : 1;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -123,6 +108,7 @@ struct _GtkCssSelectorTree
|
||||
gint32 parent_offset;
|
||||
gint32 previous_offset;
|
||||
gint32 sibling_offset;
|
||||
gint32 non_name_sibling_offset;
|
||||
gint32 matches_offset; /* pointers that we return as matches if selector matches */
|
||||
};
|
||||
|
||||
@@ -141,7 +127,7 @@ gtk_css_selector_hash_one (const GtkCssSelector *selector)
|
||||
return GPOINTER_TO_UINT (selector->class) ^ selector->class->hash_one (selector);
|
||||
}
|
||||
|
||||
static inline gpointer *
|
||||
static gpointer *
|
||||
gtk_css_selector_tree_get_matches (const GtkCssSelectorTree *tree)
|
||||
{
|
||||
if (tree->matches_offset == GTK_CSS_SELECTOR_TREE_EMPTY_OFFSET)
|
||||
@@ -186,14 +172,14 @@ gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
|
||||
}
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
static gboolean
|
||||
gtk_css_selector_match (const GtkCssSelector *selector,
|
||||
const GtkCssMatcher *matcher)
|
||||
{
|
||||
return selector->class->match_one (selector, matcher);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
static gboolean
|
||||
gtk_css_selector_foreach (const GtkCssSelector *selector,
|
||||
const GtkCssMatcher *matcher,
|
||||
GtkCssSelectorForeachFunc func,
|
||||
@@ -219,7 +205,7 @@ gtk_css_selector_previous (const GtkCssSelector *selector)
|
||||
return selector->class ? selector : NULL;
|
||||
}
|
||||
|
||||
static inline const GtkCssSelectorTree *
|
||||
static const GtkCssSelectorTree *
|
||||
gtk_css_selector_tree_at_offset (const GtkCssSelectorTree *tree,
|
||||
gint32 offset)
|
||||
{
|
||||
@@ -229,24 +215,30 @@ gtk_css_selector_tree_at_offset (const GtkCssSelectorTree *tree,
|
||||
return (GtkCssSelectorTree *) ((guint8 *)tree + offset);
|
||||
}
|
||||
|
||||
static inline const GtkCssSelectorTree *
|
||||
static const GtkCssSelectorTree *
|
||||
gtk_css_selector_tree_get_parent (const GtkCssSelectorTree *tree)
|
||||
{
|
||||
return gtk_css_selector_tree_at_offset (tree, tree->parent_offset);
|
||||
}
|
||||
|
||||
static inline const GtkCssSelectorTree *
|
||||
static const GtkCssSelectorTree *
|
||||
gtk_css_selector_tree_get_previous (const GtkCssSelectorTree *tree)
|
||||
{
|
||||
return gtk_css_selector_tree_at_offset (tree, tree->previous_offset);
|
||||
}
|
||||
|
||||
static inline const GtkCssSelectorTree *
|
||||
static const GtkCssSelectorTree *
|
||||
gtk_css_selector_tree_get_sibling (const GtkCssSelectorTree *tree)
|
||||
{
|
||||
return gtk_css_selector_tree_at_offset (tree, tree->sibling_offset);
|
||||
}
|
||||
|
||||
static const GtkCssSelectorTree *
|
||||
gtk_css_selector_tree_get_sibling2 (const GtkCssSelectorTree *tree, gboolean skip_names)
|
||||
{
|
||||
return gtk_css_selector_tree_at_offset (tree, skip_names ? tree->non_name_sibling_offset: tree->sibling_offset);
|
||||
}
|
||||
|
||||
/* DEFAULTS */
|
||||
|
||||
static void
|
||||
@@ -323,7 +315,6 @@ gtk_css_selector_descendant_get_change (const GtkCssSelector *selector, GtkCssCh
|
||||
|
||||
static const GtkCssSelectorClass GTK_CSS_SELECTOR_DESCENDANT = {
|
||||
"descendant",
|
||||
GTK_CSS_SELECTOR_CATEGORY_PARENT,
|
||||
gtk_css_selector_descendant_print,
|
||||
gtk_css_selector_descendant_foreach_matcher,
|
||||
gtk_css_selector_default_match_one,
|
||||
@@ -331,6 +322,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_DESCENDANT = {
|
||||
gtk_css_selector_default_add_specificity,
|
||||
gtk_css_selector_default_hash_one,
|
||||
gtk_css_selector_default_compare_one,
|
||||
FALSE,
|
||||
TRUE
|
||||
};
|
||||
|
||||
/* CHILD */
|
||||
@@ -364,7 +357,6 @@ gtk_css_selector_child_get_change (const GtkCssSelector *selector, GtkCssChange
|
||||
|
||||
static const GtkCssSelectorClass GTK_CSS_SELECTOR_CHILD = {
|
||||
"child",
|
||||
GTK_CSS_SELECTOR_CATEGORY_PARENT,
|
||||
gtk_css_selector_child_print,
|
||||
gtk_css_selector_child_foreach_matcher,
|
||||
gtk_css_selector_default_match_one,
|
||||
@@ -372,6 +364,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_CHILD = {
|
||||
gtk_css_selector_default_add_specificity,
|
||||
gtk_css_selector_default_hash_one,
|
||||
gtk_css_selector_default_compare_one,
|
||||
FALSE,
|
||||
TRUE
|
||||
};
|
||||
|
||||
/* SIBLING */
|
||||
@@ -410,7 +404,6 @@ gtk_css_selector_sibling_get_change (const GtkCssSelector *selector, GtkCssChang
|
||||
|
||||
static const GtkCssSelectorClass GTK_CSS_SELECTOR_SIBLING = {
|
||||
"sibling",
|
||||
GTK_CSS_SELECTOR_CATEGORY_SIBLING,
|
||||
gtk_css_selector_sibling_print,
|
||||
gtk_css_selector_sibling_foreach_matcher,
|
||||
gtk_css_selector_default_match_one,
|
||||
@@ -418,6 +411,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_SIBLING = {
|
||||
gtk_css_selector_default_add_specificity,
|
||||
gtk_css_selector_default_hash_one,
|
||||
gtk_css_selector_default_compare_one,
|
||||
FALSE,
|
||||
TRUE
|
||||
};
|
||||
|
||||
/* ADJACENT */
|
||||
@@ -451,7 +446,6 @@ gtk_css_selector_adjacent_get_change (const GtkCssSelector *selector, GtkCssChan
|
||||
|
||||
static const GtkCssSelectorClass GTK_CSS_SELECTOR_ADJACENT = {
|
||||
"adjacent",
|
||||
GTK_CSS_SELECTOR_CATEGORY_SIBLING,
|
||||
gtk_css_selector_adjacent_print,
|
||||
gtk_css_selector_adjacent_foreach_matcher,
|
||||
gtk_css_selector_default_match_one,
|
||||
@@ -459,6 +453,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_ADJACENT = {
|
||||
gtk_css_selector_default_add_specificity,
|
||||
gtk_css_selector_default_hash_one,
|
||||
gtk_css_selector_default_compare_one,
|
||||
FALSE,
|
||||
TRUE
|
||||
};
|
||||
|
||||
/* SIMPLE SELECTOR DEFINE */
|
||||
@@ -524,7 +520,6 @@ gtk_css_selector_ ## n ## _add_specificity (const GtkCssSelector *selector, \
|
||||
\
|
||||
static const GtkCssSelectorClass GTK_CSS_SELECTOR_ ## c = { \
|
||||
G_STRINGIFY(n), \
|
||||
ignore_for_change ? GTK_CSS_SELECTOR_CATEGORY_SIMPLE : GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL, \
|
||||
gtk_css_selector_ ## n ## _print, \
|
||||
gtk_css_selector_default_foreach_matcher, \
|
||||
match_func, \
|
||||
@@ -532,11 +527,12 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_ ## c = { \
|
||||
gtk_css_selector_ ## n ## _add_specificity, \
|
||||
hash_func, \
|
||||
comp_func, \
|
||||
TRUE, \
|
||||
ignore_for_change \
|
||||
};\
|
||||
\
|
||||
static const GtkCssSelectorClass GTK_CSS_SELECTOR_NOT_ ## c = { \
|
||||
"not_" G_STRINGIFY(n), \
|
||||
ignore_for_change ? GTK_CSS_SELECTOR_CATEGORY_SIMPLE : GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL, \
|
||||
gtk_css_selector_not_ ## n ## _print, \
|
||||
gtk_css_selector_default_foreach_matcher, \
|
||||
gtk_css_selector_not_ ## n ## _match_one, \
|
||||
@@ -544,6 +540,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_NOT_ ## c = { \
|
||||
gtk_css_selector_ ## n ## _add_specificity, \
|
||||
hash_func, \
|
||||
comp_func, \
|
||||
TRUE, \
|
||||
ignore_for_change \
|
||||
};
|
||||
|
||||
/* ANY */
|
||||
@@ -1764,23 +1762,6 @@ _gtk_css_selector_get_change (const GtkCssSelector *selector)
|
||||
|
||||
/******************** SelectorTree handling *****************/
|
||||
|
||||
static gboolean
|
||||
gtk_css_selector_is_simple (const GtkCssSelector *selector)
|
||||
{
|
||||
switch (selector->class->category)
|
||||
{
|
||||
case GTK_CSS_SELECTOR_CATEGORY_SIMPLE:
|
||||
case GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL:
|
||||
return TRUE;
|
||||
case GTK_CSS_SELECTOR_CATEGORY_PARENT:
|
||||
case GTK_CSS_SELECTOR_CATEGORY_SIBLING:
|
||||
return FALSE;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static GHashTable *
|
||||
gtk_css_selectors_count_initial_init (void)
|
||||
{
|
||||
@@ -1790,7 +1771,7 @@ gtk_css_selectors_count_initial_init (void)
|
||||
static void
|
||||
gtk_css_selectors_count_initial (const GtkCssSelector *selector, GHashTable *hash_one)
|
||||
{
|
||||
if (!gtk_css_selector_is_simple (selector))
|
||||
if (!selector->class->is_simple)
|
||||
{
|
||||
guint count = GPOINTER_TO_INT (g_hash_table_lookup (hash_one, selector));
|
||||
g_hash_table_replace (hash_one, (gpointer)selector, GUINT_TO_POINTER (count + 1));
|
||||
@@ -1798,7 +1779,7 @@ gtk_css_selectors_count_initial (const GtkCssSelector *selector, GHashTable *has
|
||||
}
|
||||
|
||||
for (;
|
||||
selector && gtk_css_selector_is_simple (selector);
|
||||
selector && selector->class->is_simple;
|
||||
selector = gtk_css_selector_previous (selector))
|
||||
{
|
||||
guint count = GPOINTER_TO_INT (g_hash_table_lookup (hash_one, selector));
|
||||
@@ -1809,11 +1790,11 @@ gtk_css_selectors_count_initial (const GtkCssSelector *selector, GHashTable *has
|
||||
static gboolean
|
||||
gtk_css_selectors_has_initial_selector (const GtkCssSelector *selector, const GtkCssSelector *initial)
|
||||
{
|
||||
if (!gtk_css_selector_is_simple (selector))
|
||||
if (!selector->class->is_simple)
|
||||
return gtk_css_selector_equal (selector, initial);
|
||||
|
||||
for (;
|
||||
selector && gtk_css_selector_is_simple (selector);
|
||||
selector && selector->class->is_simple;
|
||||
selector = gtk_css_selector_previous (selector))
|
||||
{
|
||||
if (gtk_css_selector_equal (selector, initial))
|
||||
@@ -1833,13 +1814,13 @@ gtk_css_selectors_skip_initial_selector (GtkCssSelector *selector, const GtkCssS
|
||||
without losing any other selectors */
|
||||
if (!gtk_css_selector_equal (selector, initial))
|
||||
{
|
||||
for (found = selector; found && gtk_css_selector_is_simple (found); found = (GtkCssSelector *)gtk_css_selector_previous (found))
|
||||
for (found = selector; found && found->class->is_simple; found = (GtkCssSelector *)gtk_css_selector_previous (found))
|
||||
{
|
||||
if (gtk_css_selector_equal (found, initial))
|
||||
break;
|
||||
}
|
||||
|
||||
g_assert (found != NULL && gtk_css_selector_is_simple (found));
|
||||
g_assert (found != NULL && found->class->is_simple);
|
||||
|
||||
tmp = *found;
|
||||
*found = *selector;
|
||||
@@ -1849,23 +1830,38 @@ gtk_css_selectors_skip_initial_selector (GtkCssSelector *selector, const GtkCssS
|
||||
return (GtkCssSelector *)gtk_css_selector_previous (selector);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
gboolean matched_name;
|
||||
GPtrArray *matches;
|
||||
} MatchData;
|
||||
|
||||
static gboolean
|
||||
gtk_css_selector_tree_match_foreach (const GtkCssSelector *selector,
|
||||
const GtkCssMatcher *matcher,
|
||||
gpointer res)
|
||||
{
|
||||
const GtkCssSelectorTree *tree = (const GtkCssSelectorTree *) selector;
|
||||
MatchData *data = res;
|
||||
MatchData level_data;
|
||||
const GtkCssSelectorTree *prev;
|
||||
|
||||
if (!gtk_css_selector_match (selector, matcher))
|
||||
return FALSE;
|
||||
|
||||
gtk_css_selector_tree_found_match (tree, res);
|
||||
if (selector->class == >K_CSS_SELECTOR_NAME)
|
||||
data->matched_name = TRUE;
|
||||
|
||||
gtk_css_selector_tree_found_match (tree, &data->matches);
|
||||
|
||||
level_data.matched_name = FALSE;
|
||||
level_data.matches = data->matches;
|
||||
|
||||
for (prev = gtk_css_selector_tree_get_previous (tree);
|
||||
prev != NULL;
|
||||
prev = gtk_css_selector_tree_get_sibling (prev))
|
||||
gtk_css_selector_foreach (&prev->selector, matcher, gtk_css_selector_tree_match_foreach, res);
|
||||
prev = gtk_css_selector_tree_get_sibling2 (prev, level_data.matched_name))
|
||||
gtk_css_selector_foreach (&prev->selector, matcher, gtk_css_selector_tree_match_foreach, &level_data);
|
||||
|
||||
data->matches = level_data.matches;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1874,13 +1870,15 @@ GPtrArray *
|
||||
_gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
|
||||
const GtkCssMatcher *matcher)
|
||||
{
|
||||
GPtrArray *array = NULL;
|
||||
MatchData data = { FALSE, NULL };
|
||||
|
||||
for (; tree != NULL;
|
||||
tree = gtk_css_selector_tree_get_sibling (tree))
|
||||
gtk_css_selector_foreach (&tree->selector, matcher, gtk_css_selector_tree_match_foreach, &array);
|
||||
tree = gtk_css_selector_tree_get_sibling2 (tree, data.matched_name))
|
||||
{
|
||||
gtk_css_selector_foreach (&tree->selector, matcher, gtk_css_selector_tree_match_foreach, &data);
|
||||
}
|
||||
|
||||
return array;
|
||||
return data.matches;
|
||||
}
|
||||
|
||||
/* The code for collecting matches assumes that the name, id and classes
|
||||
@@ -1892,7 +1890,7 @@ static gboolean
|
||||
gtk_css_selector_match_for_change (const GtkCssSelector *selector,
|
||||
const GtkCssMatcher *matcher)
|
||||
{
|
||||
if (selector->class->category != GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL)
|
||||
if (selector->class->ignore_for_change)
|
||||
return TRUE;
|
||||
|
||||
return selector->class->match_one (selector, matcher);
|
||||
@@ -1935,7 +1933,7 @@ gtk_css_selector_tree_get_change (const GtkCssSelectorTree *tree,
|
||||
if (!gtk_css_selector_match_for_change (&tree->selector, matcher))
|
||||
return 0;
|
||||
|
||||
if (!gtk_css_selector_is_simple (&tree->selector))
|
||||
if (!tree->selector.class->is_simple)
|
||||
return gtk_css_selector_tree_collect_change (tree) | GTK_CSS_CHANGE_GOT_MATCH;
|
||||
|
||||
for (prev = gtk_css_selector_tree_get_previous (tree);
|
||||
@@ -1972,9 +1970,10 @@ _gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
|
||||
return change & ~GTK_CSS_CHANGE_RESERVED_BIT;
|
||||
}
|
||||
|
||||
#define PRINT_TREE
|
||||
#ifdef PRINT_TREE
|
||||
static void
|
||||
_gtk_css_selector_tree_print (const GtkCssSelectorTree *tree, GString *str, char *prefix)
|
||||
_gtk_css_selector_tree_print (const GtkCssSelectorTree *tree, GString *str, const char *prefix)
|
||||
{
|
||||
gboolean first = TRUE;
|
||||
int len, i;
|
||||
@@ -2044,7 +2043,7 @@ _gtk_css_selector_tree_match_print (const GtkCssSelectorTree *tree,
|
||||
|
||||
/* print name and * selector before others */
|
||||
for (iter = tree;
|
||||
iter && gtk_css_selector_is_simple (&iter->selector);
|
||||
iter && iter->selector.class->is_simple;
|
||||
iter = gtk_css_selector_tree_get_parent (iter))
|
||||
{
|
||||
if (iter->selector.class == >K_CSS_SELECTOR_NAME ||
|
||||
@@ -2055,7 +2054,7 @@ _gtk_css_selector_tree_match_print (const GtkCssSelectorTree *tree,
|
||||
}
|
||||
/* now print other simple selectors */
|
||||
for (iter = tree;
|
||||
iter && gtk_css_selector_is_simple (&iter->selector);
|
||||
iter && iter->selector.class->is_simple;
|
||||
iter = gtk_css_selector_tree_get_parent (iter))
|
||||
{
|
||||
if (iter->selector.class != >K_CSS_SELECTOR_NAME &&
|
||||
@@ -2175,7 +2174,7 @@ subdivide_infos (GByteArray *array, GList *infos, gint32 parent_offset)
|
||||
exact_matches = g_ptr_array_new ();
|
||||
g_ptr_array_add (exact_matches, info->match);
|
||||
if (info->selector_match != NULL)
|
||||
*info->selector_match = GUINT_TO_POINTER (tree_offset);
|
||||
*info->selector_match = GUINT_TO_POINTER (tree_offset);
|
||||
}
|
||||
else
|
||||
matched = g_list_prepend (matched, info);
|
||||
@@ -2266,6 +2265,33 @@ fixup_offsets (GtkCssSelectorTree *tree, guint8 *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
compute_non_name_offsets (GtkCssSelectorTree *tree)
|
||||
{
|
||||
GtkCssSelectorTree *current = tree;
|
||||
|
||||
for (; tree != NULL;
|
||||
tree = (GtkCssSelectorTree *)gtk_css_selector_tree_get_sibling (tree))
|
||||
{
|
||||
compute_non_name_offsets ((GtkCssSelectorTree *)gtk_css_selector_tree_get_previous (tree));
|
||||
|
||||
if (tree->selector.class != >K_CSS_SELECTOR_NAME)
|
||||
{
|
||||
for (; current != tree;
|
||||
current = (GtkCssSelectorTree *)gtk_css_selector_tree_get_sibling (current))
|
||||
{
|
||||
current->non_name_sibling_offset = ((guint8 *)tree - (guint8 *)current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (; current != NULL;
|
||||
current = (GtkCssSelectorTree *)gtk_css_selector_tree_get_sibling (current))
|
||||
{
|
||||
current->non_name_sibling_offset = GTK_CSS_SELECTOR_TREE_EMPTY_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
GtkCssSelectorTree *
|
||||
_gtk_css_selector_tree_builder_build (GtkCssSelectorTreeBuilder *builder)
|
||||
{
|
||||
@@ -2288,6 +2314,7 @@ _gtk_css_selector_tree_builder_build (GtkCssSelectorTreeBuilder *builder)
|
||||
tree = (GtkCssSelectorTree *)data;
|
||||
|
||||
fixup_offsets (tree, data);
|
||||
compute_non_name_offsets (tree);
|
||||
|
||||
/* Convert offsets to final pointers */
|
||||
for (l = builder->infos; l != NULL; l = l->next)
|
||||
|
@@ -131,7 +131,6 @@ gtk_css_value_shadow_compute (GtkCssValue *value,
|
||||
shadows[i].radius = _gtk_css_value_compute (shadow->radius, property_id, provider, style, parent_style);
|
||||
shadows[i].spread = _gtk_css_value_compute (shadow->spread, property_id, provider, style, parent_style),
|
||||
shadows[i].color = _gtk_css_value_compute (shadow->color, property_id, provider, style, parent_style);
|
||||
shadows[i].inset = shadow->inset;
|
||||
}
|
||||
|
||||
return gtk_css_shadow_value_new (shadows, value->n_shadows);
|
||||
|
@@ -46,8 +46,8 @@ void gtk_css_shadow_value_snapshot_inset (const GtkCssValue
|
||||
GtkSnapshot *snapshot,
|
||||
const GskRoundedRect *padding_box);
|
||||
|
||||
gboolean gtk_css_shadow_value_is_clear (const GtkCssValue *shadow) G_GNUC_PURE;
|
||||
gboolean gtk_css_shadow_value_is_none (const GtkCssValue *shadow) G_GNUC_PURE;
|
||||
gboolean gtk_css_shadow_value_is_clear (const GtkCssValue *shadow);
|
||||
gboolean gtk_css_shadow_value_is_none (const GtkCssValue *shadow);
|
||||
|
||||
gboolean gtk_css_shadow_value_push_snapshot (const GtkCssValue *value,
|
||||
GtkSnapshot *snapshot);
|
||||
|
@@ -67,7 +67,7 @@ GType _gtk_css_shorthand_property_get_type (void) G
|
||||
|
||||
GtkCssStyleProperty * _gtk_css_shorthand_property_get_subproperty (GtkCssShorthandProperty *shorthand,
|
||||
guint property);
|
||||
guint _gtk_css_shorthand_property_get_n_subproperties (GtkCssShorthandProperty *shorthand) G_GNUC_CONST;
|
||||
guint _gtk_css_shorthand_property_get_n_subproperties (GtkCssShorthandProperty *shorthand);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -34,164 +34,11 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkCssStaticStyleClass GtkCssStaticStyleClass;
|
||||
|
||||
/* inherited */
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *color;
|
||||
GtkCssValue *dpi;
|
||||
GtkCssValue *font_size;
|
||||
GtkCssValue *icon_theme;
|
||||
GtkCssValue *icon_palette;
|
||||
} GtkCssCoreValues;
|
||||
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *background_color;
|
||||
GtkCssValue *box_shadow;
|
||||
GtkCssValue *background_clip;
|
||||
GtkCssValue *background_origin;
|
||||
GtkCssValue *background_size;
|
||||
GtkCssValue *background_position;
|
||||
GtkCssValue *background_repeat;
|
||||
GtkCssValue *background_image;
|
||||
GtkCssValue *background_blend_mode;
|
||||
} GtkCssBackgroundValues;
|
||||
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *border_top_style;
|
||||
GtkCssValue *border_top_width;
|
||||
GtkCssValue *border_left_style;
|
||||
GtkCssValue *border_left_width;
|
||||
GtkCssValue *border_bottom_style;
|
||||
GtkCssValue *border_bottom_width;
|
||||
GtkCssValue *border_right_style;
|
||||
GtkCssValue *border_right_width;
|
||||
GtkCssValue *border_top_left_radius;
|
||||
GtkCssValue *border_top_right_radius;
|
||||
GtkCssValue *border_bottom_right_radius;
|
||||
GtkCssValue *border_bottom_left_radius;
|
||||
GtkCssValue *border_top_color;
|
||||
GtkCssValue *border_right_color;
|
||||
GtkCssValue *border_bottom_color;
|
||||
GtkCssValue *border_left_color;
|
||||
GtkCssValue *border_image_source;
|
||||
GtkCssValue *border_image_repeat;
|
||||
GtkCssValue *border_image_slice;
|
||||
GtkCssValue *border_image_width;
|
||||
} GtkCssBorderValues;
|
||||
|
||||
/* inherited */
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *icon_size;
|
||||
GtkCssValue *icon_shadow;
|
||||
GtkCssValue *icon_style;
|
||||
} GtkCssIconValues;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *outline_style;
|
||||
GtkCssValue *outline_width;
|
||||
GtkCssValue *outline_offset;
|
||||
GtkCssValue *outline_top_left_radius;
|
||||
GtkCssValue *outline_top_right_radius;
|
||||
GtkCssValue *outline_bottom_right_radius;
|
||||
GtkCssValue *outline_bottom_left_radius;
|
||||
GtkCssValue *outline_color;
|
||||
} GtkCssOutlineValues;
|
||||
|
||||
/* inherited */
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *font_family;
|
||||
GtkCssValue *font_style;
|
||||
GtkCssValue *font_weight;
|
||||
GtkCssValue *font_stretch;
|
||||
GtkCssValue *letter_spacing;
|
||||
GtkCssValue *text_shadow;
|
||||
GtkCssValue *caret_color;
|
||||
GtkCssValue *secondary_caret_color;
|
||||
GtkCssValue *font_feature_settings;
|
||||
GtkCssValue *font_variation_settings;
|
||||
} GtkCssFontValues;
|
||||
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *text_decoration_line;
|
||||
GtkCssValue *text_decoration_color;
|
||||
GtkCssValue *text_decoration_style;
|
||||
GtkCssValue *font_kerning;
|
||||
GtkCssValue *font_variant_ligatures;
|
||||
GtkCssValue *font_variant_position;
|
||||
GtkCssValue *font_variant_caps;
|
||||
GtkCssValue *font_variant_numeric;
|
||||
GtkCssValue *font_variant_alternates;
|
||||
GtkCssValue *font_variant_east_asian;
|
||||
} GtkCssFontVariantValues;
|
||||
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *animation_name;
|
||||
GtkCssValue *animation_duration;
|
||||
GtkCssValue *animation_timing_function;
|
||||
GtkCssValue *animation_iteration_count;
|
||||
GtkCssValue *animation_direction;
|
||||
GtkCssValue *animation_play_state;
|
||||
GtkCssValue *animation_delay;
|
||||
GtkCssValue *animation_fill_mode;
|
||||
} GtkCssAnimationValues;
|
||||
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *transition_property;
|
||||
GtkCssValue *transition_duration;
|
||||
GtkCssValue *transition_timing_function;
|
||||
GtkCssValue *transition_delay;
|
||||
} GtkCssTransitionValues;
|
||||
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *margin_top;
|
||||
GtkCssValue *margin_left;
|
||||
GtkCssValue *margin_bottom;
|
||||
GtkCssValue *margin_right;
|
||||
GtkCssValue *padding_top;
|
||||
GtkCssValue *padding_left;
|
||||
GtkCssValue *padding_bottom;
|
||||
GtkCssValue *padding_right;
|
||||
GtkCssValue *border_spacing;
|
||||
GtkCssValue *min_width;
|
||||
GtkCssValue *min_height;
|
||||
} GtkCssSizeValues;
|
||||
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
GtkCssValue *icon_source;
|
||||
GtkCssValue *icon_transform;
|
||||
GtkCssValue *icon_filter;
|
||||
GtkCssValue *transform;
|
||||
GtkCssValue *opacity;
|
||||
GtkCssValue *filter;
|
||||
} GtkCssOtherValues;
|
||||
|
||||
struct _GtkCssStaticStyle
|
||||
{
|
||||
GtkCssStyle parent;
|
||||
|
||||
GtkCssCoreValues *core;
|
||||
GtkCssBackgroundValues *background;
|
||||
GtkCssBorderValues *border;
|
||||
GtkCssIconValues *icon;
|
||||
GtkCssOutlineValues *outline;
|
||||
GtkCssFontValues *font;
|
||||
GtkCssFontVariantValues *font_variant;
|
||||
GtkCssAnimationValues *animation;
|
||||
GtkCssTransitionValues *transition;
|
||||
GtkCssSizeValues *size;
|
||||
GtkCssOtherValues *other;
|
||||
|
||||
GtkCssValue *values[GTK_CSS_PROPERTY_N_PROPERTIES]; /* the values */
|
||||
GPtrArray *sections; /* sections the values are defined in */
|
||||
|
||||
GtkCssChange change; /* change as returned by value lookup */
|
||||
@@ -210,6 +57,13 @@ GtkCssStyle * gtk_css_static_style_new_compute (GtkStyleProvide
|
||||
GtkCssStyle *parent,
|
||||
GtkCssChange change);
|
||||
|
||||
void gtk_css_static_style_compute_value (GtkCssStaticStyle *style,
|
||||
GtkStyleProvider *provider,
|
||||
GtkCssStyle *parent_style,
|
||||
guint id,
|
||||
GtkCssValue *specified,
|
||||
GtkCssSection *section);
|
||||
|
||||
GtkCssChange gtk_css_static_style_get_change (GtkCssStaticStyle *style);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -921,9 +921,6 @@ icon_theme_value_parse (GtkCssStyleProperty *property,
|
||||
|
||||
/*** REGISTRATION ***/
|
||||
|
||||
G_STATIC_ASSERT (GTK_CSS_PROPERTY_COLOR == 0);
|
||||
G_STATIC_ASSERT (GTK_CSS_PROPERTY_DPI < GTK_CSS_PROPERTY_FONT_SIZE);
|
||||
|
||||
void
|
||||
_gtk_css_style_property_init_properties (void)
|
||||
{
|
||||
@@ -935,7 +932,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_PROPERTY_COLOR,
|
||||
GDK_TYPE_RGBA,
|
||||
GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
|
||||
GTK_CSS_AFFECTS_CONTENT | GTK_CSS_AFFECTS_ICON_REDRAW_SYMBOLIC,
|
||||
GTK_CSS_AFFECTS_CONTENT | GTK_CSS_AFFECTS_SYMBOLIC_ICON,
|
||||
color_parse,
|
||||
color_query,
|
||||
gtk_css_color_value_new_white ());
|
||||
@@ -959,7 +956,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_PROPERTY_ICON_THEME,
|
||||
G_TYPE_NONE,
|
||||
GTK_STYLE_PROPERTY_INHERIT,
|
||||
GTK_CSS_AFFECTS_ICON_TEXTURE,
|
||||
GTK_CSS_AFFECTS_ICON | GTK_CSS_AFFECTS_SYMBOLIC_ICON | GTK_CSS_AFFECTS_ICON_SIZE,
|
||||
icon_theme_value_parse,
|
||||
NULL,
|
||||
gtk_css_icon_theme_value_new (NULL));
|
||||
@@ -967,7 +964,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_PROPERTY_ICON_PALETTE,
|
||||
G_TYPE_NONE,
|
||||
GTK_STYLE_PROPERTY_ANIMATED | GTK_STYLE_PROPERTY_INHERIT,
|
||||
GTK_CSS_AFFECTS_ICON_REDRAW_SYMBOLIC,
|
||||
GTK_CSS_AFFECTS_SYMBOLIC_ICON,
|
||||
icon_palette_parse,
|
||||
NULL,
|
||||
gtk_css_palette_value_new_default ());
|
||||
@@ -1494,7 +1491,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_PROPERTY_ICON_SOURCE,
|
||||
G_TYPE_NONE,
|
||||
GTK_STYLE_PROPERTY_ANIMATED,
|
||||
GTK_CSS_AFFECTS_ICON_TEXTURE,
|
||||
GTK_CSS_AFFECTS_ICON | GTK_CSS_AFFECTS_SYMBOLIC_ICON,
|
||||
css_image_value_parse,
|
||||
NULL,
|
||||
_gtk_css_image_value_new (NULL));
|
||||
@@ -1502,7 +1499,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_PROPERTY_ICON_SIZE,
|
||||
G_TYPE_NONE,
|
||||
GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
|
||||
GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_ICON_SIZE,
|
||||
GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_ICON | GTK_CSS_AFFECTS_SYMBOLIC_ICON,
|
||||
icon_size_parse,
|
||||
NULL,
|
||||
_gtk_css_number_value_new (16, GTK_CSS_PX));
|
||||
@@ -1510,7 +1507,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_PROPERTY_ICON_SHADOW,
|
||||
G_TYPE_NONE,
|
||||
GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
|
||||
GTK_CSS_AFFECTS_ICON_REDRAW,
|
||||
GTK_CSS_AFFECTS_ICON | GTK_CSS_AFFECTS_SYMBOLIC_ICON,
|
||||
shadow_value_parse,
|
||||
NULL,
|
||||
gtk_css_shadow_value_new_none ());
|
||||
@@ -1518,7 +1515,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_PROPERTY_ICON_STYLE,
|
||||
G_TYPE_NONE,
|
||||
GTK_STYLE_PROPERTY_INHERIT,
|
||||
GTK_CSS_AFFECTS_ICON_TEXTURE,
|
||||
GTK_CSS_AFFECTS_ICON | GTK_CSS_AFFECTS_SYMBOLIC_ICON | GTK_CSS_AFFECTS_ICON_SIZE,
|
||||
icon_style_parse,
|
||||
NULL,
|
||||
_gtk_css_icon_style_value_new (GTK_CSS_ICON_STYLE_REQUESTED));
|
||||
|
@@ -64,7 +64,7 @@ GType _gtk_css_style_property_get_type (void) G_GNUC_CO
|
||||
|
||||
void _gtk_css_style_property_init_properties (void);
|
||||
|
||||
guint _gtk_css_style_property_get_n_properties(void) G_GNUC_CONST;
|
||||
guint _gtk_css_style_property_get_n_properties(void);
|
||||
GtkCssStyleProperty * _gtk_css_style_property_lookup_by_id (guint id);
|
||||
|
||||
gboolean _gtk_css_style_property_is_inherit (GtkCssStyleProperty *property);
|
||||
|
@@ -22,6 +22,36 @@
|
||||
|
||||
G_DEFINE_TYPE (GtkCssTransientNode, gtk_css_transient_node, GTK_TYPE_CSS_NODE)
|
||||
|
||||
static GtkWidgetPath *
|
||||
gtk_css_transient_node_create_widget_path (GtkCssNode *node)
|
||||
{
|
||||
GtkWidgetPath *result;
|
||||
GtkCssNode *parent;
|
||||
|
||||
parent = gtk_css_node_get_parent (node);
|
||||
if (parent == NULL)
|
||||
result = gtk_widget_path_new ();
|
||||
else
|
||||
result = gtk_css_node_create_widget_path (parent);
|
||||
|
||||
gtk_widget_path_append_type (result, gtk_css_node_get_widget_type (node));
|
||||
gtk_css_node_declaration_add_to_widget_path (gtk_css_node_get_declaration (node), result, -1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const GtkWidgetPath *
|
||||
gtk_css_transient_node_get_widget_path (GtkCssNode *node)
|
||||
{
|
||||
GtkCssNode *parent;
|
||||
|
||||
parent = gtk_css_node_get_parent (node);
|
||||
if (parent == NULL)
|
||||
return NULL;
|
||||
|
||||
return gtk_css_node_get_widget_path (parent);
|
||||
}
|
||||
|
||||
static GtkCssStyle *
|
||||
gtk_css_transient_node_update_style (GtkCssNode *cssnode,
|
||||
GtkCssChange change,
|
||||
@@ -37,6 +67,8 @@ gtk_css_transient_node_class_init (GtkCssTransientNodeClass *klass)
|
||||
{
|
||||
GtkCssNodeClass *node_class = GTK_CSS_NODE_CLASS (klass);
|
||||
|
||||
node_class->create_widget_path = gtk_css_transient_node_create_widget_path;
|
||||
node_class->get_widget_path = gtk_css_transient_node_get_widget_path;
|
||||
node_class->update_style = gtk_css_transient_node_update_style;
|
||||
}
|
||||
|
||||
|
@@ -132,16 +132,13 @@ typedef guint64 GtkCssChange;
|
||||
* see @GTK_CSS_AFFECTS_TEXT.
|
||||
* @GTK_CSS_AFFECTS_BACKGROUND: The background rendering is affected.
|
||||
* @GTK_CSS_AFFECTS_BORDER: The border styling is affected.
|
||||
* @GTK_CSS_AFFECTS_ICON_SIZE: Icon size is affected.
|
||||
* @GTK_CSS_AFFECTS_TEXT_ATTRS: Text attributes are affected.
|
||||
* @GTK_CSS_AFFECTS_TEXT_SIZE: Text size is affected.
|
||||
* @GTK_CSS_AFFECTS_TEXT_CONTENT: Text rendering is affected, but size or
|
||||
* attributes are not.
|
||||
* @GTK_CSS_AFFECTS_ICON_SIZE: Icon size is affected.
|
||||
* @GTK_CSS_AFFECTS_ICON_TEXTURE: The icon texture has changed and needs to be
|
||||
* reloaded.
|
||||
* @GTK_CSS_AFFECTS_ICON_REDRAW: Icons need to be redrawn (both symbolic and
|
||||
* non-symbolic).
|
||||
* @GTK_CSS_AFFECTS_ICON_REDRAW_SYMBOLIC: Symbolic icons need to be redrawn.
|
||||
* @GTK_CSS_AFFECTS_ICON: Fullcolor icons and their rendering is affected.
|
||||
* @GTK_CSS_AFFECTS_SYMBOLIC_ICON: Symbolic icons and their rendering is affected.
|
||||
* @GTK_CSS_AFFECTS_OUTLINE: The outline styling is affected.
|
||||
* @GTK_CSS_AFFECTS_SIZE: Changes in this property may have an effect
|
||||
* on the allocated size of the element. Changes in these properties
|
||||
@@ -157,25 +154,26 @@ typedef guint64 GtkCssChange;
|
||||
* Note that multiple values can be set.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_CSS_AFFECTS_CONTENT = (1 << 0),
|
||||
GTK_CSS_AFFECTS_BACKGROUND = (1 << 1),
|
||||
GTK_CSS_AFFECTS_BORDER = (1 << 2),
|
||||
GTK_CSS_AFFECTS_TEXT_ATTRS = (1 << 3),
|
||||
GTK_CSS_AFFECTS_TEXT_SIZE = (1 << 4),
|
||||
GTK_CSS_AFFECTS_TEXT_CONTENT = (1 << 5),
|
||||
GTK_CSS_AFFECTS_ICON_SIZE = (1 << 6),
|
||||
GTK_CSS_AFFECTS_ICON_TEXTURE = (1 << 7),
|
||||
GTK_CSS_AFFECTS_ICON_REDRAW = (1 << 8),
|
||||
GTK_CSS_AFFECTS_ICON_REDRAW_SYMBOLIC = (1 << 9),
|
||||
GTK_CSS_AFFECTS_OUTLINE = (1 << 10),
|
||||
GTK_CSS_AFFECTS_SIZE = (1 << 11),
|
||||
GTK_CSS_AFFECTS_POSTEFFECT = (1 << 12),
|
||||
GTK_CSS_AFFECTS_TRANSFORM = (1 << 13),
|
||||
GTK_CSS_AFFECTS_CONTENT = (1 << 0),
|
||||
GTK_CSS_AFFECTS_BACKGROUND = (1 << 1),
|
||||
GTK_CSS_AFFECTS_BORDER = (1 << 2),
|
||||
GTK_CSS_AFFECTS_ICON_SIZE = (1 << 3),
|
||||
GTK_CSS_AFFECTS_TEXT_ATTRS = (1 << 4),
|
||||
GTK_CSS_AFFECTS_TEXT_SIZE = (1 << 5),
|
||||
GTK_CSS_AFFECTS_TEXT_CONTENT = (1 << 6),
|
||||
GTK_CSS_AFFECTS_ICON = (1 << 7),
|
||||
GTK_CSS_AFFECTS_SYMBOLIC_ICON = (1 << 8),
|
||||
GTK_CSS_AFFECTS_OUTLINE = (1 << 9),
|
||||
GTK_CSS_AFFECTS_SIZE = (1 << 10),
|
||||
GTK_CSS_AFFECTS_POSTEFFECT = (1 << 11),
|
||||
GTK_CSS_AFFECTS_TRANSFORM = (1 << 12),
|
||||
} GtkCssAffects;
|
||||
|
||||
#define GTK_CSS_AFFECTS_REDRAW (GTK_CSS_AFFECTS_CONTENT | \
|
||||
GTK_CSS_AFFECTS_BACKGROUND | \
|
||||
GTK_CSS_AFFECTS_BORDER | \
|
||||
GTK_CSS_AFFECTS_ICON | \
|
||||
GTK_CSS_AFFECTS_SYMBOLIC_ICON | \
|
||||
GTK_CSS_AFFECTS_OUTLINE | \
|
||||
GTK_CSS_AFFECTS_POSTEFFECT)
|
||||
|
||||
|
@@ -329,7 +329,7 @@ _gtk_css_value_print (const GtkCssValue *value,
|
||||
* Returns %TRUE if the value is dynamic
|
||||
*/
|
||||
gboolean
|
||||
gtk_css_value_is_dynamic (const GtkCssValue *value)
|
||||
gtk_css_value_is_dynamic (GtkCssValue *value)
|
||||
{
|
||||
gtk_internal_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
|
@@ -55,7 +55,7 @@ struct _GtkCssValueClass {
|
||||
GtkCssValue *end,
|
||||
guint property_id,
|
||||
double progress);
|
||||
gboolean (* is_dynamic) (const GtkCssValue *value);
|
||||
gboolean (* is_dynamic) (GtkCssValue *value);
|
||||
GtkCssValue * (* get_dynamic_value) (GtkCssValue *value,
|
||||
gint64 monotonic_time);
|
||||
void (* print) (const GtkCssValue *value,
|
||||
@@ -77,16 +77,16 @@ GtkCssValue *_gtk_css_value_compute (GtkCssValue
|
||||
guint property_id,
|
||||
GtkStyleProvider *provider,
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style) G_GNUC_PURE;
|
||||
GtkCssStyle *parent_style);
|
||||
gboolean _gtk_css_value_equal (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2) G_GNUC_PURE;
|
||||
const GtkCssValue *value2);
|
||||
gboolean _gtk_css_value_equal0 (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2) G_GNUC_PURE;
|
||||
const GtkCssValue *value2);
|
||||
GtkCssValue *_gtk_css_value_transition (GtkCssValue *start,
|
||||
GtkCssValue *end,
|
||||
guint property_id,
|
||||
double progress);
|
||||
gboolean gtk_css_value_is_dynamic (const GtkCssValue *value) G_GNUC_PURE;
|
||||
gboolean gtk_css_value_is_dynamic (GtkCssValue *value);
|
||||
GtkCssValue * gtk_css_value_get_dynamic_value (GtkCssValue *value,
|
||||
gint64 monotonic_time);
|
||||
|
||||
|
@@ -38,6 +38,20 @@ gtk_css_widget_node_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (gtk_css_widget_node_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_widget_node_style_changed (GtkCssNode *cssnode,
|
||||
GtkCssStyleChange *change)
|
||||
{
|
||||
GtkCssWidgetNode *node;
|
||||
|
||||
node = GTK_CSS_WIDGET_NODE (cssnode);
|
||||
|
||||
if (node->widget)
|
||||
gtk_widget_clear_path (node->widget);
|
||||
|
||||
GTK_CSS_NODE_CLASS (gtk_css_widget_node_parent_class)->style_changed (cssnode, change);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_widget_node_queue_callback (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
@@ -119,6 +133,40 @@ gtk_css_widget_node_init_matcher (GtkCssNode *node,
|
||||
return GTK_CSS_NODE_CLASS (gtk_css_widget_node_parent_class)->init_matcher (node, matcher);
|
||||
}
|
||||
|
||||
static GtkWidgetPath *
|
||||
gtk_css_widget_node_create_widget_path (GtkCssNode *node)
|
||||
{
|
||||
GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node);
|
||||
GtkWidgetPath *path;
|
||||
guint length;
|
||||
|
||||
if (widget_node->widget == NULL)
|
||||
path = gtk_widget_path_new ();
|
||||
else
|
||||
path = _gtk_widget_create_path (widget_node->widget);
|
||||
|
||||
length = gtk_widget_path_length (path);
|
||||
if (length > 0)
|
||||
{
|
||||
gtk_css_node_declaration_add_to_widget_path (gtk_css_node_get_declaration (node),
|
||||
path,
|
||||
length - 1);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static const GtkWidgetPath *
|
||||
gtk_css_widget_node_get_widget_path (GtkCssNode *node)
|
||||
{
|
||||
GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node);
|
||||
|
||||
if (widget_node->widget == NULL)
|
||||
return NULL;
|
||||
|
||||
return gtk_widget_get_path (widget_node->widget);
|
||||
}
|
||||
|
||||
static GtkStyleProvider *
|
||||
gtk_css_widget_node_get_style_provider (GtkCssNode *node)
|
||||
{
|
||||
@@ -163,8 +211,11 @@ gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass)
|
||||
node_class->queue_validate = gtk_css_widget_node_queue_validate;
|
||||
node_class->dequeue_validate = gtk_css_widget_node_dequeue_validate;
|
||||
node_class->init_matcher = gtk_css_widget_node_init_matcher;
|
||||
node_class->create_widget_path = gtk_css_widget_node_create_widget_path;
|
||||
node_class->get_widget_path = gtk_css_widget_node_get_widget_path;
|
||||
node_class->get_style_provider = gtk_css_widget_node_get_style_provider;
|
||||
node_class->get_frame_clock = gtk_css_widget_node_get_frame_clock;
|
||||
node_class->style_changed = gtk_css_widget_node_style_changed;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -22,12 +22,9 @@
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkcssstyleprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcsstypesprivate.h"
|
||||
#include "gtknativeprivate.h"
|
||||
#include "gtkpicture.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -110,15 +107,16 @@ gtk_drag_icon_native_get_surface_transform (GtkNative *native,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
GtkCssStyle *style;
|
||||
GtkStyleContext *context;
|
||||
GtkBorder margin, border, padding;
|
||||
|
||||
style = gtk_css_node_get_style (gtk_widget_get_css_node (GTK_WIDGET (native)));
|
||||
*x = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_MARGIN_LEFT), 100) +
|
||||
_gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH), 100) +
|
||||
_gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_PADDING_LEFT), 100);
|
||||
*y = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_MARGIN_TOP), 100) +
|
||||
_gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 100) +
|
||||
_gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_PADDING_TOP), 100);
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (native));
|
||||
gtk_style_context_get_margin (context, &margin);
|
||||
gtk_style_context_get_border (context, &border);
|
||||
gtk_style_context_get_padding (context, &padding);
|
||||
|
||||
*x = margin.left + border.left + padding.left;
|
||||
*y = margin.top + border.top + padding.top;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -387,7 +387,8 @@ add_emoji (GtkWidget *box,
|
||||
return;
|
||||
}
|
||||
|
||||
child = g_object_new (GTK_TYPE_FLOW_BOX_CHILD, "css-name", "emoji", NULL);
|
||||
child = gtk_flow_box_child_new ();
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (child), "emoji");
|
||||
g_object_set_data_full (G_OBJECT (child), "emoji-data",
|
||||
g_variant_ref (item),
|
||||
(GDestroyNotify)g_variant_unref);
|
||||
|
@@ -179,11 +179,16 @@ move_active_row (GtkEmojiCompletion *completion,
|
||||
int direction)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GtkWidget *base;
|
||||
|
||||
for (child = gtk_widget_get_first_child (completion->list);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
gtk_widget_unset_state_flags (child, GTK_STATE_FLAG_FOCUSED);
|
||||
{
|
||||
gtk_widget_unset_state_flags (child, GTK_STATE_FLAG_PRELIGHT);
|
||||
base = GTK_WIDGET (g_object_get_data (G_OBJECT (child), "base"));
|
||||
gtk_widget_unset_state_flags (base, GTK_STATE_FLAG_PRELIGHT);
|
||||
}
|
||||
|
||||
if (completion->active != NULL)
|
||||
{
|
||||
@@ -202,11 +207,11 @@ move_active_row (GtkEmojiCompletion *completion,
|
||||
}
|
||||
|
||||
if (completion->active != NULL)
|
||||
gtk_widget_set_state_flags (completion->active, GTK_STATE_FLAG_FOCUSED, FALSE);
|
||||
gtk_widget_set_state_flags (completion->active, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
||||
|
||||
if (completion->active_variation)
|
||||
{
|
||||
gtk_widget_unset_state_flags (completion->active_variation, GTK_STATE_FLAG_FOCUSED);
|
||||
gtk_widget_unset_state_flags (completion->active_variation, GTK_STATE_FLAG_PRELIGHT);
|
||||
completion->active_variation = NULL;
|
||||
}
|
||||
}
|
||||
@@ -227,7 +232,6 @@ show_variations (GtkEmojiCompletion *completion,
|
||||
{
|
||||
GtkWidget *stack;
|
||||
GtkWidget *box;
|
||||
GtkWidget *child;
|
||||
gboolean is_visible;
|
||||
|
||||
if (!row)
|
||||
@@ -242,10 +246,17 @@ show_variations (GtkEmojiCompletion *completion,
|
||||
if (is_visible == visible)
|
||||
return;
|
||||
|
||||
if (visible)
|
||||
gtk_widget_unset_state_flags (row, GTK_STATE_FLAG_PRELIGHT);
|
||||
else
|
||||
gtk_widget_set_state_flags (row, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
||||
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (stack), visible ? "variations" : "text");
|
||||
for (child = gtk_widget_get_first_child (box); child; child = gtk_widget_get_next_sibling (child))
|
||||
gtk_widget_unset_state_flags (child, GTK_STATE_FLAG_FOCUSED);
|
||||
completion->active_variation = NULL;
|
||||
if (completion->active_variation)
|
||||
{
|
||||
gtk_widget_unset_state_flags (completion->active_variation, GTK_STATE_FLAG_PRELIGHT);
|
||||
completion->active_variation = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -283,9 +294,9 @@ move_active_variation (GtkEmojiCompletion *completion,
|
||||
if (next)
|
||||
{
|
||||
if (completion->active_variation)
|
||||
gtk_widget_unset_state_flags (completion->active_variation, GTK_STATE_FLAG_FOCUSED);
|
||||
gtk_widget_unset_state_flags (completion->active_variation, GTK_STATE_FLAG_PRELIGHT);
|
||||
completion->active_variation = next;
|
||||
gtk_widget_set_state_flags (completion->active_variation, GTK_STATE_FLAG_FOCUSED, FALSE);
|
||||
gtk_widget_set_state_flags (completion->active_variation, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
||||
}
|
||||
|
||||
return next != NULL;
|
||||
@@ -466,7 +477,8 @@ add_emoji_variation (GtkWidget *box,
|
||||
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
|
||||
child = g_object_new (GTK_TYPE_FLOW_BOX_CHILD, "css-name", "emoji", NULL);
|
||||
child = gtk_flow_box_child_new ();
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (child), "emoji");
|
||||
g_object_set_data_full (G_OBJECT (child), "text", g_strdup (text), g_free);
|
||||
g_object_set_data_full (G_OBJECT (child), "emoji-data",
|
||||
g_variant_ref (emoji_data),
|
||||
@@ -501,7 +513,7 @@ add_emoji (GtkWidget *list,
|
||||
pango_attr_list_unref (attrs);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (label), "emoji");
|
||||
|
||||
child = g_object_new (GTK_TYPE_LIST_BOX_ROW, "css-name", "emoji-completion-row", NULL);
|
||||
child = gtk_list_box_row_new ();
|
||||
gtk_widget_set_focus_on_click (child, FALSE);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (child), box);
|
||||
@@ -538,6 +550,7 @@ add_emoji (GtkWidget *list,
|
||||
g_object_set_data_full (G_OBJECT (child), "text", g_strdup (text), g_free);
|
||||
g_object_set_data_full (G_OBJECT (child), "emoji-data",
|
||||
g_variant_ref (emoji_data), (GDestroyNotify)g_variant_unref);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (child), "emoji-completion-row");
|
||||
|
||||
gtk_list_box_insert (GTK_LIST_BOX (list), child, -1);
|
||||
}
|
||||
@@ -553,12 +566,9 @@ populate_completion (GtkEmojiCompletion *completion,
|
||||
GVariantIter iter;
|
||||
GVariant *item;
|
||||
|
||||
if (completion->text != text)
|
||||
{
|
||||
g_free (completion->text);
|
||||
completion->text = g_strdup (text);
|
||||
completion->length = g_utf8_strlen (text, -1);
|
||||
}
|
||||
g_free (completion->text);
|
||||
completion->text = g_strdup (text);
|
||||
completion->length = g_utf8_strlen (text, -1);
|
||||
completion->offset = offset;
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (completion->list));
|
||||
@@ -593,7 +603,7 @@ populate_completion (GtkEmojiCompletion *completion,
|
||||
if (n_added > 0)
|
||||
{
|
||||
completion->active = gtk_widget_get_first_child (completion->list);
|
||||
gtk_widget_set_state_flags (completion->active, GTK_STATE_FLAG_FOCUSED, FALSE);
|
||||
gtk_widget_set_state_flags (completion->active, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
||||
}
|
||||
|
||||
return n_added;
|
||||
|
@@ -73,7 +73,7 @@
|
||||
* ├── box.start
|
||||
* │ ╰── box
|
||||
* │ ├── [image.titlebutton.icon]
|
||||
* │ ├── [menubutton.titlebutton.menu]
|
||||
* │ ├── [menubutton.titlebutton.appmenu]
|
||||
* │ ├── [button.titlebutton.minimize]
|
||||
* │ ├── [button.titlebutton.maximize]
|
||||
* │ ╰── [button.titlebutton.close]
|
||||
@@ -406,7 +406,7 @@ _gtk_header_bar_update_window_buttons (GtkHeaderBar *bar)
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton");
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (button), "menu");
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (button), "appmenu");
|
||||
image = gtk_image_new ();
|
||||
gtk_menu_button_add_child (GTK_MENU_BUTTON (button), image);
|
||||
gtk_widget_set_can_focus (button, FALSE);
|
||||
|
@@ -54,29 +54,6 @@ gtk_icon_snapshot (GtkWidget *widget,
|
||||
gtk_css_style_snapshot_icon (style, snapshot, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_style_updated (GtkWidget *widget)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkCssStyleChange *change = NULL;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
change = gtk_style_context_get_change (context);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_icon_parent_class)->style_updated (widget);
|
||||
|
||||
if (change == NULL ||
|
||||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_SIZE))
|
||||
{
|
||||
gtk_widget_queue_resize (widget);
|
||||
}
|
||||
else if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_TEXTURE) ||
|
||||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_REDRAW))
|
||||
{
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
@@ -99,7 +76,6 @@ gtk_icon_class_init (GtkIconClass *klass)
|
||||
|
||||
wclass->snapshot = gtk_icon_snapshot;
|
||||
wclass->measure = gtk_icon_measure;
|
||||
wclass->style_updated = gtk_icon_style_updated;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -35,7 +35,6 @@
|
||||
#include "gtkscalerprivate.h"
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
|
||||
struct _GtkIconHelper
|
||||
{
|
||||
@@ -144,14 +143,11 @@ gtk_icon_helper_load_paintable (GtkIconHelper *self,
|
||||
GdkPaintable *paintable;
|
||||
GIcon *gicon;
|
||||
gboolean symbolic;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
char *item;
|
||||
|
||||
switch (gtk_image_definition_get_storage_type (self->def))
|
||||
{
|
||||
case GTK_IMAGE_PAINTABLE:
|
||||
paintable = g_object_ref (gtk_image_definition_get_paintable (self->def));
|
||||
item = g_strdup ("paintable");
|
||||
symbolic = FALSE;
|
||||
break;
|
||||
|
||||
@@ -160,7 +156,6 @@ gtk_icon_helper_load_paintable (GtkIconHelper *self,
|
||||
gicon = g_themed_icon_new_with_default_fallbacks (gtk_image_definition_get_icon_name (self->def));
|
||||
else
|
||||
gicon = g_themed_icon_new (gtk_image_definition_get_icon_name (self->def));
|
||||
item = g_icon_to_string (gicon);
|
||||
paintable = ensure_paintable_for_gicon (self,
|
||||
gtk_css_node_get_style (self->node),
|
||||
gtk_widget_get_direction (self->owner),
|
||||
@@ -171,7 +166,6 @@ gtk_icon_helper_load_paintable (GtkIconHelper *self,
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_GICON:
|
||||
item = g_icon_to_string (gtk_image_definition_get_gicon (self->def));
|
||||
paintable = ensure_paintable_for_gicon (self,
|
||||
gtk_css_node_get_style (self->node),
|
||||
gtk_widget_get_direction (self->owner),
|
||||
@@ -184,16 +178,11 @@ gtk_icon_helper_load_paintable (GtkIconHelper *self,
|
||||
default:
|
||||
paintable = NULL;
|
||||
symbolic = FALSE;
|
||||
item = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
*out_symbolic = symbolic;
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000, (g_get_monotonic_time () - before) * 1000, "icon helper load", item);
|
||||
g_free (item);
|
||||
|
||||
return paintable;
|
||||
}
|
||||
|
||||
@@ -385,24 +374,19 @@ gtk_icon_helper_invalidate_for_change (GtkIconHelper *self,
|
||||
GtkCssStyleChange *change)
|
||||
{
|
||||
if (change == NULL ||
|
||||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_TEXTURE))
|
||||
((gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SYMBOLIC_ICON) &&
|
||||
self->texture_is_symbolic) ||
|
||||
(gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON) &&
|
||||
!self->texture_is_symbolic)))
|
||||
{
|
||||
/* Avoid the queue_resize in gtk_icon_helper_invalidate */
|
||||
g_clear_object (&self->paintable);
|
||||
self->texture_is_symbolic = FALSE;
|
||||
gtk_widget_queue_draw (self->owner);
|
||||
}
|
||||
|
||||
if (change == NULL ||
|
||||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_SIZE))
|
||||
{
|
||||
gtk_widget_queue_resize (self->owner);
|
||||
}
|
||||
else if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_REDRAW) ||
|
||||
(self->texture_is_symbolic &&
|
||||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_REDRAW_SYMBOLIC)))
|
||||
{
|
||||
gtk_widget_queue_draw (self->owner);
|
||||
if (change == NULL ||
|
||||
(gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_SIZE) &&
|
||||
!GTK_IS_CSS_TRANSIENT_NODE (self->node)))
|
||||
gtk_widget_queue_resize (self->owner);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -50,7 +50,6 @@
|
||||
#include "gtkprivate.h"
|
||||
#include "gdkpixbufutilsprivate.h"
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
|
||||
/* this is in case round() is not provided by the compiler,
|
||||
* such as in the case of C89 compilers, like MSVC
|
||||
@@ -1363,7 +1362,6 @@ ensure_valid_themes (GtkIconTheme *self)
|
||||
{
|
||||
GTimeVal tv;
|
||||
gboolean was_valid = self->themes_valid;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
|
||||
if (self->loading_themes)
|
||||
return;
|
||||
@@ -1390,9 +1388,6 @@ ensure_valid_themes (GtkIconTheme *self)
|
||||
queue_theme_changed (self);
|
||||
}
|
||||
|
||||
if (gdk_profiler_is_running ())
|
||||
gdk_profiler_add_mark (before * 1000, (g_get_monotonic_time () - before) * 1000, "icon theme load", NULL);
|
||||
|
||||
self->loading_themes = FALSE;
|
||||
}
|
||||
|
||||
@@ -3248,8 +3243,6 @@ icon_info_ensure_scale_and_texture (GtkIconInfo *icon_info)
|
||||
icon_info->scale = (gdouble) scaled_desired_size / (icon_info->dir_size * dir_scale);
|
||||
}
|
||||
|
||||
gdk_profiler_add_mark (g_get_monotonic_time () * 1000, 0, "icon load", icon_info->filename);
|
||||
|
||||
/* At this point, we need to actually get the icon; either from the
|
||||
* builtin image or by loading the file
|
||||
*/
|
||||
|
@@ -924,10 +924,13 @@ gtk_im_context_ime_set_preedit_font (GtkIMContext *context)
|
||||
}
|
||||
|
||||
style = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_save (style);
|
||||
gtk_style_context_set_state (style, GTK_STATE_FLAG_NORMAL);
|
||||
gtk_style_context_get (style,
|
||||
"font",
|
||||
&font_desc,
|
||||
NULL);
|
||||
gtk_style_context_restore (style);
|
||||
|
||||
if (lang[0])
|
||||
{
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "gtkmodulesprivate.h"
|
||||
#include "gtksettings.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkutilsprivate.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
|
@@ -25,82 +25,10 @@
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkmodulesprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkutilsprivate.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
static char *
|
||||
gtk_trim_string (const char *str)
|
||||
{
|
||||
int len;
|
||||
|
||||
g_return_val_if_fail (str != NULL, NULL);
|
||||
|
||||
while (*str && g_ascii_isspace (*str))
|
||||
str++;
|
||||
|
||||
len = strlen (str);
|
||||
while (len > 0 && g_ascii_isspace (str[len - 1]))
|
||||
len--;
|
||||
|
||||
return g_strndup (str, len);
|
||||
}
|
||||
|
||||
static char **
|
||||
split_file_list (const char *str)
|
||||
{
|
||||
int i = 0;
|
||||
int j;
|
||||
char **files;
|
||||
|
||||
files = g_strsplit (str, G_SEARCHPATH_SEPARATOR_S, -1);
|
||||
|
||||
while (files[i])
|
||||
{
|
||||
char *file = gtk_trim_string (files[i]);
|
||||
|
||||
/* If the resulting file is empty, skip it */
|
||||
if (file[0] == '\0')
|
||||
{
|
||||
g_free (file);
|
||||
g_free (files[i]);
|
||||
|
||||
for (j = i + 1; files[j]; j++)
|
||||
files[j - 1] = files[j];
|
||||
|
||||
files[j - 1] = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
/* '~' is a quite normal and common character in file names on
|
||||
* Windows, especially in the 8.3 versions of long file names, which
|
||||
* still occur now and then. Also, few Windows user are aware of the
|
||||
* Unix shell convention that '~' stands for the home directory,
|
||||
* even if they happen to have a home directory.
|
||||
*/
|
||||
if (file[0] == '~' && file[1] == G_DIR_SEPARATOR)
|
||||
{
|
||||
char *tmp = g_strconcat (g_get_home_dir(), file + 1, NULL);
|
||||
g_free (file);
|
||||
file = tmp;
|
||||
}
|
||||
else if (file[0] == '~' && file[1] == '\0')
|
||||
{
|
||||
g_free (file);
|
||||
file = g_strdup (g_get_home_dir ());
|
||||
}
|
||||
#endif
|
||||
|
||||
g_free (files[i]);
|
||||
files[i] = file;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
static gchar **
|
||||
get_module_path (void)
|
||||
{
|
||||
@@ -130,7 +58,7 @@ get_module_path (void)
|
||||
|
||||
g_free (default_dir);
|
||||
|
||||
result = split_file_list (module_path);
|
||||
result = gtk_split_file_list (module_path);
|
||||
g_free (module_path);
|
||||
|
||||
return result;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user