Compare commits
136 Commits
3.33.1
...
wip/nielsd
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e04cbddf92 | ||
![]() |
d3e789e677 | ||
![]() |
c24d8e856b | ||
![]() |
9db9793f33 | ||
![]() |
c237bc5f45 | ||
![]() |
178b975d6a | ||
![]() |
4abca411f3 | ||
![]() |
e48c7c009a | ||
![]() |
36b361617d | ||
![]() |
5eac1d696d | ||
![]() |
9b53583945 | ||
![]() |
1dbf25afa1 | ||
![]() |
e415cc538a | ||
![]() |
67a3715ded | ||
![]() |
35aa278194 | ||
![]() |
a76762a05e | ||
![]() |
ccf27e5f83 | ||
![]() |
912a9ecfba | ||
![]() |
0487d672ed | ||
![]() |
e94a0fced9 | ||
![]() |
a3b86447f7 | ||
![]() |
1d76eace1e | ||
![]() |
c1303bd642 | ||
![]() |
db11a37a68 | ||
![]() |
0d0b9da6f8 | ||
![]() |
ab0b407da4 | ||
![]() |
c33b330799 | ||
![]() |
144b24bfcc | ||
![]() |
4d21650d6d | ||
![]() |
a6fc656e91 | ||
![]() |
a38bae259e | ||
![]() |
c53aa89098 | ||
![]() |
851b7d0639 | ||
![]() |
b4c78726cf | ||
![]() |
c9cc07fd3a | ||
![]() |
f6eb2a8cf8 | ||
![]() |
08e5589836 | ||
![]() |
4f5a5e84fc | ||
![]() |
0786683189 | ||
![]() |
4887de533c | ||
![]() |
57945a730f | ||
![]() |
78254146f3 | ||
![]() |
3e2a2cf532 | ||
![]() |
04b240b50c | ||
![]() |
7810f0e276 | ||
![]() |
9b8f9b65b8 | ||
![]() |
e741cab3f4 | ||
![]() |
53748e3da7 | ||
![]() |
17c5436f6e | ||
![]() |
04fb6f7659 | ||
![]() |
e5e58f8075 | ||
![]() |
1da0355528 | ||
![]() |
e5881156f6 | ||
![]() |
60170cff70 | ||
![]() |
e2bea48073 | ||
![]() |
bbfaf8204b | ||
![]() |
b3e19ee669 | ||
![]() |
75e2bfb062 | ||
![]() |
a859d76c72 | ||
![]() |
2145333969 | ||
![]() |
1b61b9cd73 | ||
![]() |
a2c545c321 | ||
![]() |
3cd8f3b7dc | ||
![]() |
033ce2d956 | ||
![]() |
2b47e89405 | ||
![]() |
80d11287eb | ||
![]() |
f869e4d54b | ||
![]() |
c1059df7f9 | ||
![]() |
e3d3df985f | ||
![]() |
86ff3dfb3c | ||
![]() |
7e0d185120 | ||
![]() |
61c173b777 | ||
![]() |
f99cd18254 | ||
![]() |
0405786573 | ||
![]() |
b016ff29f6 | ||
![]() |
3f2e86f67c | ||
![]() |
0aa4a526c6 | ||
![]() |
85c2aef4bc | ||
![]() |
76664ef891 | ||
![]() |
b1ea768949 | ||
![]() |
ea9d8a895b | ||
![]() |
38432da328 | ||
![]() |
430f354cd9 | ||
![]() |
1cf4279745 | ||
![]() |
7713006f5b | ||
![]() |
465e13128b | ||
![]() |
86de79cfc5 | ||
![]() |
1d77641f0b | ||
![]() |
2f217109aa | ||
![]() |
5e0523cc8b | ||
![]() |
dbe6e01e12 | ||
![]() |
103c469cc9 | ||
![]() |
ef074ea510 | ||
![]() |
39bac6eabd | ||
![]() |
0200f4fcd9 | ||
![]() |
439afb3f19 | ||
![]() |
b01edc22f3 | ||
![]() |
e8bca5052a | ||
![]() |
468882ecec | ||
![]() |
be3c89d823 | ||
![]() |
7719e33e68 | ||
![]() |
deef9960a4 | ||
![]() |
9305b6d8ee | ||
![]() |
62de4b4f82 | ||
![]() |
ea0a89bde8 | ||
![]() |
4faeb12731 | ||
![]() |
91ac64bb44 | ||
![]() |
ed56edc7ba | ||
![]() |
6eeba2434a | ||
![]() |
7fb7b28cd6 | ||
![]() |
08aec58c22 | ||
![]() |
52945f383d | ||
![]() |
fecc57ddf0 | ||
![]() |
0d7a929b83 | ||
![]() |
991f9505ad | ||
![]() |
358b67871f | ||
![]() |
2b1acea1b0 | ||
![]() |
91aee3d5c4 | ||
![]() |
02812fb988 | ||
![]() |
29211c9020 | ||
![]() |
68fba458b3 | ||
![]() |
9c2fdcdbb2 | ||
![]() |
d4a0893d76 | ||
![]() |
7a6c755833 | ||
![]() |
45244852ac | ||
![]() |
e96136e418 | ||
![]() |
eae6e7a889 | ||
![]() |
a48b6cc9ca | ||
![]() |
786305f7d6 | ||
![]() |
30a2483e6e | ||
![]() |
f5f0aa1023 | ||
![]() |
b86fba2f3c | ||
![]() |
f7ecf3b618 | ||
![]() |
7a17e236f7 | ||
![]() |
df7d8e2cbf | ||
![]() |
9e82f9af25 |
@@ -1,4 +1,4 @@
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v1
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
|
||||
|
||||
stages:
|
||||
- review
|
||||
@@ -35,12 +35,17 @@ test-mutter:
|
||||
variables:
|
||||
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
|
||||
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data"
|
||||
G_SLICE: "always-malloc"
|
||||
MALLOC_CHECK_: "3"
|
||||
NO_AT_BRIDGE: "1"
|
||||
MALLOC_PERTURB_: "123"
|
||||
script:
|
||||
- dconf update
|
||||
- mkdir -m 700 $XDG_RUNTIME_DIR
|
||||
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
|
||||
- >
|
||||
dbus-run-session -- xvfb-run -s '+iglx -noreset'
|
||||
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --wrap catchsegv
|
||||
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --print-errorlogs --wrap catchsegv
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
@@ -1,4 +1,4 @@
|
||||
FROM fedora:29
|
||||
FROM fedora:30
|
||||
|
||||
RUN dnf -y update && dnf -y upgrade && \
|
||||
dnf install -y 'dnf-command(builddep)' && \
|
||||
@@ -15,6 +15,7 @@ RUN dnf -y update && dnf -y upgrade && \
|
||||
|
||||
# Unpackaged versions
|
||||
dnf install -y https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00834984-gsettings-desktop-schemas/gsettings-desktop-schemas-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00834984-gsettings-desktop-schemas/gsettings-desktop-schemas-devel-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm && \
|
||||
dnf install -y https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/libsysprof-ui-3.33.2-1.fc30.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/sysprof-cli-3.33.2-1.fc30.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/sysprof-3.33.2-1.fc30.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/sysprof-devel-3.33.2-1.fc30.x86_64.rpm && \
|
||||
|
||||
dnf install -y intltool redhat-rpm-config make && \
|
||||
|
||||
|
15
NEWS
15
NEWS
@@ -1,3 +1,18 @@
|
||||
3.33.2
|
||||
======
|
||||
* Fix rendering lag on Xorg [Daniel; !520, !281]
|
||||
* Misc. bug fixes and cleanups [Carlos, Marco, Jonas D., Florian, Niels,
|
||||
Daniel, Benjamin, Jonas Å., Ignacio, Vasilis; #598, !576, !547, !578,
|
||||
!583, !582, !469, !524, !119, !571, !584, !585, !586, #425]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Benjamin Berg, Jonas Dreßler, Carlos Garnacho, Niels De Graef,
|
||||
Vasilis Liaskovitis, Florian Müllner, Ignacio Casal Quinteiro,
|
||||
Marco Trevisan (Treviño), Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Daniel Mustieles [es]
|
||||
|
||||
3.33.1
|
||||
======
|
||||
* Remove unused APIs and outdated driver support
|
||||
|
@@ -1044,10 +1044,8 @@ _cally_actor_clean_action_list (CallyActor *cally_actor)
|
||||
|
||||
if (priv->action_list)
|
||||
{
|
||||
g_list_foreach (priv->action_list,
|
||||
(GFunc) _cally_actor_destroy_action_info,
|
||||
NULL);
|
||||
g_list_free (priv->action_list);
|
||||
g_list_free_full (priv->action_list,
|
||||
(GDestroyNotify) _cally_actor_destroy_action_info);
|
||||
priv->action_list = NULL;
|
||||
}
|
||||
}
|
||||
|
@@ -577,8 +577,7 @@ _clutter_meta_group_clear_metas (ClutterMetaGroup *group)
|
||||
{
|
||||
g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL);
|
||||
|
||||
g_list_foreach (group->meta, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (group->meta);
|
||||
g_list_free_full (group->meta, g_object_unref);
|
||||
group->meta = NULL;
|
||||
}
|
||||
|
||||
|
@@ -8849,9 +8849,9 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
|
||||
*
|
||||
* later during _clutter_stage_do_update(), once relayouting is done
|
||||
* and the scenegraph has been updated we will call:
|
||||
* _clutter_stage_finish_queue_redraws().
|
||||
* clutter_stage_maybe_finish_queue_redraws().
|
||||
*
|
||||
* _clutter_stage_finish_queue_redraws() will call
|
||||
* clutter_stage_maybe_finish_queue_redraws() will call
|
||||
* _clutter_actor_finish_queue_redraw() for each listed actor.
|
||||
*
|
||||
* Note: actors *are* allowed to queue further redraws during this
|
||||
@@ -17551,7 +17551,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
|
||||
l != NULL && l->data != priv->current_effect;
|
||||
l = l->next)
|
||||
{
|
||||
if (!_clutter_effect_get_paint_volume (l->data, pv))
|
||||
if (!_clutter_effect_modify_paint_volume (l->data, pv))
|
||||
{
|
||||
clutter_paint_volume_free (pv);
|
||||
CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "
|
||||
@@ -17569,7 +17569,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
|
||||
/* otherwise, get the cumulative volume */
|
||||
effects = _clutter_meta_group_peek_metas (priv->effects);
|
||||
for (l = effects; l != NULL; l = l->next)
|
||||
if (!_clutter_effect_get_paint_volume (l->data, pv))
|
||||
if (!_clutter_effect_modify_paint_volume (l->data, pv))
|
||||
{
|
||||
clutter_paint_volume_free (pv);
|
||||
CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "
|
||||
|
@@ -235,8 +235,7 @@ clutter_binding_pool_finalize (GObject *gobject)
|
||||
|
||||
g_hash_table_destroy (pool->entries_hash);
|
||||
|
||||
g_slist_foreach (pool->entries, (GFunc) binding_entry_free, NULL);
|
||||
g_slist_free (pool->entries);
|
||||
g_slist_free_full (pool->entries, (GDestroyNotify) binding_entry_free);
|
||||
|
||||
G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
@@ -178,8 +178,8 @@ clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_blur_effect_get_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
clutter_blur_effect_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
gfloat cur_width, cur_height;
|
||||
ClutterVertex origin;
|
||||
@@ -223,7 +223,7 @@ clutter_blur_effect_class_init (ClutterBlurEffectClass *klass)
|
||||
gobject_class->dispose = clutter_blur_effect_dispose;
|
||||
|
||||
effect_class->pre_paint = clutter_blur_effect_pre_paint;
|
||||
effect_class->get_paint_volume = clutter_blur_effect_get_paint_volume;
|
||||
effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->paint_target = clutter_blur_effect_paint_target;
|
||||
|
@@ -69,6 +69,22 @@ typedef struct _ClutterTouchInfo
|
||||
gfloat current_y;
|
||||
} ClutterTouchInfo;
|
||||
|
||||
typedef struct _ClutterPtrA11yData
|
||||
{
|
||||
int n_btn_pressed;
|
||||
float current_x;
|
||||
float current_y;
|
||||
|
||||
float dwell_x;
|
||||
float dwell_y;
|
||||
gboolean dwell_drag_started;
|
||||
gboolean dwell_gesture_started;
|
||||
guint dwell_timer;
|
||||
|
||||
guint secondary_click_timer;
|
||||
gboolean secondary_click_triggered;
|
||||
} ClutterPtrA11yData;
|
||||
|
||||
struct _ClutterInputDevice
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -143,6 +159,10 @@ struct _ClutterInputDevice
|
||||
|
||||
guint has_cursor : 1;
|
||||
guint is_enabled : 1;
|
||||
|
||||
/* Accessiblity */
|
||||
ClutterVirtualInputDevice *accessibility_virtual_device;
|
||||
ClutterPtrA11yData *ptr_a11y_data;
|
||||
};
|
||||
|
||||
typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-virtual-input-device.h"
|
||||
#include "clutter-input-device-tool.h"
|
||||
#include "clutter-input-pointer-a11y-private.h"
|
||||
|
||||
struct _ClutterDeviceManagerPrivate
|
||||
{
|
||||
@@ -55,6 +56,8 @@ struct _ClutterDeviceManagerPrivate
|
||||
|
||||
/* Keyboard a11y */
|
||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
||||
/* Pointer a11y */
|
||||
ClutterPointerA11ySettings pointer_a11y_settings;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -75,6 +78,9 @@ enum
|
||||
TOOL_CHANGED,
|
||||
KBD_A11Y_MASK_CHANGED,
|
||||
KBD_A11Y_FLAGS_CHANGED,
|
||||
PTR_A11Y_DWELL_CLICK_TYPE_CHANGED,
|
||||
PTR_A11Y_TIMEOUT_STARTED,
|
||||
PTR_A11Y_TIMEOUT_STOPPED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@@ -239,6 +245,67 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_UINT);
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager::ptr-a11y-dwell-click-type-changed:
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @click_type: the new #ClutterPointerA11yDwellClickType mode
|
||||
*
|
||||
* The ::ptr-a11y-dwell-click-type-changed signal is emitted each time
|
||||
* the ClutterPointerA11yDwellClickType mode is changed as the result
|
||||
* of pointer accessibility operations.
|
||||
*/
|
||||
manager_signals[PTR_A11Y_DWELL_CLICK_TYPE_CHANGED] =
|
||||
g_signal_new (I_("ptr-a11y-dwell-click-type-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__FLAGS,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_POINTER_A11Y_DWELL_CLICK_TYPE);
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager::ptr-a11y-timeout-started:
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @device: the core pointer #ClutterInputDevice
|
||||
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
|
||||
* @delay: the delay in ms before secondary-click is triggered.
|
||||
*
|
||||
* The ::ptr-a11y-timeout-started signal is emitted when a
|
||||
* pointer accessibility timeout delay is started, so that upper
|
||||
* layers can notify the user with some visual feedback.
|
||||
*/
|
||||
manager_signals[PTR_A11Y_TIMEOUT_STARTED] =
|
||||
g_signal_new (I_("ptr-a11y-timeout-started"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT_FLAGS_UINT,
|
||||
G_TYPE_NONE, 3,
|
||||
CLUTTER_TYPE_INPUT_DEVICE,
|
||||
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
|
||||
G_TYPE_UINT);
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager::ptr-a11y-timeout-stopped:
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @device: the core pointer #ClutterInputDevice
|
||||
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
|
||||
*
|
||||
* The ::ptr-a11y-timeout-stopped signal is emitted when a running
|
||||
* pointer accessibility timeout delay is stopped, either because
|
||||
* it's triggered at the end of the delay or cancelled, so that
|
||||
* upper layers can notify the user with some visual feedback.
|
||||
*/
|
||||
manager_signals[PTR_A11Y_TIMEOUT_STOPPED] =
|
||||
g_signal_new (I_("ptr-a11y-timeout-stopped"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT_FLAGS,
|
||||
G_TYPE_NONE, 2,
|
||||
CLUTTER_TYPE_INPUT_DEVICE,
|
||||
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -579,3 +646,88 @@ clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_man
|
||||
|
||||
*settings = device_manager->priv->kbd_a11y_settings;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
are_pointer_a11y_settings_equal (ClutterPointerA11ySettings *a,
|
||||
ClutterPointerA11ySettings *b)
|
||||
{
|
||||
return (memcmp (a, b, sizeof (ClutterPointerA11ySettings)) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_enable_pointer_a11y (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
|
||||
core_pointer = clutter_device_manager_get_core_device (device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
_clutter_input_pointer_a11y_add_device (core_pointer);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_disable_pointer_a11y (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
|
||||
core_pointer = clutter_device_manager_get_core_device (device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
_clutter_input_pointer_a11y_remove_device (core_pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_device_manager_set_pointer_a11y_settings:
|
||||
* @device_manager: a #ClutterDeviceManager
|
||||
* @settings: a pointer to a #ClutterPointerA11ySettings
|
||||
*
|
||||
* Sets the pointer accessibility settings
|
||||
**/
|
||||
void
|
||||
clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11ySettings *settings)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
if (are_pointer_a11y_settings_equal (&device_manager->priv->pointer_a11y_settings, settings))
|
||||
return;
|
||||
|
||||
if (device_manager->priv->pointer_a11y_settings.controls == 0 && settings->controls != 0)
|
||||
clutter_device_manager_enable_pointer_a11y (device_manager);
|
||||
else if (device_manager->priv->pointer_a11y_settings.controls != 0 && settings->controls == 0)
|
||||
clutter_device_manager_disable_pointer_a11y (device_manager);
|
||||
|
||||
device_manager->priv->pointer_a11y_settings = *settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_device_manager_get_pointer_a11y_settings:
|
||||
* @device_manager: a #ClutterDeviceManager
|
||||
* @settings: a pointer to a #ClutterPointerA11ySettings
|
||||
*
|
||||
* Gets the current pointer accessibility settings
|
||||
**/
|
||||
void
|
||||
clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11ySettings *settings)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
*settings = device_manager->priv->pointer_a11y_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_device_manager_set_pointer_a11y_dwell_click_type:
|
||||
* @device_manager: a #ClutterDeviceManager
|
||||
* @click_type: type of click as #ClutterPointerA11yDwellClickType
|
||||
*
|
||||
* Sets the dwell click type
|
||||
**/
|
||||
void
|
||||
clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11yDwellClickType click_type)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
device_manager->priv->pointer_a11y_settings.dwell_click_type = click_type;
|
||||
}
|
||||
|
@@ -73,6 +73,27 @@ typedef struct _ClutterKbdA11ySettings
|
||||
gint mousekeys_accel_time;
|
||||
} ClutterKbdA11ySettings;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11ySettings:
|
||||
*
|
||||
* The #ClutterPointerA11ySettings structure contains pointer accessibility
|
||||
* settings
|
||||
*
|
||||
*/
|
||||
typedef struct _ClutterPointerA11ySettings
|
||||
{
|
||||
ClutterPointerA11yFlags controls;
|
||||
ClutterPointerA11yDwellClickType dwell_click_type;
|
||||
ClutterPointerA11yDwellMode dwell_mode;
|
||||
ClutterPointerA11yDwellDirection dwell_gesture_single;
|
||||
ClutterPointerA11yDwellDirection dwell_gesture_double;
|
||||
ClutterPointerA11yDwellDirection dwell_gesture_drag;
|
||||
ClutterPointerA11yDwellDirection dwell_gesture_secondary;
|
||||
gint secondary_click_delay;
|
||||
gint dwell_delay;
|
||||
gint dwell_threshold;
|
||||
} ClutterPointerA11ySettings;
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager:
|
||||
*
|
||||
@@ -152,10 +173,23 @@ ClutterVirtualDeviceType clutter_device_manager_get_supported_virtual_device_typ
|
||||
CLUTTER_EXPORT
|
||||
void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11ySettings *settings);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11ySettings *settings);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11yDwellClickType click_type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_DEVICE_MANAGER_H__ */
|
||||
|
@@ -7,7 +7,7 @@ G_BEGIN_DECLS
|
||||
|
||||
gboolean _clutter_effect_pre_paint (ClutterEffect *effect);
|
||||
void _clutter_effect_post_paint (ClutterEffect *effect);
|
||||
gboolean _clutter_effect_get_paint_volume (ClutterEffect *effect,
|
||||
gboolean _clutter_effect_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume);
|
||||
gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect);
|
||||
void _clutter_effect_paint (ClutterEffect *effect,
|
||||
|
@@ -188,8 +188,8 @@ clutter_effect_real_post_paint (ClutterEffect *effect)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_effect_real_get_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
clutter_effect_real_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -252,7 +252,7 @@ clutter_effect_class_init (ClutterEffectClass *klass)
|
||||
|
||||
klass->pre_paint = clutter_effect_real_pre_paint;
|
||||
klass->post_paint = clutter_effect_real_post_paint;
|
||||
klass->get_paint_volume = clutter_effect_real_get_paint_volume;
|
||||
klass->modify_paint_volume = clutter_effect_real_modify_paint_volume;
|
||||
klass->paint = clutter_effect_real_paint;
|
||||
klass->pick = clutter_effect_real_pick;
|
||||
}
|
||||
@@ -297,13 +297,14 @@ _clutter_effect_pick (ClutterEffect *effect,
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_effect_get_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
_clutter_effect_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
|
||||
g_return_val_if_fail (volume != NULL, FALSE);
|
||||
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume (effect, volume);
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume (effect,
|
||||
volume);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -311,7 +312,7 @@ _clutter_effect_has_custom_paint_volume (ClutterEffect *effect)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
|
||||
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume != clutter_effect_real_get_paint_volume;
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume != clutter_effect_real_modify_paint_volume;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -60,7 +60,7 @@ struct _ClutterEffect
|
||||
* ClutterEffectClass:
|
||||
* @pre_paint: virtual function
|
||||
* @post_paint: virtual function
|
||||
* @get_paint_volume: virtual function
|
||||
* @modify_paint_volume: virtual function
|
||||
* @paint: virtual function
|
||||
* @pick: virtual function
|
||||
*
|
||||
@@ -74,16 +74,16 @@ struct _ClutterEffectClass
|
||||
ClutterActorMetaClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
gboolean (* pre_paint) (ClutterEffect *effect);
|
||||
void (* post_paint) (ClutterEffect *effect);
|
||||
gboolean (* pre_paint) (ClutterEffect *effect);
|
||||
void (* post_paint) (ClutterEffect *effect);
|
||||
|
||||
gboolean (* get_paint_volume) (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume);
|
||||
gboolean (* modify_paint_volume) (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume);
|
||||
|
||||
void (* paint) (ClutterEffect *effect,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void (* pick) (ClutterEffect *effect,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void (* paint) (ClutterEffect *effect,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void (* pick) (ClutterEffect *effect,
|
||||
ClutterEffectPaintFlags flags);
|
||||
|
||||
/*< private >*/
|
||||
void (* _clutter_effect4) (void);
|
||||
|
@@ -443,6 +443,88 @@ typedef enum
|
||||
CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
|
||||
} ClutterKeyboardA11yFlags;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yFlags:
|
||||
* @CLUTTER_A11Y_POINTER_ENABLED:
|
||||
* @CLUTTER_A11Y_SECONDARY_CLICK_ENABLED:
|
||||
* @CLUTTER_A11Y_DWELL_ENABLED:
|
||||
*
|
||||
* Pointer accessibility features applied to a ClutterInputDevice pointer.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_SECONDARY_CLICK_ENABLED = 1 << 0,
|
||||
CLUTTER_A11Y_DWELL_ENABLED = 1 << 1,
|
||||
} ClutterPointerA11yFlags;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yDwellClickType:
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: Internal use only
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
|
||||
*
|
||||
* Dwell click types.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE,
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY,
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY,
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE,
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE,
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG,
|
||||
} ClutterPointerA11yDwellClickType;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yDwellDirection:
|
||||
* @CLUTTER_A11Y_DWELL_DIRECTION_NONE:
|
||||
* @CLUTTER_A11Y_DWELL_DIRECTION_LEFT:
|
||||
* @CLUTTER_A11Y_DWELL_DIRECTION_RIGHT:
|
||||
* @CLUTTER_A11Y_DWELL_DIRECTION_UP:
|
||||
* @CLUTTER_A11Y_DWELL_DIRECTION_DOWN:
|
||||
*
|
||||
* Dwell gesture directions.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_DWELL_DIRECTION_NONE,
|
||||
CLUTTER_A11Y_DWELL_DIRECTION_LEFT,
|
||||
CLUTTER_A11Y_DWELL_DIRECTION_RIGHT,
|
||||
CLUTTER_A11Y_DWELL_DIRECTION_UP,
|
||||
CLUTTER_A11Y_DWELL_DIRECTION_DOWN,
|
||||
} ClutterPointerA11yDwellDirection;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yDwellMode:
|
||||
* @CLUTTER_A11Y_DWELL_MODE_WINDOW:
|
||||
* @CLUTTER_A11Y_DWELL_MODE_GESTURE:
|
||||
*
|
||||
* Dwell mode.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_DWELL_MODE_WINDOW,
|
||||
CLUTTER_A11Y_DWELL_MODE_GESTURE,
|
||||
} ClutterPointerA11yDwellMode;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yTimeoutType:
|
||||
* @CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK:
|
||||
* @CLUTTER_A11Y_TIMEOUT_TYPE_DWELL:
|
||||
* @CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE:
|
||||
*
|
||||
* Pointer accessibility timeout type.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
|
||||
} ClutterPointerA11yTimeoutType;
|
||||
|
||||
/**
|
||||
* ClutterActorFlags:
|
||||
* @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside
|
||||
|
@@ -107,6 +107,9 @@ clutter_input_device_dispose (GObject *gobject)
|
||||
device->associated = NULL;
|
||||
}
|
||||
|
||||
if (device->accessibility_virtual_device)
|
||||
g_clear_object (&device->accessibility_virtual_device);
|
||||
|
||||
g_clear_pointer (&device->axes, g_array_unref);
|
||||
g_clear_pointer (&device->keys, g_array_unref);
|
||||
g_clear_pointer (&device->scroll_info, g_array_unref);
|
||||
@@ -1036,9 +1039,10 @@ _clutter_input_device_update (ClutterInputDevice *device,
|
||||
ClutterActor *new_cursor_actor;
|
||||
ClutterActor *old_cursor_actor;
|
||||
ClutterPoint point = { -1, -1 };
|
||||
ClutterInputDeviceType device_type = device->device_type;
|
||||
|
||||
if (device->device_type == CLUTTER_KEYBOARD_DEVICE)
|
||||
return NULL;
|
||||
g_assert (device_type != CLUTTER_KEYBOARD_DEVICE &&
|
||||
device_type != CLUTTER_PAD_DEVICE);
|
||||
|
||||
stage = device->stage;
|
||||
if (G_UNLIKELY (stage == NULL))
|
||||
|
42
clutter/clutter/clutter-input-pointer-a11y-private.h
Normal file
42
clutter/clutter/clutter-input-pointer-a11y-private.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Olivier Fourdan <ofourdan@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_POINTER_A11Y_H__
|
||||
#define __CLUTTER_INPUT_POINTER_A11Y_H__
|
||||
|
||||
#include <clutter/clutter-types.h>
|
||||
#include "clutter-enum-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _clutter_input_pointer_a11y_add_device (ClutterInputDevice *device);
|
||||
void _clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device);
|
||||
void _clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y);
|
||||
void _clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device,
|
||||
int button,
|
||||
gboolean pressed);
|
||||
gboolean _clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_POINTER_A11Y_H__ */
|
669
clutter/clutter/clutter-input-pointer-a11y.c
Normal file
669
clutter/clutter/clutter-input-pointer-a11y.c
Normal file
@@ -0,0 +1,669 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Olivier Fourdan <ofourdan@redhat.com>
|
||||
*
|
||||
* This reimplements in Clutter the same behavior as mousetweaks original
|
||||
* implementation by Gerd Kohlberger <gerdko gmail com>
|
||||
* mousetweaks Copyright (C) 2007-2010 Gerd Kohlberger <gerdko gmail com>
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-device-manager.h"
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-input-device.h"
|
||||
#include "clutter-input-pointer-a11y-private.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-virtual-input-device.h"
|
||||
|
||||
static gboolean
|
||||
is_secondary_click_enabled (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return (settings.controls & CLUTTER_A11Y_SECONDARY_CLICK_ENABLED);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_dwell_click_enabled (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return (settings.controls & CLUTTER_A11Y_DWELL_ENABLED);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_secondary_click_delay (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return settings.secondary_click_delay;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_dwell_delay (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return settings.dwell_delay;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_dwell_threshold (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return settings.dwell_threshold;
|
||||
}
|
||||
|
||||
static ClutterPointerA11yDwellMode
|
||||
get_dwell_mode (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return settings.dwell_mode;
|
||||
}
|
||||
|
||||
static ClutterPointerA11yDwellClickType
|
||||
get_dwell_click_type (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
#
|
||||
return settings.dwell_click_type;
|
||||
}
|
||||
|
||||
static ClutterPointerA11yDwellClickType
|
||||
get_dwell_click_type_for_direction (ClutterInputDevice *device,
|
||||
ClutterPointerA11yDwellDirection direction)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
if (direction == settings.dwell_gesture_single)
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
|
||||
else if (direction == settings.dwell_gesture_double)
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE;
|
||||
else if (direction == settings.dwell_gesture_drag)
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG;
|
||||
else if (direction == settings.dwell_gesture_secondary)
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY;
|
||||
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
emit_button_press (ClutterInputDevice *device,
|
||||
gint button)
|
||||
{
|
||||
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
|
||||
g_get_monotonic_time (),
|
||||
button,
|
||||
CLUTTER_BUTTON_STATE_PRESSED);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_button_release (ClutterInputDevice *device,
|
||||
gint button)
|
||||
{
|
||||
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
|
||||
g_get_monotonic_time (),
|
||||
button,
|
||||
CLUTTER_BUTTON_STATE_RELEASED);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_button_click (ClutterInputDevice *device,
|
||||
gint button)
|
||||
{
|
||||
emit_button_press (device, button);
|
||||
emit_button_release (device, button);
|
||||
}
|
||||
|
||||
static void
|
||||
restore_dwell_position (ClutterInputDevice *device)
|
||||
{
|
||||
clutter_virtual_input_device_notify_absolute_motion (device->accessibility_virtual_device,
|
||||
g_get_monotonic_time (),
|
||||
device->ptr_a11y_data->dwell_x,
|
||||
device->ptr_a11y_data->dwell_y);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
trigger_secondary_click (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
|
||||
device->ptr_a11y_data->secondary_click_triggered = TRUE;
|
||||
device->ptr_a11y_data->secondary_click_timer = 0;
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_secondary_click_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
unsigned int delay = get_secondary_click_delay (device);
|
||||
|
||||
device->ptr_a11y_data->secondary_click_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_secondary_click, device);
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-started",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
|
||||
delay);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_secondary_click_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
if (device->ptr_a11y_data->secondary_click_timer)
|
||||
{
|
||||
g_source_remove (device->ptr_a11y_data->secondary_click_timer);
|
||||
device->ptr_a11y_data->secondary_click_timer = 0;
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK);
|
||||
}
|
||||
device->ptr_a11y_data->secondary_click_triggered = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pointer_has_moved (ClutterInputDevice *device)
|
||||
{
|
||||
float dx, dy;
|
||||
gint threshold;
|
||||
|
||||
dx = device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x;
|
||||
dy = device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y;
|
||||
threshold = get_dwell_threshold (device);
|
||||
|
||||
/* Pythagorean theorem */
|
||||
return ((dx * dx) + (dy * dy)) > (threshold * threshold);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_secondary_click_pending (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->secondary_click_timer != 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_secondary_click_triggered (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->secondary_click_triggered;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_dwell_click_pending (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->dwell_timer != 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_dwell_dragging (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->dwell_drag_started;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_dwell_gesturing (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->dwell_gesture_started;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_button_pressed (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->n_btn_pressed > 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_start_secondary_click_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
return !is_dwell_dragging (device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_start_dwell (ClutterInputDevice *device)
|
||||
{
|
||||
/* We should trigger a dwell if we've not already started one, and if
|
||||
* no button is currently pressed or we are in the middle of a dwell
|
||||
* drag action.
|
||||
*/
|
||||
return !is_dwell_click_pending (device) &&
|
||||
(is_dwell_dragging (device) ||
|
||||
!has_button_pressed (device));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_stop_dwell (ClutterInputDevice *device)
|
||||
{
|
||||
/* We should stop a dwell if the motion exceeds the threshold, unless
|
||||
* we've started a gesture, because we want to keep the original dwell
|
||||
* location to both detect a gesture and restore the original pointer
|
||||
* location once the gesture is finished.
|
||||
*/
|
||||
return pointer_has_moved (device) &&
|
||||
!is_dwell_gesturing (device);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
should_update_dwell_position (ClutterInputDevice *device)
|
||||
{
|
||||
return !is_dwell_gesturing (device) &&
|
||||
!is_dwell_click_pending (device) &&
|
||||
!is_secondary_click_pending (device);
|
||||
}
|
||||
|
||||
static void
|
||||
update_dwell_click_type (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterPointerA11yDwellClickType dwell_click_type;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
dwell_click_type = settings.dwell_click_type;
|
||||
switch (dwell_click_type)
|
||||
{
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
|
||||
dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
|
||||
if (!is_dwell_dragging (device))
|
||||
dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (dwell_click_type != settings.dwell_click_type)
|
||||
{
|
||||
settings.dwell_click_type = dwell_click_type;
|
||||
clutter_device_manager_set_pointer_a11y_settings (device->device_manager,
|
||||
&settings);
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-dwell-click-type-changed",
|
||||
dwell_click_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
emit_dwell_click (ClutterInputDevice *device,
|
||||
ClutterPointerA11yDwellClickType dwell_click_type)
|
||||
{
|
||||
switch (dwell_click_type)
|
||||
{
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
|
||||
emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
|
||||
emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
|
||||
emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
|
||||
if (is_dwell_dragging (device))
|
||||
{
|
||||
emit_button_release (device, CLUTTER_BUTTON_PRIMARY);
|
||||
device->ptr_a11y_data->dwell_drag_started = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_button_press (device, CLUTTER_BUTTON_PRIMARY);
|
||||
device->ptr_a11y_data->dwell_drag_started = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
|
||||
emit_button_click (device, CLUTTER_BUTTON_SECONDARY);
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
|
||||
emit_button_click (device, CLUTTER_BUTTON_MIDDLE);
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterPointerA11yDwellDirection
|
||||
get_dwell_direction (ClutterInputDevice *device)
|
||||
{
|
||||
float dx, dy;
|
||||
|
||||
dx = ABS (device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x);
|
||||
dy = ABS (device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y);
|
||||
|
||||
/* The pointer hasn't moved */
|
||||
if (!pointer_has_moved (device))
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_NONE;
|
||||
|
||||
if (device->ptr_a11y_data->dwell_x < device->ptr_a11y_data->current_x)
|
||||
{
|
||||
if (dx > dy)
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dx > dy)
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT;
|
||||
}
|
||||
|
||||
if (device->ptr_a11y_data->dwell_y < device->ptr_a11y_data->current_y)
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_UP;
|
||||
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_DOWN;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
trigger_clear_dwell_gesture (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
|
||||
device->ptr_a11y_data->dwell_timer = 0;
|
||||
device->ptr_a11y_data->dwell_gesture_started = FALSE;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
trigger_dwell_gesture (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
ClutterPointerA11yDwellDirection direction;
|
||||
unsigned int delay = get_dwell_delay (device);
|
||||
|
||||
restore_dwell_position (device);
|
||||
direction = get_dwell_direction (device);
|
||||
emit_dwell_click (device,
|
||||
get_dwell_click_type_for_direction (device,
|
||||
direction));
|
||||
|
||||
/* Do not clear the gesture right away, otherwise we'll start another one */
|
||||
device->ptr_a11y_data->dwell_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_clear_dwell_gesture, device);
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_dwell_gesture_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
unsigned int delay = get_dwell_delay (device);
|
||||
|
||||
device->ptr_a11y_data->dwell_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_dwell_gesture, device);
|
||||
device->ptr_a11y_data->dwell_gesture_started = TRUE;
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-started",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
|
||||
delay);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
trigger_dwell_click (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
|
||||
device->ptr_a11y_data->dwell_timer = 0;
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL);
|
||||
|
||||
if (get_dwell_mode (device) == CLUTTER_A11Y_DWELL_MODE_GESTURE)
|
||||
{
|
||||
if (is_dwell_dragging (device))
|
||||
emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
|
||||
else
|
||||
start_dwell_gesture_timeout (device);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_dwell_click (device, get_dwell_click_type (device));
|
||||
update_dwell_click_type (device);
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_dwell_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
unsigned int delay = get_dwell_delay (device);
|
||||
|
||||
device->ptr_a11y_data->dwell_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_dwell_click, device);
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-started",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
|
||||
delay);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_dwell_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
if (device->ptr_a11y_data->dwell_timer)
|
||||
{
|
||||
g_source_remove (device->ptr_a11y_data->dwell_timer);
|
||||
device->ptr_a11y_data->dwell_timer = 0;
|
||||
device->ptr_a11y_data->dwell_gesture_started = FALSE;
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_dwell_position (ClutterInputDevice *device)
|
||||
{
|
||||
device->ptr_a11y_data->dwell_x = device->ptr_a11y_data->current_x;
|
||||
device->ptr_a11y_data->dwell_y = device->ptr_a11y_data->current_y;
|
||||
}
|
||||
|
||||
static void
|
||||
update_current_position (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
device->ptr_a11y_data->current_x = x;
|
||||
device->ptr_a11y_data->current_y = y;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_device_core_pointer (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
|
||||
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
if (core_pointer == NULL)
|
||||
return FALSE;
|
||||
|
||||
return (core_pointer == device);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_input_pointer_a11y_add_device (ClutterInputDevice *device)
|
||||
{
|
||||
if (!is_device_core_pointer (device))
|
||||
return;
|
||||
|
||||
device->accessibility_virtual_device =
|
||||
clutter_device_manager_create_virtual_device (device->device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
device->ptr_a11y_data = g_new0 (ClutterPtrA11yData, 1);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device)
|
||||
{
|
||||
if (!is_device_core_pointer (device))
|
||||
return;
|
||||
|
||||
/* Terminate a drag if started */
|
||||
if (is_dwell_dragging (device))
|
||||
emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
|
||||
|
||||
stop_dwell_timeout (device);
|
||||
stop_secondary_click_timeout (device);
|
||||
|
||||
g_clear_pointer (&device->ptr_a11y_data, g_free);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
if (!is_device_core_pointer (device))
|
||||
return;
|
||||
|
||||
if (!_clutter_is_input_pointer_a11y_enabled (device))
|
||||
return;
|
||||
|
||||
update_current_position (device, x, y);
|
||||
|
||||
if (is_secondary_click_enabled (device))
|
||||
{
|
||||
if (pointer_has_moved (device))
|
||||
stop_secondary_click_timeout (device);
|
||||
}
|
||||
|
||||
if (is_dwell_click_enabled (device))
|
||||
{
|
||||
if (should_stop_dwell (device))
|
||||
stop_dwell_timeout (device);
|
||||
else if (should_start_dwell (device))
|
||||
start_dwell_timeout (device);
|
||||
}
|
||||
|
||||
if (should_update_dwell_position (device))
|
||||
update_dwell_position (device);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device,
|
||||
int button,
|
||||
gboolean pressed)
|
||||
{
|
||||
if (!is_device_core_pointer (device))
|
||||
return;
|
||||
|
||||
if (!_clutter_is_input_pointer_a11y_enabled (device))
|
||||
return;
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
device->ptr_a11y_data->n_btn_pressed++;
|
||||
|
||||
if (is_dwell_click_enabled (device))
|
||||
stop_dwell_timeout (device);
|
||||
|
||||
if (is_dwell_dragging (device))
|
||||
stop_dwell_timeout (device);
|
||||
|
||||
if (is_secondary_click_enabled (device))
|
||||
{
|
||||
if (button == CLUTTER_BUTTON_PRIMARY)
|
||||
{
|
||||
if (should_start_secondary_click_timeout (device))
|
||||
start_secondary_click_timeout (device);
|
||||
}
|
||||
else if (is_secondary_click_pending (device))
|
||||
{
|
||||
stop_secondary_click_timeout (device);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (has_button_pressed (device))
|
||||
device->ptr_a11y_data->n_btn_pressed--;
|
||||
|
||||
if (is_secondary_click_triggered (device))
|
||||
{
|
||||
emit_button_click (device, CLUTTER_BUTTON_SECONDARY);
|
||||
stop_secondary_click_timeout (device);
|
||||
}
|
||||
|
||||
if (is_secondary_click_pending (device))
|
||||
stop_secondary_click_timeout (device);
|
||||
|
||||
if (is_dwell_dragging (device))
|
||||
emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
||||
|
||||
return (is_secondary_click_enabled (device) || is_dwell_click_enabled (device));
|
||||
}
|
@@ -58,6 +58,7 @@
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-event-private.h"
|
||||
#include "clutter-feature.h"
|
||||
#include "clutter-input-pointer-a11y-private.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-master-clock.h"
|
||||
#include "clutter-mutter.h"
|
||||
@@ -2261,6 +2262,21 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
break;
|
||||
|
||||
case CLUTTER_MOTION:
|
||||
#ifdef CLUTTER_WINDOWING_X11
|
||||
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
||||
{
|
||||
if (_clutter_is_input_pointer_a11y_enabled (device))
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
gfloat x, y;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
_clutter_input_pointer_a11y_on_motion_event (core_pointer, x, y);
|
||||
}
|
||||
}
|
||||
#endif /* CLUTTER_WINDOWING_X11 */
|
||||
/* only the stage gets motion events if they are enabled */
|
||||
if (!clutter_stage_get_motion_events_enabled (CLUTTER_STAGE (stage)) &&
|
||||
event->any.source == NULL)
|
||||
@@ -2299,6 +2315,22 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
/* fallthrough from motion */
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
#ifdef CLUTTER_WINDOWING_X11
|
||||
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
||||
{
|
||||
if (_clutter_is_input_pointer_a11y_enabled (device) && (event->type != CLUTTER_MOTION))
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
|
||||
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
_clutter_input_pointer_a11y_on_button_event (core_pointer,
|
||||
event->button.button,
|
||||
event->type == CLUTTER_BUTTON_PRESS);
|
||||
}
|
||||
}
|
||||
#endif /* CLUTTER_WINDOWING_X11 */
|
||||
case CLUTTER_SCROLL:
|
||||
case CLUTTER_TOUCHPAD_PINCH:
|
||||
case CLUTTER_TOUCHPAD_SWIPE:
|
||||
|
@@ -23,6 +23,7 @@ VOID:FLOAT,FLOAT
|
||||
VOID:INT,INT,INT,INT
|
||||
VOID:OBJECT
|
||||
VOID:OBJECT,FLAGS
|
||||
VOID:OBJECT,FLAGS,UINT
|
||||
VOID:OBJECT,FLOAT,FLOAT
|
||||
VOID:OBJECT,FLOAT,FLOAT,FLAGS
|
||||
VOID:OBJECT,OBJECT
|
||||
|
@@ -64,9 +64,6 @@ struct _ClutterMasterClockDefault
|
||||
/* the current state of the clock, in usecs */
|
||||
gint64 cur_tick;
|
||||
|
||||
/* the previous state of the clock, in usecs, used to compute the delta */
|
||||
gint64 prev_tick;
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
gint64 frame_budget;
|
||||
gint64 remaining_budget;
|
||||
@@ -77,12 +74,6 @@ struct _ClutterMasterClockDefault
|
||||
*/
|
||||
GSource *source;
|
||||
|
||||
/* If the master clock is idle that means it has
|
||||
* fallen back to idle polling for timeline
|
||||
* progressions and it may have been some time since
|
||||
* the last real stage update.
|
||||
*/
|
||||
guint idle : 1;
|
||||
guint ensure_next_iteration : 1;
|
||||
|
||||
guint paused : 1;
|
||||
@@ -275,78 +266,12 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock,
|
||||
static gint
|
||||
master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock)
|
||||
{
|
||||
gint64 now, next;
|
||||
gint swap_delay;
|
||||
|
||||
if (!master_clock_is_running (master_clock))
|
||||
return -1;
|
||||
|
||||
/* If all of the stages are busy waiting for a swap-buffers to complete
|
||||
* then we wait for one to be ready.. */
|
||||
swap_delay = master_clock_get_swap_wait_time (master_clock);
|
||||
if (swap_delay != 0)
|
||||
return swap_delay;
|
||||
|
||||
/* When we have sync-to-vblank, we count on swap-buffer requests (or
|
||||
* swap-buffer-complete events if supported in the backend) to throttle our
|
||||
* frame rate so no additional delay is needed to start the next frame.
|
||||
*
|
||||
* If the master-clock has become idle due to no timeline progression causing
|
||||
* redraws then we can no longer rely on vblank synchronization because the
|
||||
* last real stage update/redraw may have happened a long time ago and so we
|
||||
* fallback to polling for timeline progressions every 1/frame_rate seconds.
|
||||
*
|
||||
* (NB: if there aren't even any timelines running then the master clock will
|
||||
* be completely stopped in master_clock_is_running())
|
||||
*/
|
||||
if (clutter_feature_available (CLUTTER_FEATURE_SWAP_THROTTLE) &&
|
||||
!master_clock->idle)
|
||||
{
|
||||
CLUTTER_NOTE (SCHEDULER, "swap throttling available and updated stages");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (master_clock->prev_tick == 0)
|
||||
{
|
||||
/* If we weren't previously running, then draw the next frame
|
||||
* immediately
|
||||
*/
|
||||
CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise, wait at least 1/frame_rate seconds since we last
|
||||
* started a frame
|
||||
*/
|
||||
now = g_source_get_time (master_clock->source);
|
||||
|
||||
next = master_clock->prev_tick;
|
||||
|
||||
/* If time has gone backwards then there's no way of knowing how
|
||||
long we should wait so let's just dispatch immediately */
|
||||
if (now <= next)
|
||||
{
|
||||
CLUTTER_NOTE (SCHEDULER, "Time has gone backwards");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
next += (1000000L / clutter_get_default_frame_rate ());
|
||||
|
||||
if (next <= now)
|
||||
{
|
||||
CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs",
|
||||
1000000L / (gulong) clutter_get_default_frame_rate ());
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs",
|
||||
(next - now) / 1000);
|
||||
|
||||
return (next - now) / 1000;
|
||||
}
|
||||
return master_clock_get_swap_wait_time (master_clock);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -412,8 +337,7 @@ master_clock_advance_timelines (ClutterMasterClockDefault *master_clock)
|
||||
for (l = timelines; l != NULL; l = l->next)
|
||||
_clutter_timeline_do_tick (l->data, master_clock->cur_tick / 1000);
|
||||
|
||||
g_slist_foreach (timelines, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (timelines);
|
||||
g_slist_free_full (timelines, g_object_unref);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
if (_clutter_diagnostic_enabled ())
|
||||
@@ -531,7 +455,6 @@ clutter_clock_dispatch (GSource *source,
|
||||
{
|
||||
ClutterClockSource *clock_source = (ClutterClockSource *) source;
|
||||
ClutterMasterClockDefault *master_clock = clock_source->master_clock;
|
||||
gboolean stages_updated = FALSE;
|
||||
GSList *stages;
|
||||
|
||||
CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");
|
||||
@@ -551,8 +474,6 @@ clutter_clock_dispatch (GSource *source,
|
||||
*/
|
||||
stages = master_clock_list_ready_stages (master_clock);
|
||||
|
||||
master_clock->idle = FALSE;
|
||||
|
||||
/* Each frame is split into three separate phases: */
|
||||
|
||||
/* 1. process all the events; each stage goes through its events queue
|
||||
@@ -565,19 +486,11 @@ clutter_clock_dispatch (GSource *source,
|
||||
master_clock_advance_timelines (master_clock);
|
||||
|
||||
/* 3. relayout and redraw the stages */
|
||||
stages_updated = master_clock_update_stages (master_clock, stages);
|
||||
|
||||
/* The master clock goes idle if no stages were updated and falls back
|
||||
* to polling for timeline progressions... */
|
||||
if (!stages_updated)
|
||||
master_clock->idle = TRUE;
|
||||
master_clock_update_stages (master_clock, stages);
|
||||
|
||||
master_clock_reschedule_stage_updates (master_clock, stages);
|
||||
|
||||
g_slist_foreach (stages, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (stages);
|
||||
|
||||
master_clock->prev_tick = master_clock->cur_tick;
|
||||
g_slist_free_full (stages, g_object_unref);
|
||||
|
||||
_clutter_threads_release_lock ();
|
||||
|
||||
@@ -610,7 +523,6 @@ clutter_master_clock_default_init (ClutterMasterClockDefault *self)
|
||||
source = clutter_clock_source_new (self);
|
||||
self->source = source;
|
||||
|
||||
self->idle = FALSE;
|
||||
self->ensure_next_iteration = FALSE;
|
||||
self->paused = FALSE;
|
||||
|
||||
|
@@ -43,6 +43,11 @@ void clutter_stage_capture_into (ClutterStage *stage,
|
||||
cairo_rectangle_int_t *rect,
|
||||
uint8_t *data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterStageView * clutter_stage_get_view_at (ClutterStage *stage,
|
||||
float x,
|
||||
float y);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_freeze_updates (ClutterStage *stage);
|
||||
|
||||
|
@@ -295,8 +295,7 @@ clutter_path_clear (ClutterPath *path)
|
||||
{
|
||||
ClutterPathPrivate *priv = path->priv;
|
||||
|
||||
g_slist_foreach (priv->nodes, (GFunc) clutter_path_node_full_free, NULL);
|
||||
g_slist_free (priv->nodes);
|
||||
g_slist_free_full (priv->nodes, (GDestroyNotify) clutter_path_node_full_free);
|
||||
|
||||
priv->nodes = priv->nodes_tail = NULL;
|
||||
priv->nodes_dirty = TRUE;
|
||||
@@ -659,8 +658,7 @@ clutter_path_parse_description (const gchar *p,
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
g_slist_foreach (nodes, (GFunc) clutter_path_node_full_free, NULL);
|
||||
g_slist_free (nodes);
|
||||
g_slist_free_full (nodes, (GDestroyNotify) clutter_path_node_full_free);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@@ -303,6 +303,11 @@ gboolean _clutter_util_matrix_decompose (const ClutterMatrix *src,
|
||||
ClutterVertex *translate_p,
|
||||
ClutterVertex4 *perspective_p);
|
||||
|
||||
PangoDirection _clutter_pango_unichar_direction (gunichar ch);
|
||||
|
||||
PangoDirection _clutter_pango_find_base_dir (const gchar *text,
|
||||
gint length);
|
||||
|
||||
typedef struct _ClutterPlane
|
||||
{
|
||||
float v0[3];
|
||||
|
@@ -2021,8 +2021,7 @@ add_children (ClutterScript *script,
|
||||
clutter_container_add_actor (container, CLUTTER_ACTOR (object));
|
||||
}
|
||||
|
||||
g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
|
||||
g_list_free (oinfo->children);
|
||||
g_list_free_full (oinfo->children, g_free);
|
||||
|
||||
oinfo->children = unresolved;
|
||||
}
|
||||
|
@@ -346,15 +346,12 @@ object_info_free (gpointer data)
|
||||
g_free (oinfo->class_name);
|
||||
g_free (oinfo->type_func);
|
||||
|
||||
g_list_foreach (oinfo->properties, (GFunc) property_info_free, NULL);
|
||||
g_list_free (oinfo->properties);
|
||||
g_list_free_full (oinfo->properties, property_info_free);
|
||||
|
||||
g_list_foreach (oinfo->signals, (GFunc) signal_info_free, NULL);
|
||||
g_list_free (oinfo->signals);
|
||||
g_list_free_full (oinfo->signals, signal_info_free);
|
||||
|
||||
/* these are ids */
|
||||
g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
|
||||
g_list_free (oinfo->children);
|
||||
g_list_free_full (oinfo->children, g_free);
|
||||
|
||||
/* we unref top-level objects and leave the actors alone,
|
||||
* unless we are unmerging in which case we have to destroy
|
||||
@@ -846,8 +843,7 @@ clutter_script_unmerge_objects (ClutterScript *script,
|
||||
for (l = data.ids; l != NULL; l = l->next)
|
||||
g_hash_table_remove (priv->objects, l->data);
|
||||
|
||||
g_slist_foreach (data.ids, (GFunc) g_free, NULL);
|
||||
g_slist_free (data.ids);
|
||||
g_slist_free_full (data.ids, g_free);
|
||||
|
||||
clutter_script_ensure_objects (script);
|
||||
}
|
||||
|
@@ -89,8 +89,8 @@ clutter_stage_manager_dispose (GObject *gobject)
|
||||
|
||||
stage_manager = CLUTTER_STAGE_MANAGER (gobject);
|
||||
|
||||
g_slist_foreach (stage_manager->stages, (GFunc) clutter_actor_destroy, NULL);
|
||||
g_slist_free (stage_manager->stages);
|
||||
g_slist_free_full (stage_manager->stages,
|
||||
(GDestroyNotify) clutter_actor_destroy);
|
||||
stage_manager->stages = NULL;
|
||||
|
||||
G_OBJECT_CLASS (clutter_stage_manager_parent_class)->dispose (gobject);
|
||||
|
@@ -75,6 +75,7 @@
|
||||
#include "clutter-private.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
#include "cogl/cogl-trace.h"
|
||||
|
||||
/* <private>
|
||||
* ClutterStageHint:
|
||||
@@ -688,6 +689,8 @@ _clutter_stage_paint_view (ClutterStage *stage,
|
||||
if (!priv->impl)
|
||||
return;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterStagePaintView, "Paint (view)");
|
||||
|
||||
clutter_stage_do_paint_view (stage, view, clip);
|
||||
g_signal_emit (stage, stage_signals[AFTER_PAINT], 0);
|
||||
}
|
||||
@@ -1225,22 +1228,31 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
||||
return FALSE;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterStageDoUpdate, "Update");
|
||||
|
||||
/* NB: We need to ensure we have an up to date layout *before* we
|
||||
* check or clear the pending redraws flag since a relayout may
|
||||
* queue a redraw.
|
||||
*/
|
||||
COGL_TRACE_BEGIN (ClutterStageRelayout, "Layout");
|
||||
|
||||
_clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage));
|
||||
|
||||
COGL_TRACE_END (ClutterStageRelayout);
|
||||
|
||||
if (!priv->redraw_pending)
|
||||
return FALSE;
|
||||
|
||||
if (stage_was_relayout)
|
||||
pointers = _clutter_stage_check_updated_pointers (stage);
|
||||
|
||||
clutter_stage_maybe_finish_queue_redraws (stage);
|
||||
COGL_TRACE_BEGIN (ClutterStagePaint, "Paint");
|
||||
|
||||
clutter_stage_maybe_finish_queue_redraws (stage);
|
||||
clutter_stage_do_redraw (stage);
|
||||
|
||||
COGL_TRACE_END (ClutterStagePaint);
|
||||
|
||||
/* reset the guard, so that new redraws are possible */
|
||||
priv->redraw_pending = FALSE;
|
||||
|
||||
@@ -1254,12 +1266,16 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
}
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterStagePick, "Pick");
|
||||
|
||||
while (pointers)
|
||||
{
|
||||
_clutter_input_device_update (pointers->data, NULL, TRUE);
|
||||
pointers = g_slist_delete_link (pointers, pointers);
|
||||
}
|
||||
|
||||
COGL_TRACE_END (ClutterStagePick);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1303,14 +1319,8 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
|
||||
return TRUE;
|
||||
|
||||
if (_clutter_stage_window_ignoring_redraw_clips (stage_window))
|
||||
{
|
||||
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
/* Convert the clip volume into stage coordinates and then into an
|
||||
* axis aligned stage coordinates bounding box...
|
||||
*/
|
||||
if (redraw_clip == NULL)
|
||||
{
|
||||
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
|
||||
@@ -1320,6 +1330,8 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
|
||||
if (redraw_clip->is_empty)
|
||||
return TRUE;
|
||||
|
||||
/* Convert the clip volume into stage coordinates and then into an
|
||||
* axis aligned stage coordinates bounding box... */
|
||||
_clutter_paint_volume_get_stage_paint_box (redraw_clip,
|
||||
stage,
|
||||
&bounding_box);
|
||||
@@ -1574,10 +1586,13 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static ClutterStageView *
|
||||
get_view_at (ClutterStage *stage,
|
||||
int x,
|
||||
int y)
|
||||
/**
|
||||
* clutter_stage_get_view_at: (skip)
|
||||
*/
|
||||
ClutterStageView *
|
||||
clutter_stage_get_view_at (ClutterStage *stage,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
GList *l;
|
||||
@@ -1624,7 +1639,7 @@ _clutter_stage_do_pick (ClutterStage *stage,
|
||||
if (x < 0 || x >= stage_width || y < 0 || y >= stage_height)
|
||||
return actor;
|
||||
|
||||
view = get_view_at (stage, x, y);
|
||||
view = clutter_stage_get_view_at (stage, x, y);
|
||||
if (view)
|
||||
return _clutter_stage_do_pick_on_view (stage, x, y, mode, view);
|
||||
|
||||
@@ -2949,6 +2964,8 @@ clutter_stage_read_pixels (ClutterStage *stage,
|
||||
float pixel_height;
|
||||
uint8_t *pixels;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterStageReadPixels, "Read Pixels");
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||
|
||||
priv = stage->priv;
|
||||
@@ -3014,7 +3031,11 @@ clutter_stage_read_pixels (ClutterStage *stage,
|
||||
* @y: Y coordinate to check
|
||||
*
|
||||
* Checks the scene at the coordinates @x and @y and returns a pointer
|
||||
* to the #ClutterActor at those coordinates.
|
||||
* to the #ClutterActor at those coordinates. The result is the actor which
|
||||
* would be at the specified location on the next redraw, and is not
|
||||
* necessarily that which was there on the previous redraw. This allows the
|
||||
* function to perform chronologically correctly after any queued changes to
|
||||
* the scene, and even if nothing has been drawn.
|
||||
*
|
||||
* By using @pick_mode it is possible to control which actors will be
|
||||
* painted and thus available.
|
||||
|
@@ -751,7 +751,7 @@ clutter_text_create_layout_no_cache (ClutterText *text,
|
||||
if (priv->password_char != 0)
|
||||
pango_dir = PANGO_DIRECTION_NEUTRAL;
|
||||
else
|
||||
pango_dir = pango_find_base_dir (contents, contents_len);
|
||||
pango_dir = _clutter_pango_find_base_dir (contents, contents_len);
|
||||
|
||||
if (pango_dir == PANGO_DIRECTION_NEUTRAL)
|
||||
{
|
||||
@@ -1975,6 +1975,7 @@ selection_paint (ClutterText *self,
|
||||
else
|
||||
{
|
||||
/* Paint selection background first */
|
||||
CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline);
|
||||
PangoLayout *layout = clutter_text_get_layout (self);
|
||||
CoglPath *selection_path = cogl_path_new ();
|
||||
CoglColor cogl_color = { 0, };
|
||||
@@ -1987,11 +1988,19 @@ selection_paint (ClutterText *self,
|
||||
else
|
||||
color = &priv->text_color;
|
||||
|
||||
cogl_color_init_from_4ub (&cogl_color,
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
paint_opacity * color->alpha / 255);
|
||||
cogl_color_premultiply (&cogl_color);
|
||||
cogl_pipeline_set_color (color_pipeline, &cogl_color);
|
||||
|
||||
clutter_text_foreach_selection_rectangle_prescaled (self,
|
||||
add_selection_rectangle_to_path,
|
||||
selection_path);
|
||||
|
||||
cogl_path_fill (selection_path);
|
||||
cogl_framebuffer_fill_path (fb, color_pipeline, selection_path);
|
||||
|
||||
/* Paint selected text */
|
||||
cogl_framebuffer_push_path_clip (fb, selection_path);
|
||||
|
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <fribidi.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter-debug.h"
|
||||
@@ -105,8 +106,9 @@ _clutter_util_fully_transform_vertices (const CoglMatrix *modelview,
|
||||
}
|
||||
}
|
||||
|
||||
void _clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
|
||||
ClutterRect *dest)
|
||||
void
|
||||
_clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
|
||||
ClutterRect *dest)
|
||||
{
|
||||
*dest = (ClutterRect) {
|
||||
.origin = {
|
||||
@@ -120,8 +122,9 @@ void _clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
|
||||
};
|
||||
}
|
||||
|
||||
void _clutter_util_rectangle_int_extents (const ClutterRect *src,
|
||||
cairo_rectangle_int_t *dest)
|
||||
void
|
||||
_clutter_util_rectangle_int_extents (const ClutterRect *src,
|
||||
cairo_rectangle_int_t *dest)
|
||||
{
|
||||
ClutterRect tmp = *src;
|
||||
|
||||
@@ -135,10 +138,11 @@ void _clutter_util_rectangle_int_extents (const ClutterRect *src,
|
||||
};
|
||||
}
|
||||
|
||||
void _clutter_util_rectangle_offset (const cairo_rectangle_int_t *src,
|
||||
int x,
|
||||
int y,
|
||||
cairo_rectangle_int_t *dest)
|
||||
void
|
||||
_clutter_util_rectangle_offset (const cairo_rectangle_int_t *src,
|
||||
int x,
|
||||
int y,
|
||||
cairo_rectangle_int_t *dest)
|
||||
{
|
||||
*dest = *src;
|
||||
|
||||
@@ -696,3 +700,45 @@ clutter_interval_register_progress_func (GType value_type,
|
||||
|
||||
G_UNLOCK (progress_funcs);
|
||||
}
|
||||
|
||||
PangoDirection
|
||||
_clutter_pango_unichar_direction (gunichar ch)
|
||||
{
|
||||
FriBidiCharType fribidi_ch_type;
|
||||
|
||||
G_STATIC_ASSERT (sizeof (FriBidiChar) == sizeof (gunichar));
|
||||
|
||||
fribidi_ch_type = fribidi_get_bidi_type (ch);
|
||||
|
||||
if (!FRIBIDI_IS_STRONG (fribidi_ch_type))
|
||||
return PANGO_DIRECTION_NEUTRAL;
|
||||
else if (FRIBIDI_IS_RTL (fribidi_ch_type))
|
||||
return PANGO_DIRECTION_RTL;
|
||||
else
|
||||
return PANGO_DIRECTION_LTR;
|
||||
}
|
||||
|
||||
PangoDirection
|
||||
_clutter_pango_find_base_dir (const gchar *text,
|
||||
gint length)
|
||||
{
|
||||
PangoDirection dir = PANGO_DIRECTION_NEUTRAL;
|
||||
const gchar *p;
|
||||
|
||||
g_return_val_if_fail (text != NULL || length == 0, PANGO_DIRECTION_NEUTRAL);
|
||||
|
||||
p = text;
|
||||
while ((length < 0 || p < text + length) && *p)
|
||||
{
|
||||
gunichar wc = g_utf8_get_char (p);
|
||||
|
||||
dir = _clutter_pango_unichar_direction (wc);
|
||||
|
||||
if (dir != PANGO_DIRECTION_NEUTRAL)
|
||||
break;
|
||||
|
||||
p = g_utf8_next_char (p);
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
@@ -46,6 +46,8 @@
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-stage-private.h"
|
||||
|
||||
#include "cogl/cogl-trace.h"
|
||||
|
||||
typedef struct _ClutterStageViewCoglPrivate
|
||||
{
|
||||
/*
|
||||
@@ -77,6 +79,10 @@ enum
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static void
|
||||
clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
|
||||
gint sync_delay);
|
||||
|
||||
static void
|
||||
clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window)
|
||||
{
|
||||
@@ -122,6 +128,16 @@ _clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl,
|
||||
}
|
||||
|
||||
_clutter_stage_presented (stage_cogl->wrapper, frame_event, frame_info);
|
||||
|
||||
if (frame_event == COGL_FRAME_EVENT_COMPLETE &&
|
||||
stage_cogl->update_time != -1)
|
||||
{
|
||||
ClutterStageWindow *stage_window = CLUTTER_STAGE_WINDOW (stage_cogl);
|
||||
|
||||
stage_cogl->update_time = -1;
|
||||
clutter_stage_cogl_schedule_update (stage_window,
|
||||
stage_cogl->last_sync_delay);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -152,10 +168,15 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
|
||||
gint64 now;
|
||||
float refresh_rate;
|
||||
gint64 refresh_interval;
|
||||
int64_t min_render_time_allowed;
|
||||
int64_t max_render_time_allowed;
|
||||
int64_t next_presentation_time;
|
||||
|
||||
if (stage_cogl->update_time != -1)
|
||||
return;
|
||||
|
||||
stage_cogl->last_sync_delay = sync_delay;
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
|
||||
if (sync_delay < 0)
|
||||
@@ -164,30 +185,56 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
|
||||
return;
|
||||
}
|
||||
|
||||
/* We only extrapolate presentation times for 150ms - this is somewhat
|
||||
* arbitrary. The reasons it might not be accurate for larger times are
|
||||
* that the refresh interval might be wrong or the vertical refresh
|
||||
* might be downclocked if nothing is going on onscreen.
|
||||
*/
|
||||
if (stage_cogl->last_presentation_time == 0||
|
||||
stage_cogl->last_presentation_time < now - 150000)
|
||||
refresh_rate = stage_cogl->refresh_rate;
|
||||
if (refresh_rate <= 0.0)
|
||||
refresh_rate = clutter_get_default_frame_rate ();
|
||||
|
||||
refresh_interval = (gint64) (0.5 + G_USEC_PER_SEC / refresh_rate);
|
||||
if (refresh_interval == 0)
|
||||
{
|
||||
stage_cogl->update_time = now;
|
||||
return;
|
||||
}
|
||||
|
||||
refresh_rate = stage_cogl->refresh_rate;
|
||||
if (refresh_rate == 0.0)
|
||||
refresh_rate = 60.0;
|
||||
min_render_time_allowed = refresh_interval / 2;
|
||||
max_render_time_allowed = refresh_interval - 1000 * sync_delay;
|
||||
|
||||
refresh_interval = (gint64) (0.5 + 1000000 / refresh_rate);
|
||||
if (refresh_interval == 0)
|
||||
refresh_interval = 16667; /* 1/60th second */
|
||||
/* Be robust in the case of incredibly bogus refresh rate */
|
||||
if (max_render_time_allowed <= 0)
|
||||
{
|
||||
g_warning ("Unsupported monitor refresh rate detected. "
|
||||
"(Refresh rate: %.3f, refresh interval: %ld)",
|
||||
refresh_rate,
|
||||
refresh_interval);
|
||||
stage_cogl->update_time = now;
|
||||
return;
|
||||
}
|
||||
|
||||
stage_cogl->update_time = stage_cogl->last_presentation_time + 1000 * sync_delay;
|
||||
if (min_render_time_allowed > max_render_time_allowed)
|
||||
min_render_time_allowed = max_render_time_allowed;
|
||||
|
||||
while (stage_cogl->update_time < now)
|
||||
stage_cogl->update_time += refresh_interval;
|
||||
next_presentation_time = stage_cogl->last_presentation_time + refresh_interval;
|
||||
|
||||
/* Get next_presentation_time closer to its final value, to reduce
|
||||
* the number of while iterations below.
|
||||
*/
|
||||
if (next_presentation_time < now)
|
||||
{
|
||||
int64_t last_virtual_presentation_time = now - now % refresh_interval;
|
||||
int64_t hardware_clock_phase =
|
||||
stage_cogl->last_presentation_time % refresh_interval;
|
||||
|
||||
next_presentation_time =
|
||||
last_virtual_presentation_time + hardware_clock_phase;
|
||||
}
|
||||
|
||||
while (next_presentation_time < now + min_render_time_allowed)
|
||||
next_presentation_time += refresh_interval;
|
||||
|
||||
stage_cogl->update_time = next_presentation_time - max_render_time_allowed;
|
||||
|
||||
if (stage_cogl->update_time == stage_cogl->last_update_time)
|
||||
stage_cogl->update_time = stage_cogl->last_update_time + refresh_interval;
|
||||
}
|
||||
|
||||
static gint64
|
||||
@@ -206,6 +253,7 @@ clutter_stage_cogl_clear_update_time (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||
|
||||
stage_cogl->last_update_time = stage_cogl->update_time;
|
||||
stage_cogl->update_time = -1;
|
||||
}
|
||||
|
||||
@@ -273,7 +321,7 @@ clutter_stage_cogl_ignoring_redraw_clips (ClutterStageWindow *stage_window)
|
||||
}
|
||||
|
||||
/* A redraw clip represents (in stage coordinates) the bounding box of
|
||||
* something that needs to be redraw. Typically they are added to the
|
||||
* something that needs to be redrawn. Typically they are added to the
|
||||
* StageWindow as a result of clutter_actor_queue_clipped_redraw() by
|
||||
* actors such as ClutterGLXTexturePixmap. All redraw clips are
|
||||
* discarded after the next paint.
|
||||
@@ -502,8 +550,8 @@ fill_current_damage_history_and_step (ClutterStageView *view)
|
||||
*current_fb_damage = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = view_rect.width * fb_scale,
|
||||
.height = view_rect.height * fb_scale
|
||||
.width = ceilf (view_rect.width * fb_scale),
|
||||
.height = ceilf (view_rect.height * fb_scale)
|
||||
};
|
||||
view_priv->damage_index++;
|
||||
}
|
||||
@@ -878,26 +926,16 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
*/
|
||||
if (use_clipped_redraw)
|
||||
{
|
||||
if (use_clipped_redraw && clip_region_empty)
|
||||
if (clip_region_empty)
|
||||
{
|
||||
do_swap_buffer = FALSE;
|
||||
}
|
||||
else if (use_clipped_redraw)
|
||||
else
|
||||
{
|
||||
swap_region = fb_clip_region;
|
||||
g_assert (swap_region.width > 0);
|
||||
do_swap_buffer = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
swap_region = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = view_rect.width * fb_scale,
|
||||
.height = view_rect.height * fb_scale,
|
||||
};
|
||||
do_swap_buffer = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -907,6 +945,9 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
|
||||
if (do_swap_buffer)
|
||||
{
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterStageCoglRedrawViewSwapFramebuffer,
|
||||
"Paint (swap framebuffer)");
|
||||
|
||||
if (clutter_stage_view_get_onscreen (view) !=
|
||||
clutter_stage_view_get_framebuffer (view))
|
||||
{
|
||||
@@ -931,6 +972,8 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
gboolean swap_event = FALSE;
|
||||
GList *l;
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterStageCoglRedraw, "Paint (Cogl Redraw)");
|
||||
|
||||
for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
@@ -954,6 +997,8 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
stage_cogl->initialized_redraw_clip = FALSE;
|
||||
|
||||
stage_cogl->frame_count++;
|
||||
|
||||
COGL_TRACE_END (ClutterStageCoglRedraw);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -53,12 +53,15 @@ struct _ClutterStageCogl
|
||||
|
||||
gint64 last_presentation_time;
|
||||
gint64 update_time;
|
||||
int64_t last_update_time;
|
||||
|
||||
/* We only enable clipped redraws after 2 frames, since we've seen
|
||||
* a lot of drivers can struggle to get going and may output some
|
||||
* junk frames to start with. */
|
||||
unsigned int frame_count;
|
||||
|
||||
gint last_sync_delay;
|
||||
|
||||
cairo_rectangle_int_t bounding_redraw_clip;
|
||||
|
||||
guint initialized_redraw_clip : 1;
|
||||
|
@@ -739,31 +739,33 @@ get_button_index (gint button)
|
||||
}
|
||||
|
||||
static void
|
||||
emulate_button_press (ClutterInputDeviceEvdev *device)
|
||||
emulate_button_press (ClutterInputDeviceEvdev *device_evdev)
|
||||
{
|
||||
gint btn = device->mousekeys_btn;
|
||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||
gint btn = device_evdev->mousekeys_btn;
|
||||
|
||||
if (device->mousekeys_btn_states[get_button_index (btn)])
|
||||
if (device_evdev->mousekeys_btn_states[get_button_index (btn)])
|
||||
return;
|
||||
|
||||
clutter_virtual_input_device_notify_button (device->mousekeys_virtual_device,
|
||||
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
|
||||
g_get_monotonic_time (), btn,
|
||||
CLUTTER_BUTTON_STATE_PRESSED);
|
||||
device->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_PRESSED;
|
||||
device_evdev->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_PRESSED;
|
||||
}
|
||||
|
||||
static void
|
||||
emulate_button_release (ClutterInputDeviceEvdev *device)
|
||||
emulate_button_release (ClutterInputDeviceEvdev *device_evdev)
|
||||
{
|
||||
gint btn = device->mousekeys_btn;
|
||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||
gint btn = device_evdev->mousekeys_btn;
|
||||
|
||||
if (device->mousekeys_btn_states[get_button_index (btn)] == CLUTTER_BUTTON_STATE_RELEASED)
|
||||
if (device_evdev->mousekeys_btn_states[get_button_index (btn)] == CLUTTER_BUTTON_STATE_RELEASED)
|
||||
return;
|
||||
|
||||
clutter_virtual_input_device_notify_button (device->mousekeys_virtual_device,
|
||||
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
|
||||
g_get_monotonic_time (), btn,
|
||||
CLUTTER_BUTTON_STATE_RELEASED);
|
||||
device->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_RELEASED;
|
||||
device_evdev->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_RELEASED;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -830,17 +832,18 @@ mousekeys_get_speed_factor (ClutterInputDeviceEvdev *device,
|
||||
#undef MOUSEKEYS_CURVE
|
||||
|
||||
static void
|
||||
emulate_pointer_motion (ClutterInputDeviceEvdev *device,
|
||||
emulate_pointer_motion (ClutterInputDeviceEvdev *device_evdev,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||
gdouble dx_motion;
|
||||
gdouble dy_motion;
|
||||
gdouble speed;
|
||||
gint64 time_us;
|
||||
|
||||
time_us = g_get_monotonic_time ();
|
||||
speed = mousekeys_get_speed_factor (device, time_us);
|
||||
speed = mousekeys_get_speed_factor (device_evdev, time_us);
|
||||
|
||||
if (dx < 0)
|
||||
dx_motion = floor (((gdouble) dx) * speed);
|
||||
@@ -852,7 +855,7 @@ emulate_pointer_motion (ClutterInputDeviceEvdev *device,
|
||||
else
|
||||
dy_motion = ceil (((gdouble) dy) * speed);
|
||||
|
||||
clutter_virtual_input_device_notify_relative_motion (device->mousekeys_virtual_device,
|
||||
clutter_virtual_input_device_notify_relative_motion (device->accessibility_virtual_device,
|
||||
time_us, dx_motion, dy_motion);
|
||||
}
|
||||
static gboolean
|
||||
@@ -865,51 +868,53 @@ is_numlock_active (ClutterInputDeviceEvdev *device)
|
||||
}
|
||||
|
||||
static void
|
||||
enable_mousekeys (ClutterInputDeviceEvdev *device)
|
||||
enable_mousekeys (ClutterInputDeviceEvdev *device_evdev)
|
||||
{
|
||||
ClutterDeviceManager *manager;
|
||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||
ClutterDeviceManager *manager = device->device_manager;
|
||||
|
||||
device->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
|
||||
device->move_mousekeys_timer = 0;
|
||||
device->mousekeys_first_motion_time = 0;
|
||||
device->mousekeys_last_motion_time = 0;
|
||||
device->last_mousekeys_key = 0;
|
||||
device_evdev->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
|
||||
device_evdev->move_mousekeys_timer = 0;
|
||||
device_evdev->mousekeys_first_motion_time = 0;
|
||||
device_evdev->mousekeys_last_motion_time = 0;
|
||||
device_evdev->last_mousekeys_key = 0;
|
||||
|
||||
if (device->mousekeys_virtual_device)
|
||||
if (device->accessibility_virtual_device)
|
||||
return;
|
||||
|
||||
manager = CLUTTER_INPUT_DEVICE (device)->device_manager;
|
||||
device->mousekeys_virtual_device =
|
||||
device->accessibility_virtual_device =
|
||||
clutter_device_manager_create_virtual_device (manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
}
|
||||
|
||||
static void
|
||||
disable_mousekeys (ClutterInputDeviceEvdev *device)
|
||||
disable_mousekeys (ClutterInputDeviceEvdev *device_evdev)
|
||||
{
|
||||
stop_mousekeys_move (device);
|
||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||
|
||||
stop_mousekeys_move (device_evdev);
|
||||
|
||||
/* Make sure we don't leave button pressed behind... */
|
||||
if (device->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_PRIMARY)])
|
||||
if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_PRIMARY)])
|
||||
{
|
||||
device->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
|
||||
emulate_button_release (device);
|
||||
device_evdev->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
|
||||
emulate_button_release (device_evdev);
|
||||
}
|
||||
|
||||
if (device->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_MIDDLE)])
|
||||
if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_MIDDLE)])
|
||||
{
|
||||
device->mousekeys_btn = CLUTTER_BUTTON_MIDDLE;
|
||||
emulate_button_release (device);
|
||||
device_evdev->mousekeys_btn = CLUTTER_BUTTON_MIDDLE;
|
||||
emulate_button_release (device_evdev);
|
||||
}
|
||||
|
||||
if (device->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_SECONDARY)])
|
||||
if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_SECONDARY)])
|
||||
{
|
||||
device->mousekeys_btn = CLUTTER_BUTTON_SECONDARY;
|
||||
emulate_button_release (device);
|
||||
device_evdev->mousekeys_btn = CLUTTER_BUTTON_SECONDARY;
|
||||
emulate_button_release (device_evdev);
|
||||
}
|
||||
|
||||
if (device->mousekeys_virtual_device)
|
||||
g_clear_object (&device->mousekeys_virtual_device);
|
||||
if (device->accessibility_virtual_device)
|
||||
g_clear_object (&device->accessibility_virtual_device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@@ -94,7 +94,6 @@ struct _ClutterInputDeviceEvdev
|
||||
gdouble mousekeys_curve_factor;
|
||||
guint move_mousekeys_timer;
|
||||
guint16 last_mousekeys_key;
|
||||
ClutterVirtualInputDevice *mousekeys_virtual_device;
|
||||
};
|
||||
|
||||
GType _clutter_input_device_evdev_get_type (void) G_GNUC_CONST;
|
||||
|
@@ -133,6 +133,7 @@ clutter_sources = [
|
||||
'clutter-input-device-tool.c',
|
||||
'clutter-input-focus.c',
|
||||
'clutter-input-method.c',
|
||||
'clutter-input-pointer-a11y.c',
|
||||
'clutter-virtual-input-device.c',
|
||||
'clutter-interval.c',
|
||||
'clutter-keyframe-transition.c',
|
||||
@@ -195,6 +196,7 @@ clutter_private_headers = [
|
||||
'clutter-id-pool.h',
|
||||
'clutter-input-focus-private.h',
|
||||
'clutter-input-method-private.h',
|
||||
'clutter-input-pointer-a11y-private.h',
|
||||
'clutter-master-clock.h',
|
||||
'clutter-master-clock-default.h',
|
||||
'clutter-offscreen-effect-private.h',
|
||||
@@ -504,7 +506,12 @@ libmutter_clutter_dep = declare_dependency(
|
||||
)
|
||||
|
||||
if have_introspection
|
||||
clutter_introspection_args = introspection_args + clutter_c_args
|
||||
clutter_introspection_args = introspection_args + [
|
||||
'-DCLUTTER_SYSCONFDIR="@0@"'.format(join_paths(prefix, sysconfdir)),
|
||||
'-DCLUTTER_COMPILATION=1',
|
||||
'-DCOGL_DISABLE_DEPRECATION_WARNINGS',
|
||||
'-DG_LOG_DOMAIN="Clutter"'
|
||||
]
|
||||
|
||||
libmutter_clutter_gir = gnome.generate_gir(libmutter_clutter,
|
||||
sources: [
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "clutter-backend-x11.h"
|
||||
#include "clutter-input-device-xi2.h"
|
||||
#include "clutter-input-device-tool-xi2.h"
|
||||
#include "clutter-input-pointer-a11y-private.h"
|
||||
#include "clutter-virtual-input-device-x11.h"
|
||||
#include "clutter-stage-x11.h"
|
||||
|
||||
@@ -1273,6 +1274,60 @@ translate_pad_event (ClutterEvent *event,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_raw_event (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
XEvent *xevent)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
XGenericEventCookie *cookie;
|
||||
XIEvent *xi_event;
|
||||
XIRawEvent *xev;
|
||||
float x,y;
|
||||
|
||||
cookie = &xevent->xcookie;
|
||||
xi_event = (XIEvent *) cookie->data;
|
||||
xev = (XIRawEvent *) xi_event;
|
||||
|
||||
device = g_hash_table_lookup (manager_xi2->devices_by_id,
|
||||
GINT_TO_POINTER (xev->deviceid));
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
if (!_clutter_is_input_pointer_a11y_enabled (device))
|
||||
return;
|
||||
|
||||
switch (cookie->evtype)
|
||||
{
|
||||
case XI_RawMotion:
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"raw motion: device:%d '%s'",
|
||||
device->id,
|
||||
device->device_name);
|
||||
/* We don't get actual pointer location with raw events, and we cannot
|
||||
* rely on `clutter_input_device_get_coords()` either because of
|
||||
* unreparented toplevels (like all client-side decoration windows),
|
||||
* so we need to explicitely query the pointer here...
|
||||
*/
|
||||
if (clutter_input_device_xi2_get_pointer_location (device, &x, &y))
|
||||
_clutter_input_pointer_a11y_on_motion_event (device, x, y);
|
||||
break;
|
||||
case XI_RawButtonPress:
|
||||
case XI_RawButtonRelease:
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"raw button %s: device:%d '%s' button %i",
|
||||
cookie->evtype == XI_RawButtonPress
|
||||
? "press "
|
||||
: "release",
|
||||
device->id,
|
||||
device->device_name,
|
||||
xev->detail);
|
||||
_clutter_input_pointer_a11y_on_button_event (device,
|
||||
xev->detail,
|
||||
(cookie->evtype == XI_RawButtonPress));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterTranslateReturn
|
||||
clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
gpointer native,
|
||||
@@ -1303,6 +1358,14 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
if (!xi_event)
|
||||
return CLUTTER_TRANSLATE_REMOVE;
|
||||
|
||||
if (cookie->evtype == XI_RawMotion ||
|
||||
cookie->evtype == XI_RawButtonPress ||
|
||||
cookie->evtype == XI_RawButtonRelease)
|
||||
{
|
||||
handle_raw_event (manager_xi2, xevent);
|
||||
return CLUTTER_TRANSLATE_REMOVE;
|
||||
}
|
||||
|
||||
if (!(xi_event->evtype == XI_HierarchyChanged ||
|
||||
xi_event->evtype == XI_DeviceChanged ||
|
||||
xi_event->evtype == XI_PropertyEvent))
|
||||
@@ -2031,7 +2094,7 @@ clutter_device_manager_xi2_constructed (GObject *gobject)
|
||||
GHashTable *masters, *slaves;
|
||||
XIDeviceInfo *info;
|
||||
XIEventMask event_mask;
|
||||
unsigned char mask[2] = { 0, };
|
||||
unsigned char mask[(XI_LASTEVENT + 7) / 8] = { 0, };
|
||||
int n_devices, i;
|
||||
|
||||
backend_x11 =
|
||||
@@ -2083,6 +2146,19 @@ clutter_device_manager_xi2_constructed (GObject *gobject)
|
||||
event_mask.mask_len = sizeof (mask);
|
||||
event_mask.mask = mask;
|
||||
|
||||
clutter_device_manager_xi2_select_events (manager,
|
||||
clutter_x11_get_root_window (),
|
||||
&event_mask);
|
||||
|
||||
memset(mask, 0, sizeof (mask));
|
||||
XISetMask (mask, XI_RawMotion);
|
||||
XISetMask (mask, XI_RawButtonPress);
|
||||
XISetMask (mask, XI_RawButtonRelease);
|
||||
|
||||
event_mask.deviceid = XIAllMasterDevices;
|
||||
event_mask.mask_len = sizeof (mask);
|
||||
event_mask.mask = mask;
|
||||
|
||||
clutter_device_manager_xi2_select_events (manager,
|
||||
clutter_x11_get_root_window (),
|
||||
&event_mask);
|
||||
|
@@ -46,6 +46,11 @@ struct _ClutterInputDeviceXI2
|
||||
gint device_id;
|
||||
ClutterInputDeviceTool *current_tool;
|
||||
|
||||
guint inhibit_pointer_query_timer;
|
||||
gboolean query_status;
|
||||
float current_x;
|
||||
float current_y;
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
WacomDevice *wacom_device;
|
||||
GArray *group_modes;
|
||||
@@ -112,6 +117,9 @@ clutter_input_device_xi2_finalize (GObject *object)
|
||||
|
||||
if (device_xi2->group_modes)
|
||||
g_array_unref (device_xi2->group_modes);
|
||||
|
||||
if (device_xi2->inhibit_pointer_query_timer)
|
||||
g_source_remove (device_xi2->inhibit_pointer_query_timer);
|
||||
#endif
|
||||
|
||||
G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object);
|
||||
@@ -293,6 +301,75 @@ clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device)
|
||||
return device_xi2->current_tool;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_input_device_xi2_query_pointer_location (ClutterInputDeviceXI2 *device_xi2)
|
||||
{
|
||||
Window xroot_window, xchild_window;
|
||||
double xroot_x, xroot_y, xwin_x, xwin_y;
|
||||
XIButtonState button_state;
|
||||
XIModifierState mod_state;
|
||||
XIGroupState group_state;
|
||||
int result;
|
||||
|
||||
clutter_x11_trap_x_errors ();
|
||||
result = XIQueryPointer (clutter_x11_get_default_display (),
|
||||
device_xi2->device_id,
|
||||
clutter_x11_get_root_window (),
|
||||
&xroot_window,
|
||||
&xchild_window,
|
||||
&xroot_x, &xroot_y,
|
||||
&xwin_x, &xwin_y,
|
||||
&button_state,
|
||||
&mod_state,
|
||||
&group_state);
|
||||
clutter_x11_untrap_x_errors ();
|
||||
|
||||
if (!result)
|
||||
return FALSE;
|
||||
|
||||
device_xi2->current_x = (float) xroot_x;
|
||||
device_xi2->current_y = (float) xroot_y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clear_inhibit_pointer_query_cb (gpointer data)
|
||||
{
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (data);
|
||||
|
||||
device_xi2->inhibit_pointer_query_timer = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_input_device_xi2_get_pointer_location (ClutterInputDevice *device,
|
||||
float *x,
|
||||
float *y)
|
||||
|
||||
{
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_XI2 (device_xi2), FALSE);
|
||||
g_return_val_if_fail (device->device_type == CLUTTER_POINTER_DEVICE, FALSE);
|
||||
|
||||
/* Throttle XServer queries and roundtrips using an idle timeout */
|
||||
if (device_xi2->inhibit_pointer_query_timer == 0)
|
||||
{
|
||||
device_xi2->query_status =
|
||||
clutter_input_device_xi2_query_pointer_location (device_xi2);
|
||||
device_xi2->inhibit_pointer_query_timer =
|
||||
clutter_threads_add_idle (clear_inhibit_pointer_query_cb, device_xi2);
|
||||
}
|
||||
|
||||
*x = device_xi2->current_x;
|
||||
*y = device_xi2->current_y;
|
||||
|
||||
return device_xi2->query_status;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
void
|
||||
clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device,
|
||||
|
@@ -48,6 +48,9 @@ void _clutter_input_device_xi2_translate_state (ClutterEvent *event,
|
||||
void clutter_input_device_xi2_update_tool (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool);
|
||||
ClutterInputDeviceTool * clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device);
|
||||
gboolean clutter_input_device_xi2_get_pointer_location (ClutterInputDevice *device,
|
||||
float *x,
|
||||
float *y);
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
void clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device,
|
||||
|
@@ -250,7 +250,8 @@ get_direction (XkbDescPtr xkb,
|
||||
{
|
||||
int level = 0;
|
||||
KeySym sym = XkbKeySymEntry (xkb, code, level, group);
|
||||
PangoDirection dir = pango_unichar_direction (clutter_keysym_to_unicode (sym));
|
||||
PangoDirection dir =
|
||||
_clutter_pango_unichar_direction (clutter_keysym_to_unicode (sym));
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
|
@@ -12,19 +12,19 @@ clutter_c_args = [
|
||||
]
|
||||
|
||||
clutter_debug_c_args = []
|
||||
if buildtype.startswith('debug')
|
||||
clutter_debug_c_args += '-DG_DISABLE_CAST_CHECKS'
|
||||
if buildtype == 'debug'
|
||||
clutter_debug_c_args += '-DCLUTTER_ENABLE_DEBUG'
|
||||
endif
|
||||
elif buildtype == 'release'
|
||||
if get_option('debug')
|
||||
clutter_debug_c_args += [
|
||||
'-DCLUTTER_ENABLE_DEBUG',
|
||||
'-fno-omit-frame-pointer'
|
||||
]
|
||||
elif buildtype != 'plain'
|
||||
clutter_debug_c_args += [
|
||||
'-DG_DISABLE_ASSERT',
|
||||
'-DG_DISABLE_CHECKS',
|
||||
'-DG_DISABLE_CAST_CHECKS',
|
||||
]
|
||||
endif
|
||||
|
||||
supported_clutter_debug_c_args = cc.get_supported_arguments(clutter_debug_c_args)
|
||||
clutter_c_args += clutter_debug_c_args
|
||||
|
||||
clutter_pkg_deps = [
|
||||
@@ -38,6 +38,7 @@ clutter_pkg_deps = [
|
||||
]
|
||||
|
||||
clutter_pkg_private_deps = [
|
||||
fribidi_dep,
|
||||
gdk_pixbuf_dep,
|
||||
gthread_dep,
|
||||
gmodule_no_export_dep,
|
||||
|
@@ -114,12 +114,12 @@ test_destroy_destroy (ClutterActor *self)
|
||||
test->tex = NULL;
|
||||
}
|
||||
|
||||
g_list_foreach (test->children, (GFunc) clutter_actor_destroy, NULL);
|
||||
g_list_free (test->children);
|
||||
test->children = NULL;
|
||||
g_assert_nonnull (test->children);
|
||||
|
||||
if (CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy)
|
||||
CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy (self);
|
||||
|
||||
g_assert_null (test->children);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -38,8 +38,7 @@ timeline_data_init (TimelineData *data, int timeline_num)
|
||||
static void
|
||||
timeline_data_destroy (TimelineData *data)
|
||||
{
|
||||
g_slist_foreach (data->markers_hit, (GFunc) g_free, NULL);
|
||||
g_slist_free (data->markers_hit);
|
||||
g_slist_free_full (data->markers_hit, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -4,6 +4,9 @@
|
||||
/* Have GLES 2.0 for rendering */
|
||||
#mesondefine HAVE_COGL_GLES2
|
||||
|
||||
/* Building with Sysprof profiling suport */
|
||||
#mesondefine HAVE_TRACING
|
||||
|
||||
/* Enable unit tests */
|
||||
#mesondefine ENABLE_UNIT_TESTS
|
||||
|
||||
|
@@ -483,8 +483,8 @@ _cogl_pango_display_list_node_free (CoglPangoDisplayListNode *node)
|
||||
void
|
||||
_cogl_pango_display_list_clear (CoglPangoDisplayList *dl)
|
||||
{
|
||||
g_slist_foreach (dl->nodes, (GFunc) _cogl_pango_display_list_node_free, NULL);
|
||||
g_slist_free (dl->nodes);
|
||||
g_slist_free_full (dl->nodes, (GDestroyNotify)
|
||||
_cogl_pango_display_list_node_free);
|
||||
dl->nodes = NULL;
|
||||
dl->last_node = NULL;
|
||||
}
|
||||
|
@@ -460,9 +460,7 @@ cogl_path_fill (CoglPath *path);
|
||||
* use while filling a path.</note>
|
||||
*
|
||||
* Stability: unstable
|
||||
* Deprecated: 1.16: Use cogl_path_fill() instead
|
||||
*/
|
||||
COGL_DEPRECATED_FOR (cogl_path_fill)
|
||||
void
|
||||
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
@@ -492,9 +490,7 @@ cogl_path_stroke (CoglPath *path);
|
||||
* regardless of the current transformation matrix.
|
||||
*
|
||||
* Stability: unstable
|
||||
* Deprecated: 1.16: Use cogl_path_stroke() instead
|
||||
*/
|
||||
COGL_DEPRECATED_FOR (cogl_path_stroke)
|
||||
void
|
||||
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
@@ -529,9 +525,7 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
|
||||
*
|
||||
* Since: 1.8
|
||||
* Stability: Unstable
|
||||
* Deprecated: 1.16: Use cogl_framebuffer_push_path_clip() instead
|
||||
*/
|
||||
COGL_DEPRECATED_FOR (cogl_framebuffer_push_path_clip)
|
||||
void
|
||||
cogl_clip_push_from_path (CoglPath *path);
|
||||
|
||||
|
@@ -1504,7 +1504,6 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
|
||||
COGL_FRAMEBUFFER_STATE_CLIP;
|
||||
}
|
||||
|
||||
/* XXX: deprecated */
|
||||
void
|
||||
cogl_clip_push_from_path (CoglPath *path)
|
||||
{
|
||||
@@ -1575,7 +1574,6 @@ _cogl_path_build_stroke_attribute_buffer (CoglPath *path)
|
||||
data->stroke_n_attributes = n_attributes;
|
||||
}
|
||||
|
||||
/* XXX: deprecated */
|
||||
void
|
||||
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
@@ -1588,7 +1586,6 @@ cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
|
||||
_cogl_path_fill_nodes (path, framebuffer, pipeline, 0 /* flags */);
|
||||
}
|
||||
|
||||
/* XXX: deprecated */
|
||||
void
|
||||
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
|
@@ -43,6 +43,7 @@ typedef struct _CoglBitmap CoglBitmap;
|
||||
#include <cogl/cogl-buffer.h>
|
||||
#include <cogl/cogl-context.h>
|
||||
#include <cogl/cogl-pixel-buffer.h>
|
||||
#include <cogl/cogl-pixel-format.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
|
@@ -31,7 +31,7 @@
|
||||
#ifndef __COGL_MUTTER_H___
|
||||
#define __COGL_MUTTER_H___
|
||||
|
||||
#include "cogl-mutter-config.h"
|
||||
#include "cogl-config.h"
|
||||
#include "cogl-defines.h"
|
||||
|
||||
#include <cogl/cogl-texture.h>
|
||||
|
@@ -452,15 +452,8 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
|
||||
_cogl_bitmask_destroy (&uniforms_state->changed_mask);
|
||||
}
|
||||
|
||||
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
|
||||
g_slice_free (CoglPipelineBigState, pipeline->big_state);
|
||||
|
||||
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
|
||||
{
|
||||
g_list_foreach (pipeline->layer_differences,
|
||||
(GFunc)cogl_object_unref, NULL);
|
||||
g_list_free (pipeline->layer_differences);
|
||||
}
|
||||
g_list_free_full (pipeline->layer_differences, cogl_object_unref);
|
||||
|
||||
if (pipeline->differences & COGL_PIPELINE_STATE_VERTEX_SNIPPETS)
|
||||
_cogl_pipeline_snippet_list_free (&pipeline->big_state->vertex_snippets);
|
||||
@@ -468,6 +461,9 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
|
||||
if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
|
||||
_cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets);
|
||||
|
||||
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
|
||||
g_slice_free (CoglPipelineBigState, pipeline->big_state);
|
||||
|
||||
g_list_free (pipeline->deprecated_get_layers_list);
|
||||
|
||||
recursively_free_layer_caches (pipeline);
|
||||
@@ -937,12 +933,7 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest,
|
||||
|
||||
if (dest->differences & COGL_PIPELINE_STATE_LAYERS &&
|
||||
dest->layer_differences)
|
||||
{
|
||||
g_list_foreach (dest->layer_differences,
|
||||
(GFunc)cogl_object_unref,
|
||||
NULL);
|
||||
g_list_free (dest->layer_differences);
|
||||
}
|
||||
g_list_free_full (dest->layer_differences, cogl_object_unref);
|
||||
|
||||
for (l = src->layer_differences; l; l = l->next)
|
||||
{
|
||||
|
310
cogl/cogl/cogl-pixel-format.c
Normal file
310
cogl/cogl/cogl-pixel-format.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* A Low Level GPU Graphics and Utilities API
|
||||
*
|
||||
* Copyright (C) 2007,2008,2009,2010 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 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 "cogl-config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cogl-pixel-format.h"
|
||||
|
||||
/* An entry to map CoglPixelFormats to their respective properties */
|
||||
typedef struct _CoglPixelFormatInfo
|
||||
{
|
||||
CoglPixelFormat cogl_format;
|
||||
const char *format_str;
|
||||
int bpp; /* Bytes per pixel */
|
||||
int aligned; /* Aligned components? (-1 if n/a) */
|
||||
} CoglPixelFormatInfo;
|
||||
|
||||
static const CoglPixelFormatInfo format_info_table[] = {
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ANY,
|
||||
.format_str = "ANY",
|
||||
.bpp = 0,
|
||||
.aligned = -1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_A_8,
|
||||
.format_str = "A_8",
|
||||
.bpp = 1,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGB_565,
|
||||
.format_str = "RGB_565",
|
||||
.bpp = 2,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444,
|
||||
.format_str = "RGBA_4444",
|
||||
.bpp = 2,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551,
|
||||
.format_str = "RGBA_5551",
|
||||
.bpp = 2,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_YUV,
|
||||
.format_str = "YUV",
|
||||
.bpp = 0,
|
||||
.aligned = -1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_G_8,
|
||||
.format_str = "G_8",
|
||||
.bpp = 1,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RG_88,
|
||||
.format_str = "RG_88",
|
||||
.bpp = 2,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGB_888,
|
||||
.format_str = "RGB_888",
|
||||
.bpp = 3,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_BGR_888,
|
||||
.format_str = "BGR_888",
|
||||
.bpp = 3,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
.format_str = "RGBA_8888",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888,
|
||||
.format_str = "BGRA_8888",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888,
|
||||
.format_str = "ARGB_8888",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888,
|
||||
.format_str = "ABGR_8888",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102,
|
||||
.format_str = "RGBA_1010102",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102,
|
||||
.format_str = "BGRA_1010102",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010,
|
||||
.format_str = "ARGB_2101010",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010,
|
||||
.format_str = "ABGR_2101010",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
.format_str = "RGBA_8888_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE,
|
||||
.format_str = "BGRA_8888_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE,
|
||||
.format_str = "ARGB_8888_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE,
|
||||
.format_str = "ABGR_8888_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE,
|
||||
.format_str = "RGBA_4444_PRE",
|
||||
.bpp = 2,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE,
|
||||
.format_str = "RGBA_5551_PRE",
|
||||
.bpp = 2,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE,
|
||||
.format_str = "RGBA_1010102_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE,
|
||||
.format_str = "BGRA_1010102_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE,
|
||||
.format_str = "ARGB_2101010_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE,
|
||||
.format_str = "ABGR_2101010_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_16,
|
||||
.format_str = "DEPTH_16",
|
||||
.bpp = 2,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_32,
|
||||
.format_str = "DEPTH_32",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8,
|
||||
.format_str = "DEPTH_24_STENCIL_8",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns the number of bytes-per-pixel of a given format. The bpp
|
||||
* can be extracted from the least significant nibble of the pixel
|
||||
* format (see CoglPixelFormat).
|
||||
*
|
||||
* The mapping is the following (see discussion on bug #660188):
|
||||
*
|
||||
* 0 = undefined
|
||||
* 1, 8 = 1 bpp (e.g. A_8, G_8)
|
||||
* 2 = 3 bpp, aligned (e.g. 888)
|
||||
* 3 = 4 bpp, aligned (e.g. 8888)
|
||||
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
|
||||
* 7 = undefined yuv
|
||||
* 9 = 2 bpp, aligned
|
||||
* 10 = undefined
|
||||
* 11 = undefined
|
||||
* 12 = 3 bpp, not aligned
|
||||
* 13 = 4 bpp, not aligned (e.g. 2101010)
|
||||
* 14-15 = undefined
|
||||
*/
|
||||
int
|
||||
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
|
||||
{
|
||||
if (format_info_table[i].cogl_format == format)
|
||||
return format_info_table[i].bpp;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
/* Note: this also refers to the mapping defined above for
|
||||
* _cogl_pixel_format_get_bytes_per_pixel() */
|
||||
gboolean
|
||||
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format)
|
||||
{
|
||||
int aligned = -1;
|
||||
size_t i;
|
||||
|
||||
/* NB: currently checking whether the format components are aligned
|
||||
* or not determines whether the format is endian dependent or not.
|
||||
* In the future though we might consider adding formats with
|
||||
* aligned components that are also endian independant. */
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
|
||||
{
|
||||
if (format_info_table[i].cogl_format == format)
|
||||
{
|
||||
aligned = format_info_table[i].aligned;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_return_val_if_fail (aligned != -1, FALSE);
|
||||
|
||||
return aligned;
|
||||
}
|
||||
|
||||
const char *
|
||||
cogl_pixel_format_to_string (CoglPixelFormat format)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
|
||||
{
|
||||
if (format_info_table[i].cogl_format == format)
|
||||
return format_info_table[i].format_str;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
300
cogl/cogl/cogl-pixel-format.h
Normal file
300
cogl/cogl/cogl-pixel-format.h
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* A Low Level GPU Graphics and Utilities API
|
||||
*
|
||||
* Copyright (C) 2008,2009 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 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
|
||||
#error "Only <cogl/cogl.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __COGL_PIXEL_FORMAT_H__
|
||||
#define __COGL_PIXEL_FORMAT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cogl/cogl-defines.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:cogl-pixel-format
|
||||
* @short_description: Pixel formats supported by Cogl
|
||||
*
|
||||
* The pixel format of an image descrbes how the bits of each pixel are
|
||||
* represented in memory. For example: an image can be laid out as one long
|
||||
* sequence of pixels, where each pixel is a sequence of 8 bits of Red, Green
|
||||
* and Blue. The amount of bits that are used can be different for each pixel
|
||||
* format, as well as the components (for example an Alpha layer to include
|
||||
* transparency, or non_RGBA).
|
||||
*
|
||||
* Other examples of factors that can influence the layout in memory are the
|
||||
* system's endianness.
|
||||
*/
|
||||
|
||||
#define COGL_A_BIT (1 << 4)
|
||||
#define COGL_BGR_BIT (1 << 5)
|
||||
#define COGL_AFIRST_BIT (1 << 6)
|
||||
#define COGL_PREMULT_BIT (1 << 7)
|
||||
#define COGL_DEPTH_BIT (1 << 8)
|
||||
#define COGL_STENCIL_BIT (1 << 9)
|
||||
|
||||
/* XXX: Notes to those adding new formats here...
|
||||
*
|
||||
* First this diagram outlines how we allocate the 32bits of a
|
||||
* CoglPixelFormat currently...
|
||||
*
|
||||
* 6 bits for flags
|
||||
* |-----|
|
||||
* enum unused 4 bits for the bytes-per-pixel
|
||||
* and component alignment info
|
||||
* |------| |-------------| |--|
|
||||
* 00000000 xxxxxxxx xxxxxxSD PFBA0000
|
||||
* ^ stencil
|
||||
* ^ depth
|
||||
* ^ premult
|
||||
* ^ alpha first
|
||||
* ^ bgr order
|
||||
* ^ has alpha
|
||||
*
|
||||
* The most awkward part about the formats is how we use the last 4
|
||||
* bits to encode the bytes per pixel and component alignment
|
||||
* information. Ideally we should have had 3 bits for the bpp and a
|
||||
* flag for alignment but we didn't plan for that in advance so we
|
||||
* instead use a small lookup table to query the bpp and whether the
|
||||
* components are byte aligned or not.
|
||||
*
|
||||
* The mapping is the following (see discussion on bug #660188):
|
||||
*
|
||||
* 0 = undefined
|
||||
* 1, 8 = 1 bpp (e.g. A_8, G_8)
|
||||
* 2 = 3 bpp, aligned (e.g. 888)
|
||||
* 3 = 4 bpp, aligned (e.g. 8888)
|
||||
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
|
||||
* 7 = YUV: undefined bpp, undefined alignment
|
||||
* 9 = 2 bpp, aligned
|
||||
* 10 = depth, aligned (8, 16, 24, 32, 32f)
|
||||
* 11 = undefined
|
||||
* 12 = 3 bpp, not aligned
|
||||
* 13 = 4 bpp, not aligned (e.g. 2101010)
|
||||
* 14-15 = undefined
|
||||
*
|
||||
* Note: the gap at 10-11 is just because we wanted to maintain that
|
||||
* all non-aligned formats have the third bit set in case that's
|
||||
* useful later.
|
||||
*
|
||||
* Since we don't want to waste bits adding more and more flags, we'd
|
||||
* like to see most new pixel formats that can't be represented
|
||||
* uniquely with the existing flags in the least significant byte
|
||||
* simply be enumerated with sequential values in the most significant
|
||||
* enum byte.
|
||||
*
|
||||
* Note: Cogl avoids exposing any padded XRGB or RGBX formats and
|
||||
* instead we leave it up to applications to decided whether they
|
||||
* consider the A component as padding or valid data. We shouldn't
|
||||
* change this policy without good reasoning.
|
||||
*
|
||||
* So to add a new format:
|
||||
* 1) Use the mapping table above to figure out what to but in
|
||||
* the lowest nibble.
|
||||
* 2) OR in the COGL_PREMULT_BIT, COGL_AFIRST_BIT, COGL_A_BIT and
|
||||
* COGL_BGR_BIT flags as appropriate.
|
||||
* 3) If the result is not yet unique then also combine with an
|
||||
* increment of the last sequence number in the most significant
|
||||
* byte.
|
||||
*
|
||||
* The last sequence number used was 0 (i.e. no formats currently need
|
||||
* a sequence number)
|
||||
* Update this note whenever a new sequence number is used.
|
||||
*/
|
||||
/**
|
||||
* CoglPixelFormat:
|
||||
* @COGL_PIXEL_FORMAT_ANY: Any format
|
||||
* @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask
|
||||
* @COGL_PIXEL_FORMAT_RG_88: RG, 16 bits. Note that red-green textures
|
||||
* are only available if %COGL_FEATURE_ID_TEXTURE_RG is advertised.
|
||||
* See cogl_texture_set_components() for details.
|
||||
* @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_YUV: Not currently supported
|
||||
* @COGL_PIXEL_FORMAT_G_8: Single luminance component
|
||||
* @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits
|
||||
* @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_1010102 : RGBA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_BGRA_1010102 : BGRA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ARGB_2101010 : ARGB, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ABGR_2101010 : ABGR, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_1010102_PRE: Premultiplied RGBA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc
|
||||
*
|
||||
* Pixel formats used by Cogl. For the formats with a byte per
|
||||
* component, the order of the components specify the order in
|
||||
* increasing memory addresses. So for example
|
||||
* %COGL_PIXEL_FORMAT_RGB_888 would have the red component in the
|
||||
* lowest address, green in the next address and blue after that
|
||||
* regardless of the endianness of the system.
|
||||
*
|
||||
* For the formats with non byte aligned components the component
|
||||
* order specifies the order within a 16-bit or 32-bit number from
|
||||
* most significant bit to least significant. So for
|
||||
* %COGL_PIXEL_FORMAT_RGB_565, the red component would be in bits
|
||||
* 11-15, the green component would be in 6-11 and the blue component
|
||||
* would be in 1-5. Therefore the order in memory depends on the
|
||||
* endianness of the system.
|
||||
*
|
||||
* When uploading a texture %COGL_PIXEL_FORMAT_ANY can be used as the
|
||||
* internal format. Cogl will try to pick the best format to use
|
||||
* internally and convert the texture data if necessary.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
|
||||
{
|
||||
COGL_PIXEL_FORMAT_ANY = 0,
|
||||
COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT,
|
||||
|
||||
COGL_PIXEL_FORMAT_RGB_565 = 4,
|
||||
COGL_PIXEL_FORMAT_RGBA_4444 = 5 | COGL_A_BIT,
|
||||
COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT,
|
||||
COGL_PIXEL_FORMAT_YUV = 7,
|
||||
COGL_PIXEL_FORMAT_G_8 = 8,
|
||||
|
||||
COGL_PIXEL_FORMAT_RG_88 = 9,
|
||||
|
||||
COGL_PIXEL_FORMAT_RGB_888 = 2,
|
||||
COGL_PIXEL_FORMAT_BGR_888 = (2 | COGL_BGR_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_8888 = (3 | COGL_A_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_8888 = (3 | COGL_A_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_1010102 = (13 | COGL_A_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_1010102 = (13 | COGL_A_BIT | COGL_BGR_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_2101010 = (13 | COGL_A_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_2101010 = (13 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT),
|
||||
COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT)
|
||||
} CoglPixelFormat;
|
||||
|
||||
/*
|
||||
* _cogl_pixel_format_get_bytes_per_pixel:
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Queries how many bytes a pixel of the given @format takes.
|
||||
*
|
||||
* Return value: The number of bytes taken for a pixel of the given
|
||||
* @format.
|
||||
*/
|
||||
int
|
||||
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format);
|
||||
|
||||
/*
|
||||
* _cogl_pixel_format_has_aligned_components:
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Queries whether the ordering of the components for the given
|
||||
* @format depend on the endianness of the host CPU or if the
|
||||
* components can be accessed using bit shifting and bitmasking by
|
||||
* loading a whole pixel into a word.
|
||||
*
|
||||
* XXX: If we ever consider making something like this public we
|
||||
* should really try to think of a better name and come up with
|
||||
* much clearer documentation since it really depends on what
|
||||
* point of view you consider this from whether a format like
|
||||
* COGL_PIXEL_FORMAT_RGBA_8888 is endian dependent. E.g. If you
|
||||
* read an RGBA_8888 pixel into a uint32
|
||||
* it's endian dependent how you mask out the different channels.
|
||||
* But If you already have separate color components and you want
|
||||
* to write them to an RGBA_8888 pixel then the bytes can be
|
||||
* written sequentially regardless of the endianness.
|
||||
*
|
||||
* Return value: %TRUE if you need to consider the host CPU
|
||||
* endianness when dealing with the given @format
|
||||
* else %FALSE.
|
||||
*/
|
||||
gboolean
|
||||
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format);
|
||||
|
||||
/*
|
||||
* COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format):
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Returns TRUE if the pixel format can take a premult bit. This is
|
||||
* currently true for all formats that have an alpha channel except
|
||||
* COGL_PIXEL_FORMAT_A_8 (because that doesn't have any other
|
||||
* components to multiply by the alpha).
|
||||
*/
|
||||
#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \
|
||||
(((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8)
|
||||
|
||||
/**
|
||||
* cogl_pixel_format_to_string:
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Returns a string representation of @format, useful for debugging purposes.
|
||||
*
|
||||
* Returns: (transfer none): A string representation of @format.
|
||||
*/
|
||||
const char *
|
||||
cogl_pixel_format_to_string (CoglPixelFormat format);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_PIXEL_FORMAT_H__ */
|
@@ -116,57 +116,6 @@ _cogl_get_enable_legacy_state (void);
|
||||
#define _cogl_has_private_feature(ctx, feature) \
|
||||
COGL_FLAGS_GET ((ctx)->private_features, (feature))
|
||||
|
||||
/*
|
||||
* _cogl_pixel_format_get_bytes_per_pixel:
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Queries how many bytes a pixel of the given @format takes.
|
||||
*
|
||||
* Return value: The number of bytes taken for a pixel of the given
|
||||
* @format.
|
||||
*/
|
||||
int
|
||||
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format);
|
||||
|
||||
/*
|
||||
* _cogl_pixel_format_has_aligned_components:
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Queries whether the ordering of the components for the given
|
||||
* @format depend on the endianness of the host CPU or if the
|
||||
* components can be accessed using bit shifting and bitmasking by
|
||||
* loading a whole pixel into a word.
|
||||
*
|
||||
* XXX: If we ever consider making something like this public we
|
||||
* should really try to think of a better name and come up with
|
||||
* much clearer documentation since it really depends on what
|
||||
* point of view you consider this from whether a format like
|
||||
* COGL_PIXEL_FORMAT_RGBA_8888 is endian dependent. E.g. If you
|
||||
* read an RGBA_8888 pixel into a uint32
|
||||
* it's endian dependent how you mask out the different channels.
|
||||
* But If you already have separate color components and you want
|
||||
* to write them to an RGBA_8888 pixel then the bytes can be
|
||||
* written sequentially regardless of the endianness.
|
||||
*
|
||||
* Return value: %TRUE if you need to consider the host CPU
|
||||
* endianness when dealing with the given @format
|
||||
* else %FALSE.
|
||||
*/
|
||||
gboolean
|
||||
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format);
|
||||
|
||||
/*
|
||||
* COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format):
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Returns TRUE if the pixel format can take a premult bit. This is
|
||||
* currently true for all formats that have an alpha channel except
|
||||
* COGL_PIXEL_FORMAT_A_8 (because that doesn't have any other
|
||||
* components to multiply by the alpha).
|
||||
*/
|
||||
#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \
|
||||
(((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_PRIVATE_H__ */
|
||||
|
@@ -194,10 +194,8 @@ _cogl_renderer_free (CoglRenderer *renderer)
|
||||
if (renderer->libgl_module)
|
||||
g_module_close (renderer->libgl_module);
|
||||
|
||||
g_slist_foreach (renderer->event_filters,
|
||||
(GFunc) native_filter_closure_free,
|
||||
NULL);
|
||||
g_slist_free (renderer->event_filters);
|
||||
g_slist_free_full (renderer->event_filters,
|
||||
(GDestroyNotify) native_filter_closure_free);
|
||||
|
||||
g_array_free (renderer->poll_fds, TRUE);
|
||||
|
||||
|
@@ -53,6 +53,7 @@ typedef struct _CoglTexture CoglTexture;
|
||||
#include <cogl/cogl-macros.h>
|
||||
#include <cogl/cogl-defines.h>
|
||||
#include <cogl/cogl-pixel-buffer.h>
|
||||
#include <cogl/cogl-pixel-format.h>
|
||||
#include <cogl/cogl-bitmap.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
258
cogl/cogl/cogl-trace.c
Normal file
258
cogl/cogl/cogl-trace.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cogl-config.h"
|
||||
|
||||
#ifdef HAVE_TRACING
|
||||
|
||||
#include "cogl/cogl-trace.h"
|
||||
|
||||
#include <sysprof-capture.h>
|
||||
#include <syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define COGL_TRACE_OUTPUT_FILE "cogl-trace-sp-capture.syscap"
|
||||
#define BUFFER_LENGTH (4096 * 4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fd;
|
||||
char *filename;
|
||||
char *group;
|
||||
} TraceData;
|
||||
|
||||
static void
|
||||
trace_data_free (gpointer user_data)
|
||||
{
|
||||
TraceData *data = user_data;
|
||||
|
||||
data->fd = -1;
|
||||
g_clear_pointer (&data->group, g_free);
|
||||
g_clear_pointer (&data->filename, g_free);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void cogl_trace_thread_context_free (gpointer data);
|
||||
|
||||
GPrivate cogl_trace_thread_data = G_PRIVATE_INIT (cogl_trace_thread_context_free);
|
||||
CoglTraceContext *cogl_trace_context;
|
||||
GMutex cogl_trace_mutex;
|
||||
|
||||
static CoglTraceContext *
|
||||
cogl_trace_context_new (int fd,
|
||||
const char *filename)
|
||||
{
|
||||
CoglTraceContext *context;
|
||||
SysprofCaptureWriter *writer;
|
||||
|
||||
if (fd != -1)
|
||||
{
|
||||
g_debug ("Initializing trace context with fd=%d", fd);
|
||||
writer = sysprof_capture_writer_new_from_fd (fd, BUFFER_LENGTH);
|
||||
}
|
||||
else if (filename != NULL)
|
||||
{
|
||||
g_debug ("Initializing trace context with filename='%s'", filename);
|
||||
writer = sysprof_capture_writer_new (filename, BUFFER_LENGTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Initializing trace context with default filename");
|
||||
writer = sysprof_capture_writer_new (COGL_TRACE_OUTPUT_FILE, BUFFER_LENGTH);
|
||||
}
|
||||
|
||||
context = g_new0 (CoglTraceContext, 1);
|
||||
context->writer = writer;
|
||||
return context;
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_trace_context_free (CoglTraceContext *trace_context)
|
||||
{
|
||||
g_clear_pointer (&trace_context->writer, sysprof_capture_writer_unref);
|
||||
g_free (trace_context);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_trace_context (TraceData *data)
|
||||
{
|
||||
g_mutex_lock (&cogl_trace_mutex);
|
||||
if (!cogl_trace_context)
|
||||
cogl_trace_context = cogl_trace_context_new (data->fd, data->filename);
|
||||
g_mutex_unlock (&cogl_trace_mutex);
|
||||
}
|
||||
|
||||
static CoglTraceThreadContext *
|
||||
cogl_trace_thread_context_new (const char *group)
|
||||
{
|
||||
CoglTraceThreadContext *thread_context;
|
||||
pid_t tid;
|
||||
|
||||
tid = (pid_t) syscall (SYS_gettid);
|
||||
|
||||
thread_context = g_new0 (CoglTraceThreadContext, 1);
|
||||
thread_context->cpu_id = -1;
|
||||
thread_context->pid = getpid ();
|
||||
thread_context->group =
|
||||
group ? g_strdup (group) : g_strdup_printf ("t:%d", tid);
|
||||
|
||||
return thread_context;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
enable_tracing_idle_callback (gpointer user_data)
|
||||
{
|
||||
CoglTraceThreadContext *thread_context =
|
||||
g_private_get (&cogl_trace_thread_data);
|
||||
TraceData *data = user_data;
|
||||
|
||||
ensure_trace_context (data);
|
||||
|
||||
if (thread_context)
|
||||
{
|
||||
g_warning ("Tracing already enabled");
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
thread_context = cogl_trace_thread_context_new (data->group);
|
||||
g_private_set (&cogl_trace_thread_data, thread_context);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_trace_thread_context_free (gpointer data)
|
||||
{
|
||||
CoglTraceThreadContext *thread_context = data;
|
||||
|
||||
if (!thread_context)
|
||||
return;
|
||||
|
||||
g_free (thread_context->group);
|
||||
g_free (thread_context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
disable_tracing_idle_callback (gpointer user_data)
|
||||
{
|
||||
CoglTraceThreadContext *thread_context =
|
||||
g_private_get (&cogl_trace_thread_data);
|
||||
CoglTraceContext *trace_context;
|
||||
|
||||
if (!thread_context)
|
||||
{
|
||||
g_warning ("Tracing not enabled");
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
g_private_replace (&cogl_trace_thread_data, NULL);
|
||||
|
||||
g_mutex_lock (&cogl_trace_mutex);
|
||||
trace_context = cogl_trace_context;
|
||||
sysprof_capture_writer_flush (trace_context->writer);
|
||||
|
||||
g_clear_pointer (&cogl_trace_context, cogl_trace_context_free);
|
||||
|
||||
g_mutex_unlock (&cogl_trace_mutex);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
set_tracing_enabled_on_thread (GMainContext *main_context,
|
||||
const char *group,
|
||||
int fd,
|
||||
const char *filename)
|
||||
{
|
||||
TraceData *data;
|
||||
GSource *source;
|
||||
|
||||
data = g_new0 (TraceData, 1);
|
||||
data->fd = fd;
|
||||
data->group = group ? strdup (group) : NULL;
|
||||
data->filename = filename ? strdup (filename) : NULL;
|
||||
|
||||
source = g_idle_source_new ();
|
||||
|
||||
g_source_set_callback (source,
|
||||
enable_tracing_idle_callback,
|
||||
data,
|
||||
trace_data_free);
|
||||
|
||||
g_source_attach (source, main_context);
|
||||
g_source_unref (source);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_set_tracing_enabled_on_thread_with_fd (GMainContext *main_context,
|
||||
const char *group,
|
||||
int fd)
|
||||
{
|
||||
set_tracing_enabled_on_thread (main_context, group, fd, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_set_tracing_enabled_on_thread (GMainContext *main_context,
|
||||
const char *group,
|
||||
const char *filename)
|
||||
{
|
||||
set_tracing_enabled_on_thread (main_context, group, -1, filename);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_set_tracing_disabled_on_thread (GMainContext *main_context)
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
source = g_idle_source_new ();
|
||||
|
||||
g_source_set_callback (source, disable_tracing_idle_callback, NULL, NULL);
|
||||
|
||||
g_source_attach (source, main_context);
|
||||
g_source_unref (source);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void
|
||||
cogl_set_tracing_enabled_on_thread_with_fd (void *data,
|
||||
const char *group,
|
||||
int fd)
|
||||
{
|
||||
fprintf (stderr, "Tracing not enabled");
|
||||
}
|
||||
|
||||
void
|
||||
cogl_set_tracing_enabled_on_thread (void *data,
|
||||
const char *group,
|
||||
const char *filename)
|
||||
{
|
||||
fprintf (stderr, "Tracing not enabled");
|
||||
}
|
||||
|
||||
void
|
||||
cogl_set_tracing_disabled_on_thread (void *data)
|
||||
{
|
||||
fprintf (stderr, "Tracing not enabled");
|
||||
}
|
||||
|
||||
#endif /* HAVE_TRACING */
|
147
cogl/cogl/cogl-trace.h
Normal file
147
cogl/cogl/cogl-trace.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COGL_TRACE_H
|
||||
#define COGL_TRACE_H
|
||||
|
||||
#include "cogl-config.h"
|
||||
|
||||
#ifdef HAVE_TRACING
|
||||
|
||||
#include <glib.h>
|
||||
#include <sysprof-capture-writer.h>
|
||||
#include <sysprof-clock.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
typedef struct _CoglTraceContext
|
||||
{
|
||||
SysprofCaptureWriter *writer;
|
||||
} CoglTraceContext;
|
||||
|
||||
typedef struct _CoglTraceThreadContext
|
||||
{
|
||||
int cpu_id;
|
||||
GPid pid;
|
||||
char *group;
|
||||
} CoglTraceThreadContext;
|
||||
|
||||
typedef struct _CoglTraceHead
|
||||
{
|
||||
SysprofTimeStamp begin_time;
|
||||
const char *name;
|
||||
} CoglTraceHead;
|
||||
|
||||
extern GPrivate cogl_trace_thread_data;
|
||||
extern CoglTraceContext *cogl_trace_context;
|
||||
extern GMutex cogl_trace_mutex;
|
||||
|
||||
void cogl_set_tracing_enabled_on_thread_with_fd (GMainContext *main_context,
|
||||
const char *group,
|
||||
int fd);
|
||||
|
||||
void cogl_set_tracing_enabled_on_thread (GMainContext *main_context,
|
||||
const char *group,
|
||||
const char *filename);
|
||||
|
||||
void cogl_set_tracing_disabled_on_thread (GMainContext *main_context);
|
||||
|
||||
static inline void
|
||||
cogl_trace_begin (CoglTraceHead *head,
|
||||
const char *name)
|
||||
{
|
||||
head->begin_time = g_get_monotonic_time () * 1000;
|
||||
head->name = name;
|
||||
}
|
||||
|
||||
static inline void
|
||||
cogl_trace_end (CoglTraceHead *head)
|
||||
{
|
||||
SysprofTimeStamp end_time;
|
||||
CoglTraceContext *trace_context;
|
||||
CoglTraceThreadContext *trace_thread_context;
|
||||
|
||||
end_time = g_get_monotonic_time () * 1000;
|
||||
trace_context = cogl_trace_context;
|
||||
trace_thread_context = g_private_get (&cogl_trace_thread_data);
|
||||
|
||||
g_mutex_lock (&cogl_trace_mutex);
|
||||
if (!sysprof_capture_writer_add_mark (trace_context->writer,
|
||||
head->begin_time,
|
||||
trace_thread_context->cpu_id,
|
||||
trace_thread_context->pid,
|
||||
(uint64_t) end_time - head->begin_time,
|
||||
trace_thread_context->group,
|
||||
head->name,
|
||||
NULL))
|
||||
{
|
||||
/* XXX: g_main_context_get_thread_default() might be wrong, it probably
|
||||
* needs to store the GMainContext in CoglTraceThreadContext when creating
|
||||
* and use it here.
|
||||
*/
|
||||
if (errno == EPIPE)
|
||||
cogl_set_tracing_disabled_on_thread (g_main_context_get_thread_default ());
|
||||
}
|
||||
g_mutex_unlock (&cogl_trace_mutex);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cogl_auto_trace_end_helper (CoglTraceHead **head)
|
||||
{
|
||||
if (*head)
|
||||
cogl_trace_end (*head);
|
||||
}
|
||||
|
||||
#define COGL_TRACE_BEGIN(Name, description) \
|
||||
CoglTraceHead CoglTrace##Name = { 0 }; \
|
||||
if (g_private_get (&cogl_trace_thread_data)) \
|
||||
cogl_trace_begin (&CoglTrace##Name, description); \
|
||||
|
||||
#define COGL_TRACE_END(Name)\
|
||||
if (g_private_get (&cogl_trace_thread_data)) \
|
||||
cogl_trace_end (&CoglTrace##Name);
|
||||
|
||||
#define COGL_TRACE_BEGIN_SCOPED(Name, description) \
|
||||
CoglTraceHead CoglTrace##Name = { 0 }; \
|
||||
__attribute__((cleanup (cogl_auto_trace_end_helper))) \
|
||||
CoglTraceHead *ScopedCoglTrace##Name = NULL; \
|
||||
if (g_private_get (&cogl_trace_thread_data)) \
|
||||
{ \
|
||||
cogl_trace_begin (&CoglTrace##Name, description); \
|
||||
ScopedCoglTrace##Name = &CoglTrace##Name; \
|
||||
}
|
||||
|
||||
#else /* HAVE_TRACING */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define COGL_TRACE_BEGIN(Name, description) (void) 0
|
||||
#define COGL_TRACE_END(Name) (void) 0
|
||||
#define COGL_TRACE_BEGIN_SCOPED(Name, description) (void) 0
|
||||
|
||||
void cogl_set_tracing_enabled_on_thread_with_fd (void *data,
|
||||
const char *group,
|
||||
int fd);
|
||||
void cogl_set_tracing_enabled_on_thread (void *data,
|
||||
const char *group,
|
||||
const char *filename);
|
||||
void cogl_set_tracing_disabled_on_thread (void *data);
|
||||
|
||||
#endif /* HAVE_TRACING */
|
||||
|
||||
#endif /* COGL_TRACE_H */
|
@@ -147,172 +147,6 @@ typedef struct _CoglTextureVertex CoglTextureVertex;
|
||||
#define COGL_DEPTH_BIT (1 << 8)
|
||||
#define COGL_STENCIL_BIT (1 << 9)
|
||||
|
||||
/* XXX: Notes to those adding new formats here...
|
||||
*
|
||||
* First this diagram outlines how we allocate the 32bits of a
|
||||
* CoglPixelFormat currently...
|
||||
*
|
||||
* 6 bits for flags
|
||||
* |-----|
|
||||
* enum unused 4 bits for the bytes-per-pixel
|
||||
* and component alignment info
|
||||
* |------| |-------------| |--|
|
||||
* 00000000 xxxxxxxx xxxxxxSD PFBA0000
|
||||
* ^ stencil
|
||||
* ^ depth
|
||||
* ^ premult
|
||||
* ^ alpha first
|
||||
* ^ bgr order
|
||||
* ^ has alpha
|
||||
*
|
||||
* The most awkward part about the formats is how we use the last 4
|
||||
* bits to encode the bytes per pixel and component alignment
|
||||
* information. Ideally we should have had 3 bits for the bpp and a
|
||||
* flag for alignment but we didn't plan for that in advance so we
|
||||
* instead use a small lookup table to query the bpp and whether the
|
||||
* components are byte aligned or not.
|
||||
*
|
||||
* The mapping is the following (see discussion on bug #660188):
|
||||
*
|
||||
* 0 = undefined
|
||||
* 1, 8 = 1 bpp (e.g. A_8, G_8)
|
||||
* 2 = 3 bpp, aligned (e.g. 888)
|
||||
* 3 = 4 bpp, aligned (e.g. 8888)
|
||||
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
|
||||
* 7 = YUV: undefined bpp, undefined alignment
|
||||
* 9 = 2 bpp, aligned
|
||||
* 10 = depth, aligned (8, 16, 24, 32, 32f)
|
||||
* 11 = undefined
|
||||
* 12 = 3 bpp, not aligned
|
||||
* 13 = 4 bpp, not aligned (e.g. 2101010)
|
||||
* 14-15 = undefined
|
||||
*
|
||||
* Note: the gap at 10-11 is just because we wanted to maintain that
|
||||
* all non-aligned formats have the third bit set in case that's
|
||||
* useful later.
|
||||
*
|
||||
* Since we don't want to waste bits adding more and more flags, we'd
|
||||
* like to see most new pixel formats that can't be represented
|
||||
* uniquely with the existing flags in the least significant byte
|
||||
* simply be enumerated with sequential values in the most significant
|
||||
* enum byte.
|
||||
*
|
||||
* Note: Cogl avoids exposing any padded XRGB or RGBX formats and
|
||||
* instead we leave it up to applications to decided whether they
|
||||
* consider the A component as padding or valid data. We shouldn't
|
||||
* change this policy without good reasoning.
|
||||
*
|
||||
* So to add a new format:
|
||||
* 1) Use the mapping table above to figure out what to but in
|
||||
* the lowest nibble.
|
||||
* 2) OR in the COGL_PREMULT_BIT, COGL_AFIRST_BIT, COGL_A_BIT and
|
||||
* COGL_BGR_BIT flags as appropriate.
|
||||
* 3) If the result is not yet unique then also combine with an
|
||||
* increment of the last sequence number in the most significant
|
||||
* byte.
|
||||
*
|
||||
* The last sequence number used was 0 (i.e. no formats currently need
|
||||
* a sequence number)
|
||||
* Update this note whenever a new sequence number is used.
|
||||
*/
|
||||
/**
|
||||
* CoglPixelFormat:
|
||||
* @COGL_PIXEL_FORMAT_ANY: Any format
|
||||
* @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask
|
||||
* @COGL_PIXEL_FORMAT_RG_88: RG, 16 bits. Note that red-green textures
|
||||
* are only available if %COGL_FEATURE_ID_TEXTURE_RG is advertised.
|
||||
* See cogl_texture_set_components() for details.
|
||||
* @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_YUV: Not currently supported
|
||||
* @COGL_PIXEL_FORMAT_G_8: Single luminance component
|
||||
* @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits
|
||||
* @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_1010102 : RGBA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_BGRA_1010102 : BGRA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ARGB_2101010 : ARGB, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ABGR_2101010 : ABGR, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_1010102_PRE: Premultiplied RGBA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc
|
||||
*
|
||||
* Pixel formats used by Cogl. For the formats with a byte per
|
||||
* component, the order of the components specify the order in
|
||||
* increasing memory addresses. So for example
|
||||
* %COGL_PIXEL_FORMAT_RGB_888 would have the red component in the
|
||||
* lowest address, green in the next address and blue after that
|
||||
* regardless of the endianness of the system.
|
||||
*
|
||||
* For the formats with non byte aligned components the component
|
||||
* order specifies the order within a 16-bit or 32-bit number from
|
||||
* most significant bit to least significant. So for
|
||||
* %COGL_PIXEL_FORMAT_RGB_565, the red component would be in bits
|
||||
* 11-15, the green component would be in 6-11 and the blue component
|
||||
* would be in 1-5. Therefore the order in memory depends on the
|
||||
* endianness of the system.
|
||||
*
|
||||
* When uploading a texture %COGL_PIXEL_FORMAT_ANY can be used as the
|
||||
* internal format. Cogl will try to pick the best format to use
|
||||
* internally and convert the texture data if necessary.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
|
||||
{
|
||||
COGL_PIXEL_FORMAT_ANY = 0,
|
||||
COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT,
|
||||
|
||||
COGL_PIXEL_FORMAT_RGB_565 = 4,
|
||||
COGL_PIXEL_FORMAT_RGBA_4444 = 5 | COGL_A_BIT,
|
||||
COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT,
|
||||
COGL_PIXEL_FORMAT_YUV = 7,
|
||||
COGL_PIXEL_FORMAT_G_8 = 8,
|
||||
|
||||
COGL_PIXEL_FORMAT_RG_88 = 9,
|
||||
|
||||
COGL_PIXEL_FORMAT_RGB_888 = 2,
|
||||
COGL_PIXEL_FORMAT_BGR_888 = (2 | COGL_BGR_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_8888 = (3 | COGL_A_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_8888 = (3 | COGL_A_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_1010102 = (13 | COGL_A_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_1010102 = (13 | COGL_A_BIT | COGL_BGR_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_2101010 = (13 | COGL_A_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_2101010 = (13 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT),
|
||||
COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT)
|
||||
} CoglPixelFormat;
|
||||
|
||||
/**
|
||||
* CoglFeatureFlags:
|
||||
* @COGL_FEATURE_TEXTURE_YUV: ycbcr conversion support
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <cogl/cogl-defines.h>
|
||||
#include <cogl/cogl-pixel-format.h>
|
||||
#include "cogl-types.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
@@ -54,41 +54,27 @@ static char *_cogl_x11_display_name = NULL;
|
||||
static GList *_cogl_xlib_renderers = NULL;
|
||||
|
||||
static void
|
||||
destroy_xlib_renderer_data (void *user_data)
|
||||
_xlib_renderer_data_free (CoglXlibRenderer *data)
|
||||
{
|
||||
CoglXlibRenderer *data = user_data;
|
||||
|
||||
if (data->xvisinfo)
|
||||
XFree (data->xvisinfo);
|
||||
|
||||
g_slice_free (CoglXlibRenderer, user_data);
|
||||
g_slice_free (CoglXlibRenderer, data);
|
||||
}
|
||||
|
||||
CoglXlibRenderer *
|
||||
_cogl_xlib_renderer_get_data (CoglRenderer *renderer)
|
||||
{
|
||||
static CoglUserDataKey key;
|
||||
CoglXlibRenderer *data;
|
||||
|
||||
/* Constructs a CoglXlibRenderer struct on demand and attaches it to
|
||||
the object using user data. It's done this way instead of using a
|
||||
subclassing hierarchy in the winsys data because all EGL winsys's
|
||||
need the EGL winsys data but only one of them wants the Xlib
|
||||
data. */
|
||||
|
||||
data = cogl_object_get_user_data (COGL_OBJECT (renderer), &key);
|
||||
if (!renderer->custom_winsys_user_data)
|
||||
renderer->custom_winsys_user_data = g_slice_new0 (CoglXlibRenderer);
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
data = g_slice_new0 (CoglXlibRenderer);
|
||||
|
||||
cogl_object_set_user_data (COGL_OBJECT (renderer),
|
||||
&key,
|
||||
data,
|
||||
destroy_xlib_renderer_data);
|
||||
}
|
||||
|
||||
return data;
|
||||
return renderer->custom_winsys_user_data;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -570,6 +556,8 @@ _cogl_xlib_renderer_disconnect (CoglRenderer *renderer)
|
||||
if (!renderer->foreign_xdpy && xlib_renderer->xdpy)
|
||||
XCloseDisplay (xlib_renderer->xdpy);
|
||||
|
||||
g_clear_pointer (&renderer->custom_winsys_user_data, _xlib_renderer_data_free);
|
||||
|
||||
unregister_xlib_renderer (renderer);
|
||||
}
|
||||
|
||||
|
@@ -764,55 +764,3 @@ _cogl_init (void)
|
||||
initialized = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of bytes-per-pixel of a given format. The bpp
|
||||
* can be extracted from the least significant nibble of the pixel
|
||||
* format (see CoglPixelFormat).
|
||||
*
|
||||
* The mapping is the following (see discussion on bug #660188):
|
||||
*
|
||||
* 0 = undefined
|
||||
* 1, 8 = 1 bpp (e.g. A_8, G_8)
|
||||
* 2 = 3 bpp, aligned (e.g. 888)
|
||||
* 3 = 4 bpp, aligned (e.g. 8888)
|
||||
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
|
||||
* 7 = undefined yuv
|
||||
* 9 = 2 bpp, aligned
|
||||
* 10 = undefined
|
||||
* 11 = undefined
|
||||
* 12 = 3 bpp, not aligned
|
||||
* 13 = 4 bpp, not aligned (e.g. 2101010)
|
||||
* 14-15 = undefined
|
||||
*/
|
||||
int
|
||||
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format)
|
||||
{
|
||||
int bpp_lut[] = { 0, 1, 3, 4,
|
||||
2, 2, 2, 0,
|
||||
1, 2, 0, 0,
|
||||
3, 4, 0, 0 };
|
||||
|
||||
return bpp_lut [format & 0xf];
|
||||
}
|
||||
|
||||
/* Note: this also refers to the mapping defined above for
|
||||
* _cogl_pixel_format_get_bytes_per_pixel() */
|
||||
gboolean
|
||||
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format)
|
||||
{
|
||||
int aligned_lut[] = { -1, 1, 1, 1,
|
||||
0, 0, 0, -1,
|
||||
1, 1, -1, -1,
|
||||
0, 0, -1, -1};
|
||||
int aligned = aligned_lut[format & 0xf];
|
||||
|
||||
_COGL_RETURN_VAL_IF_FAIL (aligned != -1, FALSE);
|
||||
|
||||
/* NB: currently checking whether the format components are aligned
|
||||
* or not determines whether the format is endian dependent or not.
|
||||
* In the future though we might consider adding formats with
|
||||
* aligned components that are also endian independant. */
|
||||
|
||||
return aligned;
|
||||
}
|
||||
|
@@ -64,6 +64,7 @@
|
||||
#include <cogl/cogl-matrix.h>
|
||||
#include <cogl/cogl-matrix-stack.h>
|
||||
#include <cogl/cogl-offscreen.h>
|
||||
#include <cogl/cogl-pixel-format.h>
|
||||
#include <cogl/cogl-primitives.h>
|
||||
#include <cogl/cogl-texture.h>
|
||||
#include <cogl/cogl-types.h>
|
||||
|
@@ -59,10 +59,8 @@ _cogl_program_free (CoglProgram *program)
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* Unref all of the attached shaders */
|
||||
g_slist_foreach (program->attached_shaders, (GFunc) cogl_handle_unref, NULL);
|
||||
/* Destroy the list */
|
||||
g_slist_free (program->attached_shaders);
|
||||
/* Unref all of the attached shaders and destroy the list */
|
||||
g_slist_free_full (program->attached_shaders, cogl_handle_unref);
|
||||
|
||||
for (i = 0; i < program->custom_uniforms->len; i++)
|
||||
{
|
||||
|
@@ -111,20 +111,8 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
switch (format)
|
||||
{
|
||||
case COGL_PIXEL_FORMAT_A_8:
|
||||
/* If the driver doesn't natively support alpha textures then we
|
||||
* will use a red component texture with a swizzle to implement
|
||||
* the texture */
|
||||
if (_cogl_has_private_feature
|
||||
(context, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) == 0)
|
||||
{
|
||||
glintformat = GL_RED;
|
||||
glformat = GL_RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
glintformat = GL_ALPHA;
|
||||
glformat = GL_ALPHA;
|
||||
}
|
||||
glintformat = GL_RED;
|
||||
glformat = GL_RED;
|
||||
gltype = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_G_8:
|
||||
|
@@ -98,11 +98,8 @@ _cogl_texture_driver_gen (CoglContext *ctx,
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
/* If the driver doesn't support alpha textures directly then we'll
|
||||
* fake them by setting the swizzle parameters */
|
||||
if (internal_format == COGL_PIXEL_FORMAT_A_8 &&
|
||||
!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) &&
|
||||
_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
|
||||
/* GL_ALPHA is deprecated; instead, use GL_RED with a swizzle mask */
|
||||
if (internal_format == COGL_PIXEL_FORMAT_A_8)
|
||||
{
|
||||
static const GLint red_swizzle[] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED };
|
||||
|
||||
|
@@ -83,8 +83,8 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
switch (format)
|
||||
{
|
||||
case COGL_PIXEL_FORMAT_A_8:
|
||||
glintformat = GL_ALPHA;
|
||||
glformat = GL_ALPHA;
|
||||
glintformat = GL_RED;
|
||||
glformat = GL_RED;
|
||||
gltype = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_G_8:
|
||||
|
@@ -88,6 +88,7 @@ cogl_headers = [
|
||||
'cogl-pipeline.h',
|
||||
'cogl-pipeline-state.h',
|
||||
'cogl-pipeline-layer-state.h',
|
||||
'cogl-pixel-format.h',
|
||||
'cogl-primitives.h',
|
||||
'cogl-texture.h',
|
||||
'cogl-texture-2d.h',
|
||||
@@ -233,6 +234,7 @@ cogl_sources = [
|
||||
'cogl-display.c',
|
||||
'cogl-driver.h',
|
||||
'cogl.c',
|
||||
'cogl-pixel-format.c',
|
||||
'cogl-object-private.h',
|
||||
'cogl-object.h',
|
||||
'cogl-object.c',
|
||||
@@ -301,6 +303,8 @@ cogl_sources = [
|
||||
'cogl-blend-string.c',
|
||||
'cogl-blend-string.h',
|
||||
'cogl-debug.c',
|
||||
'cogl-trace.c',
|
||||
'cogl-trace.h',
|
||||
'cogl-sub-texture-private.h',
|
||||
'cogl-texture-private.h',
|
||||
'cogl-texture-2d-private.h',
|
||||
|
@@ -7,6 +7,7 @@ cogl_includepath = include_directories('.', 'cogl')
|
||||
cdata = configuration_data()
|
||||
cdata.set('HAVE_COGL_GL', have_gl)
|
||||
cdata.set('HAVE_COGL_GLES2', have_gles2)
|
||||
cdata.set('HAVE_TRACING', have_profiler)
|
||||
cdata.set('ENABLE_UNIT_TESTS', have_cogl_tests)
|
||||
|
||||
cogl_config_h = configure_file(
|
||||
@@ -14,12 +15,6 @@ cogl_config_h = configure_file(
|
||||
output: 'cogl-config.h',
|
||||
configuration: cdata)
|
||||
|
||||
# TODO: Remove this when autotools support is removed
|
||||
cogl_mutter_config_h = configure_file(
|
||||
input: 'cogl-config.h.meson',
|
||||
output: 'cogl-mutter-config.h',
|
||||
configuration: cdata)
|
||||
|
||||
cogl_pkg_deps = [
|
||||
glib_dep,
|
||||
gobject_dep,
|
||||
@@ -32,6 +27,12 @@ cogl_pkg_private_deps = [
|
||||
#uprof_dep,
|
||||
]
|
||||
|
||||
if have_profiler
|
||||
cogl_pkg_private_deps += [
|
||||
sysprof_dep,
|
||||
]
|
||||
endif
|
||||
|
||||
if have_wayland
|
||||
cogl_pkg_deps += [
|
||||
wayland_server_dep,
|
||||
@@ -93,19 +94,21 @@ if have_gles2
|
||||
endif
|
||||
|
||||
cogl_debug_c_args = []
|
||||
if buildtype.startswith('debug')
|
||||
buildtype = get_option('buildtype')
|
||||
if get_option('debug')
|
||||
cogl_debug_c_args += [
|
||||
'-DCOGL_GL_DEBUG',
|
||||
'-DCOGL_OBJECT_DEBUG',
|
||||
'-DCOGL_ENABLE_DEBUG',
|
||||
'-fno-omit-frame-pointer'
|
||||
]
|
||||
elif buildtype == 'release'
|
||||
elif buildtype != 'plain'
|
||||
cogl_debug_c_args += [
|
||||
'-DG_DISABLE_CHECKS',
|
||||
'-DG_DISABLE_CAST_CHECKS',
|
||||
'-DG_DISABLE_CAST_CHECKS'
|
||||
]
|
||||
endif
|
||||
|
||||
supported_cogl_debug_c_args = cc.get_supported_arguments(cogl_debug_c_args)
|
||||
cogl_c_args += cogl_debug_c_args
|
||||
|
||||
if have_cogl_tests
|
||||
|
@@ -4,19 +4,9 @@ cdata = configuration_data()
|
||||
cdata.set('HAVE_GL', have_gl.to_int())
|
||||
cdata.set('HAVE_GLES2', have_gles2.to_int())
|
||||
|
||||
# Until meson 0.50 setting the install parameter in 'configure_file' is ignored
|
||||
# if 'install_dir' is set, then until mutter doesn't depend on such meson version
|
||||
# cogl_installed_tests_libexecdir should be empty unless have_installed_tests
|
||||
# is false, or this file will be installed anyway.
|
||||
#
|
||||
# See https://github.com/mesonbuild/meson/issues/4160
|
||||
cogl_installed_tests_libexecdir = ''
|
||||
|
||||
if have_installed_tests
|
||||
cogl_installed_tests_libexecdir = join_paths(
|
||||
mutter_installed_tests_libexecdir, 'cogl', 'conform')
|
||||
install_data('run-tests.sh', install_dir: cogl_installed_tests_libexecdir)
|
||||
endif
|
||||
cogl_installed_tests_libexecdir = join_paths(
|
||||
mutter_installed_tests_libexecdir, 'cogl', 'conform')
|
||||
install_data('run-tests.sh', install_dir: cogl_installed_tests_libexecdir)
|
||||
|
||||
cogl_config_env = configure_file(
|
||||
input: 'config.env.in',
|
||||
|
@@ -49,6 +49,9 @@
|
||||
/* Building with startup notification support */
|
||||
#mesondefine HAVE_STARTUP_NOTIFICATION
|
||||
|
||||
/* Building with Sysprof profiling suport */
|
||||
#mesondefine HAVE_PROFILER
|
||||
|
||||
/* Path to Xwayland executable */
|
||||
#mesondefine XWAYLAND_PATH
|
||||
|
||||
|
@@ -127,6 +127,14 @@
|
||||
</description>
|
||||
</key>
|
||||
|
||||
<key name="locate-pointer-key" type="s">
|
||||
<default>'Control_L'</default>
|
||||
<summary>Modifier to use to locate the pointer</summary>
|
||||
<description>
|
||||
This key will initiate the “locate pointer” action.
|
||||
</description>
|
||||
</key>
|
||||
|
||||
<child name="keybindings" schema="org.gnome.mutter.keybindings"/>
|
||||
|
||||
</schema>
|
||||
|
@@ -61,10 +61,17 @@
|
||||
|
||||
<key name="xwayland-allow-grabs" type="b">
|
||||
<default>false</default>
|
||||
<summary>Allow grabs with Xwayland</summary>
|
||||
<summary>Allow X11 grabs to lock keyboard focus with Xwayland</summary>
|
||||
<description>
|
||||
Allow keyboard grabs issued by X11 applications running in Xwayland
|
||||
to be taken into account.
|
||||
Allow all keyboard events to be routed to X11 “override redirect”
|
||||
windows with a grab when running in Xwayland.
|
||||
|
||||
This option is to support X11 clients which map an “override redirect”
|
||||
window (which do not receive keyboard focus) and issue a keyboard
|
||||
grab to force all keyboard events to that window.
|
||||
|
||||
This option is seldom used and has no effect on regular X11 windows
|
||||
which can receive keyboard focus under normal circumstances.
|
||||
|
||||
For a X11 grab to be taken into account under Wayland, the client must
|
||||
also either send a specific X11 ClientMessage to the root window or be
|
||||
|
108
meson.build
108
meson.build
@@ -1,6 +1,6 @@
|
||||
project('mutter', 'c',
|
||||
version: '3.33.1',
|
||||
meson_version: '>= 0.48.0',
|
||||
version: '3.33.2',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
|
||||
@@ -9,6 +9,7 @@ mutter_plugin_api_version = '3'
|
||||
libmutter_api_version = '4'
|
||||
|
||||
# generic version requirements
|
||||
fribidi_req = '>= 1.0.0'
|
||||
glib_req = '>= 2.53.2'
|
||||
gi_req = '>= 0.9.5'
|
||||
gtk3_req = '>= 3.19.8'
|
||||
@@ -86,6 +87,7 @@ pango_dep = dependency('pango', version: pango_req)
|
||||
cairo_dep = dependency('cairo', version: cairo_req)
|
||||
cairo_gobject_dep = dependency('cairo-gobject', version: cairo_req)
|
||||
pangocairo_dep = dependency('pangocairo', version: pangocairo_req)
|
||||
fribidi_dep = dependency('fribidi', version: fribidi_req)
|
||||
gsettings_desktop_schemas_dep = dependency('gsettings-desktop-schemas',
|
||||
version: gsettings_desktop_schemas_req)
|
||||
glib_dep = dependency('glib-2.0', version: glib_req)
|
||||
@@ -262,6 +264,11 @@ if have_tests
|
||||
have_installed_tests = get_option('installed_tests')
|
||||
endif
|
||||
|
||||
have_profiler = get_option('profiler')
|
||||
if have_profiler
|
||||
sysprof_dep = dependency('sysprof-capture-3')
|
||||
endif
|
||||
|
||||
required_functions = [
|
||||
'ffs',
|
||||
'clz',
|
||||
@@ -274,54 +281,57 @@ endforeach
|
||||
|
||||
add_project_arguments('-D_GNU_SOURCE', language: 'c')
|
||||
|
||||
all_warnings = [
|
||||
'-fno-strict-aliasing',
|
||||
'-Wpointer-arith',
|
||||
'-Wmissing-declarations',
|
||||
'-Wimplicit-function-declaration',
|
||||
'-Wformat=2',
|
||||
'-Wformat-nonliteral',
|
||||
'-Wformat-security',
|
||||
'-Wstrict-prototypes',
|
||||
'-Wmissing-prototypes',
|
||||
'-Wnested-externs',
|
||||
'-Wold-style-definition',
|
||||
'-Wundef',
|
||||
'-Wunused',
|
||||
'-Wcast-align',
|
||||
'-Wmissing-noreturn',
|
||||
'-Wmissing-format-attribute',
|
||||
'-Wmissing-include-dirs',
|
||||
'-Wlogical-op',
|
||||
'-Wignored-qualifiers',
|
||||
'-Werror=redundant-decls',
|
||||
'-Werror=implicit',
|
||||
'-Werror=nonnull',
|
||||
'-Werror=init-self',
|
||||
'-Werror=main',
|
||||
'-Werror=missing-braces',
|
||||
'-Werror=sequence-point',
|
||||
'-Werror=return-type',
|
||||
'-Werror=trigraphs',
|
||||
'-Werror=array-bounds',
|
||||
'-Werror=write-strings',
|
||||
'-Werror=address',
|
||||
'-Werror=int-to-pointer-cast',
|
||||
'-Werror=pointer-to-int-cast',
|
||||
'-Werror=empty-body',
|
||||
'-Werror=write-strings',
|
||||
]
|
||||
|
||||
supported_warnings = cc.get_supported_arguments(all_warnings)
|
||||
|
||||
add_project_arguments(supported_warnings, language: 'c')
|
||||
|
||||
debug_c_args = []
|
||||
buildtype = get_option('buildtype')
|
||||
if buildtype.startswith('debug')
|
||||
debug_c_args += '-DG_ENABLE_DEBUG'
|
||||
if buildtype != 'plain'
|
||||
all_warnings = [
|
||||
'-fno-strict-aliasing',
|
||||
'-Wpointer-arith',
|
||||
'-Wmissing-declarations',
|
||||
'-Wimplicit-function-declaration',
|
||||
'-Wformat=2',
|
||||
'-Wformat-nonliteral',
|
||||
'-Wformat-security',
|
||||
'-Wstrict-prototypes',
|
||||
'-Wmissing-prototypes',
|
||||
'-Wnested-externs',
|
||||
'-Wold-style-definition',
|
||||
'-Wundef',
|
||||
'-Wunused',
|
||||
'-Wcast-align',
|
||||
'-Wmissing-noreturn',
|
||||
'-Wmissing-format-attribute',
|
||||
'-Wmissing-include-dirs',
|
||||
'-Wlogical-op',
|
||||
'-Wignored-qualifiers',
|
||||
'-Werror=redundant-decls',
|
||||
'-Werror=implicit',
|
||||
'-Werror=nonnull',
|
||||
'-Werror=init-self',
|
||||
'-Werror=main',
|
||||
'-Werror=missing-braces',
|
||||
'-Werror=sequence-point',
|
||||
'-Werror=return-type',
|
||||
'-Werror=trigraphs',
|
||||
'-Werror=array-bounds',
|
||||
'-Werror=write-strings',
|
||||
'-Werror=address',
|
||||
'-Werror=int-to-pointer-cast',
|
||||
'-Werror=pointer-to-int-cast',
|
||||
'-Werror=empty-body',
|
||||
'-Werror=write-strings',
|
||||
]
|
||||
supported_warnings = cc.get_supported_arguments(all_warnings)
|
||||
add_project_arguments(supported_warnings, language: 'c')
|
||||
endif
|
||||
|
||||
if get_option('debug')
|
||||
debug_c_args = [
|
||||
'-DG_ENABLE_DEBUG',
|
||||
'-fno-omit-frame-pointer'
|
||||
]
|
||||
supported_debug_c_args = cc.get_supported_arguments(debug_c_args)
|
||||
add_project_arguments(supported_debug_c_args, language: 'c')
|
||||
endif
|
||||
add_project_arguments(debug_c_args, language: 'c')
|
||||
|
||||
cc.compiles('void main (void) { __builtin_ffsl (0); __builtin_popcountl (0); }')
|
||||
|
||||
@@ -341,6 +351,7 @@ cdata.set('HAVE_LIBWACOM', have_libwacom)
|
||||
cdata.set('HAVE_SM', have_sm)
|
||||
cdata.set('HAVE_STARTUP_NOTIFICATION', have_startup_notification)
|
||||
cdata.set('HAVE_INTROSPECTION', have_introspection)
|
||||
cdata.set('HAVE_PROFILER', have_profiler)
|
||||
|
||||
xkb_base = xkeyboard_config_dep.get_pkgconfig_variable('xkb_base')
|
||||
cdata.set_quoted('XKB_BASE', xkb_base)
|
||||
@@ -406,6 +417,7 @@ output = [
|
||||
' SM....................... ' + have_sm.to_string(),
|
||||
' Startup notification..... ' + have_startup_notification.to_string(),
|
||||
' Introspection............ ' + have_introspection.to_string(),
|
||||
' Profiler................. ' + have_profiler.to_string(),
|
||||
'',
|
||||
' Tests:',
|
||||
'',
|
||||
|
@@ -123,6 +123,12 @@ option('tests',
|
||||
description: 'Enable tests globally. Specific test suites can be controlled with core_tests, clutter_tests, and cogl_tests'
|
||||
)
|
||||
|
||||
option('profiler',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Enable Sysprof tracing'
|
||||
)
|
||||
|
||||
option('installed_tests',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
|
@@ -9,6 +9,7 @@ data/org.gnome.mutter.gschema.xml.in
|
||||
data/org.gnome.mutter.wayland.gschema.xml.in
|
||||
src/backends/meta-input-settings.c
|
||||
src/backends/meta-monitor-manager.c
|
||||
src/backends/meta-profiler.c
|
||||
src/compositor/compositor.c
|
||||
src/compositor/meta-background.c
|
||||
src/core/bell.c
|
||||
|
86
po/es.po
86
po/es.po
@@ -13,8 +13,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter.master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
|
||||
"POT-Creation-Date: 2019-05-03 10:54+0000\n"
|
||||
"PO-Revision-Date: 2019-05-03 14:28+0200\n"
|
||||
"POT-Creation-Date: 2019-06-07 19:32+0000\n"
|
||||
"PO-Revision-Date: 2019-06-11 12:54+0200\n"
|
||||
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
|
||||
"Language-Team: es <gnome-es-list@gnome.org>\n"
|
||||
"Language: es\n"
|
||||
@@ -405,7 +405,9 @@ msgid ""
|
||||
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
|
||||
"mutter default to layout logical monitors in a logical pixel coordinate "
|
||||
"space, while scaling monitor framebuffers instead of window content, to "
|
||||
"manage HiDPI monitors. Does not require a restart."
|
||||
"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes "
|
||||
"mutter request a low priority real-time scheduling. The executable or user "
|
||||
"must have CAP_SYS_NICE. Requires a restart."
|
||||
msgstr ""
|
||||
"Para activar las características experimentales, añada la palabra clave de "
|
||||
"la característica a la lista. Depende de la característica que se deba "
|
||||
@@ -416,21 +418,31 @@ msgstr ""
|
||||
"manera predeterminada de disponer monitores lógicos en un espacio lógico de "
|
||||
"coordenadas de píxeles, al escalar framebuffers de monitores framebuffers en "
|
||||
"lugar del contenido de ventana, para administrar monitores HiDPI. No "
|
||||
"requiere un reinicio."
|
||||
"requiere un reinicio. • “rt-scheduler” — hace que mutter pida una "
|
||||
"planificación en tiempo real con prioridad baja. El ejecutable o el usuario "
|
||||
"deben tener CAP_SYS_NICE. Requiere reniciar."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:141
|
||||
#: data/org.gnome.mutter.gschema.xml.in:132
|
||||
msgid "Modifier to use to locate the pointer"
|
||||
msgstr "Modificador que usar para encontrar el puntero"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:133
|
||||
msgid "This key will initiate the “locate pointer” action."
|
||||
msgstr "Esta tecla iniciará la acción de encontrar el puntero."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:153
|
||||
msgid "Select window from tab popup"
|
||||
msgstr "Seleccionar ventana de la pestaña emergente"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:146
|
||||
#: data/org.gnome.mutter.gschema.xml.in:158
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Cancelar pestaña emergente"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:151
|
||||
#: data/org.gnome.mutter.gschema.xml.in:163
|
||||
msgid "Switch monitor configurations"
|
||||
msgstr "Cambiar la configuración del monitor"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:156
|
||||
#: data/org.gnome.mutter.gschema.xml.in:168
|
||||
msgid "Rotates the built-in monitor configuration"
|
||||
msgstr "Rota la configuración del monitor empotrado"
|
||||
|
||||
@@ -487,16 +499,29 @@ msgid "Re-enable shortcuts"
|
||||
msgstr "Volver a activar los atajos"
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:64
|
||||
msgid "Allow grabs with Xwayland"
|
||||
msgstr "Permitir capturas con Xwayland"
|
||||
#| msgid "Allow grabs with Xwayland"
|
||||
msgid "Allow X11 grabs to lock keyboard focus with Xwayland"
|
||||
msgstr ""
|
||||
"Permitir capturas con X11 para bloquear el foco del teclado con Xwayland"
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:65
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Allow keyboard grabs issued by X11 applications running in Xwayland to be "
|
||||
#| "taken into account. For a X11 grab to be taken into account under "
|
||||
#| "Wayland, the client must also either send a specific X11 ClientMessage to "
|
||||
#| "the root window or be among the applications white-listed in key "
|
||||
#| "“xwayland-grab-access-rules”."
|
||||
msgid ""
|
||||
"Allow keyboard grabs issued by X11 applications running in Xwayland to be "
|
||||
"taken into account. For a X11 grab to be taken into account under Wayland, "
|
||||
"the client must also either send a specific X11 ClientMessage to the root "
|
||||
"window or be among the applications white-listed in key “xwayland-grab-"
|
||||
"access-rules”."
|
||||
"Allow all keyboard events to be routed to X11 “override redirect” windows "
|
||||
"with a grab when running in Xwayland. This option is to support X11 clients "
|
||||
"which map an “override redirect” window (which do not receive keyboard "
|
||||
"focus) and issue a keyboard grab to force all keyboard events to that "
|
||||
"window. This option is seldom used and has no effect on regular X11 windows "
|
||||
"which can receive keyboard focus under normal circumstances. For a X11 grab "
|
||||
"to be taken into account under Wayland, the client must also either send a "
|
||||
"specific X11 ClientMessage to the root window or be among the applications "
|
||||
"white-listed in key “xwayland-grab-access-rules”."
|
||||
msgstr ""
|
||||
"Permitir que las pulsaciones del teclado emitidas por aplicaciones X11 "
|
||||
"ejecutándose en XWayland se tengan en cuenta. Para que una pulsación X11 se "
|
||||
@@ -504,11 +529,11 @@ msgstr ""
|
||||
"específico de X11 a la ventana raíz o estar en la lista blanca de "
|
||||
"aplicaciones en la clave “xwayland-grab-access-rules”."
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:77
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:84
|
||||
msgid "Xwayland applications allowed to issue keyboard grabs"
|
||||
msgstr "Aplicaciones de Xwayland que pueden capturar el teclado"
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:78
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:85
|
||||
msgid ""
|
||||
"List the resource names or resource class of X11 windows either allowed or "
|
||||
"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or "
|
||||
@@ -534,7 +559,7 @@ msgstr ""
|
||||
#. TRANSLATORS: This string refers to a button that switches between
|
||||
#. * different modes.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2426
|
||||
#: src/backends/meta-input-settings.c:2529
|
||||
#, c-format
|
||||
msgid "Mode Switch (Group %d)"
|
||||
msgstr "Cambiar modo (grupo %d)"
|
||||
@@ -542,11 +567,11 @@ msgstr "Cambiar modo (grupo %d)"
|
||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||
#. * mapping through the available outputs.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2449
|
||||
#: src/backends/meta-input-settings.c:2552
|
||||
msgid "Switch monitor"
|
||||
msgstr "Cambiar monitor"
|
||||
|
||||
#: src/backends/meta-input-settings.c:2451
|
||||
#: src/backends/meta-input-settings.c:2554
|
||||
msgid "Show on-screen help"
|
||||
msgstr "Mostrar la ayuda en pantalla"
|
||||
|
||||
@@ -577,9 +602,15 @@ msgctxt ""
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. Translators: this string will appear in Sysprof
|
||||
#: src/backends/meta-profiler.c:82
|
||||
#| msgid "Compositing Manager"
|
||||
msgid "Compositor"
|
||||
msgstr "Compositor"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: src/compositor/compositor.c:508
|
||||
#: src/compositor/compositor.c:510
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display “%s”."
|
||||
@@ -685,7 +716,7 @@ msgstr "Imprimir versión"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Complemento de mutter que usar"
|
||||
|
||||
#: src/core/prefs.c:1786
|
||||
#: src/core/prefs.c:1834
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Área de trabajo %d"
|
||||
@@ -699,7 +730,7 @@ msgstr "Mutter fue compilado sin soporte para modo prolijo\n"
|
||||
msgid "Mode Switch: Mode %d"
|
||||
msgstr "Cambiar modo: modo %d"
|
||||
|
||||
#: src/x11/meta-x11-display.c:669
|
||||
#: src/x11/meta-x11-display.c:681
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display “%s” already has a window manager; try using the --replace option to "
|
||||
@@ -708,16 +739,16 @@ msgstr ""
|
||||
"La pantalla «%s» ya tiene un gestor de ventanas; pruebe a usar la opción «--"
|
||||
"replace» para reemplazar el gestor de ventanas activo."
|
||||
|
||||
#: src/x11/meta-x11-display.c:1011
|
||||
#: src/x11/meta-x11-display.c:1023
|
||||
msgid "Failed to initialize GDK\n"
|
||||
msgstr "Falló al inicializar GDK\n"
|
||||
|
||||
#: src/x11/meta-x11-display.c:1035
|
||||
#: src/x11/meta-x11-display.c:1047
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display “%s”\n"
|
||||
msgstr "Ocurrió un error al abrir la pantalla de X Window System «%s»\n"
|
||||
|
||||
#: src/x11/meta-x11-display.c:1116
|
||||
#: src/x11/meta-x11-display.c:1131
|
||||
#, c-format
|
||||
msgid "Screen %d on display “%s” is invalid\n"
|
||||
msgstr "La ventana %d en la pantalla «%s» no es válida\n"
|
||||
@@ -2120,9 +2151,6 @@ msgstr "%s (on %s)"
|
||||
#~ msgid "Commands to run in response to keybindings"
|
||||
#~ msgstr "Comandos a ejecutar en respuesta a combinaciones de teclas"
|
||||
|
||||
#~ msgid "Compositing Manager"
|
||||
#~ msgstr "Gestor de composición"
|
||||
|
||||
#~ msgid "Control how new windows get focus"
|
||||
#~ msgstr "Controla cómo obtienen el foco las ventanas nuevas"
|
||||
|
||||
|
77
po/hu.po
77
po/hu.po
@@ -6,20 +6,20 @@
|
||||
# Gabor Sari <saga at externet dot hu>, 2003.
|
||||
# Laszlo Dvornik <dvornik at gnome dot hu>, 2004.
|
||||
# Gabor Kelemen <kelemeng at gnome dot hu>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013.
|
||||
# Balázs Úr <urbalazs at gmail dot com>, 2013, 2014, 2015, 2016, 2017, 2018, 2019.
|
||||
# Balázs Úr <ur.balazs at fsf dot hu>, 2013, 2014, 2015, 2016, 2017, 2018, 2019.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
|
||||
"POT-Creation-Date: 2019-02-04 17:52+0000\n"
|
||||
"PO-Revision-Date: 2019-02-05 21:06+0100\n"
|
||||
"Last-Translator: Balázs Úr <urbalazs@gmail.com>\n"
|
||||
"POT-Creation-Date: 2019-05-31 18:48+0000\n"
|
||||
"PO-Revision-Date: 2019-06-01 17:46+0200\n"
|
||||
"Last-Translator: Balázs Úr <ur.balazs at fsf dot hu>\n"
|
||||
"Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n"
|
||||
"Language: hu\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Lokalize 1.2\n"
|
||||
"X-Generator: Lokalize 18.12.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: data/50-mutter-navigation.xml:6
|
||||
@@ -395,7 +395,9 @@ msgid ""
|
||||
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
|
||||
"mutter default to layout logical monitors in a logical pixel coordinate "
|
||||
"space, while scaling monitor framebuffers instead of window content, to "
|
||||
"manage HiDPI monitors. Does not require a restart."
|
||||
"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes "
|
||||
"mutter request a low priority real-time scheduling. The executable or user "
|
||||
"must have CAP_SYS_NICE. Requires a restart."
|
||||
msgstr ""
|
||||
"A kísérleti funkciók engedélyezéséhez adja hozzá a funkció kulcsszavát a "
|
||||
"listához. A funkció a betűszedő újraindítását igényelheti az adott "
|
||||
@@ -406,21 +408,23 @@ msgstr ""
|
||||
"teszi a mutter programot a logikai monitorok elrendezéséhez egy logikai "
|
||||
"képpontkoordináta-térben, miközben átméretezi a monitor keretpufferét az "
|
||||
"ablaktartalom helyett azért, hogy kezelje a HiDPI monitorokat. Nem igényel "
|
||||
"újraindítást."
|
||||
"újraindítást. • „rt-scheduler” — alacsony prioritású, valós idejű ütemezésre "
|
||||
"kéri a mutter programot. A programnak vagy a felhasználónak CAP_SYS_NICE "
|
||||
"értékkel kell rendelkeznie. Újraindítást igényel."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:141
|
||||
#: data/org.gnome.mutter.gschema.xml.in:145
|
||||
msgid "Select window from tab popup"
|
||||
msgstr "Ablakok kiválasztása tab billentyűre felugró ablakból"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:146
|
||||
#: data/org.gnome.mutter.gschema.xml.in:150
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Tab felugró kikapcsolása"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:151
|
||||
#: data/org.gnome.mutter.gschema.xml.in:155
|
||||
msgid "Switch monitor configurations"
|
||||
msgstr "Monitorkonfiguráció átváltása"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:156
|
||||
#: data/org.gnome.mutter.gschema.xml.in:160
|
||||
msgid "Rotates the built-in monitor configuration"
|
||||
msgstr "Cserélgeti a beépített monitorkonfigurációkat"
|
||||
|
||||
@@ -525,7 +529,7 @@ msgstr ""
|
||||
#. TRANSLATORS: This string refers to a button that switches between
|
||||
#. * different modes.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2423
|
||||
#: src/backends/meta-input-settings.c:2426
|
||||
#, c-format
|
||||
msgid "Mode Switch (Group %d)"
|
||||
msgstr "Módkapcsoló (%d. csoport)"
|
||||
@@ -533,34 +537,34 @@ msgstr "Módkapcsoló (%d. csoport)"
|
||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||
#. * mapping through the available outputs.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2446
|
||||
#: src/backends/meta-input-settings.c:2449
|
||||
msgid "Switch monitor"
|
||||
msgstr "Monitorváltás"
|
||||
|
||||
#: src/backends/meta-input-settings.c:2448
|
||||
#: src/backends/meta-input-settings.c:2451
|
||||
msgid "Show on-screen help"
|
||||
msgstr "Képernyősúgó megjelenítése"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:954
|
||||
#: src/backends/meta-monitor-manager.c:976
|
||||
msgid "Built-in display"
|
||||
msgstr "Beépített kijelző"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:986
|
||||
#: src/backends/meta-monitor-manager.c:1008
|
||||
msgid "Unknown"
|
||||
msgstr "Ismeretlen"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:988
|
||||
#: src/backends/meta-monitor-manager.c:1010
|
||||
msgid "Unknown Display"
|
||||
msgstr "Ismeretlen kijelző"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:996
|
||||
#: src/backends/meta-monitor-manager.c:1018
|
||||
#, c-format
|
||||
msgctxt ""
|
||||
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:1004
|
||||
#: src/backends/meta-monitor-manager.c:1026
|
||||
#, c-format
|
||||
msgctxt ""
|
||||
"This is a monitor vendor name followed by product/model name where size in "
|
||||
@@ -568,9 +572,14 @@ msgctxt ""
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. Translators: this string will appear in Sysprof
|
||||
#: src/backends/meta-profiler.c:82
|
||||
msgid "Compositor"
|
||||
msgstr "Betűszedő"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: src/compositor/compositor.c:482
|
||||
#: src/compositor/compositor.c:510
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display “%s”."
|
||||
@@ -578,7 +587,7 @@ msgstr ""
|
||||
"Már fut egy másik kompozitálás-kezelő a(z) %i. képernyőn a(z) „%s” "
|
||||
"megjelenítőn."
|
||||
|
||||
#: src/core/bell.c:252
|
||||
#: src/core/bell.c:192
|
||||
msgid "Bell event"
|
||||
msgstr "Csengetés esemény"
|
||||
|
||||
@@ -628,16 +637,16 @@ msgid "Run with X11 backend"
|
||||
msgstr "Futtatás X11 háttérprogrammal"
|
||||
|
||||
#. Translators: %s is a window title
|
||||
#: src/core/meta-close-dialog-default.c:150
|
||||
#: src/core/meta-close-dialog-default.c:151
|
||||
#, c-format
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "„%s” nem válaszol."
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:152
|
||||
#: src/core/meta-close-dialog-default.c:153
|
||||
msgid "Application is not responding."
|
||||
msgstr "Az alkalmazás nem válaszol."
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:157
|
||||
#: src/core/meta-close-dialog-default.c:158
|
||||
msgid ""
|
||||
"You may choose to wait a short while for it to continue or force the "
|
||||
"application to quit entirely."
|
||||
@@ -645,11 +654,11 @@ msgstr ""
|
||||
"Várhat egy kicsit a folytatódására, vagy kikényszerítheti az alkalmazás "
|
||||
"teljes kilépését."
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:164
|
||||
#: src/core/meta-close-dialog-default.c:165
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Erőltetett kilépés"
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:164
|
||||
#: src/core/meta-close-dialog-default.c:165
|
||||
msgid "_Wait"
|
||||
msgstr "Vá_rakozás"
|
||||
|
||||
@@ -690,7 +699,7 @@ msgstr "A Mutter ablakkezelőt a részletes mód támogatása nélkül fordítot
|
||||
msgid "Mode Switch: Mode %d"
|
||||
msgstr "Módkapcsoló: %d. mód"
|
||||
|
||||
#: src/x11/meta-x11-display.c:666
|
||||
#: src/x11/meta-x11-display.c:674
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display “%s” already has a window manager; try using the --replace option to "
|
||||
@@ -699,20 +708,25 @@ msgstr ""
|
||||
"A(z) „%s” kijelző már rendelkezik ablakkezelővel; próbálja a --replace "
|
||||
"kapcsolóval helyettesíteni a jelenlegi ablakkezelőt."
|
||||
|
||||
#: src/x11/meta-x11-display.c:1008
|
||||
#: src/x11/meta-x11-display.c:1016
|
||||
msgid "Failed to initialize GDK\n"
|
||||
msgstr "A GDK előkészítése meghiúsult\n"
|
||||
|
||||
#: src/x11/meta-x11-display.c:1032
|
||||
#: src/x11/meta-x11-display.c:1040
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display “%s”\n"
|
||||
msgstr "Nem sikerült megnyitni a(z) „%s” X Window rendszer képernyőt\n"
|
||||
|
||||
#: src/x11/meta-x11-display.c:1115
|
||||
#: src/x11/meta-x11-display.c:1124
|
||||
#, c-format
|
||||
msgid "Screen %d on display “%s” is invalid\n"
|
||||
msgstr "A(z) %d. képernyő a(z) „%s” megjelenítőn érvénytelen\n"
|
||||
|
||||
#: src/x11/meta-x11-selection-input-stream.c:445
|
||||
#, c-format
|
||||
msgid "Format %s not supported"
|
||||
msgstr "A(z) %s formátum nem támogatott"
|
||||
|
||||
#: src/x11/session.c:1821
|
||||
msgid ""
|
||||
"These windows do not support “save current setup” and will have to be "
|
||||
@@ -721,8 +735,7 @@ msgstr ""
|
||||
"Az alábbi ablakok nem támogatják az „aktuális beállítások mentését”, emiatt "
|
||||
"ezeket a legközelebbi bejelentkezéskor manuálisan újra kell indítania."
|
||||
|
||||
#: src/x11/window-props.c:568
|
||||
#: src/x11/window-props.c:569
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (ezen: %s)"
|
||||
|
||||
|
@@ -66,6 +66,10 @@
|
||||
#include "meta/meta-backend.h"
|
||||
#include "meta/util.h"
|
||||
|
||||
#ifdef HAVE_PROFILER
|
||||
#include "backends/meta-profiler.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_REMOTE_DESKTOP
|
||||
#include "backends/meta-dbus-session-watcher.h"
|
||||
#include "backends/meta-remote-access-controller-private.h"
|
||||
@@ -127,6 +131,10 @@ struct _MetaBackendPrivate
|
||||
MetaRemoteDesktop *remote_desktop;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROFILER
|
||||
MetaProfiler *profiler;
|
||||
#endif
|
||||
|
||||
ClutterBackend *clutter_backend;
|
||||
ClutterActor *stage;
|
||||
|
||||
@@ -193,6 +201,10 @@ meta_backend_finalize (GObject *object)
|
||||
|
||||
g_clear_object (&priv->settings);
|
||||
|
||||
#ifdef HAVE_PROFILER
|
||||
g_clear_object (&priv->profiler);
|
||||
#endif
|
||||
|
||||
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -841,6 +853,10 @@ meta_backend_initable_init (GInitable *initable,
|
||||
system_bus_gotten_cb,
|
||||
backend);
|
||||
|
||||
#ifdef HAVE_PROFILER
|
||||
priv->profiler = meta_profiler_new ();
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "backends/meta-stage-private.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "cogl/cogl.h"
|
||||
#include "meta/meta-backend.h"
|
||||
#include "meta/util.h"
|
||||
@@ -82,6 +83,33 @@ meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer,
|
||||
g_signal_emit (renderer, signals[CURSOR_PAINTED], 0, cursor_sprite);
|
||||
}
|
||||
|
||||
static void
|
||||
align_cursor_position (MetaCursorRenderer *renderer,
|
||||
ClutterRect *rect)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
ClutterStageView *view;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
float view_scale;
|
||||
|
||||
view = clutter_stage_get_view_at (CLUTTER_STAGE (stage),
|
||||
priv->current_x,
|
||||
priv->current_y);
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
view_scale = clutter_stage_view_get_scale (view);
|
||||
|
||||
clutter_rect_offset (rect, -view_layout.x, -view_layout.y);
|
||||
rect->origin.x = floorf (rect->origin.x * view_scale) / view_scale;
|
||||
rect->origin.y = floorf (rect->origin.y * view_scale) / view_scale;
|
||||
clutter_rect_offset (rect, view_layout.x, view_layout.y);
|
||||
}
|
||||
|
||||
static void
|
||||
queue_redraw (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
@@ -92,13 +120,16 @@ queue_redraw (MetaCursorRenderer *renderer,
|
||||
CoglTexture *texture;
|
||||
ClutterRect rect = CLUTTER_RECT_INIT_ZERO;
|
||||
|
||||
if (cursor_sprite)
|
||||
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
|
||||
|
||||
/* During early initialization, we can have no stage */
|
||||
if (!stage)
|
||||
return;
|
||||
|
||||
if (cursor_sprite)
|
||||
{
|
||||
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
|
||||
align_cursor_position (renderer, &rect);
|
||||
}
|
||||
|
||||
if (!priv->stage_overlay)
|
||||
priv->stage_overlay = meta_stage_create_cursor_overlay (META_STAGE (stage));
|
||||
|
||||
|
@@ -353,7 +353,7 @@ find_builtin_output (MetaInputMapper *mapper,
|
||||
return panel != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
guess_candidates (MetaInputMapper *mapper,
|
||||
MetaMapperInputInfo *input,
|
||||
DeviceCandidates *info)
|
||||
@@ -387,15 +387,7 @@ guess_candidates (MetaInputMapper *mapper,
|
||||
find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]);
|
||||
}
|
||||
|
||||
if (best < N_OUTPUT_MATCHES)
|
||||
{
|
||||
info->best = best;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
info->best = best;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -408,8 +400,7 @@ mapping_helper_add (MappingHelper *helper,
|
||||
|
||||
info.input = input;
|
||||
|
||||
if (!guess_candidates (mapper, input, &info))
|
||||
return;
|
||||
guess_candidates (mapper, input, &info);
|
||||
|
||||
for (i = 0; i < helper->device_maps->len; i++)
|
||||
{
|
||||
|
@@ -76,7 +76,8 @@ struct _MetaInputSettingsPrivate
|
||||
GSettings *trackball_settings;
|
||||
GSettings *keyboard_settings;
|
||||
GSettings *gsd_settings;
|
||||
GSettings *a11y_settings;
|
||||
GSettings *keyboard_a11y_settings;
|
||||
GSettings *mouse_a11y_settings;
|
||||
|
||||
GHashTable *mappable_devices;
|
||||
|
||||
@@ -161,7 +162,8 @@ meta_input_settings_dispose (GObject *object)
|
||||
g_clear_object (&priv->trackball_settings);
|
||||
g_clear_object (&priv->keyboard_settings);
|
||||
g_clear_object (&priv->gsd_settings);
|
||||
g_clear_object (&priv->a11y_settings);
|
||||
g_clear_object (&priv->keyboard_a11y_settings);
|
||||
g_clear_object (&priv->mouse_a11y_settings);
|
||||
g_clear_object (&priv->input_mapper);
|
||||
g_clear_pointer (&priv->mappable_devices, g_hash_table_unref);
|
||||
g_clear_pointer (&priv->current_tools, g_hash_table_unref);
|
||||
@@ -1191,10 +1193,10 @@ apply_mappable_device_settings (MetaInputSettings *input_settings,
|
||||
}
|
||||
}
|
||||
|
||||
struct _a11y_settings_flags_pair {
|
||||
struct _keyboard_a11y_settings_flags_pair {
|
||||
const char *name;
|
||||
ClutterKeyboardA11yFlags flag;
|
||||
} settings_flags_pair[] = {
|
||||
} keyboard_a11y_settings_flags_pair[] = {
|
||||
{ "enable", CLUTTER_A11Y_KEYBOARD_ENABLED },
|
||||
{ "timeout-enable", CLUTTER_A11Y_TIMEOUT_ENABLED },
|
||||
{ "mousekeys-enable", CLUTTER_A11Y_MOUSE_KEYS_ENABLED },
|
||||
@@ -1225,23 +1227,23 @@ load_keyboard_a11y_settings (MetaInputSettings *input_settings,
|
||||
return;
|
||||
|
||||
kbd_a11y_settings.controls = 0;
|
||||
for (i = 0; i < G_N_ELEMENTS (settings_flags_pair); i++)
|
||||
for (i = 0; i < G_N_ELEMENTS (keyboard_a11y_settings_flags_pair); i++)
|
||||
{
|
||||
if (g_settings_get_boolean (priv->a11y_settings, settings_flags_pair[i].name))
|
||||
kbd_a11y_settings.controls |= settings_flags_pair[i].flag;
|
||||
if (g_settings_get_boolean (priv->keyboard_a11y_settings, keyboard_a11y_settings_flags_pair[i].name))
|
||||
kbd_a11y_settings.controls |= keyboard_a11y_settings_flags_pair[i].flag;
|
||||
}
|
||||
|
||||
kbd_a11y_settings.timeout_delay = g_settings_get_int (priv->a11y_settings,
|
||||
kbd_a11y_settings.timeout_delay = g_settings_get_int (priv->keyboard_a11y_settings,
|
||||
"disable-timeout");
|
||||
kbd_a11y_settings.slowkeys_delay = g_settings_get_int (priv->a11y_settings,
|
||||
kbd_a11y_settings.slowkeys_delay = g_settings_get_int (priv->keyboard_a11y_settings,
|
||||
"slowkeys-delay");
|
||||
kbd_a11y_settings.debounce_delay = g_settings_get_int (priv->a11y_settings,
|
||||
kbd_a11y_settings.debounce_delay = g_settings_get_int (priv->keyboard_a11y_settings,
|
||||
"bouncekeys-delay");
|
||||
kbd_a11y_settings.mousekeys_init_delay = g_settings_get_int (priv->a11y_settings,
|
||||
kbd_a11y_settings.mousekeys_init_delay = g_settings_get_int (priv->keyboard_a11y_settings,
|
||||
"mousekeys-init-delay");
|
||||
kbd_a11y_settings.mousekeys_max_speed = g_settings_get_int (priv->a11y_settings,
|
||||
kbd_a11y_settings.mousekeys_max_speed = g_settings_get_int (priv->keyboard_a11y_settings,
|
||||
"mousekeys-max-speed");
|
||||
kbd_a11y_settings.mousekeys_accel_time = g_settings_get_int (priv->a11y_settings,
|
||||
kbd_a11y_settings.mousekeys_accel_time = g_settings_get_int (priv->keyboard_a11y_settings,
|
||||
"mousekeys-accel-time");
|
||||
|
||||
clutter_device_manager_set_kbd_a11y_settings (priv->device_manager, &kbd_a11y_settings);
|
||||
@@ -1256,25 +1258,121 @@ on_keyboard_a11y_settings_changed (ClutterDeviceManager *device_manager,
|
||||
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (settings_flags_pair); i++)
|
||||
for (i = 0; i < G_N_ELEMENTS (keyboard_a11y_settings_flags_pair); i++)
|
||||
{
|
||||
if (settings_flags_pair[i].flag & what_changed)
|
||||
g_settings_set_boolean (priv->a11y_settings,
|
||||
settings_flags_pair[i].name,
|
||||
(new_flags & settings_flags_pair[i].flag) ? TRUE : FALSE);
|
||||
if (keyboard_a11y_settings_flags_pair[i].flag & what_changed)
|
||||
g_settings_set_boolean (priv->keyboard_a11y_settings,
|
||||
keyboard_a11y_settings_flags_pair[i].name,
|
||||
(new_flags & keyboard_a11y_settings_flags_pair[i].flag) ? TRUE : FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_a11y_settings_changed (GSettings *settings,
|
||||
const char *key,
|
||||
gpointer user_data)
|
||||
meta_input_keyboard_a11y_settings_changed (GSettings *settings,
|
||||
const char *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data);
|
||||
|
||||
load_keyboard_a11y_settings (input_settings, NULL);
|
||||
}
|
||||
|
||||
struct _pointer_a11y_settings_flags_pair {
|
||||
const char *name;
|
||||
ClutterPointerA11yFlags flag;
|
||||
} pointer_a11y_settings_flags_pair[] = {
|
||||
{ "secondary-click-enabled", CLUTTER_A11Y_SECONDARY_CLICK_ENABLED },
|
||||
{ "dwell-click-enabled", CLUTTER_A11Y_DWELL_ENABLED },
|
||||
};
|
||||
|
||||
static ClutterPointerA11yDwellDirection
|
||||
pointer_a11y_dwell_direction_from_setting (MetaInputSettings *input_settings,
|
||||
const char *key)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
|
||||
GDesktopMouseDwellDirection dwell_gesture_direction;
|
||||
|
||||
dwell_gesture_direction = g_settings_get_enum (priv->mouse_a11y_settings, key);
|
||||
switch (dwell_gesture_direction)
|
||||
{
|
||||
case G_DESKTOP_MOUSE_DWELL_DIRECTION_LEFT:
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_LEFT;
|
||||
break;
|
||||
case G_DESKTOP_MOUSE_DWELL_DIRECTION_RIGHT:
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT;
|
||||
break;
|
||||
case G_DESKTOP_MOUSE_DWELL_DIRECTION_UP:
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_UP;
|
||||
break;
|
||||
case G_DESKTOP_MOUSE_DWELL_DIRECTION_DOWN:
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_DOWN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
load_pointer_a11y_settings (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
|
||||
ClutterPointerA11ySettings pointer_a11y_settings;
|
||||
ClutterInputDevice *core_pointer;
|
||||
GDesktopMouseDwellMode dwell_mode;
|
||||
|
||||
guint i;
|
||||
|
||||
core_pointer = clutter_device_manager_get_core_device (priv->device_manager, CLUTTER_POINTER_DEVICE);
|
||||
if (device && device != core_pointer)
|
||||
return;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (priv->device_manager, &pointer_a11y_settings);
|
||||
pointer_a11y_settings.controls = 0;
|
||||
for (i = 0; i < G_N_ELEMENTS (pointer_a11y_settings_flags_pair); i++)
|
||||
{
|
||||
if (g_settings_get_boolean (priv->mouse_a11y_settings, pointer_a11y_settings_flags_pair[i].name))
|
||||
pointer_a11y_settings.controls |= pointer_a11y_settings_flags_pair[i].flag;
|
||||
}
|
||||
|
||||
/* "secondary-click-time" is expressed in seconds */
|
||||
pointer_a11y_settings.secondary_click_delay =
|
||||
(1000 * g_settings_get_double (priv->mouse_a11y_settings, "secondary-click-time"));
|
||||
/* "dwell-time" is expressed in seconds */
|
||||
pointer_a11y_settings.dwell_delay =
|
||||
(1000 * g_settings_get_double (priv->mouse_a11y_settings, "dwell-time"));
|
||||
pointer_a11y_settings.dwell_threshold = g_settings_get_int (priv->mouse_a11y_settings,
|
||||
"dwell-threshold");
|
||||
|
||||
dwell_mode = g_settings_get_enum (priv->mouse_a11y_settings, "dwell-mode");
|
||||
if (dwell_mode == G_DESKTOP_MOUSE_DWELL_MODE_WINDOW)
|
||||
pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_WINDOW;
|
||||
else
|
||||
pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_GESTURE;
|
||||
|
||||
pointer_a11y_settings.dwell_gesture_single =
|
||||
pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-single");
|
||||
pointer_a11y_settings.dwell_gesture_double =
|
||||
pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-double");
|
||||
pointer_a11y_settings.dwell_gesture_drag =
|
||||
pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-drag");
|
||||
pointer_a11y_settings.dwell_gesture_secondary =
|
||||
pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-secondary");
|
||||
|
||||
clutter_device_manager_set_pointer_a11y_settings (priv->device_manager, &pointer_a11y_settings);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_mouse_a11y_settings_changed (GSettings *settings,
|
||||
const char *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data);
|
||||
|
||||
load_pointer_a11y_settings (input_settings, NULL);
|
||||
}
|
||||
|
||||
static GSettings *
|
||||
lookup_device_settings (ClutterInputDevice *device)
|
||||
{
|
||||
@@ -1556,6 +1654,7 @@ apply_device_settings (MetaInputSettings *input_settings,
|
||||
priv->trackball_settings,
|
||||
device);
|
||||
load_keyboard_a11y_settings (input_settings, device);
|
||||
load_pointer_a11y_settings (input_settings, device);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1856,12 +1955,16 @@ meta_input_settings_init (MetaInputSettings *settings)
|
||||
clutter_settings_get_default(), "double-click-time",
|
||||
G_SETTINGS_BIND_GET);
|
||||
|
||||
priv->a11y_settings = g_settings_new ("org.gnome.desktop.a11y.keyboard");
|
||||
g_signal_connect (priv->a11y_settings, "changed",
|
||||
G_CALLBACK (meta_input_a11y_settings_changed), settings);
|
||||
priv->keyboard_a11y_settings = g_settings_new ("org.gnome.desktop.a11y.keyboard");
|
||||
g_signal_connect (priv->keyboard_a11y_settings, "changed",
|
||||
G_CALLBACK (meta_input_keyboard_a11y_settings_changed), settings);
|
||||
g_signal_connect (priv->device_manager, "kbd-a11y-flags-changed",
|
||||
G_CALLBACK (on_keyboard_a11y_settings_changed), settings);
|
||||
|
||||
priv->mouse_a11y_settings = g_settings_new ("org.gnome.desktop.a11y.mouse");
|
||||
g_signal_connect (priv->mouse_a11y_settings, "changed",
|
||||
G_CALLBACK (meta_input_mouse_a11y_settings_changed), settings);
|
||||
|
||||
priv->mappable_devices =
|
||||
g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) device_mapping_info_free);
|
||||
|
||||
|
@@ -589,12 +589,7 @@ meta_monitor_normal_derive_layout (MetaMonitor *monitor,
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
*layout = (MetaRectangle) {
|
||||
.x = crtc->rect.x,
|
||||
.y = crtc->rect.y,
|
||||
.width = crtc->rect.width,
|
||||
.height = crtc->rect.height
|
||||
};
|
||||
*layout = crtc->rect;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
206
src/backends/meta-profiler.c
Normal file
206
src/backends/meta-profiler.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Endless, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "src/backends/meta-profiler.h"
|
||||
|
||||
#include <glib-unix.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gunixfdlist.h>
|
||||
|
||||
#include "cogl/cogl-trace.h"
|
||||
|
||||
#define META_SYSPROF_PROFILER_DBUS_PATH "/org/gnome/Sysprof3/Profiler"
|
||||
|
||||
struct _MetaProfiler
|
||||
{
|
||||
MetaDBusSysprof3ProfilerSkeleton parent_instance;
|
||||
|
||||
GDBusConnection *connection;
|
||||
GCancellable *cancellable;
|
||||
|
||||
gboolean running;
|
||||
};
|
||||
|
||||
static void
|
||||
meta_sysprof_capturer_init_iface (MetaDBusSysprof3ProfilerIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaProfiler,
|
||||
meta_profiler,
|
||||
META_DBUS_TYPE_SYSPROF3_PROFILER_SKELETON,
|
||||
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SYSPROF3_PROFILER,
|
||||
meta_sysprof_capturer_init_iface))
|
||||
|
||||
static gboolean
|
||||
handle_start (MetaDBusSysprof3Profiler *dbus_profiler,
|
||||
GDBusMethodInvocation *invocation,
|
||||
GVariant *options,
|
||||
GVariant *fd_variant)
|
||||
{
|
||||
MetaProfiler *profiler = META_PROFILER (dbus_profiler);
|
||||
GMainContext *main_context = g_main_context_default ();
|
||||
GDBusMessage *message;
|
||||
GUnixFDList *fd_list;
|
||||
const char *group_name;
|
||||
int position;
|
||||
int fd = -1;
|
||||
|
||||
if (profiler->running)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Profiler already running");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_variant_get (fd_variant, "h", &position);
|
||||
|
||||
message = g_dbus_method_invocation_get_message (invocation);
|
||||
fd_list = g_dbus_message_get_unix_fd_list (message);
|
||||
if (fd_list)
|
||||
fd = g_unix_fd_list_get (fd_list, position, NULL);
|
||||
|
||||
/* Translators: this string will appear in Sysprof */
|
||||
group_name = _("Compositor");
|
||||
|
||||
if (fd != -1)
|
||||
{
|
||||
cogl_set_tracing_enabled_on_thread_with_fd (main_context,
|
||||
group_name,
|
||||
fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
cogl_set_tracing_enabled_on_thread (main_context,
|
||||
group_name,
|
||||
"mutter-profile.syscap");
|
||||
}
|
||||
|
||||
profiler->running = TRUE;
|
||||
|
||||
g_debug ("Profiler running");
|
||||
|
||||
meta_dbus_sysprof3_profiler_complete_start (dbus_profiler, invocation);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_stop (MetaDBusSysprof3Profiler *dbus_profiler,
|
||||
GDBusMethodInvocation *invocation)
|
||||
{
|
||||
MetaProfiler *profiler = META_PROFILER (dbus_profiler);
|
||||
|
||||
if (!profiler->running)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Profiler not running");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cogl_set_tracing_disabled_on_thread (g_main_context_default ());
|
||||
profiler->running = FALSE;
|
||||
|
||||
g_debug ("Stopping profiler");
|
||||
|
||||
meta_dbus_sysprof3_profiler_complete_stop (dbus_profiler, invocation);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sysprof_capturer_init_iface (MetaDBusSysprof3ProfilerIface *iface)
|
||||
{
|
||||
iface->handle_start = handle_start;
|
||||
iface->handle_stop = handle_stop;
|
||||
}
|
||||
|
||||
static void
|
||||
on_bus_acquired_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr (GDBusConnection) connection = NULL;
|
||||
GDBusInterfaceSkeleton *interface_skeleton;
|
||||
g_autoptr (GError) error = NULL;
|
||||
MetaProfiler *profiler;
|
||||
|
||||
connection = g_bus_get_finish (result, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to get session bus: %s\n", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
profiler = META_PROFILER (user_data);
|
||||
interface_skeleton = G_DBUS_INTERFACE_SKELETON (profiler);
|
||||
|
||||
if (!g_dbus_interface_skeleton_export (interface_skeleton,
|
||||
connection,
|
||||
META_SYSPROF_PROFILER_DBUS_PATH,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Failed to export profiler object: %s\n", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
profiler->connection = g_steal_pointer (&connection);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_profiler_finalize (GObject *object)
|
||||
{
|
||||
MetaProfiler *self = (MetaProfiler *)object;
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_object (&self->connection);
|
||||
|
||||
G_OBJECT_CLASS (meta_profiler_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_profiler_class_init (MetaProfilerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_profiler_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_profiler_init (MetaProfiler *self)
|
||||
{
|
||||
self->cancellable = g_cancellable_new ();
|
||||
|
||||
g_bus_get (G_BUS_TYPE_SESSION,
|
||||
self->cancellable,
|
||||
on_bus_acquired_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
MetaProfiler *
|
||||
meta_profiler_new (void)
|
||||
{
|
||||
return g_object_new (META_TYPE_PROFILER, NULL);
|
||||
}
|
41
src/backends/meta-profiler.h
Normal file
41
src/backends/meta-profiler.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Endless, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_PROFILER_H
|
||||
#define META_PROFILER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "meta-dbus-sysprof3-profiler.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_PROFILER (meta_profiler_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (MetaProfiler,
|
||||
meta_profiler,
|
||||
META,
|
||||
PROFILER,
|
||||
MetaDBusSysprof3ProfilerSkeleton)
|
||||
|
||||
MetaProfiler * meta_profiler_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* META_PROFILER_H */
|
@@ -66,6 +66,6 @@ void meta_settings_get_xwayland_grab_patterns (MetaSettings *settings,
|
||||
GPtrArray **whitelist_patterns,
|
||||
GPtrArray **blacklist_patterns);
|
||||
|
||||
gboolean meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings);
|
||||
gboolean meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings);
|
||||
|
||||
#endif /* META_SETTINGS_PRIVATE_H */
|
||||
|
@@ -404,7 +404,7 @@ meta_settings_get_xwayland_grab_patterns (MetaSettings *settings,
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings)
|
||||
meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings)
|
||||
{
|
||||
return (settings->xwayland_allow_grabs);
|
||||
}
|
||||
|
@@ -823,6 +823,7 @@ static void
|
||||
cursor_priv_free (MetaCursorNativePrivate *cursor_priv)
|
||||
{
|
||||
g_hash_table_destroy (cursor_priv->gpu_states);
|
||||
g_free (cursor_priv);
|
||||
}
|
||||
|
||||
static MetaCursorNativePrivate *
|
||||
|
65
src/backends/native/meta-drm-buffer-dumb.c
Normal file
65
src/backends/native/meta-drm-buffer-dumb.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Intel Corporation.
|
||||
* Copyright (C) 2016 Red Hat
|
||||
* Copyright (C) 2018 DisplayLink (UK) Ltd.
|
||||
* Copyright (C) 2018 Canonical Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-drm-buffer-dumb.h"
|
||||
|
||||
struct _MetaDrmBufferDumb
|
||||
{
|
||||
MetaDrmBuffer parent;
|
||||
|
||||
uint32_t fb_id;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaDrmBufferDumb, meta_drm_buffer_dumb, META_TYPE_DRM_BUFFER)
|
||||
|
||||
MetaDrmBufferDumb *
|
||||
meta_drm_buffer_dumb_new (uint32_t dumb_fb_id)
|
||||
{
|
||||
MetaDrmBufferDumb *buffer_dumb;
|
||||
|
||||
buffer_dumb = g_object_new (META_TYPE_DRM_BUFFER_DUMB, NULL);
|
||||
buffer_dumb->fb_id = dumb_fb_id;
|
||||
|
||||
return buffer_dumb;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
meta_drm_buffer_dumb_get_fb_id (MetaDrmBuffer *buffer)
|
||||
{
|
||||
return META_DRM_BUFFER_DUMB (buffer)->fb_id;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_dumb_init (MetaDrmBufferDumb *buffer_dumb)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_dumb_class_init (MetaDrmBufferDumbClass *klass)
|
||||
{
|
||||
MetaDrmBufferClass *buffer_class = META_DRM_BUFFER_CLASS (klass);
|
||||
|
||||
buffer_class->get_fb_id = meta_drm_buffer_dumb_get_fb_id;
|
||||
}
|
35
src/backends/native/meta-drm-buffer-dumb.h
Normal file
35
src/backends/native/meta-drm-buffer-dumb.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Canonical Ltd.
|
||||
* Copyright (C) 2019 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef META_DRM_BUFFER_DUMB_H
|
||||
#define META_DRM_BUFFER_DUMB_H
|
||||
|
||||
#include "backends/native/meta-drm-buffer.h"
|
||||
|
||||
#define META_TYPE_DRM_BUFFER_DUMB (meta_drm_buffer_dumb_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaDrmBufferDumb,
|
||||
meta_drm_buffer_dumb,
|
||||
META, DRM_BUFFER_DUMB,
|
||||
MetaDrmBuffer)
|
||||
|
||||
MetaDrmBufferDumb * meta_drm_buffer_dumb_new (uint32_t dumb_fb_id);
|
||||
|
||||
#endif /* META_DRM_BUFFER_DUMB_H */
|
232
src/backends/native/meta-drm-buffer-gbm.c
Normal file
232
src/backends/native/meta-drm-buffer-gbm.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Intel Corporation.
|
||||
* Copyright (C) 2016 Red Hat
|
||||
* Copyright (C) 2018 DisplayLink (UK) Ltd.
|
||||
* Copyright (C) 2018 Canonical Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-drm-buffer-gbm.h"
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
#include <errno.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#define INVALID_FB_ID 0U
|
||||
|
||||
struct _MetaDrmBufferGbm
|
||||
{
|
||||
MetaDrmBuffer parent;
|
||||
|
||||
MetaGpuKms *gpu_kms;
|
||||
|
||||
struct gbm_surface *surface;
|
||||
|
||||
struct gbm_bo *bo;
|
||||
uint32_t fb_id;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaDrmBufferGbm, meta_drm_buffer_gbm, META_TYPE_DRM_BUFFER)
|
||||
|
||||
struct gbm_bo *
|
||||
meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm)
|
||||
{
|
||||
return buffer_gbm->bo;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
acquire_swapped_buffer (MetaDrmBufferGbm *buffer_gbm,
|
||||
gboolean use_modifiers,
|
||||
GError **error)
|
||||
{
|
||||
uint32_t handles[4] = {0, 0, 0, 0};
|
||||
uint32_t strides[4] = {0, 0, 0, 0};
|
||||
uint32_t offsets[4] = {0, 0, 0, 0};
|
||||
uint64_t modifiers[4] = {0, 0, 0, 0};
|
||||
uint32_t width, height;
|
||||
uint32_t format;
|
||||
struct gbm_bo *bo;
|
||||
int kms_fd;
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (buffer_gbm->gpu_kms);
|
||||
|
||||
bo = gbm_surface_lock_front_buffer (buffer_gbm->surface);
|
||||
if (!bo)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"gbm_surface_lock_front_buffer failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gbm_bo_get_handle_for_plane (bo, 0).s32 == -1)
|
||||
{
|
||||
/* Failed to fetch handle to plane, falling back to old method */
|
||||
strides[0] = gbm_bo_get_stride (bo);
|
||||
handles[0] = gbm_bo_get_handle (bo).u32;
|
||||
offsets[0] = 0;
|
||||
modifiers[0] = DRM_FORMAT_MOD_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < gbm_bo_get_plane_count (bo); i++)
|
||||
{
|
||||
strides[i] = gbm_bo_get_stride_for_plane (bo, i);
|
||||
handles[i] = gbm_bo_get_handle_for_plane (bo, i).u32;
|
||||
offsets[i] = gbm_bo_get_offset (bo, i);
|
||||
modifiers[i] = gbm_bo_get_modifier (bo);
|
||||
}
|
||||
}
|
||||
|
||||
width = gbm_bo_get_width (bo);
|
||||
height = gbm_bo_get_height (bo);
|
||||
format = gbm_bo_get_format (bo);
|
||||
|
||||
if (use_modifiers && modifiers[0] != DRM_FORMAT_MOD_INVALID)
|
||||
{
|
||||
if (drmModeAddFB2WithModifiers (kms_fd,
|
||||
width, height,
|
||||
format,
|
||||
handles,
|
||||
strides,
|
||||
offsets,
|
||||
modifiers,
|
||||
&buffer_gbm->fb_id,
|
||||
DRM_MODE_FB_MODIFIERS))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (errno),
|
||||
"drmModeAddFB2WithModifiers failed: %s",
|
||||
g_strerror (errno));
|
||||
gbm_surface_release_buffer (buffer_gbm->surface, bo);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (drmModeAddFB2 (kms_fd,
|
||||
width,
|
||||
height,
|
||||
format,
|
||||
handles,
|
||||
strides,
|
||||
offsets,
|
||||
&buffer_gbm->fb_id,
|
||||
0))
|
||||
{
|
||||
if (format != DRM_FORMAT_XRGB8888)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"drmModeAddFB does not support format 0x%x",
|
||||
format);
|
||||
gbm_surface_release_buffer (buffer_gbm->surface, bo);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (drmModeAddFB (kms_fd,
|
||||
width,
|
||||
height,
|
||||
24,
|
||||
32,
|
||||
strides[0],
|
||||
handles[0],
|
||||
&buffer_gbm->fb_id))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (errno),
|
||||
"drmModeAddFB failed: %s",
|
||||
g_strerror (errno));
|
||||
gbm_surface_release_buffer (buffer_gbm->surface, bo);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
buffer_gbm->bo = bo;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
MetaDrmBufferGbm *
|
||||
meta_drm_buffer_gbm_new (MetaGpuKms *gpu_kms,
|
||||
struct gbm_surface *gbm_surface,
|
||||
gboolean use_modifiers,
|
||||
GError **error)
|
||||
{
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
|
||||
buffer_gbm = g_object_new (META_TYPE_DRM_BUFFER_GBM, NULL);
|
||||
buffer_gbm->gpu_kms = gpu_kms;
|
||||
buffer_gbm->surface = gbm_surface;
|
||||
|
||||
if (!acquire_swapped_buffer (buffer_gbm, use_modifiers, error))
|
||||
{
|
||||
g_object_unref (buffer_gbm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buffer_gbm;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
meta_drm_buffer_gbm_get_fb_id (MetaDrmBuffer *buffer)
|
||||
{
|
||||
return META_DRM_BUFFER_GBM (buffer)->fb_id;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_gbm_finalize (GObject *object)
|
||||
{
|
||||
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (object);
|
||||
|
||||
if (buffer_gbm->fb_id != INVALID_FB_ID)
|
||||
{
|
||||
int kms_fd;
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (buffer_gbm->gpu_kms);
|
||||
drmModeRmFB (kms_fd, buffer_gbm->fb_id);
|
||||
}
|
||||
|
||||
if (buffer_gbm->bo)
|
||||
gbm_surface_release_buffer (buffer_gbm->surface, buffer_gbm->bo);
|
||||
|
||||
G_OBJECT_CLASS (meta_drm_buffer_gbm_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_gbm_init (MetaDrmBufferGbm *buffer_gbm)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_gbm_class_init (MetaDrmBufferGbmClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
MetaDrmBufferClass *buffer_class = META_DRM_BUFFER_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_drm_buffer_gbm_finalize;
|
||||
|
||||
buffer_class->get_fb_id = meta_drm_buffer_gbm_get_fb_id;
|
||||
}
|
43
src/backends/native/meta-drm-buffer-gbm.h
Normal file
43
src/backends/native/meta-drm-buffer-gbm.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Canonical Ltd.
|
||||
* Copyright (C) 2019 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef META_DRM_BUFFER_GBM_H
|
||||
#define META_DRM_BUFFER_GBM_H
|
||||
|
||||
#include <gbm.h>
|
||||
|
||||
#include "backends/native/meta-drm-buffer.h"
|
||||
#include "backends/native/meta-gpu-kms.h"
|
||||
|
||||
#define META_TYPE_DRM_BUFFER_GBM (meta_drm_buffer_gbm_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaDrmBufferGbm,
|
||||
meta_drm_buffer_gbm,
|
||||
META, DRM_BUFFER_GBM,
|
||||
MetaDrmBuffer)
|
||||
|
||||
MetaDrmBufferGbm * meta_drm_buffer_gbm_new (MetaGpuKms *gpu_kms,
|
||||
struct gbm_surface *gbm_surface,
|
||||
gboolean use_modifiers,
|
||||
GError **error);
|
||||
|
||||
struct gbm_bo * meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm);
|
||||
|
||||
#endif /* META_DRM_BUFFER_GBM_H */
|
45
src/backends/native/meta-drm-buffer.c
Normal file
45
src/backends/native/meta-drm-buffer.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Intel Corporation.
|
||||
* Copyright (C) 2016 Red Hat
|
||||
* Copyright (C) 2018 DisplayLink (UK) Ltd.
|
||||
* Copyright (C) 2018 Canonical Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-drm-buffer.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (MetaDrmBuffer, meta_drm_buffer, G_TYPE_OBJECT)
|
||||
|
||||
uint32_t
|
||||
meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer)
|
||||
{
|
||||
return META_DRM_BUFFER_GET_CLASS (buffer)->get_fb_id (buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_init (MetaDrmBuffer *buffer)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_class_init (MetaDrmBufferClass *klass)
|
||||
{
|
||||
}
|
46
src/backends/native/meta-drm-buffer.h
Normal file
46
src/backends/native/meta-drm-buffer.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Canonical Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
|
||||
*/
|
||||
|
||||
#ifndef META_DRM_BUFFER_H
|
||||
#define META_DRM_BUFFER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define META_TYPE_DRM_BUFFER (meta_drm_buffer_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaDrmBuffer,
|
||||
meta_drm_buffer,
|
||||
META, DRM_BUFFER,
|
||||
GObject)
|
||||
|
||||
struct _MetaDrmBufferClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
uint32_t (* get_fb_id) (MetaDrmBuffer *buffer);
|
||||
};
|
||||
|
||||
MetaDrmBuffer *
|
||||
meta_drm_buffer_new_from_dumb (uint32_t dumb_fb_id);
|
||||
|
||||
uint32_t meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer);
|
||||
|
||||
#endif /* META_DRM_BUFFER_H */
|
@@ -251,13 +251,15 @@ get_session_proxy (GCancellable *cancellable,
|
||||
}
|
||||
|
||||
static Login1Seat *
|
||||
get_seat_proxy (GCancellable *cancellable,
|
||||
get_seat_proxy (gchar *seat_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autofree char *seat_proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/seat", seat_id);
|
||||
Login1Seat *seat = login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1/seat/self",
|
||||
seat_proxy_path,
|
||||
cancellable, error);
|
||||
if (!seat)
|
||||
g_prefix_error(error, "Could not get seat proxy: ");
|
||||
@@ -511,7 +513,7 @@ meta_launcher_new (GError **error)
|
||||
if (!seat_id)
|
||||
goto fail;
|
||||
|
||||
seat_proxy = get_seat_proxy (NULL, error);
|
||||
seat_proxy = get_seat_proxy (seat_id, NULL, error);
|
||||
if (!seat_proxy)
|
||||
goto fail;
|
||||
|
||||
|
@@ -58,6 +58,9 @@
|
||||
#include "backends/meta-output.h"
|
||||
#include "backends/meta-renderer-view.h"
|
||||
#include "backends/native/meta-crtc-kms.h"
|
||||
#include "backends/native/meta-drm-buffer-dumb.h"
|
||||
#include "backends/native/meta-drm-buffer-gbm.h"
|
||||
#include "backends/native/meta-drm-buffer.h"
|
||||
#include "backends/native/meta-gpu-kms.h"
|
||||
#include "backends/native/meta-monitor-manager-kms.h"
|
||||
#include "backends/native/meta-renderer-native-gles3.h"
|
||||
@@ -144,10 +147,8 @@ typedef struct _MetaOnscreenNativeSecondaryGpuState
|
||||
|
||||
struct {
|
||||
struct gbm_surface *surface;
|
||||
uint32_t current_fb_id;
|
||||
uint32_t next_fb_id;
|
||||
struct gbm_bo *current_bo;
|
||||
struct gbm_bo *next_bo;
|
||||
MetaDrmBuffer *current_fb;
|
||||
MetaDrmBuffer *next_fb;
|
||||
} gbm;
|
||||
|
||||
struct {
|
||||
@@ -168,10 +169,8 @@ typedef struct _MetaOnscreenNative
|
||||
|
||||
struct {
|
||||
struct gbm_surface *surface;
|
||||
uint32_t current_fb_id;
|
||||
uint32_t next_fb_id;
|
||||
struct gbm_bo *current_bo;
|
||||
struct gbm_bo *next_bo;
|
||||
MetaDrmBuffer *current_fb;
|
||||
MetaDrmBuffer *next_fb;
|
||||
} gbm;
|
||||
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
@@ -971,25 +970,12 @@ free_current_secondary_bo (MetaGpuKms *gpu_kms,
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
|
||||
{
|
||||
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||
int kms_fd;
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
||||
|
||||
renderer_gpu_data = secondary_gpu_state->renderer_gpu_data;
|
||||
switch (renderer_gpu_data->secondary.copy_mode)
|
||||
{
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_GPU:
|
||||
if (secondary_gpu_state->gbm.current_fb_id)
|
||||
{
|
||||
drmModeRmFB (kms_fd, secondary_gpu_state->gbm.current_fb_id);
|
||||
secondary_gpu_state->gbm.current_fb_id = 0;
|
||||
}
|
||||
if (secondary_gpu_state->gbm.current_bo)
|
||||
{
|
||||
gbm_surface_release_buffer (secondary_gpu_state->gbm.surface,
|
||||
secondary_gpu_state->gbm.current_bo);
|
||||
secondary_gpu_state->gbm.current_bo = NULL;
|
||||
}
|
||||
g_clear_object (&secondary_gpu_state->gbm.current_fb);
|
||||
break;
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_CPU:
|
||||
break;
|
||||
@@ -1001,22 +987,8 @@ free_current_bo (CoglOnscreen *onscreen)
|
||||
{
|
||||
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
|
||||
int kms_fd;
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (render_gpu);
|
||||
|
||||
if (onscreen_native->gbm.current_fb_id)
|
||||
{
|
||||
drmModeRmFB (kms_fd, onscreen_native->gbm.current_fb_id);
|
||||
onscreen_native->gbm.current_fb_id = 0;
|
||||
}
|
||||
if (onscreen_native->gbm.current_bo)
|
||||
{
|
||||
gbm_surface_release_buffer (onscreen_native->gbm.surface,
|
||||
onscreen_native->gbm.current_bo);
|
||||
onscreen_native->gbm.current_bo = NULL;
|
||||
}
|
||||
g_clear_object (&onscreen_native->gbm.current_fb);
|
||||
|
||||
g_hash_table_foreach (onscreen_native->secondary_gpu_states,
|
||||
(GHFunc) free_current_secondary_bo,
|
||||
@@ -1310,11 +1282,9 @@ static void
|
||||
swap_secondary_drm_fb (MetaGpuKms *gpu_kms,
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
|
||||
{
|
||||
secondary_gpu_state->gbm.current_fb_id = secondary_gpu_state->gbm.next_fb_id;
|
||||
secondary_gpu_state->gbm.next_fb_id = 0;
|
||||
|
||||
secondary_gpu_state->gbm.current_bo = secondary_gpu_state->gbm.next_bo;
|
||||
secondary_gpu_state->gbm.next_bo = NULL;
|
||||
g_set_object (&secondary_gpu_state->gbm.current_fb,
|
||||
secondary_gpu_state->gbm.next_fb);
|
||||
g_clear_object (&secondary_gpu_state->gbm.next_fb);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1325,11 +1295,8 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
|
||||
|
||||
free_current_bo (onscreen);
|
||||
|
||||
onscreen_native->gbm.current_fb_id = onscreen_native->gbm.next_fb_id;
|
||||
onscreen_native->gbm.next_fb_id = 0;
|
||||
|
||||
onscreen_native->gbm.current_bo = onscreen_native->gbm.next_bo;
|
||||
onscreen_native->gbm.next_bo = NULL;
|
||||
g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb);
|
||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
||||
|
||||
g_hash_table_foreach (onscreen_native->secondary_gpu_states,
|
||||
(GHFunc) swap_secondary_drm_fb,
|
||||
@@ -1413,17 +1380,7 @@ free_next_secondary_bo (MetaGpuKms *gpu_kms,
|
||||
switch (renderer_gpu_data->secondary.copy_mode)
|
||||
{
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_GPU:
|
||||
if (secondary_gpu_state->gbm.next_fb_id)
|
||||
{
|
||||
int kms_fd;
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
||||
drmModeRmFB (kms_fd, secondary_gpu_state->gbm.next_fb_id);
|
||||
gbm_surface_release_buffer (secondary_gpu_state->gbm.surface,
|
||||
secondary_gpu_state->gbm.next_bo);
|
||||
secondary_gpu_state->gbm.next_fb_id = 0;
|
||||
secondary_gpu_state->gbm.next_bo = NULL;
|
||||
}
|
||||
g_clear_object (&secondary_gpu_state->gbm.next_fb);
|
||||
break;
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_CPU:
|
||||
break;
|
||||
@@ -1448,17 +1405,7 @@ flip_closure_destroyed (MetaRendererView *view)
|
||||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
if (onscreen_native->gbm.next_fb_id)
|
||||
{
|
||||
int kms_fd;
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (render_gpu);
|
||||
drmModeRmFB (kms_fd, onscreen_native->gbm.next_fb_id);
|
||||
gbm_surface_release_buffer (onscreen_native->gbm.surface,
|
||||
onscreen_native->gbm.next_bo);
|
||||
onscreen_native->gbm.next_bo = NULL;
|
||||
onscreen_native->gbm.next_fb_id = 0;
|
||||
}
|
||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
||||
|
||||
g_hash_table_foreach (onscreen_native->secondary_gpu_states,
|
||||
(GHFunc) free_next_secondary_bo,
|
||||
@@ -1808,12 +1755,12 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
if (gpu_kms == render_gpu)
|
||||
{
|
||||
fb_id = onscreen_native->gbm.next_fb_id;
|
||||
fb_id = meta_drm_buffer_get_fb_id (onscreen_native->gbm.next_fb);
|
||||
}
|
||||
else
|
||||
{
|
||||
secondary_gpu_state = get_secondary_gpu_state (onscreen, gpu_kms);
|
||||
fb_id = secondary_gpu_state->gbm.next_fb_id;
|
||||
fb_id = meta_drm_buffer_get_fb_id (secondary_gpu_state->gbm.next_fb);
|
||||
}
|
||||
|
||||
if (!meta_gpu_kms_flip_crtc (gpu_kms,
|
||||
@@ -1879,7 +1826,7 @@ set_crtc_fb (CoglOnscreen *onscreen,
|
||||
if (!secondary_gpu_state)
|
||||
return;
|
||||
|
||||
fb_id = secondary_gpu_state->gbm.next_fb_id;
|
||||
fb_id = meta_drm_buffer_get_fb_id (secondary_gpu_state->gbm.next_fb);
|
||||
}
|
||||
|
||||
x = crtc->rect.x - logical_monitor->rect.x;
|
||||
@@ -1922,7 +1869,7 @@ meta_onscreen_native_set_crtc_modes (CoglOnscreen *onscreen)
|
||||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
fb_id = onscreen_native->gbm.next_fb_id;
|
||||
fb_id = meta_drm_buffer_get_fb_id (onscreen_native->gbm.next_fb);
|
||||
break;
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
|
||||
@@ -1990,7 +1937,7 @@ crtc_mode_set_fallback (CoglOnscreen *onscreen,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fb_id = onscreen_native->gbm.next_fb_id;
|
||||
fb_id = meta_drm_buffer_get_fb_id (onscreen_native->gbm.next_fb);
|
||||
set_crtc_fb (onscreen, logical_monitor, crtc, fb_id);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2090,101 +2037,6 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
|
||||
g_closure_unref (flip_closure);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gbm_get_next_fb_id (MetaGpuKms *gpu_kms,
|
||||
struct gbm_surface *gbm_surface,
|
||||
struct gbm_bo **out_next_bo,
|
||||
uint32_t *out_next_fb_id)
|
||||
{
|
||||
MetaRendererNative *renderer_native = meta_renderer_native_from_gpu (gpu_kms);
|
||||
struct gbm_bo *next_bo;
|
||||
uint32_t next_fb_id;
|
||||
int kms_fd;
|
||||
uint32_t handles[4] = { 0, };
|
||||
uint32_t strides[4] = { 0, };
|
||||
uint32_t offsets[4] = { 0, };
|
||||
uint64_t modifiers[4] = { 0, };
|
||||
int i;
|
||||
|
||||
/* Now we need to set the CRTC to whatever is the front buffer */
|
||||
next_bo = gbm_surface_lock_front_buffer (gbm_surface);
|
||||
|
||||
if (!next_bo)
|
||||
{
|
||||
g_error ("Impossible to lock surface front buffer: %m");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gbm_bo_get_handle_for_plane (next_bo, 0).s32 == -1)
|
||||
{
|
||||
/* Failed to fetch handle to plane, falling back to old method */
|
||||
strides[0] = gbm_bo_get_stride (next_bo);
|
||||
handles[0] = gbm_bo_get_handle (next_bo).u32;
|
||||
offsets[0] = 0;
|
||||
modifiers[0] = DRM_FORMAT_MOD_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < gbm_bo_get_plane_count (next_bo); i++)
|
||||
{
|
||||
strides[i] = gbm_bo_get_stride_for_plane (next_bo, i);
|
||||
handles[i] = gbm_bo_get_handle_for_plane (next_bo, i).u32;
|
||||
offsets[i] = gbm_bo_get_offset (next_bo, i);
|
||||
modifiers[i] = gbm_bo_get_modifier (next_bo);
|
||||
}
|
||||
}
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
||||
|
||||
if (renderer_native->use_modifiers &&
|
||||
modifiers[0] != DRM_FORMAT_MOD_INVALID)
|
||||
{
|
||||
if (drmModeAddFB2WithModifiers (kms_fd,
|
||||
gbm_bo_get_width (next_bo),
|
||||
gbm_bo_get_height (next_bo),
|
||||
gbm_bo_get_format (next_bo),
|
||||
handles,
|
||||
strides,
|
||||
offsets,
|
||||
modifiers,
|
||||
&next_fb_id,
|
||||
DRM_MODE_FB_MODIFIERS))
|
||||
{
|
||||
g_warning ("Failed to create new back buffer handle: %m");
|
||||
gbm_surface_release_buffer (gbm_surface, next_bo);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (drmModeAddFB2 (kms_fd,
|
||||
gbm_bo_get_width (next_bo),
|
||||
gbm_bo_get_height (next_bo),
|
||||
gbm_bo_get_format (next_bo),
|
||||
handles,
|
||||
strides,
|
||||
offsets,
|
||||
&next_fb_id,
|
||||
0))
|
||||
{
|
||||
if (drmModeAddFB (kms_fd,
|
||||
gbm_bo_get_width (next_bo),
|
||||
gbm_bo_get_height (next_bo),
|
||||
24, /* depth */
|
||||
32, /* bpp */
|
||||
strides[0],
|
||||
handles[0],
|
||||
&next_fb_id))
|
||||
{
|
||||
g_warning ("Failed to create new back buffer handle: %m");
|
||||
gbm_surface_release_buffer (gbm_surface, next_bo);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*out_next_bo = next_bo;
|
||||
*out_next_fb_id = next_fb_id;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
wait_for_pending_flips (CoglOnscreen *onscreen)
|
||||
{
|
||||
@@ -2217,6 +2069,8 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
||||
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
|
||||
GError *error = NULL;
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
struct gbm_bo *bo;
|
||||
|
||||
if (!meta_egl_make_current (egl,
|
||||
renderer_gpu_data->egl_display,
|
||||
@@ -2232,12 +2086,14 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
|
||||
*egl_context_changed = TRUE;
|
||||
|
||||
buffer_gbm = META_DRM_BUFFER_GBM (onscreen_native->gbm.next_fb);
|
||||
bo = meta_drm_buffer_gbm_get_bo (buffer_gbm);
|
||||
if (!meta_renderer_native_gles3_blit_shared_bo (egl,
|
||||
renderer_native->gles3,
|
||||
renderer_gpu_data->egl_display,
|
||||
renderer_gpu_data->secondary.egl_context,
|
||||
secondary_gpu_state->egl_surface,
|
||||
onscreen_native->gbm.next_bo,
|
||||
bo,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Failed to blit shared framebuffer: %s", error->message);
|
||||
@@ -2255,10 +2111,31 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
return;
|
||||
}
|
||||
|
||||
gbm_get_next_fb_id (secondary_gpu_state->gpu_kms,
|
||||
secondary_gpu_state->gbm.surface,
|
||||
&secondary_gpu_state->gbm.next_bo,
|
||||
&secondary_gpu_state->gbm.next_fb_id);
|
||||
g_clear_object (&secondary_gpu_state->gbm.next_fb);
|
||||
buffer_gbm = meta_drm_buffer_gbm_new (secondary_gpu_state->gpu_kms,
|
||||
secondary_gpu_state->gbm.surface,
|
||||
renderer_native->use_modifiers,
|
||||
&error);
|
||||
secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_gbm);
|
||||
if (!secondary_gpu_state->gbm.next_fb)
|
||||
{
|
||||
g_warning ("meta_drm_buffer_gbm_new failed: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static MetaDumbBuffer *
|
||||
secondary_gpu_get_next_dumb_buffer (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
|
||||
{
|
||||
MetaDumbBuffer *current_dumb_fb;
|
||||
|
||||
current_dumb_fb = secondary_gpu_state->cpu.dumb_fb;
|
||||
if (current_dumb_fb == &secondary_gpu_state->cpu.dumb_fbs[0])
|
||||
return &secondary_gpu_state->cpu.dumb_fbs[1];
|
||||
else
|
||||
return &secondary_gpu_state->cpu.dumb_fbs[0];
|
||||
}
|
||||
|
||||
typedef struct _PixelFormatMap {
|
||||
@@ -2327,46 +2204,28 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
|
||||
{
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
CoglContext *cogl_context = framebuffer->context;
|
||||
int width, height;
|
||||
uint8_t *target_data;
|
||||
int target_stride_bytes;
|
||||
uint32_t target_fb_id;
|
||||
uint32_t target_drm_format;
|
||||
MetaDumbBuffer *next_dumb_fb;
|
||||
MetaDumbBuffer *current_dumb_fb;
|
||||
MetaDumbBuffer *dumb_fb;
|
||||
CoglBitmap *dumb_bitmap;
|
||||
CoglPixelFormat cogl_format;
|
||||
gboolean ret;
|
||||
MetaDrmBufferDumb *buffer_dumb;
|
||||
|
||||
width = cogl_framebuffer_get_width (framebuffer);
|
||||
height = cogl_framebuffer_get_height (framebuffer);
|
||||
dumb_fb = secondary_gpu_get_next_dumb_buffer (secondary_gpu_state);
|
||||
|
||||
current_dumb_fb = secondary_gpu_state->cpu.dumb_fb;
|
||||
if (current_dumb_fb == &secondary_gpu_state->cpu.dumb_fbs[0])
|
||||
next_dumb_fb = &secondary_gpu_state->cpu.dumb_fbs[1];
|
||||
else
|
||||
next_dumb_fb = &secondary_gpu_state->cpu.dumb_fbs[0];
|
||||
secondary_gpu_state->cpu.dumb_fb = next_dumb_fb;
|
||||
g_assert (cogl_framebuffer_get_width (framebuffer) == dumb_fb->width);
|
||||
g_assert (cogl_framebuffer_get_height (framebuffer) == dumb_fb->height);
|
||||
|
||||
g_assert (width == secondary_gpu_state->cpu.dumb_fb->width);
|
||||
g_assert (height == secondary_gpu_state->cpu.dumb_fb->height);
|
||||
|
||||
target_data = secondary_gpu_state->cpu.dumb_fb->map;
|
||||
target_stride_bytes = secondary_gpu_state->cpu.dumb_fb->stride_bytes;
|
||||
target_fb_id = secondary_gpu_state->cpu.dumb_fb->fb_id;
|
||||
target_drm_format = secondary_gpu_state->cpu.dumb_fb->drm_format;
|
||||
|
||||
ret = cogl_pixel_format_from_drm_format (target_drm_format,
|
||||
ret = cogl_pixel_format_from_drm_format (dumb_fb->drm_format,
|
||||
&cogl_format,
|
||||
NULL);
|
||||
g_assert (ret);
|
||||
|
||||
dumb_bitmap = cogl_bitmap_new_for_data (cogl_context,
|
||||
width,
|
||||
height,
|
||||
dumb_fb->width,
|
||||
dumb_fb->height,
|
||||
cogl_format,
|
||||
target_stride_bytes,
|
||||
target_data);
|
||||
dumb_fb->stride_bytes,
|
||||
dumb_fb->map);
|
||||
|
||||
if (!cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
|
||||
0 /* x */,
|
||||
@@ -2377,7 +2236,10 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
|
||||
|
||||
cogl_object_unref (dumb_bitmap);
|
||||
|
||||
secondary_gpu_state->gbm.next_fb_id = target_fb_id;
|
||||
g_clear_object (&secondary_gpu_state->gbm.next_fb);
|
||||
buffer_dumb = meta_drm_buffer_dumb_new (dumb_fb->fb_id);
|
||||
secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_dumb);
|
||||
secondary_gpu_state->cpu.dumb_fb = dumb_fb;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2464,6 +2326,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
CoglFrameInfo *frame_info;
|
||||
gboolean egl_context_changed = FALSE;
|
||||
MetaPowerSave power_save_mode;
|
||||
g_autoptr (GError) error = NULL;
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
|
||||
/*
|
||||
* Wait for the flip callback before continuing, as we might have started the
|
||||
@@ -2485,14 +2349,20 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
g_warn_if_fail (onscreen_native->gbm.next_bo == NULL &&
|
||||
onscreen_native->gbm.next_fb_id == 0);
|
||||
g_warn_if_fail (onscreen_native->gbm.next_fb == NULL);
|
||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
||||
|
||||
if (!gbm_get_next_fb_id (render_gpu,
|
||||
onscreen_native->gbm.surface,
|
||||
&onscreen_native->gbm.next_bo,
|
||||
&onscreen_native->gbm.next_fb_id))
|
||||
return;
|
||||
buffer_gbm = meta_drm_buffer_gbm_new (render_gpu,
|
||||
onscreen_native->gbm.surface,
|
||||
renderer_native->use_modifiers,
|
||||
&error);
|
||||
onscreen_native->gbm.next_fb = META_DRM_BUFFER (buffer_gbm);
|
||||
if (!onscreen_native->gbm.next_fb)
|
||||
{
|
||||
g_warning ("meta_drm_buffer_gbm_new failed: %s",
|
||||
error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
@@ -3083,7 +2953,7 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
/* flip state takes a reference on the onscreen so there should
|
||||
* never be outstanding flips when we reach here. */
|
||||
g_return_if_fail (onscreen_native->gbm.next_fb_id == 0);
|
||||
g_return_if_fail (onscreen_native->gbm.next_fb == NULL);
|
||||
|
||||
free_current_bo (onscreen);
|
||||
|
||||
|
@@ -357,7 +357,6 @@ handle_host_xevent (MetaBackend *backend,
|
||||
{
|
||||
switch (xkb_ev->any.xkb_type)
|
||||
{
|
||||
case XkbNewKeyboardNotify:
|
||||
case XkbMapNotify:
|
||||
keymap_changed (backend);
|
||||
break;
|
||||
|
@@ -203,7 +203,7 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
|
||||
height = logical_monitor->rect.height;
|
||||
}
|
||||
width = roundf (width * view_scale);
|
||||
height = roundf (width * view_scale);
|
||||
height = roundf (height * view_scale);
|
||||
|
||||
fake_onscreen = create_offscreen (cogl_context, width, height);
|
||||
|
||||
|
@@ -71,4 +71,6 @@ MetaCloseDialog * meta_compositor_create_close_dialog (MetaCompositor *composito
|
||||
MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_compositor_locate_pointer (MetaCompositor *compositor);
|
||||
|
||||
#endif /* META_COMPOSITOR_PRIVATE_H */
|
||||
|
@@ -431,13 +431,11 @@ meta_end_modal_for_plugin (MetaCompositor *compositor,
|
||||
{
|
||||
MetaDisplay *display = compositor->display;
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaWindow *grab_window = display->grab_window;
|
||||
MetaGrabOp grab_op = display->grab_op;
|
||||
|
||||
g_return_if_fail (is_modal (display));
|
||||
|
||||
g_signal_emit_by_name (display, "grab-op-end",
|
||||
meta_plugin_get_display (plugin),
|
||||
display->grab_window, display->grab_op);
|
||||
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->event_route = META_EVENT_ROUTE_NORMAL;
|
||||
display->grab_window = NULL;
|
||||
@@ -454,6 +452,10 @@ meta_end_modal_for_plugin (MetaCompositor *compositor,
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_signal_emit_by_name (display, "grab-op-end",
|
||||
meta_plugin_get_display (plugin),
|
||||
grab_window, grab_op);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -692,11 +694,8 @@ meta_compositor_add_window (MetaCompositor *compositor,
|
||||
{
|
||||
MetaWindowActor *window_actor;
|
||||
ClutterActor *window_group;
|
||||
MetaDisplay *display = compositor->display;
|
||||
GType window_actor_type = G_TYPE_INVALID;
|
||||
|
||||
meta_x11_error_trap_push (display->x11_display);
|
||||
|
||||
switch (window->client_type)
|
||||
{
|
||||
case META_WINDOW_CLIENT_TYPE_X11:
|
||||
@@ -724,8 +723,6 @@ meta_compositor_add_window (MetaCompositor *compositor,
|
||||
*/
|
||||
compositor->windows = g_list_append (compositor->windows, window_actor);
|
||||
sync_actor_stacking (compositor);
|
||||
|
||||
meta_x11_error_trap_pop (display->x11_display);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1556,3 +1553,9 @@ meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor,
|
||||
return meta_plugin_manager_create_inhibit_shortcuts_dialog (compositor->plugin_mgr,
|
||||
window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_locate_pointer (MetaCompositor *compositor)
|
||||
{
|
||||
meta_plugin_manager_locate_pointer (compositor->plugin_mgr);
|
||||
}
|
||||
|
@@ -405,3 +405,13 @@ meta_plugin_manager_create_inhibit_shortcuts_dialog (MetaPluginManager *plugin_m
|
||||
|
||||
return meta_inhibit_shortcuts_dialog_default_new (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_manager_locate_pointer (MetaPluginManager *plugin_mgr)
|
||||
{
|
||||
MetaPlugin *plugin = plugin_mgr->plugin;
|
||||
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (klass->locate_pointer)
|
||||
klass->locate_pointer (plugin);
|
||||
}
|
||||
|
@@ -100,4 +100,6 @@ MetaInhibitShortcutsDialog *
|
||||
meta_plugin_manager_create_inhibit_shortcuts_dialog (MetaPluginManager *plugin_mgr,
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_plugin_manager_locate_pointer (MetaPluginManager *mgr);
|
||||
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user