Compare commits
247 Commits
wip/ebassi
...
css-style-
Author | SHA1 | Date | |
---|---|---|---|
|
8a14144658 | ||
|
0ff6176525 | ||
|
c30befed1e | ||
|
9d38806ced | ||
|
3cdde3fc4b | ||
|
05b9a99661 | ||
|
a16e1cbf18 | ||
|
c7ea83cd82 | ||
|
352c9ba42a | ||
|
30b37dd7c5 | ||
|
2e256986c3 | ||
|
77e0d360ed | ||
|
942a93250a | ||
|
7ccd6597c3 | ||
|
355a417dba | ||
|
36e3f4d902 | ||
|
69fe705d0d | ||
|
f62535affc | ||
|
1a56a10fc1 | ||
|
4287f0def4 | ||
|
7bebc3e2b2 | ||
|
b4e2df8fca | ||
|
0df0de0b5d | ||
|
53c22bf833 | ||
|
d8144ec497 | ||
|
3d9e3390f1 | ||
|
03595f9567 | ||
|
64e026d0a9 | ||
|
0623b00512 | ||
|
ac902e697e | ||
|
f1ff69963e | ||
|
731ae8f39e | ||
|
7da6fdc30e | ||
|
a297129685 | ||
|
1eec7362b9 | ||
|
a105256611 | ||
|
2ee04ee8ed | ||
|
6e358e2a49 | ||
|
71ee4df357 | ||
|
2bc6e1b875 | ||
|
4e58541d52 | ||
|
53bc1d60c4 | ||
|
5b6b4f5075 | ||
|
16654eeef4 | ||
|
871959c88c | ||
|
55d08d8400 | ||
|
5dcce0c0bd | ||
|
975fe76a0e | ||
|
00be314feb | ||
|
da5d524324 | ||
|
8e41fa2778 | ||
|
f80a341b4f | ||
|
77f8245c0c | ||
|
8afdbd6ee3 | ||
|
ac4e98f16a | ||
|
ab0869ecbc | ||
|
cff8304133 | ||
|
962e38c5c9 | ||
|
7855a98fd1 | ||
|
aea27b86c1 | ||
|
d4caf3d679 | ||
|
d9652675ef | ||
|
685288216f | ||
|
c8fa1f19db | ||
|
7e4feb092b | ||
|
9eadcd8d55 | ||
|
86aa011587 | ||
|
f9e613f8fd | ||
|
e13692c52f | ||
|
cbed409f52 | ||
|
0351f27af2 | ||
|
f84ecf9cd2 | ||
|
5e9d186c26 | ||
|
de9f0c5505 | ||
|
f5865b125e | ||
|
3483c1a45b | ||
|
5cc088128f | ||
|
c4548e9c7b | ||
|
5d6aeb4bf7 | ||
|
560e03f962 | ||
|
c3f1ff7db4 | ||
|
88d26b7549 | ||
|
4ac8011126 | ||
|
9b29da93b6 | ||
|
0fe9643728 | ||
|
73a214d1a9 | ||
|
59a31e05bc | ||
|
527b67af3d | ||
|
3c03d7970a | ||
|
278762f00a | ||
|
1565f597c8 | ||
|
fea42def61 | ||
|
56b8d1dfbe | ||
|
3120fb29e1 | ||
|
119457279b | ||
|
dfea9bf0e8 | ||
|
36cb812ad8 | ||
|
95ed9de706 | ||
|
a0448e2c7f | ||
|
a6b05a19f1 | ||
|
672d7f679a | ||
|
feecfcab27 | ||
|
24fa0f8e28 | ||
|
878f35515d | ||
|
68fd796125 | ||
|
5014b2a7fe | ||
|
8cb375de11 | ||
|
7927bcf6c5 | ||
|
d24d0e9667 | ||
|
e9e4bd423a | ||
|
81ddf4b946 | ||
|
c8485af819 | ||
|
704a659438 | ||
|
d32b0d3118 | ||
|
23426b0f39 | ||
|
417edd28fb | ||
|
ea17728ee5 | ||
|
a6f300cefd | ||
|
05b98c3834 | ||
|
820c9403e3 | ||
|
509531349d | ||
|
2a5a52dd4b | ||
|
f42e18507f | ||
|
e6a0a2f587 | ||
|
631ea5caac | ||
|
d59784f7c7 | ||
|
193eb5b0dd | ||
|
6a1adf6f1a | ||
|
563ad2db1b | ||
|
c85d9a3259 | ||
|
b9c81b1b94 | ||
|
b52bcf7e0a | ||
|
a38ba91e35 | ||
|
a350c2452a | ||
|
025902b9fb | ||
|
7e2e92a87e | ||
|
be4d42507c | ||
|
6e88ccf7fb | ||
|
cec4c15f05 | ||
|
ce1f1f7dec | ||
|
95f00c6071 | ||
|
55cfeccfd2 | ||
|
2301916fa4 | ||
|
bb4efe18b7 | ||
|
a463dccd81 | ||
|
eff129323f | ||
|
a5530caec3 | ||
|
92cfc03821 | ||
|
46bb1a9b6a | ||
|
19280db075 | ||
|
7210c5484e | ||
|
433c8307b2 | ||
|
26506b0a15 | ||
|
f8fa946989 | ||
|
119ebe1d70 | ||
|
dda54b2b8f | ||
|
821efcb725 | ||
|
85793fe6b6 | ||
|
dc8dedce07 | ||
|
f5182f1c35 | ||
|
1efa39672b | ||
|
3f38a1c94c | ||
|
d861dd5df8 | ||
|
8c98fd2e46 | ||
|
3091679ffa | ||
|
2e89c5360a | ||
|
e448fc41f3 | ||
|
c9e972eecb | ||
|
45455f1bdb | ||
|
a3769eb0e5 | ||
|
7c75ea376f | ||
|
96143548ac | ||
|
0b2a6e34c4 | ||
|
24d8c0a7dc | ||
|
ba08f5e67d | ||
|
31aa5a0e53 | ||
|
7aa17afe7a | ||
|
8c678ac756 | ||
|
7d1f915a61 | ||
|
afa991752c | ||
|
fc2d05ee38 | ||
|
00aa4f0597 | ||
|
3401150cca | ||
|
67991ed0f4 | ||
|
741e12012d | ||
|
91aa60b210 | ||
|
e31c0898e5 | ||
|
1f2f2777e1 | ||
|
9cb2fe5cac | ||
|
8d15efba8f | ||
|
1200fe2daf | ||
|
515a527b27 | ||
|
06dbde22a0 | ||
|
c21280e455 | ||
|
0d9a7fe089 | ||
|
03883b8b1a | ||
|
f28cd6cea9 | ||
|
b8b90fefd8 | ||
|
b4a9cf2bfb | ||
|
2a919a4d4f | ||
|
b2775d9bdd | ||
|
d0a8a717ef | ||
|
7d72703d54 | ||
|
8ecd4e87e3 | ||
|
9de31929d6 | ||
|
b41bba07fa | ||
|
0f694b8beb | ||
|
7b1ab8fb8b | ||
|
d9b1a1ebb1 | ||
|
d4f3979896 | ||
|
2e7cb6019f | ||
|
f1fce5253e | ||
|
81b65eadcb | ||
|
1e7705c08e | ||
|
cc3cf581ab | ||
|
6e09c5cee8 | ||
|
69fb3648b2 | ||
|
23f84e3a3d | ||
|
1a9b1f38a4 | ||
|
00a488a5b5 | ||
|
26c4c28068 | ||
|
da2e184639 | ||
|
9576222b47 | ||
|
7738a05bd2 | ||
|
93b5b487ae | ||
|
7588655a42 | ||
|
007713c0ba | ||
|
f0c1c3349f | ||
|
0dba6e5759 | ||
|
60cd7cd96c | ||
|
2b504201e3 | ||
|
3fcbe8d5f3 | ||
|
105acfe908 | ||
|
1caf197a0d | ||
|
0a49726c73 | ||
|
dd0cc9df9f | ||
|
789f6f3941 | ||
|
2c231f4336 | ||
|
3c50e5324f | ||
|
3182063ffe | ||
|
5910e5ac6d | ||
|
b2b89f6c57 | ||
|
5ac24db049 | ||
|
192a24fa1f | ||
|
2426b9e23a | ||
|
64848aebf4 | ||
|
fcceac6d11 |
@@ -13,7 +13,7 @@ stages:
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64: &fedora-x86_64-defaults
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v8
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v9
|
||||
stage: build
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
@@ -29,6 +29,7 @@ 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,6 +67,7 @@ RUN dnf -y install \
|
||||
python3-wheel \
|
||||
redhat-rpm-config \
|
||||
sassc \
|
||||
sysprof-devel \
|
||||
systemtap-sdt-devel \
|
||||
vulkan-devel \
|
||||
wayland-devel \
|
||||
|
@@ -16,6 +16,7 @@ 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 (gtk_widget_get_style_context(widget), "menu");
|
||||
menu_context = get_style (NULL, "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");
|
||||
|
@@ -94,9 +94,12 @@ drawing_area_draw (GtkDrawingArea *area,
|
||||
cairo_pattern_t *pat;
|
||||
cairo_matrix_t matrix;
|
||||
gdouble angle, scale;
|
||||
gdouble x_center, y_center;
|
||||
|
||||
gtk_gesture_get_bounding_box_center (GTK_GESTURE (zoom), &x_center, &y_center);
|
||||
|
||||
cairo_get_matrix (cr, &matrix);
|
||||
cairo_matrix_translate (&matrix, width / 2, height / 2);
|
||||
cairo_matrix_translate (&matrix, x_center, y_center);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
|
@@ -2000,6 +2000,13 @@ 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[])
|
||||
{
|
||||
@@ -2065,6 +2072,9 @@ 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,6 +183,7 @@ 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,7 +775,6 @@ 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
|
||||
@@ -4412,7 +4411,6 @@ 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
|
||||
@@ -4897,7 +4895,6 @@ gtk_border_free
|
||||
<SUBSECTION>
|
||||
gtk_render_arrow
|
||||
gtk_render_background
|
||||
gtk_render_background_get_clip
|
||||
gtk_render_check
|
||||
gtk_render_expander
|
||||
gtk_render_focus
|
||||
|
@@ -23,6 +23,10 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkcontentserializer.h"
|
||||
#include "gdkcontentdeserializer.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
@@ -42,145 +46,6 @@
|
||||
#include "filetransferportalprivate.h"
|
||||
|
||||
static GDBusProxy *file_transfer_proxy = NULL;
|
||||
static gboolean done;
|
||||
static guint timeout_id;
|
||||
|
||||
static void
|
||||
got_proxy (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
file_transfer_proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
|
||||
if (!file_transfer_proxy)
|
||||
{
|
||||
g_message ("failed to get file transfer portal proxy: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
if (timeout_id)
|
||||
{
|
||||
g_source_remove (timeout_id);
|
||||
timeout_id = 0;
|
||||
}
|
||||
|
||||
done = TRUE;
|
||||
g_main_context_wakeup (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
got_bus (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GDBusConnection **bus = data;
|
||||
GError *error = NULL;
|
||||
|
||||
*bus = g_bus_get_finish (result, &error);
|
||||
if (!*bus)
|
||||
{
|
||||
g_message ("failed to get session bus connection: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
if (timeout_id)
|
||||
{
|
||||
g_source_remove (timeout_id);
|
||||
timeout_id = 0;
|
||||
}
|
||||
|
||||
done = TRUE;
|
||||
g_main_context_wakeup (NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
give_up_on_proxy (gpointer data)
|
||||
{
|
||||
GCancellable *cancellable = data;
|
||||
|
||||
g_cancellable_cancel (cancellable);
|
||||
|
||||
timeout_id = 0;
|
||||
|
||||
done = TRUE;
|
||||
g_main_context_wakeup (NULL);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static GDBusProxy *
|
||||
ensure_file_transfer_portal (void)
|
||||
{
|
||||
if (file_transfer_proxy == NULL)
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
GDBusConnection *bus = NULL;
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
done = FALSE;
|
||||
timeout_id = g_timeout_add (500, give_up_on_proxy, cancellable);
|
||||
g_bus_get (G_BUS_TYPE_SESSION,
|
||||
cancellable,
|
||||
got_bus,
|
||||
&bus);
|
||||
|
||||
while (!done)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
if (bus)
|
||||
{
|
||||
done = FALSE;
|
||||
timeout_id = g_timeout_add (500, give_up_on_proxy, cancellable);
|
||||
g_dbus_proxy_new (bus,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
|
||||
| G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS
|
||||
| G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
NULL,
|
||||
"org.freedesktop.portal.Documents",
|
||||
"/org/freedesktop/portal/documents",
|
||||
"org.freedesktop.portal.FileTransfer",
|
||||
cancellable,
|
||||
got_proxy,
|
||||
NULL);
|
||||
|
||||
while (!done)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
g_clear_object (&bus);
|
||||
}
|
||||
|
||||
g_clear_object (&cancellable);
|
||||
}
|
||||
|
||||
if (file_transfer_proxy)
|
||||
{
|
||||
char *owner = g_dbus_proxy_get_name_owner (file_transfer_proxy);
|
||||
|
||||
if (owner)
|
||||
{
|
||||
g_free (owner);
|
||||
return file_transfer_proxy;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
file_transfer_portal_available (void)
|
||||
{
|
||||
gboolean available;
|
||||
|
||||
ensure_file_transfer_portal ();
|
||||
|
||||
available = file_transfer_proxy != NULL;
|
||||
|
||||
g_clear_object (&file_transfer_proxy);
|
||||
|
||||
return available;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GTask *task;
|
||||
@@ -328,15 +193,12 @@ file_transfer_portal_register_files (const char **files,
|
||||
gpointer data)
|
||||
{
|
||||
GTask *task;
|
||||
GDBusProxy *proxy;
|
||||
AddFileData *afd;
|
||||
GVariantBuilder options;
|
||||
|
||||
task = g_task_new (NULL, NULL, callback, data);
|
||||
|
||||
proxy = ensure_file_transfer_portal ();
|
||||
|
||||
if (proxy == NULL)
|
||||
if (file_transfer_proxy == NULL)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
"No portal found");
|
||||
@@ -354,7 +216,7 @@ file_transfer_portal_register_files (const char **files,
|
||||
g_variant_builder_add (&options, "{sv}", "writable", g_variant_new_boolean (writable));
|
||||
g_variant_builder_add (&options, "{sv}", "autostop", g_variant_new_boolean (TRUE));
|
||||
|
||||
g_dbus_proxy_call (proxy, "StartTransfer",
|
||||
g_dbus_proxy_call (file_transfer_proxy, "StartTransfer",
|
||||
g_variant_new ("(a{sv})", &options),
|
||||
0, -1, NULL, start_session_done, afd);
|
||||
}
|
||||
@@ -406,15 +268,12 @@ file_transfer_portal_retrieve_files (const char *key,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
GDBusProxy *proxy;
|
||||
GTask *task;
|
||||
GVariantBuilder options;
|
||||
|
||||
task = g_task_new (NULL, NULL, callback, data);
|
||||
|
||||
proxy = ensure_file_transfer_portal ();
|
||||
|
||||
if (proxy == NULL)
|
||||
if (file_transfer_proxy == NULL)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
"No portal found");
|
||||
@@ -423,7 +282,7 @@ file_transfer_portal_retrieve_files (const char *key,
|
||||
}
|
||||
|
||||
g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
|
||||
g_dbus_proxy_call (proxy,
|
||||
g_dbus_proxy_call (file_transfer_proxy,
|
||||
"RetrieveFiles",
|
||||
g_variant_new ("(sa{sv})", key, &options),
|
||||
0, -1, NULL,
|
||||
@@ -444,4 +303,235 @@ file_transfer_portal_retrieve_files_finish (GAsyncResult *result,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* serializer */
|
||||
|
||||
static void
|
||||
file_serializer_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer serializer)
|
||||
{
|
||||
GOutputStream *stream = G_OUTPUT_STREAM (source);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_output_stream_write_all_finish (stream, result, NULL, &error))
|
||||
gdk_content_serializer_return_error (serializer, error);
|
||||
else
|
||||
gdk_content_serializer_return_success (serializer);
|
||||
}
|
||||
|
||||
static void
|
||||
portal_ready (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer serializer)
|
||||
{
|
||||
GError *error = NULL;
|
||||
char *key;
|
||||
|
||||
if (!file_transfer_portal_register_files_finish (result, &key, &error))
|
||||
{
|
||||
gdk_content_serializer_return_error (serializer, error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
|
||||
key,
|
||||
strlen (key) + 1,
|
||||
gdk_content_serializer_get_priority (serializer),
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
file_serializer_finish,
|
||||
serializer);
|
||||
gdk_content_serializer_set_task_data (serializer, key, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
portal_file_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
GFile *file;
|
||||
const GValue *value;
|
||||
GPtrArray *files;
|
||||
|
||||
files = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
value = gdk_content_serializer_get_value (serializer);
|
||||
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
file = g_value_get_object (gdk_content_serializer_get_value (serializer));
|
||||
if (file)
|
||||
g_ptr_array_add (files, g_file_get_path (file));
|
||||
g_ptr_array_add (files, NULL);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = g_value_get_boxed (value); l; l = l->next)
|
||||
g_ptr_array_add (files, g_file_get_path (l->data));
|
||||
|
||||
g_ptr_array_add (files, NULL);
|
||||
}
|
||||
|
||||
/* this call doesn't copy the strings, so keep the array around until the registration is done */
|
||||
file_transfer_portal_register_files ((const char **)files->pdata, TRUE, portal_ready, serializer);
|
||||
gdk_content_serializer_set_task_data (serializer, files, (GDestroyNotify)g_ptr_array_unref);
|
||||
}
|
||||
|
||||
/* deserializer */
|
||||
|
||||
static void
|
||||
portal_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer deserializer)
|
||||
{
|
||||
char **files = NULL;
|
||||
GError *error = NULL;
|
||||
GValue *value;
|
||||
|
||||
if (!file_transfer_portal_retrieve_files_finish (result, &files, &error))
|
||||
{
|
||||
gdk_content_deserializer_return_error (deserializer, error);
|
||||
return;
|
||||
}
|
||||
|
||||
value = gdk_content_deserializer_get_value (deserializer);
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
if (files[0] != NULL)
|
||||
g_value_take_object (value, g_file_new_for_path (files[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
GSList *l = NULL;
|
||||
gsize i;
|
||||
|
||||
for (i = 0; files[i] != NULL; i++)
|
||||
l = g_slist_prepend (l, g_file_new_for_path (files[i]));
|
||||
g_value_take_boxed (value, g_slist_reverse (l));
|
||||
}
|
||||
g_strfreev (files);
|
||||
|
||||
gdk_content_deserializer_return_success (deserializer);
|
||||
}
|
||||
|
||||
static void
|
||||
portal_file_deserializer_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer deserializer)
|
||||
{
|
||||
GOutputStream *stream = G_OUTPUT_STREAM (source);
|
||||
GError *error = NULL;
|
||||
gssize written;
|
||||
char *key;
|
||||
|
||||
written = g_output_stream_splice_finish (stream, result, &error);
|
||||
if (written < 0)
|
||||
{
|
||||
gdk_content_deserializer_return_error (deserializer, error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* write terminating NULL */
|
||||
if (!g_output_stream_write (stream, "", 1, NULL, &error))
|
||||
{
|
||||
gdk_content_deserializer_return_error (deserializer, error);
|
||||
return;
|
||||
}
|
||||
|
||||
key = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (stream));
|
||||
if (key == NULL)
|
||||
{
|
||||
GError *gerror = g_error_new (G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"Could not convert data from %s to %s",
|
||||
gdk_content_deserializer_get_mime_type (deserializer),
|
||||
g_type_name (gdk_content_deserializer_get_gtype (deserializer)));
|
||||
gdk_content_deserializer_return_error (deserializer, gerror);
|
||||
return;
|
||||
}
|
||||
|
||||
file_transfer_portal_retrieve_files (key, portal_finish, deserializer);
|
||||
gdk_content_deserializer_set_task_data (deserializer, key, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
portal_file_deserializer (GdkContentDeserializer *deserializer)
|
||||
{
|
||||
GOutputStream *output;
|
||||
|
||||
output = g_memory_output_stream_new_resizable ();
|
||||
|
||||
g_output_stream_splice_async (output,
|
||||
gdk_content_deserializer_get_input_stream (deserializer),
|
||||
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
|
||||
gdk_content_deserializer_get_priority (deserializer),
|
||||
gdk_content_deserializer_get_cancellable (deserializer),
|
||||
portal_file_deserializer_finish,
|
||||
deserializer);
|
||||
g_object_unref (output);
|
||||
}
|
||||
|
||||
static void
|
||||
got_proxy (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
file_transfer_proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
|
||||
if (!file_transfer_proxy)
|
||||
{
|
||||
g_message ("Failed to get file transfer portal: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_content_register_serializer (G_TYPE_FILE,
|
||||
"application/vnd.portal.files",
|
||||
portal_file_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
gdk_content_register_serializer (GDK_TYPE_FILE_LIST,
|
||||
"application/vnd.portal.files",
|
||||
portal_file_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
gdk_content_register_deserializer ("application/vnd.portal.files",
|
||||
GDK_TYPE_FILE_LIST,
|
||||
portal_file_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
gdk_content_register_deserializer ("application/vnd.portal.files",
|
||||
G_TYPE_FILE,
|
||||
portal_file_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
file_transfer_portal_register (void)
|
||||
{
|
||||
static gboolean called;
|
||||
|
||||
if (!called)
|
||||
{
|
||||
called = TRUE;
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
|
||||
| G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS
|
||||
| G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
NULL,
|
||||
"org.freedesktop.portal.Documents",
|
||||
"/org/freedesktop/portal/documents",
|
||||
"org.freedesktop.portal.FileTransfer",
|
||||
NULL,
|
||||
got_proxy,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* G_OS_UNIX */
|
||||
|
@@ -19,7 +19,8 @@
|
||||
#define __FILE_TRANSFER_PROTOCOL_H__
|
||||
|
||||
|
||||
gboolean file_transfer_portal_available (void);
|
||||
void file_transfer_portal_register (void);
|
||||
|
||||
void file_transfer_portal_register_files (const char **files,
|
||||
gboolean writable,
|
||||
GAsyncReadyCallback callback,
|
||||
|
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
|
||||
|
@@ -692,95 +692,6 @@ string_deserializer (GdkContentDeserializer *deserializer)
|
||||
g_object_unref (filter);
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
static void
|
||||
portal_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer deserializer)
|
||||
{
|
||||
char **files = NULL;
|
||||
GError *error = NULL;
|
||||
GValue *value;
|
||||
|
||||
if (!file_transfer_portal_retrieve_files_finish (result, &files, &error))
|
||||
{
|
||||
gdk_content_deserializer_return_error (deserializer, error);
|
||||
return;
|
||||
}
|
||||
|
||||
value = gdk_content_deserializer_get_value (deserializer);
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
if (files[0] != NULL)
|
||||
g_value_take_object (value, g_file_new_for_path (files[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
GSList *l = NULL;
|
||||
gsize i;
|
||||
|
||||
for (i = 0; files[i] != NULL; i++)
|
||||
l = g_slist_prepend (l, g_file_new_for_path (files[i]));
|
||||
g_value_take_boxed (value, g_slist_reverse (l));
|
||||
}
|
||||
g_strfreev (files);
|
||||
|
||||
gdk_content_deserializer_return_success (deserializer);
|
||||
}
|
||||
|
||||
static void
|
||||
portal_file_deserializer_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer deserializer)
|
||||
{
|
||||
GOutputStream *stream = G_OUTPUT_STREAM (source);
|
||||
GError *error = NULL;
|
||||
gssize written;
|
||||
char *key;
|
||||
|
||||
written = g_output_stream_splice_finish (stream, result, &error);
|
||||
if (written < 0)
|
||||
{
|
||||
gdk_content_deserializer_return_error (deserializer, error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* write terminating NULL */
|
||||
if (!g_output_stream_write (stream, "", 1, NULL, &error))
|
||||
{
|
||||
gdk_content_deserializer_return_error (deserializer, error);
|
||||
return;
|
||||
}
|
||||
|
||||
key = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (stream));
|
||||
if (key == NULL)
|
||||
{
|
||||
deserialize_not_found (deserializer);
|
||||
return;
|
||||
}
|
||||
|
||||
file_transfer_portal_retrieve_files (key, portal_finish, deserializer);
|
||||
gdk_content_deserializer_set_task_data (deserializer, key, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
portal_file_deserializer (GdkContentDeserializer *deserializer)
|
||||
{
|
||||
GOutputStream *output;
|
||||
|
||||
output = g_memory_output_stream_new_resizable ();
|
||||
|
||||
g_output_stream_splice_async (output,
|
||||
gdk_content_deserializer_get_input_stream (deserializer),
|
||||
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
|
||||
gdk_content_deserializer_get_priority (deserializer),
|
||||
gdk_content_deserializer_get_cancellable (deserializer),
|
||||
portal_file_deserializer_finish,
|
||||
deserializer);
|
||||
g_object_unref (output);
|
||||
}
|
||||
#endif /* G_OS_UNIX */
|
||||
|
||||
static void
|
||||
file_uri_deserializer_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
@@ -965,13 +876,7 @@ init (void)
|
||||
g_slist_free (formats);
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
gboolean has_portal = file_transfer_portal_available ();
|
||||
if (has_portal)
|
||||
gdk_content_register_deserializer ("application/vnd.portal.files",
|
||||
GDK_TYPE_FILE_LIST,
|
||||
portal_file_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
file_transfer_portal_register ();
|
||||
#endif
|
||||
|
||||
gdk_content_register_deserializer ("text/uri-list",
|
||||
@@ -980,15 +885,6 @@ init (void)
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
if (has_portal)
|
||||
gdk_content_register_deserializer ("application/vnd.portal.files",
|
||||
G_TYPE_FILE,
|
||||
portal_file_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
gdk_content_register_deserializer ("text/uri-list",
|
||||
G_TYPE_FILE,
|
||||
file_uri_deserializer,
|
||||
|
@@ -703,65 +703,6 @@ file_serializer_finish (GObject *source,
|
||||
gdk_content_serializer_return_success (serializer);
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
static void
|
||||
portal_ready (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer serializer)
|
||||
{
|
||||
GError *error = NULL;
|
||||
char *key;
|
||||
|
||||
if (!file_transfer_portal_register_files_finish (result, &key, &error))
|
||||
{
|
||||
gdk_content_serializer_return_error (serializer, error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
|
||||
key,
|
||||
strlen (key) + 1,
|
||||
gdk_content_serializer_get_priority (serializer),
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
file_serializer_finish,
|
||||
serializer);
|
||||
gdk_content_serializer_set_task_data (serializer, key, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
portal_file_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
GFile *file;
|
||||
const GValue *value;
|
||||
GPtrArray *files;
|
||||
|
||||
files = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
value = gdk_content_serializer_get_value (serializer);
|
||||
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
file = g_value_get_object (gdk_content_serializer_get_value (serializer));
|
||||
if (file)
|
||||
g_ptr_array_add (files, g_file_get_path (file));
|
||||
g_ptr_array_add (files, NULL);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = g_value_get_boxed (value); l; l = l->next)
|
||||
g_ptr_array_add (files, g_file_get_path (l->data));
|
||||
|
||||
g_ptr_array_add (files, NULL);
|
||||
}
|
||||
|
||||
/* this call doesn't copy the strings, so keep the array around until the registration is done */
|
||||
file_transfer_portal_register_files ((const char **)files->pdata, TRUE, portal_ready, serializer);
|
||||
gdk_content_serializer_set_task_data (serializer, files, (GDestroyNotify)g_ptr_array_unref);
|
||||
}
|
||||
#endif /* G_OS_UNIX */
|
||||
|
||||
static void
|
||||
file_uri_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
@@ -967,14 +908,7 @@ init (void)
|
||||
g_slist_free (formats);
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
gboolean has_portal = file_transfer_portal_available ();
|
||||
|
||||
if (has_portal)
|
||||
gdk_content_register_serializer (G_TYPE_FILE,
|
||||
"application/vnd.portal.files",
|
||||
portal_file_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
file_transfer_portal_register ();
|
||||
#endif
|
||||
|
||||
gdk_content_register_serializer (G_TYPE_FILE,
|
||||
@@ -988,15 +922,6 @@ init (void)
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
if (has_portal)
|
||||
gdk_content_register_serializer (GDK_TYPE_FILE_LIST,
|
||||
"application/vnd.portal.files",
|
||||
portal_file_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
gdk_content_register_serializer (GDK_TYPE_FILE_LIST,
|
||||
"text/uri-list",
|
||||
file_uri_serializer,
|
||||
|
@@ -649,46 +649,94 @@ 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)
|
||||
{
|
||||
@@ -758,34 +806,17 @@ 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->frame_end_time * 1000,
|
||||
timings->presentation_time * 1000,
|
||||
frame_clock_get_fps (clock));
|
||||
#endif
|
||||
}
|
||||
|
@@ -42,9 +42,7 @@ 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;
|
||||
@@ -319,6 +317,7 @@ 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;
|
||||
@@ -409,13 +408,13 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
{
|
||||
int iter;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ())
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
if (priv->phase != GDK_FRAME_CLOCK_PHASE_LAYOUT &&
|
||||
(priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT))
|
||||
timings->layout_start_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
#endif
|
||||
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||
/* We loop in the layout phase, because we don't want to progress
|
||||
@@ -439,13 +438,13 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
if (priv->freeze_count == 0)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ())
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
if (priv->phase != GDK_FRAME_CLOCK_PHASE_PAINT &&
|
||||
(priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT))
|
||||
timings->paint_start_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
#endif
|
||||
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_PAINT;
|
||||
if (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT)
|
||||
@@ -466,7 +465,7 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
|
||||
}
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ())
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
timings->frame_end_time = g_get_monotonic_time ();
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
@@ -502,6 +501,9 @@ 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;
|
||||
}
|
||||
|
||||
@@ -561,13 +563,11 @@ 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,7 +594,6 @@ 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)
|
||||
@@ -602,11 +601,10 @@ 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,
|
||||
"freeze", "");
|
||||
"frameclock 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);
|
||||
gboolean gdk_rgba_is_clear (const GdkRGBA *rgba) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_rgba_is_opaque (const GdkRGBA *rgba);
|
||||
gboolean gdk_rgba_is_opaque (const GdkRGBA *rgba) G_GNUC_PURE;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gdk_rgba_hash (gconstpointer p);
|
||||
guint gdk_rgba_hash (gconstpointer p) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_rgba_equal (gconstpointer p1,
|
||||
gconstpointer p2);
|
||||
gconstpointer p2) G_GNUC_PURE;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_rgba_parse (GdkRGBA *rgba,
|
||||
|
@@ -4005,7 +4005,6 @@ 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,
|
||||
@@ -4072,6 +4071,9 @@ 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:
|
||||
@@ -4113,14 +4115,11 @@ 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))
|
||||
@@ -4139,10 +4138,8 @@ 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);
|
||||
int gdk_texture_get_width (GdkTexture *texture) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_texture_get_height (GdkTexture *texture);
|
||||
int gdk_texture_get_height (GdkTexture *texture) G_GNUC_PURE;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_texture_download (GdkTexture *texture,
|
||||
|
12
gdk/wayland/cursor/meson.build
Normal file
12
gdk/wayland/cursor/meson.build
Normal file
@@ -0,0 +1,12 @@
|
||||
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)
|
173
gdk/wayland/cursor/os-compatibility.c
Normal file
173
gdk/wayland/cursor/os-compatibility.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
34
gdk/wayland/cursor/os-compatibility.h
Normal file
34
gdk/wayland/cursor/os-compatibility.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 */
|
385
gdk/wayland/cursor/wayland-cursor.c
Normal file
385
gdk/wayland/cursor/wayland-cursor.c
Normal file
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
72
gdk/wayland/cursor/wayland-cursor.h
Normal file
72
gdk/wayland/cursor/wayland-cursor.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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
|
612
gdk/wayland/cursor/xcursor.c
Normal file
612
gdk/wayland/cursor/xcursor.c
Normal file
@@ -0,0 +1,612 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
61
gdk/wayland/cursor/xcursor.h
Normal file
61
gdk/wayland/cursor/xcursor.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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,8 +33,7 @@
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkwayland.h"
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#include <wayland-cursor.h>
|
||||
#include "cursor/wayland-cursor.h"
|
||||
|
||||
static void
|
||||
gdk_wayland_cursor_remove_from_cache (gpointer data, GObject *cursor)
|
||||
@@ -119,11 +118,12 @@ 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);
|
||||
c = wl_cursor_theme_get_cursor (theme, name, scale);
|
||||
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);
|
||||
c = wl_cursor_theme_get_cursor (theme, fallback, scale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,8 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
goto none;
|
||||
|
||||
c = gdk_wayland_cursor_load_for_name (display,
|
||||
_gdk_wayland_display_get_scaled_cursor_theme (display, desired_scale),
|
||||
_gdk_wayland_display_get_cursor_theme (display),
|
||||
desired_scale,
|
||||
gdk_cursor_get_name (cursor));
|
||||
if (c)
|
||||
{
|
||||
@@ -270,7 +271,8 @@ _gdk_wayland_cursor_get_next_image_index (GdkWaylandDisplay *display,
|
||||
}
|
||||
|
||||
c = gdk_wayland_cursor_load_for_name (display,
|
||||
_gdk_wayland_display_get_scaled_cursor_theme (display, scale),
|
||||
_gdk_wayland_display_get_cursor_theme (display),
|
||||
scale,
|
||||
gdk_cursor_get_name (cursor));
|
||||
|
||||
if (c)
|
||||
|
@@ -56,6 +56,8 @@
|
||||
#define BTN_STYLUS3 0x149 /* Linux 4.15 */
|
||||
#endif
|
||||
|
||||
#define GDK_SEAT_NOTE(seat,type,action) GDK_DISPLAY_NOTE(gdk_seat_get_display (GDK_SEAT (seat)),type,action)
|
||||
|
||||
typedef struct _GdkWaylandDevicePad GdkWaylandDevicePad;
|
||||
typedef struct _GdkWaylandDevicePadClass GdkWaylandDevicePadClass;
|
||||
|
||||
@@ -1119,7 +1121,7 @@ data_offer_offer (void *data,
|
||||
|
||||
if (seat->pending_offer != offer)
|
||||
{
|
||||
GDK_DISPLAY_NOTE (gdk_seat_get_display (GDK_SEAT (seat)), EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("%p: offer for unknown offer %p of %s",
|
||||
seat, offer, type));
|
||||
return;
|
||||
@@ -1191,7 +1193,7 @@ data_device_data_offer (void *data,
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("data device data offer, data device %p, offer %p",
|
||||
data_device, offer));
|
||||
|
||||
@@ -1228,13 +1230,13 @@ data_device_enter (void *data,
|
||||
|
||||
if (offer != seat->pending_offer)
|
||||
{
|
||||
GDK_DISPLAY_NOTE (gdk_seat_get_display (GDK_SEAT (seat)), EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("%p: enter event for unknown offer %p, expected %p",
|
||||
seat, offer, seat->pending_offer));
|
||||
return;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("data device enter, data device %p serial %u, surface %p, x %f y %f, offer %p",
|
||||
data_device, serial, surface, wl_fixed_to_double (x), wl_fixed_to_double (y), offer));
|
||||
|
||||
@@ -1274,7 +1276,7 @@ data_device_leave (void *data,
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("data device leave, data device %p", data_device));
|
||||
|
||||
if (seat->drop == NULL)
|
||||
@@ -1300,7 +1302,7 @@ data_device_motion (void *data,
|
||||
GdkWaylandSeat *seat = data;
|
||||
int origin_x, origin_y;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("data device motion, data_device = %p, time = %d, x = %f, y = %f",
|
||||
data_device, time, wl_fixed_to_double (x), wl_fixed_to_double (y)));
|
||||
|
||||
@@ -1327,7 +1329,7 @@ data_device_drop (void *data,
|
||||
GdkWaylandSeat *seat = data;
|
||||
int origin_x, origin_y;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("data device drop, data device %p", data_device));
|
||||
|
||||
gdk_surface_get_origin (gdk_drop_get_surface (seat->drop), &origin_x, &origin_y);
|
||||
@@ -1573,7 +1575,7 @@ pointer_handle_enter (void *data,
|
||||
&event->crossing.x_root,
|
||||
&event->crossing.y_root);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("enter, seat %p surface %p",
|
||||
seat, seat->pointer_info.focus));
|
||||
|
||||
@@ -1621,7 +1623,7 @@ pointer_handle_leave (void *data,
|
||||
&event->crossing.x_root,
|
||||
&event->crossing.y_root);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("leave, seat %p surface %p",
|
||||
seat, seat->pointer_info.focus));
|
||||
|
||||
@@ -1667,7 +1669,7 @@ pointer_handle_motion (void *data,
|
||||
&event->motion.x_root,
|
||||
&event->motion.y_root);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("motion %f %f, seat %p state %d",
|
||||
wl_fixed_to_double (sx), wl_fixed_to_double (sy),
|
||||
seat, event->motion.state));
|
||||
@@ -1740,7 +1742,7 @@ pointer_handle_button (void *data,
|
||||
else
|
||||
seat->pointer_info.button_modifiers &= ~modifier;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("button %d %s, seat %p state %d",
|
||||
event->button.button,
|
||||
state ? "press" : "release",
|
||||
@@ -1798,7 +1800,7 @@ pointer_handle_axis (void *data,
|
||||
|
||||
seat->pointer_info.time = time;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("scroll, axis %s, value %f, seat %p",
|
||||
get_axis_name (axis), wl_fixed_to_double (value) / 10.0,
|
||||
seat));
|
||||
@@ -1813,7 +1815,7 @@ pointer_handle_frame (void *data,
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("frame, seat %p", seat));
|
||||
|
||||
gdk_wayland_seat_flush_frame_event (seat);
|
||||
@@ -1854,7 +1856,7 @@ pointer_handle_axis_source (void *data,
|
||||
|
||||
pointer_frame->source = source;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("axis source %s, seat %p", get_axis_source_name (source), seat));
|
||||
}
|
||||
|
||||
@@ -1886,7 +1888,7 @@ pointer_handle_axis_stop (void *data,
|
||||
|
||||
pointer_frame->is_scroll_stop = TRUE;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("axis %s stop, seat %p", get_axis_name (axis), seat));
|
||||
}
|
||||
|
||||
@@ -1914,7 +1916,7 @@ pointer_handle_axis_discrete (void *data,
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("discrete scroll, axis %s, value %d, seat %p",
|
||||
get_axis_name (axis), value, seat));
|
||||
}
|
||||
@@ -1970,7 +1972,7 @@ keyboard_handle_enter (void *data,
|
||||
gdk_event_set_device (event, seat->master_keyboard);
|
||||
gdk_event_set_source_device (event, seat->keyboard);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("focus in, seat %p surface %p",
|
||||
seat, seat->keyboard_focus));
|
||||
|
||||
@@ -2011,7 +2013,7 @@ keyboard_handle_leave (void *data,
|
||||
seat->keyboard_focus = NULL;
|
||||
seat->repeat_key = 0;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("focus out, seat %p surface %p",
|
||||
seat, event->any.surface));
|
||||
|
||||
@@ -2106,7 +2108,7 @@ deliver_key_event (GdkWaylandSeat *seat,
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("keyboard %s event%s, surface %p, code %d, sym %d, "
|
||||
"mods 0x%x",
|
||||
(state ? "press" : "release"),
|
||||
@@ -2394,7 +2396,7 @@ touch_handle_down (void *data,
|
||||
mimic_pointer_emulating_touch_info (seat->touch_master, touch);
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("touch begin %f %f", event->touch.x, event->touch.y));
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
@@ -2417,7 +2419,7 @@ touch_handle_up (void *data,
|
||||
touch = gdk_wayland_seat_get_touch (seat, id);
|
||||
event = _create_touch_event (seat, touch, GDK_TOUCH_END, time);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("touch end %f %f", event->touch.x, event->touch.y));
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
@@ -2449,7 +2451,7 @@ touch_handle_motion (void *data,
|
||||
|
||||
event = _create_touch_event (seat, touch, GDK_TOUCH_UPDATE, time);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("touch update %f %f", event->touch.x, event->touch.y));
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
@@ -2486,7 +2488,7 @@ touch_handle_cancel (void *data,
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (wayland_seat->display, EVENTS, g_message ("touch cancel"));
|
||||
GDK_SEAT_NOTE (wayland_seat, EVENTS, g_message ("touch cancel"));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2522,7 +2524,7 @@ emit_gesture_swipe_event (GdkWaylandSeat *seat,
|
||||
&event->touchpad_swipe.x_root,
|
||||
&event->touchpad_swipe.y_root);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("swipe event %d, coords: %f %f, seat %p state %d",
|
||||
event->any.type, event->touchpad_swipe.x,
|
||||
event->touchpad_swipe.y, seat,
|
||||
@@ -2625,7 +2627,7 @@ emit_gesture_pinch_event (GdkWaylandSeat *seat,
|
||||
&event->touchpad_pinch.x_root,
|
||||
&event->touchpad_pinch.y_root);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("pinch event %d, coords: %f %f, seat %p state %d",
|
||||
event->any.type, event->touchpad_pinch.x,
|
||||
event->touchpad_pinch.y, seat,
|
||||
@@ -2951,7 +2953,7 @@ seat_handle_capabilities (void *data,
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, MISC,
|
||||
GDK_SEAT_NOTE (seat, MISC,
|
||||
g_message ("seat %p with %s%s%s", wl_seat,
|
||||
(caps & WL_SEAT_CAPABILITY_POINTER) ? " pointer, " : "",
|
||||
(caps & WL_SEAT_CAPABILITY_KEYBOARD) ? " keyboard, " : "",
|
||||
@@ -3174,7 +3176,7 @@ seat_handle_name (void *data,
|
||||
const char *name)
|
||||
{
|
||||
/* We don't care about the name. */
|
||||
GDK_DISPLAY_NOTE (GDK_WAYLAND_SEAT (data)->display, MISC,
|
||||
GDK_SEAT_NOTE (GDK_WAYLAND_SEAT (data), MISC,
|
||||
g_message ("seat %p name %s", seat, name));
|
||||
}
|
||||
|
||||
@@ -3488,7 +3490,7 @@ tablet_tool_handle_proximity_in (void *data,
|
||||
gdk_wayland_surface_get_wl_output (surface));
|
||||
pointer_surface_update_scale (tablet->master);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("proximity in, seat %p surface %p tool %d",
|
||||
seat, tablet->pointer_info.focus,
|
||||
gdk_device_tool_get_tool_type (tool->tool)));
|
||||
@@ -3500,11 +3502,10 @@ tablet_tool_handle_proximity_out (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
|
||||
GdkEvent *event;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("proximity out, seat %p, tool %d", seat,
|
||||
GDK_SEAT_NOTE (tool->seat, EVENTS,
|
||||
g_message ("proximity out, seat %p, tool %d", tool->seat,
|
||||
gdk_device_tool_get_tool_type (tool->tool)));
|
||||
|
||||
event = gdk_wayland_tablet_get_frame_event (tablet, GDK_PROXIMITY_OUT);
|
||||
@@ -3600,7 +3601,7 @@ tablet_tool_handle_motion (void *data,
|
||||
tablet->pointer_info.surface_x = wl_fixed_to_double (sx);
|
||||
tablet->pointer_info.surface_y = wl_fixed_to_double (sy);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("tablet motion %f %f",
|
||||
tablet->pointer_info.surface_x,
|
||||
tablet->pointer_info.surface_y));
|
||||
@@ -3633,7 +3634,7 @@ tablet_tool_handle_pressure (void *data,
|
||||
_gdk_device_translate_axis (tablet->current_device, axis_index,
|
||||
pressure, &tablet->axes[axis_index]);
|
||||
|
||||
GDK_DISPLAY_NOTE (GDK_WAYLAND_SEAT (tool->seat)->display, EVENTS,
|
||||
GDK_SEAT_NOTE (tool->seat, EVENTS,
|
||||
g_message ("tablet tool %d pressure %d",
|
||||
gdk_device_tool_get_tool_type (tool->tool), pressure));
|
||||
}
|
||||
@@ -3650,7 +3651,7 @@ tablet_tool_handle_distance (void *data,
|
||||
_gdk_device_translate_axis (tablet->current_device, axis_index,
|
||||
distance, &tablet->axes[axis_index]);
|
||||
|
||||
GDK_DISPLAY_NOTE (GDK_WAYLAND_SEAT (tool->seat)->display, EVENTS,
|
||||
GDK_SEAT_NOTE (tool->seat, EVENTS,
|
||||
g_message ("tablet tool %d distance %d",
|
||||
gdk_device_tool_get_tool_type (tool->tool), distance));
|
||||
}
|
||||
@@ -3673,7 +3674,7 @@ tablet_tool_handle_tilt (void *data,
|
||||
wl_fixed_to_double (ytilt),
|
||||
&tablet->axes[ytilt_axis_index]);
|
||||
|
||||
GDK_DISPLAY_NOTE (GDK_WAYLAND_SEAT (tool->seat)->display, EVENTS,
|
||||
GDK_SEAT_NOTE (tool->seat, EVENTS,
|
||||
g_message ("tablet tool %d tilt %f/%f",
|
||||
gdk_device_tool_get_tool_type (tool->tool),
|
||||
wl_fixed_to_double (xtilt), wl_fixed_to_double (ytilt)));
|
||||
@@ -3728,7 +3729,7 @@ tablet_tool_handle_rotation (void *data,
|
||||
wl_fixed_to_double (degrees),
|
||||
&tablet->axes[axis_index]);
|
||||
|
||||
GDK_DISPLAY_NOTE (GDK_WAYLAND_SEAT (tool->seat)->display, EVENTS,
|
||||
GDK_SEAT_NOTE (tool->seat, EVENTS,
|
||||
g_message ("tablet tool %d rotation %f",
|
||||
gdk_device_tool_get_tool_type (tool->tool),
|
||||
wl_fixed_to_double (degrees)));
|
||||
@@ -3746,7 +3747,7 @@ tablet_tool_handle_slider (void *data,
|
||||
_gdk_device_translate_axis (tablet->current_device, axis_index,
|
||||
position, &tablet->axes[axis_index]);
|
||||
|
||||
GDK_DISPLAY_NOTE (GDK_WAYLAND_SEAT (tool->seat)->display, EVENTS,
|
||||
GDK_SEAT_NOTE (tool->seat, EVENTS,
|
||||
g_message ("tablet tool %d slider %d",
|
||||
gdk_device_tool_get_tool_type (tool->tool), position));
|
||||
}
|
||||
@@ -3762,7 +3763,7 @@ tablet_tool_handle_wheel (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkEvent *event;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("tablet tool %d wheel %d/%d",
|
||||
gdk_device_tool_get_tool_type (tool->tool), degrees, clicks));
|
||||
|
||||
@@ -3792,10 +3793,9 @@ tablet_tool_handle_frame (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkEvent *frame_event;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (tablet->seat, EVENTS,
|
||||
g_message ("tablet frame, time %d", time));
|
||||
|
||||
frame_event = tablet->pointer_info.frame.event;
|
||||
@@ -3838,10 +3838,8 @@ tablet_pad_ring_handle_source (void *data,
|
||||
uint32_t source)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad ring handle source, ring = %p source = %d",
|
||||
wp_tablet_pad_ring, source));
|
||||
|
||||
@@ -3854,10 +3852,8 @@ tablet_pad_ring_handle_angle (void *data,
|
||||
wl_fixed_t angle)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad ring handle angle, ring = %p angle = %f",
|
||||
wp_tablet_pad_ring, wl_fixed_to_double (angle)));
|
||||
|
||||
@@ -3869,10 +3865,8 @@ tablet_pad_ring_handle_stop (void *data,
|
||||
struct zwp_tablet_pad_ring_v2 *wp_tablet_pad_ring)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad ring handle stop, ring = %p", wp_tablet_pad_ring));
|
||||
|
||||
group->axis_tmp_info.is_stop = TRUE;
|
||||
@@ -3888,7 +3882,7 @@ tablet_pad_ring_handle_frame (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
GdkEvent *event;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("tablet pad ring handle frame, ring = %p", wp_tablet_pad_ring));
|
||||
|
||||
event = gdk_event_new (GDK_PAD_RING);
|
||||
@@ -3918,10 +3912,8 @@ tablet_pad_strip_handle_source (void *data,
|
||||
uint32_t source)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad strip handle source, strip = %p source = %d",
|
||||
wp_tablet_pad_strip, source));
|
||||
|
||||
@@ -3934,10 +3926,8 @@ tablet_pad_strip_handle_position (void *data,
|
||||
uint32_t position)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad strip handle position, strip = %p position = %d",
|
||||
wp_tablet_pad_strip, position));
|
||||
|
||||
@@ -3949,10 +3939,8 @@ tablet_pad_strip_handle_stop (void *data,
|
||||
struct zwp_tablet_pad_strip_v2 *wp_tablet_pad_strip)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad strip handle stop, strip = %p",
|
||||
wp_tablet_pad_strip));
|
||||
|
||||
@@ -3969,7 +3957,7 @@ tablet_pad_strip_handle_frame (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
GdkEvent *event;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("tablet pad strip handle frame, strip = %p",
|
||||
wp_tablet_pad_strip));
|
||||
|
||||
@@ -4001,11 +3989,9 @@ tablet_pad_group_handle_buttons (void *data,
|
||||
struct wl_array *buttons)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
uint32_t *p;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad group handle buttons, pad group = %p, n_buttons = %" G_GSIZE_FORMAT,
|
||||
wp_tablet_pad_group, buttons->size));
|
||||
|
||||
@@ -4023,10 +4009,8 @@ tablet_pad_group_handle_ring (void *data,
|
||||
struct zwp_tablet_pad_ring_v2 *wp_tablet_pad_ring)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad group handle ring, pad group = %p, ring = %p",
|
||||
wp_tablet_pad_group, wp_tablet_pad_ring));
|
||||
|
||||
@@ -4044,10 +4028,8 @@ tablet_pad_group_handle_strip (void *data,
|
||||
struct zwp_tablet_pad_strip_v2 *wp_tablet_pad_strip)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad group handle strip, pad group = %p, strip = %p",
|
||||
wp_tablet_pad_group, wp_tablet_pad_strip));
|
||||
|
||||
@@ -4065,10 +4047,8 @@ tablet_pad_group_handle_modes (void *data,
|
||||
uint32_t modes)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad group handle modes, pad group = %p, n_modes = %d",
|
||||
wp_tablet_pad_group, modes));
|
||||
|
||||
@@ -4079,11 +4059,11 @@ static void
|
||||
tablet_pad_group_handle_done (void *data,
|
||||
struct zwp_tablet_pad_group_v2 *wp_tablet_pad_group)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
GdkWaylandTabletPadData *pad = group->pad;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
#endif
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (group->pad->seat, EVENTS,
|
||||
g_message ("tablet pad group handle done, pad group = %p",
|
||||
wp_tablet_pad_group));
|
||||
}
|
||||
@@ -4101,7 +4081,7 @@ tablet_pad_group_handle_mode (void *data,
|
||||
GdkEvent *event;
|
||||
guint n_group;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("tablet pad group handle mode, pad group = %p, mode = %d",
|
||||
wp_tablet_pad_group, mode));
|
||||
|
||||
@@ -4137,9 +4117,8 @@ tablet_pad_handle_group (void *data,
|
||||
{
|
||||
GdkWaylandTabletPadData *pad = data;
|
||||
GdkWaylandTabletPadGroupData *group;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (pad->seat, EVENTS,
|
||||
g_message ("tablet pad handle group, pad group = %p, group = %p",
|
||||
wp_tablet_pad_group, wp_tablet_pad_group));
|
||||
|
||||
@@ -4159,9 +4138,8 @@ tablet_pad_handle_path (void *data,
|
||||
const char *path)
|
||||
{
|
||||
GdkWaylandTabletPadData *pad = data;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (pad->seat, EVENTS,
|
||||
g_message ("tablet pad handle path, pad = %p, path = %s",
|
||||
wp_tablet_pad, path));
|
||||
|
||||
@@ -4174,9 +4152,8 @@ tablet_pad_handle_buttons (void *data,
|
||||
uint32_t buttons)
|
||||
{
|
||||
GdkWaylandTabletPadData *pad = data;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (pad->seat, EVENTS,
|
||||
g_message ("tablet pad handle buttons, pad = %p, n_buttons = %d",
|
||||
wp_tablet_pad, buttons));
|
||||
|
||||
@@ -4188,9 +4165,8 @@ tablet_pad_handle_done (void *data,
|
||||
struct zwp_tablet_pad_v2 *wp_tablet_pad)
|
||||
{
|
||||
GdkWaylandTabletPadData *pad = data;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (pad->seat, EVENTS,
|
||||
g_message ("tablet pad handle done, pad = %p", wp_tablet_pad));
|
||||
|
||||
pad->device =
|
||||
@@ -4200,11 +4176,11 @@ tablet_pad_handle_done (void *data,
|
||||
"input-source", GDK_SOURCE_TABLET_PAD,
|
||||
"input-mode", GDK_MODE_SCREEN,
|
||||
"display", gdk_seat_get_display (pad->seat),
|
||||
"seat", seat,
|
||||
"seat", pad->seat,
|
||||
NULL);
|
||||
|
||||
_gdk_device_set_associated_device (pad->device, seat->master_keyboard);
|
||||
gdk_seat_device_added (GDK_SEAT (seat), pad->device);
|
||||
_gdk_device_set_associated_device (pad->device, GDK_WAYLAND_SEAT (pad->seat)->master_keyboard);
|
||||
gdk_seat_device_added (GDK_SEAT (pad->seat), pad->device);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4216,11 +4192,10 @@ tablet_pad_handle_button (void *data,
|
||||
{
|
||||
GdkWaylandTabletPadData *pad = data;
|
||||
GdkWaylandTabletPadGroupData *group;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
GdkEvent *event;
|
||||
gint n_group;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (pad->seat, EVENTS,
|
||||
g_message ("tablet pad handle button, pad = %p, button = %d, state = %d",
|
||||
wp_tablet_pad, button, state));
|
||||
|
||||
@@ -4230,7 +4205,7 @@ tablet_pad_handle_button (void *data,
|
||||
event = gdk_event_new (state == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED ?
|
||||
GDK_PAD_BUTTON_PRESS :
|
||||
GDK_PAD_BUTTON_RELEASE);
|
||||
g_set_object (&event->any.surface, seat->keyboard_focus);
|
||||
g_set_object (&event->any.surface, GDK_WAYLAND_SEAT (pad->seat)->keyboard_focus);
|
||||
event->pad_button.button = button;
|
||||
event->pad_button.group = n_group;
|
||||
event->pad_button.mode = group->current_mode;
|
||||
@@ -4238,8 +4213,7 @@ tablet_pad_handle_button (void *data,
|
||||
gdk_event_set_device (event, pad->device);
|
||||
gdk_event_set_source_device (event, pad->device);
|
||||
|
||||
_gdk_wayland_display_deliver_event (gdk_seat_get_display (pad->seat),
|
||||
event);
|
||||
_gdk_wayland_display_deliver_event (gdk_seat_get_display (pad->seat), event);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4250,10 +4224,9 @@ tablet_pad_handle_enter (void *data,
|
||||
struct wl_surface *surface)
|
||||
{
|
||||
GdkWaylandTabletPadData *pad = data;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
GdkWaylandTabletData *tablet = zwp_tablet_v2_get_user_data (wp_tablet);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (pad->seat, EVENTS,
|
||||
g_message ("tablet pad handle enter, pad = %p, tablet = %p surface = %p",
|
||||
wp_tablet_pad, wp_tablet, surface));
|
||||
|
||||
@@ -4269,9 +4242,8 @@ tablet_pad_handle_leave (void *data,
|
||||
struct wl_surface *surface)
|
||||
{
|
||||
GdkWaylandTabletPadData *pad = data;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (pad->seat, EVENTS,
|
||||
g_message ("tablet pad handle leave, pad = %p, surface = %p",
|
||||
wp_tablet_pad, surface));
|
||||
|
||||
@@ -4287,9 +4259,8 @@ tablet_pad_handle_removed (void *data,
|
||||
struct zwp_tablet_pad_v2 *wp_tablet_pad)
|
||||
{
|
||||
GdkWaylandTabletPadData *pad = data;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (pad->seat);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (pad->seat, EVENTS,
|
||||
g_message ("tablet pad handle removed, pad = %p", wp_tablet_pad));
|
||||
|
||||
/* Remove from the current tablet */
|
||||
@@ -4461,7 +4432,7 @@ pointer_surface_enter (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
|
||||
GdkWaylandTabletData *tablet;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("pointer surface of seat %p entered output %p",
|
||||
seat, output));
|
||||
|
||||
@@ -4490,7 +4461,7 @@ pointer_surface_leave (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
|
||||
GdkWaylandTabletData *tablet;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("pointer surface of seat %p left output %p",
|
||||
seat, output));
|
||||
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#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>
|
||||
@@ -725,7 +726,6 @@ 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,13 +733,10 @@ gdk_wayland_display_finalize (GObject *object)
|
||||
g_free (display_wayland->cursor_theme_name);
|
||||
xkb_context_unref (display_wayland->xkb_context);
|
||||
|
||||
for (i = 0; i < GDK_WAYLAND_THEME_SCALES_COUNT; i++)
|
||||
if (display_wayland->cursor_theme)
|
||||
{
|
||||
if (display_wayland->scaled_cursor_themes[i])
|
||||
{
|
||||
wl_cursor_theme_destroy (display_wayland->scaled_cursor_themes[i]);
|
||||
display_wayland->scaled_cursor_themes[i] = NULL;
|
||||
}
|
||||
wl_cursor_theme_destroy (display_wayland->cursor_theme);
|
||||
display_wayland->cursor_theme = NULL;
|
||||
}
|
||||
|
||||
g_ptr_array_free (display_wayland->monitors, TRUE);
|
||||
@@ -1059,6 +1056,33 @@ 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,
|
||||
@@ -1066,7 +1090,6 @@ 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);
|
||||
@@ -1075,22 +1098,20 @@ gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
|
||||
display_wayland->cursor_theme_size == size)
|
||||
return;
|
||||
|
||||
theme = wl_cursor_theme_load (name, size, display_wayland->shm);
|
||||
theme = get_cursor_theme (display_wayland, name, size);
|
||||
|
||||
if (theme == NULL)
|
||||
{
|
||||
g_warning ("Failed to load cursor theme %s", name);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < GDK_WAYLAND_THEME_SCALES_COUNT; i++)
|
||||
if (display_wayland->cursor_theme)
|
||||
{
|
||||
if (display_wayland->scaled_cursor_themes[i])
|
||||
{
|
||||
wl_cursor_theme_destroy (display_wayland->scaled_cursor_themes[i]);
|
||||
display_wayland->scaled_cursor_themes[i] = NULL;
|
||||
}
|
||||
wl_cursor_theme_destroy (display_wayland->cursor_theme);
|
||||
display_wayland->cursor_theme = NULL;
|
||||
}
|
||||
display_wayland->scaled_cursor_themes[0] = theme;
|
||||
display_wayland->cursor_theme = theme;
|
||||
if (display_wayland->cursor_theme_name != NULL)
|
||||
g_free (display_wayland->cursor_theme_name);
|
||||
display_wayland->cursor_theme_name = g_strdup (name);
|
||||
@@ -1098,31 +1119,11 @@ gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
|
||||
}
|
||||
|
||||
struct wl_cursor_theme *
|
||||
_gdk_wayland_display_get_scaled_cursor_theme (GdkWaylandDisplay *display_wayland,
|
||||
guint scale)
|
||||
_gdk_wayland_display_get_cursor_theme (GdkWaylandDisplay *display_wayland)
|
||||
{
|
||||
struct wl_cursor_theme *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;
|
||||
return display_wayland->cursor_theme;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1131,6 +1132,7 @@ _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);
|
||||
@@ -1150,6 +1152,12 @@ _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
|
||||
@@ -2307,10 +2315,11 @@ xdg_output_handle_description (void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
const char *description)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle description xdg-output %d", monitor->id));
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
g_message ("handle description xdg-output %d", monitor->id);
|
||||
});
|
||||
}
|
||||
|
||||
static const struct zxdg_output_v1_listener xdg_output_listener = {
|
||||
|
@@ -26,7 +26,6 @@
|
||||
|
||||
#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>
|
||||
@@ -45,6 +44,7 @@
|
||||
|
||||
#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 *scaled_cursor_themes[GDK_WAYLAND_THEME_SCALES_COUNT];
|
||||
struct wl_cursor_theme *cursor_theme;
|
||||
gchar *cursor_theme_name;
|
||||
int cursor_theme_size;
|
||||
GHashTable *cursor_surface_cache;
|
||||
|
@@ -181,19 +181,17 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
GdkDisplay *display;
|
||||
GInputStream *stream;
|
||||
const char *mime_type;
|
||||
int pipe_fd[2];
|
||||
GError *error = NULL;
|
||||
GTask *task;
|
||||
|
||||
display = gdk_drop_get_display (drop),
|
||||
task = g_task_new (drop, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_wayland_drop_read_async);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, DND, char *s = gdk_content_formats_to_string (formats);
|
||||
GDK_DISPLAY_NOTE (gdk_drop_get_display (drop), DND, char *s = gdk_content_formats_to_string (formats);
|
||||
g_message ("%p: read for %s", drop, s);
|
||||
g_free (s); );
|
||||
mime_type = gdk_content_formats_match_mime_type (formats,
|
||||
|
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
|
||||
#include "gdkintl.h"
|
||||
|
||||
@@ -238,6 +239,7 @@ 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,8 +57,7 @@ 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_scaled_cursor_theme (GdkWaylandDisplay *display_wayland,
|
||||
guint scale);
|
||||
struct wl_cursor_theme * _gdk_wayland_display_get_cursor_theme (GdkWaylandDisplay *display_wayland);
|
||||
|
||||
void _gdk_wayland_display_get_default_cursor_size (GdkDisplay *display,
|
||||
guint *width,
|
||||
|
@@ -357,6 +357,7 @@ 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);
|
||||
@@ -395,10 +396,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 = {
|
||||
@@ -477,6 +478,7 @@ 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;
|
||||
@@ -1508,6 +1510,7 @@ 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);
|
||||
}
|
||||
|
||||
@@ -2302,6 +2305,7 @@ 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,3 +1,5 @@
|
||||
subdir('cursor')
|
||||
|
||||
gdk_wayland_sources = files([
|
||||
'gdkapplaunchcontext-wayland.c',
|
||||
'gdkcairocontext-wayland.c',
|
||||
@@ -33,7 +35,6 @@ gdk_wayland_deps = [
|
||||
xkbdep,
|
||||
wlclientdep,
|
||||
wlprotocolsdep,
|
||||
wlcursordep,
|
||||
wlegldep,
|
||||
]
|
||||
|
||||
@@ -105,4 +106,5 @@ libgdk_wayland = static_library('gdk-wayland',
|
||||
'-DG_LOG_DOMAIN="Gdk"',
|
||||
] + common_cflags,
|
||||
link_args: common_ldflags,
|
||||
dependencies: [ gdk_deps, gdk_wayland_deps, ])
|
||||
link_with: [libwayland_cursor, ],
|
||||
dependencies: [ gdk_deps, gdk_wayland_deps])
|
||||
|
@@ -65,16 +65,15 @@ print_atoms (GdkX11Clipboard *cb,
|
||||
const Atom *atoms,
|
||||
gsize n_atoms)
|
||||
{
|
||||
GdkDisplay *display = gdk_clipboard_get_display (GDK_CLIPBOARD (cb));
|
||||
|
||||
GDK_DISPLAY_NOTE (display, CLIPBOARD,
|
||||
GDK_DISPLAY_NOTE (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD, {
|
||||
gsize i;
|
||||
GdkDisplay *display = gdk_clipboard_get_display (GDK_CLIPBOARD (cb));
|
||||
|
||||
g_printerr ("%s: %s [ ", cb->selection, prefix);
|
||||
for (i = 0; i < n_atoms; i++)
|
||||
g_printerr ("%s%s", i > 0 ? ", " : "", gdk_x11_get_xatom_name_for_display (display , atoms[i]));
|
||||
g_printerr (" ]\n");
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -86,9 +85,7 @@ gdk_x11_clipboard_default_output_done (GObject *clipboard,
|
||||
|
||||
if (!gdk_clipboard_write_finish (GDK_CLIPBOARD (clipboard), result, &error))
|
||||
{
|
||||
GdkDisplay *display = gdk_clipboard_get_display (GDK_CLIPBOARD (clipboard));
|
||||
|
||||
GDK_DISPLAY_NOTE (display, CLIPBOARD,
|
||||
GDK_DISPLAY_NOTE (gdk_clipboard_get_display (GDK_CLIPBOARD (clipboard)), CLIPBOARD,
|
||||
g_printerr ("%s: failed to write stream: %s\n",
|
||||
GDK_X11_CLIPBOARD (clipboard)->selection, error->message));
|
||||
g_error_free (error);
|
||||
@@ -440,16 +437,20 @@ gdk_x11_clipboard_xevent (GdkDisplay *display,
|
||||
|
||||
case SelectionRequest:
|
||||
{
|
||||
const char *target, *property;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
const char *target, *property;
|
||||
#endif
|
||||
|
||||
if (xevent->xselectionrequest.selection != cb->xselection)
|
||||
return FALSE;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
target = gdk_x11_get_xatom_name_for_display (display, xevent->xselectionrequest.target);
|
||||
if (xevent->xselectionrequest.property == None)
|
||||
property = target;
|
||||
else
|
||||
property = gdk_x11_get_xatom_name_for_display (display, xevent->xselectionrequest.property);
|
||||
#endif
|
||||
|
||||
if (!gdk_clipboard_is_local (GDK_CLIPBOARD (cb)))
|
||||
{
|
||||
|
@@ -1749,16 +1749,20 @@ gdk_x11_drag_xevent (GdkDisplay *display,
|
||||
|
||||
case SelectionRequest:
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
const char *target, *property;
|
||||
#endif
|
||||
|
||||
if (xevent->xselectionrequest.selection != xselection)
|
||||
return FALSE;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
target = gdk_x11_get_xatom_name_for_display (display, xevent->xselectionrequest.target);
|
||||
if (xevent->xselectionrequest.property == None)
|
||||
property = target;
|
||||
else
|
||||
property = gdk_x11_get_xatom_name_for_display (display, xevent->xselectionrequest.property);
|
||||
#endif
|
||||
|
||||
if (xevent->xselectionrequest.requestor == None)
|
||||
{
|
||||
|
@@ -145,9 +145,9 @@ gdk_x11_drop_read_got_stream (GObject *source,
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *mime_type = ((GSList *) g_task_get_task_data (task))->data;
|
||||
#if 0
|
||||
gsize i;
|
||||
const char *mime_type = ((GSList *) g_task_get_task_data (task))->data;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (special_targets); i++)
|
||||
{
|
||||
@@ -166,7 +166,7 @@ gdk_x11_drop_read_got_stream (GObject *source,
|
||||
#endif
|
||||
|
||||
GDK_NOTE (DND, g_printerr ("reading DND as %s now\n",
|
||||
mime_type));
|
||||
(const char *)((GSList *) g_task_get_task_data (task))->data));
|
||||
g_task_return_pointer (task, stream, g_object_unref);
|
||||
}
|
||||
|
||||
@@ -732,14 +732,14 @@ gdk_x11_drop_do_nothing (Window window,
|
||||
gboolean success,
|
||||
gpointer data)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GdkDisplay *display = data;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
GDK_DISPLAY_NOTE (display, DND,
|
||||
g_message ("Send event to %lx failed",
|
||||
window));
|
||||
GDK_DISPLAY_NOTE (display, DND, g_message ("Send event to %lx failed", window));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -196,7 +196,7 @@ dump_node (GskRenderNode *node,
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
static inline gboolean G_GNUC_PURE
|
||||
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
|
||||
static inline gboolean G_GNUC_PURE
|
||||
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
|
||||
static inline gboolean G_GNUC_PURE
|
||||
node_supports_transform (GskRenderNode *node)
|
||||
{
|
||||
/* Some nodes can't handle non-trivial transforms without being
|
||||
@@ -535,17 +535,16 @@ transform_rect (GskGLRenderer *self,
|
||||
RenderOpBuilder *builder,
|
||||
const GskRoundedRect *rect)
|
||||
{
|
||||
const float scale = ops_get_scale (builder);
|
||||
GskRoundedRect r;
|
||||
int i;
|
||||
|
||||
ops_transform_bounds_modelview (builder, &rect->bounds, &r.bounds);
|
||||
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;
|
||||
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
r.corner[i].width = rect->corner[i].width * scale;
|
||||
r.corner[i].height = rect->corner[i].height * scale;
|
||||
}
|
||||
r.corner[0] = rect->corner[0];
|
||||
r.corner[1] = rect->corner[1];
|
||||
r.corner[2] = rect->corner[2];
|
||||
r.corner[3] = rect->corner[3];
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -612,7 +611,7 @@ render_fallback_node (GskGLRenderer *self,
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
|
||||
#if G_ENABLE_DEBUG
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
||||
{
|
||||
cairo_move_to (cr, 0, 0);
|
||||
@@ -745,25 +744,35 @@ 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 *og_widths = gsk_border_node_peek_widths (node);
|
||||
GskRoundedRect outline;
|
||||
float widths[4];
|
||||
const float *widths = gsk_border_node_peek_widths (node);
|
||||
int i;
|
||||
struct {
|
||||
float w;
|
||||
float h;
|
||||
} sizes[4];
|
||||
|
||||
if (widths[0] == widths[1] &&
|
||||
widths[0] == widths[2] &&
|
||||
widths[0] == widths[3] &&
|
||||
gdk_rgba_equal (&colors[0], &colors[1]) &&
|
||||
gdk_rgba_equal (&colors[0], &colors[2]) &&
|
||||
gdk_rgba_equal (&colors[0], &colors[3]))
|
||||
{
|
||||
OpShadow *op;
|
||||
|
||||
for (i = 0; i < 4; i ++)
|
||||
widths[i] = og_widths[i];
|
||||
ops_set_program (builder, &self->inset_shadow_program);
|
||||
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->offset[0] = 0;
|
||||
op->offset[1] = 0;
|
||||
|
||||
load_vertex_data (ops_draw (builder, NULL), node, builder);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Top left */
|
||||
if (widths[3] > 0)
|
||||
@@ -810,10 +819,11 @@ 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 */
|
||||
{
|
||||
@@ -857,6 +867,7 @@ render_border_node (GskGLRenderer *self,
|
||||
}
|
||||
};
|
||||
int indices[4] = { 0, 1, 2, 3 };
|
||||
GskRoundedRect outline;
|
||||
|
||||
/* We sort them by color */
|
||||
sort_border_sides (colors, indices);
|
||||
@@ -1169,17 +1180,16 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
RenderOpBuilder *builder)
|
||||
{
|
||||
const float scale = ops_get_scale (builder);
|
||||
GskRoundedRect child_clip = *gsk_rounded_clip_node_peek_clip (node);
|
||||
GskRoundedRect transformed_clip;
|
||||
const GskRoundedRect *clip = gsk_rounded_clip_node_peek_clip (node);
|
||||
GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
|
||||
GskRoundedRect transformed_clip;
|
||||
gboolean need_offscreen;
|
||||
int i;
|
||||
|
||||
if (node_is_invisible (child))
|
||||
return;
|
||||
|
||||
transformed_clip = child_clip;
|
||||
ops_transform_bounds_modelview (builder, &child_clip.bounds, &transformed_clip.bounds);
|
||||
ops_transform_bounds_modelview (builder, &clip->bounds, &transformed_clip.bounds);
|
||||
|
||||
if (!ops_has_clip (builder))
|
||||
need_offscreen = FALSE;
|
||||
@@ -1195,8 +1205,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 *= scale;
|
||||
transformed_clip.corner[i].height *= scale;
|
||||
transformed_clip.corner[i].width = clip->corner[i].width * scale;
|
||||
transformed_clip.corner[i].height = clip->corner[i].height * scale;
|
||||
}
|
||||
|
||||
ops_push_clip (builder, &transformed_clip);
|
||||
@@ -1205,7 +1215,7 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
graphene_matrix_t scale_matrix;
|
||||
GskRoundedRect scaled_clip;
|
||||
gboolean is_offscreen;
|
||||
TextureRegion region;
|
||||
/* NOTE: We are *not* transforming the clip by the current modelview here.
|
||||
@@ -1214,18 +1224,19 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
*
|
||||
* We do, however, apply the scale factor to the child clip of course.
|
||||
*/
|
||||
|
||||
graphene_matrix_init_scale (&scale_matrix, scale, scale, 1.0f);
|
||||
graphene_matrix_transform_bounds (&scale_matrix, &child_clip.bounds, &child_clip.bounds);
|
||||
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;
|
||||
|
||||
/* Increase corner radius size by scale factor */
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
child_clip.corner[i].width *= scale;
|
||||
child_clip.corner[i].height *= scale;
|
||||
scaled_clip.corner[i].width = clip->corner[i].width * scale;
|
||||
scaled_clip.corner[i].height = clip->corner[i].height * scale;
|
||||
}
|
||||
|
||||
ops_push_clip (builder, &child_clip);
|
||||
ops_push_clip (builder, &scaled_clip);
|
||||
if (!add_offscreen_ops (self, builder, &node->bounds,
|
||||
child,
|
||||
®ion, &is_offscreen,
|
||||
@@ -1435,6 +1446,9 @@ 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);
|
||||
@@ -1461,7 +1475,6 @@ 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);
|
||||
@@ -1474,9 +1487,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 * scale;
|
||||
op->offset[0] = dx * scale;
|
||||
op->offset[1] = dy * scale;
|
||||
op->spread = spread;
|
||||
op->offset[0] = dx;
|
||||
op->offset[1] = dy;
|
||||
|
||||
load_vertex_data (ops_draw (builder, NULL), node, builder);
|
||||
}
|
||||
@@ -1627,7 +1640,6 @@ 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);
|
||||
@@ -1638,13 +1650,14 @@ 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 * scale;
|
||||
op->offset[0] = dx * scale;
|
||||
op->offset[1] = dy * scale;
|
||||
op->spread = spread;
|
||||
op->offset[0] = dx;
|
||||
op->offset[1] = dy;
|
||||
|
||||
load_vertex_data (ops_draw (builder, NULL), node, builder);
|
||||
}
|
||||
|
||||
static GdkRGBA COLOR_WHITE = { 1, 1, 1, 1 };
|
||||
static inline void
|
||||
render_outset_shadow_node (GskGLRenderer *self,
|
||||
GskRenderNode *node,
|
||||
@@ -1652,6 +1665,7 @@ render_outset_shadow_node (GskGLRenderer *self,
|
||||
{
|
||||
const float scale = ops_get_scale (builder);
|
||||
const GskRoundedRect *outline = gsk_outset_shadow_node_peek_outline (node);
|
||||
const GdkRGBA *color = gsk_outset_shadow_node_peek_color (node);
|
||||
const float blur_radius = gsk_outset_shadow_node_get_blur_radius (node);
|
||||
const float blur_extra = blur_radius * 3; /* 3 Because we use that in the shader as well */
|
||||
const float spread = gsk_outset_shadow_node_get_spread (node);
|
||||
@@ -1727,7 +1741,7 @@ render_outset_shadow_node (GskGLRenderer *self,
|
||||
/* Draw outline */
|
||||
ops_set_program (builder, &self->color_program);
|
||||
ops_push_clip (builder, &scaled_outline);
|
||||
ops_set_color (builder, gsk_outset_shadow_node_peek_color (node));
|
||||
ops_set_color (builder, &COLOR_WHITE);
|
||||
ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
|
||||
{ { 0, }, { 0, 1 }, },
|
||||
{ { 0, texture_height }, { 0, 0 }, },
|
||||
@@ -1763,6 +1777,7 @@ render_outset_shadow_node (GskGLRenderer *self,
|
||||
}
|
||||
|
||||
ops_set_program (builder, &self->outset_shadow_program);
|
||||
ops_set_color (builder, color);
|
||||
ops_set_texture (builder, blurred_texture_id);
|
||||
|
||||
shadow = ops_begin (builder, OP_CHANGE_OUTSET_SHADOW);
|
||||
@@ -2140,14 +2155,24 @@ render_cross_fade_node (GskGLRenderer *self,
|
||||
start_node,
|
||||
&start_region, &is_offscreen1,
|
||||
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY))
|
||||
g_assert_not_reached ();
|
||||
{
|
||||
gsk_gl_renderer_add_render_ops (self, end_node, builder);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!add_offscreen_ops (self, builder,
|
||||
&node->bounds,
|
||||
end_node,
|
||||
&end_region, &is_offscreen2,
|
||||
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY))
|
||||
g_assert_not_reached ();
|
||||
{
|
||||
load_vertex_data_with_region (ops_draw (builder, NULL),
|
||||
node,
|
||||
builder,
|
||||
&start_region,
|
||||
TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
ops_set_program (builder, &self->cross_fade_program);
|
||||
|
||||
@@ -2553,6 +2578,7 @@ 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");
|
||||
|
||||
@@ -2637,6 +2663,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, outline_rect);
|
||||
|
||||
/* outset shadow */
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (outset_shadow, color);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (outset_shadow, outline_rect);
|
||||
|
||||
/* unblurred outset shadow */
|
||||
@@ -2746,6 +2773,7 @@ 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.
|
||||
@@ -2775,6 +2803,9 @@ 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;
|
||||
}
|
||||
|
||||
@@ -3461,7 +3492,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, "render", "");
|
||||
gdk_profiler_add_mark (start_time, cpu_time, "GL 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
|
||||
static inline gboolean G_GNUC_PURE
|
||||
rounded_rect_equal (const GskRoundedRect *r1,
|
||||
const GskRoundedRect *r2)
|
||||
{
|
||||
@@ -31,7 +31,7 @@ rounded_rect_equal (const GskRoundedRect *r1,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
static inline gboolean G_GNUC_PURE
|
||||
rounded_rect_corners_equal (const GskRoundedRect *r1,
|
||||
const GskRoundedRect *r2)
|
||||
{
|
||||
@@ -180,13 +180,15 @@ 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);
|
||||
|
||||
gsk_transform_transform_bounds (builder->current_modelview, src, dst);
|
||||
r.origin.x += builder->dx;
|
||||
r.origin.y += builder->dy;
|
||||
|
||||
dst->origin.x += builder->dx * builder->scale_x;
|
||||
dst->origin.y += builder->dy * builder->scale_y;
|
||||
gsk_transform_transform_bounds (builder->current_modelview, &r, dst);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -73,6 +73,7 @@ struct _Program
|
||||
int outline_rect_location;
|
||||
} inset_shadow;
|
||||
struct {
|
||||
int color_location;
|
||||
int outline_rect_location;
|
||||
} outset_shadow;
|
||||
struct {
|
||||
|
@@ -9,14 +9,17 @@
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -24,6 +27,7 @@ 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);
|
||||
}
|
||||
@@ -102,13 +106,14 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
"#version %d\n", self->version);
|
||||
|
||||
vertex_id = glCreateShader (GL_VERTEX_SHADER);
|
||||
glShaderSource (vertex_id, 7,
|
||||
glShaderSource (vertex_id, 8,
|
||||
(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
|
||||
},
|
||||
@@ -119,6 +124,7 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
fragment_shader_start - vertex_shader_start
|
||||
});
|
||||
glCompileShader (vertex_id);
|
||||
@@ -130,13 +136,14 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
}
|
||||
|
||||
fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
|
||||
glShaderSource (fragment_id, 7,
|
||||
glShaderSource (fragment_id, 8,
|
||||
(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
|
||||
},
|
||||
@@ -148,6 +155,7 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
});
|
||||
glCompileShader (fragment_id);
|
||||
|
||||
|
@@ -8,6 +8,7 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GBytes *preamble;
|
||||
GBytes *vs_preamble;
|
||||
GBytes *fs_preamble;
|
||||
|
||||
@@ -22,6 +23,7 @@ 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);
|
||||
|
@@ -25,12 +25,12 @@ key_equal (const void *x,
|
||||
const CacheKey *a = x;
|
||||
const CacheKey *b = y;
|
||||
|
||||
return graphene_size_equal (&a->outline.corner[0], &b->outline.corner[0]) &&
|
||||
return a->blur_radius == b->blur_radius &&
|
||||
graphene_size_equal (&a->outline.corner[0], &b->outline.corner[0]) &&
|
||||
graphene_size_equal (&a->outline.corner[1], &b->outline.corner[1]) &&
|
||||
graphene_size_equal (&a->outline.corner[2], &b->outline.corner[2]) &&
|
||||
graphene_size_equal (&a->outline.corner[3], &b->outline.corner[3]) &&
|
||||
graphene_rect_equal (&a->outline.bounds, &b->outline.bounds) &&
|
||||
a->blur_radius == b->blur_radius;
|
||||
graphene_rect_equal (&a->outline.bounds, &b->outline.bounds);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -145,9 +145,9 @@ gsk_render_node_get_node_type (GskRenderNode *node)
|
||||
return node->node_class->node_type;
|
||||
}
|
||||
|
||||
static inline
|
||||
G_GNUC_PURE static inline
|
||||
GskRenderNodeType
|
||||
_gsk_render_node_get_node_type (GskRenderNode *node)
|
||||
_gsk_render_node_get_node_type (const 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 (GskRenderNode *node1,
|
||||
GskRenderNode *node2)
|
||||
gsk_render_node_can_diff (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2)
|
||||
{
|
||||
if (node1 == node2)
|
||||
return TRUE;
|
||||
@@ -314,9 +314,6 @@ 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 (GskRenderNode *node1,
|
||||
GskRenderNode *node2)
|
||||
gsk_render_node_can_diff_true (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1707,8 +1707,8 @@ gsk_container_node_draw (GskRenderNode *node,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_container_node_can_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2)
|
||||
gsk_container_node_can_diff (const GskRenderNode *node1,
|
||||
const 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 ((GskRenderNode *) elem1, (GskRenderNode *) elem2) ? 0 : 1;
|
||||
return gsk_render_node_can_diff ((const GskRenderNode *) elem1, (const GskRenderNode *) elem2) ? 0 : 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1918,8 +1918,8 @@ gsk_transform_node_draw (GskRenderNode *node,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_transform_node_can_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2)
|
||||
gsk_transform_node_can_diff (const GskRenderNode *node1,
|
||||
const 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 (GskRenderNode *node1,
|
||||
GskRenderNode *node2)
|
||||
gsk_debug_node_can_diff (const GskRenderNode *node1,
|
||||
const 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) (GskRenderNode *node1,
|
||||
GskRenderNode *node2);
|
||||
gboolean (* can_diff) (const GskRenderNode *node1,
|
||||
const 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 (GskRenderNode *node1,
|
||||
GskRenderNode *node2);
|
||||
gboolean gsk_render_node_can_diff (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2) G_GNUC_PURE;
|
||||
void gsk_render_node_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
|
@@ -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);
|
||||
gboolean gsk_rounded_rect_is_rectilinear (const GskRoundedRect *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_rounded_rect_contains_point (const GskRoundedRect *self,
|
||||
const graphene_point_t *point);
|
||||
const graphene_point_t *point) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_rounded_rect_contains_rect (const GskRoundedRect *self,
|
||||
const graphene_rect_t *rect);
|
||||
const graphene_rect_t *rect) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_rounded_rect_intersects_rect (const GskRoundedRect *self,
|
||||
const graphene_rect_t *rect);
|
||||
const graphene_rect_t *rect) G_GNUC_PURE;
|
||||
|
||||
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);
|
||||
gconstpointer rect2) G_GNUC_PURE;
|
||||
char * gsk_rounded_rect_to_string (const GskRoundedRect *self);
|
||||
|
||||
|
||||
|
@@ -1773,6 +1773,62 @@ 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,6 +116,11 @@ 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,4 +1,5 @@
|
||||
gsk_private_gl_shaders = [
|
||||
'resources/glsl/preamble.glsl',
|
||||
'resources/glsl/preamble.fs.glsl',
|
||||
'resources/glsl/preamble.vs.glsl',
|
||||
'resources/glsl/border.glsl',
|
||||
|
@@ -1,7 +1,11 @@
|
||||
// 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);
|
||||
@@ -9,25 +13,32 @@ 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;
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
@@ -1,7 +1,12 @@
|
||||
// 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);
|
||||
@@ -9,26 +14,33 @@ 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;
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
@@ -1,12 +1,28 @@
|
||||
// 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);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
|
||||
final_color = u_color;
|
||||
// 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;
|
||||
@@ -14,8 +30,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);
|
||||
vec4 color = Texture(u_source, vUv);
|
||||
color = color * (1.0 - clamp(rounded_rect_coverage(outline, f.xy), 0.0, 1.0));
|
||||
setOutputColor(color * u_alpha);
|
||||
float alpha = Texture(u_source, vUv).a;
|
||||
alpha *= (1.0 - clamp(rounded_rect_coverage(decode_rect(transformed_outline), f.xy), 0.0, 1.0));
|
||||
|
||||
vec4 color = final_color * alpha;
|
||||
|
||||
setOutputColor(color);
|
||||
}
|
||||
|
@@ -1,12 +1,3 @@
|
||||
#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;
|
||||
@@ -15,36 +6,23 @@ 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;
|
||||
|
||||
|
||||
|
||||
struct RoundedRect
|
||||
RoundedRect decode_rect(_ROUNDED_RECT_UNIFORM_ r)
|
||||
{
|
||||
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);
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
return RoundedRect(r[0], r[1], r[2]);
|
||||
#else
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
float
|
||||
@@ -73,15 +51,15 @@ rounded_rect_coverage (RoundedRect r, vec2 p)
|
||||
p.x >= r.bounds.z || p.y >= r.bounds.w)
|
||||
return 0.0;
|
||||
|
||||
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 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 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);
|
||||
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;
|
||||
|
||||
float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
|
||||
float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
|
||||
@@ -98,37 +76,8 @@ 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 GSK_GLES
|
||||
return texture2D(sampler, texCoords);
|
||||
#elif GSK_LEGACY
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
return texture2D(sampler, texCoords);
|
||||
#else
|
||||
return texture(sampler, texCoords);
|
||||
@@ -141,9 +90,10 @@ void setOutputColor(vec4 color) {
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
#if GSK_GLES
|
||||
gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
|
||||
#elif GSK_LEGACY
|
||||
|
||||
// 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)
|
||||
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);
|
||||
|
37
gsk/resources/glsl/preamble.glsl
Normal file
37
gsk/resources/glsl/preamble.glsl
Normal file
@@ -0,0 +1,37 @@
|
||||
#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,26 +2,68 @@ uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
uniform float u_alpha;
|
||||
|
||||
#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
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
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,7 +1,12 @@
|
||||
// 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);
|
||||
@@ -9,26 +14,33 @@ 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;
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
@@ -261,14 +261,14 @@ gtk_css_parser_get_end_location (GtkCssParser *self)
|
||||
const GtkCssLocation *
|
||||
gtk_css_parser_get_block_location (GtkCssParser *self)
|
||||
{
|
||||
GtkCssParserBlock *block;
|
||||
const 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)
|
||||
{
|
||||
GtkCssParserBlock *block = &g_array_index (self->blocks, GtkCssParserBlock, self->blocks->len - 1);
|
||||
const 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);
|
||||
gboolean gtk_css_token_is_finite (const GtkCssToken *token) G_GNUC_PURE;
|
||||
gboolean gtk_css_token_is_preserved (const GtkCssToken *token,
|
||||
GtkCssTokenType *out_closing);
|
||||
GtkCssTokenType *out_closing) G_GNUC_PURE;
|
||||
#define gtk_css_token_is(token, _type) ((token)->type == (_type))
|
||||
gboolean gtk_css_token_is_ident (const GtkCssToken *token,
|
||||
const char *ident);
|
||||
const char *ident) G_GNUC_PURE;
|
||||
gboolean gtk_css_token_is_function (const GtkCssToken *token,
|
||||
const char *ident);
|
||||
const char *ident) G_GNUC_PURE;
|
||||
gboolean gtk_css_token_is_delim (const GtkCssToken *token,
|
||||
gunichar delim);
|
||||
gunichar delim) G_GNUC_PURE;
|
||||
|
||||
void gtk_css_token_print (const GtkCssToken *token,
|
||||
GString *string);
|
||||
|
@@ -17,6 +17,7 @@ def get_files(subdir,extension):
|
||||
return sorted(filter(lambda x: x.endswith((extension)), os.listdir(os.path.join(srcdir,subdir))))
|
||||
|
||||
xml += '''
|
||||
<file>theme/Empty/gtk.css</file>
|
||||
<file>theme/Adwaita/gtk.css</file>
|
||||
<file>theme/Adwaita/gtk-dark.css</file>
|
||||
<file>theme/Adwaita/gtk-contained.css</file>
|
||||
|
@@ -23,9 +23,11 @@
|
||||
#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>
|
||||
|
||||
@@ -307,7 +309,6 @@ 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;
|
||||
@@ -320,8 +321,6 @@ 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
|
||||
@@ -332,22 +331,21 @@ gsk_pango_renderer_prepare_run (PangoRenderer *renderer,
|
||||
if (crenderer->state == GSK_PANGO_RENDERER_SELECTED &&
|
||||
GTK_IS_TEXT_VIEW (crenderer->widget))
|
||||
{
|
||||
GtkCssNode *selection_node;
|
||||
GtkCssNode *node;
|
||||
GtkCssValue *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);
|
||||
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);
|
||||
}
|
||||
else if (crenderer->state == GSK_PANGO_RENDERER_CURSOR && gtk_widget_has_focus (crenderer->widget))
|
||||
{
|
||||
gtk_style_context_get (context,
|
||||
"background-color", &fg_rgba,
|
||||
NULL);
|
||||
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);
|
||||
}
|
||||
else
|
||||
fg_rgba = appearance->fg_rgba;
|
||||
|
@@ -297,17 +297,25 @@ 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,9 +109,6 @@ 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)
|
||||
@@ -131,7 +128,6 @@ 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,
|
||||
@@ -242,105 +238,6 @@ 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,6 +229,7 @@ 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,9 +115,6 @@ 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;
|
||||
@@ -149,7 +146,6 @@ 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"),
|
||||
@@ -375,9 +371,7 @@ gtk_container_idle_sizer (GdkFrameClock *clock,
|
||||
*/
|
||||
if (gtk_widget_needs_allocate (GTK_WIDGET (container)))
|
||||
{
|
||||
if (GTK_IS_WINDOW (container))
|
||||
gtk_window_check_resize (GTK_WINDOW (container));
|
||||
else if (GTK_IS_ROOT (container))
|
||||
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");
|
||||
@@ -651,18 +645,6 @@ 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)
|
||||
@@ -783,35 +765,3 @@ 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,8 +62,6 @@ 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.
|
||||
*/
|
||||
@@ -83,8 +81,6 @@ 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 >*/
|
||||
@@ -132,10 +128,6 @@ 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
|
||||
|
@@ -79,6 +79,15 @@ gtk_css_animated_style_is_static (GtkCssStyle *style)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkCssStaticStyle *
|
||||
gtk_css_animated_style_get_static_style (GtkCssStyle *style)
|
||||
{
|
||||
/* This is called a lot, so we avoid a dynamic type check here */
|
||||
GtkCssAnimatedStyle *animated = (GtkCssAnimatedStyle *) style;
|
||||
|
||||
return (GtkCssStaticStyle *)animated->style;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_animated_style_dispose (GObject *object)
|
||||
{
|
||||
@@ -123,6 +132,7 @@ gtk_css_animated_style_class_init (GtkCssAnimatedStyleClass *klass)
|
||||
style_class->get_value = gtk_css_animated_style_get_value;
|
||||
style_class->get_section = gtk_css_animated_style_get_section;
|
||||
style_class->is_static = gtk_css_animated_style_is_static;
|
||||
style_class->get_static_style = gtk_css_animated_style_get_static_style;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -299,7 +299,7 @@ gtk_css_value_array_transition (GtkCssValue *start,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_value_array_is_dynamic (GtkCssValue *value)
|
||||
gtk_css_value_array_is_dynamic (const GtkCssValue *value)
|
||||
{
|
||||
guint i;
|
||||
|
||||
@@ -369,6 +369,7 @@ gtk_css_value_array_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_ARRAY = {
|
||||
"GtkCssArrayValue",
|
||||
gtk_css_value_array_free,
|
||||
gtk_css_value_array_compute,
|
||||
gtk_css_value_array_equal,
|
||||
@@ -391,14 +392,28 @@ _gtk_css_array_value_new_from_array (GtkCssValue **values,
|
||||
guint n_values)
|
||||
{
|
||||
GtkCssValue *result;
|
||||
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (values != NULL, NULL);
|
||||
g_return_val_if_fail (n_values > 0, NULL);
|
||||
|
||||
|
||||
if (n_values == 1)
|
||||
return values[0];
|
||||
|
||||
result = _gtk_css_value_alloc (>K_CSS_VALUE_ARRAY, sizeof (GtkCssValue) + sizeof (GtkCssValue *) * (n_values - 1));
|
||||
result->n_values = n_values;
|
||||
memcpy (&result->values[0], values, sizeof (GtkCssValue *) * n_values);
|
||||
|
||||
|
||||
result->is_computed = TRUE;
|
||||
for (i = 0; i < n_values; i ++)
|
||||
{
|
||||
if (!gtk_css_value_is_computed (values[i]))
|
||||
{
|
||||
result->is_computed = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -407,32 +422,38 @@ _gtk_css_array_value_parse (GtkCssParser *parser,
|
||||
GtkCssValue *(* parse_func) (GtkCssParser *parser))
|
||||
{
|
||||
GtkCssValue *value, *result;
|
||||
GPtrArray *values;
|
||||
|
||||
values = g_ptr_array_new ();
|
||||
GtkCssValue *values[128];
|
||||
guint n_values = 0;
|
||||
guint i;
|
||||
|
||||
do {
|
||||
value = parse_func (parser);
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
g_ptr_array_set_free_func (values, (GDestroyNotify) _gtk_css_value_unref);
|
||||
g_ptr_array_free (values, TRUE);
|
||||
for (i = 0; i < n_values; i ++)
|
||||
_gtk_css_value_unref (values[i]);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_ptr_array_add (values, value);
|
||||
values[n_values] = value;
|
||||
n_values ++;
|
||||
if (G_UNLIKELY (n_values > G_N_ELEMENTS (values)))
|
||||
g_error ("Only %d elements in a css array are allowed", (int)G_N_ELEMENTS (values));
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
result = _gtk_css_array_value_new_from_array ((GtkCssValue **) values->pdata, values->len);
|
||||
g_ptr_array_free (values, TRUE);
|
||||
result = _gtk_css_array_value_new_from_array (values, n_values);
|
||||
return result;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_array_value_get_nth (const GtkCssValue *value,
|
||||
guint i)
|
||||
_gtk_css_array_value_get_nth (GtkCssValue *value,
|
||||
guint i)
|
||||
{
|
||||
if (value->class != >K_CSS_VALUE_ARRAY)
|
||||
return value;
|
||||
|
||||
g_return_val_if_fail (value != NULL, NULL);
|
||||
g_return_val_if_fail (value->class == >K_CSS_VALUE_ARRAY, NULL);
|
||||
g_return_val_if_fail (value->n_values > 0, NULL);
|
||||
@@ -443,6 +464,9 @@ _gtk_css_array_value_get_nth (const GtkCssValue *value,
|
||||
guint
|
||||
_gtk_css_array_value_get_n_values (const GtkCssValue *value)
|
||||
{
|
||||
if (value->class != >K_CSS_VALUE_ARRAY)
|
||||
return 1;
|
||||
|
||||
g_return_val_if_fail (value != NULL, 0);
|
||||
g_return_val_if_fail (value->class == >K_CSS_VALUE_ARRAY, 0);
|
||||
|
||||
|
@@ -32,9 +32,9 @@ GtkCssValue * _gtk_css_array_value_new_from_array (GtkCssValue **
|
||||
GtkCssValue * _gtk_css_array_value_parse (GtkCssParser *parser,
|
||||
GtkCssValue * (* parse_func) (GtkCssParser *));
|
||||
|
||||
GtkCssValue * _gtk_css_array_value_get_nth (const GtkCssValue *value,
|
||||
GtkCssValue * _gtk_css_array_value_get_nth (GtkCssValue *value,
|
||||
guint i);
|
||||
guint _gtk_css_array_value_get_n_values (const GtkCssValue *value);
|
||||
guint _gtk_css_array_value_get_n_values (const GtkCssValue *value) G_GNUC_PURE;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -153,6 +153,7 @@ gtk_css_value_bg_size_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_BG_SIZE = {
|
||||
"GtkCssBgSizeValue",
|
||||
gtk_css_value_bg_size_free,
|
||||
gtk_css_value_bg_size_compute,
|
||||
gtk_css_value_bg_size_equal,
|
||||
@@ -162,9 +163,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_BG_SIZE = {
|
||||
gtk_css_value_bg_size_print
|
||||
};
|
||||
|
||||
static GtkCssValue auto_singleton = { >K_CSS_VALUE_BG_SIZE, 1, FALSE, FALSE, NULL, NULL };
|
||||
static GtkCssValue cover_singleton = { >K_CSS_VALUE_BG_SIZE, 1, TRUE, FALSE, NULL, NULL };
|
||||
static GtkCssValue contain_singleton = { >K_CSS_VALUE_BG_SIZE, 1, FALSE, TRUE, NULL, NULL };
|
||||
static GtkCssValue auto_singleton = { >K_CSS_VALUE_BG_SIZE, 1, TRUE, FALSE, FALSE, NULL, NULL };
|
||||
static GtkCssValue cover_singleton = { >K_CSS_VALUE_BG_SIZE, 1, TRUE, TRUE, FALSE, NULL, NULL };
|
||||
static GtkCssValue contain_singleton = { >K_CSS_VALUE_BG_SIZE, 1, TRUE, FALSE, TRUE, NULL, NULL };
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_bg_size_value_new (GtkCssValue *x,
|
||||
@@ -178,6 +179,8 @@ _gtk_css_bg_size_value_new (GtkCssValue *x,
|
||||
result = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_BG_SIZE);
|
||||
result->x = x;
|
||||
result->y = y;
|
||||
result->is_computed = (!x || gtk_css_value_is_computed (x)) &&
|
||||
(!y || gtk_css_value_is_computed (y));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -140,6 +140,7 @@ gtk_css_value_border_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_BORDER = {
|
||||
"GtkCssBorderValue",
|
||||
gtk_css_value_border_free,
|
||||
gtk_css_value_border_compute,
|
||||
gtk_css_value_border_equal,
|
||||
@@ -162,6 +163,10 @@ _gtk_css_border_value_new (GtkCssValue *top,
|
||||
result->values[GTK_CSS_RIGHT] = right;
|
||||
result->values[GTK_CSS_BOTTOM] = bottom;
|
||||
result->values[GTK_CSS_LEFT] = left;
|
||||
result->is_computed = (top && gtk_css_value_is_computed (top)) &&
|
||||
(right && gtk_css_value_is_computed (right)) &&
|
||||
(bottom && gtk_css_value_is_computed (bottom)) &&
|
||||
(left && gtk_css_value_is_computed (left));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -212,6 +217,14 @@ _gtk_css_border_value_parse (GtkCssParser *parser,
|
||||
result->values[i] = _gtk_css_value_ref (result->values[(i - 1) >> 1]);
|
||||
}
|
||||
|
||||
result->is_computed = TRUE;
|
||||
for (; i < 4; i++)
|
||||
if (result->values[i] && !gtk_css_value_is_computed (result->values[i]))
|
||||
{
|
||||
result->is_computed = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "gtkcsscornervalueprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssdimensionvalueprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
/* This file is included from gtkcssboxesprivate.h */
|
||||
@@ -79,15 +80,50 @@ gtk_css_boxes_rect_grow (GskRoundedRect *dest,
|
||||
int bottom_property,
|
||||
int 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);
|
||||
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);
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -323,19 +359,38 @@ gtk_css_boxes_apply_border_radius (GskRoundedRect *box,
|
||||
const GtkCssValue *bottom_right,
|
||||
const GtkCssValue *bottom_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);
|
||||
gboolean has_border_radius = FALSE;
|
||||
|
||||
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_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_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 (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_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_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;
|
||||
}
|
||||
|
||||
gtk_css_boxes_clamp_border_radius (box);
|
||||
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);
|
||||
}
|
||||
|
||||
/* NB: width and height must be >= 0 */
|
||||
|
@@ -211,8 +211,8 @@ gtk_css_value_calc_has_percent (const GtkCssValue *value)
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_calc_multiply (const GtkCssValue *value,
|
||||
double factor)
|
||||
gtk_css_value_calc_multiply (GtkCssValue *value,
|
||||
double factor)
|
||||
{
|
||||
GtkCssValue *result;
|
||||
gsize i;
|
||||
@@ -245,6 +245,7 @@ gtk_css_value_calc_get_calc_term_order (const GtkCssValue *value)
|
||||
|
||||
static const GtkCssNumberValueClass GTK_CSS_VALUE_CALC = {
|
||||
{
|
||||
"GtkCssCalcValue",
|
||||
gtk_css_value_calc_free,
|
||||
gtk_css_value_calc_compute,
|
||||
gtk_css_value_calc_equal,
|
||||
|
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkhslaprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
@@ -45,6 +44,7 @@ struct _GtkCssValue
|
||||
union
|
||||
{
|
||||
gchar *name;
|
||||
GdkRGBA rgba;
|
||||
|
||||
struct
|
||||
{
|
||||
@@ -104,7 +104,7 @@ gtk_css_value_color_get_fallback (guint property_id,
|
||||
case GTK_CSS_PROPERTY_TEXT_SHADOW:
|
||||
case GTK_CSS_PROPERTY_ICON_SHADOW:
|
||||
case GTK_CSS_PROPERTY_BOX_SHADOW:
|
||||
return _gtk_css_rgba_value_new_transparent ();
|
||||
return gtk_css_color_value_new_transparent ();
|
||||
case GTK_CSS_PROPERTY_COLOR:
|
||||
case GTK_CSS_PROPERTY_BACKGROUND_COLOR:
|
||||
case GTK_CSS_PROPERTY_BORDER_TOP_COLOR:
|
||||
@@ -125,7 +125,7 @@ gtk_css_value_color_get_fallback (guint property_id,
|
||||
if (property_id < GTK_CSS_PROPERTY_N_PROPERTIES)
|
||||
g_warning ("No fallback color defined for property '%s'",
|
||||
_gtk_style_property_get_name (GTK_STYLE_PROPERTY (_gtk_css_style_property_lookup_by_id (property_id))));
|
||||
return _gtk_css_rgba_value_new_transparent ();
|
||||
return gtk_css_color_value_new_transparent ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ gtk_css_value_color_compute (GtkCssValue *value,
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style)
|
||||
{
|
||||
GtkCssValue *resolved, *current;
|
||||
GtkCssValue *resolved;
|
||||
|
||||
/* The computed value of the ‘currentColor’ keyword is the computed
|
||||
* value of the ‘color’ property. If the ‘currentColor’ keyword is
|
||||
@@ -144,20 +144,31 @@ gtk_css_value_color_compute (GtkCssValue *value,
|
||||
*/
|
||||
if (property_id == GTK_CSS_PROPERTY_COLOR)
|
||||
{
|
||||
GtkCssValue *current;
|
||||
|
||||
if (parent_style)
|
||||
current = gtk_css_style_get_value (parent_style, GTK_CSS_PROPERTY_COLOR);
|
||||
else
|
||||
current = NULL;
|
||||
|
||||
resolved = _gtk_css_color_value_resolve (value,
|
||||
provider,
|
||||
current,
|
||||
NULL);
|
||||
}
|
||||
else if (value->type == COLOR_TYPE_LITERAL)
|
||||
{
|
||||
resolved = _gtk_css_value_ref (value);
|
||||
}
|
||||
else
|
||||
{
|
||||
current = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_COLOR);
|
||||
GtkCssValue *current = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_COLOR);
|
||||
|
||||
resolved = _gtk_css_color_value_resolve (value,
|
||||
provider,
|
||||
current,
|
||||
NULL);
|
||||
}
|
||||
|
||||
resolved = _gtk_css_color_value_resolve (value,
|
||||
provider,
|
||||
current,
|
||||
NULL);
|
||||
|
||||
if (resolved == NULL)
|
||||
return gtk_css_value_color_get_fallback (property_id, provider, style, parent_style);
|
||||
@@ -175,7 +186,7 @@ gtk_css_value_color_equal (const GtkCssValue *value1,
|
||||
switch (value1->type)
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
return _gtk_css_value_equal (value1->last_value, value2->last_value);
|
||||
return gdk_rgba_equal (&value1->sym_col.rgba, &value2->sym_col.rgba);
|
||||
case COLOR_TYPE_NAME:
|
||||
return g_str_equal (value1->sym_col.name, value2->sym_col.name);
|
||||
case COLOR_TYPE_SHADE:
|
||||
@@ -216,7 +227,11 @@ gtk_css_value_color_print (const GtkCssValue *value,
|
||||
switch (value->type)
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
_gtk_css_value_print (value->last_value, string);
|
||||
{
|
||||
char *s = gdk_rgba_to_string (&value->sym_col.rgba);
|
||||
g_string_append (string, s);
|
||||
g_free (s);
|
||||
}
|
||||
break;
|
||||
case COLOR_TYPE_NAME:
|
||||
g_string_append (string, "@");
|
||||
@@ -269,6 +284,7 @@ gtk_css_value_color_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_COLOR = {
|
||||
"GtkCssColorValue",
|
||||
gtk_css_value_color_free,
|
||||
gtk_css_value_color_compute,
|
||||
gtk_css_value_color_equal,
|
||||
@@ -278,6 +294,57 @@ static const GtkCssValueClass GTK_CSS_VALUE_COLOR = {
|
||||
gtk_css_value_color_print
|
||||
};
|
||||
|
||||
static void
|
||||
apply_alpha (const GdkRGBA *in,
|
||||
GdkRGBA *out,
|
||||
double factor)
|
||||
{
|
||||
*out = *in;
|
||||
|
||||
out->alpha = CLAMP (in->alpha * factor, 0, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_shade (const GdkRGBA *in,
|
||||
GdkRGBA *out,
|
||||
double factor)
|
||||
{
|
||||
GtkHSLA hsla;
|
||||
|
||||
_gtk_hsla_init_from_rgba (&hsla, in);
|
||||
_gtk_hsla_shade (&hsla, &hsla, factor);
|
||||
|
||||
_gdk_rgba_init_from_hsla (out, &hsla);
|
||||
}
|
||||
|
||||
static inline double
|
||||
transition (double start,
|
||||
double end,
|
||||
double progress)
|
||||
{
|
||||
return start + (end - start) * progress;
|
||||
}
|
||||
|
||||
static void
|
||||
apply_mix (const GdkRGBA *in1,
|
||||
const GdkRGBA *in2,
|
||||
GdkRGBA *out,
|
||||
double factor)
|
||||
{
|
||||
out->alpha = CLAMP (transition (in1->alpha, in2->alpha, factor), 0, 1);
|
||||
|
||||
if (out->alpha <= 0.0)
|
||||
{
|
||||
out->red = out->green = out->blue = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
out->red = CLAMP (transition (in1->red * in1->alpha, in2->red * in2->alpha, factor), 0, 1) / out->alpha;
|
||||
out->green = CLAMP (transition (in1->green * in1->alpha, in2->green * in2->alpha, factor), 0, 1) / out->alpha;
|
||||
out->blue = CLAMP (transition (in1->blue * in1->alpha, in2->blue * in2->alpha, factor), 0, 1) / out->alpha;
|
||||
}
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_resolve (GtkCssValue *color,
|
||||
GtkStyleProvider *provider,
|
||||
@@ -291,7 +358,7 @@ _gtk_css_color_value_resolve (GtkCssValue *color,
|
||||
switch (color->type)
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
return _gtk_css_value_ref (color->last_value);
|
||||
return _gtk_css_value_ref (color);
|
||||
case COLOR_TYPE_NAME:
|
||||
{
|
||||
GtkCssValue *named;
|
||||
@@ -314,66 +381,61 @@ _gtk_css_color_value_resolve (GtkCssValue *color,
|
||||
break;
|
||||
case COLOR_TYPE_SHADE:
|
||||
{
|
||||
GtkCssValue *val;
|
||||
GtkHSLA hsla;
|
||||
GdkRGBA shade;
|
||||
const GdkRGBA *c;
|
||||
GtkCssValue *val;
|
||||
GdkRGBA shade;
|
||||
|
||||
val = _gtk_css_color_value_resolve (color->sym_col.shade.color, provider, current, cycle_list);
|
||||
if (val == NULL)
|
||||
return NULL;
|
||||
val = _gtk_css_color_value_resolve (color->sym_col.shade.color, provider, current, cycle_list);
|
||||
if (val == NULL)
|
||||
return NULL;
|
||||
c = gtk_css_color_value_get_rgba (val);
|
||||
|
||||
_gtk_hsla_init_from_rgba (&hsla, _gtk_css_rgba_value_get_rgba (val));
|
||||
_gtk_hsla_shade (&hsla, &hsla, color->sym_col.shade.factor);
|
||||
apply_shade (c, &shade, color->sym_col.shade.factor);
|
||||
|
||||
_gdk_rgba_init_from_hsla (&shade, &hsla);
|
||||
|
||||
_gtk_css_value_unref (val);
|
||||
|
||||
value = _gtk_css_rgba_value_new_from_rgba (&shade);
|
||||
value = _gtk_css_color_value_new_literal (&shade);
|
||||
_gtk_css_value_unref (val);
|
||||
}
|
||||
|
||||
break;
|
||||
case COLOR_TYPE_ALPHA:
|
||||
{
|
||||
GtkCssValue *val;
|
||||
GdkRGBA alpha;
|
||||
const GdkRGBA *c;
|
||||
GtkCssValue *val;
|
||||
GdkRGBA alpha;
|
||||
|
||||
val = _gtk_css_color_value_resolve (color->sym_col.alpha.color, provider, current, cycle_list);
|
||||
if (val == NULL)
|
||||
return NULL;
|
||||
val = _gtk_css_color_value_resolve (color->sym_col.alpha.color, provider, current, cycle_list);
|
||||
if (val == NULL)
|
||||
return NULL;
|
||||
c = gtk_css_color_value_get_rgba (val);
|
||||
|
||||
alpha = *_gtk_css_rgba_value_get_rgba (val);
|
||||
alpha.alpha = CLAMP (alpha.alpha * color->sym_col.alpha.factor, 0, 1);
|
||||
apply_alpha (c, &alpha, color->sym_col.alpha.factor);
|
||||
|
||||
_gtk_css_value_unref (val);
|
||||
|
||||
value = _gtk_css_rgba_value_new_from_rgba (&alpha);
|
||||
value = _gtk_css_color_value_new_literal (&alpha);
|
||||
_gtk_css_value_unref (val);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_TYPE_MIX:
|
||||
{
|
||||
GtkCssValue *val;
|
||||
GdkRGBA color1, color2, res;
|
||||
const GdkRGBA *color1, *color2;
|
||||
GtkCssValue *val1, *val2;
|
||||
GdkRGBA res;
|
||||
|
||||
val = _gtk_css_color_value_resolve (color->sym_col.mix.color1, provider, current, cycle_list);
|
||||
if (val == NULL)
|
||||
return NULL;
|
||||
color1 = *_gtk_css_rgba_value_get_rgba (val);
|
||||
_gtk_css_value_unref (val);
|
||||
val1 = _gtk_css_color_value_resolve (color->sym_col.mix.color1, provider, current, cycle_list);
|
||||
if (val1 == NULL)
|
||||
return NULL;
|
||||
color1 = gtk_css_color_value_get_rgba (val1);
|
||||
|
||||
val = _gtk_css_color_value_resolve (color->sym_col.mix.color2, provider, current, cycle_list);
|
||||
if (val == NULL)
|
||||
return NULL;
|
||||
color2 = *_gtk_css_rgba_value_get_rgba (val);
|
||||
_gtk_css_value_unref (val);
|
||||
val2 = _gtk_css_color_value_resolve (color->sym_col.mix.color2, provider, current, cycle_list);
|
||||
if (val2 == NULL)
|
||||
return NULL;
|
||||
color2 = gtk_css_color_value_get_rgba (val2);
|
||||
|
||||
res.red = CLAMP (color1.red + ((color2.red - color1.red) * color->sym_col.mix.factor), 0, 1);
|
||||
res.green = CLAMP (color1.green + ((color2.green - color1.green) * color->sym_col.mix.factor), 0, 1);
|
||||
res.blue = CLAMP (color1.blue + ((color2.blue - color1.blue) * color->sym_col.mix.factor), 0, 1);
|
||||
res.alpha = CLAMP (color1.alpha + ((color2.alpha - color1.alpha) * color->sym_col.mix.factor), 0, 1);
|
||||
apply_mix (color1, color2, &res, color->sym_col.mix.factor);
|
||||
|
||||
value =_gtk_css_rgba_value_new_from_rgba (&res);
|
||||
value = _gtk_css_color_value_new_literal (&res);
|
||||
_gtk_css_value_unref (val1);
|
||||
_gtk_css_value_unref (val2);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -420,6 +482,24 @@ _gtk_css_color_value_resolve (GtkCssValue *color,
|
||||
return value;
|
||||
}
|
||||
|
||||
static GtkCssValue transparent_black_singleton = { >K_CSS_VALUE_COLOR, 1, TRUE, COLOR_TYPE_LITERAL, NULL,
|
||||
.sym_col.rgba = {0, 0, 0, 0} };
|
||||
static GtkCssValue white_singleton = { >K_CSS_VALUE_COLOR, 1, TRUE, COLOR_TYPE_LITERAL, NULL,
|
||||
.sym_col.rgba = {1, 1, 1, 1} };
|
||||
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_color_value_new_transparent (void)
|
||||
{
|
||||
return _gtk_css_value_ref (&transparent_black_singleton);
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_color_value_new_white (void)
|
||||
{
|
||||
return _gtk_css_value_ref (&white_singleton);
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_new_literal (const GdkRGBA *color)
|
||||
{
|
||||
@@ -427,9 +507,16 @@ _gtk_css_color_value_new_literal (const GdkRGBA *color)
|
||||
|
||||
g_return_val_if_fail (color != NULL, NULL);
|
||||
|
||||
if (gdk_rgba_equal (color, &white_singleton.sym_col.rgba))
|
||||
return _gtk_css_value_ref (&white_singleton);
|
||||
|
||||
if (gdk_rgba_equal (color, &transparent_black_singleton.sym_col.rgba))
|
||||
return _gtk_css_value_ref (&transparent_black_singleton);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_LITERAL;
|
||||
value->last_value = _gtk_css_rgba_value_new_from_rgba (color);
|
||||
value->is_computed = TRUE;
|
||||
value->sym_col.rgba = *color;
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -456,6 +543,15 @@ _gtk_css_color_value_new_shade (GtkCssValue *color,
|
||||
|
||||
gtk_internal_return_val_if_fail (color->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
|
||||
if (color->type == COLOR_TYPE_LITERAL)
|
||||
{
|
||||
GdkRGBA c;
|
||||
|
||||
apply_shade (&color->sym_col.rgba, &c, factor);
|
||||
|
||||
return _gtk_css_color_value_new_literal (&c);
|
||||
}
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_SHADE;
|
||||
value->sym_col.shade.color = _gtk_css_value_ref (color);
|
||||
@@ -472,6 +568,15 @@ _gtk_css_color_value_new_alpha (GtkCssValue *color,
|
||||
|
||||
gtk_internal_return_val_if_fail (color->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
|
||||
if (color->type == COLOR_TYPE_LITERAL)
|
||||
{
|
||||
GdkRGBA c;
|
||||
|
||||
apply_alpha (&color->sym_col.rgba, &c, factor);
|
||||
|
||||
return _gtk_css_color_value_new_literal (&c);
|
||||
}
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_ALPHA;
|
||||
value->sym_col.alpha.color = _gtk_css_value_ref (color);
|
||||
@@ -490,6 +595,17 @@ _gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
gtk_internal_return_val_if_fail (color1->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
gtk_internal_return_val_if_fail (color2->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
|
||||
if (color1->type == COLOR_TYPE_LITERAL &&
|
||||
color2->type == COLOR_TYPE_LITERAL)
|
||||
{
|
||||
GdkRGBA result;
|
||||
|
||||
apply_mix (&color1->sym_col.rgba, &color2->sym_col.rgba, &result, factor);
|
||||
|
||||
return _gtk_css_color_value_new_literal (&result);
|
||||
|
||||
}
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_MIX;
|
||||
value->sym_col.mix.color1 = _gtk_css_value_ref (color1);
|
||||
@@ -502,7 +618,7 @@ _gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_new_current_color (void)
|
||||
{
|
||||
static GtkCssValue current_color = { >K_CSS_VALUE_COLOR, 1, COLOR_TYPE_CURRENT_COLOR, NULL, };
|
||||
static GtkCssValue current_color = { >K_CSS_VALUE_COLOR, 1, FALSE, COLOR_TYPE_CURRENT_COLOR, NULL, };
|
||||
|
||||
return _gtk_css_value_ref (¤t_color);
|
||||
}
|
||||
@@ -665,3 +781,11 @@ _gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const GdkRGBA *
|
||||
gtk_css_color_value_get_rgba (const GtkCssValue *color)
|
||||
{
|
||||
g_assert (color->class == >K_CSS_VALUE_COLOR);
|
||||
g_assert (color->type == COLOR_TYPE_LITERAL);
|
||||
|
||||
return &color->sym_col.rgba;
|
||||
}
|
||||
|
@@ -24,16 +24,18 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
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_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_shade (GtkCssValue *color,
|
||||
gdouble factor);
|
||||
gdouble factor) G_GNUC_PURE;
|
||||
GtkCssValue * _gtk_css_color_value_new_alpha (GtkCssValue *color,
|
||||
gdouble factor);
|
||||
gdouble factor) G_GNUC_PURE;
|
||||
GtkCssValue * _gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
GtkCssValue *color2,
|
||||
gdouble factor);
|
||||
GtkCssValue * _gtk_css_color_value_new_current_color (void);
|
||||
gdouble factor) G_GNUC_PURE;
|
||||
GtkCssValue * _gtk_css_color_value_new_current_color (void) G_GNUC_PURE;
|
||||
|
||||
gboolean gtk_css_color_value_can_parse (GtkCssParser *parser);
|
||||
GtkCssValue * _gtk_css_color_value_parse (GtkCssParser *parser);
|
||||
@@ -42,6 +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;
|
||||
|
||||
|
||||
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
|
||||
@@ -99,6 +99,7 @@ gtk_css_value_corner_print (const GtkCssValue *corner,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_CORNER = {
|
||||
"GtkCssCornerValue",
|
||||
gtk_css_value_corner_free,
|
||||
gtk_css_value_corner_compute,
|
||||
gtk_css_value_corner_equal,
|
||||
@@ -114,6 +115,12 @@ _gtk_css_corner_value_new (GtkCssValue *x,
|
||||
{
|
||||
GtkCssValue *result;
|
||||
|
||||
if (_gtk_css_value_equal (x, y))
|
||||
{
|
||||
_gtk_css_value_unref (y);
|
||||
return x;
|
||||
}
|
||||
|
||||
result = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_CORNER);
|
||||
result->x = x;
|
||||
result->y = y;
|
||||
@@ -155,6 +162,9 @@ double
|
||||
_gtk_css_corner_value_get_x (const GtkCssValue *corner,
|
||||
double one_hundred_percent)
|
||||
{
|
||||
if (corner->class != >K_CSS_VALUE_CORNER)
|
||||
return _gtk_css_number_value_get (corner, one_hundred_percent);
|
||||
|
||||
g_return_val_if_fail (corner != NULL, 0.0);
|
||||
g_return_val_if_fail (corner->class == >K_CSS_VALUE_CORNER, 0.0);
|
||||
|
||||
@@ -165,9 +175,21 @@ double
|
||||
_gtk_css_corner_value_get_y (const GtkCssValue *corner,
|
||||
double one_hundred_percent)
|
||||
{
|
||||
if (corner->class != >K_CSS_VALUE_CORNER)
|
||||
return _gtk_css_number_value_get (corner, one_hundred_percent);
|
||||
|
||||
g_return_val_if_fail (corner != NULL, 0.0);
|
||||
g_return_val_if_fail (corner->class == >K_CSS_VALUE_CORNER, 0.0);
|
||||
|
||||
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,9 +30,10 @@ 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);
|
||||
double one_hundred_percent) G_GNUC_PURE;
|
||||
double _gtk_css_corner_value_get_y (const GtkCssValue *corner,
|
||||
double one_hundred_percent);
|
||||
double one_hundred_percent) G_GNUC_PURE;
|
||||
gboolean gtk_css_corner_value_is_zero (const GtkCssValue *corner) G_GNUC_PURE;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -66,40 +66,6 @@ gtk_css_value_dimension_compute (GtkCssValue *number,
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style)
|
||||
{
|
||||
GtkBorderStyle border_style;
|
||||
|
||||
/* special case according to http://dev.w3.org/csswg/css-backgrounds/#the-border-width */
|
||||
switch (property_id)
|
||||
{
|
||||
case GTK_CSS_PROPERTY_BORDER_TOP_WIDTH:
|
||||
border_style = _gtk_css_border_style_value_get(gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_STYLE));
|
||||
if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN)
|
||||
return gtk_css_dimension_value_new (0, GTK_CSS_NUMBER);
|
||||
break;
|
||||
case GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH:
|
||||
border_style = _gtk_css_border_style_value_get(gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE));
|
||||
if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN)
|
||||
return gtk_css_dimension_value_new (0, GTK_CSS_NUMBER);
|
||||
break;
|
||||
case GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH:
|
||||
border_style = _gtk_css_border_style_value_get(gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE));
|
||||
if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN)
|
||||
return gtk_css_dimension_value_new (0, GTK_CSS_NUMBER);
|
||||
break;
|
||||
case GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH:
|
||||
border_style = _gtk_css_border_style_value_get(gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_LEFT_STYLE));
|
||||
if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN)
|
||||
return gtk_css_dimension_value_new (0, GTK_CSS_NUMBER);
|
||||
break;
|
||||
case GTK_CSS_PROPERTY_OUTLINE_WIDTH:
|
||||
border_style = _gtk_css_border_style_value_get(gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_STYLE));
|
||||
if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN)
|
||||
return gtk_css_dimension_value_new (0, GTK_CSS_NUMBER);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (number->unit)
|
||||
{
|
||||
default:
|
||||
@@ -228,8 +194,8 @@ gtk_css_value_dimension_has_percent (const GtkCssValue *value)
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_dimension_multiply (const GtkCssValue *value,
|
||||
double factor)
|
||||
gtk_css_value_dimension_multiply (GtkCssValue *value,
|
||||
double factor)
|
||||
{
|
||||
return gtk_css_dimension_value_new (value->value * factor, value->unit);
|
||||
}
|
||||
@@ -277,12 +243,25 @@ gtk_css_value_dimension_get_calc_term_order (const GtkCssValue *value)
|
||||
return 1000 + order_per_unit[value->unit];
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_dimension_transition (GtkCssValue *start,
|
||||
GtkCssValue *end,
|
||||
guint property_id,
|
||||
double progress)
|
||||
{
|
||||
if (start->unit != end->unit)
|
||||
return NULL;
|
||||
|
||||
return gtk_css_dimension_value_new (start->value + (end->value - start->value) * progress, start->unit);
|
||||
}
|
||||
|
||||
static const GtkCssNumberValueClass GTK_CSS_VALUE_DIMENSION = {
|
||||
{
|
||||
"GtkCssDimensionValue",
|
||||
gtk_css_value_dimension_free,
|
||||
gtk_css_value_dimension_compute,
|
||||
gtk_css_value_dimension_equal,
|
||||
gtk_css_number_value_transition,
|
||||
gtk_css_value_dimension_transition,
|
||||
NULL,
|
||||
NULL,
|
||||
gtk_css_value_dimension_print
|
||||
@@ -300,35 +279,35 @@ gtk_css_dimension_value_new (double value,
|
||||
GtkCssUnit unit)
|
||||
{
|
||||
static GtkCssValue number_singletons[] = {
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_NUMBER, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_NUMBER, 1 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_NUMBER, 96 }, /* DPI default */
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_NUMBER, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_NUMBER, 1 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_NUMBER, 96 }, /* DPI default */
|
||||
};
|
||||
static GtkCssValue px_singletons[] = {
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 1 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 2 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 3 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 4 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 8 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 16 }, /* Icon size default */
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 32 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 64 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 1 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 2 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 3 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 4 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 8 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 16 }, /* Icon size default */
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 32 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 64 },
|
||||
};
|
||||
static GtkCssValue percent_singletons[] = {
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PERCENT, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PERCENT, 50 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PERCENT, 100 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PERCENT, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, FALSE, GTK_CSS_PERCENT, 50 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, FALSE, GTK_CSS_PERCENT, 100 },
|
||||
};
|
||||
static GtkCssValue second_singletons[] = {
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_S, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_S, 1 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_S, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_S, 1 },
|
||||
};
|
||||
static GtkCssValue deg_singletons[] = {
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 90 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 180 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 270 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 90 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 180 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 270 },
|
||||
};
|
||||
GtkCssValue *result;
|
||||
|
||||
@@ -396,6 +375,11 @@ gtk_css_dimension_value_new (double value,
|
||||
result = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_DIMENSION.value_class);
|
||||
result->unit = unit;
|
||||
result->value = value;
|
||||
result->is_computed = value == 0 ||
|
||||
unit == GTK_CSS_NUMBER ||
|
||||
unit == GTK_CSS_PX ||
|
||||
unit == GTK_CSS_DEG ||
|
||||
unit == GTK_CSS_S;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -513,3 +497,14 @@ 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,10 +26,12 @@ 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__ */
|
||||
|
@@ -135,6 +135,7 @@ gtk_css_value_ease_print (const GtkCssValue *ease,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_EASE = {
|
||||
"GtkCssEaseValue",
|
||||
gtk_css_value_ease_free,
|
||||
gtk_css_value_ease_compute,
|
||||
gtk_css_value_ease_equal,
|
||||
@@ -158,12 +159,13 @@ _gtk_css_ease_value_new_cubic_bezier (double x1,
|
||||
g_return_val_if_fail (x2 <= 1.0, NULL);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_EASE);
|
||||
|
||||
|
||||
value->type = GTK_CSS_EASE_CUBIC_BEZIER;
|
||||
value->u.cubic.x1 = x1;
|
||||
value->u.cubic.y1 = y1;
|
||||
value->u.cubic.x2 = x2;
|
||||
value->u.cubic.y2 = y2;
|
||||
value->is_computed = TRUE;
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -177,10 +179,11 @@ _gtk_css_ease_value_new_steps (guint n_steps,
|
||||
g_return_val_if_fail (n_steps > 0, NULL);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_EASE);
|
||||
|
||||
|
||||
value->type = GTK_CSS_EASE_STEPS;
|
||||
value->u.steps.steps = n_steps;
|
||||
value->u.steps.start = start;
|
||||
value->is_computed = TRUE;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@@ -78,6 +78,7 @@ gtk_css_value_enum_print (const GtkCssValue *value,
|
||||
/* GtkBorderStyle */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_BORDER_STYLE = {
|
||||
"GtkCssBorderStyleValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -88,16 +89,16 @@ static const GtkCssValueClass GTK_CSS_VALUE_BORDER_STYLE = {
|
||||
};
|
||||
|
||||
static GtkCssValue border_style_values[] = {
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_NONE, "none" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_SOLID, "solid" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_INSET, "inset" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_OUTSET, "outset" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_HIDDEN, "hidden" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DOTTED, "dotted" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DASHED, "dashed" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DOUBLE, "double" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_GROOVE, "groove" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_RIDGE, "ridge" }
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_NONE, "none" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_SOLID, "solid" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_INSET, "inset" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_OUTSET, "outset" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_HIDDEN, "hidden" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_DOTTED, "dotted" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_DASHED, "dashed" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_DOUBLE, "double" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_GROOVE, "groove" },
|
||||
{ >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_RIDGE, "ridge" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -135,6 +136,7 @@ _gtk_css_border_style_value_get (const GtkCssValue *value)
|
||||
/* GtkCssBlendMode */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_BLEND_MODE = {
|
||||
"GtkCssBlendModeValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -145,22 +147,22 @@ static const GtkCssValueClass GTK_CSS_VALUE_BLEND_MODE = {
|
||||
};
|
||||
|
||||
static GtkCssValue blend_mode_values[] = {
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_DEFAULT, "normal" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_MULTIPLY, "multiply" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_SCREEN, "screen" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_OVERLAY, "overlay" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_DARKEN, "darken" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_LIGHTEN, "lighten" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_COLOR_DODGE, "color-dodge" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_COLOR_BURN, "color-burn" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_HARD_LIGHT, "hard-light" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_SOFT_LIGHT, "soft-light" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_DIFFERENCE, "difference" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_EXCLUSION, "exclusion" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_COLOR, "color" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_HUE, "hue" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_SATURATION, "saturation" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_LUMINOSITY, "luminosity" }
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_DEFAULT, "normal" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_MULTIPLY, "multiply" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_SCREEN, "screen" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_OVERLAY, "overlay" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_DARKEN, "darken" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_LIGHTEN, "lighten" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_COLOR_DODGE, "color-dodge" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_COLOR_BURN, "color-burn" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_HARD_LIGHT, "hard-light" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_SOFT_LIGHT, "soft-light" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_DIFFERENCE, "difference" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_EXCLUSION, "exclusion" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_COLOR, "color" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_HUE, "hue" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_SATURATION, "saturation" },
|
||||
{ >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_LUMINOSITY, "luminosity" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -285,6 +287,7 @@ gtk_css_value_font_size_compute (GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_SIZE = {
|
||||
"GtkCssFontSizeValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_font_size_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -295,15 +298,15 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_SIZE = {
|
||||
};
|
||||
|
||||
static GtkCssValue font_size_values[] = {
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_SMALLER, "smaller" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_LARGER, "larger" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_XX_SMALL, "xx-small" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_X_SMALL, "x-small" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_SMALL, "small" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_MEDIUM, "medium" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_LARGE, "large" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_X_LARGE, "x-large" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_XX_LARGE, "xx-large" }
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_SMALLER, "smaller" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_LARGER, "larger" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_XX_SMALL, "xx-small" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_X_SMALL, "x-small" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_SMALL, "small" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_MEDIUM, "medium" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_LARGE, "large" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_X_LARGE, "x-large" },
|
||||
{ >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_XX_LARGE, "xx-large" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -341,6 +344,7 @@ _gtk_css_font_size_value_get (const GtkCssValue *value)
|
||||
/* PangoStyle */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_STYLE = {
|
||||
"GtkCssFontStyleValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -351,9 +355,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_STYLE = {
|
||||
};
|
||||
|
||||
static GtkCssValue font_style_values[] = {
|
||||
{ >K_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_OBLIQUE, "oblique" },
|
||||
{ >K_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_ITALIC, "italic" }
|
||||
{ >K_CSS_VALUE_FONT_STYLE, 1, TRUE, PANGO_STYLE_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_STYLE, 1, TRUE, PANGO_STYLE_OBLIQUE, "oblique" },
|
||||
{ >K_CSS_VALUE_FONT_STYLE, 1, TRUE, PANGO_STYLE_ITALIC, "italic" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -439,6 +443,7 @@ gtk_css_value_font_weight_compute (GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = {
|
||||
"GtkCssFontWeightValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_font_weight_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -449,8 +454,8 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = {
|
||||
};
|
||||
|
||||
static GtkCssValue font_weight_values[] = {
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, BOLDER, "bolder" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, LIGHTER, "lighter" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, FALSE, BOLDER, "bolder" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, FALSE, LIGHTER, "lighter" },
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -488,6 +493,7 @@ gtk_css_font_weight_value_get (const GtkCssValue *value)
|
||||
/* PangoStretch */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_STRETCH = {
|
||||
"GtkCssFontStretchValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -498,15 +504,15 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_STRETCH = {
|
||||
};
|
||||
|
||||
static GtkCssValue font_stretch_values[] = {
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_ULTRA_CONDENSED, "ultra-condensed" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_EXTRA_CONDENSED, "extra-condensed" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_CONDENSED, "condensed" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_SEMI_CONDENSED, "semi-condensed" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_SEMI_EXPANDED, "semi-expanded" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_EXPANDED, "expanded" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_EXTRA_EXPANDED, "extra-expanded" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_ULTRA_EXPANDED, "ultra-expanded" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_ULTRA_CONDENSED, "ultra-condensed" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_EXTRA_CONDENSED, "extra-condensed" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_CONDENSED, "condensed" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_SEMI_CONDENSED, "semi-condensed" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_SEMI_EXPANDED, "semi-expanded" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_EXPANDED, "expanded" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_EXTRA_EXPANDED, "extra-expanded" },
|
||||
{ >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_ULTRA_EXPANDED, "ultra-expanded" },
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -544,6 +550,7 @@ _gtk_css_font_stretch_value_get (const GtkCssValue *value)
|
||||
/* GtkTextDecorationLine */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_TEXT_DECORATION_LINE = {
|
||||
"GtkCssTextDecorationLineValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -554,9 +561,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_TEXT_DECORATION_LINE = {
|
||||
};
|
||||
|
||||
static GtkCssValue text_decoration_line_values[] = {
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_LINE, 1, GTK_CSS_TEXT_DECORATION_LINE_NONE, "none" },
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_LINE, 1, GTK_CSS_TEXT_DECORATION_LINE_UNDERLINE, "underline" },
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_LINE, 1, GTK_CSS_TEXT_DECORATION_LINE_LINE_THROUGH, "line-through" },
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_LINE, 1, TRUE, GTK_CSS_TEXT_DECORATION_LINE_NONE, "none" },
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_LINE, 1, TRUE, GTK_CSS_TEXT_DECORATION_LINE_UNDERLINE, "underline" },
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_LINE, 1, TRUE, GTK_CSS_TEXT_DECORATION_LINE_LINE_THROUGH, "line-through" },
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -594,6 +601,7 @@ _gtk_css_text_decoration_line_value_get (const GtkCssValue *value)
|
||||
/* GtkTextDecorationStyle */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_TEXT_DECORATION_STYLE = {
|
||||
"GtkCssTextDecorationStyleValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -604,9 +612,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_TEXT_DECORATION_STYLE = {
|
||||
};
|
||||
|
||||
static GtkCssValue text_decoration_style_values[] = {
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_STYLE, 1, GTK_CSS_TEXT_DECORATION_STYLE_SOLID, "solid" },
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_STYLE, 1, GTK_CSS_TEXT_DECORATION_STYLE_DOUBLE, "double" },
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_STYLE, 1, GTK_CSS_TEXT_DECORATION_STYLE_WAVY, "wavy" },
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_STYLE, 1, TRUE, GTK_CSS_TEXT_DECORATION_STYLE_SOLID, "solid" },
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_STYLE, 1, TRUE, GTK_CSS_TEXT_DECORATION_STYLE_DOUBLE, "double" },
|
||||
{ >K_CSS_VALUE_TEXT_DECORATION_STYLE, 1, TRUE, GTK_CSS_TEXT_DECORATION_STYLE_WAVY, "wavy" },
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -644,6 +652,7 @@ _gtk_css_text_decoration_style_value_get (const GtkCssValue *value)
|
||||
/* GtkCssArea */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_AREA = {
|
||||
"GtkCssAreaValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -654,9 +663,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_AREA = {
|
||||
};
|
||||
|
||||
static GtkCssValue area_values[] = {
|
||||
{ >K_CSS_VALUE_AREA, 1, GTK_CSS_AREA_BORDER_BOX, "border-box" },
|
||||
{ >K_CSS_VALUE_AREA, 1, GTK_CSS_AREA_PADDING_BOX, "padding-box" },
|
||||
{ >K_CSS_VALUE_AREA, 1, GTK_CSS_AREA_CONTENT_BOX, "content-box" }
|
||||
{ >K_CSS_VALUE_AREA, 1, TRUE, GTK_CSS_AREA_BORDER_BOX, "border-box" },
|
||||
{ >K_CSS_VALUE_AREA, 1, TRUE, GTK_CSS_AREA_PADDING_BOX, "padding-box" },
|
||||
{ >K_CSS_VALUE_AREA, 1, TRUE, GTK_CSS_AREA_CONTENT_BOX, "content-box" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -700,6 +709,7 @@ _gtk_css_area_value_get (const GtkCssValue *value)
|
||||
/* GtkCssDirection */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_DIRECTION = {
|
||||
"GtkCssDirectionValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -710,10 +720,10 @@ static const GtkCssValueClass GTK_CSS_VALUE_DIRECTION = {
|
||||
};
|
||||
|
||||
static GtkCssValue direction_values[] = {
|
||||
{ >K_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_REVERSE, "reverse" },
|
||||
{ >K_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_ALTERNATE, "alternate" },
|
||||
{ >K_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_ALTERNATE_REVERSE, "alternate-reverse" }
|
||||
{ >K_CSS_VALUE_DIRECTION, 1, TRUE, GTK_CSS_DIRECTION_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_DIRECTION, 1, TRUE, GTK_CSS_DIRECTION_REVERSE, "reverse" },
|
||||
{ >K_CSS_VALUE_DIRECTION, 1, TRUE, GTK_CSS_DIRECTION_ALTERNATE, "alternate" },
|
||||
{ >K_CSS_VALUE_DIRECTION, 1, TRUE, GTK_CSS_DIRECTION_ALTERNATE_REVERSE, "alternate-reverse" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -760,6 +770,7 @@ _gtk_css_direction_value_get (const GtkCssValue *value)
|
||||
/* GtkCssPlayState */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_PLAY_STATE = {
|
||||
"GtkCssPlayStateValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -770,8 +781,8 @@ static const GtkCssValueClass GTK_CSS_VALUE_PLAY_STATE = {
|
||||
};
|
||||
|
||||
static GtkCssValue play_state_values[] = {
|
||||
{ >K_CSS_VALUE_PLAY_STATE, 1, GTK_CSS_PLAY_STATE_RUNNING, "running" },
|
||||
{ >K_CSS_VALUE_PLAY_STATE, 1, GTK_CSS_PLAY_STATE_PAUSED, "paused" }
|
||||
{ >K_CSS_VALUE_PLAY_STATE, 1, TRUE, GTK_CSS_PLAY_STATE_RUNNING, "running" },
|
||||
{ >K_CSS_VALUE_PLAY_STATE, 1, TRUE, GTK_CSS_PLAY_STATE_PAUSED, "paused" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -815,6 +826,7 @@ _gtk_css_play_state_value_get (const GtkCssValue *value)
|
||||
/* GtkCssFillMode */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FILL_MODE = {
|
||||
"GtkCssFillModeValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -825,10 +837,10 @@ static const GtkCssValueClass GTK_CSS_VALUE_FILL_MODE = {
|
||||
};
|
||||
|
||||
static GtkCssValue fill_mode_values[] = {
|
||||
{ >K_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_NONE, "none" },
|
||||
{ >K_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_FORWARDS, "forwards" },
|
||||
{ >K_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_BACKWARDS, "backwards" },
|
||||
{ >K_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_BOTH, "both" }
|
||||
{ >K_CSS_VALUE_FILL_MODE, 1, TRUE, GTK_CSS_FILL_NONE, "none" },
|
||||
{ >K_CSS_VALUE_FILL_MODE, 1, TRUE, GTK_CSS_FILL_FORWARDS, "forwards" },
|
||||
{ >K_CSS_VALUE_FILL_MODE, 1, TRUE, GTK_CSS_FILL_BACKWARDS, "backwards" },
|
||||
{ >K_CSS_VALUE_FILL_MODE, 1, TRUE, GTK_CSS_FILL_BOTH, "both" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -872,6 +884,7 @@ _gtk_css_fill_mode_value_get (const GtkCssValue *value)
|
||||
/* GtkCssIconStyle */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_ICON_STYLE = {
|
||||
"GtkCssIconStyleValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -882,9 +895,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_ICON_STYLE = {
|
||||
};
|
||||
|
||||
static GtkCssValue icon_style_values[] = {
|
||||
{ >K_CSS_VALUE_ICON_STYLE, 1, GTK_CSS_ICON_STYLE_REQUESTED, "requested" },
|
||||
{ >K_CSS_VALUE_ICON_STYLE, 1, GTK_CSS_ICON_STYLE_REGULAR, "regular" },
|
||||
{ >K_CSS_VALUE_ICON_STYLE, 1, GTK_CSS_ICON_STYLE_SYMBOLIC, "symbolic" }
|
||||
{ >K_CSS_VALUE_ICON_STYLE, 1, TRUE, GTK_CSS_ICON_STYLE_REQUESTED, "requested" },
|
||||
{ >K_CSS_VALUE_ICON_STYLE, 1, TRUE, GTK_CSS_ICON_STYLE_REGULAR, "regular" },
|
||||
{ >K_CSS_VALUE_ICON_STYLE, 1, TRUE, GTK_CSS_ICON_STYLE_SYMBOLIC, "symbolic" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -928,6 +941,7 @@ _gtk_css_icon_style_value_get (const GtkCssValue *value)
|
||||
/* GtkCssFontKerning */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_KERNING = {
|
||||
"GtkCssFontKerningValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -938,9 +952,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_KERNING = {
|
||||
};
|
||||
|
||||
static GtkCssValue font_kerning_values[] = {
|
||||
{ >K_CSS_VALUE_FONT_KERNING, 1, GTK_CSS_FONT_KERNING_AUTO, "auto" },
|
||||
{ >K_CSS_VALUE_FONT_KERNING, 1, GTK_CSS_FONT_KERNING_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_KERNING, 1, GTK_CSS_FONT_KERNING_NONE, "none" }
|
||||
{ >K_CSS_VALUE_FONT_KERNING, 1, TRUE, GTK_CSS_FONT_KERNING_AUTO, "auto" },
|
||||
{ >K_CSS_VALUE_FONT_KERNING, 1, TRUE, GTK_CSS_FONT_KERNING_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_KERNING, 1, TRUE, GTK_CSS_FONT_KERNING_NONE, "none" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -984,6 +998,7 @@ _gtk_css_font_kerning_value_get (const GtkCssValue *value)
|
||||
/* GtkCssFontVariantPos */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_POSITION = {
|
||||
"GtkCssFontVariationPositionValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -994,9 +1009,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_POSITION = {
|
||||
};
|
||||
|
||||
static GtkCssValue font_variant_position_values[] = {
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, GTK_CSS_FONT_VARIANT_POSITION_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, GTK_CSS_FONT_VARIANT_POSITION_SUB, "sub" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, GTK_CSS_FONT_VARIANT_POSITION_SUPER, "super" }
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, TRUE, GTK_CSS_FONT_VARIANT_POSITION_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, TRUE, GTK_CSS_FONT_VARIANT_POSITION_SUB, "sub" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, TRUE, GTK_CSS_FONT_VARIANT_POSITION_SUPER, "super" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -1040,6 +1055,7 @@ _gtk_css_font_variant_position_value_get (const GtkCssValue *value)
|
||||
/* GtkCssFontVariantCaps */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_CAPS = {
|
||||
"GtkCssFontVariantCapsValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -1050,13 +1066,13 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_CAPS = {
|
||||
};
|
||||
|
||||
static GtkCssValue font_variant_caps_values[] = {
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_SMALL_CAPS, "small-caps" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_ALL_SMALL_CAPS, "all-small-caps" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_PETITE_CAPS, "petite-caps" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_ALL_PETITE_CAPS, "all-petite-caps" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_UNICASE, "unicase" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_TITLING_CAPS, "titling-caps" }
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_SMALL_CAPS, "small-caps" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_ALL_SMALL_CAPS, "all-small-caps" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_PETITE_CAPS, "petite-caps" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_ALL_PETITE_CAPS, "all-petite-caps" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_UNICASE, "unicase" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_TITLING_CAPS, "titling-caps" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -1100,6 +1116,7 @@ _gtk_css_font_variant_caps_value_get (const GtkCssValue *value)
|
||||
/* GtkCssFontVariantAlternate */
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_ALTERNATE = {
|
||||
"GtkCssFontVariantAlternateValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
@@ -1110,8 +1127,8 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_ALTERNATE = {
|
||||
};
|
||||
|
||||
static GtkCssValue font_variant_alternate_values[] = {
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, GTK_CSS_FONT_VARIANT_ALTERNATE_HISTORICAL_FORMS, "historical-forms" }
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, TRUE, GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, TRUE, GTK_CSS_FONT_VARIANT_ALTERNATE_HISTORICAL_FORMS, "historical-forms" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
@@ -1213,6 +1230,7 @@ gtk_css_font_variant_ligature_value_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_LIGATURE = {
|
||||
"GtkCssFontVariantLigatureValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_flags_equal,
|
||||
@@ -1253,6 +1271,7 @@ _gtk_css_font_variant_ligature_value_new (GtkCssFontVariantLigature ligatures)
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_FONT_VARIANT_LIGATURE);
|
||||
value->value = ligatures;
|
||||
value->name = NULL;
|
||||
value->is_computed = TRUE;
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -1319,6 +1338,7 @@ gtk_css_font_variant_numeric_value_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_NUMERIC = {
|
||||
"GtkCssFontVariantNumbericValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_flags_equal,
|
||||
@@ -1355,6 +1375,7 @@ _gtk_css_font_variant_numeric_value_new (GtkCssFontVariantNumeric numeric)
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_FONT_VARIANT_NUMERIC);
|
||||
value->value = numeric;
|
||||
value->name = NULL;
|
||||
value->is_computed = TRUE;
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -1422,6 +1443,7 @@ gtk_css_font_variant_east_asian_value_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_EAST_ASIAN = {
|
||||
"GtkCssFontVariantEastAsianValue",
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_enum_compute,
|
||||
gtk_css_value_flags_equal,
|
||||
@@ -1497,6 +1519,7 @@ _gtk_css_font_variant_east_asian_value_new (GtkCssFontVariantEastAsian east_asia
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_FONT_VARIANT_EAST_ASIAN);
|
||||
value->value = east_asian;
|
||||
value->name = NULL;
|
||||
value->is_computed = TRUE;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@@ -693,6 +693,7 @@ gtk_css_value_filter_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FILTER = {
|
||||
"GtkCssFilterValue",
|
||||
gtk_css_value_filter_free,
|
||||
gtk_css_value_filter_compute,
|
||||
gtk_css_value_filter_equal,
|
||||
@@ -702,7 +703,7 @@ static const GtkCssValueClass GTK_CSS_VALUE_FILTER = {
|
||||
gtk_css_value_filter_print
|
||||
};
|
||||
|
||||
static GtkCssValue none_singleton = { >K_CSS_VALUE_FILTER, 1, 0, { { GTK_CSS_FILTER_NONE } } };
|
||||
static GtkCssValue none_singleton = { >K_CSS_VALUE_FILTER, 1, TRUE, 0, { { GTK_CSS_FILTER_NONE } } };
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_filter_value_alloc (guint n_filters)
|
||||
@@ -777,6 +778,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
GtkCssValue *value;
|
||||
GArray *array;
|
||||
guint i;
|
||||
gboolean computed = TRUE;
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "none"))
|
||||
return gtk_css_filter_value_new_none ();
|
||||
@@ -793,6 +795,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_BLUR;
|
||||
computed = computed && gtk_css_value_is_computed (filter.blur.value);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "brightness"))
|
||||
{
|
||||
@@ -800,6 +803,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_BRIGHTNESS;
|
||||
computed = computed && gtk_css_value_is_computed (filter.brightness.value);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "contrast"))
|
||||
{
|
||||
@@ -807,6 +811,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_CONTRAST;
|
||||
computed = computed && gtk_css_value_is_computed (filter.contrast.value);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "grayscale"))
|
||||
{
|
||||
@@ -814,13 +819,15 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_GRAYSCALE;
|
||||
computed = computed && gtk_css_value_is_computed (filter.grayscale.value);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "hue-rotate"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_angle, &filter.blur.value))
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_angle, &filter.hue_rotate.value))
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_HUE_ROTATE;
|
||||
computed = computed && gtk_css_value_is_computed (filter.hue_rotate.value);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "invert"))
|
||||
{
|
||||
@@ -828,6 +835,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_INVERT;
|
||||
computed = computed && gtk_css_value_is_computed (filter.invert.value);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "opacity"))
|
||||
{
|
||||
@@ -835,6 +843,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_OPACITY;
|
||||
computed = computed && gtk_css_value_is_computed (filter.opacity.value);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "saturate"))
|
||||
{
|
||||
@@ -842,6 +851,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_SATURATE;
|
||||
computed = computed && gtk_css_value_is_computed (filter.saturate.value);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "sepia"))
|
||||
{
|
||||
@@ -849,6 +859,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_SEPIA;
|
||||
computed = computed && gtk_css_value_is_computed (filter.sepia.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -866,6 +877,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
|
||||
value = gtk_css_filter_value_alloc (array->len);
|
||||
memcpy (value->filters, array->data, sizeof (GtkCssFilter) * array->len);
|
||||
value->is_computed = computed;
|
||||
|
||||
g_array_free (array, TRUE);
|
||||
|
||||
|
@@ -154,6 +154,7 @@ gtk_css_value_font_features_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_FEATURES = {
|
||||
"GtkCssFontFeaturesValue",
|
||||
gtk_css_value_font_features_free,
|
||||
gtk_css_value_font_features_compute,
|
||||
gtk_css_value_font_features_equal,
|
||||
@@ -172,6 +173,7 @@ gtk_css_font_features_value_new_empty (void)
|
||||
result->features = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify) _gtk_css_value_unref);
|
||||
result->is_computed = TRUE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -154,6 +154,7 @@ gtk_css_value_font_variations_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIATIONS = {
|
||||
"GtkCssFontVariationsValue",
|
||||
gtk_css_value_font_variations_free,
|
||||
gtk_css_value_font_variations_compute,
|
||||
gtk_css_value_font_variations_equal,
|
||||
@@ -172,6 +173,7 @@ gtk_css_font_variations_value_new_empty (void)
|
||||
result->axes = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify) _gtk_css_value_unref);
|
||||
result->is_computed = TRUE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -111,6 +111,7 @@ gtk_css_value_icon_theme_print (const GtkCssValue *icon_theme,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_ICON_THEME = {
|
||||
"GtkCssIconThemeValue",
|
||||
gtk_css_value_icon_theme_free,
|
||||
gtk_css_value_icon_theme_compute,
|
||||
gtk_css_value_icon_theme_equal,
|
||||
@@ -120,7 +121,7 @@ static const GtkCssValueClass GTK_CSS_VALUE_ICON_THEME = {
|
||||
gtk_css_value_icon_theme_print
|
||||
};
|
||||
|
||||
static GtkCssValue default_icon_theme_value = { >K_CSS_VALUE_ICON_THEME, 1, NULL, 0 };
|
||||
static GtkCssValue default_icon_theme_value = { >K_CSS_VALUE_ICON_THEME, 1, FALSE, NULL, 0 };
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_icon_theme_value_new (GtkIconTheme *icontheme)
|
||||
|
@@ -115,6 +115,12 @@ gtk_css_image_real_get_dynamic_image (GtkCssImage *image,
|
||||
return g_object_ref (image);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_real_is_computed (GtkCssImage *image)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_class_init (GtkCssImageClass *klass)
|
||||
{
|
||||
@@ -127,6 +133,7 @@ _gtk_css_image_class_init (GtkCssImageClass *klass)
|
||||
klass->is_invalid = gtk_css_image_real_is_invalid;
|
||||
klass->is_dynamic = gtk_css_image_real_is_dynamic;
|
||||
klass->get_dynamic_image = gtk_css_image_real_get_dynamic_image;
|
||||
klass->is_computed = gtk_css_image_real_is_computed;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -333,6 +340,17 @@ _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
|
||||
*/
|
||||
@@ -565,3 +583,10 @@ _gtk_css_image_new_parse (GtkCssParser *parser)
|
||||
return image;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_image_is_computed (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageClass *klass = GTK_CSS_IMAGE_GET_CLASS (image);
|
||||
|
||||
return klass->is_computed (image);
|
||||
}
|
||||
|
@@ -414,6 +414,22 @@ gtk_css_image_cross_fade_dispose (GObject *object)
|
||||
G_OBJECT_CLASS (gtk_css_image_cross_fade_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_cross_fade_is_computed (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < cross_fade->images->len; i++)
|
||||
{
|
||||
const CrossFadeEntry *entry = &g_array_index (cross_fade->images, CrossFadeEntry, i);
|
||||
if (!gtk_css_image_is_computed (entry->image))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_cross_fade_class_init (GtkCssImageCrossFadeClass *klass)
|
||||
{
|
||||
@@ -429,6 +445,7 @@ gtk_css_image_cross_fade_class_init (GtkCssImageCrossFadeClass *klass)
|
||||
image_class->get_dynamic_image = gtk_css_image_cross_fade_get_dynamic_image;
|
||||
image_class->parse = gtk_css_image_cross_fade_parse;
|
||||
image_class->print = gtk_css_image_cross_fade_print;
|
||||
image_class->is_computed = gtk_css_image_cross_fade_is_computed;
|
||||
|
||||
object_class->dispose = gtk_css_image_cross_fade_dispose;
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "gtkcssimagefallbackprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
|
||||
#include "gtkstyleproviderprivate.h"
|
||||
|
||||
@@ -70,15 +70,18 @@ gtk_css_image_fallback_snapshot (GtkCssImage *image,
|
||||
|
||||
if (fallback->used < 0)
|
||||
{
|
||||
GdkRGBA red = { 1, 0, 0, 1 };
|
||||
const GdkRGBA *color;
|
||||
|
||||
if (fallback->color)
|
||||
color = _gtk_css_rgba_value_get_rgba (fallback->color);
|
||||
{
|
||||
const GdkRGBA *color = gtk_css_color_value_get_rgba (fallback->color);
|
||||
if (!gdk_rgba_is_clear (color))
|
||||
gtk_snapshot_append_color (snapshot, color,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
}
|
||||
else
|
||||
color = &red;
|
||||
|
||||
gtk_snapshot_append_color (snapshot, color, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
{
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) {1, 0, 0, 1},
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
}
|
||||
}
|
||||
else
|
||||
gtk_css_image_snapshot (fallback->images[fallback->used], snapshot, width, height);
|
||||
@@ -142,6 +145,20 @@ gtk_css_image_fallback_compute (GtkCssImage *image,
|
||||
|
||||
if (fallback->used < 0)
|
||||
{
|
||||
GtkCssValue *computed_color = NULL;
|
||||
|
||||
if (fallback->color)
|
||||
computed_color= _gtk_css_value_compute (fallback->color,
|
||||
property_id,
|
||||
provider,
|
||||
style,
|
||||
parent_style);
|
||||
|
||||
/* image($color) that didn't change */
|
||||
if (computed_color && !fallback->images &&
|
||||
computed_color == fallback->color)
|
||||
return g_object_ref (image);
|
||||
|
||||
copy = g_object_new (_gtk_css_image_fallback_get_type (), NULL);
|
||||
copy->n_images = fallback->n_images;
|
||||
copy->images = g_new (GtkCssImage *, fallback->n_images);
|
||||
@@ -160,14 +177,7 @@ gtk_css_image_fallback_compute (GtkCssImage *image,
|
||||
copy->used = i;
|
||||
}
|
||||
|
||||
if (fallback->color)
|
||||
copy->color = _gtk_css_value_compute (fallback->color,
|
||||
property_id,
|
||||
provider,
|
||||
style,
|
||||
parent_style);
|
||||
else
|
||||
copy->color = NULL;
|
||||
copy->color = computed_color;
|
||||
|
||||
return GTK_CSS_IMAGE (copy);
|
||||
}
|
||||
@@ -263,6 +273,30 @@ gtk_css_image_fallback_equal (GtkCssImage *image1,
|
||||
fallback2->images[fallback2->used]);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_fallback_is_computed (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageFallback *fallback = GTK_CSS_IMAGE_FALLBACK (image);
|
||||
|
||||
if (fallback->used < 0)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (fallback->color && !fallback->images)
|
||||
return gtk_css_value_is_computed (fallback->color);
|
||||
|
||||
for (i = 0; i < fallback->n_images; i++)
|
||||
{
|
||||
if (!gtk_css_image_is_computed (fallback->images[i]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_fallback_class_init (GtkCssImageFallbackClass *klass)
|
||||
{
|
||||
@@ -277,6 +311,7 @@ _gtk_css_image_fallback_class_init (GtkCssImageFallbackClass *klass)
|
||||
image_class->compute = gtk_css_image_fallback_compute;
|
||||
image_class->print = gtk_css_image_fallback_print;
|
||||
image_class->equal = gtk_css_image_fallback_equal;
|
||||
image_class->is_computed = gtk_css_image_fallback_is_computed;
|
||||
|
||||
object_class->dispose = gtk_css_image_fallback_dispose;
|
||||
}
|
||||
|
@@ -24,7 +24,6 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "gtkcssiconthemevalueprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtksettingsprivate.h"
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtkstyleproviderprivate.h"
|
||||
@@ -95,21 +94,22 @@ 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);
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssprovider.h"
|
||||
|
||||
G_DEFINE_TYPE (GtkCssImageLinear, _gtk_css_image_linear, GTK_TYPE_CSS_IMAGE)
|
||||
@@ -36,13 +36,13 @@ gtk_css_image_linear_get_repeating_start_end (GtkCssImageLinear *linear,
|
||||
double *start,
|
||||
double *end)
|
||||
{
|
||||
GtkCssImageLinearColorStop *stop;
|
||||
const GtkCssImageLinearColorStop *stop;
|
||||
double pos;
|
||||
guint i;
|
||||
|
||||
g_assert (linear->repeating);
|
||||
|
||||
stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, 0);
|
||||
stop = &linear->color_stops[0];
|
||||
if (stop->offset == NULL)
|
||||
*start = 0;
|
||||
else
|
||||
@@ -50,9 +50,9 @@ gtk_css_image_linear_get_repeating_start_end (GtkCssImageLinear *linear,
|
||||
|
||||
*end = *start;
|
||||
|
||||
for (i = 0; i < linear->stops->len; i++)
|
||||
for (i = 0; i < linear->n_stops; i++)
|
||||
{
|
||||
stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);
|
||||
stop = &linear->color_stops[i];
|
||||
|
||||
if (stop->offset == NULL)
|
||||
continue;
|
||||
@@ -190,11 +190,10 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
|
||||
{
|
||||
/* repeating gradients with all color stops sharing the same offset
|
||||
* get the color of the last color stop */
|
||||
GtkCssImageLinearColorStop *stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop,
|
||||
linear->stops->len - 1);
|
||||
const GtkCssImageLinearColorStop *stop = &linear->color_stops[linear->n_stops - 1];
|
||||
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
_gtk_css_rgba_value_get_rgba (stop->color),
|
||||
gtk_css_color_value_get_rgba (stop->color),
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
return;
|
||||
}
|
||||
@@ -207,20 +206,18 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
|
||||
|
||||
offset = start;
|
||||
last = -1;
|
||||
stops = g_newa (GskColorStop, linear->stops->len);
|
||||
stops = g_newa (GskColorStop, linear->n_stops);
|
||||
|
||||
for (i = 0; i < linear->stops->len; i++)
|
||||
for (i = 0; i < linear->n_stops; i++)
|
||||
{
|
||||
GtkCssImageLinearColorStop *stop;
|
||||
const GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
|
||||
double pos, step;
|
||||
|
||||
stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);
|
||||
|
||||
if (stop->offset == NULL)
|
||||
{
|
||||
if (i == 0)
|
||||
pos = 0.0;
|
||||
else if (i + 1 == linear->stops->len)
|
||||
else if (i + 1 == linear->n_stops)
|
||||
pos = 1.0;
|
||||
else
|
||||
continue;
|
||||
@@ -235,12 +232,12 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
|
||||
step = (pos - offset) / (i - last);
|
||||
for (last = last + 1; last <= i; last++)
|
||||
{
|
||||
stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, last);
|
||||
stop = &linear->color_stops[last];
|
||||
|
||||
offset += step;
|
||||
|
||||
stops[last].offset = (offset - start) / (end - start);
|
||||
stops[last].color = *_gtk_css_rgba_value_get_rgba (stop->color);
|
||||
stops[last].color = *gtk_css_color_value_get_rgba (stop->color);
|
||||
}
|
||||
|
||||
offset = pos;
|
||||
@@ -255,7 +252,7 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
|
||||
&GRAPHENE_POINT_INIT (width / 2 + x * (start - 0.5), height / 2 + y * (start - 0.5)),
|
||||
&GRAPHENE_POINT_INIT (width / 2 + x * (end - 0.5), height / 2 + y * (end - 0.5)),
|
||||
stops,
|
||||
linear->stops->len);
|
||||
linear->n_stops);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -265,13 +262,14 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
|
||||
&GRAPHENE_POINT_INIT (width / 2 + x * (start - 0.5), height / 2 + y * (start - 0.5)),
|
||||
&GRAPHENE_POINT_INIT (width / 2 + x * (end - 0.5), height / 2 + y * (end - 0.5)),
|
||||
stops,
|
||||
linear->stops->len);
|
||||
linear->n_stops);
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_image_linear_parse_color_stop (GtkCssImageLinear *self,
|
||||
GtkCssParser *parser)
|
||||
GtkCssParser *parser,
|
||||
GArray *stop_array)
|
||||
{
|
||||
GtkCssImageLinearColorStop stop;
|
||||
|
||||
@@ -295,14 +293,15 @@ gtk_css_image_linear_parse_color_stop (GtkCssImageLinear *self,
|
||||
stop.offset = NULL;
|
||||
}
|
||||
|
||||
g_array_append_val (self->stops, stop);
|
||||
g_array_append_val (stop_array, stop);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_image_linear_parse_first_arg (GtkCssImageLinear *linear,
|
||||
GtkCssParser *parser)
|
||||
GtkCssParser *parser,
|
||||
GArray *stop_array)
|
||||
{
|
||||
guint i;
|
||||
|
||||
@@ -363,31 +362,37 @@ gtk_css_image_linear_parse_first_arg (GtkCssImageLinear *linear,
|
||||
linear->angle = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (linear->angle == NULL)
|
||||
return 0;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
linear->side = 1 << GTK_CSS_BOTTOM;
|
||||
if (!gtk_css_image_linear_parse_color_stop (linear, parser))
|
||||
if (!gtk_css_image_linear_parse_color_stop (linear, parser, stop_array))
|
||||
return 0;
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkCssImageLinear *self;
|
||||
GArray *stop_array;
|
||||
} ParseData;
|
||||
|
||||
static guint
|
||||
gtk_css_image_linear_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkCssImageLinear *self = data;
|
||||
ParseData *parse_data = user_data;
|
||||
GtkCssImageLinear *self = parse_data->self;
|
||||
|
||||
if (arg == 0)
|
||||
return gtk_css_image_linear_parse_first_arg (self, parser);
|
||||
return gtk_css_image_linear_parse_first_arg (self, parser, parse_data->stop_array);
|
||||
else
|
||||
return gtk_css_image_linear_parse_color_stop (self, parser);
|
||||
|
||||
return gtk_css_image_linear_parse_color_stop (self, parser, parse_data->stop_array);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -395,6 +400,8 @@ gtk_css_image_linear_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageLinear *self = GTK_CSS_IMAGE_LINEAR (image);
|
||||
ParseData parse_data;
|
||||
gboolean success;
|
||||
|
||||
if (gtk_css_parser_has_function (parser, "repeating-linear-gradient"))
|
||||
self->repeating = TRUE;
|
||||
@@ -406,7 +413,22 @@ gtk_css_image_linear_parse (GtkCssImage *image,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return gtk_css_parser_consume_function (parser, 3, G_MAXUINT, gtk_css_image_linear_parse_arg, self);
|
||||
parse_data.self = self;
|
||||
parse_data.stop_array = g_array_new (TRUE, FALSE, sizeof (GtkCssImageLinearColorStop));
|
||||
|
||||
success = gtk_css_parser_consume_function (parser, 3, G_MAXUINT, gtk_css_image_linear_parse_arg, &parse_data);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
g_array_free (parse_data.stop_array, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->n_stops = parse_data.stop_array->len;
|
||||
self->color_stops = (GtkCssImageLinearColorStop *)g_array_free (parse_data.stop_array, FALSE);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -446,15 +468,13 @@ gtk_css_image_linear_print (GtkCssImage *image,
|
||||
g_string_append (string, ", ");
|
||||
}
|
||||
|
||||
for (i = 0; i < linear->stops->len; i++)
|
||||
for (i = 0; i < linear->n_stops; i++)
|
||||
{
|
||||
GtkCssImageLinearColorStop *stop;
|
||||
|
||||
const GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
|
||||
|
||||
if (i > 0)
|
||||
g_string_append (string, ", ");
|
||||
|
||||
stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);
|
||||
|
||||
_gtk_css_value_print (stop->color, string);
|
||||
|
||||
if (stop->offset)
|
||||
@@ -463,7 +483,7 @@ gtk_css_image_linear_print (GtkCssImage *image,
|
||||
_gtk_css_value_print (stop->offset, string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
g_string_append (string, ")");
|
||||
}
|
||||
|
||||
@@ -484,17 +504,16 @@ gtk_css_image_linear_compute (GtkCssImage *image,
|
||||
|
||||
if (linear->angle)
|
||||
copy->angle = _gtk_css_value_compute (linear->angle, property_id, provider, style, parent_style);
|
||||
|
||||
g_array_set_size (copy->stops, linear->stops->len);
|
||||
for (i = 0; i < linear->stops->len; i++)
|
||||
{
|
||||
GtkCssImageLinearColorStop *stop, *scopy;
|
||||
|
||||
stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);
|
||||
scopy = &g_array_index (copy->stops, GtkCssImageLinearColorStop, i);
|
||||
|
||||
copy->n_stops = linear->n_stops;
|
||||
copy->color_stops = g_malloc (sizeof (GtkCssImageLinearColorStop) * copy->n_stops);
|
||||
for (i = 0; i < linear->n_stops; i++)
|
||||
{
|
||||
const GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
|
||||
GtkCssImageLinearColorStop *scopy = ©->color_stops[i];
|
||||
|
||||
scopy->color = _gtk_css_value_compute (stop->color, property_id, provider, style, parent_style);
|
||||
|
||||
|
||||
if (stop->offset)
|
||||
{
|
||||
scopy->offset = _gtk_css_value_compute (stop->offset, property_id, provider, style, parent_style);
|
||||
@@ -528,7 +547,7 @@ gtk_css_image_linear_transition (GtkCssImage *start_image,
|
||||
end = GTK_CSS_IMAGE_LINEAR (end_image);
|
||||
|
||||
if ((start->repeating != end->repeating)
|
||||
|| (start->stops->len != end->stops->len))
|
||||
|| (start->n_stops != end->n_stops))
|
||||
return GTK_CSS_IMAGE_CLASS (_gtk_css_image_linear_parent_class)->transition (start_image, end_image, property_id, progress);
|
||||
|
||||
result = g_object_new (GTK_TYPE_CSS_IMAGE_LINEAR, NULL);
|
||||
@@ -542,43 +561,45 @@ gtk_css_image_linear_transition (GtkCssImage *start_image,
|
||||
result->angle = _gtk_css_value_transition (start->angle, end->angle, property_id, progress);
|
||||
if (result->angle == NULL)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < start->stops->len; i++)
|
||||
{
|
||||
GtkCssImageLinearColorStop stop, *start_stop, *end_stop;
|
||||
|
||||
start_stop = &g_array_index (start->stops, GtkCssImageLinearColorStop, i);
|
||||
end_stop = &g_array_index (end->stops, GtkCssImageLinearColorStop, i);
|
||||
/* Maximum amountof stops */
|
||||
result->color_stops = g_malloc (sizeof (GtkCssImageLinearColorStop) * start->n_stops);
|
||||
result->n_stops = 0;
|
||||
for (i = 0; i < start->n_stops; i++)
|
||||
{
|
||||
const GtkCssImageLinearColorStop *start_stop = &start->color_stops[i];
|
||||
const GtkCssImageLinearColorStop *end_stop = &end->color_stops[i];
|
||||
GtkCssImageLinearColorStop *stop = &result->color_stops[i];
|
||||
|
||||
if ((start_stop->offset != NULL) != (end_stop->offset != NULL))
|
||||
goto fail;
|
||||
|
||||
if (start_stop->offset == NULL)
|
||||
{
|
||||
stop.offset = NULL;
|
||||
stop->offset = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stop.offset = _gtk_css_value_transition (start_stop->offset,
|
||||
end_stop->offset,
|
||||
property_id,
|
||||
progress);
|
||||
if (stop.offset == NULL)
|
||||
stop->offset = _gtk_css_value_transition (start_stop->offset,
|
||||
end_stop->offset,
|
||||
property_id,
|
||||
progress);
|
||||
if (stop->offset == NULL)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
stop.color = _gtk_css_value_transition (start_stop->color,
|
||||
end_stop->color,
|
||||
property_id,
|
||||
progress);
|
||||
if (stop.color == NULL)
|
||||
stop->color = _gtk_css_value_transition (start_stop->color,
|
||||
end_stop->color,
|
||||
property_id,
|
||||
progress);
|
||||
if (stop->color == NULL)
|
||||
{
|
||||
if (stop.offset)
|
||||
_gtk_css_value_unref (stop.offset);
|
||||
if (stop->offset)
|
||||
_gtk_css_value_unref (stop->offset);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
g_array_append_val (result->stops, stop);
|
||||
result->n_stops ++;
|
||||
}
|
||||
|
||||
return GTK_CSS_IMAGE (result);
|
||||
@@ -599,15 +620,13 @@ gtk_css_image_linear_equal (GtkCssImage *image1,
|
||||
if (linear1->repeating != linear2->repeating ||
|
||||
linear1->side != linear2->side ||
|
||||
(linear1->side == 0 && !_gtk_css_value_equal (linear1->angle, linear2->angle)) ||
|
||||
linear1->stops->len != linear2->stops->len)
|
||||
linear1->n_stops != linear2->n_stops)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < linear1->stops->len; i++)
|
||||
for (i = 0; i < linear1->n_stops; i++)
|
||||
{
|
||||
GtkCssImageLinearColorStop *stop1, *stop2;
|
||||
|
||||
stop1 = &g_array_index (linear1->stops, GtkCssImageLinearColorStop, i);
|
||||
stop2 = &g_array_index (linear2->stops, GtkCssImageLinearColorStop, i);
|
||||
const GtkCssImageLinearColorStop *stop1 = &linear1->color_stops[i];
|
||||
const GtkCssImageLinearColorStop *stop2 = &linear2->color_stops[i];
|
||||
|
||||
if (!_gtk_css_value_equal0 (stop1->offset, stop2->offset) ||
|
||||
!_gtk_css_value_equal (stop1->color, stop2->color))
|
||||
@@ -621,12 +640,17 @@ static void
|
||||
gtk_css_image_linear_dispose (GObject *object)
|
||||
{
|
||||
GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (object);
|
||||
guint i;
|
||||
|
||||
if (linear->stops)
|
||||
for (i = 0; i < linear->n_stops; i ++)
|
||||
{
|
||||
g_array_free (linear->stops, TRUE);
|
||||
linear->stops = NULL;
|
||||
GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
|
||||
|
||||
_gtk_css_value_unref (stop->color);
|
||||
if (stop->offset)
|
||||
_gtk_css_value_unref (stop->offset);
|
||||
}
|
||||
g_free (linear->color_stops);
|
||||
|
||||
linear->side = 0;
|
||||
if (linear->angle)
|
||||
@@ -638,6 +662,35 @@ gtk_css_image_linear_dispose (GObject *object)
|
||||
G_OBJECT_CLASS (_gtk_css_image_linear_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_linear_is_computed (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (image);
|
||||
guint i;
|
||||
gboolean computed = TRUE;
|
||||
|
||||
computed = !linear->angle || gtk_css_value_is_computed (linear->angle);
|
||||
|
||||
for (i = 0; i < linear->n_stops; i ++)
|
||||
{
|
||||
const GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
|
||||
|
||||
if (stop->offset && !gtk_css_value_is_computed (stop->offset))
|
||||
{
|
||||
computed = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gtk_css_value_is_computed (stop->color))
|
||||
{
|
||||
computed = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return computed;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_linear_class_init (GtkCssImageLinearClass *klass)
|
||||
{
|
||||
@@ -650,24 +703,13 @@ _gtk_css_image_linear_class_init (GtkCssImageLinearClass *klass)
|
||||
image_class->compute = gtk_css_image_linear_compute;
|
||||
image_class->equal = gtk_css_image_linear_equal;
|
||||
image_class->transition = gtk_css_image_linear_transition;
|
||||
image_class->is_computed = gtk_css_image_linear_is_computed;
|
||||
|
||||
object_class->dispose = gtk_css_image_linear_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_clear_color_stop (gpointer color_stop)
|
||||
{
|
||||
GtkCssImageLinearColorStop *stop = color_stop;
|
||||
|
||||
_gtk_css_value_unref (stop->color);
|
||||
if (stop->offset)
|
||||
_gtk_css_value_unref (stop->offset);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_linear_init (GtkCssImageLinear *linear)
|
||||
{
|
||||
linear->stops = g_array_new (FALSE, FALSE, sizeof (GtkCssImageLinearColorStop));
|
||||
g_array_set_clear_func (linear->stops, gtk_css_image_clear_color_stop);
|
||||
}
|
||||
|
||||
|
@@ -45,10 +45,12 @@ struct _GtkCssImageLinear
|
||||
{
|
||||
GtkCssImage parent;
|
||||
|
||||
guint side; /* side the gradient should go to or 0 for angle */
|
||||
GtkCssValue *angle;
|
||||
GArray *stops;
|
||||
guint side; /* side the gradient should go to or 0 for angle */
|
||||
guint repeating :1;
|
||||
GtkCssValue *angle;
|
||||
|
||||
guint n_stops;
|
||||
GtkCssImageLinearColorStop *color_stops;
|
||||
};
|
||||
|
||||
struct _GtkCssImageLinearClass
|
||||
|
@@ -150,6 +150,14 @@ 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)
|
||||
{
|
||||
@@ -164,6 +172,7 @@ 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;
|
||||
|
@@ -89,6 +89,7 @@ struct _GtkCssImageClass
|
||||
/* print to CSS */
|
||||
void (* print) (GtkCssImage *image,
|
||||
GString *string);
|
||||
gboolean (* is_computed) (GtkCssImage *image);
|
||||
};
|
||||
|
||||
GType _gtk_css_image_get_type (void) G_GNUC_CONST;
|
||||
@@ -96,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);
|
||||
int _gtk_css_image_get_height (GtkCssImage *image);
|
||||
double _gtk_css_image_get_aspect_ratio (GtkCssImage *image);
|
||||
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;
|
||||
|
||||
GtkCssImage * _gtk_css_image_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
@@ -106,7 +107,7 @@ GtkCssImage * _gtk_css_image_compute (GtkCssImage *
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style);
|
||||
gboolean _gtk_css_image_equal (GtkCssImage *image1,
|
||||
GtkCssImage *image2);
|
||||
GtkCssImage *image2) G_GNUC_PURE;
|
||||
GtkCssImage * _gtk_css_image_transition (GtkCssImage *start,
|
||||
GtkCssImage *end,
|
||||
guint property_id,
|
||||
@@ -120,12 +121,13 @@ void gtk_css_image_snapshot (GtkCssImage *
|
||||
GtkSnapshot *snapshot,
|
||||
double width,
|
||||
double height);
|
||||
gboolean gtk_css_image_is_invalid (GtkCssImage *image);
|
||||
gboolean gtk_css_image_is_dynamic (GtkCssImage *image);
|
||||
gboolean gtk_css_image_is_invalid (GtkCssImage *image) G_GNUC_PURE;
|
||||
gboolean gtk_css_image_is_dynamic (GtkCssImage *image) G_GNUC_PURE;
|
||||
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,
|
||||
@@ -139,6 +141,8 @@ cairo_surface_t *
|
||||
cairo_surface_t *target,
|
||||
int surface_width,
|
||||
int surface_height);
|
||||
gboolean gtk_css_image_is_computed (GtkCssImage *image) G_GNUC_PURE;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcsspositionvalueprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssprovider.h"
|
||||
|
||||
G_DEFINE_TYPE (GtkCssImageRadial, _gtk_css_image_radial, GTK_TYPE_CSS_IMAGE)
|
||||
@@ -37,13 +37,13 @@ gtk_css_image_radial_get_start_end (GtkCssImageRadial *radial,
|
||||
double *start,
|
||||
double *end)
|
||||
{
|
||||
GtkCssImageRadialColorStop *stop;
|
||||
const GtkCssImageRadialColorStop *stop;
|
||||
double pos;
|
||||
guint i;
|
||||
|
||||
if (radial->repeating)
|
||||
{
|
||||
stop = &g_array_index (radial->stops, GtkCssImageRadialColorStop, 0);
|
||||
stop = &radial->color_stops[0];
|
||||
if (stop->offset == NULL)
|
||||
*start = 0;
|
||||
else
|
||||
@@ -51,9 +51,9 @@ gtk_css_image_radial_get_start_end (GtkCssImageRadial *radial,
|
||||
|
||||
*end = *start;
|
||||
|
||||
for (i = 0; i < radial->stops->len; i++)
|
||||
for (i = 0; i < radial->n_stops; i++)
|
||||
{
|
||||
stop = &g_array_index (radial->stops, GtkCssImageRadialColorStop, i);
|
||||
stop = &radial->color_stops[i];
|
||||
|
||||
if (stop->offset == NULL)
|
||||
continue;
|
||||
@@ -181,18 +181,16 @@ gtk_css_image_radial_snapshot (GtkCssImage *image,
|
||||
|
||||
offset = start;
|
||||
last = -1;
|
||||
for (i = 0; i < radial->stops->len; i++)
|
||||
for (i = 0; i < radial->n_stops; i++)
|
||||
{
|
||||
GtkCssImageRadialColorStop *stop;
|
||||
const GtkCssImageRadialColorStop *stop = &radial->color_stops[i];
|
||||
double pos, step;
|
||||
|
||||
stop = &g_array_index (radial->stops, GtkCssImageRadialColorStop, i);
|
||||
|
||||
if (stop->offset == NULL)
|
||||
{
|
||||
if (i == 0)
|
||||
pos = 0.0;
|
||||
else if (i + 1 == radial->stops->len)
|
||||
else if (i + 1 == radial->n_stops)
|
||||
pos = 1.0;
|
||||
else
|
||||
continue;
|
||||
@@ -206,9 +204,9 @@ gtk_css_image_radial_snapshot (GtkCssImage *image,
|
||||
{
|
||||
const GdkRGBA *rgba;
|
||||
|
||||
stop = &g_array_index (radial->stops, GtkCssImageRadialColorStop, last);
|
||||
stop = &radial->color_stops[last];
|
||||
|
||||
rgba = _gtk_css_rgba_value_get_rgba (stop->color);
|
||||
rgba = gtk_css_color_value_get_rgba (stop->color);
|
||||
offset += step;
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern,
|
||||
@@ -235,7 +233,8 @@ gtk_css_image_radial_snapshot (GtkCssImage *image,
|
||||
|
||||
static guint
|
||||
gtk_css_image_radial_parse_color_stop (GtkCssImageRadial *radial,
|
||||
GtkCssParser *parser)
|
||||
GtkCssParser *parser,
|
||||
GArray *stop_array)
|
||||
{
|
||||
GtkCssImageRadialColorStop stop;
|
||||
|
||||
@@ -259,14 +258,15 @@ gtk_css_image_radial_parse_color_stop (GtkCssImageRadial *radial,
|
||||
stop.offset = NULL;
|
||||
}
|
||||
|
||||
g_array_append_val (radial->stops, stop);
|
||||
g_array_append_val (stop_array, stop);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_image_radial_parse_first_arg (GtkCssImageRadial *radial,
|
||||
GtkCssParser *parser)
|
||||
GtkCssParser *parser,
|
||||
GArray *stop_array)
|
||||
{
|
||||
gboolean has_shape = FALSE;
|
||||
gboolean has_size = FALSE;
|
||||
@@ -379,23 +379,30 @@ gtk_css_image_radial_parse_first_arg (GtkCssImageRadial *radial,
|
||||
if (found_one)
|
||||
return 1;
|
||||
|
||||
if (!gtk_css_image_radial_parse_color_stop (radial, parser))
|
||||
if (!gtk_css_image_radial_parse_color_stop (radial, parser, stop_array))
|
||||
return 0;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkCssImageRadial *self;
|
||||
GArray *stop_array;
|
||||
} ParseData;
|
||||
|
||||
static guint
|
||||
gtk_css_image_radial_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkCssImageRadial *self = data;
|
||||
ParseData *parse_data = user_data;
|
||||
GtkCssImageRadial *self = parse_data->self;
|
||||
|
||||
if (arg == 0)
|
||||
return gtk_css_image_radial_parse_first_arg (self, parser);
|
||||
return gtk_css_image_radial_parse_first_arg (self, parser, parse_data->stop_array);
|
||||
else
|
||||
return gtk_css_image_radial_parse_color_stop (self, parser);
|
||||
return gtk_css_image_radial_parse_color_stop (self, parser, parse_data->stop_array);
|
||||
|
||||
}
|
||||
|
||||
@@ -404,6 +411,8 @@ gtk_css_image_radial_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageRadial *self = GTK_CSS_IMAGE_RADIAL (image);
|
||||
ParseData parse_data;
|
||||
gboolean success;
|
||||
|
||||
if (gtk_css_parser_has_function (parser, "repeating-radial-gradient"))
|
||||
self->repeating = TRUE;
|
||||
@@ -415,7 +424,22 @@ gtk_css_image_radial_parse (GtkCssImage *image,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return gtk_css_parser_consume_function (parser, 3, G_MAXUINT, gtk_css_image_radial_parse_arg, self);
|
||||
parse_data.self = self;
|
||||
parse_data.stop_array = g_array_new (TRUE, FALSE, sizeof (GtkCssImageRadialColorStop));
|
||||
|
||||
success = gtk_css_parser_consume_function (parser, 3, G_MAXUINT, gtk_css_image_radial_parse_arg, &parse_data);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
g_array_free (parse_data.stop_array, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->n_stops = parse_data.stop_array->len;
|
||||
self->color_stops = (GtkCssImageRadialColorStop *)g_array_free (parse_data.stop_array, FALSE);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -460,15 +484,13 @@ gtk_css_image_radial_print (GtkCssImage *image,
|
||||
|
||||
g_string_append (string, ", ");
|
||||
|
||||
for (i = 0; i < radial->stops->len; i++)
|
||||
for (i = 0; i < radial->n_stops; i++)
|
||||
{
|
||||
GtkCssImageRadialColorStop *stop;
|
||||
const GtkCssImageRadialColorStop *stop = &radial->color_stops[i];
|
||||
|
||||
if (i > 0)
|
||||
g_string_append (string, ", ");
|
||||
|
||||
stop = &g_array_index (radial->stops, GtkCssImageRadialColorStop, i);
|
||||
|
||||
_gtk_css_value_print (stop->color, string);
|
||||
|
||||
if (stop->offset)
|
||||
@@ -505,13 +527,12 @@ gtk_css_image_radial_compute (GtkCssImage *image,
|
||||
if (radial->sizes[1])
|
||||
copy->sizes[1] = _gtk_css_value_compute (radial->sizes[1], property_id, provider, style, parent_style);
|
||||
|
||||
g_array_set_size (copy->stops, radial->stops->len);
|
||||
for (i = 0; i < radial->stops->len; i++)
|
||||
copy->n_stops = radial->n_stops;
|
||||
copy->color_stops = g_malloc (sizeof (GtkCssImageRadialColorStop) * copy->n_stops);
|
||||
for (i = 0; i < radial->n_stops; i++)
|
||||
{
|
||||
GtkCssImageRadialColorStop *stop, *scopy;
|
||||
|
||||
stop = &g_array_index (radial->stops, GtkCssImageRadialColorStop, i);
|
||||
scopy = &g_array_index (copy->stops, GtkCssImageRadialColorStop, i);
|
||||
const GtkCssImageRadialColorStop *stop = &radial->color_stops[i];
|
||||
GtkCssImageRadialColorStop *scopy = ©->color_stops[i];
|
||||
|
||||
scopy->color = _gtk_css_value_compute (stop->color, property_id, provider, style, parent_style);
|
||||
|
||||
@@ -548,7 +569,7 @@ gtk_css_image_radial_transition (GtkCssImage *start_image,
|
||||
end = GTK_CSS_IMAGE_RADIAL (end_image);
|
||||
|
||||
if (start->repeating != end->repeating ||
|
||||
start->stops->len != end->stops->len ||
|
||||
start->n_stops != end->n_stops ||
|
||||
start->size != end->size ||
|
||||
start->circle != end->circle)
|
||||
return GTK_CSS_IMAGE_CLASS (_gtk_css_image_radial_parent_class)->transition (start_image, end_image, property_id, progress);
|
||||
@@ -580,42 +601,43 @@ gtk_css_image_radial_transition (GtkCssImage *start_image,
|
||||
else
|
||||
result->sizes[1] = 0;
|
||||
|
||||
for (i = 0; i < start->stops->len; i++)
|
||||
result->color_stops = g_malloc (sizeof (GtkCssImageRadialColorStop) * start->n_stops);
|
||||
result->n_stops = 0;
|
||||
for (i = 0; i < start->n_stops; i++)
|
||||
{
|
||||
GtkCssImageRadialColorStop stop, *start_stop, *end_stop;
|
||||
|
||||
start_stop = &g_array_index (start->stops, GtkCssImageRadialColorStop, i);
|
||||
end_stop = &g_array_index (end->stops, GtkCssImageRadialColorStop, i);
|
||||
const GtkCssImageRadialColorStop *start_stop = &start->color_stops[i];
|
||||
const GtkCssImageRadialColorStop *end_stop = &end->color_stops[i];
|
||||
GtkCssImageRadialColorStop *stop = &result->color_stops[i];
|
||||
|
||||
if ((start_stop->offset != NULL) != (end_stop->offset != NULL))
|
||||
goto fail;
|
||||
|
||||
if (start_stop->offset == NULL)
|
||||
{
|
||||
stop.offset = NULL;
|
||||
stop->offset = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stop.offset = _gtk_css_value_transition (start_stop->offset,
|
||||
end_stop->offset,
|
||||
property_id,
|
||||
progress);
|
||||
if (stop.offset == NULL)
|
||||
stop->offset = _gtk_css_value_transition (start_stop->offset,
|
||||
end_stop->offset,
|
||||
property_id,
|
||||
progress);
|
||||
if (stop->offset == NULL)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
stop.color = _gtk_css_value_transition (start_stop->color,
|
||||
end_stop->color,
|
||||
property_id,
|
||||
progress);
|
||||
if (stop.color == NULL)
|
||||
stop->color = _gtk_css_value_transition (start_stop->color,
|
||||
end_stop->color,
|
||||
property_id,
|
||||
progress);
|
||||
if (stop->color == NULL)
|
||||
{
|
||||
if (stop.offset)
|
||||
_gtk_css_value_unref (stop.offset);
|
||||
if (stop->offset)
|
||||
_gtk_css_value_unref (stop->offset);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
g_array_append_val (result->stops, stop);
|
||||
result->n_stops++;
|
||||
}
|
||||
|
||||
return GTK_CSS_IMAGE (result);
|
||||
@@ -640,15 +662,13 @@ gtk_css_image_radial_equal (GtkCssImage *image1,
|
||||
(radial1->sizes[0] && radial2->sizes[0] && !_gtk_css_value_equal (radial1->sizes[0], radial2->sizes[0])) ||
|
||||
((radial1->sizes[1] == NULL) != (radial2->sizes[1] == NULL)) ||
|
||||
(radial1->sizes[1] && radial2->sizes[1] && !_gtk_css_value_equal (radial1->sizes[1], radial2->sizes[1])) ||
|
||||
radial1->stops->len != radial2->stops->len)
|
||||
radial1->n_stops != radial2->n_stops)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < radial1->stops->len; i++)
|
||||
for (i = 0; i < radial1->n_stops; i++)
|
||||
{
|
||||
GtkCssImageRadialColorStop *stop1, *stop2;
|
||||
|
||||
stop1 = &g_array_index (radial1->stops, GtkCssImageRadialColorStop, i);
|
||||
stop2 = &g_array_index (radial2->stops, GtkCssImageRadialColorStop, i);
|
||||
const GtkCssImageRadialColorStop *stop1 = &radial1->color_stops[i];
|
||||
const GtkCssImageRadialColorStop *stop2 = &radial2->color_stops[i];
|
||||
|
||||
if (!_gtk_css_value_equal0 (stop1->offset, stop2->offset) ||
|
||||
!_gtk_css_value_equal (stop1->color, stop2->color))
|
||||
@@ -662,13 +682,17 @@ static void
|
||||
gtk_css_image_radial_dispose (GObject *object)
|
||||
{
|
||||
GtkCssImageRadial *radial = GTK_CSS_IMAGE_RADIAL (object);
|
||||
int i;
|
||||
guint i;
|
||||
|
||||
if (radial->stops)
|
||||
for (i = 0; i < radial->n_stops; i ++)
|
||||
{
|
||||
g_array_free (radial->stops, TRUE);
|
||||
radial->stops = NULL;
|
||||
GtkCssImageRadialColorStop *stop = &radial->color_stops[i];
|
||||
|
||||
_gtk_css_value_unref (stop->color);
|
||||
if (stop->offset)
|
||||
_gtk_css_value_unref (stop->offset);
|
||||
}
|
||||
g_free (radial->color_stops);
|
||||
|
||||
if (radial->position)
|
||||
{
|
||||
@@ -686,6 +710,37 @@ gtk_css_image_radial_dispose (GObject *object)
|
||||
G_OBJECT_CLASS (_gtk_css_image_radial_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_radial_is_computed (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageRadial *radial = GTK_CSS_IMAGE_RADIAL (image);
|
||||
guint i;
|
||||
gboolean computed = TRUE;
|
||||
|
||||
computed = computed && (!radial->position || gtk_css_value_is_computed (radial->position));
|
||||
computed = computed && (!radial->sizes[0] || gtk_css_value_is_computed (radial->sizes[0]));
|
||||
computed = computed && (!radial->sizes[1] || gtk_css_value_is_computed (radial->sizes[1]));
|
||||
|
||||
if (computed)
|
||||
for (i = 0; i < radial->n_stops; i ++)
|
||||
{
|
||||
const GtkCssImageRadialColorStop *stop = &radial->color_stops[i];
|
||||
|
||||
if (stop->offset && !gtk_css_value_is_computed (stop->offset))
|
||||
{
|
||||
computed = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gtk_css_value_is_computed (stop->color))
|
||||
{
|
||||
computed = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return computed;
|
||||
}
|
||||
static void
|
||||
_gtk_css_image_radial_class_init (GtkCssImageRadialClass *klass)
|
||||
{
|
||||
@@ -698,24 +753,13 @@ _gtk_css_image_radial_class_init (GtkCssImageRadialClass *klass)
|
||||
image_class->compute = gtk_css_image_radial_compute;
|
||||
image_class->transition = gtk_css_image_radial_transition;
|
||||
image_class->equal = gtk_css_image_radial_equal;
|
||||
image_class->is_computed = gtk_css_image_radial_is_computed;
|
||||
|
||||
object_class->dispose = gtk_css_image_radial_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_clear_color_stop (gpointer color_stop)
|
||||
{
|
||||
GtkCssImageRadialColorStop *stop = color_stop;
|
||||
|
||||
_gtk_css_value_unref (stop->color);
|
||||
if (stop->offset)
|
||||
_gtk_css_value_unref (stop->offset);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_radial_init (GtkCssImageRadial *radial)
|
||||
{
|
||||
radial->stops = g_array_new (FALSE, FALSE, sizeof (GtkCssImageRadialColorStop));
|
||||
g_array_set_clear_func (radial->stops, gtk_css_image_clear_color_stop);
|
||||
}
|
||||
|
||||
|
@@ -55,7 +55,8 @@ struct _GtkCssImageRadial
|
||||
|
||||
GtkCssValue *position;
|
||||
GtkCssValue *sizes[2];
|
||||
GArray *stops;
|
||||
guint n_stops;
|
||||
GtkCssImageRadialColorStop *color_stops;
|
||||
GtkCssRadialSize size;
|
||||
guint circle : 1;
|
||||
guint repeating :1;
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#include "gtkcssimagerecolorprivate.h"
|
||||
#include "gtkcssimageprivate.h"
|
||||
#include "gtkcsspalettevalueprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkiconthemeprivate.h"
|
||||
#include "gdkpixbufutilsprivate.h"
|
||||
|
||||
@@ -74,7 +74,7 @@ lookup_symbolic_colors (GtkCssStyle *style,
|
||||
const GdkRGBA *lookup;
|
||||
|
||||
color = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_COLOR);
|
||||
*color_out = *_gtk_css_rgba_value_get_rgba (color);
|
||||
*color_out = *gtk_css_color_value_get_rgba (color);
|
||||
|
||||
lookup = gtk_css_palette_value_get_color (palette, "success");
|
||||
if (lookup)
|
||||
@@ -308,6 +308,15 @@ 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)
|
||||
{
|
||||
@@ -320,6 +329,7 @@ _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,6 +203,15 @@ 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)
|
||||
{
|
||||
@@ -216,6 +225,7 @@ _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,6 +161,12 @@ 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)
|
||||
@@ -249,6 +255,7 @@ _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 (GtkCssValue *value)
|
||||
gtk_css_value_image_is_dynamic (const GtkCssValue *value)
|
||||
{
|
||||
GtkCssImage *image = _gtk_css_image_value_get_image (value);
|
||||
|
||||
@@ -123,6 +123,7 @@ gtk_css_value_image_print (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_IMAGE = {
|
||||
"GtkCssImageValue",
|
||||
gtk_css_value_image_free,
|
||||
gtk_css_value_image_compute,
|
||||
gtk_css_value_image_equal,
|
||||
@@ -135,7 +136,7 @@ static const GtkCssValueClass GTK_CSS_VALUE_IMAGE = {
|
||||
GtkCssValue *
|
||||
_gtk_css_image_value_new (GtkCssImage *image)
|
||||
{
|
||||
static GtkCssValue none_singleton = { >K_CSS_VALUE_IMAGE, 1, NULL };
|
||||
static GtkCssValue none_singleton = { >K_CSS_VALUE_IMAGE, 1, TRUE, NULL };
|
||||
GtkCssValue *value;
|
||||
|
||||
if (image == NULL)
|
||||
@@ -143,6 +144,7 @@ _gtk_css_image_value_new (GtkCssImage *image)
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_IMAGE);
|
||||
value->image = image;
|
||||
value->is_computed = gtk_css_image_is_computed (image);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user