Compare commits
17 Commits
wip/kms-co
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8aeec308fb | ||
![]() |
252fd771b1 | ||
![]() |
41bff1e997 | ||
![]() |
323742e736 | ||
![]() |
14f41f3130 | ||
![]() |
21b4cf8a50 | ||
![]() |
a4f47820c3 | ||
![]() |
471eca3745 | ||
![]() |
c1f39514ca | ||
![]() |
038720fecc | ||
![]() |
d367d97364 | ||
![]() |
885f89a217 | ||
![]() |
21411faeb1 | ||
![]() |
cf4a9b3f6a | ||
![]() |
1226c599c9 | ||
![]() |
c9459fa096 | ||
![]() |
d31fb640d5 |
@@ -72,7 +72,7 @@ can-build-gnome-shell:
|
||||
- meson install --no-rebuild -C build
|
||||
script:
|
||||
- .gitlab-ci/checkout-gnome-shell.sh
|
||||
- meson gnome-shell gnome-shell/build --prefix /usr -Dman=false
|
||||
- meson gnome-shell gnome-shell/build --prefix /usr
|
||||
- ninja -C gnome-shell/build install
|
||||
only:
|
||||
- merge_requests
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# Rebuild and push with
|
||||
#
|
||||
# cd .gitlab-ci/
|
||||
# docker build --no-cache -t registry.gitlab.gnome.org/gnome/mutter/master:v2 .
|
||||
# docker build -t registry.gitlab.gnome.org/gnome/mutter/master:v2 .
|
||||
# docker push registry.gitlab.gnome.org/gnome/mutter/master:v2
|
||||
#
|
||||
|
||||
@@ -13,7 +13,6 @@ RUN dnf -y update && dnf -y upgrade && \
|
||||
dnf copr enable -y fmuellner/gnome-shell-ci && \
|
||||
dnf copr enable -y jadahl/mutter-ci && \
|
||||
dnf copr enable -y hergertme/sysprof-3 && \
|
||||
dnf -y update && dnf -y upgrade && \
|
||||
|
||||
dnf builddep -y mutter && \
|
||||
|
||||
@@ -32,8 +31,6 @@ RUN dnf -y update && dnf -y upgrade && \
|
||||
|
||||
# GNOME Shell
|
||||
dnf builddep -y gnome-shell --setopt=install_weak_deps=False && \
|
||||
# New dep this cycle
|
||||
dnf install -y 'pkgconfig(gnome-autoar-0)' && \
|
||||
dnf remove -y gnome-bluetooth-libs-devel dbus-glib-devel upower-devel python3-devel && \
|
||||
dnf remove -y --noautoremove mutter mutter-devel && \
|
||||
|
||||
|
39
NEWS
39
NEWS
@@ -1,42 +1,3 @@
|
||||
3.33.91
|
||||
=======
|
||||
* Fix primary selection copy and paste between X11 and wayland [Hans; #702]
|
||||
* Improve monitor hotplug support [Hans; !713]
|
||||
* Remove a source of frame skips [Daniel; !719]
|
||||
* Fix windows being lowered after unmaximizing with double click [Olivier; #88]
|
||||
* Remove Clutter API for global grabs [Jonas D.; !536]
|
||||
* Improve processing of incompressible events [Daniel; !711]
|
||||
* Add xdg-output v3 support [Olivier; !704]
|
||||
* Misc. bug fixes and cleanups [Jonas Å., Marco, Carlos, Adam, Albert, Niels,
|
||||
Olivier, Florian; !722, !385, !728, !726, !500, !731, !727, !700, !735, !738]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Albert Vaca Cintora, Jonas Dreßler, Olivier Fourdan,
|
||||
Carlos Garnacho, Hans de Goede, Niels De Graef, Adam Jackson, Florian Müllner,
|
||||
Marco Trevisan (Treviño), Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Asier Sarasua Garmendia [eu], Kukuh Syafaat [id], Florentina Mușat [ro],
|
||||
Aurimas Černius [lt], Daniel Mustieles [es]
|
||||
|
||||
3.33.90
|
||||
=======
|
||||
* Fix visibility of clones with hidden source [Florian; #683]
|
||||
* Reduce freezes when opening some popup windows [Carlos; #556]
|
||||
* Be more thorough when excluding obscured areas from painting [Carlos; !698]
|
||||
* Make it possible to start Xwayland on demand [Carlos; !709]
|
||||
* clutter: Expose layout_manager to transitions [Florian; !716]
|
||||
* Misc. bug fixes and cleanups [Mark, Florian, Iain, Niels, Carlos, Ray; !671,
|
||||
!691, !694, !696, !703, !707, !697, !710, !708, !714, #719, !721]
|
||||
|
||||
Contributors:
|
||||
Mark Blakeney, Carlos Garnacho, Niels De Graef, Iain Lane, Florian Müllner,
|
||||
Ray Strode
|
||||
|
||||
Translators:
|
||||
Asier Sarasua Garmendia [eu], Rafael Fontenelle [pt_BR], Fabio Tomat [fur],
|
||||
Florentina Mușat [ro]
|
||||
|
||||
3.33.4
|
||||
======
|
||||
* Discard page flip retries on hotplug [Jonas; !630]
|
||||
|
@@ -737,7 +737,11 @@ cally_actor_grab_focus (AtkComponent *component)
|
||||
*
|
||||
* This gets the top level origin, it is, the position of the stage in
|
||||
* the global screen. You can see it as the absolute display position
|
||||
* of the stage. This is 0,0 for a compositor.
|
||||
* of the stage.
|
||||
*
|
||||
* FIXME: only the case with x11 is implemented, other backends are
|
||||
* required
|
||||
*
|
||||
*/
|
||||
void
|
||||
_cally_actor_get_top_level_origin (ClutterActor *actor,
|
||||
@@ -745,11 +749,54 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
|
||||
gint *yp)
|
||||
{
|
||||
/* default values */
|
||||
gint x = 0;
|
||||
gint y = 0;
|
||||
|
||||
#ifdef CLUTTER_WINDOWING_X11
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
||||
{
|
||||
ClutterActor *stage = NULL;
|
||||
Display *display = NULL;
|
||||
Window root_window;
|
||||
Window stage_window;
|
||||
Window child;
|
||||
gint return_val = 0;
|
||||
|
||||
stage = clutter_actor_get_stage (actor);
|
||||
|
||||
/* FIXME: what happens if you use another display with
|
||||
clutter_backend_x11_set_display ?*/
|
||||
display = clutter_x11_get_default_display ();
|
||||
root_window = clutter_x11_get_root_window ();
|
||||
stage_window = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
|
||||
return_val = XTranslateCoordinates (display, stage_window, root_window,
|
||||
0, 0, &x, &y,
|
||||
&child);
|
||||
|
||||
if (!return_val)
|
||||
g_warning ("[x11] We were not able to get proper absolute "
|
||||
"position of the stage");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
static gboolean yet_warned = FALSE;
|
||||
|
||||
if (!yet_warned)
|
||||
{
|
||||
yet_warned = TRUE;
|
||||
|
||||
g_warning ("The current Clutter backend does not support using "
|
||||
"atk_component_get_extents() with ATK_XY_SCREEN.");
|
||||
}
|
||||
}
|
||||
|
||||
if (xp)
|
||||
*xp = 0;
|
||||
*xp = x;
|
||||
|
||||
if (yp)
|
||||
*yp = 0;
|
||||
*yp = y;
|
||||
}
|
||||
|
||||
/* AtkAction implementation */
|
||||
|
@@ -297,6 +297,8 @@ const gchar * _clutter_actor_get_debug_name
|
||||
void _clutter_actor_push_clone_paint (void);
|
||||
void _clutter_actor_pop_clone_paint (void);
|
||||
|
||||
guint32 _clutter_actor_get_pick_id (ClutterActor *self);
|
||||
|
||||
void _clutter_actor_shader_pre_paint (ClutterActor *actor,
|
||||
gboolean repeat);
|
||||
void _clutter_actor_shader_post_paint (ClutterActor *actor);
|
||||
|
@@ -433,7 +433,7 @@
|
||||
*
|
||||
* #ClutterActor allows accessing properties of #ClutterAction,
|
||||
* #ClutterEffect, and #ClutterConstraint instances associated to an actor
|
||||
* instance for animation purposes, as well as its #ClutterLayoutManager.
|
||||
* instance for animation purposes.
|
||||
*
|
||||
* In order to access a specific #ClutterAction or a #ClutterConstraint
|
||||
* property it is necessary to set the #ClutterActorMeta:name property on the
|
||||
@@ -457,13 +457,6 @@
|
||||
* on the `origin` actor, and in its initial state is overlapping the actor
|
||||
* to which is bound to.
|
||||
*
|
||||
* As the actor has only one #ClutterLayoutManager, the syntax for accessing its
|
||||
* properties is simpler:
|
||||
*
|
||||
* |[
|
||||
* @layout.<property-name>
|
||||
* ]|
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* constraint = clutter_bind_constraint_new (origin, CLUTTER_BIND_X, 0.0);
|
||||
* clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "bind-x");
|
||||
@@ -736,6 +729,8 @@ struct _ClutterActorPrivate
|
||||
|
||||
gchar *name; /* a non-unique name, used for debugging */
|
||||
|
||||
gint32 pick_id; /* per-stage unique id, used for picking */
|
||||
|
||||
/* a back-pointer to the Pango context that we can use
|
||||
* to create pre-configured PangoLayout
|
||||
*/
|
||||
@@ -1288,105 +1283,6 @@ clutter_actor_verify_map_state (ClutterActor *self)
|
||||
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
static gboolean
|
||||
_clutter_actor_transform_local_box_to_stage (ClutterActor *self,
|
||||
ClutterStage *stage,
|
||||
const ClutterActorBox *box,
|
||||
ClutterPoint vertices[4])
|
||||
{
|
||||
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
|
||||
CoglMatrix stage_transform, inv_stage_transform;
|
||||
CoglMatrix modelview, transform_to_stage;
|
||||
int v;
|
||||
|
||||
clutter_actor_get_transform (CLUTTER_ACTOR (stage), &stage_transform);
|
||||
if (!cogl_matrix_get_inverse (&stage_transform, &inv_stage_transform))
|
||||
return FALSE;
|
||||
cogl_framebuffer_get_modelview_matrix (fb, &modelview);
|
||||
cogl_matrix_multiply (&transform_to_stage, &inv_stage_transform, &modelview);
|
||||
|
||||
vertices[0].x = box->x1;
|
||||
vertices[0].y = box->y1;
|
||||
|
||||
vertices[1].x = box->x2;
|
||||
vertices[1].y = box->y1;
|
||||
|
||||
vertices[2].x = box->x2;
|
||||
vertices[2].y = box->y2;
|
||||
|
||||
vertices[3].x = box->x1;
|
||||
vertices[3].y = box->y2;
|
||||
|
||||
for (v = 0; v < 4; v++)
|
||||
{
|
||||
float z = 0.f;
|
||||
float w = 1.f;
|
||||
|
||||
cogl_matrix_transform_point (&transform_to_stage,
|
||||
&vertices[v].x,
|
||||
&vertices[v].y,
|
||||
&z,
|
||||
&w);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_pick_box:
|
||||
* @self: The #ClutterActor being "pick" painted.
|
||||
* @box: A rectangle in the actor's own local coordinates.
|
||||
*
|
||||
* Logs (does a virtual paint of) a rectangle for picking. Note that @box is
|
||||
* in the actor's own local coordinates, so is usually {0,0,width,height}
|
||||
* to include the whole actor. That is unless the actor has a shaped input
|
||||
* region in which case you may wish to log the (multiple) smaller rectangles
|
||||
* that make up the input region.
|
||||
*/
|
||||
void
|
||||
clutter_actor_pick_box (ClutterActor *self,
|
||||
const ClutterActorBox *box)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
ClutterPoint vertices[4];
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
g_return_if_fail (box != NULL);
|
||||
|
||||
if (box->x1 >= box->x2 || box->y1 >= box->y2)
|
||||
return;
|
||||
|
||||
stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self));
|
||||
|
||||
if (_clutter_actor_transform_local_box_to_stage (self, stage, box, vertices))
|
||||
clutter_stage_log_pick (stage, vertices, self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_clutter_actor_push_pick_clip (ClutterActor *self,
|
||||
const ClutterActorBox *clip)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
ClutterPoint vertices[4];
|
||||
|
||||
stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self));
|
||||
|
||||
if (!_clutter_actor_transform_local_box_to_stage (self, stage, clip, vertices))
|
||||
return FALSE;
|
||||
|
||||
clutter_stage_push_pick_clip (stage, vertices);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_actor_pop_pick_clip (ClutterActor *self)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = _clutter_actor_get_stage_internal (self);
|
||||
clutter_stage_pop_pick_clip (CLUTTER_STAGE (stage));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_set_mapped (ClutterActor *self,
|
||||
gboolean mapped)
|
||||
@@ -1615,7 +1511,8 @@ clutter_actor_update_map_state (ClutterActor *self,
|
||||
static void
|
||||
clutter_actor_real_map (ClutterActor *self)
|
||||
{
|
||||
ClutterActor *iter;
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
ClutterActor *stage, *iter;
|
||||
|
||||
g_assert (!CLUTTER_ACTOR_IS_MAPPED (self));
|
||||
|
||||
@@ -1626,6 +1523,13 @@ clutter_actor_real_map (ClutterActor *self)
|
||||
|
||||
self->priv->needs_paint_volume_update = TRUE;
|
||||
|
||||
stage = _clutter_actor_get_stage_internal (self);
|
||||
priv->pick_id = _clutter_stage_acquire_pick_id (CLUTTER_STAGE (stage), self);
|
||||
|
||||
CLUTTER_NOTE (ACTOR, "Pick id '%d' for actor '%s'",
|
||||
priv->pick_id,
|
||||
_clutter_actor_get_debug_name (self));
|
||||
|
||||
clutter_actor_ensure_resource_scale (self);
|
||||
|
||||
/* notify on parent mapped before potentially mapping
|
||||
@@ -1730,6 +1634,11 @@ clutter_actor_real_unmap (ClutterActor *self)
|
||||
|
||||
stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self));
|
||||
|
||||
if (stage != NULL)
|
||||
_clutter_stage_release_pick_id (stage, priv->pick_id);
|
||||
|
||||
priv->pick_id = -1;
|
||||
|
||||
if (stage != NULL &&
|
||||
clutter_stage_get_key_focus (stage) == self)
|
||||
{
|
||||
@@ -2348,16 +2257,46 @@ static void
|
||||
clutter_actor_real_pick (ClutterActor *self,
|
||||
const ClutterColor *color)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
|
||||
|
||||
/* the default implementation is just to paint a rectangle
|
||||
* with the same size of the actor using the passed color
|
||||
*/
|
||||
if (clutter_actor_should_pick_paint (self))
|
||||
{
|
||||
ClutterActorBox box = {
|
||||
.x1 = 0,
|
||||
.y1 = 0,
|
||||
.x2 = clutter_actor_get_width (self),
|
||||
.y2 = clutter_actor_get_height (self),
|
||||
};
|
||||
static CoglPipeline *default_pick_pipeline = NULL;
|
||||
ClutterActorBox box = { 0, };
|
||||
CoglPipeline *pick_pipeline;
|
||||
float width, height;
|
||||
|
||||
clutter_actor_pick_box (self, &box);
|
||||
if (G_UNLIKELY (default_pick_pipeline == NULL))
|
||||
{
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
|
||||
default_pick_pipeline = cogl_pipeline_new (ctx);
|
||||
}
|
||||
|
||||
g_assert (default_pick_pipeline != NULL);
|
||||
pick_pipeline = cogl_pipeline_copy (default_pick_pipeline);
|
||||
|
||||
clutter_actor_get_allocation_box (self, &box);
|
||||
|
||||
width = box.x2 - box.x1;
|
||||
height = box.y2 - box.y1;
|
||||
|
||||
cogl_pipeline_set_color4ub (pick_pipeline,
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
color->alpha);
|
||||
|
||||
cogl_framebuffer_draw_rectangle (framebuffer,
|
||||
pick_pipeline,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
cogl_object_unref (pick_pipeline);
|
||||
}
|
||||
|
||||
/* XXX - this thoroughly sucks, but we need to maintain compatibility
|
||||
@@ -3648,6 +3587,15 @@ _clutter_actor_update_last_paint_volume (ClutterActor *self)
|
||||
priv->last_paint_volume_valid = TRUE;
|
||||
}
|
||||
|
||||
guint32
|
||||
_clutter_actor_get_pick_id (ClutterActor *self)
|
||||
{
|
||||
if (self->priv->pick_id < 0)
|
||||
return 0;
|
||||
|
||||
return self->priv->pick_id;
|
||||
}
|
||||
|
||||
/* This is the same as clutter_actor_add_effect except that it doesn't
|
||||
queue a redraw and it doesn't notify on the effect property */
|
||||
static void
|
||||
@@ -3879,7 +3827,6 @@ clutter_actor_paint (ClutterActor *self)
|
||||
{
|
||||
ClutterActorPrivate *priv;
|
||||
ClutterPickMode pick_mode;
|
||||
ClutterActorBox clip;
|
||||
gboolean clip_set = FALSE;
|
||||
ClutterStage *stage;
|
||||
|
||||
@@ -3973,40 +3920,26 @@ clutter_actor_paint (ClutterActor *self)
|
||||
|
||||
if (priv->has_clip)
|
||||
{
|
||||
clip.x1 = priv->clip.origin.x;
|
||||
clip.y1 = priv->clip.origin.y;
|
||||
clip.x2 = priv->clip.origin.x + priv->clip.size.width;
|
||||
clip.y2 = priv->clip.origin.y + priv->clip.size.height;
|
||||
CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);
|
||||
cogl_framebuffer_push_rectangle_clip (fb,
|
||||
priv->clip.origin.x,
|
||||
priv->clip.origin.y,
|
||||
priv->clip.origin.x + priv->clip.size.width,
|
||||
priv->clip.origin.y + priv->clip.size.height);
|
||||
clip_set = TRUE;
|
||||
}
|
||||
else if (priv->clip_to_allocation)
|
||||
{
|
||||
clip.x1 = 0.f;
|
||||
clip.y1 = 0.f;
|
||||
clip.x2 = priv->allocation.x2 - priv->allocation.x1;
|
||||
clip.y2 = priv->allocation.y2 - priv->allocation.y1;
|
||||
CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);
|
||||
gfloat width, height;
|
||||
|
||||
width = priv->allocation.x2 - priv->allocation.x1;
|
||||
height = priv->allocation.y2 - priv->allocation.y1;
|
||||
|
||||
cogl_framebuffer_push_rectangle_clip (fb, 0, 0, width, height);
|
||||
clip_set = TRUE;
|
||||
}
|
||||
|
||||
if (clip_set)
|
||||
{
|
||||
if (pick_mode == CLUTTER_PICK_NONE)
|
||||
{
|
||||
CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);
|
||||
|
||||
cogl_framebuffer_push_rectangle_clip (fb,
|
||||
clip.x1,
|
||||
clip.y1,
|
||||
clip.x2,
|
||||
clip.y2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_clutter_actor_push_pick_clip (self, &clip))
|
||||
clip_set = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (pick_mode == CLUTTER_PICK_NONE)
|
||||
{
|
||||
/* We check whether we need to add the flatten effect before
|
||||
@@ -4085,16 +4018,9 @@ clutter_actor_paint (ClutterActor *self)
|
||||
done:
|
||||
if (clip_set)
|
||||
{
|
||||
if (pick_mode == CLUTTER_PICK_NONE)
|
||||
{
|
||||
CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);
|
||||
CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);
|
||||
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
}
|
||||
else
|
||||
{
|
||||
_clutter_actor_pop_pick_clip (self);
|
||||
}
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
}
|
||||
|
||||
cogl_pop_matrix ();
|
||||
@@ -4165,12 +4091,11 @@ clutter_actor_continue_paint (ClutterActor *self)
|
||||
{
|
||||
ClutterColor col = { 0, };
|
||||
|
||||
/* The actor will log a silhouette of itself to the stage pick log.
|
||||
* Note that the picking color is no longer used as the "log" instead
|
||||
* keeps a weak pointer to the actor itself. But we keep the color
|
||||
* parameter for now so as to maintain ABI compatibility. The color
|
||||
* parameter can be removed when someone feels like breaking the ABI
|
||||
* along with gnome-shell.
|
||||
_clutter_id_to_color (_clutter_actor_get_pick_id (self), &col);
|
||||
|
||||
/* Actor will then paint silhouette of itself in supplied
|
||||
* color. See clutter_stage_get_actor_at_pos() for where
|
||||
* picking is enabled.
|
||||
*
|
||||
* XXX:2.0 - Call the pick() virtual directly
|
||||
*/
|
||||
@@ -8073,7 +7998,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, destroy),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterActor::show:
|
||||
@@ -8089,7 +8015,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, show),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterActor::hide:
|
||||
@@ -8105,7 +8032,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, hide),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterActor::parent-set:
|
||||
@@ -8121,7 +8049,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, parent_set),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
@@ -8189,9 +8118,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
CLUTTER_TYPE_PAINT_VOLUME);
|
||||
g_signal_set_va_marshaller (actor_signals[QUEUE_REDRAW],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__OBJECT_BOXEDv);
|
||||
|
||||
/**
|
||||
* ClutterActor::queue-relayout:
|
||||
@@ -8216,7 +8142,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_SIGNAL_RUN_LAST |
|
||||
G_SIGNAL_NO_HOOKS,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, queue_relayout),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -8243,9 +8170,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
/**
|
||||
* ClutterActor::button-press-event:
|
||||
* @actor: the actor which received the event
|
||||
@@ -8268,9 +8192,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[BUTTON_PRESS_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
/**
|
||||
* ClutterActor::button-release-event:
|
||||
* @actor: the actor which received the event
|
||||
@@ -8293,9 +8214,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[BUTTON_RELEASE_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
/**
|
||||
* ClutterActor::scroll-event:
|
||||
* @actor: the actor which received the event
|
||||
@@ -8318,9 +8236,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[SCROLL_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
/**
|
||||
* ClutterActor::key-press-event:
|
||||
* @actor: the actor which received the event
|
||||
@@ -8343,9 +8258,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[KEY_PRESS_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
/**
|
||||
* ClutterActor::key-release-event:
|
||||
* @actor: the actor which received the event
|
||||
@@ -8369,9 +8281,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[KEY_RELEASE_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
/**
|
||||
* ClutterActor::motion-event:
|
||||
* @actor: the actor which received the event
|
||||
@@ -8394,9 +8303,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[MOTION_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
|
||||
/**
|
||||
* ClutterActor::key-focus-in:
|
||||
@@ -8411,7 +8317,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, key_focus_in),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -8427,7 +8334,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, key_focus_out),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -8451,9 +8359,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[ENTER_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
|
||||
/**
|
||||
* ClutterActor::leave-event:
|
||||
@@ -8476,9 +8381,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[LEAVE_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
|
||||
/**
|
||||
* ClutterActor::captured-event:
|
||||
@@ -8507,9 +8409,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[CAPTURED_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
|
||||
/**
|
||||
* ClutterActor::paint:
|
||||
@@ -8540,7 +8439,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_SIGNAL_NO_HOOKS |
|
||||
G_SIGNAL_DEPRECATED,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, paint),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterActor::realize:
|
||||
@@ -8559,7 +8459,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, realize),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterActor::unrealize:
|
||||
@@ -8578,7 +8479,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, unrealize),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -8606,7 +8508,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, pick),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_COLOR | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
|
||||
@@ -8635,9 +8538,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_NONE, 2,
|
||||
CLUTTER_TYPE_ACTOR_BOX | G_SIGNAL_TYPE_STATIC_SCOPE,
|
||||
CLUTTER_TYPE_ALLOCATION_FLAGS);
|
||||
g_signal_set_va_marshaller (actor_signals[ALLOCATION_CHANGED],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_VOID__BOXED_FLAGSv);
|
||||
|
||||
/**
|
||||
* ClutterActor::transitions-completed:
|
||||
@@ -8653,7 +8553,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -8681,9 +8582,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_BOOLEAN);
|
||||
g_signal_set_va_marshaller (actor_signals[TRANSITION_STOPPED],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_VOID__STRING_BOOLEANv);
|
||||
|
||||
/**
|
||||
* ClutterActor::touch-event:
|
||||
@@ -8707,9 +8605,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_BOOLEAN__BOXED,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
g_signal_set_va_marshaller (actor_signals[TOUCH_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -8719,6 +8614,8 @@ clutter_actor_init (ClutterActor *self)
|
||||
|
||||
self->priv = priv = clutter_actor_get_instance_private (self);
|
||||
|
||||
priv->pick_id = -1;
|
||||
|
||||
priv->opacity = 0xff;
|
||||
priv->show_on_set_parent = TRUE;
|
||||
priv->resource_scale = -1.0f;
|
||||
@@ -15022,30 +14919,6 @@ clutter_scriptable_iface_init (ClutterScriptableIface *iface)
|
||||
iface->set_custom_property = clutter_actor_set_custom_property;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_layout_from_animation_property (ClutterActor *actor,
|
||||
const gchar *name,
|
||||
gchar **name_p)
|
||||
{
|
||||
g_auto (GStrv) tokens = NULL;
|
||||
|
||||
if (!g_str_has_prefix (name, "@layout"))
|
||||
return FALSE;
|
||||
|
||||
tokens = g_strsplit (name, ".", -1);
|
||||
if (tokens == NULL || g_strv_length (tokens) != 2)
|
||||
{
|
||||
CLUTTER_NOTE (ANIMATION, "Invalid property name '%s'",
|
||||
name + 1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (name_p != NULL)
|
||||
*name_p = g_strdup (tokens[1]);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ClutterActorMeta *
|
||||
get_meta_from_animation_property (ClutterActor *actor,
|
||||
const gchar *name,
|
||||
@@ -15108,32 +14981,19 @@ static GParamSpec *
|
||||
clutter_actor_find_property (ClutterAnimatable *animatable,
|
||||
const gchar *property_name)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (animatable);
|
||||
ClutterActorMeta *meta = NULL;
|
||||
GObjectClass *klass = NULL;
|
||||
GParamSpec *pspec = NULL;
|
||||
gchar *p_name = NULL;
|
||||
gboolean use_layout;
|
||||
|
||||
use_layout = get_layout_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout)
|
||||
meta = get_meta_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
meta = get_meta_from_animation_property (CLUTTER_ACTOR (animatable),
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (meta != NULL)
|
||||
{
|
||||
klass = G_OBJECT_GET_CLASS (meta);
|
||||
|
||||
pspec = g_object_class_find_property (klass, p_name);
|
||||
}
|
||||
else if (use_layout)
|
||||
{
|
||||
klass = G_OBJECT_GET_CLASS (actor->priv->layout_manager);
|
||||
|
||||
pspec = g_object_class_find_property (klass, p_name);
|
||||
}
|
||||
else
|
||||
@@ -15153,24 +15013,15 @@ clutter_actor_get_initial_state (ClutterAnimatable *animatable,
|
||||
const gchar *property_name,
|
||||
GValue *initial)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (animatable);
|
||||
ClutterActorMeta *meta = NULL;
|
||||
gchar *p_name = NULL;
|
||||
gboolean use_layout;
|
||||
|
||||
use_layout = get_layout_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout)
|
||||
meta = get_meta_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
meta = get_meta_from_animation_property (CLUTTER_ACTOR (animatable),
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (meta != NULL)
|
||||
g_object_get_property (G_OBJECT (meta), p_name, initial);
|
||||
else if (use_layout)
|
||||
g_object_get_property (G_OBJECT (actor->priv->layout_manager), p_name, initial);
|
||||
else
|
||||
g_object_get_property (G_OBJECT (animatable), property_name, initial);
|
||||
|
||||
@@ -15323,21 +15174,12 @@ clutter_actor_set_final_state (ClutterAnimatable *animatable,
|
||||
ClutterActor *actor = CLUTTER_ACTOR (animatable);
|
||||
ClutterActorMeta *meta = NULL;
|
||||
gchar *p_name = NULL;
|
||||
gboolean use_layout;
|
||||
|
||||
use_layout = get_layout_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout)
|
||||
meta = get_meta_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
meta = get_meta_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
if (meta != NULL)
|
||||
g_object_set_property (G_OBJECT (meta), p_name, final);
|
||||
else if (use_layout)
|
||||
g_object_set_property (G_OBJECT (actor->priv->layout_manager), p_name, final);
|
||||
else
|
||||
{
|
||||
GObjectClass *obj_class = G_OBJECT_GET_CLASS (animatable);
|
||||
|
@@ -902,10 +902,6 @@ void clutter_actor_bind_model_with_properties
|
||||
const char *first_model_property,
|
||||
...);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_pick_box (ClutterActor *self,
|
||||
const ClutterActorBox *box);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_H__ */
|
||||
|
@@ -50,6 +50,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeformEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeviceManager, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDragAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDropAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref)
|
||||
|
@@ -27,6 +27,8 @@
|
||||
#include <clutter/clutter-keymap.h>
|
||||
#include <clutter/clutter-stage-window.h>
|
||||
|
||||
#include "clutter-event-translator.h"
|
||||
|
||||
#define CLUTTER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND, ClutterBackendClass))
|
||||
#define CLUTTER_IS_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND))
|
||||
#define CLUTTER_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND, ClutterBackendClass))
|
||||
@@ -56,7 +58,7 @@ struct _ClutterBackend
|
||||
gfloat units_per_em;
|
||||
gint32 units_serial;
|
||||
|
||||
ClutterStageWindow *stage_window;
|
||||
GList *event_translators;
|
||||
|
||||
ClutterInputMethod *input_method;
|
||||
|
||||
@@ -91,6 +93,12 @@ struct _ClutterBackendClass
|
||||
GError **error);
|
||||
ClutterDeviceManager *(* get_device_manager) (ClutterBackend *backend);
|
||||
|
||||
void (* copy_event_data) (ClutterBackend *backend,
|
||||
const ClutterEvent *src,
|
||||
ClutterEvent *dest);
|
||||
void (* free_event_data) (ClutterBackend *backend,
|
||||
ClutterEvent *event);
|
||||
|
||||
gboolean (* translate_event) (ClutterBackend *backend,
|
||||
gpointer native,
|
||||
ClutterEvent *event);
|
||||
@@ -128,11 +136,17 @@ void _clutter_backend_copy_event_data (Clutter
|
||||
ClutterEvent *dest);
|
||||
void _clutter_backend_free_event_data (ClutterBackend *backend,
|
||||
ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_backend_translate_event (ClutterBackend *backend,
|
||||
gpointer native,
|
||||
ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_backend_add_event_translator (ClutterBackend *backend,
|
||||
ClutterEventTranslator *translator);
|
||||
|
||||
void _clutter_backend_remove_event_translator (ClutterBackend *backend,
|
||||
ClutterEventTranslator *translator);
|
||||
|
||||
ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
|
||||
|
||||
gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend,
|
||||
@@ -146,9 +160,6 @@ void _clutter_backend_reset_cogl_framebuffer (Clutter
|
||||
|
||||
void clutter_set_allowed_drivers (const char *drivers);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterStageWindow * clutter_backend_get_stage_window (ClutterBackend *backend);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BACKEND_PRIVATE_H__ */
|
||||
|
@@ -62,6 +62,9 @@
|
||||
#ifdef CLUTTER_INPUT_X11
|
||||
#include "x11/clutter-backend-x11.h"
|
||||
#endif
|
||||
#ifdef CLUTTER_INPUT_EVDEV
|
||||
#include "evdev/clutter-device-manager-evdev.h"
|
||||
#endif
|
||||
#ifdef CLUTTER_WINDOWING_EGL
|
||||
#include "egl/clutter-backend-eglnative.h"
|
||||
#endif
|
||||
@@ -101,12 +104,10 @@ clutter_backend_dispose (GObject *gobject)
|
||||
/* clear the events still in the queue of the main context */
|
||||
_clutter_clear_events_queue ();
|
||||
|
||||
/* remove all event translators */
|
||||
g_clear_pointer (&backend->event_translators, g_list_free);
|
||||
|
||||
g_clear_pointer (&backend->dummy_onscreen, cogl_object_unref);
|
||||
if (backend->stage_window)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (backend->stage_window),
|
||||
(gpointer *) &backend->stage_window);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject);
|
||||
}
|
||||
@@ -396,7 +397,7 @@ clutter_backend_real_create_context (ClutterBackend *backend,
|
||||
else
|
||||
g_set_error_literal (error, CLUTTER_INIT_ERROR,
|
||||
CLUTTER_INIT_ERROR_BACKEND,
|
||||
"Unable to initialize the Clutter backend: no available drivers found.");
|
||||
_("Unable to initialize the Clutter backend: no available drivers found."));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -525,7 +526,40 @@ _clutter_create_backend (void)
|
||||
static void
|
||||
clutter_backend_real_init_events (ClutterBackend *backend)
|
||||
{
|
||||
g_error ("Unknown input backend");
|
||||
const char *input_backend = NULL;
|
||||
|
||||
input_backend = g_getenv ("CLUTTER_INPUT_BACKEND");
|
||||
if (input_backend != NULL)
|
||||
input_backend = g_intern_string (input_backend);
|
||||
|
||||
#ifdef CLUTTER_INPUT_X11
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) &&
|
||||
(input_backend == NULL || input_backend == I_(CLUTTER_INPUT_X11)))
|
||||
{
|
||||
_clutter_backend_x11_events_init (backend);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef CLUTTER_INPUT_EVDEV
|
||||
/* Evdev can be used regardless of the windowing system */
|
||||
if ((input_backend != NULL && strcmp (input_backend, CLUTTER_INPUT_EVDEV) == 0)
|
||||
#ifdef CLUTTER_WINDOWING_EGL
|
||||
/* but we do want to always use it for EGL native */
|
||||
|| clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
_clutter_events_evdev_init (backend);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (input_backend != NULL)
|
||||
{
|
||||
if (input_backend != I_(CLUTTER_INPUT_NULL))
|
||||
g_error ("Unrecognized input backend '%s'", input_backend);
|
||||
}
|
||||
else
|
||||
g_error ("Unknown input backend");
|
||||
}
|
||||
|
||||
static ClutterDeviceManager *
|
||||
@@ -552,6 +586,34 @@ clutter_backend_real_get_keymap (ClutterBackend *backend)
|
||||
return backend->keymap;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_backend_real_translate_event (ClutterBackend *backend,
|
||||
gpointer native,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = backend->event_translators;
|
||||
l != NULL;
|
||||
l = l->next)
|
||||
{
|
||||
ClutterEventTranslator *translator = l->data;
|
||||
ClutterTranslateReturn retval;
|
||||
|
||||
retval = _clutter_event_translator_translate_event (translator,
|
||||
native,
|
||||
event);
|
||||
|
||||
if (retval == CLUTTER_TRANSLATE_QUEUE)
|
||||
return TRUE;
|
||||
|
||||
if (retval == CLUTTER_TRANSLATE_REMOVE)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_class_init (ClutterBackendClass *klass)
|
||||
{
|
||||
@@ -574,7 +636,8 @@ clutter_backend_class_init (ClutterBackendClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -591,7 +654,8 @@ clutter_backend_class_init (ClutterBackendClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterBackendClass, font_changed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -608,7 +672,8 @@ clutter_backend_class_init (ClutterBackendClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterBackendClass, settings_changed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
klass->resolution_changed = clutter_backend_real_resolution_changed;
|
||||
@@ -616,6 +681,7 @@ clutter_backend_class_init (ClutterBackendClass *klass)
|
||||
|
||||
klass->init_events = clutter_backend_real_init_events;
|
||||
klass->get_device_manager = clutter_backend_real_get_device_manager;
|
||||
klass->translate_event = clutter_backend_real_translate_event;
|
||||
klass->create_context = clutter_backend_real_create_context;
|
||||
klass->get_features = clutter_backend_real_get_features;
|
||||
klass->get_keymap = clutter_backend_real_get_keymap;
|
||||
@@ -695,10 +761,6 @@ _clutter_backend_create_stage (ClutterBackend *backend,
|
||||
|
||||
g_assert (CLUTTER_IS_STAGE_WINDOW (stage_window));
|
||||
|
||||
backend->stage_window = stage_window;
|
||||
g_object_add_weak_pointer (G_OBJECT (backend->stage_window),
|
||||
(gpointer *) &backend->stage_window);
|
||||
|
||||
return stage_window;
|
||||
}
|
||||
|
||||
@@ -783,24 +845,37 @@ _clutter_backend_copy_event_data (ClutterBackend *backend,
|
||||
const ClutterEvent *src,
|
||||
ClutterEvent *dest)
|
||||
{
|
||||
ClutterDeviceManagerClass *device_manager_class;
|
||||
ClutterDeviceManager *device_manager;
|
||||
ClutterEventExtenderInterface *iface;
|
||||
ClutterBackendClass *klass;
|
||||
|
||||
device_manager = clutter_device_manager_get_default ();
|
||||
device_manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
|
||||
device_manager_class->copy_event_data (device_manager, src, dest);
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
if (CLUTTER_IS_EVENT_EXTENDER (backend->device_manager))
|
||||
{
|
||||
iface = CLUTTER_EVENT_EXTENDER_GET_IFACE (backend->device_manager);
|
||||
iface->copy_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager),
|
||||
src, dest);
|
||||
}
|
||||
else if (klass->copy_event_data != NULL)
|
||||
klass->copy_event_data (backend, src, dest);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_backend_free_event_data (ClutterBackend *backend,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
ClutterDeviceManagerClass *device_manager_class;
|
||||
ClutterDeviceManager *device_manager;
|
||||
ClutterEventExtenderInterface *iface;
|
||||
ClutterBackendClass *klass;
|
||||
|
||||
device_manager = clutter_device_manager_get_default ();
|
||||
device_manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
|
||||
device_manager_class->free_event_data (device_manager, event);
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
|
||||
if (CLUTTER_IS_EVENT_EXTENDER (backend->device_manager))
|
||||
{
|
||||
iface = CLUTTER_EVENT_EXTENDER_GET_IFACE (backend->device_manager);
|
||||
iface->free_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager),
|
||||
event);
|
||||
}
|
||||
else if (klass->free_event_data != NULL)
|
||||
klass->free_event_data (backend, event);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -946,6 +1021,28 @@ _clutter_backend_translate_event (ClutterBackend *backend,
|
||||
event);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_backend_add_event_translator (ClutterBackend *backend,
|
||||
ClutterEventTranslator *translator)
|
||||
{
|
||||
if (g_list_find (backend->event_translators, translator) != NULL)
|
||||
return;
|
||||
|
||||
backend->event_translators =
|
||||
g_list_prepend (backend->event_translators, translator);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_backend_remove_event_translator (ClutterBackend *backend,
|
||||
ClutterEventTranslator *translator)
|
||||
{
|
||||
if (g_list_find (backend->event_translators, translator) == NULL)
|
||||
return;
|
||||
|
||||
backend->event_translators =
|
||||
g_list_remove (backend->event_translators, translator);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_backend_get_cogl_context: (skip)
|
||||
* @backend: a #ClutterBackend
|
||||
@@ -1093,9 +1190,3 @@ clutter_backend_get_keymap (ClutterBackend *backend)
|
||||
{
|
||||
return CLUTTER_BACKEND_GET_CLASS (backend)->get_keymap (backend);
|
||||
}
|
||||
|
||||
ClutterStageWindow *
|
||||
clutter_backend_get_stage_window (ClutterBackend *backend)
|
||||
{
|
||||
return backend->stage_window;
|
||||
}
|
||||
|
@@ -570,68 +570,6 @@ G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterPoint, clutter_point,
|
||||
clutter_point_free,
|
||||
CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_point_progress))
|
||||
|
||||
static int
|
||||
clutter_point_compare_line (const ClutterPoint *p,
|
||||
const ClutterPoint *a,
|
||||
const ClutterPoint *b)
|
||||
{
|
||||
float x1 = b->x - a->x;
|
||||
float y1 = b->y - a->y;
|
||||
float x2 = p->x - a->x;
|
||||
float y2 = p->y - a->y;
|
||||
float cross_z = x1 * y2 - y1 * x2;
|
||||
|
||||
if (cross_z > 0.f)
|
||||
return 1;
|
||||
else if (cross_z < 0.f)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_point_inside_quadrilateral:
|
||||
* @point: a #ClutterPoint to test
|
||||
* @vertices: array of vertices of the quadrilateral, in clockwise order,
|
||||
* from top-left to bottom-left
|
||||
*
|
||||
* Determines whether a point is inside the convex quadrilateral provided,
|
||||
* and not on any of its edges or vertices.
|
||||
*
|
||||
* Returns: %TRUE if @point is inside the quadrilateral
|
||||
*/
|
||||
gboolean
|
||||
clutter_point_inside_quadrilateral (const ClutterPoint *point,
|
||||
const ClutterPoint *vertices)
|
||||
{
|
||||
unsigned int i;
|
||||
int first_side;
|
||||
|
||||
first_side = 0;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
int side;
|
||||
|
||||
side = clutter_point_compare_line (point,
|
||||
&vertices[i],
|
||||
&vertices[(i + 1) % 4]);
|
||||
|
||||
if (side)
|
||||
{
|
||||
if (first_side == 0)
|
||||
first_side = side;
|
||||
else if (side != first_side)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (first_side == 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
@@ -666,7 +666,8 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterClickActionClass, clicked),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
|
@@ -197,7 +197,8 @@ clutter_container_default_init (ClutterContainerInterface *iface)
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterContainerIface, actor_added),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
/**
|
||||
@@ -215,7 +216,8 @@ clutter_container_default_init (ClutterContainerInterface *iface)
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterContainerIface, actor_removed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
|
@@ -129,7 +129,8 @@ clutter_content_default_init (ClutterContentInterface *iface)
|
||||
G_TYPE_FROM_INTERFACE (iface),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterContentInterface, attached),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
@@ -148,7 +149,8 @@ clutter_content_default_init (ClutterContentInterface *iface)
|
||||
G_TYPE_FROM_INTERFACE (iface),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterContentInterface, detached),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@ typedef enum
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_DEBUG_NOP_PICKING = 1 << 0,
|
||||
CLUTTER_DEBUG_DUMP_PICK_BUFFERS = 1 << 1
|
||||
} ClutterPickDebugFlag;
|
||||
|
||||
typedef enum
|
||||
|
@@ -80,7 +80,6 @@ typedef struct _ClutterPtrA11yData
|
||||
gboolean dwell_drag_started;
|
||||
gboolean dwell_gesture_started;
|
||||
guint dwell_timer;
|
||||
guint dwell_position_timer;
|
||||
|
||||
guint secondary_click_timer;
|
||||
gboolean secondary_click_triggered;
|
||||
@@ -194,15 +193,34 @@ struct _ClutterInputDeviceClass
|
||||
ClutterEmitInputDeviceEvent emit_event_func);
|
||||
};
|
||||
|
||||
/* Platform-dependent interface */
|
||||
typedef struct _ClutterEventExtender ClutterEventExtender;
|
||||
typedef struct _ClutterEventExtenderInterface ClutterEventExtenderInterface;
|
||||
|
||||
#define CLUTTER_TYPE_EVENT_EXTENDER (clutter_event_extender_get_type ())
|
||||
#define CLUTTER_EVENT_EXTENDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CLUTTER_TYPE_EVENT_EXTENDER, ClutterEventExtender))
|
||||
#define CLUTTER_IS_EVENT_EXTENDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CLUTTER_TYPE_EVENT_EXTENDER))
|
||||
#define CLUTTER_EVENT_EXTENDER_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), CLUTTER_TYPE_EVENT_EXTENDER, ClutterEventExtenderInterface))
|
||||
|
||||
struct _ClutterEventExtenderInterface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
void (* copy_event_data) (ClutterEventExtender *event_extender,
|
||||
const ClutterEvent *src,
|
||||
ClutterEvent *dest);
|
||||
void (* free_event_data) (ClutterEventExtender *event_extender,
|
||||
ClutterEvent *event);
|
||||
};
|
||||
|
||||
GType clutter_event_extender_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/* device manager */
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_device_manager_add_device (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_device_manager_remove_device (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *device);
|
||||
void _clutter_device_manager_update_devices (ClutterDeviceManager *device_manager);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_device_manager_select_stage_events (ClutterDeviceManager *device_manager,
|
||||
ClutterStage *stage);
|
||||
ClutterBackend *_clutter_device_manager_get_backend (ClutterDeviceManager *device_manager);
|
||||
@@ -212,31 +230,23 @@ void _clutter_device_manager_compress_motion (ClutterDeviceMa
|
||||
const ClutterEvent *to_discard);
|
||||
|
||||
/* input device */
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_input_device_has_sequence (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_add_event_sequence (ClutterInputDevice *device,
|
||||
ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device,
|
||||
ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_coords (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
gfloat x,
|
||||
gfloat y,
|
||||
ClutterStage *stage);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_state (ClutterInputDevice *device,
|
||||
ClutterModifierType state);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_time (ClutterInputDevice *device,
|
||||
guint32 time_);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_stage (ClutterInputDevice *device,
|
||||
ClutterStage *stage);
|
||||
CLUTTER_EXPORT
|
||||
ClutterStage * _clutter_input_device_get_stage (ClutterInputDevice *device);
|
||||
void _clutter_input_device_set_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
@@ -245,57 +255,44 @@ void _clutter_input_device_set_actor (ClutterInputDev
|
||||
ClutterActor * _clutter_input_device_update (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
gboolean emit_crossing);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_n_keys (ClutterInputDevice *device,
|
||||
guint n_keys);
|
||||
CLUTTER_EXPORT
|
||||
guint _clutter_input_device_add_axis (ClutterInputDevice *device,
|
||||
ClutterInputAxis axis,
|
||||
gdouble min_value,
|
||||
gdouble max_value,
|
||||
gdouble resolution);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_reset_axes (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_associated_device (ClutterInputDevice *device,
|
||||
ClutterInputDevice *associated);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_add_slave (ClutterInputDevice *master,
|
||||
ClutterInputDevice *slave);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_remove_slave (ClutterInputDevice *master,
|
||||
ClutterInputDevice *slave);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device,
|
||||
guint index_,
|
||||
gdouble value,
|
||||
gdouble *axis_value);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_add_scroll_info (ClutterInputDevice *device,
|
||||
guint index_,
|
||||
ClutterScrollDirection direction,
|
||||
gdouble increment);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_reset_scroll_info (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_input_device_get_scroll_delta (ClutterInputDevice *device,
|
||||
guint index_,
|
||||
gdouble value,
|
||||
ClutterScrollDirection *direction_p,
|
||||
gdouble *delta_p);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDeviceTool * clutter_input_device_lookup_tool (ClutterInputDevice *device,
|
||||
guint64 serial,
|
||||
ClutterInputDeviceToolType type);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_device_add_tool (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_device_update_from_tool (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool);
|
||||
|
||||
|
@@ -91,14 +91,22 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterDeviceManager,
|
||||
clutter_device_manager,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
G_DEFINE_INTERFACE (ClutterEventExtender,
|
||||
clutter_event_extender,
|
||||
CLUTTER_TYPE_DEVICE_MANAGER)
|
||||
|
||||
static void
|
||||
clutter_event_extender_default_init (ClutterEventExtenderInterface *iface)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterDeviceManager *self = CLUTTER_DEVICE_MANAGER (gobject);
|
||||
ClutterDeviceManagerPrivate *priv = clutter_device_manager_get_instance_private (self);
|
||||
ClutterDeviceManagerPrivate *priv = CLUTTER_DEVICE_MANAGER (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -117,8 +125,7 @@ clutter_device_manager_get_property (GObject *gobject,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterDeviceManager *self = CLUTTER_DEVICE_MANAGER (gobject);
|
||||
ClutterDeviceManagerPrivate *priv = clutter_device_manager_get_instance_private (self);
|
||||
ClutterDeviceManagerPrivate *priv = CLUTTER_DEVICE_MANAGER (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -164,7 +171,8 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_INPUT_DEVICE);
|
||||
|
||||
@@ -183,7 +191,8 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_INPUT_DEVICE);
|
||||
|
||||
@@ -282,7 +291,6 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @device: the core pointer #ClutterInputDevice
|
||||
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
|
||||
* @clicked: %TRUE if the timeout finished and triggered a click
|
||||
*
|
||||
* The ::ptr-a11y-timeout-stopped signal is emitted when a running
|
||||
* pointer accessibility timeout delay is stopped, either because
|
||||
@@ -294,16 +302,16 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT_FLAGS_BOOLEAN,
|
||||
G_TYPE_NONE, 3,
|
||||
_clutter_marshal_VOID__OBJECT_FLAGS,
|
||||
G_TYPE_NONE, 2,
|
||||
CLUTTER_TYPE_INPUT_DEVICE,
|
||||
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
|
||||
G_TYPE_BOOLEAN);
|
||||
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_init (ClutterDeviceManager *self)
|
||||
{
|
||||
self->priv = clutter_device_manager_get_instance_private (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,7 +330,7 @@ clutter_device_manager_get_default (void)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
|
||||
return CLUTTER_BACKEND_GET_CLASS (backend)->get_device_manager (backend);
|
||||
return backend->device_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -546,11 +554,9 @@ _clutter_device_manager_update_devices (ClutterDeviceManager *device_manager)
|
||||
ClutterBackend *
|
||||
_clutter_device_manager_get_backend (ClutterDeviceManager *manager)
|
||||
{
|
||||
ClutterDeviceManagerPrivate *priv = clutter_device_manager_get_instance_private (manager);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (manager), NULL);
|
||||
|
||||
return priv->backend;
|
||||
return manager->priv->backend;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -619,14 +625,13 @@ clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_man
|
||||
ClutterKbdA11ySettings *settings)
|
||||
{
|
||||
ClutterDeviceManagerClass *manager_class;
|
||||
ClutterDeviceManagerPrivate *priv = clutter_device_manager_get_instance_private (device_manager);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
if (are_kbd_a11y_settings_equal (&priv->kbd_a11y_settings, settings))
|
||||
if (are_kbd_a11y_settings_equal (&device_manager->priv->kbd_a11y_settings, settings))
|
||||
return;
|
||||
|
||||
priv->kbd_a11y_settings = *settings;
|
||||
device_manager->priv->kbd_a11y_settings = *settings;
|
||||
|
||||
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
|
||||
if (manager_class->apply_kbd_a11y_settings)
|
||||
@@ -637,11 +642,9 @@ void
|
||||
clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings)
|
||||
{
|
||||
ClutterDeviceManagerPrivate *priv = clutter_device_manager_get_instance_private (device_manager);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
*settings = priv->kbd_a11y_settings;
|
||||
*settings = device_manager->priv->kbd_a11y_settings;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -684,20 +687,17 @@ void
|
||||
clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11ySettings *settings)
|
||||
{
|
||||
ClutterDeviceManagerPrivate *priv =
|
||||
clutter_device_manager_get_instance_private (device_manager);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
if (are_pointer_a11y_settings_equal (&priv->pointer_a11y_settings, settings))
|
||||
if (are_pointer_a11y_settings_equal (&device_manager->priv->pointer_a11y_settings, settings))
|
||||
return;
|
||||
|
||||
if (priv->pointer_a11y_settings.controls == 0 && settings->controls != 0)
|
||||
if (device_manager->priv->pointer_a11y_settings.controls == 0 && settings->controls != 0)
|
||||
clutter_device_manager_enable_pointer_a11y (device_manager);
|
||||
else if (priv->pointer_a11y_settings.controls != 0 && settings->controls == 0)
|
||||
else if (device_manager->priv->pointer_a11y_settings.controls != 0 && settings->controls == 0)
|
||||
clutter_device_manager_disable_pointer_a11y (device_manager);
|
||||
|
||||
priv->pointer_a11y_settings = *settings;
|
||||
device_manager->priv->pointer_a11y_settings = *settings;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -711,12 +711,9 @@ void
|
||||
clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11ySettings *settings)
|
||||
{
|
||||
ClutterDeviceManagerPrivate *priv =
|
||||
clutter_device_manager_get_instance_private (device_manager);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
*settings = priv->pointer_a11y_settings;
|
||||
*settings = device_manager->priv->pointer_a11y_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -730,10 +727,7 @@ void
|
||||
clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11yDwellClickType click_type)
|
||||
{
|
||||
ClutterDeviceManagerPrivate *priv =
|
||||
clutter_device_manager_get_instance_private (device_manager);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
priv->pointer_a11y_settings.dwell_click_type = click_type;
|
||||
device_manager->priv->pointer_a11y_settings.dwell_click_type = click_type;
|
||||
}
|
||||
|
@@ -33,12 +33,16 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_DEVICE_MANAGER (clutter_device_manager_get_type ())
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterDeviceManager, clutter_device_manager,
|
||||
CLUTTER, DEVICE_MANAGER, GObject)
|
||||
#define CLUTTER_TYPE_DEVICE_MANAGER (clutter_device_manager_get_type ())
|
||||
#define CLUTTER_DEVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEVICE_MANAGER, ClutterDeviceManager))
|
||||
#define CLUTTER_IS_DEVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEVICE_MANAGER))
|
||||
#define CLUTTER_DEVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEVICE_MANAGER, ClutterDeviceManagerClass))
|
||||
#define CLUTTER_IS_DEVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEVICE_MANAGER))
|
||||
#define CLUTTER_DEVICE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEVICE_MANAGER, ClutterDeviceManagerClass))
|
||||
|
||||
typedef struct _ClutterDeviceManager ClutterDeviceManager;
|
||||
typedef struct _ClutterDeviceManagerPrivate ClutterDeviceManagerPrivate;
|
||||
typedef struct _ClutterDeviceManagerClass ClutterDeviceManagerClass;
|
||||
|
||||
/**
|
||||
* ClutterVirtualDeviceType:
|
||||
@@ -90,6 +94,21 @@ typedef struct _ClutterPointerA11ySettings
|
||||
gint dwell_threshold;
|
||||
} ClutterPointerA11ySettings;
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager:
|
||||
*
|
||||
* The #ClutterDeviceManager structure contains only private data
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
struct _ClutterDeviceManager
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
ClutterDeviceManagerPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterDeviceManagerClass:
|
||||
*
|
||||
@@ -123,18 +142,13 @@ struct _ClutterDeviceManagerClass
|
||||
/* Keyboard accessbility */
|
||||
void (* apply_kbd_a11y_settings) (ClutterDeviceManager *device_manger,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
/* Event platform data */
|
||||
void (* copy_event_data) (ClutterDeviceManager *device_manager,
|
||||
const ClutterEvent *src,
|
||||
ClutterEvent *dest);
|
||||
void (* free_event_data) (ClutterDeviceManager *device_manager,
|
||||
ClutterEvent *event);
|
||||
|
||||
/* padding */
|
||||
gpointer _padding[4];
|
||||
gpointer _padding[6];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_device_manager_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterDeviceManager *clutter_device_manager_get_default (void);
|
||||
CLUTTER_EXPORT
|
||||
|
@@ -428,7 +428,8 @@ clutter_drop_action_class_init (ClutterDropActionClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterDropActionClass, over_in),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
@@ -447,7 +448,8 @@ clutter_drop_action_class_init (ClutterDropActionClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterDropActionClass, over_out),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
|
@@ -5,28 +5,22 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_event_set_pointer_emulated (ClutterEvent *event,
|
||||
gboolean is_emulated);
|
||||
|
||||
/* Reinjecting queued events for processing */
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_process_event (ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_event_process_filters (ClutterEvent *event);
|
||||
|
||||
/* clears the event queue inside the main context */
|
||||
void _clutter_clear_events_queue (void);
|
||||
void _clutter_clear_events_queue_for_stage (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_event_set_platform_data (ClutterEvent *event,
|
||||
gpointer data);
|
||||
CLUTTER_EXPORT
|
||||
gpointer _clutter_event_get_platform_data (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_event_set_state_full (ClutterEvent *event,
|
||||
ClutterModifierType button_state,
|
||||
ClutterModifierType base_state,
|
||||
@@ -34,7 +28,6 @@ void _clutter_event_set_state_full (ClutterEvent *ev
|
||||
ClutterModifierType locked_state,
|
||||
ClutterModifierType effective_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_event_push (const ClutterEvent *event,
|
||||
gboolean do_copy);
|
||||
|
||||
|
38
clutter/clutter/clutter-event-translator.c
Normal file
38
clutter/clutter/clutter-event-translator.c
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-event-translator.h"
|
||||
|
||||
#include "clutter-backend.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#define clutter_event_translator_get_type _clutter_event_translator_get_type
|
||||
|
||||
typedef ClutterEventTranslatorIface ClutterEventTranslatorInterface;
|
||||
|
||||
G_DEFINE_INTERFACE (ClutterEventTranslator, clutter_event_translator, G_TYPE_OBJECT);
|
||||
|
||||
static ClutterTranslateReturn
|
||||
default_translate_event (ClutterEventTranslator *translator,
|
||||
gpointer native,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
return CLUTTER_TRANSLATE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_event_translator_default_init (ClutterEventTranslatorIface *iface)
|
||||
{
|
||||
iface->translate_event = default_translate_event;
|
||||
}
|
||||
|
||||
ClutterTranslateReturn
|
||||
_clutter_event_translator_translate_event (ClutterEventTranslator *translator,
|
||||
gpointer native,
|
||||
ClutterEvent *translated)
|
||||
{
|
||||
ClutterEventTranslatorIface *iface;
|
||||
|
||||
iface = CLUTTER_EVENT_TRANSLATOR_GET_IFACE (translator);
|
||||
|
||||
return iface->translate_event (translator, native, translated);
|
||||
}
|
42
clutter/clutter/clutter-event-translator.h
Normal file
42
clutter/clutter/clutter-event-translator.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef __CLUTTER_EVENT_TRANSLATOR_H__
|
||||
#define __CLUTTER_EVENT_TRANSLATOR_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <clutter/clutter-event.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_EVENT_TRANSLATOR (_clutter_event_translator_get_type ())
|
||||
#define CLUTTER_EVENT_TRANSLATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_EVENT_TRANSLATOR, ClutterEventTranslator))
|
||||
#define CLUTTER_IS_EVENT_TRANSLATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_EVENT_TRANSLATOR))
|
||||
#define CLUTTER_EVENT_TRANSLATOR_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_EVENT_TRANSLATOR, ClutterEventTranslatorIface))
|
||||
|
||||
typedef struct _ClutterEventTranslator ClutterEventTranslator;
|
||||
typedef struct _ClutterEventTranslatorIface ClutterEventTranslatorIface;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_TRANSLATE_CONTINUE,
|
||||
CLUTTER_TRANSLATE_REMOVE,
|
||||
CLUTTER_TRANSLATE_QUEUE
|
||||
} ClutterTranslateReturn;
|
||||
|
||||
struct _ClutterEventTranslatorIface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
ClutterTranslateReturn (* translate_event) (ClutterEventTranslator *translator,
|
||||
gpointer native,
|
||||
ClutterEvent *translated);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType _clutter_event_translator_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterTranslateReturn _clutter_event_translator_translate_event (ClutterEventTranslator *translator,
|
||||
gpointer native,
|
||||
ClutterEvent *translated);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_EVENT_TRANSLATOR_H__ */
|
@@ -804,7 +804,8 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterGestureActionClass, gesture_end),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
@@ -826,7 +827,8 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterGestureActionClass, gesture_cancel),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
}
|
||||
|
@@ -256,7 +256,7 @@ clutter_image_set_data (ClutterImage *image,
|
||||
{
|
||||
g_set_error_literal (error, CLUTTER_IMAGE_ERROR,
|
||||
CLUTTER_IMAGE_ERROR_INVALID_DATA,
|
||||
"Unable to load image data");
|
||||
_("Unable to load image data"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ clutter_image_set_bytes (ClutterImage *image,
|
||||
{
|
||||
g_set_error_literal (error, CLUTTER_IMAGE_ERROR,
|
||||
CLUTTER_IMAGE_ERROR_INVALID_DATA,
|
||||
"Unable to load image data");
|
||||
_("Unable to load image data"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ clutter_image_set_area (ClutterImage *image,
|
||||
{
|
||||
g_set_error_literal (error, CLUTTER_IMAGE_ERROR,
|
||||
CLUTTER_IMAGE_ERROR_INVALID_DATA,
|
||||
"Unable to load image data");
|
||||
_("Unable to load image data"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@@ -1925,157 +1925,6 @@ _clutter_input_device_reset_scroll_info (ClutterInputDevice *device)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_grab_actor_destroy (ClutterActor *actor,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
switch (device->device_type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
case CLUTTER_TABLET_DEVICE:
|
||||
device->pointer_grab_actor = NULL;
|
||||
break;
|
||||
|
||||
case CLUTTER_KEYBOARD_DEVICE:
|
||||
device->keyboard_grab_actor = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_device_grab:
|
||||
* @device: a #ClutterInputDevice
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Acquires a grab on @actor for the given @device.
|
||||
*
|
||||
* Any event coming from @device will be delivered to @actor, bypassing
|
||||
* the usual event delivery mechanism, until the grab is released by
|
||||
* calling clutter_input_device_ungrab().
|
||||
*
|
||||
* The grab is client-side: even if the windowing system used by the Clutter
|
||||
* backend has the concept of "device grabs", Clutter will not use them.
|
||||
*
|
||||
* Only #ClutterInputDevice of types %CLUTTER_POINTER_DEVICE,
|
||||
* %CLUTTER_TABLET_DEVICE and %CLUTTER_KEYBOARD_DEVICE can hold a grab.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_input_device_grab (ClutterInputDevice *device,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterActor **grab_actor;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
switch (device->device_type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
case CLUTTER_TABLET_DEVICE:
|
||||
grab_actor = &device->pointer_grab_actor;
|
||||
break;
|
||||
|
||||
case CLUTTER_KEYBOARD_DEVICE:
|
||||
grab_actor = &device->keyboard_grab_actor;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_critical ("Only pointer and keyboard devices can grab an actor");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*grab_actor != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (*grab_actor,
|
||||
G_CALLBACK (on_grab_actor_destroy),
|
||||
device);
|
||||
}
|
||||
|
||||
*grab_actor = actor;
|
||||
|
||||
g_signal_connect (*grab_actor,
|
||||
"destroy",
|
||||
G_CALLBACK (on_grab_actor_destroy),
|
||||
device);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_device_ungrab:
|
||||
* @device: a #ClutterInputDevice
|
||||
*
|
||||
* Releases the grab on the @device, if one is in place.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_input_device_ungrab (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterActor **grab_actor;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
||||
|
||||
switch (device->device_type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
case CLUTTER_TABLET_DEVICE:
|
||||
grab_actor = &device->pointer_grab_actor;
|
||||
break;
|
||||
|
||||
case CLUTTER_KEYBOARD_DEVICE:
|
||||
grab_actor = &device->keyboard_grab_actor;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (*grab_actor == NULL)
|
||||
return;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (*grab_actor,
|
||||
G_CALLBACK (on_grab_actor_destroy),
|
||||
device);
|
||||
|
||||
*grab_actor = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_device_get_grabbed_actor:
|
||||
* @device: a #ClutterInputDevice
|
||||
*
|
||||
* Retrieves a pointer to the #ClutterActor currently grabbing all
|
||||
* the events coming from @device.
|
||||
*
|
||||
* Return value: (transfer none): a #ClutterActor, or %NULL
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_input_device_get_grabbed_actor (ClutterInputDevice *device)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
|
||||
|
||||
switch (device->device_type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
case CLUTTER_TABLET_DEVICE:
|
||||
return device->pointer_grab_actor;
|
||||
|
||||
case CLUTTER_KEYBOARD_DEVICE:
|
||||
return device->keyboard_grab_actor;
|
||||
|
||||
default:
|
||||
g_critical ("Only pointer and keyboard devices can grab an actor");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
on_grab_sequence_actor_destroy (ClutterActor *actor,
|
||||
ClutterInputDevice *device)
|
||||
|
@@ -27,19 +27,14 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_pointer_a11y_add_device (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device,
|
||||
int button,
|
||||
gboolean pressed);
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -99,7 +99,7 @@ get_dwell_click_type (ClutterInputDevice *device)
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
#
|
||||
return settings.dwell_click_type;
|
||||
}
|
||||
|
||||
@@ -171,8 +171,7 @@ trigger_secondary_click (gpointer data)
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
|
||||
TRUE);
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -203,8 +202,7 @@ stop_secondary_click_timeout (ClutterInputDevice *device)
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
|
||||
FALSE);
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK);
|
||||
}
|
||||
device->ptr_a11y_data->secondary_click_triggered = FALSE;
|
||||
}
|
||||
@@ -440,8 +438,7 @@ trigger_dwell_gesture (gpointer data)
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
|
||||
TRUE);
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -472,8 +469,7 @@ trigger_dwell_click (gpointer data)
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
|
||||
TRUE);
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL);
|
||||
|
||||
if (get_dwell_mode (device) == CLUTTER_A11Y_DWELL_MODE_GESTURE)
|
||||
{
|
||||
@@ -518,41 +514,10 @@ stop_dwell_timeout (ClutterInputDevice *device)
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
|
||||
FALSE);
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
trigger_dwell_position_timeout (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
|
||||
device->ptr_a11y_data->dwell_position_timer = 0;
|
||||
|
||||
if (is_dwell_click_enabled (device))
|
||||
{
|
||||
if (!pointer_has_moved (device))
|
||||
start_dwell_timeout (device);
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_dwell_position_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
device->ptr_a11y_data->dwell_position_timer =
|
||||
clutter_threads_add_timeout (100, trigger_dwell_position_timeout, device);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_dwell_position_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
g_clear_handle_id (&device->ptr_a11y_data->dwell_position_timer,
|
||||
g_source_remove);
|
||||
}
|
||||
|
||||
static void
|
||||
update_dwell_position (ClutterInputDevice *device)
|
||||
{
|
||||
@@ -605,7 +570,6 @@ _clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device)
|
||||
if (is_dwell_dragging (device))
|
||||
emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
|
||||
|
||||
stop_dwell_position_timeout (device);
|
||||
stop_dwell_timeout (device);
|
||||
stop_secondary_click_timeout (device);
|
||||
|
||||
@@ -633,13 +597,10 @@ _clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device,
|
||||
|
||||
if (is_dwell_click_enabled (device))
|
||||
{
|
||||
stop_dwell_position_timeout (device);
|
||||
|
||||
if (should_stop_dwell (device))
|
||||
stop_dwell_timeout (device);
|
||||
|
||||
if (should_start_dwell (device))
|
||||
start_dwell_position_timeout (device);
|
||||
else if (should_start_dwell (device))
|
||||
start_dwell_timeout (device);
|
||||
}
|
||||
|
||||
if (should_update_dwell_position (device))
|
||||
@@ -661,8 +622,6 @@ _clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device,
|
||||
{
|
||||
device->ptr_a11y_data->n_btn_pressed++;
|
||||
|
||||
stop_dwell_position_timeout (device);
|
||||
|
||||
if (is_dwell_click_enabled (device))
|
||||
stop_dwell_timeout (device);
|
||||
|
||||
|
@@ -444,7 +444,8 @@ clutter_layout_manager_class_init (ClutterLayoutManagerClass *klass)
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterLayoutManagerClass,
|
||||
layout_changed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
|
@@ -129,6 +129,7 @@ static const GDebugKey clutter_debug_keys[] = {
|
||||
|
||||
static const GDebugKey clutter_pick_debug_keys[] = {
|
||||
{ "nop-picking", CLUTTER_DEBUG_NOP_PICKING },
|
||||
{ "dump-pick-buffers", CLUTTER_DEBUG_DUMP_PICK_BUFFERS },
|
||||
};
|
||||
|
||||
static const GDebugKey clutter_paint_debug_keys[] = {
|
||||
@@ -400,6 +401,125 @@ clutter_disable_accessibility (void)
|
||||
clutter_enable_accessibility = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_id_to_color (guint id_,
|
||||
ClutterColor *col)
|
||||
{
|
||||
ClutterMainContext *ctx;
|
||||
gint red, green, blue;
|
||||
|
||||
ctx = _clutter_context_get_default ();
|
||||
|
||||
if (ctx->fb_g_mask == 0)
|
||||
{
|
||||
/* Figure out framebuffer masks used for pick */
|
||||
cogl_get_bitmasks (&ctx->fb_r_mask,
|
||||
&ctx->fb_g_mask,
|
||||
&ctx->fb_b_mask, NULL);
|
||||
|
||||
ctx->fb_r_mask_used = ctx->fb_r_mask;
|
||||
ctx->fb_g_mask_used = ctx->fb_g_mask;
|
||||
ctx->fb_b_mask_used = ctx->fb_b_mask;
|
||||
|
||||
/* XXX - describe what "fuzzy picking" is */
|
||||
if (clutter_use_fuzzy_picking)
|
||||
{
|
||||
ctx->fb_r_mask_used--;
|
||||
ctx->fb_g_mask_used--;
|
||||
ctx->fb_b_mask_used--;
|
||||
}
|
||||
}
|
||||
|
||||
/* compute the numbers we'll store in the components */
|
||||
red = (id_ >> (ctx->fb_g_mask_used+ctx->fb_b_mask_used))
|
||||
& (0xff >> (8-ctx->fb_r_mask_used));
|
||||
green = (id_ >> ctx->fb_b_mask_used)
|
||||
& (0xff >> (8-ctx->fb_g_mask_used));
|
||||
blue = (id_)
|
||||
& (0xff >> (8-ctx->fb_b_mask_used));
|
||||
|
||||
/* shift left bits a bit and add one, this circumvents
|
||||
* at least some potential rounding errors in GL/GLES
|
||||
* driver / hw implementation.
|
||||
*/
|
||||
if (ctx->fb_r_mask_used != ctx->fb_r_mask)
|
||||
red = red * 2;
|
||||
if (ctx->fb_g_mask_used != ctx->fb_g_mask)
|
||||
green = green * 2;
|
||||
if (ctx->fb_b_mask_used != ctx->fb_b_mask)
|
||||
blue = blue * 2;
|
||||
|
||||
/* shift up to be full 8bit values */
|
||||
red = (red << (8 - ctx->fb_r_mask)) | (0x7f >> (ctx->fb_r_mask_used));
|
||||
green = (green << (8 - ctx->fb_g_mask)) | (0x7f >> (ctx->fb_g_mask_used));
|
||||
blue = (blue << (8 - ctx->fb_b_mask)) | (0x7f >> (ctx->fb_b_mask_used));
|
||||
|
||||
col->red = red;
|
||||
col->green = green;
|
||||
col->blue = blue;
|
||||
col->alpha = 0xff;
|
||||
|
||||
/* XXX: We rotate the nibbles of the colors here so that there is a
|
||||
* visible variation between colors of sequential actor identifiers;
|
||||
* otherwise pick buffers dumped to an image will pretty much just look
|
||||
* black.
|
||||
*/
|
||||
if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
|
||||
{
|
||||
col->red = (col->red << 4) | (col->red >> 4);
|
||||
col->green = (col->green << 4) | (col->green >> 4);
|
||||
col->blue = (col->blue << 4) | (col->blue >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
guint
|
||||
_clutter_pixel_to_id (guchar pixel[4])
|
||||
{
|
||||
ClutterMainContext *ctx;
|
||||
gint red, green, blue;
|
||||
guint retval;
|
||||
|
||||
ctx = _clutter_context_get_default ();
|
||||
|
||||
/* reduce the pixel components to the number of bits actually used of the
|
||||
* 8bits.
|
||||
*/
|
||||
if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
|
||||
{
|
||||
guchar tmp;
|
||||
|
||||
/* XXX: In _clutter_id_to_color we rotated the nibbles of the colors so
|
||||
* that there is a visible variation between colors of sequential actor
|
||||
* identifiers (otherwise pick buffers dumped to an image will pretty
|
||||
* much just look black.) Here we reverse that rotation.
|
||||
*/
|
||||
tmp = ((pixel[0] << 4) | (pixel[0] >> 4));
|
||||
red = tmp >> (8 - ctx->fb_r_mask);
|
||||
tmp = ((pixel[1] << 4) | (pixel[1] >> 4));
|
||||
green = tmp >> (8 - ctx->fb_g_mask);
|
||||
tmp = ((pixel[2] << 4) | (pixel[2] >> 4));
|
||||
blue = tmp >> (8 - ctx->fb_b_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
red = pixel[0] >> (8 - ctx->fb_r_mask);
|
||||
green = pixel[1] >> (8 - ctx->fb_g_mask);
|
||||
blue = pixel[2] >> (8 - ctx->fb_b_mask);
|
||||
}
|
||||
|
||||
/* divide potentially by two if 'fuzzy' */
|
||||
red = red >> (ctx->fb_r_mask - ctx->fb_r_mask_used);
|
||||
green = green >> (ctx->fb_g_mask - ctx->fb_g_mask_used);
|
||||
blue = blue >> (ctx->fb_b_mask - ctx->fb_b_mask_used);
|
||||
|
||||
/* combine the correct per component values into the final id */
|
||||
retval = blue
|
||||
+ (green << ctx->fb_b_mask_used)
|
||||
+ (red << (ctx->fb_b_mask_used + ctx->fb_g_mask_used));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static CoglPangoFontMap *
|
||||
clutter_context_get_pango_fontmap (void)
|
||||
{
|
||||
@@ -1159,8 +1279,8 @@ clutter_get_option_group (void)
|
||||
context = _clutter_context_get_default ();
|
||||
|
||||
group = g_option_group_new ("clutter",
|
||||
"Clutter Options",
|
||||
"Show Clutter Options",
|
||||
_("Clutter Options"),
|
||||
_("Show Clutter Options"),
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
@@ -1581,19 +1701,37 @@ static inline void
|
||||
emit_pointer_event (ClutterEvent *event,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
|
||||
if (_clutter_event_process_filters (event))
|
||||
return;
|
||||
|
||||
if (device != NULL && device->pointer_grab_actor != NULL)
|
||||
clutter_actor_event (device->pointer_grab_actor, event, FALSE);
|
||||
if (context->pointer_grab_actor == NULL &&
|
||||
(device == NULL || device->pointer_grab_actor == NULL))
|
||||
{
|
||||
/* no grab, time to capture and bubble */
|
||||
emit_event_chain (event);
|
||||
}
|
||||
else
|
||||
emit_event_chain (event);
|
||||
{
|
||||
if (context->pointer_grab_actor != NULL)
|
||||
{
|
||||
/* global grab */
|
||||
clutter_actor_event (context->pointer_grab_actor, event, FALSE);
|
||||
}
|
||||
else if (device != NULL && device->pointer_grab_actor != NULL)
|
||||
{
|
||||
/* per device grab */
|
||||
clutter_actor_event (device->pointer_grab_actor, event, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
emit_crossing_event (ClutterEvent *event,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
||||
ClutterActor *grab_actor = NULL;
|
||||
|
||||
@@ -1607,7 +1745,9 @@ emit_crossing_event (ClutterEvent *event,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (device != NULL && device->pointer_grab_actor != NULL)
|
||||
if (context->pointer_grab_actor != NULL)
|
||||
grab_actor = context->pointer_grab_actor;
|
||||
else if (device != NULL && device->pointer_grab_actor != NULL)
|
||||
grab_actor = device->pointer_grab_actor;
|
||||
}
|
||||
|
||||
@@ -1648,13 +1788,30 @@ static inline void
|
||||
emit_keyboard_event (ClutterEvent *event,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
|
||||
if (_clutter_event_process_filters (event))
|
||||
return;
|
||||
|
||||
if (device != NULL && device->keyboard_grab_actor != NULL)
|
||||
clutter_actor_event (device->keyboard_grab_actor, event, FALSE);
|
||||
if (context->keyboard_grab_actor == NULL &&
|
||||
(device == NULL || device->keyboard_grab_actor == NULL))
|
||||
{
|
||||
/* no grab, time to capture and bubble */
|
||||
emit_event_chain (event);
|
||||
}
|
||||
else
|
||||
emit_event_chain (event);
|
||||
{
|
||||
if (context->keyboard_grab_actor != NULL)
|
||||
{
|
||||
/* global key grab */
|
||||
clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
|
||||
}
|
||||
else if (device != NULL && device->keyboard_grab_actor != NULL)
|
||||
{
|
||||
/* per-device key grab */
|
||||
clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -1828,8 +1985,7 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
|
||||
case CLUTTER_MOTION:
|
||||
#ifdef CLUTTER_WINDOWING_X11
|
||||
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) &&
|
||||
!(event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC))
|
||||
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
||||
{
|
||||
if (_clutter_is_input_pointer_a11y_enabled (device))
|
||||
{
|
||||
@@ -1853,7 +2009,15 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
if (_clutter_event_process_filters (event))
|
||||
break;
|
||||
|
||||
if (device != NULL && device->pointer_grab_actor != NULL)
|
||||
/* global grabs */
|
||||
if (context->pointer_grab_actor != NULL)
|
||||
{
|
||||
clutter_actor_event (context->pointer_grab_actor,
|
||||
event,
|
||||
FALSE);
|
||||
break;
|
||||
}
|
||||
else if (device != NULL && device->pointer_grab_actor != NULL)
|
||||
{
|
||||
clutter_actor_event (device->pointer_grab_actor,
|
||||
event,
|
||||
@@ -2216,6 +2380,332 @@ clutter_get_default_frame_rate (void)
|
||||
return context->frame_rate;
|
||||
}
|
||||
|
||||
static void
|
||||
on_grab_actor_destroy (ClutterActor *actor,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
if (device == NULL)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
|
||||
if (context->pointer_grab_actor == actor)
|
||||
clutter_ungrab_pointer ();
|
||||
|
||||
if (context->keyboard_grab_actor == actor)
|
||||
clutter_ungrab_keyboard ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (device->device_type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
device->pointer_grab_actor = NULL;
|
||||
break;
|
||||
|
||||
case CLUTTER_KEYBOARD_DEVICE:
|
||||
device->keyboard_grab_actor = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_grab_pointer:
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Grabs pointer events, after the grab is done all pointer related events
|
||||
* (press, motion, release, enter, leave and scroll) are delivered to this
|
||||
* actor directly without passing through both capture and bubble phases of
|
||||
* the event delivery chain. The source set in the event will be the actor
|
||||
* that would have received the event if the pointer grab was not in effect.
|
||||
*
|
||||
* Grabs completely override the entire event delivery chain
|
||||
* done by Clutter. Pointer grabs should only be used as a last resource;
|
||||
* using the #ClutterActor::captured-event signal should always be the
|
||||
* preferred way to intercept event delivery to reactive actors.
|
||||
*
|
||||
* This function should rarely be used.
|
||||
*
|
||||
* If a grab is required, you are strongly encouraged to use a specific
|
||||
* input device by calling clutter_input_device_grab().
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
void
|
||||
clutter_grab_pointer (ClutterActor *actor)
|
||||
{
|
||||
ClutterMainContext *context;
|
||||
|
||||
g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
context = _clutter_context_get_default ();
|
||||
|
||||
if (context->pointer_grab_actor == actor)
|
||||
return;
|
||||
|
||||
if (context->pointer_grab_actor != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (context->pointer_grab_actor,
|
||||
G_CALLBACK (on_grab_actor_destroy),
|
||||
NULL);
|
||||
context->pointer_grab_actor = NULL;
|
||||
}
|
||||
|
||||
if (actor != NULL)
|
||||
{
|
||||
context->pointer_grab_actor = actor;
|
||||
|
||||
g_signal_connect (context->pointer_grab_actor, "destroy",
|
||||
G_CALLBACK (on_grab_actor_destroy),
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_device_grab:
|
||||
* @device: a #ClutterInputDevice
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Acquires a grab on @actor for the given @device.
|
||||
*
|
||||
* Any event coming from @device will be delivered to @actor, bypassing
|
||||
* the usual event delivery mechanism, until the grab is released by
|
||||
* calling clutter_input_device_ungrab().
|
||||
*
|
||||
* The grab is client-side: even if the windowing system used by the Clutter
|
||||
* backend has the concept of "device grabs", Clutter will not use them.
|
||||
*
|
||||
* Only #ClutterInputDevice of types %CLUTTER_POINTER_DEVICE and
|
||||
* %CLUTTER_KEYBOARD_DEVICE can hold a grab.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_input_device_grab (ClutterInputDevice *device,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterActor **grab_actor;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
switch (device->device_type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
case CLUTTER_TABLET_DEVICE:
|
||||
grab_actor = &(device->pointer_grab_actor);
|
||||
break;
|
||||
|
||||
case CLUTTER_KEYBOARD_DEVICE:
|
||||
grab_actor = &(device->keyboard_grab_actor);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_critical ("Only pointer and keyboard devices can grab an actor");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*grab_actor != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (*grab_actor,
|
||||
G_CALLBACK (on_grab_actor_destroy),
|
||||
device);
|
||||
}
|
||||
|
||||
*grab_actor = actor;
|
||||
|
||||
g_signal_connect (*grab_actor,
|
||||
"destroy",
|
||||
G_CALLBACK (on_grab_actor_destroy),
|
||||
device);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_device_ungrab:
|
||||
* @device: a #ClutterInputDevice
|
||||
*
|
||||
* Releases the grab on the @device, if one is in place.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_input_device_ungrab (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterActor **grab_actor;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
||||
|
||||
switch (device->device_type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
case CLUTTER_TABLET_DEVICE:
|
||||
grab_actor = &(device->pointer_grab_actor);
|
||||
break;
|
||||
|
||||
case CLUTTER_KEYBOARD_DEVICE:
|
||||
grab_actor = &(device->keyboard_grab_actor);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (*grab_actor == NULL)
|
||||
return;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (*grab_actor,
|
||||
G_CALLBACK (on_grab_actor_destroy),
|
||||
device);
|
||||
|
||||
*grab_actor = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_device_get_grabbed_actor:
|
||||
* @device: a #ClutterInputDevice
|
||||
*
|
||||
* Retrieves a pointer to the #ClutterActor currently grabbing all
|
||||
* the events coming from @device.
|
||||
*
|
||||
* Return value: (transfer none): a #ClutterActor, or %NULL
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_input_device_get_grabbed_actor (ClutterInputDevice *device)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
|
||||
|
||||
switch (device->device_type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
return device->pointer_grab_actor;
|
||||
|
||||
case CLUTTER_KEYBOARD_DEVICE:
|
||||
return device->keyboard_grab_actor;
|
||||
|
||||
default:
|
||||
g_critical ("Only pointer and keyboard devices can grab an actor");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_ungrab_pointer:
|
||||
*
|
||||
* Removes an existing grab of the pointer.
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
void
|
||||
clutter_ungrab_pointer (void)
|
||||
{
|
||||
clutter_grab_pointer (NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_get_pointer_grab:
|
||||
*
|
||||
* Queries the current pointer grab of clutter.
|
||||
*
|
||||
* Return value: (transfer none): the actor currently holding the pointer grab, or NULL if there is no grab.
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_get_pointer_grab (void)
|
||||
{
|
||||
ClutterMainContext *context;
|
||||
context = _clutter_context_get_default ();
|
||||
|
||||
return context->pointer_grab_actor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* clutter_grab_keyboard:
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Grabs keyboard events, after the grab is done keyboard
|
||||
* events (#ClutterActor::key-press-event and #ClutterActor::key-release-event)
|
||||
* are delivered to this actor directly. The source set in the event will be
|
||||
* the actor that would have received the event if the keyboard grab was not
|
||||
* in effect.
|
||||
*
|
||||
* Like pointer grabs, keyboard grabs should only be used as a last
|
||||
* resource.
|
||||
*
|
||||
* See also clutter_stage_set_key_focus() and clutter_actor_grab_key_focus()
|
||||
* to perform a "soft" key grab and assign key focus to a specific actor.
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
void
|
||||
clutter_grab_keyboard (ClutterActor *actor)
|
||||
{
|
||||
ClutterMainContext *context;
|
||||
|
||||
g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
context = _clutter_context_get_default ();
|
||||
|
||||
if (context->keyboard_grab_actor == actor)
|
||||
return;
|
||||
|
||||
if (context->keyboard_grab_actor != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (context->keyboard_grab_actor,
|
||||
G_CALLBACK (on_grab_actor_destroy),
|
||||
NULL);
|
||||
context->keyboard_grab_actor = NULL;
|
||||
}
|
||||
|
||||
if (actor != NULL)
|
||||
{
|
||||
context->keyboard_grab_actor = actor;
|
||||
|
||||
g_signal_connect (context->keyboard_grab_actor, "destroy",
|
||||
G_CALLBACK (on_grab_actor_destroy),
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_ungrab_keyboard:
|
||||
*
|
||||
* Removes an existing grab of the keyboard.
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
void
|
||||
clutter_ungrab_keyboard (void)
|
||||
{
|
||||
clutter_grab_keyboard (NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_get_keyboard_grab:
|
||||
*
|
||||
* Queries the current keyboard grab of clutter.
|
||||
*
|
||||
* Return value: (transfer none): the actor currently holding the keyboard grab, or NULL if there is no grab.
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_get_keyboard_grab (void)
|
||||
{
|
||||
ClutterMainContext *context;
|
||||
|
||||
context = _clutter_context_get_default ();
|
||||
|
||||
return context->keyboard_grab_actor;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_get_font_map:
|
||||
*
|
||||
|
@@ -146,6 +146,19 @@ guint clutter_threads_add_repaint_func_full (ClutterRepaintF
|
||||
CLUTTER_EXPORT
|
||||
void clutter_threads_remove_repaint_func (guint handle_id);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_grab_pointer (ClutterActor *actor);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_ungrab_pointer (void);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_get_pointer_grab (void);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_grab_keyboard (ClutterActor *actor);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_ungrab_keyboard (void);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_get_keyboard_grab (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
PangoFontMap * clutter_get_font_map (void);
|
||||
|
||||
|
@@ -12,14 +12,17 @@ BOOLEAN:OBJECT,FLOAT,FLOAT
|
||||
BOXED:UINT,UINT
|
||||
DOUBLE:VOID
|
||||
UINT:VOID
|
||||
VOID:BOOLEAN
|
||||
VOID:BOXED
|
||||
VOID:BOXED,FLAGS
|
||||
VOID:INT
|
||||
VOID:INT64,INT64,FLOAT,BOOLEAN
|
||||
VOID:INT,INT
|
||||
VOID:INT,POINTER
|
||||
VOID:FLOAT,FLOAT
|
||||
VOID:INT,INT,INT,INT
|
||||
VOID:OBJECT
|
||||
VOID:OBJECT,FLAGS
|
||||
VOID:OBJECT,FLAGS,BOOLEAN
|
||||
VOID:OBJECT,FLAGS,UINT
|
||||
VOID:OBJECT,FLOAT,FLOAT
|
||||
VOID:OBJECT,FLOAT,FLOAT,FLAGS
|
||||
@@ -27,9 +30,12 @@ VOID:OBJECT,OBJECT
|
||||
VOID:OBJECT,PARAM
|
||||
VOID:OBJECT,POINTER
|
||||
VOID:OBJECT,UINT
|
||||
VOID:POINTER
|
||||
VOID:STRING,BOOLEAN
|
||||
VOID:STRING,BOOLEAN,BOOLEAN
|
||||
VOID:STRING,INT
|
||||
VOID:UINT
|
||||
VOID:UINT,STRING,UINT
|
||||
VOID:UINT,UINT
|
||||
VOID:VOID
|
||||
VOID:STRING,INT,POINTER
|
||||
|
@@ -26,15 +26,10 @@
|
||||
#define __CLUTTER_H_INSIDE__
|
||||
|
||||
#include "clutter-backend.h"
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-event-private.h"
|
||||
#include "clutter-input-pointer-a11y-private.h"
|
||||
#include "clutter-macros.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-stage-view.h"
|
||||
#include "cogl/clutter-stage-cogl.h"
|
||||
#include "clutter/x11/clutter-backend-x11.h"
|
||||
#include "x11/clutter-stage-x11.h"
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_set_custom_backend_func (ClutterBackend *(* func) (void));
|
||||
|
@@ -138,6 +138,8 @@ G_GNUC_INTERNAL
|
||||
ClutterPaintNode * clutter_paint_node_get_last_child (ClutterPaintNode *node);
|
||||
G_GNUC_INTERNAL
|
||||
ClutterPaintNode * clutter_paint_node_get_parent (ClutterPaintNode *node);
|
||||
G_GNUC_INTERNAL
|
||||
CoglFramebuffer * clutter_paint_node_get_framebuffer (ClutterPaintNode *node);
|
||||
|
||||
#define CLUTTER_TYPE_LAYER_NODE (_clutter_layer_node_get_type ())
|
||||
#define CLUTTER_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYER_NODE, ClutterLayerNode))
|
||||
|
@@ -1194,15 +1194,6 @@ clutter_paint_node_get_root (ClutterPaintNode *node)
|
||||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_paint_node_get_framebuffer:
|
||||
* @node: a #ClutterPaintNode
|
||||
*
|
||||
* Retrieves the #CoglFramebuffer that @node will draw
|
||||
* into.
|
||||
*
|
||||
* Returns: (transfer none): a #CoglFramebuffer
|
||||
*/
|
||||
CoglFramebuffer *
|
||||
clutter_paint_node_get_framebuffer (ClutterPaintNode *node)
|
||||
{
|
||||
|
@@ -56,9 +56,6 @@ CLUTTER_EXPORT
|
||||
void clutter_paint_node_set_name (ClutterPaintNode *node,
|
||||
const char *name);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
CoglFramebuffer * clutter_paint_node_get_framebuffer (ClutterPaintNode *node);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_paint_node_add_child (ClutterPaintNode *node,
|
||||
ClutterPaintNode *child);
|
||||
|
@@ -579,7 +579,8 @@ clutter_pan_action_class_init (ClutterPanActionClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterPanActionClass, pan_stopped),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
}
|
||||
|
@@ -85,6 +85,7 @@ typedef struct _ClutterVertex4 ClutterVertex4;
|
||||
/* keep this for source compatibility with clutter */
|
||||
#define P_(String) (String)
|
||||
#define N_(String) (String)
|
||||
#define _(String) (String)
|
||||
|
||||
/* This is a replacement for the nearbyint function which always rounds to the
|
||||
* nearest integer. nearbyint is apparently a C99 function so it might not
|
||||
@@ -141,6 +142,10 @@ struct _ClutterMainContext
|
||||
/* default FPS; this is only used if we cannot sync to vblank */
|
||||
guint frame_rate;
|
||||
|
||||
/* actors with a grab on all devices */
|
||||
ClutterActor *pointer_grab_actor;
|
||||
ClutterActor *keyboard_grab_actor;
|
||||
|
||||
/* fb bit masks for col<->id mapping in picking */
|
||||
gint fb_r_mask;
|
||||
gint fb_g_mask;
|
||||
@@ -181,9 +186,7 @@ typedef struct
|
||||
gboolean _clutter_threads_dispatch (gpointer data);
|
||||
void _clutter_threads_dispatch_free (gpointer data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_threads_acquire_lock (void);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_threads_release_lock (void);
|
||||
|
||||
ClutterMainContext * _clutter_context_get_default (void);
|
||||
@@ -199,7 +202,11 @@ gboolean _clutter_feature_init (GError **error);
|
||||
gboolean _clutter_diagnostic_enabled (void);
|
||||
void _clutter_diagnostic_message (const char *fmt, ...) G_GNUC_PRINTF (1, 2);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
/* Picking code */
|
||||
guint _clutter_pixel_to_id (guchar pixel[4]);
|
||||
void _clutter_id_to_color (guint id,
|
||||
ClutterColor *col);
|
||||
|
||||
void _clutter_set_sync_to_vblank (gboolean sync_to_vblank);
|
||||
|
||||
/* use this function as the accumulator if you have a signal with
|
||||
@@ -288,7 +295,6 @@ gboolean _clutter_util_matrix_decompose (const ClutterMatrix *src,
|
||||
ClutterVertex *translate_p,
|
||||
ClutterVertex4 *perspective_p);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
PangoDirection _clutter_pango_unichar_direction (gunichar ch);
|
||||
|
||||
PangoDirection _clutter_pango_find_base_dir (const gchar *text,
|
||||
|
@@ -134,7 +134,8 @@ clutter_stage_manager_class_init (ClutterStageManagerClass *klass)
|
||||
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterStageManagerClass, stage_added),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_STAGE);
|
||||
/**
|
||||
@@ -152,7 +153,8 @@ clutter_stage_manager_class_init (ClutterStageManagerClass *klass)
|
||||
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterStageManagerClass, stage_removed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_STAGE);
|
||||
}
|
||||
|
@@ -41,11 +41,8 @@ void _clutter_stage_paint_view (ClutterStage
|
||||
const cairo_rectangle_int_t *clip);
|
||||
|
||||
void _clutter_stage_emit_after_paint (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_stage_set_window (ClutterStage *stage,
|
||||
ClutterStageWindow *stage_window);
|
||||
CLUTTER_EXPORT
|
||||
ClutterStageWindow *_clutter_stage_get_window (ClutterStage *stage);
|
||||
void _clutter_stage_get_projection_matrix (ClutterStage *stage,
|
||||
CoglMatrix *projection);
|
||||
@@ -67,7 +64,6 @@ void _clutter_stage_maybe_relayout (ClutterActor
|
||||
gboolean _clutter_stage_needs_update (ClutterStage *stage);
|
||||
gboolean _clutter_stage_do_update (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_stage_queue_event (ClutterStage *stage,
|
||||
ClutterEvent *event,
|
||||
gboolean copy_event);
|
||||
@@ -79,15 +75,6 @@ gint64 _clutter_stage_get_update_time (ClutterStage *stage);
|
||||
void _clutter_stage_clear_update_time (ClutterStage *stage);
|
||||
gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage);
|
||||
|
||||
void clutter_stage_log_pick (ClutterStage *stage,
|
||||
const ClutterPoint *vertices,
|
||||
ClutterActor *actor);
|
||||
|
||||
void clutter_stage_push_pick_clip (ClutterStage *stage,
|
||||
const ClutterPoint *vertices);
|
||||
|
||||
void clutter_stage_pop_pick_clip (ClutterStage *stage);
|
||||
|
||||
ClutterActor *_clutter_stage_do_pick (ClutterStage *stage,
|
||||
gint x,
|
||||
gint y,
|
||||
@@ -106,6 +93,13 @@ void _clutter_stage_queue_redraw_entry_invalidate (Clut
|
||||
|
||||
CoglFramebuffer *_clutter_stage_get_active_framebuffer (ClutterStage *stage);
|
||||
|
||||
gint32 _clutter_stage_acquire_pick_id (ClutterStage *stage,
|
||||
ClutterActor *actor);
|
||||
void _clutter_stage_release_pick_id (ClutterStage *stage,
|
||||
gint32 pick_id);
|
||||
ClutterActor * _clutter_stage_get_actor_by_pick_id (ClutterStage *stage,
|
||||
gint32 pick_id);
|
||||
|
||||
void _clutter_stage_add_pointer_drag_actor (ClutterStage *stage,
|
||||
ClutterInputDevice *device,
|
||||
ClutterActor *actor);
|
||||
@@ -122,11 +116,8 @@ ClutterActor * _clutter_stage_get_touch_drag_actor (ClutterStage *st
|
||||
void _clutter_stage_remove_touch_drag_actor (ClutterStage *stage,
|
||||
ClutterEventSequence *sequence);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterStageState _clutter_stage_get_state (ClutterStage *stage);
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_stage_is_activated (ClutterStage *stage);
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_stage_update_state (ClutterStage *stage,
|
||||
ClutterStageState unset_state,
|
||||
ClutterStageState set_state);
|
||||
|
@@ -275,6 +275,24 @@ _clutter_stage_window_redraw (ClutterStageWindow *window)
|
||||
iface->redraw (window);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_clutter_stage_window_get_dirty_pixel (ClutterStageWindow *window,
|
||||
ClutterStageView *view,
|
||||
int *x, int *y)
|
||||
{
|
||||
ClutterStageWindowInterface *iface;
|
||||
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
|
||||
|
||||
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
if (iface->get_dirty_pixel)
|
||||
iface->get_dirty_pixel (window, view, x, y);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_stage_window_can_clip_redraws (ClutterStageWindow *window)
|
||||
{
|
||||
|
@@ -64,6 +64,10 @@ struct _ClutterStageWindowInterface
|
||||
|
||||
void (* redraw) (ClutterStageWindow *stage_window);
|
||||
|
||||
void (* get_dirty_pixel) (ClutterStageWindow *stage_window,
|
||||
ClutterStageView *view,
|
||||
int *x, int *y);
|
||||
|
||||
gboolean (* can_clip_redraws) (ClutterStageWindow *stage_window);
|
||||
|
||||
GList *(* get_views) (ClutterStageWindow *stage_window);
|
||||
@@ -88,7 +92,6 @@ void _clutter_stage_window_hide (ClutterStageWin
|
||||
void _clutter_stage_window_resize (ClutterStageWindow *window,
|
||||
gint width,
|
||||
gint height);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_stage_window_get_geometry (ClutterStageWindow *window,
|
||||
cairo_rectangle_int_t *geometry);
|
||||
void _clutter_stage_window_schedule_update (ClutterStageWindow *window,
|
||||
@@ -108,6 +111,10 @@ void _clutter_stage_window_set_accept_focus (ClutterStageWin
|
||||
|
||||
void _clutter_stage_window_redraw (ClutterStageWindow *window);
|
||||
|
||||
void _clutter_stage_window_get_dirty_pixel (ClutterStageWindow *window,
|
||||
ClutterStageView *view,
|
||||
int *x, int *y);
|
||||
|
||||
gboolean _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window);
|
||||
|
||||
GList * _clutter_stage_window_get_views (ClutterStageWindow *window);
|
||||
|
@@ -105,19 +105,6 @@ struct _ClutterStageQueueRedrawEntry
|
||||
ClutterPaintVolume clip;
|
||||
};
|
||||
|
||||
typedef struct _PickRecord
|
||||
{
|
||||
ClutterPoint vertex[4];
|
||||
ClutterActor *actor;
|
||||
int clip_stack_top;
|
||||
} PickRecord;
|
||||
|
||||
typedef struct _PickClipRecord
|
||||
{
|
||||
int prev;
|
||||
ClutterPoint vertex[4];
|
||||
} PickClipRecord;
|
||||
|
||||
struct _ClutterStagePrivate
|
||||
{
|
||||
/* the stage implementation */
|
||||
@@ -151,11 +138,7 @@ struct _ClutterStagePrivate
|
||||
GTimer *fps_timer;
|
||||
gint32 timer_n_frames;
|
||||
|
||||
GArray *pick_stack;
|
||||
GArray *pick_clip_stack;
|
||||
int pick_clip_stack_top;
|
||||
gboolean pick_stack_frozen;
|
||||
ClutterPickMode cached_pick_mode;
|
||||
ClutterIDPool *pick_id_pool;
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
gulong redraw_count;
|
||||
@@ -340,211 +323,6 @@ clutter_stage_get_preferred_height (ClutterActor *self,
|
||||
*natural_height_p = geom.height;
|
||||
}
|
||||
|
||||
static void
|
||||
add_pick_stack_weak_refs (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
int i;
|
||||
|
||||
if (priv->pick_stack_frozen)
|
||||
return;
|
||||
|
||||
for (i = 0; i < priv->pick_stack->len; i++)
|
||||
{
|
||||
PickRecord *rec = &g_array_index (priv->pick_stack, PickRecord, i);
|
||||
|
||||
if (rec->actor)
|
||||
g_object_add_weak_pointer (G_OBJECT (rec->actor),
|
||||
(gpointer) &rec->actor);
|
||||
}
|
||||
|
||||
priv->pick_stack_frozen = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_pick_stack_weak_refs (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
int i;
|
||||
|
||||
if (!priv->pick_stack_frozen)
|
||||
return;
|
||||
|
||||
for (i = 0; i < priv->pick_stack->len; i++)
|
||||
{
|
||||
PickRecord *rec = &g_array_index (priv->pick_stack, PickRecord, i);
|
||||
|
||||
if (rec->actor)
|
||||
g_object_remove_weak_pointer (G_OBJECT (rec->actor),
|
||||
(gpointer) &rec->actor);
|
||||
}
|
||||
|
||||
priv->pick_stack_frozen = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_stage_clear_pick_stack (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
remove_pick_stack_weak_refs (stage);
|
||||
g_array_set_size (priv->pick_stack, 0);
|
||||
g_array_set_size (priv->pick_clip_stack, 0);
|
||||
priv->pick_clip_stack_top = -1;
|
||||
priv->cached_pick_mode = CLUTTER_PICK_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_log_pick (ClutterStage *stage,
|
||||
const ClutterPoint *vertices,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterStagePrivate *priv;
|
||||
PickRecord rec;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
g_return_if_fail (actor != NULL);
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
g_assert (!priv->pick_stack_frozen);
|
||||
|
||||
memcpy (rec.vertex, vertices, 4 * sizeof (ClutterPoint));
|
||||
rec.actor = actor;
|
||||
rec.clip_stack_top = priv->pick_clip_stack_top;
|
||||
|
||||
g_array_append_val (priv->pick_stack, rec);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_push_pick_clip (ClutterStage *stage,
|
||||
const ClutterPoint *vertices)
|
||||
{
|
||||
ClutterStagePrivate *priv;
|
||||
PickClipRecord clip;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
g_assert (!priv->pick_stack_frozen);
|
||||
|
||||
clip.prev = priv->pick_clip_stack_top;
|
||||
memcpy (clip.vertex, vertices, 4 * sizeof (ClutterPoint));
|
||||
|
||||
g_array_append_val (priv->pick_clip_stack, clip);
|
||||
priv->pick_clip_stack_top = priv->pick_clip_stack->len - 1;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_pop_pick_clip (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv;
|
||||
const PickClipRecord *top;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
g_assert (!priv->pick_stack_frozen);
|
||||
g_assert (priv->pick_clip_stack_top >= 0);
|
||||
|
||||
/* Individual elements of pick_clip_stack are not freed. This is so they
|
||||
* can be shared as part of a tree of different stacks used by different
|
||||
* actors in the pick_stack. The whole pick_clip_stack does however get
|
||||
* freed later in _clutter_stage_clear_pick_stack.
|
||||
*/
|
||||
|
||||
top = &g_array_index (priv->pick_clip_stack,
|
||||
PickClipRecord,
|
||||
priv->pick_clip_stack_top);
|
||||
|
||||
priv->pick_clip_stack_top = top->prev;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_quadrilateral_axis_aligned_rectangle (const ClutterPoint *vertices)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (!G_APPROX_VALUE (vertices[i].x,
|
||||
vertices[(i + 1) % 4].x,
|
||||
FLT_EPSILON) &&
|
||||
!G_APPROX_VALUE (vertices[i].y,
|
||||
vertices[(i + 1) % 4].y,
|
||||
FLT_EPSILON))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_inside_axis_aligned_rectangle (const ClutterPoint *point,
|
||||
const ClutterPoint *vertices)
|
||||
{
|
||||
float min_x = FLT_MAX;
|
||||
float max_x = FLT_MIN;
|
||||
float min_y = FLT_MAX;
|
||||
float max_y = FLT_MIN;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
min_x = MIN (min_x, vertices[i].x);
|
||||
min_y = MIN (min_y, vertices[i].y);
|
||||
max_x = MAX (max_x, vertices[i].x);
|
||||
max_y = MAX (max_y, vertices[i].y);
|
||||
}
|
||||
|
||||
return (point->x >= min_x &&
|
||||
point->y >= min_y &&
|
||||
point->x < max_x &&
|
||||
point->y < max_y);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_inside_input_region (const ClutterPoint *point,
|
||||
const ClutterPoint *vertices)
|
||||
{
|
||||
|
||||
if (is_quadrilateral_axis_aligned_rectangle (vertices))
|
||||
return is_inside_axis_aligned_rectangle (point, vertices);
|
||||
else
|
||||
return clutter_point_inside_quadrilateral (point, vertices);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pick_record_contains_pixel (ClutterStage *stage,
|
||||
const PickRecord *rec,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
const ClutterPoint point = CLUTTER_POINT_INIT (x, y);
|
||||
ClutterStagePrivate *priv;
|
||||
int clip_index;
|
||||
|
||||
if (!is_inside_input_region (&point, rec->vertex))
|
||||
return FALSE;
|
||||
|
||||
priv = stage->priv;
|
||||
clip_index = rec->clip_stack_top;
|
||||
while (clip_index >= 0)
|
||||
{
|
||||
const PickClipRecord *clip = &g_array_index (priv->pick_clip_stack,
|
||||
PickClipRecord,
|
||||
clip_index);
|
||||
|
||||
if (!is_inside_input_region (&point, clip->vertex))
|
||||
return FALSE;
|
||||
|
||||
clip_index = clip->prev;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
queue_full_redraw (ClutterStage *stage)
|
||||
{
|
||||
@@ -852,12 +630,6 @@ clutter_stage_do_paint_view (ClutterStage *stage,
|
||||
float viewport[4];
|
||||
cairo_rectangle_int_t geom;
|
||||
|
||||
/* Any mode of painting/picking invalidates the pick cache, unless we're
|
||||
* in the middle of building it. So we reset the cached flag but don't
|
||||
* completely clear the pick stack.
|
||||
*/
|
||||
priv->cached_pick_mode = CLUTTER_PICK_NONE;
|
||||
|
||||
_clutter_stage_window_get_geometry (priv->impl, &geom);
|
||||
|
||||
viewport[0] = priv->viewport[0];
|
||||
@@ -1103,6 +875,15 @@ _clutter_stage_queue_event (ClutterStage *stage,
|
||||
if (copy_event)
|
||||
event = clutter_event_copy (event);
|
||||
|
||||
g_queue_push_tail (priv->event_queue, event);
|
||||
|
||||
if (first_event)
|
||||
{
|
||||
ClutterMasterClock *master_clock = _clutter_master_clock_get_default ();
|
||||
_clutter_master_clock_start_running (master_clock);
|
||||
_clutter_stage_schedule_update (stage);
|
||||
}
|
||||
|
||||
/* if needed, update the state of the input device of the event.
|
||||
* we do it here to avoid calling the same code from every backend
|
||||
* event processing function
|
||||
@@ -1123,28 +904,6 @@ _clutter_stage_queue_event (ClutterStage *stage,
|
||||
_clutter_input_device_set_state (device, event_state);
|
||||
_clutter_input_device_set_time (device, event_time);
|
||||
}
|
||||
|
||||
if (first_event)
|
||||
{
|
||||
gboolean compressible = event->type == CLUTTER_MOTION ||
|
||||
event->type == CLUTTER_TOUCH_UPDATE;
|
||||
|
||||
if (!compressible)
|
||||
{
|
||||
_clutter_process_event (event);
|
||||
clutter_event_free (event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_queue_push_tail (priv->event_queue, event);
|
||||
|
||||
if (first_event)
|
||||
{
|
||||
ClutterMasterClock *master_clock = _clutter_master_clock_get_default ();
|
||||
_clutter_master_clock_start_running (master_clock);
|
||||
_clutter_stage_schedule_update (stage);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -1626,6 +1385,40 @@ clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
read_pixels_to_file (CoglFramebuffer *fb,
|
||||
char *filename_stem,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
guint8 *data;
|
||||
cairo_surface_t *surface;
|
||||
static int read_count = 0;
|
||||
char *filename = g_strdup_printf ("%s-%05d.png",
|
||||
filename_stem,
|
||||
read_count);
|
||||
|
||||
data = g_malloc (4 * width * height);
|
||||
cogl_framebuffer_read_pixels (fb,
|
||||
x, y, width, height,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
data);
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_RGB24,
|
||||
width, height,
|
||||
width * 4);
|
||||
|
||||
cairo_surface_write_to_png (surface, filename);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
g_free (data);
|
||||
g_free (filename);
|
||||
|
||||
read_count++;
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
_clutter_stage_do_pick_on_view (ClutterStage *stage,
|
||||
gint x,
|
||||
@@ -1633,42 +1426,140 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
|
||||
ClutterPickMode mode,
|
||||
ClutterStageView *view)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
ClutterActor *actor = CLUTTER_ACTOR (stage);
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
|
||||
int i;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
ClutterMainContext *context;
|
||||
guchar pixel[4] = { 0xff, 0xff, 0xff, 0xff };
|
||||
CoglColor stage_pick_id;
|
||||
gboolean dither_enabled_save;
|
||||
ClutterActor *retval;
|
||||
gint dirty_x;
|
||||
gint dirty_y;
|
||||
gint read_x;
|
||||
gint read_y;
|
||||
float fb_width, fb_height;
|
||||
float fb_scale;
|
||||
float viewport_offset_x;
|
||||
float viewport_offset_y;
|
||||
|
||||
g_assert (context->pick_mode == CLUTTER_PICK_NONE);
|
||||
priv = stage->priv;
|
||||
|
||||
if (mode != priv->cached_pick_mode)
|
||||
context = _clutter_context_get_default ();
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
fb_width = view_layout.width * fb_scale;
|
||||
fb_height = view_layout.height * fb_scale;
|
||||
cogl_push_framebuffer (fb);
|
||||
|
||||
/* needed for when a context switch happens */
|
||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||
|
||||
/* FIXME: For some reason leaving the cogl clip stack empty causes the
|
||||
* picking to not work at all, so setting it the whole framebuffer content
|
||||
* for now. */
|
||||
cogl_framebuffer_push_scissor_clip (fb, 0, 0,
|
||||
view_layout.width * fb_scale,
|
||||
view_layout.height * fb_scale);
|
||||
|
||||
_clutter_stage_window_get_dirty_pixel (priv->impl, view, &dirty_x, &dirty_y);
|
||||
|
||||
if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
|
||||
{
|
||||
_clutter_stage_clear_pick_stack (stage);
|
||||
|
||||
cogl_push_framebuffer (fb);
|
||||
|
||||
context->pick_mode = mode;
|
||||
clutter_stage_do_paint_view (stage, view, NULL);
|
||||
context->pick_mode = CLUTTER_PICK_NONE;
|
||||
priv->cached_pick_mode = mode;
|
||||
|
||||
cogl_pop_framebuffer ();
|
||||
|
||||
add_pick_stack_weak_refs (stage);
|
||||
CLUTTER_NOTE (PICK, "Pushing pick scissor clip x: %d, y: %d, 1x1",
|
||||
(int) (dirty_x * fb_scale),
|
||||
(int) (dirty_y * fb_scale));
|
||||
cogl_framebuffer_push_scissor_clip (fb, dirty_x * fb_scale, dirty_y * fb_scale, 1, 1);
|
||||
}
|
||||
|
||||
/* Search all "painted" pickable actors from front to back. A linear search
|
||||
* is required, and also performs fine since there is typically only
|
||||
* on the order of dozens of actors in the list (on screen) at a time.
|
||||
*/
|
||||
for (i = priv->pick_stack->len - 1; i >= 0; i--)
|
||||
{
|
||||
const PickRecord *rec = &g_array_index (priv->pick_stack, PickRecord, i);
|
||||
viewport_offset_x = x * fb_scale - dirty_x * fb_scale;
|
||||
viewport_offset_y = y * fb_scale - dirty_y * fb_scale;
|
||||
CLUTTER_NOTE (PICK, "Setting viewport to %f, %f, %f, %f",
|
||||
priv->viewport[0] * fb_scale - viewport_offset_x,
|
||||
priv->viewport[1] * fb_scale - viewport_offset_y,
|
||||
priv->viewport[2] * fb_scale,
|
||||
priv->viewport[3] * fb_scale);
|
||||
cogl_framebuffer_set_viewport (fb,
|
||||
priv->viewport[0] * fb_scale - viewport_offset_x,
|
||||
priv->viewport[1] * fb_scale - viewport_offset_y,
|
||||
priv->viewport[2] * fb_scale,
|
||||
priv->viewport[3] * fb_scale);
|
||||
|
||||
if (rec->actor && pick_record_contains_pixel (stage, rec, x, y))
|
||||
return rec->actor;
|
||||
read_x = dirty_x * fb_scale;
|
||||
read_y = dirty_y * fb_scale;
|
||||
|
||||
CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d s: %f",
|
||||
x, y,
|
||||
view_layout.width, view_layout.height,
|
||||
view_layout.x, view_layout.y, fb_scale);
|
||||
|
||||
cogl_color_init_from_4ub (&stage_pick_id, 255, 255, 255, 255);
|
||||
cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH, &stage_pick_id);
|
||||
|
||||
/* Disable dithering (if any) when doing the painting in pick mode */
|
||||
dither_enabled_save = cogl_framebuffer_get_dither_enabled (fb);
|
||||
cogl_framebuffer_set_dither_enabled (fb, FALSE);
|
||||
|
||||
/* Render the entire scence in pick mode - just single colored silhouette's
|
||||
* are drawn offscreen (as we never swap buffers)
|
||||
*/
|
||||
context->pick_mode = mode;
|
||||
|
||||
clutter_stage_do_paint_view (stage, view, NULL);
|
||||
context->pick_mode = CLUTTER_PICK_NONE;
|
||||
|
||||
/* Read the color of the screen co-ords pixel. RGBA_8888_PRE is used
|
||||
even though we don't care about the alpha component because under
|
||||
GLES this is the only format that is guaranteed to work so Cogl
|
||||
will end up having to do a conversion if any other format is
|
||||
used. The format is requested as pre-multiplied because Cogl
|
||||
assumes that all pixels in the framebuffer are premultiplied so
|
||||
it avoids a conversion. */
|
||||
cogl_framebuffer_read_pixels (fb,
|
||||
read_x, read_y, 1, 1,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
|
||||
if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
|
||||
{
|
||||
char *file_name =
|
||||
g_strdup_printf ("pick-buffer-%s-view-x-%d",
|
||||
_clutter_actor_get_debug_name (actor),
|
||||
view_layout.x);
|
||||
|
||||
read_pixels_to_file (fb, file_name, 0, 0, fb_width, fb_height);
|
||||
|
||||
g_free (file_name);
|
||||
}
|
||||
|
||||
return CLUTTER_ACTOR (stage);
|
||||
/* Restore whether GL_DITHER was enabled */
|
||||
cogl_framebuffer_set_dither_enabled (fb, dither_enabled_save);
|
||||
|
||||
if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
|
||||
_clutter_stage_dirty_viewport (stage);
|
||||
|
||||
if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
|
||||
retval = actor;
|
||||
else
|
||||
{
|
||||
guint32 id_ = _clutter_pixel_to_id (pixel);
|
||||
|
||||
retval = _clutter_stage_get_actor_by_pick_id (stage, id_);
|
||||
CLUTTER_NOTE (PICK, "Picking actor %s with id %u (pixel: 0x%x%x%x%x",
|
||||
G_OBJECT_TYPE_NAME (retval),
|
||||
id_,
|
||||
pixel[0], pixel[1], pixel[2], pixel[3]);
|
||||
}
|
||||
|
||||
cogl_pop_framebuffer ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1963,9 +1854,7 @@ clutter_stage_finalize (GObject *object)
|
||||
|
||||
g_array_free (priv->paint_volume_stack, TRUE);
|
||||
|
||||
_clutter_stage_clear_pick_stack (stage);
|
||||
g_array_free (priv->pick_clip_stack, TRUE);
|
||||
g_array_free (priv->pick_stack, TRUE);
|
||||
_clutter_id_pool_free (priv->pick_id_pool);
|
||||
|
||||
if (priv->fps_timer != NULL)
|
||||
g_timer_destroy (priv->fps_timer);
|
||||
@@ -2189,7 +2078,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterStageClass, activate),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterStage::deactivate:
|
||||
@@ -2205,7 +2095,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterStageClass, deactivate),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -2273,7 +2164,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterStageClass, paint_view),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_STAGE_VIEW);
|
||||
|
||||
@@ -2400,10 +2292,7 @@ clutter_stage_init (ClutterStage *self)
|
||||
priv->paint_volume_stack =
|
||||
g_array_new (FALSE, FALSE, sizeof (ClutterPaintVolume));
|
||||
|
||||
priv->pick_stack = g_array_new (FALSE, FALSE, sizeof (PickRecord));
|
||||
priv->pick_clip_stack = g_array_new (FALSE, FALSE, sizeof (PickClipRecord));
|
||||
priv->pick_clip_stack_top = -1;
|
||||
priv->cached_pick_mode = CLUTTER_PICK_NONE;
|
||||
priv->pick_id_pool = _clutter_id_pool_new (256);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4081,12 +3970,6 @@ _clutter_stage_queue_actor_redraw (ClutterStage *stage,
|
||||
CLUTTER_NOTE (CLIPPING, "stage_queue_actor_redraw (actor=%s, clip=%p): ",
|
||||
_clutter_actor_get_debug_name (actor), clip);
|
||||
|
||||
/* Queuing a redraw or clip change invalidates the pick cache, unless we're
|
||||
* in the middle of building it. So we reset the cached flag but don't
|
||||
* completely clear the pick stack...
|
||||
*/
|
||||
priv->cached_pick_mode = CLUTTER_PICK_NONE;
|
||||
|
||||
if (!priv->redraw_pending)
|
||||
{
|
||||
ClutterMasterClock *master_clock;
|
||||
@@ -4347,6 +4230,39 @@ _clutter_stage_get_active_framebuffer (ClutterStage *stage)
|
||||
return stage->priv->active_framebuffer;
|
||||
}
|
||||
|
||||
gint32
|
||||
_clutter_stage_acquire_pick_id (ClutterStage *stage,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
g_assert (priv->pick_id_pool != NULL);
|
||||
|
||||
return _clutter_id_pool_add (priv->pick_id_pool, actor);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_release_pick_id (ClutterStage *stage,
|
||||
gint32 pick_id)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
g_assert (priv->pick_id_pool != NULL);
|
||||
|
||||
_clutter_id_pool_remove (priv->pick_id_pool, pick_id);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
_clutter_stage_get_actor_by_pick_id (ClutterStage *stage,
|
||||
gint32 pick_id)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
g_assert (priv->pick_id_pool != NULL);
|
||||
|
||||
return _clutter_id_pool_lookup (priv->pick_id_pool, pick_id);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_add_pointer_drag_actor (ClutterStage *stage,
|
||||
ClutterInputDevice *device,
|
||||
|
@@ -122,7 +122,8 @@ clutter_tap_action_class_init (ClutterTapActionClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTapActionClass, tap),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
}
|
||||
|
@@ -1,8 +1,17 @@
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-test-utils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <glib-object.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "clutter-actor.h"
|
||||
#include "clutter-color.h"
|
||||
#include "clutter-event.h"
|
||||
#include "clutter-keysyms.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-stage.h"
|
||||
|
||||
typedef struct {
|
||||
ClutterActor *stage;
|
@@ -19,23 +19,16 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef __CLUTTER_TEST_UTILS_H__
|
||||
#define __CLUTTER_TEST_UTILS_H__
|
||||
|
||||
#define __CLUTTER_H_INSIDE__
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
#include "clutter/clutter-actor.h"
|
||||
#include "clutter/clutter-color.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "core/main-private.h"
|
||||
#include "meta/common.h"
|
||||
#include "meta/main.h"
|
||||
#include "backends/x11/nested/meta-backend-x11-nested.h"
|
||||
#include "wayland/meta-wayland.h"
|
||||
#include "wayland/meta-xwayland.h"
|
||||
#include <clutter/clutter-types.h>
|
||||
#include <clutter/clutter-actor.h>
|
||||
#include <clutter/clutter-color.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -86,8 +79,6 @@ G_BEGIN_DECLS
|
||||
int \
|
||||
main (int argc, char *argv[]) \
|
||||
{ \
|
||||
meta_test_init ();\
|
||||
\
|
||||
clutter_test_init (&argc, &argv); \
|
||||
\
|
||||
{ \
|
@@ -2260,10 +2260,7 @@ clutter_text_press (ClutterActor *actor,
|
||||
priv->in_select_drag = TRUE;
|
||||
|
||||
if (type == CLUTTER_BUTTON_PRESS)
|
||||
{
|
||||
clutter_input_device_grab (clutter_event_get_device (event),
|
||||
actor);
|
||||
}
|
||||
clutter_grab_pointer (actor);
|
||||
else
|
||||
{
|
||||
clutter_input_device_sequence_grab (clutter_event_get_device (event),
|
||||
@@ -2321,7 +2318,7 @@ clutter_text_release (ClutterActor *actor,
|
||||
{
|
||||
if (!priv->in_select_touch)
|
||||
{
|
||||
clutter_input_device_ungrab (clutter_event_get_device (event));
|
||||
clutter_ungrab_pointer ();
|
||||
priv->in_select_drag = FALSE;
|
||||
|
||||
return CLUTTER_EVENT_STOP;
|
||||
@@ -4343,7 +4340,8 @@ clutter_text_class_init (ClutterTextClass *klass)
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTextClass, text_changed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -4415,7 +4413,8 @@ clutter_text_class_init (ClutterTextClass *klass)
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
|
||||
G_STRUCT_OFFSET (ClutterTextClass, cursor_event),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_GEOMETRY | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
|
||||
@@ -4433,7 +4432,8 @@ clutter_text_class_init (ClutterTextClass *klass)
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTextClass, cursor_changed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -4451,7 +4451,8 @@ clutter_text_class_init (ClutterTextClass *klass)
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTextClass, activate),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
binding_pool = clutter_binding_pool_get_for_class (klass);
|
||||
|
@@ -709,7 +709,8 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTimelineClass, new_frame),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__INT,
|
||||
G_TYPE_NONE,
|
||||
1, G_TYPE_INT);
|
||||
/**
|
||||
@@ -732,7 +733,8 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTimelineClass, completed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterTimeline::started:
|
||||
@@ -748,7 +750,8 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTimelineClass, started),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterTimeline::paused:
|
||||
@@ -761,7 +764,8 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTimelineClass, paused),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterTimeline::marker-reached:
|
||||
@@ -828,7 +832,8 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTimelineClass, stopped),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__BOOLEAN,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_BOOLEAN);
|
||||
}
|
||||
|
@@ -200,9 +200,6 @@ float clutter_point_distance (const ClutterPoint *a,
|
||||
const ClutterPoint *b,
|
||||
float *x_distance,
|
||||
float *y_distance);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_point_inside_quadrilateral (const ClutterPoint *point,
|
||||
const ClutterPoint *vertices);
|
||||
|
||||
/**
|
||||
* ClutterSize:
|
||||
|
@@ -172,7 +172,6 @@ void clutter_virtual_input_device_notify_touch_up (ClutterVirtualInputDevice *vi
|
||||
CLUTTER_EXPORT
|
||||
ClutterDeviceManager * clutter_virtual_input_device_get_manager (ClutterVirtualInputDevice *virtual_device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
int clutter_virtual_input_device_get_device_type (ClutterVirtualInputDevice *virtual_device);
|
||||
|
||||
#endif /* __CLUTTER_VIRTUAL_INPUT_DEVICE_H__ */
|
||||
|
@@ -103,6 +103,7 @@
|
||||
#include "clutter-stage-manager.h"
|
||||
#include "clutter-stage-view.h"
|
||||
#include "clutter-tap-action.h"
|
||||
#include "clutter-test-utils.h"
|
||||
#include "clutter-texture.h"
|
||||
#include "clutter-text.h"
|
||||
#include "clutter-timeline.h"
|
||||
|
@@ -1004,6 +1004,55 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
COGL_TRACE_END (ClutterStageCoglRedraw);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
|
||||
ClutterStageView *view,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
gboolean has_buffer_age =
|
||||
cogl_is_onscreen (framebuffer) &&
|
||||
is_buffer_age_enabled ();
|
||||
float fb_scale;
|
||||
gboolean scale_is_fractional;
|
||||
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
if (fb_scale != floorf (fb_scale))
|
||||
scale_is_fractional = TRUE;
|
||||
else
|
||||
scale_is_fractional = FALSE;
|
||||
|
||||
/*
|
||||
* Buffer damage is tracked in the framebuffer coordinate space
|
||||
* using the damage history. When fractional scaling is used, a
|
||||
* coordinate on the stage might not correspond to the exact position of any
|
||||
* physical pixel, which causes issues when painting using the pick mode.
|
||||
*
|
||||
* For now, always use the (0, 0) pixel for picking when using fractional
|
||||
* framebuffer scaling.
|
||||
*/
|
||||
if (!has_buffer_age || scale_is_fractional)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view);
|
||||
ClutterStageViewCoglPrivate *view_priv =
|
||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||
cairo_rectangle_int_t view_layout;
|
||||
cairo_rectangle_int_t *fb_damage;
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
fb_damage = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
|
||||
*x = fb_damage->x / fb_scale;
|
||||
*y = fb_damage->y / fb_scale;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
|
||||
{
|
||||
@@ -1021,6 +1070,7 @@ clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
|
||||
iface->ignoring_redraw_clips = clutter_stage_cogl_ignoring_redraw_clips;
|
||||
iface->get_redraw_clip_bounds = clutter_stage_cogl_get_redraw_clip_bounds;
|
||||
iface->redraw = clutter_stage_cogl_redraw;
|
||||
iface->get_dirty_pixel = clutter_stage_cogl_get_dirty_pixel;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -567,7 +567,8 @@ clutter_animation_class_init (ClutterAnimationClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterAnimationClass, started),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
@@ -588,7 +589,8 @@ clutter_animation_class_init (ClutterAnimationClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterAnimationClass, completed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
|
@@ -258,7 +258,8 @@ clutter_behaviour_class_init (ClutterBehaviourClass *klass)
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterBehaviourClass, applied),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
/**
|
||||
@@ -278,7 +279,8 @@ clutter_behaviour_class_init (ClutterBehaviourClass *klass)
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterBehaviourClass, removed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
}
|
||||
|
@@ -1423,7 +1423,8 @@ clutter_state_class_init (ClutterStateClass *klass)
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterStateClass, completed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
|
@@ -572,6 +572,83 @@ gen_texcoords_and_draw_cogl_rectangle (ClutterActor *self,
|
||||
0, 0, t_w, t_h);
|
||||
}
|
||||
|
||||
static CoglPipeline *
|
||||
create_pick_pipeline (ClutterActor *self)
|
||||
{
|
||||
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
||||
ClutterTexturePrivate *priv = texture->priv;
|
||||
CoglPipeline *pick_pipeline = cogl_pipeline_copy (texture_template_pipeline);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!cogl_pipeline_set_layer_combine (pick_pipeline, 0,
|
||||
"RGBA = "
|
||||
" MODULATE (CONSTANT, TEXTURE[A])",
|
||||
&error))
|
||||
{
|
||||
if (!priv->seen_create_pick_pipeline_warning)
|
||||
g_warning ("Error setting up texture combine for shaped "
|
||||
"texture picking: %s", error->message);
|
||||
priv->seen_create_pick_pipeline_warning = TRUE;
|
||||
g_error_free (error);
|
||||
cogl_object_unref (pick_pipeline);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cogl_pipeline_set_blend (pick_pipeline,
|
||||
"RGBA = ADD (SRC_COLOR[RGBA], 0)",
|
||||
NULL);
|
||||
|
||||
cogl_pipeline_set_alpha_test_function (pick_pipeline,
|
||||
COGL_PIPELINE_ALPHA_FUNC_EQUAL,
|
||||
1.0);
|
||||
|
||||
return pick_pipeline;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_texture_pick (ClutterActor *self,
|
||||
const ClutterColor *color)
|
||||
{
|
||||
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
||||
ClutterTexturePrivate *priv = texture->priv;
|
||||
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
|
||||
|
||||
if (!clutter_actor_should_pick_paint (self))
|
||||
return;
|
||||
|
||||
if (G_LIKELY (priv->pick_with_alpha_supported) && priv->pick_with_alpha)
|
||||
{
|
||||
CoglColor pick_color;
|
||||
|
||||
if (priv->pick_pipeline == NULL)
|
||||
priv->pick_pipeline = create_pick_pipeline (self);
|
||||
|
||||
if (priv->pick_pipeline == NULL)
|
||||
{
|
||||
priv->pick_with_alpha_supported = FALSE;
|
||||
CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->pick (self,
|
||||
color);
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->fbo_handle != NULL)
|
||||
update_fbo (self);
|
||||
|
||||
cogl_color_init_from_4ub (&pick_color,
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
0xff);
|
||||
cogl_pipeline_set_layer_combine_constant (priv->pick_pipeline,
|
||||
0, &pick_color);
|
||||
cogl_pipeline_set_layer_texture (priv->pick_pipeline, 0,
|
||||
clutter_texture_get_cogl_texture (texture));
|
||||
gen_texcoords_and_draw_cogl_rectangle (self, priv->pick_pipeline, framebuffer);
|
||||
}
|
||||
else
|
||||
CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->pick (self, color);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_texture_paint (ClutterActor *self)
|
||||
{
|
||||
@@ -690,6 +767,12 @@ clutter_texture_dispose (GObject *object)
|
||||
priv->pipeline = NULL;
|
||||
}
|
||||
|
||||
if (priv->pick_pipeline != NULL)
|
||||
{
|
||||
cogl_object_unref (priv->pick_pipeline);
|
||||
priv->pick_pipeline = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -861,6 +944,7 @@ clutter_texture_class_init (ClutterTextureClass *klass)
|
||||
GParamSpec *pspec;
|
||||
|
||||
actor_class->paint = clutter_texture_paint;
|
||||
actor_class->pick = clutter_texture_pick;
|
||||
actor_class->get_paint_volume = clutter_texture_get_paint_volume;
|
||||
actor_class->realize = clutter_texture_realize;
|
||||
actor_class->unrealize = clutter_texture_unrealize;
|
||||
@@ -1082,7 +1166,8 @@ clutter_texture_class_init (ClutterTextureClass *klass)
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTextureClass, pixbuf_change),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
/**
|
||||
@@ -1103,7 +1188,8 @@ clutter_texture_class_init (ClutterTextureClass *klass)
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterTextureClass, load_finished),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_ERROR);
|
||||
@@ -1177,9 +1263,11 @@ clutter_texture_init (ClutterTexture *self)
|
||||
priv->repeat_y = FALSE;
|
||||
priv->sync_actor_size = TRUE;
|
||||
priv->fbo_handle = NULL;
|
||||
priv->pick_pipeline = NULL;
|
||||
priv->keep_aspect_ratio = FALSE;
|
||||
priv->pick_with_alpha = FALSE;
|
||||
priv->pick_with_alpha_supported = TRUE;
|
||||
priv->seen_create_pick_pipeline_warning = FALSE;
|
||||
|
||||
if (G_UNLIKELY (texture_template_pipeline == NULL))
|
||||
{
|
||||
@@ -1477,7 +1565,7 @@ clutter_texture_set_from_data (ClutterTexture *texture,
|
||||
|
||||
g_set_error (&inner_error, CLUTTER_TEXTURE_ERROR,
|
||||
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
||||
"Failed to load the image data");
|
||||
_("Failed to load the image data"));
|
||||
|
||||
g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, inner_error);
|
||||
|
||||
@@ -1636,7 +1724,7 @@ clutter_texture_set_from_yuv_data (ClutterTexture *texture,
|
||||
{
|
||||
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
||||
CLUTTER_TEXTURE_ERROR_NO_YUV,
|
||||
"YUV textures are not supported");
|
||||
_("YUV textures are not supported"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1645,7 +1733,7 @@ clutter_texture_set_from_yuv_data (ClutterTexture *texture,
|
||||
{
|
||||
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
||||
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
||||
"YUV2 textures are not supported");
|
||||
_("YUV2 textures are not supported"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1872,7 +1960,7 @@ clutter_texture_async_load (ClutterTexture *self,
|
||||
{
|
||||
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
||||
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
||||
"Failed to load the image data");
|
||||
_("Failed to load the image data"));
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
@@ -1969,7 +2057,7 @@ clutter_texture_set_from_file (ClutterTexture *texture,
|
||||
{
|
||||
g_set_error (&internal_error, CLUTTER_TEXTURE_ERROR,
|
||||
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
||||
"Failed to load the image data");
|
||||
_("Failed to load the image data"));
|
||||
}
|
||||
|
||||
if (internal_error != NULL)
|
||||
@@ -2271,7 +2359,7 @@ clutter_texture_set_area_from_rgb_data (ClutterTexture *texture,
|
||||
{
|
||||
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
||||
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
||||
"Failed to load the image data");
|
||||
_("Failed to load the image data"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2962,8 +3050,13 @@ clutter_texture_set_pick_with_alpha (ClutterTexture *texture,
|
||||
if (priv->pick_with_alpha == pick_with_alpha)
|
||||
return;
|
||||
|
||||
g_assert (!pick_with_alpha); /* No longer supported */
|
||||
if (!pick_with_alpha && priv->pick_pipeline != NULL)
|
||||
{
|
||||
cogl_object_unref (priv->pick_pipeline);
|
||||
priv->pick_pipeline = NULL;
|
||||
}
|
||||
|
||||
/* NB: the pick pipeline is created lazily when we first pick */
|
||||
priv->pick_with_alpha = pick_with_alpha;
|
||||
|
||||
/* NB: actors are expected to call clutter_actor_queue_redraw when
|
||||
|
@@ -40,6 +40,10 @@
|
||||
/* This is a Cogl based backend */
|
||||
#include "cogl/clutter-stage-cogl.h"
|
||||
|
||||
#ifdef HAVE_EVDEV
|
||||
#include "evdev/clutter-device-manager-evdev.h"
|
||||
#endif
|
||||
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-main.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
108
clutter/clutter/evdev/clutter-device-manager-evdev.h
Normal file
108
clutter/clutter/evdev/clutter-device-manager-evdev.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Damien Lespiau <damien.lespiau@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_DEVICE_MANAGER_EVDEV_H__
|
||||
#define __CLUTTER_DEVICE_MANAGER_EVDEV_H__
|
||||
|
||||
#include <clutter/clutter-backend.h>
|
||||
#include <clutter/clutter-device-manager.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_DEVICE_MANAGER_EVDEV (clutter_device_manager_evdev_get_type ())
|
||||
#define CLUTTER_DEVICE_MANAGER_EVDEV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, ClutterDeviceManagerEvdev))
|
||||
#define CLUTTER_IS_DEVICE_MANAGER_EVDEV(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV))
|
||||
#define CLUTTER_DEVICE_MANAGER_EVDEV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, ClutterDeviceManagerEvdevClass))
|
||||
#define CLUTTER_IS_DEVICE_MANAGER_EVDEV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV))
|
||||
#define CLUTTER_DEVICE_MANAGER_EVDEV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, ClutterDeviceManagerEvdevClass))
|
||||
|
||||
typedef struct _ClutterDeviceManagerEvdev ClutterDeviceManagerEvdev;
|
||||
typedef struct _ClutterDeviceManagerEvdevClass ClutterDeviceManagerEvdevClass;
|
||||
typedef struct _ClutterDeviceManagerEvdevPrivate ClutterDeviceManagerEvdevPrivate;
|
||||
|
||||
typedef struct _ClutterSeatEvdev ClutterSeatEvdev;
|
||||
|
||||
struct _ClutterDeviceManagerEvdev
|
||||
{
|
||||
ClutterDeviceManager parent_instance;
|
||||
|
||||
ClutterDeviceManagerEvdevPrivate *priv;
|
||||
};
|
||||
|
||||
struct _ClutterDeviceManagerEvdevClass
|
||||
{
|
||||
ClutterDeviceManagerClass parent_class;
|
||||
};
|
||||
|
||||
GType clutter_device_manager_evdev_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _clutter_events_evdev_init (ClutterBackend *backend);
|
||||
void _clutter_events_evdev_uninit (ClutterBackend *backend);
|
||||
|
||||
gint _clutter_device_manager_evdev_acquire_device_id (ClutterDeviceManagerEvdev *manager_evdev);
|
||||
|
||||
void _clutter_device_manager_evdev_release_device_id (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
ClutterInputDevice *device);
|
||||
|
||||
ClutterStage * _clutter_device_manager_evdev_get_stage (ClutterDeviceManagerEvdev *manager_evdev);
|
||||
|
||||
void _clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
ClutterInputDevice *core_pointer,
|
||||
uint64_t time_us,
|
||||
float x,
|
||||
float y,
|
||||
float *new_x,
|
||||
float *new_y);
|
||||
|
||||
void _clutter_device_manager_evdev_filter_relative_motion (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
ClutterInputDevice *device,
|
||||
float x,
|
||||
float y,
|
||||
float *dx,
|
||||
float *dy);
|
||||
|
||||
void _clutter_device_manager_evdev_dispatch (ClutterDeviceManagerEvdev *manager_evdev);
|
||||
|
||||
struct xkb_state * _clutter_device_manager_evdev_get_xkb_state (ClutterDeviceManagerEvdev *manager_evdev);
|
||||
|
||||
static inline guint64
|
||||
us (guint64 us)
|
||||
{
|
||||
return us;
|
||||
}
|
||||
|
||||
static inline guint64
|
||||
ms2us (guint64 ms)
|
||||
{
|
||||
return us (ms * 1000);
|
||||
}
|
||||
|
||||
static inline guint32
|
||||
us2ms (guint64 us)
|
||||
{
|
||||
return (guint32) (us / 1000);
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_DEVICE_MANAGER_EVDEV_H__ */
|
181
clutter/clutter/evdev/clutter-evdev.h
Normal file
181
clutter/clutter/evdev/clutter-evdev.h
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2012 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_EVDEV_H__
|
||||
#define __CLUTTER_EVDEV_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <libinput.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#if !defined(CLUTTER_ENABLE_COMPOSITOR_API) && !defined(CLUTTER_COMPILATION)
|
||||
#error "You need to define CLUTTER_ENABLE_COMPOSITOR_API before including clutter-evdev.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ClutterOpenDeviceCallback:
|
||||
* @path: the device path
|
||||
* @flags: flags to be passed to open
|
||||
*
|
||||
* This callback will be called when Clutter needs to access an input
|
||||
* device. It should return an open file descriptor for the file at @path,
|
||||
* or -1 if opening failed.
|
||||
*/
|
||||
typedef int (*ClutterOpenDeviceCallback) (const char *path,
|
||||
int flags,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
typedef void (*ClutterCloseDeviceCallback) (int fd,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_set_device_callbacks (ClutterOpenDeviceCallback open_callback,
|
||||
ClutterCloseDeviceCallback close_callback,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_set_seat_id (const gchar *seat_id);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_release_devices (void);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_reclaim_devices (void);
|
||||
|
||||
/**
|
||||
* ClutterPointerConstrainCallback:
|
||||
* @device: the core pointer device
|
||||
* @time: the event time in milliseconds
|
||||
* @x: (inout): the new X coordinate
|
||||
* @y: (inout): the new Y coordinate
|
||||
* @user_data: user data passed to this function
|
||||
*
|
||||
* This callback will be called for all pointer motion events, and should
|
||||
* update (@x, @y) to constrain the pointer position appropriately.
|
||||
* The subsequent motion event will use the updated values as the new coordinates.
|
||||
* Note that the coordinates are not clamped to the stage size, and the callback
|
||||
* must make sure that this happens before it returns.
|
||||
* Also note that the event will be emitted even if the pointer is constrained
|
||||
* to be in the same position.
|
||||
*
|
||||
* Since: 1.16
|
||||
*/
|
||||
typedef void (*ClutterPointerConstrainCallback) (ClutterInputDevice *device,
|
||||
guint32 time,
|
||||
float prev_x,
|
||||
float prev_y,
|
||||
float *x,
|
||||
float *y,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_set_pointer_constrain_callback (ClutterDeviceManager *evdev,
|
||||
ClutterPointerConstrainCallback callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_notify);
|
||||
|
||||
typedef void (*ClutterRelativeMotionFilter) (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y,
|
||||
float *dx,
|
||||
float *dy,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_set_relative_motion_filter (ClutterDeviceManager *evdev,
|
||||
ClutterRelativeMotionFilter filter,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_set_keyboard_map (ClutterDeviceManager *evdev,
|
||||
struct xkb_keymap *keymap);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
struct xkb_keymap * clutter_evdev_get_keyboard_map (ClutterDeviceManager *evdev);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev,
|
||||
xkb_layout_index_t idx);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
xkb_layout_index_t clutter_evdev_get_keyboard_layout_index (ClutterDeviceManager *evdev);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_set_keyboard_numlock (ClutterDeviceManager *evdev,
|
||||
gboolean numlock_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_set_keyboard_repeat (ClutterDeviceManager *evdev,
|
||||
gboolean repeat,
|
||||
guint32 delay,
|
||||
guint32 interval);
|
||||
|
||||
typedef gboolean (* ClutterEvdevFilterFunc) (struct libinput_event *event,
|
||||
gpointer data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_add_filter (ClutterEvdevFilterFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy_notify);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_remove_filter (ClutterEvdevFilterFunc func,
|
||||
gpointer data);
|
||||
CLUTTER_EXPORT
|
||||
struct libinput_device * clutter_evdev_input_device_get_libinput_device (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gint32 clutter_evdev_event_sequence_get_slot (const ClutterEventSequence *sequence);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_warp_pointer (ClutterInputDevice *pointer_device,
|
||||
guint32 time_,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint32 clutter_evdev_event_get_event_code (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint64 clutter_evdev_event_get_time_usec (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_evdev_event_get_relative_motion (const ClutterEvent *event,
|
||||
double *dx,
|
||||
double *dy,
|
||||
double *dx_unaccel,
|
||||
double *dy_unaccel);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_input_device_tool_set_pressure_curve (ClutterInputDeviceTool *tool,
|
||||
gdouble curve[4]);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_evdev_input_device_tool_set_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button,
|
||||
guint evcode);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_EVDEV_H__ */
|
191
clutter/clutter/evdev/clutter-event-evdev.c
Normal file
191
clutter/clutter/evdev/clutter-event-evdev.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/* Clutter.
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authored by:
|
||||
* Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-device-manager-private.h"
|
||||
#include "clutter/clutter-event-private.h"
|
||||
#include "clutter-input-device-evdev.h"
|
||||
#include "clutter-evdev.h"
|
||||
|
||||
typedef struct _ClutterEventEvdev ClutterEventEvdev;
|
||||
|
||||
struct _ClutterEventEvdev
|
||||
{
|
||||
guint32 evcode;
|
||||
|
||||
guint64 time_usec;
|
||||
|
||||
gboolean has_relative_motion;
|
||||
double dx;
|
||||
double dy;
|
||||
double dx_unaccel;
|
||||
double dy_unaccel;
|
||||
};
|
||||
|
||||
static ClutterEventEvdev *
|
||||
_clutter_event_evdev_new (void)
|
||||
{
|
||||
return g_slice_new0 (ClutterEventEvdev);
|
||||
}
|
||||
|
||||
ClutterEventEvdev *
|
||||
_clutter_event_evdev_copy (ClutterEventEvdev *event_evdev)
|
||||
{
|
||||
if (event_evdev != NULL)
|
||||
return g_slice_dup (ClutterEventEvdev, event_evdev);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_event_evdev_free (ClutterEventEvdev *event_evdev)
|
||||
{
|
||||
if (event_evdev != NULL)
|
||||
g_slice_free (ClutterEventEvdev, event_evdev);
|
||||
}
|
||||
|
||||
static ClutterEventEvdev *
|
||||
clutter_evdev_event_ensure_platform_data (ClutterEvent *event)
|
||||
{
|
||||
ClutterEventEvdev *event_evdev = _clutter_event_get_platform_data (event);
|
||||
|
||||
if (!event_evdev)
|
||||
{
|
||||
event_evdev = _clutter_event_evdev_new ();
|
||||
_clutter_event_set_platform_data (event, event_evdev);
|
||||
}
|
||||
|
||||
return event_evdev;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_evdev_event_set_event_code (ClutterEvent *event,
|
||||
guint32 evcode)
|
||||
{
|
||||
ClutterEventEvdev *event_evdev;
|
||||
|
||||
event_evdev = clutter_evdev_event_ensure_platform_data (event);
|
||||
event_evdev->evcode = evcode;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_evdev_event_set_time_usec (ClutterEvent *event,
|
||||
guint64 time_usec)
|
||||
{
|
||||
ClutterEventEvdev *event_evdev;
|
||||
|
||||
event_evdev = clutter_evdev_event_ensure_platform_data (event);
|
||||
event_evdev->time_usec = time_usec;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_evdev_event_set_relative_motion (ClutterEvent *event,
|
||||
double dx,
|
||||
double dy,
|
||||
double dx_unaccel,
|
||||
double dy_unaccel)
|
||||
{
|
||||
ClutterEventEvdev *event_evdev;
|
||||
|
||||
event_evdev = clutter_evdev_event_ensure_platform_data (event);
|
||||
event_evdev->dx = dx;
|
||||
event_evdev->dy = dy;
|
||||
event_evdev->dx_unaccel = dx_unaccel;
|
||||
event_evdev->dy_unaccel = dy_unaccel;
|
||||
event_evdev->has_relative_motion = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_evdev_event_get_event_code:
|
||||
* @event: a #ClutterEvent
|
||||
*
|
||||
* Returns the event code of the original event. See linux/input.h for more
|
||||
* information.
|
||||
*
|
||||
* Returns: The event code.
|
||||
**/
|
||||
guint32
|
||||
clutter_evdev_event_get_event_code (const ClutterEvent *event)
|
||||
{
|
||||
ClutterEventEvdev *event_evdev = _clutter_event_get_platform_data (event);
|
||||
|
||||
if (event_evdev)
|
||||
return event_evdev->evcode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_evdev_event_get_time_usec:
|
||||
* @event: a #ClutterEvent
|
||||
*
|
||||
* Returns the time in microsecond granularity, or 0 if unavailable.
|
||||
*
|
||||
* Returns: The time in microsecond granularity, or 0 if unavailable.
|
||||
*/
|
||||
guint64
|
||||
clutter_evdev_event_get_time_usec (const ClutterEvent *event)
|
||||
{
|
||||
ClutterEventEvdev *event_evdev = _clutter_event_get_platform_data (event);
|
||||
|
||||
if (event_evdev)
|
||||
return event_evdev->time_usec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_evdev_event_get_pointer_motion
|
||||
* @event: a #ClutterEvent
|
||||
*
|
||||
* If available, the normal and unaccelerated motion deltas are written
|
||||
* to the dx, dy, dx_unaccel and dy_unaccel and TRUE is returned.
|
||||
*
|
||||
* If unavailable, FALSE is returned.
|
||||
*
|
||||
* Returns: TRUE on success, otherwise FALSE.
|
||||
**/
|
||||
gboolean
|
||||
clutter_evdev_event_get_relative_motion (const ClutterEvent *event,
|
||||
double *dx,
|
||||
double *dy,
|
||||
double *dx_unaccel,
|
||||
double *dy_unaccel)
|
||||
{
|
||||
ClutterEventEvdev *event_evdev = _clutter_event_get_platform_data (event);
|
||||
|
||||
if (event_evdev && event_evdev->has_relative_motion)
|
||||
{
|
||||
if (dx)
|
||||
*dx = event_evdev->dx;
|
||||
if (dy)
|
||||
*dy = event_evdev->dy;
|
||||
if (dx_unaccel)
|
||||
*dx_unaccel = event_evdev->dx_unaccel;
|
||||
if (dy_unaccel)
|
||||
*dy_unaccel = event_evdev->dy_unaccel;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
157
clutter/clutter/evdev/clutter-input-device-evdev.h
Normal file
157
clutter/clutter/evdev/clutter-input-device-evdev.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corp.
|
||||
* Copyright (C) 2014 Jonas Ådahl
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Damien Lespiau <damien.lespiau@intel.com>
|
||||
* Author: Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_DEVICE_EVDEV_H__
|
||||
#define __CLUTTER_INPUT_DEVICE_EVDEV_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <libinput.h>
|
||||
|
||||
#include "clutter/clutter-device-manager-private.h"
|
||||
#include "evdev/clutter-seat-evdev.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_DEVICE_EVDEV _clutter_input_device_evdev_get_type()
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_EVDEV(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdev))
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_EVDEV_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdevClass))
|
||||
|
||||
#define CLUTTER_IS_INPUT_DEVICE_EVDEV(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_EVDEV))
|
||||
|
||||
#define CLUTTER_IS_INPUT_DEVICE_EVDEV_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_EVDEV))
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_EVDEV_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdevClass))
|
||||
|
||||
typedef struct _ClutterInputDeviceEvdev ClutterInputDeviceEvdev;
|
||||
typedef struct _ClutterEventEvdev ClutterEventEvdev;
|
||||
|
||||
struct _ClutterInputDeviceEvdev
|
||||
{
|
||||
ClutterInputDevice parent;
|
||||
|
||||
struct libinput_device *libinput_device;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterInputDeviceTool *last_tool;
|
||||
|
||||
cairo_matrix_t device_matrix;
|
||||
gdouble device_aspect_ratio; /* w:h */
|
||||
gdouble output_ratio; /* w:h */
|
||||
|
||||
GHashTable *touches;
|
||||
|
||||
/* Keyboard a11y */
|
||||
ClutterKeyboardA11yFlags a11y_flags;
|
||||
GList *slow_keys_list;
|
||||
guint debounce_timer;
|
||||
guint16 debounce_key;
|
||||
xkb_mod_mask_t stickykeys_depressed_mask;
|
||||
xkb_mod_mask_t stickykeys_latched_mask;
|
||||
xkb_mod_mask_t stickykeys_locked_mask;
|
||||
guint toggle_slowkeys_timer;
|
||||
guint16 shift_count;
|
||||
guint32 last_shift_time;
|
||||
gint mousekeys_btn;
|
||||
gboolean mousekeys_btn_states[3];
|
||||
guint32 mousekeys_first_motion_time; /* ms */
|
||||
guint32 mousekeys_last_motion_time; /* ms */
|
||||
guint mousekeys_init_delay;
|
||||
guint mousekeys_accel_time;
|
||||
guint mousekeys_max_speed;
|
||||
gdouble mousekeys_curve_factor;
|
||||
guint move_mousekeys_timer;
|
||||
guint16 last_mousekeys_key;
|
||||
};
|
||||
|
||||
GType _clutter_input_device_evdev_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterInputDevice * _clutter_input_device_evdev_new (ClutterDeviceManager *manager,
|
||||
ClutterSeatEvdev *seat,
|
||||
struct libinput_device *libinput_device);
|
||||
|
||||
ClutterInputDevice * _clutter_input_device_evdev_new_virtual (ClutterDeviceManager *manager,
|
||||
ClutterSeatEvdev *seat,
|
||||
ClutterInputDeviceType type,
|
||||
ClutterInputMode mode);
|
||||
|
||||
ClutterSeatEvdev * _clutter_input_device_evdev_get_seat (ClutterInputDeviceEvdev *device);
|
||||
|
||||
void _clutter_input_device_evdev_update_leds (ClutterInputDeviceEvdev *device,
|
||||
enum libinput_led leds);
|
||||
|
||||
ClutterInputDeviceType _clutter_input_device_evdev_determine_type (struct libinput_device *libinput_device);
|
||||
|
||||
|
||||
ClutterEventEvdev * _clutter_event_evdev_copy (ClutterEventEvdev *event_evdev);
|
||||
void _clutter_event_evdev_free (ClutterEventEvdev *event_evdev);
|
||||
|
||||
void _clutter_evdev_event_set_event_code (ClutterEvent *event,
|
||||
guint32 evcode);
|
||||
|
||||
void _clutter_evdev_event_set_time_usec (ClutterEvent *event,
|
||||
guint64 time_usec);
|
||||
|
||||
void _clutter_evdev_event_set_relative_motion (ClutterEvent *event,
|
||||
double dx,
|
||||
double dy,
|
||||
double dx_unaccel,
|
||||
double dy_unaccel);
|
||||
|
||||
void clutter_input_device_evdev_translate_coordinates (ClutterInputDevice *device,
|
||||
ClutterStage *stage,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
|
||||
void clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *device,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
ClutterTouchState * clutter_input_device_evdev_acquire_touch_state (ClutterInputDeviceEvdev *device,
|
||||
int device_slot);
|
||||
|
||||
ClutterTouchState * clutter_input_device_evdev_lookup_touch_state (ClutterInputDeviceEvdev *device,
|
||||
int device_slot);
|
||||
|
||||
void clutter_input_device_evdev_release_touch_state (ClutterInputDeviceEvdev *device,
|
||||
ClutterTouchState *touch_state);
|
||||
|
||||
void clutter_input_device_evdev_release_touch_slots (ClutterInputDeviceEvdev *device_evdev,
|
||||
uint64_t time_us);
|
||||
|
||||
void clutter_evdev_a11y_maybe_notify_toggle_keys (ClutterInputDeviceEvdev *);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_DEVICE_EVDEV_H__ */
|
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright © 2009, 2010, 2011 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -17,46 +21,47 @@
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "backends/native/meta-input-device-tool-native.h"
|
||||
#include "clutter-input-device-tool-evdev.h"
|
||||
#include "clutter-evdev.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaInputDeviceToolNative, meta_input_device_tool_native,
|
||||
G_DEFINE_TYPE (ClutterInputDeviceToolEvdev, clutter_input_device_tool_evdev,
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL)
|
||||
|
||||
static void
|
||||
meta_input_device_tool_native_finalize (GObject *object)
|
||||
clutter_input_device_tool_evdev_finalize (GObject *object)
|
||||
{
|
||||
MetaInputDeviceToolNative *tool = META_INPUT_DEVICE_TOOL_NATIVE (object);
|
||||
ClutterInputDeviceToolEvdev *tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (object);
|
||||
|
||||
g_hash_table_unref (tool->button_map);
|
||||
libinput_tablet_tool_unref (tool->tool);
|
||||
|
||||
G_OBJECT_CLASS (meta_input_device_tool_native_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (clutter_input_device_tool_evdev_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_device_tool_native_class_init (MetaInputDeviceToolNativeClass *klass)
|
||||
clutter_input_device_tool_evdev_class_init (ClutterInputDeviceToolEvdevClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_input_device_tool_native_finalize;
|
||||
object_class->finalize = clutter_input_device_tool_evdev_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_device_tool_native_init (MetaInputDeviceToolNative *tool)
|
||||
clutter_input_device_tool_evdev_init (ClutterInputDeviceToolEvdev *tool)
|
||||
{
|
||||
tool->button_map = g_hash_table_new (NULL, NULL);
|
||||
}
|
||||
|
||||
ClutterInputDeviceTool *
|
||||
meta_input_device_tool_native_new (struct libinput_tablet_tool *tool,
|
||||
uint64_t serial,
|
||||
ClutterInputDeviceToolType type)
|
||||
clutter_input_device_tool_evdev_new (struct libinput_tablet_tool *tool,
|
||||
guint64 serial,
|
||||
ClutterInputDeviceToolType type)
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
ClutterInputDeviceToolEvdev *evdev_tool;
|
||||
|
||||
evdev_tool = g_object_new (META_TYPE_INPUT_DEVICE_TOOL_NATIVE,
|
||||
evdev_tool = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV,
|
||||
"type", type,
|
||||
"serial", serial,
|
||||
"id", libinput_tablet_tool_get_tool_id (tool),
|
||||
@@ -68,18 +73,18 @@ meta_input_device_tool_native_new (struct libinput_tablet_tool *tool,
|
||||
}
|
||||
|
||||
void
|
||||
meta_input_device_tool_native_set_pressure_curve (ClutterInputDeviceTool *tool,
|
||||
double curve[4])
|
||||
clutter_evdev_input_device_tool_set_pressure_curve (ClutterInputDeviceTool *tool,
|
||||
gdouble curve[4])
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
ClutterInputDeviceToolEvdev *evdev_tool;
|
||||
|
||||
g_return_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool));
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL_EVDEV (tool));
|
||||
g_return_if_fail (curve[0] >= 0 && curve[0] <= 1 &&
|
||||
curve[1] >= 0 && curve[1] <= 1 &&
|
||||
curve[2] >= 0 && curve[2] <= 1 &&
|
||||
curve[3] >= 0 && curve[3] <= 1);
|
||||
|
||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||
evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool);
|
||||
evdev_tool->pressure_curve[0] = curve[0];
|
||||
evdev_tool->pressure_curve[1] = curve[1];
|
||||
evdev_tool->pressure_curve[2] = curve[2];
|
||||
@@ -87,15 +92,15 @@ meta_input_device_tool_native_set_pressure_curve (ClutterInputDeviceTool *tool,
|
||||
}
|
||||
|
||||
void
|
||||
meta_input_device_tool_native_set_button_code (ClutterInputDeviceTool *tool,
|
||||
uint32_t button,
|
||||
uint32_t evcode)
|
||||
clutter_evdev_input_device_tool_set_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button,
|
||||
guint evcode)
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
ClutterInputDeviceToolEvdev *evdev_tool;
|
||||
|
||||
g_return_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool));
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL_EVDEV (tool));
|
||||
|
||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||
evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool);
|
||||
|
||||
if (evcode == 0)
|
||||
{
|
||||
@@ -108,14 +113,14 @@ meta_input_device_tool_native_set_button_code (ClutterInputDeviceTool *tool,
|
||||
}
|
||||
}
|
||||
|
||||
static double
|
||||
calculate_bezier_position (double pos,
|
||||
double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2)
|
||||
static gdouble
|
||||
calculate_bezier_position (gdouble pos,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2)
|
||||
{
|
||||
double int1_y, int2_y;
|
||||
gdouble int1_y, int2_y;
|
||||
|
||||
pos = CLAMP (pos, 0, 1);
|
||||
|
||||
@@ -129,15 +134,15 @@ calculate_bezier_position (double pos,
|
||||
return (pos * (int2_y - int1_y)) + int1_y;
|
||||
}
|
||||
|
||||
double
|
||||
meta_input_device_tool_native_translate_pressure (ClutterInputDeviceTool *tool,
|
||||
double pressure)
|
||||
gdouble
|
||||
clutter_input_device_tool_evdev_translate_pressure (ClutterInputDeviceTool *tool,
|
||||
gdouble pressure)
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
ClutterInputDeviceToolEvdev *evdev_tool;
|
||||
|
||||
g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), pressure);
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), pressure);
|
||||
|
||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||
evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool);
|
||||
|
||||
return calculate_bezier_position (CLAMP (pressure, 0, 1),
|
||||
evdev_tool->pressure_curve[0],
|
||||
@@ -146,15 +151,15 @@ meta_input_device_tool_native_translate_pressure (ClutterInputDeviceTool *tool,
|
||||
evdev_tool->pressure_curve[3]);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
meta_input_device_tool_native_get_button_code (ClutterInputDeviceTool *tool,
|
||||
uint32_t button)
|
||||
guint
|
||||
clutter_input_device_tool_evdev_get_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button)
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
ClutterInputDeviceToolEvdev *evdev_tool;
|
||||
|
||||
g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), 0);
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), 0);
|
||||
|
||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||
evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool);
|
||||
|
||||
return GPOINTER_TO_UINT (g_hash_table_lookup (evdev_tool->button_map,
|
||||
GUINT_TO_POINTER (button)));
|
84
clutter/clutter/evdev/clutter-input-device-tool-evdev.h
Normal file
84
clutter/clutter/evdev/clutter-input-device-tool-evdev.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright © 2009, 2010, 2011 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_DEVICE_EVDEV_TOOL_H__
|
||||
#define __CLUTTER_INPUT_DEVICE_EVDEV_TOOL_H__
|
||||
|
||||
#include <libinput.h>
|
||||
|
||||
#include <clutter/clutter-input-device-tool.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV (clutter_input_device_tool_evdev_get_type ())
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_TOOL_EVDEV(o) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((o), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV, ClutterInputDeviceToolEvdev))
|
||||
|
||||
#define CLUTTER_IS_INPUT_DEVICE_TOOL_EVDEV(o) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((o), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV))
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_TOOL_EVDEV_CLASS(c) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((c), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV, ClutterInputDeviceToolEvdevClass))
|
||||
|
||||
#define CLUTTER_IS_INPUT_DEVICE_TOOL_EVDEV_CLASS(c) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((c), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV))
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_TOOL_EVDEV_GET_CLASS(o) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((o), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV, ClutterInputDeviceToolEvdevClass))
|
||||
|
||||
typedef struct _ClutterInputDeviceToolEvdev ClutterInputDeviceToolEvdev;
|
||||
typedef struct _ClutterInputDeviceToolEvdevClass ClutterInputDeviceToolEvdevClass;
|
||||
|
||||
struct _ClutterInputDeviceToolEvdev
|
||||
{
|
||||
ClutterInputDeviceTool parent_instance;
|
||||
struct libinput_tablet_tool *tool;
|
||||
GHashTable *button_map;
|
||||
gdouble pressure_curve[4];
|
||||
};
|
||||
|
||||
struct _ClutterInputDeviceToolEvdevClass
|
||||
{
|
||||
ClutterInputDeviceToolClass parent_class;
|
||||
};
|
||||
|
||||
GType clutter_input_device_tool_evdev_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterInputDeviceTool * clutter_input_device_tool_evdev_new (struct libinput_tablet_tool *tool,
|
||||
guint64 serial,
|
||||
ClutterInputDeviceToolType type);
|
||||
|
||||
gdouble clutter_input_device_tool_evdev_translate_pressure (ClutterInputDeviceTool *tool,
|
||||
gdouble pressure);
|
||||
guint clutter_input_device_tool_evdev_get_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_DEVICE_EVDEV_TOOL_H__ */
|
@@ -19,46 +19,46 @@
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "backends/native/meta-device-manager-native.h"
|
||||
#include "backends/native/meta-keymap-native.h"
|
||||
#include "clutter-device-manager-evdev.h"
|
||||
#include "clutter-keymap-evdev.h"
|
||||
|
||||
static const char *option_xkb_layout = "us";
|
||||
static const char *option_xkb_variant = "";
|
||||
static const char *option_xkb_options = "";
|
||||
|
||||
typedef struct _MetaKeymapNative MetaKeymapNative;
|
||||
typedef struct _ClutterKeymapEvdev ClutterKeymapEvdev;
|
||||
|
||||
struct _MetaKeymapNative
|
||||
struct _ClutterKeymapEvdev
|
||||
{
|
||||
ClutterKeymap parent_instance;
|
||||
|
||||
struct xkb_keymap *keymap;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaKeymapNative, meta_keymap_native,
|
||||
G_DEFINE_TYPE (ClutterKeymapEvdev, clutter_keymap_evdev,
|
||||
CLUTTER_TYPE_KEYMAP)
|
||||
|
||||
static void
|
||||
meta_keymap_native_finalize (GObject *object)
|
||||
clutter_keymap_evdev_finalize (GObject *object)
|
||||
{
|
||||
MetaKeymapNative *keymap = META_KEYMAP_NATIVE (object);
|
||||
ClutterKeymapEvdev *keymap = CLUTTER_KEYMAP_EVDEV (object);
|
||||
|
||||
xkb_keymap_unref (keymap->keymap);
|
||||
|
||||
G_OBJECT_CLASS (meta_keymap_native_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (clutter_keymap_evdev_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_keymap_native_get_num_lock_state (ClutterKeymap *keymap)
|
||||
clutter_keymap_evdev_get_num_lock_state (ClutterKeymap *keymap)
|
||||
{
|
||||
MetaDeviceManagerNative *device_manager;
|
||||
ClutterDeviceManagerEvdev *device_manager;
|
||||
struct xkb_state *xkb_state;
|
||||
|
||||
device_manager =
|
||||
META_DEVICE_MANAGER_NATIVE (clutter_device_manager_get_default ());
|
||||
xkb_state = meta_device_manager_native_get_xkb_state (device_manager);
|
||||
CLUTTER_DEVICE_MANAGER_EVDEV (clutter_device_manager_get_default ());
|
||||
xkb_state = _clutter_device_manager_evdev_get_xkb_state (device_manager);
|
||||
|
||||
return xkb_state_mod_name_is_active (xkb_state,
|
||||
XKB_MOD_NAME_NUM,
|
||||
@@ -67,14 +67,14 @@ meta_keymap_native_get_num_lock_state (ClutterKeymap *keymap)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_keymap_native_get_caps_lock_state (ClutterKeymap *keymap)
|
||||
clutter_keymap_evdev_get_caps_lock_state (ClutterKeymap *keymap)
|
||||
{
|
||||
MetaDeviceManagerNative *device_manager;
|
||||
ClutterDeviceManagerEvdev *device_manager;
|
||||
struct xkb_state *xkb_state;
|
||||
|
||||
device_manager =
|
||||
META_DEVICE_MANAGER_NATIVE (clutter_device_manager_get_default ());
|
||||
xkb_state = meta_device_manager_native_get_xkb_state (device_manager);
|
||||
CLUTTER_DEVICE_MANAGER_EVDEV (clutter_device_manager_get_default ());
|
||||
xkb_state = _clutter_device_manager_evdev_get_xkb_state (device_manager);
|
||||
|
||||
return xkb_state_mod_name_is_active (xkb_state,
|
||||
XKB_MOD_NAME_CAPS,
|
||||
@@ -83,19 +83,19 @@ meta_keymap_native_get_caps_lock_state (ClutterKeymap *keymap)
|
||||
}
|
||||
|
||||
static void
|
||||
meta_keymap_native_class_init (MetaKeymapNativeClass *klass)
|
||||
clutter_keymap_evdev_class_init (ClutterKeymapEvdevClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterKeymapClass *keymap_class = CLUTTER_KEYMAP_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_keymap_native_finalize;
|
||||
object_class->finalize = clutter_keymap_evdev_finalize;
|
||||
|
||||
keymap_class->get_num_lock_state = meta_keymap_native_get_num_lock_state;
|
||||
keymap_class->get_caps_lock_state = meta_keymap_native_get_caps_lock_state;
|
||||
keymap_class->get_num_lock_state = clutter_keymap_evdev_get_num_lock_state;
|
||||
keymap_class->get_caps_lock_state = clutter_keymap_evdev_get_caps_lock_state;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_keymap_native_init (MetaKeymapNative *keymap)
|
||||
clutter_keymap_evdev_init (ClutterKeymapEvdev *keymap)
|
||||
{
|
||||
struct xkb_context *ctx;
|
||||
struct xkb_rule_names names;
|
||||
@@ -113,8 +113,8 @@ meta_keymap_native_init (MetaKeymapNative *keymap)
|
||||
}
|
||||
|
||||
void
|
||||
meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap,
|
||||
struct xkb_keymap *xkb_keymap)
|
||||
clutter_keymap_evdev_set_keyboard_map (ClutterKeymapEvdev *keymap,
|
||||
struct xkb_keymap *xkb_keymap)
|
||||
{
|
||||
if (keymap->keymap)
|
||||
xkb_keymap_unref (keymap->keymap);
|
||||
@@ -122,7 +122,7 @@ meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap,
|
||||
}
|
||||
|
||||
struct xkb_keymap *
|
||||
meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap)
|
||||
clutter_keymap_evdev_get_keyboard_map (ClutterKeymapEvdev *keymap)
|
||||
{
|
||||
return keymap->keymap;
|
||||
}
|
@@ -19,14 +19,14 @@
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "backends/native/meta-xkb-utils.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "clutter-xkb-utils.h"
|
||||
#include "clutter-keymap.h"
|
||||
|
||||
#define META_TYPE_KEYMAP_NATIVE (meta_keymap_native_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaKeymapNative, meta_keymap_native,
|
||||
META, KEYMAP_NATIVE,
|
||||
#define CLUTTER_TYPE_KEYMAP_EVDEV (clutter_keymap_evdev_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (ClutterKeymapEvdev, clutter_keymap_evdev,
|
||||
CLUTTER, KEYMAP_EVDEV,
|
||||
ClutterKeymap)
|
||||
|
||||
void meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap,
|
||||
struct xkb_keymap *xkb_keymap);
|
||||
struct xkb_keymap * meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap);
|
||||
void clutter_keymap_evdev_set_keyboard_map (ClutterKeymapEvdev *keymap,
|
||||
struct xkb_keymap *xkb_keymap);
|
||||
struct xkb_keymap * clutter_keymap_evdev_get_keyboard_map (ClutterKeymapEvdev *keymap);
|
@@ -24,17 +24,18 @@
|
||||
* Author: Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-seat-evdev.h"
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "backends/native/meta-seat-native.h"
|
||||
#include "backends/native/meta-event-native.h"
|
||||
#include "backends/native/meta-input-device-native.h"
|
||||
#include "backends/native/meta-input-device-tool-native.h"
|
||||
#include "backends/native/meta-keymap-native.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter-event-private.h"
|
||||
#include "clutter-input-device-evdev.h"
|
||||
#include "clutter-input-device-tool-evdev.h"
|
||||
#include "clutter-keymap-evdev.h"
|
||||
#include "clutter-main.h"
|
||||
|
||||
/* Try to keep the pointer inside the stage. Hopefully no one is using
|
||||
* this backend with stages smaller than this. */
|
||||
@@ -50,8 +51,8 @@
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_seat_native_set_libinput_seat (MetaSeatNative *seat,
|
||||
struct libinput_seat *libinput_seat)
|
||||
clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
|
||||
struct libinput_seat *libinput_seat)
|
||||
{
|
||||
g_assert (seat->libinput_seat == NULL);
|
||||
|
||||
@@ -61,10 +62,10 @@ meta_seat_native_set_libinput_seat (MetaSeatNative *seat,
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_sync_leds (MetaSeatNative *seat)
|
||||
clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat)
|
||||
{
|
||||
GSList *iter;
|
||||
MetaInputDeviceNative *device_evdev;
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
int caps_lock, num_lock, scroll_lock;
|
||||
enum libinput_led leds = 0;
|
||||
|
||||
@@ -82,19 +83,19 @@ meta_seat_native_sync_leds (MetaSeatNative *seat)
|
||||
for (iter = seat->devices; iter; iter = iter->next)
|
||||
{
|
||||
device_evdev = iter->data;
|
||||
meta_input_device_native_update_leds (device_evdev, leds);
|
||||
_clutter_input_device_evdev_update_leds (device_evdev, leds);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_touch_state_free (MetaTouchState *touch_state)
|
||||
clutter_touch_state_free (ClutterTouchState *touch_state)
|
||||
{
|
||||
g_slice_free (MetaTouchState, touch_state);
|
||||
g_slice_free (ClutterTouchState, touch_state);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_seat_slot_allocated (MetaSeatNative *seat,
|
||||
int seat_slot)
|
||||
ensure_seat_slot_allocated (ClutterSeatEvdev *seat,
|
||||
int seat_slot)
|
||||
{
|
||||
if (seat_slot >= seat->n_alloc_touch_states)
|
||||
{
|
||||
@@ -104,17 +105,17 @@ ensure_seat_slot_allocated (MetaSeatNative *seat,
|
||||
seat->n_alloc_touch_states += size_increase;
|
||||
seat->touch_states = g_realloc_n (seat->touch_states,
|
||||
seat->n_alloc_touch_states,
|
||||
sizeof (MetaTouchState *));
|
||||
sizeof (ClutterTouchState *));
|
||||
for (i = 0; i < size_increase; i++)
|
||||
seat->touch_states[seat->n_alloc_touch_states - (i + 1)] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MetaTouchState *
|
||||
meta_seat_native_acquire_touch_state (MetaSeatNative *seat,
|
||||
int device_slot)
|
||||
ClutterTouchState *
|
||||
clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat,
|
||||
int device_slot)
|
||||
{
|
||||
MetaTouchState *touch_state;
|
||||
ClutterTouchState *touch_state;
|
||||
int seat_slot;
|
||||
|
||||
for (seat_slot = 0; seat_slot < seat->n_alloc_touch_states; seat_slot++)
|
||||
@@ -125,8 +126,8 @@ meta_seat_native_acquire_touch_state (MetaSeatNative *seat,
|
||||
|
||||
ensure_seat_slot_allocated (seat, seat_slot);
|
||||
|
||||
touch_state = g_slice_new0 (MetaTouchState);
|
||||
*touch_state = (MetaTouchState) {
|
||||
touch_state = g_slice_new0 (ClutterTouchState);
|
||||
*touch_state = (ClutterTouchState) {
|
||||
.seat = seat,
|
||||
.seat_slot = seat_slot,
|
||||
.device_slot = device_slot,
|
||||
@@ -138,32 +139,32 @@ meta_seat_native_acquire_touch_state (MetaSeatNative *seat,
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_release_touch_state (MetaSeatNative *seat,
|
||||
MetaTouchState *touch_state)
|
||||
clutter_seat_evdev_release_touch_state (ClutterSeatEvdev *seat,
|
||||
ClutterTouchState *touch_state)
|
||||
{
|
||||
g_clear_pointer (&seat->touch_states[touch_state->seat_slot],
|
||||
clutter_touch_state_free);
|
||||
}
|
||||
|
||||
MetaSeatNative *
|
||||
meta_seat_native_new (MetaDeviceManagerNative *manager_evdev)
|
||||
ClutterSeatEvdev *
|
||||
clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev)
|
||||
{
|
||||
ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (manager_evdev);
|
||||
MetaSeatNative *seat;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterInputDevice *device;
|
||||
ClutterStage *stage;
|
||||
ClutterKeymap *keymap;
|
||||
struct xkb_keymap *xkb_keymap;
|
||||
|
||||
seat = g_new0 (MetaSeatNative, 1);
|
||||
seat = g_new0 (ClutterSeatEvdev, 1);
|
||||
if (!seat)
|
||||
return NULL;
|
||||
|
||||
seat->manager_evdev = manager_evdev;
|
||||
device = meta_input_device_native_new_virtual (
|
||||
device = _clutter_input_device_evdev_new_virtual (
|
||||
manager, seat, CLUTTER_POINTER_DEVICE,
|
||||
CLUTTER_INPUT_MODE_MASTER);
|
||||
stage = meta_device_manager_native_get_stage (manager_evdev);
|
||||
stage = _clutter_device_manager_evdev_get_stage (manager_evdev);
|
||||
_clutter_input_device_set_stage (device, stage);
|
||||
seat->pointer_x = INITIAL_POINTER_X;
|
||||
seat->pointer_y = INITIAL_POINTER_Y;
|
||||
@@ -173,7 +174,7 @@ meta_seat_native_new (MetaDeviceManagerNative *manager_evdev)
|
||||
_clutter_device_manager_add_device (manager, device);
|
||||
seat->core_pointer = device;
|
||||
|
||||
device = meta_input_device_native_new_virtual (
|
||||
device = _clutter_input_device_evdev_new_virtual (
|
||||
manager, seat, CLUTTER_KEYBOARD_DEVICE,
|
||||
CLUTTER_INPUT_MODE_MASTER);
|
||||
_clutter_input_device_set_stage (device, stage);
|
||||
@@ -185,7 +186,7 @@ meta_seat_native_new (MetaDeviceManagerNative *manager_evdev)
|
||||
seat->repeat_interval = 33; /* ms */
|
||||
|
||||
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
|
||||
xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap));
|
||||
xkb_keymap = clutter_keymap_evdev_get_keyboard_map (CLUTTER_KEYMAP_EVDEV (keymap));
|
||||
|
||||
if (xkb_keymap)
|
||||
{
|
||||
@@ -203,7 +204,7 @@ meta_seat_native_new (MetaDeviceManagerNative *manager_evdev)
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_clear_repeat_timer (MetaSeatNative *seat)
|
||||
clutter_seat_evdev_clear_repeat_timer (ClutterSeatEvdev *seat)
|
||||
{
|
||||
if (seat->repeat_timer)
|
||||
{
|
||||
@@ -216,24 +217,24 @@ meta_seat_native_clear_repeat_timer (MetaSeatNative *seat)
|
||||
static gboolean
|
||||
keyboard_repeat (gpointer data)
|
||||
{
|
||||
MetaSeatNative *seat = data;
|
||||
ClutterSeatEvdev *seat = data;
|
||||
GSource *source;
|
||||
|
||||
/* There might be events queued in libinput that could cancel the
|
||||
repeat timer. */
|
||||
meta_device_manager_native_dispatch (seat->manager_evdev);
|
||||
_clutter_device_manager_evdev_dispatch (seat->manager_evdev);
|
||||
if (!seat->repeat_timer)
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE);
|
||||
source = g_main_context_find_source_by_id (NULL, seat->repeat_timer);
|
||||
|
||||
meta_seat_native_notify_key (seat,
|
||||
seat->repeat_device,
|
||||
g_source_get_time (source),
|
||||
seat->repeat_key,
|
||||
AUTOREPEAT_VALUE,
|
||||
FALSE);
|
||||
clutter_seat_evdev_notify_key (seat,
|
||||
seat->repeat_device,
|
||||
g_source_get_time (source),
|
||||
seat->repeat_key,
|
||||
AUTOREPEAT_VALUE,
|
||||
FALSE);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
@@ -245,9 +246,9 @@ queue_event (ClutterEvent *event)
|
||||
}
|
||||
|
||||
static int
|
||||
update_button_count (MetaSeatNative *seat,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
update_button_count (ClutterSeatEvdev *seat,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
@@ -264,12 +265,12 @@ update_button_count (MetaSeatNative *seat,
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_key (MetaSeatNative *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
uint32_t key,
|
||||
uint32_t state,
|
||||
gboolean update_keys)
|
||||
clutter_seat_evdev_notify_key (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
uint32_t key,
|
||||
uint32_t state,
|
||||
gboolean update_keys)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
@@ -290,17 +291,17 @@ meta_seat_native_notify_key (MetaSeatNative *seat,
|
||||
stage = _clutter_input_device_get_stage (device);
|
||||
if (stage == NULL)
|
||||
{
|
||||
meta_seat_native_clear_repeat_timer (seat);
|
||||
clutter_seat_evdev_clear_repeat_timer (seat);
|
||||
return;
|
||||
}
|
||||
|
||||
event = meta_key_event_new_from_evdev (device,
|
||||
seat->core_keyboard,
|
||||
stage,
|
||||
seat->xkb,
|
||||
seat->button_state,
|
||||
us2ms (time_us), key, state);
|
||||
meta_event_native_set_event_code (event, key);
|
||||
event = _clutter_key_event_new_from_evdev (device,
|
||||
seat->core_keyboard,
|
||||
stage,
|
||||
seat->xkb,
|
||||
seat->button_state,
|
||||
us2ms (time_us), key, state);
|
||||
_clutter_evdev_event_set_event_code (event, key);
|
||||
|
||||
/* We must be careful and not pass multiple releases to xkb, otherwise it gets
|
||||
confused and locks the modifiers */
|
||||
@@ -324,8 +325,8 @@ meta_seat_native_notify_key (MetaSeatNative *seat,
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
g_signal_emit_by_name (clutter_backend_get_keymap (backend), "state-changed");
|
||||
meta_seat_native_sync_leds (seat);
|
||||
meta_input_device_native_a11y_maybe_notify_toggle_keys (META_INPUT_DEVICE_NATIVE (seat->core_keyboard));
|
||||
clutter_seat_evdev_sync_leds (seat);
|
||||
clutter_evdev_a11y_maybe_notify_toggle_keys (CLUTTER_INPUT_DEVICE_EVDEV (seat->core_keyboard));
|
||||
}
|
||||
|
||||
if (state == 0 || /* key release */
|
||||
@@ -333,7 +334,7 @@ meta_seat_native_notify_key (MetaSeatNative *seat,
|
||||
!xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb),
|
||||
event->key.hardware_keycode))
|
||||
{
|
||||
meta_seat_native_clear_repeat_timer (seat);
|
||||
clutter_seat_evdev_clear_repeat_timer (seat);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -348,9 +349,9 @@ meta_seat_native_notify_key (MetaSeatNative *seat,
|
||||
case 1:
|
||||
case 2:
|
||||
{
|
||||
uint32_t interval;
|
||||
guint32 interval;
|
||||
|
||||
meta_seat_native_clear_repeat_timer (seat);
|
||||
clutter_seat_evdev_clear_repeat_timer (seat);
|
||||
seat->repeat_device = g_object_ref (device);
|
||||
|
||||
if (seat->repeat_count == 1)
|
||||
@@ -372,12 +373,12 @@ meta_seat_native_notify_key (MetaSeatNative *seat,
|
||||
}
|
||||
|
||||
static ClutterEvent *
|
||||
new_absolute_motion_event (MetaSeatNative *seat,
|
||||
new_absolute_motion_event (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float x,
|
||||
float y,
|
||||
double *axes)
|
||||
guint64 time_us,
|
||||
gfloat x,
|
||||
gfloat y,
|
||||
gdouble *axes)
|
||||
{
|
||||
ClutterStage *stage = _clutter_input_device_get_stage (input_device);
|
||||
ClutterEvent *event;
|
||||
@@ -385,19 +386,17 @@ new_absolute_motion_event (MetaSeatNative *seat,
|
||||
event = clutter_event_new (CLUTTER_MOTION);
|
||||
|
||||
if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
|
||||
{
|
||||
meta_device_manager_native_constrain_pointer (seat->manager_evdev,
|
||||
seat->core_pointer,
|
||||
time_us,
|
||||
seat->pointer_x,
|
||||
seat->pointer_y,
|
||||
&x, &y);
|
||||
}
|
||||
_clutter_device_manager_evdev_constrain_pointer (seat->manager_evdev,
|
||||
seat->core_pointer,
|
||||
time_us,
|
||||
seat->pointer_x,
|
||||
seat->pointer_y,
|
||||
&x, &y);
|
||||
|
||||
meta_event_native_set_time_usec (event, time_us);
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->motion.time = us2ms (time_us);
|
||||
event->motion.stage = stage;
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
event->motion.x = x;
|
||||
event->motion.y = y;
|
||||
event->motion.axes = axes;
|
||||
@@ -406,8 +405,8 @@ new_absolute_motion_event (MetaSeatNative *seat,
|
||||
|
||||
if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
|
||||
{
|
||||
MetaInputDeviceNative *device_evdev =
|
||||
META_INPUT_DEVICE_NATIVE (input_device);
|
||||
ClutterInputDeviceEvdev *device_evdev =
|
||||
CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
|
||||
clutter_event_set_device_tool (event, device_evdev->last_tool);
|
||||
clutter_event_set_device (event, input_device);
|
||||
@@ -429,15 +428,15 @@ new_absolute_motion_event (MetaSeatNative *seat,
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_relative_motion (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float dx,
|
||||
float dy,
|
||||
float dx_unaccel,
|
||||
float dy_unaccel)
|
||||
clutter_seat_evdev_notify_relative_motion (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float dx,
|
||||
float dy,
|
||||
float dx_unaccel,
|
||||
float dy_unaccel)
|
||||
{
|
||||
float new_x, new_y;
|
||||
gfloat new_x, new_y;
|
||||
ClutterEvent *event;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
@@ -445,32 +444,31 @@ meta_seat_native_notify_relative_motion (MetaSeatNative *seat,
|
||||
if (!_clutter_input_device_get_stage (input_device))
|
||||
return;
|
||||
|
||||
meta_device_manager_native_filter_relative_motion (seat->manager_evdev,
|
||||
input_device,
|
||||
seat->pointer_x,
|
||||
seat->pointer_y,
|
||||
&dx,
|
||||
&dy);
|
||||
_clutter_device_manager_evdev_filter_relative_motion (seat->manager_evdev,
|
||||
input_device,
|
||||
seat->pointer_x,
|
||||
seat->pointer_y,
|
||||
&dx,
|
||||
&dy);
|
||||
|
||||
new_x = seat->pointer_x + dx;
|
||||
new_y = seat->pointer_y + dy;
|
||||
event = new_absolute_motion_event (seat, input_device,
|
||||
time_us, new_x, new_y, NULL);
|
||||
|
||||
meta_event_native_set_relative_motion (event,
|
||||
dx, dy,
|
||||
dx_unaccel, dy_unaccel);
|
||||
_clutter_evdev_event_set_relative_motion (event,
|
||||
dx, dy,
|
||||
dx_unaccel, dy_unaccel);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_absolute_motion (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float x,
|
||||
float y,
|
||||
double *axes)
|
||||
void clutter_seat_evdev_notify_absolute_motion (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float x,
|
||||
float y,
|
||||
double *axes)
|
||||
{
|
||||
ClutterEvent *event;
|
||||
|
||||
@@ -480,17 +478,17 @@ meta_seat_native_notify_absolute_motion (MetaSeatNative *seat,
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_button (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
{
|
||||
MetaInputDeviceNative *device_evdev = (MetaInputDeviceNative *) input_device;
|
||||
ClutterInputDeviceEvdev *device_evdev = (ClutterInputDeviceEvdev *) input_device;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
int button_nr;
|
||||
static int maskmap[8] =
|
||||
gint button_nr;
|
||||
static gint maskmap[8] =
|
||||
{
|
||||
CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON3_MASK, CLUTTER_BUTTON2_MASK,
|
||||
CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK, 0, 0, 0
|
||||
@@ -563,10 +561,10 @@ meta_seat_native_notify_button (MetaSeatNative *seat,
|
||||
seat->button_state &= ~maskmap[button_nr - 1];
|
||||
}
|
||||
|
||||
meta_event_native_set_time_usec (event, time_us);
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->button.time = us2ms (time_us);
|
||||
event->button.stage = CLUTTER_STAGE (stage);
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
event->button.button = button_nr;
|
||||
|
||||
if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
|
||||
@@ -589,15 +587,15 @@ meta_seat_native_notify_button (MetaSeatNative *seat,
|
||||
if (device_evdev->last_tool)
|
||||
{
|
||||
/* Apply the button event code as per the tool mapping */
|
||||
uint32_t mapped_button;
|
||||
guint mapped_button;
|
||||
|
||||
mapped_button = meta_input_device_tool_native_get_button_code (device_evdev->last_tool,
|
||||
button_nr);
|
||||
mapped_button = clutter_input_device_tool_evdev_get_button_code (device_evdev->last_tool,
|
||||
button_nr);
|
||||
if (mapped_button != 0)
|
||||
button = mapped_button;
|
||||
}
|
||||
|
||||
meta_event_native_set_event_code (event, button);
|
||||
_clutter_evdev_event_set_event_code (event, button);
|
||||
|
||||
if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
|
||||
{
|
||||
@@ -616,18 +614,18 @@ meta_seat_native_notify_button (MetaSeatNative *seat,
|
||||
|
||||
static void
|
||||
notify_scroll (ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
guint64 time_us,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags flags,
|
||||
gboolean emulated)
|
||||
{
|
||||
MetaInputDeviceNative *device_evdev;
|
||||
MetaSeatNative *seat;
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
double scroll_factor;
|
||||
gdouble scroll_factor;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
@@ -635,15 +633,15 @@ notify_scroll (ClutterInputDevice *input_device,
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
||||
seat = meta_input_device_native_get_seat (device_evdev);
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
meta_event_native_set_time_usec (event, time_us);
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
/* libinput pointer axis events are in pointer motion coordinate space.
|
||||
* To convert to Xi2 discrete step coordinate space, multiply the factor
|
||||
@@ -673,8 +671,8 @@ notify_discrete_scroll (ClutterInputDevice *input_device,
|
||||
ClutterScrollSource scroll_source,
|
||||
gboolean emulated)
|
||||
{
|
||||
MetaInputDeviceNative *device_evdev;
|
||||
MetaSeatNative *seat;
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
|
||||
@@ -687,15 +685,15 @@ notify_discrete_scroll (ClutterInputDevice *input_device,
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
||||
seat = meta_input_device_native_get_seat (device_evdev);
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
meta_event_native_set_time_usec (event, time_us);
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
event->scroll.direction = direction;
|
||||
|
||||
@@ -711,7 +709,7 @@ notify_discrete_scroll (ClutterInputDevice *input_device,
|
||||
}
|
||||
|
||||
static void
|
||||
check_notify_discrete_scroll (MetaSeatNative *seat,
|
||||
check_notify_discrete_scroll (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollSource scroll_source)
|
||||
@@ -742,13 +740,13 @@ check_notify_discrete_scroll (MetaSeatNative *seat,
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_scroll_continuous (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
clutter_seat_evdev_notify_scroll_continuous (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
{
|
||||
if (finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL)
|
||||
seat->accum_scroll_dx = 0;
|
||||
@@ -783,12 +781,12 @@ discrete_to_direction (double discrete_dx,
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_discrete_scroll (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double discrete_dx,
|
||||
double discrete_dy,
|
||||
ClutterScrollSource scroll_source)
|
||||
clutter_seat_evdev_notify_discrete_scroll (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double discrete_dx,
|
||||
double discrete_dy,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
notify_scroll (input_device, time_us,
|
||||
discrete_dx * DISCRETE_SCROLL_STEP,
|
||||
@@ -802,13 +800,13 @@ meta_seat_native_notify_discrete_scroll (MetaSeatNative *seat,
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_touch_event (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
ClutterEventType evtype,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y)
|
||||
clutter_seat_evdev_notify_touch_event (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
ClutterEventType evtype,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
@@ -821,18 +819,18 @@ meta_seat_native_notify_touch_event (MetaSeatNative *seat,
|
||||
|
||||
event = clutter_event_new (evtype);
|
||||
|
||||
meta_event_native_set_time_usec (event, time_us);
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->touch.time = us2ms (time_us);
|
||||
event->touch.stage = CLUTTER_STAGE (stage);
|
||||
event->touch.x = x;
|
||||
event->touch.y = y;
|
||||
meta_input_device_native_translate_coordinates (input_device, stage,
|
||||
&event->touch.x,
|
||||
&event->touch.y);
|
||||
clutter_input_device_evdev_translate_coordinates (input_device, stage,
|
||||
&event->touch.x,
|
||||
&event->touch.y);
|
||||
|
||||
/* "NULL" sequences are special cased in clutter */
|
||||
event->touch.sequence = GINT_TO_POINTER (MAX (1, slot + 1));
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
if (evtype == CLUTTER_TOUCH_BEGIN ||
|
||||
evtype == CLUTTER_TOUCH_UPDATE)
|
||||
@@ -845,7 +843,7 @@ meta_seat_native_notify_touch_event (MetaSeatNative *seat,
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_free (MetaSeatNative *seat)
|
||||
clutter_seat_evdev_free (ClutterSeatEvdev *seat)
|
||||
{
|
||||
GSList *iter;
|
||||
|
||||
@@ -860,7 +858,7 @@ meta_seat_native_free (MetaSeatNative *seat)
|
||||
|
||||
xkb_state_unref (seat->xkb);
|
||||
|
||||
meta_seat_native_clear_repeat_timer (seat);
|
||||
clutter_seat_evdev_clear_repeat_timer (seat);
|
||||
|
||||
if (seat->libinput_seat)
|
||||
libinput_seat_unref (seat->libinput_seat);
|
||||
@@ -869,8 +867,8 @@ meta_seat_native_free (MetaSeatNative *seat)
|
||||
}
|
||||
|
||||
ClutterInputDevice *
|
||||
meta_seat_native_get_device (MetaSeatNative *seat,
|
||||
int id)
|
||||
clutter_seat_evdev_get_device (ClutterSeatEvdev *seat,
|
||||
gint id)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
GSList *l;
|
||||
@@ -887,8 +885,8 @@ meta_seat_native_get_device (MetaSeatNative *seat,
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_set_stage (MetaSeatNative *seat,
|
||||
ClutterStage *stage)
|
||||
clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
|
||||
ClutterStage *stage)
|
||||
{
|
||||
GSList *l;
|
||||
|
163
clutter/clutter/evdev/clutter-seat-evdev.h
Normal file
163
clutter/clutter/evdev/clutter-seat-evdev.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corp.
|
||||
* Copyright (C) 2014 Jonas Ådahl
|
||||
* Copyright (C) 2016 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Damien Lespiau <damien.lespiau@intel.com>
|
||||
* Author: Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_SEAT_EVDEV_H__
|
||||
#define __CLUTTER_SEAT_EVDEV_H__
|
||||
|
||||
#include <libinput.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include "clutter-input-device.h"
|
||||
#include "clutter-device-manager-evdev.h"
|
||||
#include "clutter-xkb-utils.h"
|
||||
|
||||
typedef struct _ClutterTouchState ClutterTouchState;
|
||||
|
||||
struct _ClutterTouchState
|
||||
{
|
||||
ClutterSeatEvdev *seat;
|
||||
|
||||
int device_slot;
|
||||
int seat_slot;
|
||||
ClutterPoint coords;
|
||||
};
|
||||
|
||||
struct _ClutterSeatEvdev
|
||||
{
|
||||
struct libinput_seat *libinput_seat;
|
||||
ClutterDeviceManagerEvdev *manager_evdev;
|
||||
|
||||
GSList *devices;
|
||||
|
||||
ClutterInputDevice *core_pointer;
|
||||
ClutterInputDevice *core_keyboard;
|
||||
|
||||
ClutterTouchState **touch_states;
|
||||
int n_alloc_touch_states;
|
||||
|
||||
struct xkb_state *xkb;
|
||||
xkb_led_index_t caps_lock_led;
|
||||
xkb_led_index_t num_lock_led;
|
||||
xkb_led_index_t scroll_lock_led;
|
||||
xkb_layout_index_t layout_idx;
|
||||
uint32_t button_state;
|
||||
int button_count[KEY_CNT];
|
||||
|
||||
/* keyboard repeat */
|
||||
gboolean repeat;
|
||||
guint32 repeat_delay;
|
||||
guint32 repeat_interval;
|
||||
guint32 repeat_key;
|
||||
guint32 repeat_count;
|
||||
guint32 repeat_timer;
|
||||
ClutterInputDevice *repeat_device;
|
||||
|
||||
gfloat pointer_x;
|
||||
gfloat pointer_y;
|
||||
|
||||
/* Emulation of discrete scroll events out of smooth ones */
|
||||
gfloat accum_scroll_dx;
|
||||
gfloat accum_scroll_dy;
|
||||
};
|
||||
|
||||
void clutter_seat_evdev_notify_key (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
uint32_t key,
|
||||
uint32_t state,
|
||||
gboolean update_keys);
|
||||
|
||||
void clutter_seat_evdev_notify_relative_motion (ClutterSeatEvdev *seat_evdev,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float dx,
|
||||
float dy,
|
||||
float dx_unaccel,
|
||||
float dy_unaccel);
|
||||
|
||||
void clutter_seat_evdev_notify_absolute_motion (ClutterSeatEvdev *seat_evdev,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float x,
|
||||
float y,
|
||||
double *axes);
|
||||
|
||||
void clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
uint32_t button,
|
||||
uint32_t state);
|
||||
|
||||
void clutter_seat_evdev_notify_scroll_continuous (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource source,
|
||||
ClutterScrollFinishFlags flags);
|
||||
|
||||
void clutter_seat_evdev_notify_discrete_scroll (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double discrete_dx,
|
||||
double discrete_dy,
|
||||
ClutterScrollSource source);
|
||||
|
||||
void clutter_seat_evdev_notify_touch_event (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
ClutterEventType evtype,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y);
|
||||
|
||||
void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
|
||||
struct libinput_seat *libinput_seat);
|
||||
|
||||
void clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat);
|
||||
|
||||
ClutterInputDevice * clutter_seat_evdev_get_device (ClutterSeatEvdev *seat,
|
||||
gint id);
|
||||
|
||||
ClutterTouchState * clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat,
|
||||
int device_slot);
|
||||
|
||||
void clutter_seat_evdev_release_touch_state (ClutterSeatEvdev *seat,
|
||||
ClutterTouchState *touch_state);
|
||||
|
||||
ClutterTouchState * clutter_seat_evdev_get_touch (ClutterSeatEvdev *seat,
|
||||
guint32 id);
|
||||
|
||||
void clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
|
||||
ClutterStage *stage);
|
||||
|
||||
void clutter_seat_evdev_clear_repeat_timer (ClutterSeatEvdev *seat);
|
||||
|
||||
ClutterSeatEvdev * clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev);
|
||||
|
||||
void clutter_seat_evdev_free (ClutterSeatEvdev *seat);
|
||||
|
||||
#endif /* __CLUTTER_SEAT_EVDEV_H__ */
|
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2016 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -17,16 +21,17 @@
|
||||
* Author: Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include "backends/native/meta-input-device-native.h"
|
||||
#include "backends/native/meta-keymap-native.h"
|
||||
#include "backends/native/meta-seat-native.h"
|
||||
#include "backends/native/meta-virtual-input-device-native.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-virtual-input-device.h"
|
||||
#include "evdev/clutter-input-device-evdev.h"
|
||||
#include "evdev/clutter-keymap-evdev.h"
|
||||
#include "evdev/clutter-seat-evdev.h"
|
||||
#include "evdev/clutter-virtual-input-device-evdev.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -39,17 +44,17 @@ enum
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
struct _MetaVirtualInputDeviceNative
|
||||
struct _ClutterVirtualInputDeviceEvdev
|
||||
{
|
||||
ClutterVirtualInputDevice parent;
|
||||
|
||||
ClutterInputDevice *device;
|
||||
MetaSeatNative *seat;
|
||||
ClutterSeatEvdev *seat;
|
||||
int button_count[KEY_CNT];
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaVirtualInputDeviceNative,
|
||||
meta_virtual_input_device_native,
|
||||
G_DEFINE_TYPE (ClutterVirtualInputDeviceEvdev,
|
||||
clutter_virtual_input_device_evdev,
|
||||
CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE)
|
||||
|
||||
typedef enum _EvdevButtonType
|
||||
@@ -60,9 +65,9 @@ typedef enum _EvdevButtonType
|
||||
} EvdevButtonType;
|
||||
|
||||
static int
|
||||
update_button_count (MetaVirtualInputDeviceNative *virtual_evdev,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
update_button_count (ClutterVirtualInputDeviceEvdev *virtual_evdev,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
{
|
||||
if (state)
|
||||
return ++virtual_evdev->button_count[button];
|
||||
@@ -109,8 +114,8 @@ get_button_type (uint16_t code)
|
||||
static void
|
||||
release_pressed_buttons (ClutterVirtualInputDevice *virtual_device)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
int code;
|
||||
uint64_t time_us;
|
||||
|
||||
@@ -142,41 +147,41 @@ release_pressed_buttons (ClutterVirtualInputDevice *virtual_device)
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy)
|
||||
clutter_virtual_input_device_evdev_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
meta_seat_native_notify_relative_motion (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
dx, dy,
|
||||
dx, dy);
|
||||
clutter_seat_evdev_notify_relative_motion (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
dx, dy,
|
||||
dx, dy);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double x,
|
||||
double y)
|
||||
clutter_virtual_input_device_evdev_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
meta_seat_native_notify_absolute_motion (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
x, y,
|
||||
NULL);
|
||||
clutter_seat_evdev_notify_absolute_motion (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
x, y,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -200,13 +205,13 @@ translate_to_evdev_button (int clutter_button)
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t button,
|
||||
ClutterButtonState button_state)
|
||||
clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t button,
|
||||
ClutterButtonState button_state)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
int button_count;
|
||||
int evdev_button;
|
||||
|
||||
@@ -231,21 +236,21 @@ meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtu
|
||||
return;
|
||||
}
|
||||
|
||||
meta_seat_native_notify_button (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
evdev_button,
|
||||
button_state);
|
||||
clutter_seat_evdev_notify_button (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
evdev_button,
|
||||
button_state);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t key,
|
||||
ClutterKeyState key_state)
|
||||
clutter_virtual_input_device_evdev_notify_key (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t key,
|
||||
ClutterKeyState key_state)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
int key_count;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
@@ -266,12 +271,12 @@ meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_
|
||||
return;
|
||||
}
|
||||
|
||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
key,
|
||||
key_state,
|
||||
TRUE);
|
||||
clutter_seat_evdev_notify_key (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
key,
|
||||
key_state,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -280,8 +285,8 @@ pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_dev
|
||||
guint *keycode_out,
|
||||
guint *level_out)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
ClutterKeymap *keymap;
|
||||
struct xkb_keymap *xkb_keymap;
|
||||
struct xkb_state *state;
|
||||
@@ -289,7 +294,7 @@ pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_dev
|
||||
xkb_keycode_t min_keycode, max_keycode;
|
||||
|
||||
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
|
||||
xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap));
|
||||
xkb_keymap = clutter_keymap_evdev_get_keyboard_map (CLUTTER_KEYMAP_EVDEV (keymap));
|
||||
state = virtual_evdev->seat->xkb;
|
||||
|
||||
layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE);
|
||||
@@ -326,8 +331,8 @@ apply_level_modifiers (ClutterVirtualInputDevice *virtual_device,
|
||||
uint32_t level,
|
||||
uint32_t key_state)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
guint keysym, keycode, evcode;
|
||||
|
||||
if (level == 0)
|
||||
@@ -353,22 +358,22 @@ apply_level_modifiers (ClutterVirtualInputDevice *virtual_device,
|
||||
|
||||
clutter_input_device_keycode_to_evdev (virtual_evdev->device,
|
||||
keycode, &evcode);
|
||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
evcode,
|
||||
key_state,
|
||||
TRUE);
|
||||
clutter_seat_evdev_notify_key (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
evcode,
|
||||
key_state,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t keyval,
|
||||
ClutterKeyState key_state)
|
||||
clutter_virtual_input_device_evdev_notify_keyval (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t keyval,
|
||||
ClutterKeyState key_state)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
int key_count;
|
||||
guint keycode = 0, level = 0, evcode = 0;
|
||||
|
||||
@@ -403,12 +408,12 @@ meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtu
|
||||
if (key_state)
|
||||
apply_level_modifiers (virtual_device, time_us, level, key_state);
|
||||
|
||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
evcode,
|
||||
key_state,
|
||||
TRUE);
|
||||
clutter_seat_evdev_notify_key (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
evcode,
|
||||
key_state,
|
||||
TRUE);
|
||||
|
||||
if (!key_state)
|
||||
apply_level_modifiers (virtual_device, time_us, level, key_state);
|
||||
@@ -444,13 +449,13 @@ direction_to_discrete (ClutterScrollDirection direction,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source)
|
||||
clutter_virtual_input_device_evdev_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
double discrete_dx = 0.0, discrete_dy = 0.0;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
@@ -458,139 +463,139 @@ meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevi
|
||||
|
||||
direction_to_discrete (direction, &discrete_dx, &discrete_dy);
|
||||
|
||||
meta_seat_native_notify_discrete_scroll (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
discrete_dx, discrete_dy,
|
||||
scroll_source);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
meta_seat_native_notify_scroll_continuous (virtual_evdev->seat,
|
||||
clutter_seat_evdev_notify_discrete_scroll (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
dx, dy,
|
||||
scroll_source,
|
||||
CLUTTER_SCROLL_FINISHED_NONE);
|
||||
discrete_dx, discrete_dy,
|
||||
scroll_source);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
clutter_virtual_input_device_evdev_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
MetaInputDeviceNative *device_evdev =
|
||||
META_INPUT_DEVICE_NATIVE (virtual_evdev->device);
|
||||
MetaTouchState *touch_state;
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
touch_state = meta_input_device_native_acquire_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
return;
|
||||
|
||||
touch_state->coords.x = x;
|
||||
touch_state->coords.y = y;
|
||||
|
||||
meta_seat_native_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
clutter_seat_evdev_notify_scroll_continuous (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
dx, dy,
|
||||
scroll_source,
|
||||
CLUTTER_SCROLL_FINISHED_NONE);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
clutter_virtual_input_device_evdev_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
MetaInputDeviceNative *device_evdev =
|
||||
META_INPUT_DEVICE_NATIVE (virtual_evdev->device);
|
||||
MetaTouchState *touch_state;
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
ClutterInputDeviceEvdev *device_evdev =
|
||||
CLUTTER_INPUT_DEVICE_EVDEV (virtual_evdev->device);
|
||||
ClutterTouchState *touch_state;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
touch_state = meta_input_device_native_lookup_touch_state (device_evdev,
|
||||
device_slot);
|
||||
touch_state = clutter_input_device_evdev_acquire_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
return;
|
||||
|
||||
touch_state->coords.x = x;
|
||||
touch_state->coords.y = y;
|
||||
|
||||
meta_seat_native_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
clutter_seat_evdev_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot)
|
||||
clutter_virtual_input_device_evdev_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
MetaInputDeviceNative *device_evdev =
|
||||
META_INPUT_DEVICE_NATIVE (virtual_evdev->device);
|
||||
MetaTouchState *touch_state;
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
ClutterInputDeviceEvdev *device_evdev =
|
||||
CLUTTER_INPUT_DEVICE_EVDEV (virtual_evdev->device);
|
||||
ClutterTouchState *touch_state;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
touch_state = meta_input_device_native_lookup_touch_state (device_evdev,
|
||||
device_slot);
|
||||
touch_state = clutter_input_device_evdev_lookup_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
return;
|
||||
|
||||
meta_seat_native_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
touch_state->coords.x = x;
|
||||
touch_state->coords.y = y;
|
||||
|
||||
meta_input_device_native_release_touch_state (device_evdev, touch_state);
|
||||
clutter_seat_evdev_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
clutter_virtual_input_device_evdev_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
ClutterInputDeviceEvdev *device_evdev =
|
||||
CLUTTER_INPUT_DEVICE_EVDEV (virtual_evdev->device);
|
||||
ClutterTouchState *touch_state;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
touch_state = clutter_input_device_evdev_lookup_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
return;
|
||||
|
||||
clutter_seat_evdev_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
|
||||
clutter_input_device_evdev_release_touch_state (device_evdev, touch_state);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_evdev_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -604,13 +609,13 @@ meta_virtual_input_device_native_get_property (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
clutter_virtual_input_device_evdev_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -624,12 +629,12 @@ meta_virtual_input_device_native_set_property (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_constructed (GObject *object)
|
||||
clutter_virtual_input_device_evdev_constructed (GObject *object)
|
||||
{
|
||||
ClutterVirtualInputDevice *virtual_device =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE (object);
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object);
|
||||
ClutterDeviceManager *manager;
|
||||
ClutterInputDeviceType device_type;
|
||||
ClutterStage *stage;
|
||||
@@ -638,63 +643,63 @@ meta_virtual_input_device_native_constructed (GObject *object)
|
||||
device_type = clutter_virtual_input_device_get_device_type (virtual_device);
|
||||
|
||||
virtual_evdev->device =
|
||||
meta_input_device_native_new_virtual (manager,
|
||||
virtual_evdev->seat,
|
||||
device_type,
|
||||
CLUTTER_INPUT_MODE_SLAVE);
|
||||
_clutter_input_device_evdev_new_virtual (manager,
|
||||
virtual_evdev->seat,
|
||||
device_type,
|
||||
CLUTTER_INPUT_MODE_SLAVE);
|
||||
|
||||
stage = meta_device_manager_native_get_stage (META_DEVICE_MANAGER_NATIVE (manager));
|
||||
stage = _clutter_device_manager_evdev_get_stage (CLUTTER_DEVICE_MANAGER_EVDEV (manager));
|
||||
_clutter_input_device_set_stage (virtual_evdev->device, stage);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_finalize (GObject *object)
|
||||
clutter_virtual_input_device_evdev_finalize (GObject *object)
|
||||
{
|
||||
ClutterVirtualInputDevice *virtual_device =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE (object);
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object);
|
||||
GObjectClass *object_class;
|
||||
|
||||
release_pressed_buttons (virtual_device);
|
||||
g_clear_object (&virtual_evdev->device);
|
||||
|
||||
object_class =
|
||||
G_OBJECT_CLASS (meta_virtual_input_device_native_parent_class);
|
||||
G_OBJECT_CLASS (clutter_virtual_input_device_evdev_parent_class);
|
||||
object_class->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_init (MetaVirtualInputDeviceNative *virtual_device_evdev)
|
||||
clutter_virtual_input_device_evdev_init (ClutterVirtualInputDeviceEvdev *virtual_device_evdev)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_class_init (MetaVirtualInputDeviceNativeClass *klass)
|
||||
clutter_virtual_input_device_evdev_class_init (ClutterVirtualInputDeviceEvdevClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterVirtualInputDeviceClass *virtual_input_device_class =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_CLASS (klass);
|
||||
|
||||
object_class->get_property = meta_virtual_input_device_native_get_property;
|
||||
object_class->set_property = meta_virtual_input_device_native_set_property;
|
||||
object_class->constructed = meta_virtual_input_device_native_constructed;
|
||||
object_class->finalize = meta_virtual_input_device_native_finalize;
|
||||
object_class->get_property = clutter_virtual_input_device_evdev_get_property;
|
||||
object_class->set_property = clutter_virtual_input_device_evdev_set_property;
|
||||
object_class->constructed = clutter_virtual_input_device_evdev_constructed;
|
||||
object_class->finalize = clutter_virtual_input_device_evdev_finalize;
|
||||
|
||||
virtual_input_device_class->notify_relative_motion = meta_virtual_input_device_native_notify_relative_motion;
|
||||
virtual_input_device_class->notify_absolute_motion = meta_virtual_input_device_native_notify_absolute_motion;
|
||||
virtual_input_device_class->notify_button = meta_virtual_input_device_native_notify_button;
|
||||
virtual_input_device_class->notify_key = meta_virtual_input_device_native_notify_key;
|
||||
virtual_input_device_class->notify_keyval = meta_virtual_input_device_native_notify_keyval;
|
||||
virtual_input_device_class->notify_discrete_scroll = meta_virtual_input_device_native_notify_discrete_scroll;
|
||||
virtual_input_device_class->notify_scroll_continuous = meta_virtual_input_device_native_notify_scroll_continuous;
|
||||
virtual_input_device_class->notify_touch_down = meta_virtual_input_device_native_notify_touch_down;
|
||||
virtual_input_device_class->notify_touch_motion = meta_virtual_input_device_native_notify_touch_motion;
|
||||
virtual_input_device_class->notify_touch_up = meta_virtual_input_device_native_notify_touch_up;
|
||||
virtual_input_device_class->notify_relative_motion = clutter_virtual_input_device_evdev_notify_relative_motion;
|
||||
virtual_input_device_class->notify_absolute_motion = clutter_virtual_input_device_evdev_notify_absolute_motion;
|
||||
virtual_input_device_class->notify_button = clutter_virtual_input_device_evdev_notify_button;
|
||||
virtual_input_device_class->notify_key = clutter_virtual_input_device_evdev_notify_key;
|
||||
virtual_input_device_class->notify_keyval = clutter_virtual_input_device_evdev_notify_keyval;
|
||||
virtual_input_device_class->notify_discrete_scroll = clutter_virtual_input_device_evdev_notify_discrete_scroll;
|
||||
virtual_input_device_class->notify_scroll_continuous = clutter_virtual_input_device_evdev_notify_scroll_continuous;
|
||||
virtual_input_device_class->notify_touch_down = clutter_virtual_input_device_evdev_notify_touch_down;
|
||||
virtual_input_device_class->notify_touch_motion = clutter_virtual_input_device_evdev_notify_touch_motion;
|
||||
virtual_input_device_class->notify_touch_up = clutter_virtual_input_device_evdev_notify_touch_up;
|
||||
|
||||
obj_props[PROP_SEAT] = g_param_spec_pointer ("seat",
|
||||
"Seat",
|
||||
"Seat",
|
||||
P_("ClutterSeatEvdev"),
|
||||
P_("ClutterSeatEvdev"),
|
||||
CLUTTER_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
|
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2016 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -17,15 +21,15 @@
|
||||
* Author: Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_VIRTUAL_INPUT_DEVICE_NATIVE_H
|
||||
#define META_VIRTUAL_INPUT_DEVICE_NATIVE_H
|
||||
#ifndef __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_H__
|
||||
#define __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_H__
|
||||
|
||||
#include "clutter/clutter-virtual-input-device.h"
|
||||
#include "clutter-virtual-input-device.h"
|
||||
|
||||
#define META_TYPE_VIRTUAL_INPUT_DEVICE_NATIVE (meta_virtual_input_device_native_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaVirtualInputDeviceNative,
|
||||
meta_virtual_input_device_native,
|
||||
META, VIRTUAL_INPUT_DEVICE_NATIVE,
|
||||
#define CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_EVDEV (clutter_virtual_input_device_evdev_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (ClutterVirtualInputDeviceEvdev,
|
||||
clutter_virtual_input_device_evdev,
|
||||
CLUTTER, VIRTUAL_INPUT_DEVICE_EVDEV,
|
||||
ClutterVirtualInputDevice)
|
||||
|
||||
#endif /* META_VIRTUAL_INPUT_DEVICE_NATIVE_H */
|
||||
#endif /* __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_H__ */
|
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -19,11 +23,11 @@
|
||||
* Damien Lespiau <damien.lespiau@intel.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "backends/native/meta-xkb-utils.h"
|
||||
#include "clutter/clutter-keysyms.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter-keysyms.h"
|
||||
#include "clutter-event-private.h"
|
||||
#include "clutter-xkb-utils.h"
|
||||
|
||||
/*
|
||||
* _clutter_event_new_from_evdev: Create a new Clutter ClutterKeyEvent
|
||||
@@ -40,14 +44,14 @@
|
||||
* Return value: the new #ClutterEvent
|
||||
*/
|
||||
ClutterEvent *
|
||||
meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
||||
ClutterInputDevice *core_device,
|
||||
ClutterStage *stage,
|
||||
struct xkb_state *xkb_state,
|
||||
uint32_t button_state,
|
||||
uint32_t _time,
|
||||
xkb_keycode_t key,
|
||||
uint32_t state)
|
||||
_clutter_key_event_new_from_evdev (ClutterInputDevice *device,
|
||||
ClutterInputDevice *core_device,
|
||||
ClutterStage *stage,
|
||||
struct xkb_state *xkb_state,
|
||||
uint32_t button_state,
|
||||
uint32_t _time,
|
||||
xkb_keycode_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
ClutterEvent *event;
|
||||
xkb_keysym_t sym;
|
||||
@@ -74,7 +78,7 @@ meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
||||
|
||||
event->key.stage = stage;
|
||||
event->key.time = _time;
|
||||
meta_xkb_translate_state (event, xkb_state, button_state);
|
||||
_clutter_xkb_translate_state (event, xkb_state, button_state);
|
||||
event->key.hardware_keycode = key;
|
||||
event->key.keyval = sym;
|
||||
clutter_event_set_device (event, core_device);
|
||||
@@ -98,9 +102,9 @@ meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
||||
}
|
||||
|
||||
void
|
||||
meta_xkb_translate_state (ClutterEvent *event,
|
||||
struct xkb_state *state,
|
||||
uint32_t button_state)
|
||||
_clutter_xkb_translate_state (ClutterEvent *event,
|
||||
struct xkb_state *state,
|
||||
uint32_t button_state)
|
||||
{
|
||||
_clutter_event_set_state_full (event,
|
||||
button_state,
|
46
clutter/clutter/evdev/clutter-xkb-utils.h
Normal file
46
clutter/clutter/evdev/clutter-xkb-utils.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
* Authors:
|
||||
* Damien Lespiau <damien.lespiau@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_XKB_UTILS_H__
|
||||
#define __CLUTTER_XKB_UTILS_H__
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include "clutter-stage.h"
|
||||
#include "clutter-event.h"
|
||||
#include "clutter-input-device.h"
|
||||
|
||||
ClutterEvent * _clutter_key_event_new_from_evdev (ClutterInputDevice *device,
|
||||
ClutterInputDevice *core_keyboard,
|
||||
ClutterStage *stage,
|
||||
struct xkb_state *xkb_state,
|
||||
uint32_t button_state,
|
||||
uint32_t _time,
|
||||
uint32_t key,
|
||||
uint32_t state);
|
||||
void _clutter_xkb_translate_state (ClutterEvent *event,
|
||||
struct xkb_state *xkb_state,
|
||||
uint32_t button_state);
|
||||
|
||||
#endif /* __CLUTTER_XKB_UTILS_H__ */
|
@@ -77,6 +77,7 @@ clutter_headers = [
|
||||
'clutter-stage-manager.h',
|
||||
'clutter-stage-view.h',
|
||||
'clutter-tap-action.h',
|
||||
'clutter-test-utils.h',
|
||||
'clutter-texture.h',
|
||||
'clutter-text.h',
|
||||
'clutter-text-buffer.h',
|
||||
@@ -167,6 +168,7 @@ clutter_sources = [
|
||||
'clutter-stage-view.c',
|
||||
'clutter-stage-window.c',
|
||||
'clutter-tap-action.c',
|
||||
'clutter-test-utils.c',
|
||||
'clutter-text.c',
|
||||
'clutter-text-buffer.c',
|
||||
'clutter-transition-group.c',
|
||||
@@ -189,6 +191,7 @@ clutter_private_headers = [
|
||||
'clutter-device-manager-private.h',
|
||||
'clutter-easing.h',
|
||||
'clutter-effect-private.h',
|
||||
'clutter-event-translator.h',
|
||||
'clutter-event-private.h',
|
||||
'clutter-flatten-effect.h',
|
||||
'clutter-gesture-action-private.h',
|
||||
@@ -212,6 +215,7 @@ clutter_private_headers = [
|
||||
|
||||
clutter_nonintrospected_sources = [
|
||||
'clutter-easing.c',
|
||||
'clutter-event-translator.c',
|
||||
'clutter-id-pool.c',
|
||||
]
|
||||
|
||||
@@ -269,9 +273,21 @@ clutter_backend_private_headers = [
|
||||
if have_x11
|
||||
clutter_x11_sources = [
|
||||
'x11/clutter-backend-x11.c',
|
||||
'x11/clutter-device-manager-xi2.c',
|
||||
'x11/clutter-event-x11.c',
|
||||
'x11/clutter-input-device-tool-xi2.c',
|
||||
'x11/clutter-input-device-xi2.c',
|
||||
'x11/clutter-keymap-x11.c',
|
||||
'x11/clutter-stage-x11.c',
|
||||
'x11/clutter-virtual-input-device-x11.c',
|
||||
]
|
||||
clutter_backend_sources += clutter_x11_sources
|
||||
|
||||
clutter_x11_nonintrospected_sources = [
|
||||
'x11/clutter-xkb-a11y-x11.c',
|
||||
]
|
||||
clutter_backend_nonintrospected_sources += clutter_x11_nonintrospected_sources
|
||||
|
||||
clutter_x11_headers = [
|
||||
'x11/clutter-x11.h',
|
||||
]
|
||||
@@ -279,7 +295,14 @@ if have_x11
|
||||
|
||||
clutter_x11_private_headers = [
|
||||
'x11/clutter-backend-x11.h',
|
||||
'x11/clutter-device-manager-xi2.h',
|
||||
'x11/clutter-input-device-tool-xi2.h',
|
||||
'x11/clutter-input-device-xi2.h',
|
||||
'x11/clutter-keymap-x11.h',
|
||||
'x11/clutter-settings-x11.h',
|
||||
'x11/clutter-stage-x11.h',
|
||||
'x11/clutter-virtual-input-device-x11.h',
|
||||
'x11/clutter-xkb-a11y-x11.h',
|
||||
]
|
||||
clutter_backend_private_headers += clutter_x11_private_headers
|
||||
|
||||
@@ -295,8 +318,28 @@ endif
|
||||
if have_native_backend
|
||||
clutter_native_nonintrospected_sources = [
|
||||
'egl/clutter-backend-eglnative.c',
|
||||
'evdev/clutter-device-manager-evdev.c',
|
||||
'evdev/clutter-event-evdev.c',
|
||||
'evdev/clutter-input-device-evdev.c',
|
||||
'evdev/clutter-input-device-tool-evdev.c',
|
||||
'evdev/clutter-keymap-evdev.c',
|
||||
'evdev/clutter-seat-evdev.c',
|
||||
'evdev/clutter-virtual-input-device-evdev.c',
|
||||
'evdev/clutter-xkb-utils.c',
|
||||
]
|
||||
clutter_backend_nonintrospected_sources += clutter_native_nonintrospected_sources
|
||||
|
||||
clutter_native_private_headers = [
|
||||
'evdev/clutter-evdev.h',
|
||||
'evdev/clutter-device-manager-evdev.h',
|
||||
'evdev/clutter-input-device-evdev.h',
|
||||
'evdev/clutter-input-device-tool-evdev.h',
|
||||
'evdev/clutter-keymap-evdev.h',
|
||||
'evdev/clutter-seat-evdev.h',
|
||||
'evdev/clutter-virtual-input-device-evdev.h',
|
||||
'evdev/clutter-xkb-utils.h',
|
||||
]
|
||||
clutter_backend_private_headers += clutter_native_private_headers
|
||||
endif
|
||||
|
||||
if have_wayland
|
||||
|
@@ -34,7 +34,9 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "clutter-backend-x11.h"
|
||||
#include "clutter-device-manager-xi2.h"
|
||||
#include "clutter-settings-x11.h"
|
||||
#include "clutter-stage-x11.h"
|
||||
#include "clutter-x11.h"
|
||||
|
||||
#include "xsettings/xsettings-common.h"
|
||||
@@ -52,6 +54,7 @@
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-settings-private.h"
|
||||
#include "clutter-xkb-a11y-x11.h"
|
||||
|
||||
G_DEFINE_TYPE (ClutterBackendX11, clutter_backend_x11, CLUTTER_TYPE_BACKEND)
|
||||
|
||||
@@ -98,6 +101,7 @@ static const gchar *atom_names[] = {
|
||||
#define N_ATOM_NAMES G_N_ELEMENTS (atom_names)
|
||||
|
||||
/* various flags corresponding to pre init setup calls */
|
||||
static gboolean _no_xevent_retrieval = FALSE;
|
||||
static gboolean clutter_enable_xinput = TRUE;
|
||||
static gboolean clutter_enable_argb = FALSE;
|
||||
static gboolean clutter_enable_stereo = FALSE;
|
||||
@@ -225,6 +229,91 @@ clutter_backend_x11_xsettings_notify (const char *name,
|
||||
g_object_thaw_notify (G_OBJECT (settings));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_x11_create_device_manager (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
ClutterEventTranslator *translator;
|
||||
ClutterBackend *backend;
|
||||
|
||||
if (clutter_enable_xinput)
|
||||
{
|
||||
int event_base, first_event, first_error;
|
||||
|
||||
if (XQueryExtension (backend_x11->xdpy, "XInputExtension",
|
||||
&event_base,
|
||||
&first_event,
|
||||
&first_error))
|
||||
{
|
||||
int major = 2;
|
||||
int minor = 3;
|
||||
|
||||
if (XIQueryVersion (backend_x11->xdpy, &major, &minor) != BadRequest)
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "Creating XI2 device manager");
|
||||
backend_x11->has_xinput = TRUE;
|
||||
backend_x11->device_manager =
|
||||
g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_XI2,
|
||||
"backend", backend_x11,
|
||||
"opcode", event_base,
|
||||
NULL);
|
||||
|
||||
backend_x11->xi_minor = minor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (backend_x11->device_manager == NULL)
|
||||
{
|
||||
g_critical ("XI2 extension is missing.");
|
||||
backend_x11->has_xinput = FALSE;
|
||||
backend_x11->xi_minor = -1;
|
||||
}
|
||||
|
||||
backend = CLUTTER_BACKEND (backend_x11);
|
||||
backend->device_manager = backend_x11->device_manager;
|
||||
|
||||
translator = CLUTTER_EVENT_TRANSLATOR (backend_x11->device_manager);
|
||||
_clutter_backend_add_event_translator (backend, translator);
|
||||
}
|
||||
|
||||
static void
|
||||
on_keymap_state_change (ClutterKeymapX11 *keymap_x11,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterDeviceManager *device_manager = CLUTTER_DEVICE_MANAGER (data);
|
||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
||||
|
||||
/* On keymaps state change, just reapply the current settings, it'll
|
||||
* take care of enabling/disabling mousekeys based on NumLock state.
|
||||
*/
|
||||
clutter_device_manager_get_kbd_a11y_settings (device_manager, &kbd_a11y_settings);
|
||||
clutter_device_manager_x11_apply_kbd_a11y_settings (device_manager, &kbd_a11y_settings);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_x11_create_keymap (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
if (backend_x11->keymap == NULL)
|
||||
{
|
||||
ClutterEventTranslator *translator;
|
||||
ClutterBackend *backend;
|
||||
|
||||
backend_x11->keymap =
|
||||
g_object_new (CLUTTER_TYPE_KEYMAP_X11,
|
||||
"backend", backend_x11,
|
||||
NULL);
|
||||
|
||||
backend = CLUTTER_BACKEND (backend_x11);
|
||||
translator = CLUTTER_EVENT_TRANSLATOR (backend_x11->keymap);
|
||||
_clutter_backend_add_event_translator (backend, translator);
|
||||
|
||||
g_signal_connect (backend_x11->keymap,
|
||||
"state-changed",
|
||||
G_CALLBACK (on_keymap_state_change),
|
||||
backend->device_manager);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_backend_x11_pre_parse (ClutterBackend *backend,
|
||||
GError **error)
|
||||
@@ -372,6 +461,45 @@ clutter_backend_x11_post_parse (ClutterBackend *backend,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_backend_x11_events_init (ClutterBackend *backend)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
CLUTTER_NOTE (EVENT, "initialising the event loop");
|
||||
|
||||
/* the event source is optional */
|
||||
if (!_no_xevent_retrieval)
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
source = _clutter_x11_event_source_new (backend_x11);
|
||||
|
||||
/* default priority for events
|
||||
*
|
||||
* XXX - at some point we'll have a common EventSource API that
|
||||
* is created by the backend, and this code will most likely go
|
||||
* into the default implementation of ClutterBackend
|
||||
*/
|
||||
g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);
|
||||
|
||||
/* attach the source to the default context, and transfer the
|
||||
* ownership to the GMainContext itself
|
||||
*/
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
|
||||
backend_x11->event_source = source;
|
||||
}
|
||||
|
||||
clutter_backend_x11_create_device_manager (backend_x11);
|
||||
|
||||
/* register keymap; unless we create a generic Keymap object, I'm
|
||||
* afraid this will have to stay
|
||||
*/
|
||||
clutter_backend_x11_create_keymap (backend_x11);
|
||||
}
|
||||
|
||||
static const GOptionEntry entries[] =
|
||||
{
|
||||
{
|
||||
@@ -491,6 +619,7 @@ clutter_backend_x11_translate_event (ClutterBackend *backend,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
ClutterBackendClass *parent_class;
|
||||
XEvent *xevent = native;
|
||||
|
||||
/* X11 filter functions have a higher priority */
|
||||
@@ -526,7 +655,11 @@ clutter_backend_x11_translate_event (ClutterBackend *backend,
|
||||
*/
|
||||
update_last_event_time (backend_x11, xevent);
|
||||
|
||||
return FALSE;
|
||||
/* chain up to the parent implementation, which will handle
|
||||
* event translators
|
||||
*/
|
||||
parent_class = CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class);
|
||||
return parent_class->translate_event (backend, native, event);
|
||||
}
|
||||
|
||||
static CoglRenderer *
|
||||
@@ -646,6 +779,50 @@ clutter_backend_x11_get_display (ClutterBackend *backend,
|
||||
return display;
|
||||
}
|
||||
|
||||
static ClutterStageWindow *
|
||||
clutter_backend_x11_create_stage (ClutterBackend *backend,
|
||||
ClutterStage *wrapper,
|
||||
GError **error)
|
||||
{
|
||||
ClutterEventTranslator *translator;
|
||||
ClutterStageWindow *stage;
|
||||
|
||||
stage = g_object_new (CLUTTER_TYPE_STAGE_X11,
|
||||
"backend", backend,
|
||||
"wrapper", wrapper,
|
||||
NULL);
|
||||
|
||||
/* the X11 stage does event translation */
|
||||
translator = CLUTTER_EVENT_TRANSLATOR (stage);
|
||||
_clutter_backend_add_event_translator (backend, translator);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "X11 stage created (display:%p, screen:%d, root:%u)",
|
||||
CLUTTER_BACKEND_X11 (backend)->xdpy,
|
||||
CLUTTER_BACKEND_X11 (backend)->xscreen_num,
|
||||
(unsigned int) CLUTTER_BACKEND_X11 (backend)->xwin_root);
|
||||
|
||||
return stage;
|
||||
}
|
||||
|
||||
static PangoDirection
|
||||
clutter_backend_x11_get_keymap_direction (ClutterBackend *backend)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
if (G_UNLIKELY (backend_x11->keymap == NULL))
|
||||
return PANGO_DIRECTION_NEUTRAL;
|
||||
|
||||
return _clutter_keymap_x11_get_direction (backend_x11->keymap);
|
||||
}
|
||||
|
||||
static ClutterKeymap *
|
||||
clutter_backend_x11_get_keymap (ClutterBackend *backend)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
return CLUTTER_KEYMAP (backend_x11->keymap);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_x11_class_init (ClutterBackendX11Class *klass)
|
||||
{
|
||||
@@ -655,6 +832,8 @@ clutter_backend_x11_class_init (ClutterBackendX11Class *klass)
|
||||
gobject_class->dispose = clutter_backend_x11_dispose;
|
||||
gobject_class->finalize = clutter_backend_x11_finalize;
|
||||
|
||||
backend_class->create_stage = clutter_backend_x11_create_stage;
|
||||
|
||||
backend_class->pre_parse = clutter_backend_x11_pre_parse;
|
||||
backend_class->post_parse = clutter_backend_x11_post_parse;
|
||||
backend_class->add_options = clutter_backend_x11_add_options;
|
||||
@@ -664,6 +843,9 @@ clutter_backend_x11_class_init (ClutterBackendX11Class *klass)
|
||||
|
||||
backend_class->get_renderer = clutter_backend_x11_get_renderer;
|
||||
backend_class->get_display = clutter_backend_x11_get_display;
|
||||
|
||||
backend_class->get_keymap_direction = clutter_backend_x11_get_keymap_direction;
|
||||
backend_class->get_keymap = clutter_backend_x11_get_keymap;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -774,6 +956,58 @@ clutter_x11_set_display (Display *xdpy)
|
||||
_foreign_dpy= xdpy;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_disable_event_retrieval:
|
||||
*
|
||||
* Disables the internal polling of X11 events in the main loop.
|
||||
*
|
||||
* Libraries or applications calling this function will be responsible of
|
||||
* polling all X11 events.
|
||||
*
|
||||
* You also must call clutter_x11_handle_event() to let Clutter process
|
||||
* events and maintain its internal state.
|
||||
*
|
||||
* This function can only be called before calling clutter_init().
|
||||
*
|
||||
* Even with event handling disabled, Clutter will still select
|
||||
* all the events required to maintain its internal state on the stage
|
||||
* Window; compositors using Clutter and input regions to pass events
|
||||
* through to application windows should not rely on an empty input
|
||||
* region, and should instead clear it themselves explicitly using the
|
||||
* XFixes extension.
|
||||
*
|
||||
* This function should not be normally used by applications.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clutter_x11_disable_event_retrieval (void)
|
||||
{
|
||||
if (_clutter_context_is_initialized ())
|
||||
{
|
||||
g_warning ("%s() can only be used before calling clutter_init()",
|
||||
G_STRFUNC);
|
||||
return;
|
||||
}
|
||||
|
||||
_no_xevent_retrieval = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_has_event_retrieval:
|
||||
*
|
||||
* Queries the X11 backend to check if event collection has been disabled.
|
||||
*
|
||||
* Return value: TRUE if event retrival has been disabled. FALSE otherwise.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
clutter_x11_has_event_retrieval (void)
|
||||
{
|
||||
return !_no_xevent_retrieval;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_get_default_screen:
|
||||
*
|
||||
@@ -930,6 +1164,36 @@ clutter_x11_remove_filter (ClutterX11FilterFunc func,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_has_xinput:
|
||||
*
|
||||
* Gets whether Clutter has XInput support.
|
||||
*
|
||||
* Return value: %TRUE if Clutter was compiled with XInput support
|
||||
* and XInput support is available at run time.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
clutter_x11_has_xinput (void)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
|
||||
if (backend == NULL)
|
||||
{
|
||||
g_critical ("The Clutter backend has not been initialised");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!CLUTTER_IS_BACKEND_X11 (backend))
|
||||
{
|
||||
g_critical ("The Clutter backend is not a X11 backend.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return CLUTTER_BACKEND_X11 (backend)->has_xinput;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_has_composite_extension:
|
||||
*
|
||||
@@ -1077,3 +1341,84 @@ clutter_x11_get_use_stereo_stage (void)
|
||||
return clutter_enable_stereo;
|
||||
}
|
||||
|
||||
XVisualInfo *
|
||||
_clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
return cogl_clutter_winsys_xlib_get_visual_info ();
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_get_visual_info: (skip)
|
||||
*
|
||||
* Retrieves the `XVisualInfo` used by the Clutter X11 backend.
|
||||
*
|
||||
* Return value: (transfer full): a `XVisualInfo`, or `None`.
|
||||
* The returned value should be freed using `XFree()` when done
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
XVisualInfo *
|
||||
clutter_x11_get_visual_info (void)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterBackend *backend;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
if (!CLUTTER_IS_BACKEND_X11 (backend))
|
||||
{
|
||||
g_critical ("The Clutter backend is not a X11 backend.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
return _clutter_backend_x11_get_visual_info (backend_x11);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_x11_input_device_translate_screen_coord (ClutterInputDevice *device,
|
||||
gint stage_root_x,
|
||||
gint stage_root_y,
|
||||
guint index_,
|
||||
gdouble value,
|
||||
gdouble *axis_value)
|
||||
{
|
||||
ClutterAxisInfo *info;
|
||||
ClutterBackendX11 *backend_x11;
|
||||
gdouble width, scale, offset;
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (device->backend);
|
||||
|
||||
if (device->axes == NULL || index_ >= device->axes->len)
|
||||
return FALSE;
|
||||
|
||||
info = &g_array_index (device->axes, ClutterAxisInfo, index_);
|
||||
if (!(info->axis == CLUTTER_INPUT_AXIS_X || info->axis == CLUTTER_INPUT_AXIS_Y))
|
||||
return FALSE;
|
||||
|
||||
width = info->max_value - info->min_value;
|
||||
|
||||
if (info->axis == CLUTTER_INPUT_AXIS_X)
|
||||
{
|
||||
if (width > 0)
|
||||
scale = backend_x11->xscreen_width / width;
|
||||
else
|
||||
scale = 1;
|
||||
|
||||
offset = - stage_root_x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (width > 0)
|
||||
scale = backend_x11->xscreen_height / width;
|
||||
else
|
||||
scale = 1;
|
||||
|
||||
offset = - stage_root_y;
|
||||
}
|
||||
|
||||
if (axis_value)
|
||||
*axis_value = offset + scale * (value - info->min_value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "clutter-x11.h"
|
||||
|
||||
#include "clutter-backend-private.h"
|
||||
#include "clutter-keymap-x11.h"
|
||||
|
||||
#include "xsettings/xsettings-client.h"
|
||||
|
||||
@@ -44,6 +45,7 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _ClutterBackendX11 ClutterBackendX11;
|
||||
typedef struct _ClutterBackendX11Class ClutterBackendX11Class;
|
||||
typedef struct _ClutterEventX11 ClutterEventX11;
|
||||
typedef struct _ClutterX11EventFilter ClutterX11EventFilter;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackendX11, g_object_unref)
|
||||
@@ -55,6 +57,16 @@ struct _ClutterX11EventFilter
|
||||
|
||||
};
|
||||
|
||||
struct _ClutterEventX11
|
||||
{
|
||||
/* additional fields for Key events */
|
||||
gint key_group;
|
||||
|
||||
guint key_is_modifier : 1;
|
||||
guint num_lock_set : 1;
|
||||
guint caps_lock_set : 1;
|
||||
};
|
||||
|
||||
struct _ClutterBackendX11
|
||||
{
|
||||
ClutterBackend parent_instance;
|
||||
@@ -70,6 +82,7 @@ struct _ClutterBackendX11
|
||||
Window xwin_root;
|
||||
|
||||
/* event source */
|
||||
GSource *event_source;
|
||||
GSList *event_filters;
|
||||
|
||||
/* props */
|
||||
@@ -87,9 +100,16 @@ struct _ClutterBackendX11
|
||||
Time last_event_time;
|
||||
|
||||
ClutterDeviceManager *device_manager;
|
||||
gboolean has_xinput;
|
||||
int xi_minor;
|
||||
|
||||
XSettingsClient *xsettings;
|
||||
Window xsettings_xwin;
|
||||
|
||||
ClutterKeymapX11 *keymap;
|
||||
gboolean use_xkb;
|
||||
gboolean have_xkb_autorepeat;
|
||||
guint keymap_serial;
|
||||
};
|
||||
|
||||
struct _ClutterBackendX11Class
|
||||
@@ -102,9 +122,26 @@ GType clutter_backend_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterBackend *clutter_backend_x11_new (void);
|
||||
|
||||
void _clutter_backend_x11_events_init (ClutterBackend *backend);
|
||||
|
||||
GSource * _clutter_x11_event_source_new (ClutterBackendX11 *backend_x11);
|
||||
|
||||
/* Private to glx/eglx backends */
|
||||
XVisualInfo * _clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11);
|
||||
|
||||
void _clutter_x11_select_events (Window xwin);
|
||||
|
||||
ClutterEventX11 * _clutter_event_x11_new (void);
|
||||
ClutterEventX11 * _clutter_event_x11_copy (ClutterEventX11 *event_x11);
|
||||
void _clutter_event_x11_free (ClutterEventX11 *event_x11);
|
||||
|
||||
gboolean _clutter_x11_input_device_translate_screen_coord (ClutterInputDevice *device,
|
||||
gint stage_root_x,
|
||||
gint stage_root_y,
|
||||
guint index_,
|
||||
gdouble value,
|
||||
gdouble *axis_value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BACKEND_X11_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
73
clutter/clutter/x11/clutter-device-manager-xi2.h
Normal file
73
clutter/clutter/x11/clutter-device-manager-xi2.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright © 2011 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_DEVICE_MANAGER_XI2_H__
|
||||
#define __CLUTTER_DEVICE_MANAGER_XI2_H__
|
||||
|
||||
#include <clutter/clutter-device-manager.h>
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
#include <libwacom/libwacom.h>
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_DEVICE_MANAGER_XI2 (_clutter_device_manager_xi2_get_type ())
|
||||
#define CLUTTER_DEVICE_MANAGER_XI2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEVICE_MANAGER_XI2, ClutterDeviceManagerXI2))
|
||||
#define CLUTTER_IS_DEVICE_MANAGER_XI2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEVICE_MANAGER_XI2))
|
||||
#define CLUTTER_DEVICE_MANAGER_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEVICE_MANAGER_XI2, ClutterDeviceManagerXI2Class))
|
||||
#define CLUTTER_IS_DEVICE_MANAGER_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEVICE_MANAGER_XI2))
|
||||
#define CLUTTER_DEVICE_MANAGER_XI2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEVICE_MANAGER_XI2, ClutterDeviceManagerXI2Class))
|
||||
|
||||
typedef struct _ClutterDeviceManagerXI2 ClutterDeviceManagerXI2;
|
||||
typedef struct _ClutterDeviceManagerXI2Class ClutterDeviceManagerXI2Class;
|
||||
|
||||
struct _ClutterDeviceManagerXI2
|
||||
{
|
||||
ClutterDeviceManager parent_instance;
|
||||
|
||||
GHashTable *devices_by_id;
|
||||
GHashTable *tools_by_serial;
|
||||
|
||||
GSList *all_devices;
|
||||
|
||||
GList *master_devices;
|
||||
GList *slave_devices;
|
||||
|
||||
int opcode;
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
WacomDeviceDatabase *wacom_db;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _ClutterDeviceManagerXI2Class
|
||||
{
|
||||
ClutterDeviceManagerClass parent_class;
|
||||
};
|
||||
|
||||
GType _clutter_device_manager_xi2_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_DEVICE_MANAGER_XI2_H__ */
|
384
clutter/clutter/x11/clutter-event-x11.c
Normal file
384
clutter/clutter/x11/clutter-event-x11.c
Normal file
@@ -0,0 +1,384 @@
|
||||
/* Clutter.
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2006, 2007, 2008 OpenedHand Ltd
|
||||
* Copyright (C) 2009, 2010 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authored by:
|
||||
* Matthew Allum <mallum@openedhand.com>
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-backend-x11.h"
|
||||
#include "clutter-x11.h"
|
||||
|
||||
#include "clutter-backend-private.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-event-private.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-stage-private.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#if 0
|
||||
/* XEMBED protocol support for toolkit embedding */
|
||||
#define XEMBED_MAPPED (1 << 0)
|
||||
#define MAX_SUPPORTED_XEMBED_VERSION 1
|
||||
|
||||
#define XEMBED_EMBEDDED_NOTIFY 0
|
||||
#define XEMBED_WINDOW_ACTIVATE 1
|
||||
#define XEMBED_WINDOW_DEACTIVATE 2
|
||||
#define XEMBED_REQUEST_FOCUS 3
|
||||
#define XEMBED_FOCUS_IN 4
|
||||
#define XEMBED_FOCUS_OUT 5
|
||||
#define XEMBED_FOCUS_NEXT 6
|
||||
#define XEMBED_FOCUS_PREV 7
|
||||
/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
|
||||
#define XEMBED_MODALITY_ON 10
|
||||
#define XEMBED_MODALITY_OFF 11
|
||||
#define XEMBED_REGISTER_ACCELERATOR 12
|
||||
#define XEMBED_UNREGISTER_ACCELERATOR 13
|
||||
#define XEMBED_ACTIVATE_ACCELERATOR 14
|
||||
|
||||
static Window ParentEmbedderWin = None;
|
||||
#endif
|
||||
|
||||
typedef struct _ClutterEventSource ClutterEventSource;
|
||||
|
||||
struct _ClutterEventSource
|
||||
{
|
||||
GSource source;
|
||||
|
||||
ClutterBackendX11 *backend;
|
||||
|
||||
GPollFD event_poll_fd;
|
||||
};
|
||||
|
||||
ClutterEventX11 *
|
||||
_clutter_event_x11_new (void)
|
||||
{
|
||||
return g_slice_new0 (ClutterEventX11);
|
||||
}
|
||||
|
||||
ClutterEventX11 *
|
||||
_clutter_event_x11_copy (ClutterEventX11 *event_x11)
|
||||
{
|
||||
if (event_x11 != NULL)
|
||||
return g_slice_dup (ClutterEventX11, event_x11);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_event_x11_free (ClutterEventX11 *event_x11)
|
||||
{
|
||||
if (event_x11 != NULL)
|
||||
g_slice_free (ClutterEventX11, event_x11);
|
||||
}
|
||||
|
||||
static gboolean clutter_event_prepare (GSource *source,
|
||||
gint *timeout);
|
||||
static gboolean clutter_event_check (GSource *source);
|
||||
static gboolean clutter_event_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data);
|
||||
|
||||
static GSourceFuncs event_funcs = {
|
||||
clutter_event_prepare,
|
||||
clutter_event_check,
|
||||
clutter_event_dispatch,
|
||||
NULL
|
||||
};
|
||||
|
||||
GSource *
|
||||
_clutter_x11_event_source_new (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
ClutterEventSource *event_source;
|
||||
int connection_number;
|
||||
GSource *source;
|
||||
gchar *name;
|
||||
|
||||
connection_number = ConnectionNumber (backend_x11->xdpy);
|
||||
CLUTTER_NOTE (EVENT, "Connection number: %d", connection_number);
|
||||
|
||||
source = g_source_new (&event_funcs, sizeof (ClutterEventSource));
|
||||
event_source = (ClutterEventSource *) source;
|
||||
|
||||
name = g_strdup_printf ("Clutter X11 Event (connection: %d)",
|
||||
connection_number);
|
||||
g_source_set_name (source, name);
|
||||
g_free (name);
|
||||
|
||||
event_source->backend = backend_x11;
|
||||
event_source->event_poll_fd.fd = connection_number;
|
||||
event_source->event_poll_fd.events = G_IO_IN;
|
||||
|
||||
g_source_add_poll (source, &event_source->event_poll_fd);
|
||||
g_source_set_can_recurse (source, TRUE);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_handle_event:
|
||||
* @xevent: pointer to XEvent structure
|
||||
*
|
||||
* This function processes a single X event; it can be used to hook
|
||||
* into external X11 event processing (for example, a GDK filter
|
||||
* function).
|
||||
*
|
||||
* If clutter_x11_disable_event_retrieval() has been called, you must
|
||||
* let this function process events to update Clutter's internal state.
|
||||
*
|
||||
* Return value: #ClutterX11FilterReturn. %CLUTTER_X11_FILTER_REMOVE
|
||||
* indicates that Clutter has internally handled the event and the
|
||||
* caller should do no further processing. %CLUTTER_X11_FILTER_CONTINUE
|
||||
* indicates that Clutter is either not interested in the event,
|
||||
* or has used the event to update internal state without taking
|
||||
* any exclusive action. %CLUTTER_X11_FILTER_TRANSLATE will not
|
||||
* occur.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
ClutterX11FilterReturn
|
||||
clutter_x11_handle_event (XEvent *xevent)
|
||||
{
|
||||
ClutterX11FilterReturn result;
|
||||
ClutterBackend *backend;
|
||||
ClutterEvent *event;
|
||||
gint spin = 1;
|
||||
ClutterBackendX11 *backend_x11;
|
||||
Display *xdisplay;
|
||||
gboolean allocated_event;
|
||||
|
||||
/* The return values here are someone approximate; we return
|
||||
* CLUTTER_X11_FILTER_REMOVE if a clutter event is
|
||||
* generated for the event. This mostly, but not entirely,
|
||||
* corresponds to whether other event processing should be
|
||||
* excluded. As long as the stage window is not shared with another
|
||||
* toolkit it should be safe, and never return
|
||||
* %CLUTTER_X11_FILTER_REMOVE when more processing is needed.
|
||||
*/
|
||||
|
||||
result = CLUTTER_X11_FILTER_CONTINUE;
|
||||
|
||||
_clutter_threads_acquire_lock ();
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
|
||||
event = clutter_event_new (CLUTTER_NOTHING);
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
xdisplay = backend_x11->xdpy;
|
||||
|
||||
allocated_event = XGetEventData (xdisplay, &xevent->xcookie);
|
||||
|
||||
if (_clutter_backend_translate_event (backend, xevent, event))
|
||||
{
|
||||
_clutter_event_push (event, FALSE);
|
||||
|
||||
result = CLUTTER_X11_FILTER_REMOVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_event_free (event);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Motion events can generate synthetic enter and leave events, so if we
|
||||
* are processing a motion event, we need to spin the event loop at least
|
||||
* two extra times to pump the enter/leave events through (otherwise they
|
||||
* just get pushed down the queue and never processed).
|
||||
*/
|
||||
if (event->type == CLUTTER_MOTION)
|
||||
spin += 2;
|
||||
|
||||
while (spin > 0 && (event = clutter_event_get ()))
|
||||
{
|
||||
/* forward the event into clutter for emission etc. */
|
||||
_clutter_stage_queue_event (event->any.stage, event, FALSE);
|
||||
--spin;
|
||||
}
|
||||
|
||||
out:
|
||||
if (allocated_event)
|
||||
XFreeEventData (xdisplay, &xevent->xcookie);
|
||||
|
||||
_clutter_threads_release_lock ();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_event_prepare (GSource *source,
|
||||
gint *timeout)
|
||||
{
|
||||
ClutterBackendX11 *backend = ((ClutterEventSource *) source)->backend;
|
||||
gboolean retval;
|
||||
|
||||
_clutter_threads_acquire_lock ();
|
||||
|
||||
*timeout = -1;
|
||||
retval = (clutter_events_pending () || XPending (backend->xdpy));
|
||||
|
||||
_clutter_threads_release_lock ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_event_check (GSource *source)
|
||||
{
|
||||
ClutterEventSource *event_source = (ClutterEventSource *) source;
|
||||
ClutterBackendX11 *backend = event_source->backend;
|
||||
gboolean retval;
|
||||
|
||||
_clutter_threads_acquire_lock ();
|
||||
|
||||
if (event_source->event_poll_fd.revents & G_IO_IN)
|
||||
retval = (clutter_events_pending () || XPending (backend->xdpy));
|
||||
else
|
||||
retval = FALSE;
|
||||
|
||||
_clutter_threads_release_lock ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
events_queue (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
ClutterBackend *backend = CLUTTER_BACKEND (backend_x11);
|
||||
Display *xdisplay = backend_x11->xdpy;
|
||||
ClutterEvent *event;
|
||||
XEvent xevent;
|
||||
|
||||
while (!clutter_events_pending () && XPending (xdisplay))
|
||||
{
|
||||
XNextEvent (xdisplay, &xevent);
|
||||
|
||||
event = clutter_event_new (CLUTTER_NOTHING);
|
||||
|
||||
XGetEventData (xdisplay, &xevent.xcookie);
|
||||
|
||||
if (_clutter_backend_translate_event (backend, &xevent, event))
|
||||
_clutter_event_push (event, FALSE);
|
||||
else
|
||||
clutter_event_free (event);
|
||||
|
||||
XFreeEventData (xdisplay, &xevent.xcookie);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_event_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterBackendX11 *backend = ((ClutterEventSource *) source)->backend;
|
||||
ClutterEvent *event;
|
||||
|
||||
_clutter_threads_acquire_lock ();
|
||||
|
||||
/* Grab the event(s), translate and figure out double click.
|
||||
* The push onto queue (stack) if valid.
|
||||
*/
|
||||
events_queue (backend);
|
||||
|
||||
/* Pop an event off the queue if any */
|
||||
event = clutter_event_get ();
|
||||
if (event != NULL)
|
||||
{
|
||||
/* forward the event into clutter for emission etc. */
|
||||
_clutter_stage_queue_event (event->any.stage, event, FALSE);
|
||||
}
|
||||
|
||||
_clutter_threads_release_lock ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_get_current_event_time: (skip)
|
||||
*
|
||||
* Retrieves the timestamp of the last X11 event processed by
|
||||
* Clutter. This might be different from the timestamp returned
|
||||
* by clutter_get_current_event_time(), as Clutter may synthesize
|
||||
* or throttle events.
|
||||
*
|
||||
* Return value: a timestamp, in milliseconds
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
Time
|
||||
clutter_x11_get_current_event_time (void)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
|
||||
return CLUTTER_BACKEND_X11 (backend)->last_event_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_event_get_key_group:
|
||||
* @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS or %CLUTTER_KEY_RELEASE
|
||||
*
|
||||
* Retrieves the group for the modifiers set in @event
|
||||
*
|
||||
* Return value: the group id
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gint
|
||||
clutter_x11_event_get_key_group (const ClutterEvent *event)
|
||||
{
|
||||
ClutterEventX11 *event_x11;
|
||||
|
||||
g_return_val_if_fail (event != NULL, 0);
|
||||
g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS ||
|
||||
event->type == CLUTTER_KEY_RELEASE, 0);
|
||||
|
||||
event_x11 = _clutter_event_get_platform_data (event);
|
||||
if (event_x11 == NULL)
|
||||
return 0;
|
||||
|
||||
return event_x11->key_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_event_sequence_get_touch_detail:
|
||||
* @sequence: a #ClutterEventSequence
|
||||
*
|
||||
* Retrieves the touch detail froma #ClutterEventSequence.
|
||||
*
|
||||
* Return value: the touch detail
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
guint
|
||||
clutter_x11_event_sequence_get_touch_detail (const ClutterEventSequence *sequence)
|
||||
{
|
||||
g_return_val_if_fail (sequence != NULL, 0);
|
||||
|
||||
return GPOINTER_TO_UINT (sequence);
|
||||
}
|
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright © 2016 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -17,28 +21,28 @@
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "meta-input-device-tool-x11.h"
|
||||
#include "clutter-input-device-tool-xi2.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaInputDeviceToolX11, meta_input_device_tool_x11,
|
||||
G_DEFINE_TYPE (ClutterInputDeviceToolXI2, clutter_input_device_tool_xi2,
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL)
|
||||
|
||||
static void
|
||||
meta_input_device_tool_x11_class_init (MetaInputDeviceToolX11Class *klass)
|
||||
clutter_input_device_tool_xi2_class_init (ClutterInputDeviceToolXI2Class *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_device_tool_x11_init (MetaInputDeviceToolX11 *tool)
|
||||
clutter_input_device_tool_xi2_init (ClutterInputDeviceToolXI2 *tool)
|
||||
{
|
||||
}
|
||||
|
||||
ClutterInputDeviceTool *
|
||||
meta_input_device_tool_x11_new (guint serial,
|
||||
ClutterInputDeviceToolType type)
|
||||
clutter_input_device_tool_xi2_new (guint serial,
|
||||
ClutterInputDeviceToolType type)
|
||||
{
|
||||
return g_object_new (META_TYPE_INPUT_DEVICE_TOOL_X11,
|
||||
return g_object_new (CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2,
|
||||
"type", type,
|
||||
"serial", serial,
|
||||
NULL);
|
74
clutter/clutter/x11/clutter-input-device-tool-xi2.h
Normal file
74
clutter/clutter/x11/clutter-input-device-tool-xi2.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright © 2016 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_DEVICE_XI2_TOOL_H__
|
||||
#define __CLUTTER_INPUT_DEVICE_XI2_TOOL_H__
|
||||
|
||||
#include <clutter/clutter-input-device-tool.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2 (clutter_input_device_tool_xi2_get_type ())
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_TOOL_XI2(o) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((o), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2, ClutterInputDeviceToolXI2))
|
||||
|
||||
#define CLUTTER_IS_INPUT_DEVICE_TOOL_XI2(o) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((o), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2))
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_TOOL_XI2_CLASS(c) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((c), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2, ClutterInputDeviceToolXI2Class))
|
||||
|
||||
#define CLUTTER_IS_INPUT_DEVICE_TOOL_XI2_CLASS(c) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((c), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2))
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_TOOL_XI2_GET_CLASS(o) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((o), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2, ClutterInputDeviceToolXI2Class))
|
||||
|
||||
typedef struct _ClutterInputDeviceToolXI2 ClutterInputDeviceToolXI2;
|
||||
typedef struct _ClutterInputDeviceToolXI2Class ClutterInputDeviceToolXI2Class;
|
||||
|
||||
struct _ClutterInputDeviceToolXI2
|
||||
{
|
||||
ClutterInputDeviceTool parent_instance;
|
||||
struct libinput_tablet_tool *tool;
|
||||
};
|
||||
|
||||
struct _ClutterInputDeviceToolXI2Class
|
||||
{
|
||||
ClutterInputDeviceToolClass parent_class;
|
||||
};
|
||||
|
||||
GType clutter_input_device_tool_xi2_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterInputDeviceTool * clutter_input_device_tool_xi2_new (guint serial,
|
||||
ClutterInputDeviceToolType type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_DEVICE_XI2_TOOL_H__ */
|
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright © 2011 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -17,22 +21,32 @@
|
||||
* Author: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-input-device-xi2.h"
|
||||
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-event-private.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-stage-private.h"
|
||||
|
||||
#include "clutter-backend-x11.h"
|
||||
#include "clutter-stage-x11.h"
|
||||
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
#include "backends/x11/meta-input-device-x11.h"
|
||||
typedef struct _ClutterInputDeviceClass ClutterInputDeviceXI2Class;
|
||||
|
||||
struct _MetaInputDeviceX11
|
||||
/* a specific XI2 input device */
|
||||
struct _ClutterInputDeviceXI2
|
||||
{
|
||||
ClutterInputDevice device;
|
||||
|
||||
int32_t device_id;
|
||||
gint device_id;
|
||||
ClutterInputDeviceTool *current_tool;
|
||||
|
||||
int inhibit_pointer_query_timer;
|
||||
guint inhibit_pointer_query_timer;
|
||||
gboolean query_status;
|
||||
float current_x;
|
||||
float current_y;
|
||||
@@ -43,41 +57,38 @@ struct _MetaInputDeviceX11
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _MetaInputDeviceX11Class
|
||||
{
|
||||
ClutterInputDeviceClass device_class;
|
||||
};
|
||||
|
||||
#define N_BUTTONS 5
|
||||
|
||||
G_DEFINE_TYPE (MetaInputDeviceX11,
|
||||
meta_input_device_x11,
|
||||
CLUTTER_TYPE_INPUT_DEVICE)
|
||||
#define clutter_input_device_xi2_get_type _clutter_input_device_xi2_get_type
|
||||
|
||||
G_DEFINE_TYPE (ClutterInputDeviceXI2,
|
||||
clutter_input_device_xi2,
|
||||
CLUTTER_TYPE_INPUT_DEVICE);
|
||||
|
||||
static void
|
||||
meta_input_device_x11_constructed (GObject *object)
|
||||
clutter_input_device_xi2_constructed (GObject *gobject)
|
||||
{
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (object);
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (gobject);
|
||||
|
||||
g_object_get (object, "id", &device_xi2->device_id, NULL);
|
||||
g_object_get (gobject, "id", &device_xi2->device_id, NULL);
|
||||
|
||||
if (G_OBJECT_CLASS (meta_input_device_x11_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (meta_input_device_x11_parent_class)->constructed (object);
|
||||
if (G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->constructed (gobject);
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
if (clutter_input_device_get_device_type (CLUTTER_INPUT_DEVICE (object)) == CLUTTER_PAD_DEVICE)
|
||||
if (clutter_input_device_get_device_type (CLUTTER_INPUT_DEVICE (gobject)) == CLUTTER_PAD_DEVICE)
|
||||
{
|
||||
device_xi2->group_modes = g_array_new (FALSE, TRUE, sizeof (uint32_t));
|
||||
device_xi2->group_modes = g_array_new (FALSE, TRUE, sizeof (guint));
|
||||
g_array_set_size (device_xi2->group_modes,
|
||||
clutter_input_device_get_n_mode_groups (CLUTTER_INPUT_DEVICE (object)));
|
||||
clutter_input_device_get_n_mode_groups (CLUTTER_INPUT_DEVICE (gobject)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_input_device_x11_keycode_to_evdev (ClutterInputDevice *device,
|
||||
uint32_t hardware_keycode,
|
||||
uint32_t *evdev_keycode)
|
||||
clutter_input_device_xi2_keycode_to_evdev (ClutterInputDevice *device,
|
||||
guint hardware_keycode,
|
||||
guint *evdev_keycode)
|
||||
{
|
||||
/* When using evdev under X11 the hardware keycodes are the evdev
|
||||
keycodes plus 8. I haven't been able to find any documentation to
|
||||
@@ -89,17 +100,17 @@ meta_input_device_x11_keycode_to_evdev (ClutterInputDevice *device,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_input_device_x11_is_grouped (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device)
|
||||
clutter_input_device_xi2_is_grouped (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_device_x11_finalize (GObject *object)
|
||||
clutter_input_device_xi2_finalize (GObject *object)
|
||||
{
|
||||
#ifdef HAVE_LIBWACOM
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (object);
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (object);
|
||||
|
||||
if (device_xi2->wacom_device)
|
||||
libwacom_destroy (device_xi2->wacom_device);
|
||||
@@ -111,15 +122,15 @@ meta_input_device_x11_finalize (GObject *object)
|
||||
g_source_remove (device_xi2->inhibit_pointer_query_timer);
|
||||
#endif
|
||||
|
||||
G_OBJECT_CLASS (meta_input_device_x11_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static int
|
||||
meta_input_device_x11_get_group_n_modes (ClutterInputDevice *device,
|
||||
int group)
|
||||
static gint
|
||||
clutter_input_device_xi2_get_group_n_modes (ClutterInputDevice *device,
|
||||
gint group)
|
||||
{
|
||||
#ifdef HAVE_LIBWACOM
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device);
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
|
||||
if (device_xi2->wacom_device)
|
||||
{
|
||||
@@ -145,10 +156,10 @@ meta_input_device_x11_get_group_n_modes (ClutterInputDevice *device,
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
static int
|
||||
meta_input_device_x11_get_button_group (ClutterInputDevice *device,
|
||||
uint32_t button)
|
||||
clutter_input_device_xi2_get_button_group (ClutterInputDevice *device,
|
||||
guint button)
|
||||
{
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device);
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
|
||||
if (device_xi2->wacom_device)
|
||||
{
|
||||
@@ -164,36 +175,36 @@ meta_input_device_x11_get_button_group (ClutterInputDevice *device,
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
meta_input_device_x11_is_mode_switch_button (ClutterInputDevice *device,
|
||||
uint32_t group,
|
||||
uint32_t button)
|
||||
clutter_input_device_xi2_is_mode_switch_button (ClutterInputDevice *device,
|
||||
guint group,
|
||||
guint button)
|
||||
{
|
||||
int button_group = -1;
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
button_group = meta_input_device_x11_get_button_group (device, button);
|
||||
button_group = clutter_input_device_xi2_get_button_group (device, button);
|
||||
#endif
|
||||
|
||||
return button_group == (int) group;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_device_x11_class_init (MetaInputDeviceX11Class *klass)
|
||||
clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass);
|
||||
|
||||
gobject_class->constructed = meta_input_device_x11_constructed;
|
||||
gobject_class->finalize = meta_input_device_x11_finalize;
|
||||
gobject_class->constructed = clutter_input_device_xi2_constructed;
|
||||
gobject_class->finalize = clutter_input_device_xi2_finalize;
|
||||
|
||||
device_class->keycode_to_evdev = meta_input_device_x11_keycode_to_evdev;
|
||||
device_class->is_grouped = meta_input_device_x11_is_grouped;
|
||||
device_class->get_group_n_modes = meta_input_device_x11_get_group_n_modes;
|
||||
device_class->is_mode_switch_button = meta_input_device_x11_is_mode_switch_button;
|
||||
device_class->keycode_to_evdev = clutter_input_device_xi2_keycode_to_evdev;
|
||||
device_class->is_grouped = clutter_input_device_xi2_is_grouped;
|
||||
device_class->get_group_n_modes = clutter_input_device_xi2_get_group_n_modes;
|
||||
device_class->is_mode_switch_button = clutter_input_device_xi2_is_mode_switch_button;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_device_x11_init (MetaInputDeviceX11 *self)
|
||||
clutter_input_device_xi2_init (ClutterInputDeviceXI2 *self)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -218,22 +229,22 @@ get_modifier_for_button (int i)
|
||||
}
|
||||
|
||||
void
|
||||
meta_input_device_x11_translate_state (ClutterEvent *event,
|
||||
XIModifierState *modifiers_state,
|
||||
XIButtonState *buttons_state,
|
||||
XIGroupState *group_state)
|
||||
_clutter_input_device_xi2_translate_state (ClutterEvent *event,
|
||||
XIModifierState *modifiers_state,
|
||||
XIButtonState *buttons_state,
|
||||
XIGroupState *group_state)
|
||||
{
|
||||
uint32_t button = 0;
|
||||
uint32_t base = 0;
|
||||
uint32_t latched = 0;
|
||||
uint32_t locked = 0;
|
||||
uint32_t effective;
|
||||
guint button = 0;
|
||||
guint base = 0;
|
||||
guint latched = 0;
|
||||
guint locked = 0;
|
||||
guint effective;
|
||||
|
||||
if (modifiers_state)
|
||||
{
|
||||
base = (uint32_t) modifiers_state->base;
|
||||
latched = (uint32_t) modifiers_state->latched;
|
||||
locked = (uint32_t) modifiers_state->locked;
|
||||
base = (guint) modifiers_state->base;
|
||||
latched = (guint) modifiers_state->latched;
|
||||
locked = (guint) modifiers_state->locked;
|
||||
}
|
||||
|
||||
if (buttons_state)
|
||||
@@ -276,22 +287,22 @@ meta_input_device_x11_translate_state (ClutterEvent *event,
|
||||
}
|
||||
|
||||
void
|
||||
meta_input_device_x11_update_tool (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool)
|
||||
clutter_input_device_xi2_update_tool (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool)
|
||||
{
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device);
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
g_set_object (&device_xi2->current_tool, tool);
|
||||
}
|
||||
|
||||
ClutterInputDeviceTool *
|
||||
meta_input_device_x11_get_current_tool (ClutterInputDevice *device)
|
||||
clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device);
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
return device_xi2->current_tool;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_input_device_x11_query_pointer_location (MetaInputDeviceX11 *device_xi2)
|
||||
clutter_input_device_xi2_query_pointer_location (ClutterInputDeviceXI2 *device_xi2)
|
||||
{
|
||||
Window xroot_window, xchild_window;
|
||||
double xroot_x, xroot_y, xwin_x, xwin_y;
|
||||
@@ -325,7 +336,7 @@ meta_input_device_x11_query_pointer_location (MetaInputDeviceX11 *device_xi2)
|
||||
static gboolean
|
||||
clear_inhibit_pointer_query_cb (gpointer data)
|
||||
{
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (data);
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (data);
|
||||
|
||||
device_xi2->inhibit_pointer_query_timer = 0;
|
||||
|
||||
@@ -333,21 +344,22 @@ clear_inhibit_pointer_query_cb (gpointer data)
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_input_device_x11_get_pointer_location (ClutterInputDevice *device,
|
||||
float *x,
|
||||
float *y)
|
||||
clutter_input_device_xi2_get_pointer_location (ClutterInputDevice *device,
|
||||
float *x,
|
||||
float *y)
|
||||
|
||||
{
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device);
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
|
||||
g_return_val_if_fail (META_IS_INPUT_DEVICE_X11 (device), FALSE);
|
||||
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 =
|
||||
meta_input_device_x11_query_pointer_location (device_xi2);
|
||||
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);
|
||||
}
|
||||
@@ -360,10 +372,10 @@ meta_input_device_x11_get_pointer_location (ClutterInputDevice *device,
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
void
|
||||
meta_input_device_x11_ensure_wacom_info (ClutterInputDevice *device,
|
||||
WacomDeviceDatabase *wacom_db)
|
||||
clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device,
|
||||
WacomDeviceDatabase *wacom_db)
|
||||
{
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device);
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
const gchar *node_path;
|
||||
|
||||
node_path = clutter_input_device_get_device_node (device);
|
||||
@@ -371,30 +383,30 @@ meta_input_device_x11_ensure_wacom_info (ClutterInputDevice *device,
|
||||
WFALLBACK_NONE, NULL);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
meta_input_device_x11_get_pad_group_mode (ClutterInputDevice *device,
|
||||
uint32_t group)
|
||||
guint
|
||||
clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device,
|
||||
guint group)
|
||||
{
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device);
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
|
||||
if (group >= device_xi2->group_modes->len)
|
||||
return 0;
|
||||
|
||||
return g_array_index (device_xi2->group_modes, uint32_t, group);
|
||||
return g_array_index (device_xi2->group_modes, guint, group);
|
||||
}
|
||||
|
||||
void
|
||||
meta_input_device_x11_update_pad_state (ClutterInputDevice *device,
|
||||
uint32_t button,
|
||||
uint32_t state,
|
||||
uint32_t *group,
|
||||
uint32_t *mode)
|
||||
clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device,
|
||||
guint button,
|
||||
guint state,
|
||||
guint *group,
|
||||
guint *mode)
|
||||
{
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device);
|
||||
uint32_t button_group, *group_mode;
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
guint button_group, *group_mode;
|
||||
gboolean is_mode_switch = FALSE;
|
||||
|
||||
button_group = meta_input_device_x11_get_button_group (device, button);
|
||||
button_group = clutter_input_device_xi2_get_button_group (device, button);
|
||||
is_mode_switch = button_group >= 0;
|
||||
|
||||
/* Assign all non-mode-switch buttons to group 0 so far */
|
||||
@@ -403,11 +415,11 @@ meta_input_device_x11_update_pad_state (ClutterInputDevice *device,
|
||||
if (button_group >= device_xi2->group_modes->len)
|
||||
return;
|
||||
|
||||
group_mode = &g_array_index (device_xi2->group_modes, uint32_t, button_group);
|
||||
group_mode = &g_array_index (device_xi2->group_modes, guint, button_group);
|
||||
|
||||
if (is_mode_switch && state)
|
||||
{
|
||||
uint32_t next, n_modes;
|
||||
guint next, n_modes;
|
||||
|
||||
n_modes = clutter_input_device_get_group_n_modes (device, button_group);
|
||||
next = (*group_mode + 1) % n_modes;
|
72
clutter/clutter/x11/clutter-input-device-xi2.h
Normal file
72
clutter/clutter/x11/clutter-input-device-xi2.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright © 2011 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_DEVICE_XI2_H__
|
||||
#define __CLUTTER_INPUT_DEVICE_XI2_H__
|
||||
|
||||
#include <clutter/clutter-input-device.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
#include <libwacom/libwacom.h>
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_DEVICE_XI2 (_clutter_input_device_xi2_get_type ())
|
||||
#define CLUTTER_INPUT_DEVICE_XI2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_INPUT_DEVICE_XI2, ClutterInputDeviceXI2))
|
||||
#define CLUTTER_IS_INPUT_DEVICE_XI2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_INPUT_DEVICE_XI2))
|
||||
|
||||
typedef struct _ClutterInputDeviceXI2 ClutterInputDeviceXI2;
|
||||
|
||||
GType _clutter_input_device_xi2_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _clutter_input_device_xi2_translate_state (ClutterEvent *event,
|
||||
XIModifierState *modifiers_state,
|
||||
XIButtonState *buttons_state,
|
||||
XIGroupState *group_state);
|
||||
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,
|
||||
WacomDeviceDatabase *wacom_db);
|
||||
|
||||
guint clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device,
|
||||
guint group);
|
||||
|
||||
void clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device,
|
||||
guint button,
|
||||
guint state,
|
||||
guint *group,
|
||||
guint *mode);
|
||||
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_DEVICE_XI2_H__ */
|
@@ -21,34 +21,37 @@
|
||||
* Author: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-keymap-x11.h"
|
||||
#include "clutter-backend-x11.h"
|
||||
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-event-translator.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include "backends/x11/meta-keymap-x11.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
|
||||
typedef struct _ClutterKeymapX11Class ClutterKeymapX11Class;
|
||||
typedef struct _DirectionCacheEntry DirectionCacheEntry;
|
||||
typedef struct _ClutterKeymapKey ClutterKeymapKey;
|
||||
|
||||
struct _ClutterKeymapKey
|
||||
{
|
||||
uint32_t keycode;
|
||||
uint32_t group;
|
||||
uint32_t level;
|
||||
guint keycode;
|
||||
guint group;
|
||||
guint level;
|
||||
};
|
||||
|
||||
struct _DirectionCacheEntry
|
||||
{
|
||||
uint32_t serial;
|
||||
guint serial;
|
||||
Atom group_atom;
|
||||
PangoDirection direction;
|
||||
};
|
||||
|
||||
struct _MetaKeymapX11
|
||||
struct _ClutterKeymapX11
|
||||
{
|
||||
ClutterKeymap parent_instance;
|
||||
|
||||
@@ -67,23 +70,23 @@ struct _MetaKeymapX11
|
||||
|
||||
XkbDescPtr xkb_desc;
|
||||
int xkb_event_base;
|
||||
uint32_t xkb_map_serial;
|
||||
guint xkb_map_serial;
|
||||
Atom current_group_atom;
|
||||
uint32_t current_cache_serial;
|
||||
guint current_cache_serial;
|
||||
DirectionCacheEntry group_direction_cache[4];
|
||||
int current_group;
|
||||
|
||||
GHashTable *reserved_keycodes;
|
||||
GQueue *available_keycodes;
|
||||
|
||||
uint32_t keymap_serial;
|
||||
guint caps_lock_state : 1;
|
||||
guint num_lock_state : 1;
|
||||
guint has_direction : 1;
|
||||
};
|
||||
|
||||
uint32_t caps_lock_state : 1;
|
||||
uint32_t num_lock_state : 1;
|
||||
uint32_t has_direction : 1;
|
||||
|
||||
uint32_t use_xkb : 1;
|
||||
uint32_t have_xkb_autorepeat : 1;
|
||||
struct _ClutterKeymapX11Class
|
||||
{
|
||||
ClutterKeymapClass parent_class;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -97,15 +100,22 @@ enum
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE (MetaKeymapX11, meta_keymap_x11, CLUTTER_TYPE_KEYMAP)
|
||||
static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface);
|
||||
|
||||
#define clutter_keymap_x11_get_type _clutter_keymap_x11_get_type
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (ClutterKeymapX11, clutter_keymap_x11,
|
||||
CLUTTER_TYPE_KEYMAP,
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_TRANSLATOR,
|
||||
clutter_event_translator_iface_init));
|
||||
|
||||
/* code adapted from gdk/x11/gdkkeys-x11.c - update_modmap */
|
||||
static void
|
||||
update_modmap (Display *display,
|
||||
MetaKeymapX11 *keymap_x11)
|
||||
update_modmap (Display *display,
|
||||
ClutterKeymapX11 *keymap_x11)
|
||||
{
|
||||
static struct {
|
||||
const char *name;
|
||||
const gchar *name;
|
||||
Atom atom;
|
||||
ClutterModifierType mask;
|
||||
} vmods[] = {
|
||||
@@ -141,12 +151,12 @@ update_modmap (Display *display,
|
||||
}
|
||||
|
||||
static XkbDescPtr
|
||||
get_xkb (MetaKeymapX11 *keymap_x11)
|
||||
get_xkb (ClutterKeymapX11 *keymap_x11)
|
||||
{
|
||||
Display *xdisplay = clutter_x11_get_default_display ();
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);
|
||||
|
||||
if (keymap_x11->max_keycode == 0)
|
||||
XDisplayKeycodes (xdisplay,
|
||||
XDisplayKeycodes (backend_x11->xdpy,
|
||||
&keymap_x11->min_keycode,
|
||||
&keymap_x11->max_keycode);
|
||||
|
||||
@@ -157,7 +167,7 @@ get_xkb (MetaKeymapX11 *keymap_x11)
|
||||
| XkbModifierMapMask
|
||||
| XkbVirtualModsMask;
|
||||
|
||||
keymap_x11->xkb_desc = XkbGetMap (xdisplay, flags, XkbUseCoreKbd);
|
||||
keymap_x11->xkb_desc = XkbGetMap (backend_x11->xdpy, flags, XkbUseCoreKbd);
|
||||
if (G_UNLIKELY (keymap_x11->xkb_desc == NULL))
|
||||
{
|
||||
g_error ("Failed to get the keymap from XKB");
|
||||
@@ -165,43 +175,46 @@ get_xkb (MetaKeymapX11 *keymap_x11)
|
||||
}
|
||||
|
||||
flags = XkbGroupNamesMask | XkbVirtualModNamesMask;
|
||||
XkbGetNames (xdisplay, flags, keymap_x11->xkb_desc);
|
||||
XkbGetNames (backend_x11->xdpy, flags, keymap_x11->xkb_desc);
|
||||
|
||||
update_modmap (xdisplay, keymap_x11);
|
||||
update_modmap (backend_x11->xdpy, keymap_x11);
|
||||
}
|
||||
else if (keymap_x11->xkb_map_serial != keymap_x11->keymap_serial)
|
||||
else if (keymap_x11->xkb_map_serial != backend_x11->keymap_serial)
|
||||
{
|
||||
int flags = XkbKeySymsMask
|
||||
| XkbKeyTypesMask
|
||||
| XkbModifierMapMask
|
||||
| XkbVirtualModsMask;
|
||||
|
||||
XkbGetUpdatedMap (xdisplay, flags, keymap_x11->xkb_desc);
|
||||
CLUTTER_NOTE (BACKEND, "Updating XKB keymap");
|
||||
|
||||
XkbGetUpdatedMap (backend_x11->xdpy, flags, keymap_x11->xkb_desc);
|
||||
|
||||
flags = XkbGroupNamesMask | XkbVirtualModNamesMask;
|
||||
XkbGetNames (xdisplay, flags, keymap_x11->xkb_desc);
|
||||
XkbGetNames (backend_x11->xdpy, flags, keymap_x11->xkb_desc);
|
||||
|
||||
update_modmap (xdisplay, keymap_x11);
|
||||
update_modmap (backend_x11->xdpy, keymap_x11);
|
||||
|
||||
keymap_x11->xkb_map_serial = keymap_x11->keymap_serial;
|
||||
keymap_x11->xkb_map_serial = backend_x11->keymap_serial;
|
||||
}
|
||||
|
||||
if (keymap_x11->num_lock_mask == 0)
|
||||
keymap_x11->num_lock_mask = XkbKeysymToModifiers (xdisplay, XK_Num_Lock);
|
||||
keymap_x11->num_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy,
|
||||
XK_Num_Lock);
|
||||
|
||||
if (keymap_x11->scroll_lock_mask == 0)
|
||||
keymap_x11->scroll_lock_mask = XkbKeysymToModifiers (xdisplay,
|
||||
keymap_x11->scroll_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy,
|
||||
XK_Scroll_Lock);
|
||||
if (keymap_x11->level3_shift_mask == 0)
|
||||
keymap_x11->level3_shift_mask = XkbKeysymToModifiers (xdisplay,
|
||||
keymap_x11->level3_shift_mask = XkbKeysymToModifiers (backend_x11->xdpy,
|
||||
XK_ISO_Level3_Shift);
|
||||
|
||||
return keymap_x11->xkb_desc;
|
||||
}
|
||||
|
||||
static void
|
||||
update_locked_mods (MetaKeymapX11 *keymap_x11,
|
||||
int locked_mods)
|
||||
update_locked_mods (ClutterKeymapX11 *keymap_x11,
|
||||
gint locked_mods)
|
||||
{
|
||||
gboolean old_caps_lock_state, old_num_lock_state;
|
||||
|
||||
@@ -211,9 +224,9 @@ update_locked_mods (MetaKeymapX11 *keymap_x11,
|
||||
keymap_x11->caps_lock_state = (locked_mods & CLUTTER_LOCK_MASK) != 0;
|
||||
keymap_x11->num_lock_state = (locked_mods & keymap_x11->num_lock_mask) != 0;
|
||||
|
||||
g_debug ("Locks state changed - Num: %s, Caps: %s",
|
||||
keymap_x11->num_lock_state ? "set" : "unset",
|
||||
keymap_x11->caps_lock_state ? "set" : "unset");
|
||||
CLUTTER_NOTE (BACKEND, "Locks state changed - Num: %s, Caps: %s",
|
||||
keymap_x11->num_lock_state ? "set" : "unset",
|
||||
keymap_x11->caps_lock_state ? "set" : "unset");
|
||||
|
||||
if ((keymap_x11->caps_lock_state != old_caps_lock_state) ||
|
||||
(keymap_x11->num_lock_state != old_num_lock_state))
|
||||
@@ -262,9 +275,9 @@ get_direction (XkbDescPtr xkb,
|
||||
}
|
||||
|
||||
static PangoDirection
|
||||
get_direction_from_cache (MetaKeymapX11 *keymap_x11,
|
||||
XkbDescPtr xkb,
|
||||
int group)
|
||||
get_direction_from_cache (ClutterKeymapX11 *keymap_x11,
|
||||
XkbDescPtr xkb,
|
||||
int group)
|
||||
{
|
||||
Atom group_atom = xkb->names->groups[group];
|
||||
gboolean cache_hit = FALSE;
|
||||
@@ -323,8 +336,8 @@ get_direction_from_cache (MetaKeymapX11 *keymap_x11,
|
||||
}
|
||||
|
||||
static void
|
||||
update_direction (MetaKeymapX11 *keymap_x11,
|
||||
int group)
|
||||
update_direction (ClutterKeymapX11 *keymap_x11,
|
||||
int group)
|
||||
{
|
||||
XkbDescPtr xkb = get_xkb (keymap_x11);
|
||||
Atom group_atom;
|
||||
@@ -340,21 +353,22 @@ update_direction (MetaKeymapX11 *keymap_x11,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_keymap_x11_constructed (GObject *object)
|
||||
clutter_keymap_x11_constructed (GObject *gobject)
|
||||
{
|
||||
MetaKeymapX11 *keymap_x11 = META_KEYMAP_X11 (object);
|
||||
Display *xdisplay = clutter_x11_get_default_display ();
|
||||
int xkb_major = XkbMajorVersion;
|
||||
int xkb_minor = XkbMinorVersion;
|
||||
ClutterKeymapX11 *keymap_x11 = CLUTTER_KEYMAP_X11 (gobject);
|
||||
ClutterBackendX11 *backend_x11;
|
||||
gint xkb_major = XkbMajorVersion;
|
||||
gint xkb_minor = XkbMinorVersion;
|
||||
|
||||
g_assert (keymap_x11->backend != NULL);
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);
|
||||
|
||||
if (XkbLibraryVersion (&xkb_major, &xkb_minor))
|
||||
{
|
||||
xkb_major = XkbMajorVersion;
|
||||
xkb_minor = XkbMinorVersion;
|
||||
|
||||
if (XkbQueryExtension (xdisplay,
|
||||
if (XkbQueryExtension (backend_x11->xdpy,
|
||||
NULL,
|
||||
&keymap_x11->xkb_event_base,
|
||||
NULL,
|
||||
@@ -362,35 +376,39 @@ meta_keymap_x11_constructed (GObject *object)
|
||||
{
|
||||
Bool detectable_autorepeat_supported;
|
||||
|
||||
keymap_x11->use_xkb = TRUE;
|
||||
backend_x11->use_xkb = TRUE;
|
||||
|
||||
XkbSelectEvents (xdisplay,
|
||||
XkbSelectEvents (backend_x11->xdpy,
|
||||
XkbUseCoreKbd,
|
||||
XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask,
|
||||
XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask);
|
||||
|
||||
XkbSelectEventDetails (xdisplay,
|
||||
XkbSelectEventDetails (backend_x11->xdpy,
|
||||
XkbUseCoreKbd, XkbStateNotify,
|
||||
XkbAllStateComponentsMask,
|
||||
XkbGroupLockMask | XkbModifierLockMask);
|
||||
|
||||
/* enable XKB autorepeat */
|
||||
XkbSetDetectableAutoRepeat (xdisplay,
|
||||
XkbSetDetectableAutoRepeat (backend_x11->xdpy,
|
||||
True,
|
||||
&detectable_autorepeat_supported);
|
||||
|
||||
keymap_x11->have_xkb_autorepeat = detectable_autorepeat_supported;
|
||||
backend_x11->have_xkb_autorepeat = detectable_autorepeat_supported;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Detectable autorepeat: %s",
|
||||
backend_x11->have_xkb_autorepeat ? "supported"
|
||||
: "not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_keymap_x11_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
clutter_keymap_x11_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaKeymapX11 *keymap = META_KEYMAP_X11 (object);
|
||||
ClutterKeymapX11 *keymap = CLUTTER_KEYMAP_X11 (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -399,13 +417,13 @@ meta_keymap_x11_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_keymap_x11_refresh_reserved_keycodes (MetaKeymapX11 *keymap_x11)
|
||||
clutter_keymap_x11_refresh_reserved_keycodes (ClutterKeymapX11 *keymap_x11)
|
||||
{
|
||||
Display *dpy = clutter_x11_get_default_display ();
|
||||
GHashTableIter iter;
|
||||
@@ -414,9 +432,9 @@ meta_keymap_x11_refresh_reserved_keycodes (MetaKeymapX11 *keymap_x11)
|
||||
g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
uint32_t reserved_keycode = GPOINTER_TO_UINT (key);
|
||||
uint32_t reserved_keysym = GPOINTER_TO_UINT (value);
|
||||
uint32_t actual_keysym = XkbKeycodeToKeysym (dpy, reserved_keycode, 0, 0);
|
||||
guint reserved_keycode = GPOINTER_TO_UINT (key);
|
||||
guint reserved_keysym = GPOINTER_TO_UINT (value);
|
||||
guint actual_keysym = XkbKeycodeToKeysym (dpy, reserved_keycode, 0, 0);
|
||||
|
||||
/* If an available keycode is no longer mapped to the stored keysym, then
|
||||
* the keycode should not be considered available anymore and should be
|
||||
@@ -431,11 +449,11 @@ meta_keymap_x11_refresh_reserved_keycodes (MetaKeymapX11 *keymap_x11)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_keymap_x11_replace_keycode (MetaKeymapX11 *keymap_x11,
|
||||
KeyCode keycode,
|
||||
KeySym keysym)
|
||||
clutter_keymap_x11_replace_keycode (ClutterKeymapX11 *keymap_x11,
|
||||
KeyCode keycode,
|
||||
KeySym keysym)
|
||||
{
|
||||
if (keymap_x11->use_xkb)
|
||||
if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
|
||||
{
|
||||
Display *dpy = clutter_x11_get_default_display ();
|
||||
XkbDescPtr xkb = get_xkb (keymap_x11);
|
||||
@@ -474,72 +492,76 @@ meta_keymap_x11_replace_keycode (MetaKeymapX11 *keymap_x11,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_keymap_x11_finalize (GObject *object)
|
||||
clutter_keymap_x11_finalize (GObject *gobject)
|
||||
{
|
||||
MetaKeymapX11 *keymap;
|
||||
ClutterKeymapX11 *keymap;
|
||||
ClutterEventTranslator *translator;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
keymap = META_KEYMAP_X11 (object);
|
||||
keymap = CLUTTER_KEYMAP_X11 (gobject);
|
||||
translator = CLUTTER_EVENT_TRANSLATOR (keymap);
|
||||
|
||||
meta_keymap_x11_refresh_reserved_keycodes (keymap);
|
||||
clutter_keymap_x11_refresh_reserved_keycodes (keymap);
|
||||
g_hash_table_iter_init (&iter, keymap->reserved_keycodes);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
uint32_t keycode = GPOINTER_TO_UINT (key);
|
||||
meta_keymap_x11_replace_keycode (keymap, keycode, NoSymbol);
|
||||
guint keycode = GPOINTER_TO_UINT (key);
|
||||
clutter_keymap_x11_replace_keycode (keymap, keycode, NoSymbol);
|
||||
}
|
||||
|
||||
g_hash_table_destroy (keymap->reserved_keycodes);
|
||||
g_queue_free (keymap->available_keycodes);
|
||||
|
||||
_clutter_backend_remove_event_translator (keymap->backend, translator);
|
||||
|
||||
if (keymap->xkb_desc != NULL)
|
||||
XkbFreeKeyboard (keymap->xkb_desc, XkbAllComponentsMask, True);
|
||||
|
||||
G_OBJECT_CLASS (meta_keymap_x11_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (clutter_keymap_x11_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_keymap_x11_get_num_lock_state (ClutterKeymap *keymap)
|
||||
clutter_keymap_x11_get_num_lock_state (ClutterKeymap *keymap)
|
||||
{
|
||||
MetaKeymapX11 *keymap_x11 = META_KEYMAP_X11 (keymap);
|
||||
ClutterKeymapX11 *keymap_x11 = CLUTTER_KEYMAP_X11 (keymap);
|
||||
|
||||
return keymap_x11->num_lock_state;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_keymap_x11_get_caps_lock_state (ClutterKeymap *keymap)
|
||||
clutter_keymap_x11_get_caps_lock_state (ClutterKeymap *keymap)
|
||||
{
|
||||
MetaKeymapX11 *keymap_x11 = META_KEYMAP_X11 (keymap);
|
||||
ClutterKeymapX11 *keymap_x11 = CLUTTER_KEYMAP_X11 (keymap);
|
||||
|
||||
return keymap_x11->caps_lock_state;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_keymap_x11_class_init (MetaKeymapX11Class *klass)
|
||||
clutter_keymap_x11_class_init (ClutterKeymapX11Class *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterKeymapClass *keymap_class = CLUTTER_KEYMAP_CLASS (klass);
|
||||
|
||||
obj_props[PROP_BACKEND] =
|
||||
g_param_spec_object ("backend",
|
||||
"Backend",
|
||||
"The Clutter backend",
|
||||
P_("Backend"),
|
||||
P_("The Clutter backend"),
|
||||
CLUTTER_TYPE_BACKEND,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
|
||||
CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
gobject_class->constructed = meta_keymap_x11_constructed;
|
||||
gobject_class->set_property = meta_keymap_x11_set_property;
|
||||
gobject_class->finalize = meta_keymap_x11_finalize;
|
||||
gobject_class->constructed = clutter_keymap_x11_constructed;
|
||||
gobject_class->set_property = clutter_keymap_x11_set_property;
|
||||
gobject_class->finalize = clutter_keymap_x11_finalize;
|
||||
|
||||
keymap_class->get_num_lock_state = meta_keymap_x11_get_num_lock_state;
|
||||
keymap_class->get_caps_lock_state = meta_keymap_x11_get_caps_lock_state;
|
||||
keymap_class->get_num_lock_state = clutter_keymap_x11_get_num_lock_state;
|
||||
keymap_class->get_caps_lock_state = clutter_keymap_x11_get_caps_lock_state;
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_keymap_x11_init (MetaKeymapX11 *keymap)
|
||||
clutter_keymap_x11_init (ClutterKeymapX11 *keymap)
|
||||
{
|
||||
keymap->current_direction = PANGO_DIRECTION_NEUTRAL;
|
||||
keymap->current_group = -1;
|
||||
@@ -547,16 +569,23 @@ meta_keymap_x11_init (MetaKeymapX11 *keymap)
|
||||
keymap->available_keycodes = g_queue_new ();
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_keymap_x11_handle_event (MetaKeymapX11 *keymap_x11,
|
||||
XEvent *xevent)
|
||||
static ClutterTranslateReturn
|
||||
clutter_keymap_x11_translate_event (ClutterEventTranslator *translator,
|
||||
gpointer native,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
gboolean retval;
|
||||
ClutterKeymapX11 *keymap_x11 = CLUTTER_KEYMAP_X11 (translator);
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterTranslateReturn retval;
|
||||
XEvent *xevent;
|
||||
|
||||
if (!keymap_x11->use_xkb)
|
||||
return FALSE;
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);
|
||||
if (!backend_x11->use_xkb)
|
||||
return CLUTTER_TRANSLATE_CONTINUE;
|
||||
|
||||
retval = FALSE;
|
||||
xevent = native;
|
||||
|
||||
retval = CLUTTER_TRANSLATE_CONTINUE;
|
||||
|
||||
if (xevent->type == keymap_x11->xkb_event_base)
|
||||
{
|
||||
@@ -565,38 +594,38 @@ meta_keymap_x11_handle_event (MetaKeymapX11 *keymap_x11,
|
||||
switch (xkb_event->any.xkb_type)
|
||||
{
|
||||
case XkbStateNotify:
|
||||
g_debug ("Updating keyboard state");
|
||||
CLUTTER_NOTE (EVENT, "Updating keyboard state");
|
||||
keymap_x11->current_group = XkbStateGroup (&xkb_event->state);
|
||||
update_direction (keymap_x11, keymap_x11->current_group);
|
||||
update_locked_mods (keymap_x11, xkb_event->state.locked_mods);
|
||||
retval = TRUE;
|
||||
retval = CLUTTER_TRANSLATE_REMOVE;
|
||||
break;
|
||||
|
||||
case XkbNewKeyboardNotify:
|
||||
case XkbMapNotify:
|
||||
g_debug ("Updating keyboard mapping");
|
||||
CLUTTER_NOTE (EVENT, "Updating keyboard mapping");
|
||||
XkbRefreshKeyboardMapping (&xkb_event->map);
|
||||
keymap_x11->keymap_serial += 1;
|
||||
retval = TRUE;
|
||||
backend_x11->keymap_serial += 1;
|
||||
retval = CLUTTER_TRANSLATE_REMOVE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (xevent->type == MappingNotify)
|
||||
{
|
||||
XRefreshKeyboardMapping (&xevent->xmapping);
|
||||
keymap_x11->keymap_serial += 1;
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
meta_keymap_x11_get_key_group (MetaKeymapX11 *keymap,
|
||||
ClutterModifierType state)
|
||||
static void
|
||||
clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface)
|
||||
{
|
||||
iface->translate_event = clutter_keymap_x11_translate_event;
|
||||
}
|
||||
|
||||
gint
|
||||
_clutter_keymap_x11_get_key_group (ClutterKeymapX11 *keymap,
|
||||
ClutterModifierType state)
|
||||
{
|
||||
return XkbGroupForCoreState (state);
|
||||
}
|
||||
@@ -609,31 +638,37 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
* a fallback path.
|
||||
*/
|
||||
static int
|
||||
translate_keysym (MetaKeymapX11 *keymap,
|
||||
uint32_t hardware_keycode)
|
||||
translate_keysym (ClutterKeymapX11 *keymap,
|
||||
guint hardware_keycode)
|
||||
{
|
||||
int retval;
|
||||
ClutterBackendX11 *backend_x11;
|
||||
gint retval;
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (keymap->backend);
|
||||
|
||||
retval = XKeycodeToKeysym (backend_x11->xdpy, hardware_keycode, 0);
|
||||
|
||||
retval = XKeycodeToKeysym (clutter_x11_get_default_display (),
|
||||
hardware_keycode, 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
int
|
||||
meta_keymap_x11_translate_key_state (MetaKeymapX11 *keymap,
|
||||
uint32_t hardware_keycode,
|
||||
ClutterModifierType *modifier_state_p,
|
||||
ClutterModifierType *mods_p)
|
||||
gint
|
||||
_clutter_keymap_x11_translate_key_state (ClutterKeymapX11 *keymap,
|
||||
guint hardware_keycode,
|
||||
ClutterModifierType *modifier_state_p,
|
||||
ClutterModifierType *mods_p)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterModifierType unconsumed_modifiers = 0;
|
||||
ClutterModifierType modifier_state = *modifier_state_p;
|
||||
int retval;
|
||||
gint retval;
|
||||
|
||||
g_return_val_if_fail (META_IS_KEYMAP_X11 (keymap), 0);
|
||||
g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), 0);
|
||||
|
||||
if (keymap->use_xkb)
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (keymap->backend);
|
||||
|
||||
if (backend_x11->use_xkb)
|
||||
{
|
||||
XkbDescRec *xkb = get_xkb (keymap);
|
||||
KeySym tmp_keysym;
|
||||
@@ -661,15 +696,15 @@ meta_keymap_x11_translate_key_state (MetaKeymapX11 *keymap,
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_keymap_x11_get_is_modifier (MetaKeymapX11 *keymap,
|
||||
int keycode)
|
||||
_clutter_keymap_x11_get_is_modifier (ClutterKeymapX11 *keymap,
|
||||
gint keycode)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_KEYMAP_X11 (keymap), FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), FALSE);
|
||||
|
||||
if (keycode < keymap->min_keycode || keycode > keymap->max_keycode)
|
||||
return FALSE;
|
||||
|
||||
if (keymap->use_xkb)
|
||||
if (CLUTTER_BACKEND_X11 (keymap->backend)->use_xkb)
|
||||
{
|
||||
XkbDescRec *xkb = get_xkb (keymap);
|
||||
|
||||
@@ -681,18 +716,18 @@ meta_keymap_x11_get_is_modifier (MetaKeymapX11 *keymap,
|
||||
}
|
||||
|
||||
PangoDirection
|
||||
meta_keymap_x11_get_direction (MetaKeymapX11 *keymap)
|
||||
_clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_KEYMAP_X11 (keymap), PANGO_DIRECTION_NEUTRAL);
|
||||
g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), PANGO_DIRECTION_NEUTRAL);
|
||||
|
||||
if (keymap->use_xkb)
|
||||
if (CLUTTER_BACKEND_X11 (keymap->backend)->use_xkb)
|
||||
{
|
||||
if (!keymap->has_direction)
|
||||
{
|
||||
Display *xdisplay = CLUTTER_BACKEND_X11 (keymap->backend)->xdpy;
|
||||
XkbStateRec state_rec;
|
||||
|
||||
XkbGetState (clutter_x11_get_default_display (),
|
||||
XkbUseCoreKbd, &state_rec);
|
||||
XkbGetState (xdisplay, XkbUseCoreKbd, &state_rec);
|
||||
update_direction (keymap, XkbStateGroup (&state_rec));
|
||||
}
|
||||
|
||||
@@ -703,27 +738,27 @@ meta_keymap_x11_get_direction (MetaKeymapX11 *keymap)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_keymap_x11_get_entries_for_keyval (MetaKeymapX11 *keymap_x11,
|
||||
uint32_t keyval,
|
||||
ClutterKeymapKey **keys,
|
||||
int *n_keys)
|
||||
clutter_keymap_x11_get_entries_for_keyval (ClutterKeymapX11 *keymap_x11,
|
||||
guint keyval,
|
||||
ClutterKeymapKey **keys,
|
||||
gint *n_keys)
|
||||
{
|
||||
if (keymap_x11->use_xkb)
|
||||
if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
|
||||
{
|
||||
XkbDescRec *xkb = get_xkb (keymap_x11);
|
||||
GArray *retval;
|
||||
int keycode;
|
||||
gint keycode;
|
||||
|
||||
keycode = keymap_x11->min_keycode;
|
||||
retval = g_array_new (FALSE, FALSE, sizeof (ClutterKeymapKey));
|
||||
|
||||
while (keycode <= keymap_x11->max_keycode)
|
||||
{
|
||||
int max_shift_levels = XkbKeyGroupsWidth (xkb, keycode);
|
||||
int group = 0;
|
||||
int level = 0;
|
||||
int total_syms = XkbKeyNumSyms (xkb, keycode);
|
||||
int i = 0;
|
||||
gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode);
|
||||
gint group = 0;
|
||||
gint level = 0;
|
||||
gint total_syms = XkbKeyNumSyms (xkb, keycode);
|
||||
gint i = 0;
|
||||
KeySym *entry;
|
||||
|
||||
/* entry is an array with all syms for group 0, all
|
||||
@@ -785,18 +820,18 @@ meta_keymap_x11_get_entries_for_keyval (MetaKeymapX11 *keymap_x11,
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
meta_keymap_x11_get_available_keycode (MetaKeymapX11 *keymap_x11)
|
||||
static guint
|
||||
clutter_keymap_x11_get_available_keycode (ClutterKeymapX11 *keymap_x11)
|
||||
{
|
||||
if (keymap_x11->use_xkb)
|
||||
if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
|
||||
{
|
||||
meta_keymap_x11_refresh_reserved_keycodes (keymap_x11);
|
||||
clutter_keymap_x11_refresh_reserved_keycodes (keymap_x11);
|
||||
|
||||
if (g_hash_table_size (keymap_x11->reserved_keycodes) < 5)
|
||||
{
|
||||
Display *dpy = clutter_x11_get_default_display ();
|
||||
XkbDescPtr xkb = get_xkb (keymap_x11);
|
||||
uint32_t i;
|
||||
guint i;
|
||||
|
||||
for (i = xkb->max_key_code; i >= xkb->min_key_code; --i)
|
||||
{
|
||||
@@ -811,16 +846,15 @@ meta_keymap_x11_get_available_keycode (MetaKeymapX11 *keymap_x11)
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11,
|
||||
uint32_t keyval,
|
||||
uint32_t *keycode_out)
|
||||
gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11,
|
||||
guint keyval,
|
||||
guint *keycode_out)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_KEYMAP_X11 (keymap_x11), FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11), FALSE);
|
||||
g_return_val_if_fail (keyval != 0, FALSE);
|
||||
g_return_val_if_fail (keycode_out != NULL, FALSE);
|
||||
|
||||
*keycode_out = meta_keymap_x11_get_available_keycode (keymap_x11);
|
||||
*keycode_out = clutter_keymap_x11_get_available_keycode (keymap_x11);
|
||||
|
||||
if (*keycode_out == NoSymbol)
|
||||
{
|
||||
@@ -828,7 +862,7 @@ meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!meta_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval))
|
||||
if (!clutter_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval))
|
||||
{
|
||||
g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval);
|
||||
return FALSE;
|
||||
@@ -840,11 +874,10 @@ meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11,
|
||||
uint32_t keycode)
|
||||
void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11,
|
||||
guint keycode)
|
||||
{
|
||||
g_return_if_fail (META_IS_KEYMAP_X11 (keymap_x11));
|
||||
g_return_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11));
|
||||
|
||||
if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) ||
|
||||
g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1)
|
||||
@@ -854,10 +887,11 @@ meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11,
|
||||
}
|
||||
|
||||
void
|
||||
meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11,
|
||||
uint32_t level,
|
||||
gboolean enable)
|
||||
clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
|
||||
uint32_t level,
|
||||
gboolean enable)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);
|
||||
uint32_t modifiers[] = {
|
||||
0,
|
||||
ShiftMask,
|
||||
@@ -866,7 +900,7 @@ meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11,
|
||||
};
|
||||
uint32_t value = 0;
|
||||
|
||||
if (!keymap_x11->use_xkb)
|
||||
if (!backend_x11->use_xkb)
|
||||
return;
|
||||
|
||||
level = CLAMP (level, 0, G_N_ELEMENTS (modifiers) - 1);
|
||||
@@ -882,34 +916,34 @@ meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11,
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
meta_keymap_x11_get_current_group (MetaKeymapX11 *keymap_x11)
|
||||
clutter_keymap_x11_get_current_group (ClutterKeymapX11 *keymap_x11)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);
|
||||
XkbStateRec state_rec;
|
||||
|
||||
if (keymap_x11->current_group >= 0)
|
||||
return keymap_x11->current_group;
|
||||
|
||||
XkbGetState (clutter_x11_get_default_display (),
|
||||
XkbUseCoreKbd, &state_rec);
|
||||
XkbGetState (backend_x11->xdpy, XkbUseCoreKbd, &state_rec);
|
||||
return XkbStateGroup (&state_rec);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_keymap_x11_keycode_for_keyval (MetaKeymapX11 *keymap_x11,
|
||||
uint32_t keyval,
|
||||
uint32_t *keycode_out,
|
||||
uint32_t *level_out)
|
||||
clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
|
||||
guint keyval,
|
||||
guint *keycode_out,
|
||||
guint *level_out)
|
||||
{
|
||||
ClutterKeymapKey *keys;
|
||||
int i, n_keys, group;
|
||||
gint i, n_keys, group;
|
||||
gboolean found = FALSE;
|
||||
|
||||
g_return_val_if_fail (keycode_out != NULL, FALSE);
|
||||
g_return_val_if_fail (level_out != NULL, FALSE);
|
||||
|
||||
group = meta_keymap_x11_get_current_group (keymap_x11);
|
||||
group = clutter_keymap_x11_get_current_group (keymap_x11);
|
||||
|
||||
if (!meta_keymap_x11_get_entries_for_keyval (keymap_x11, keyval, &keys, &n_keys))
|
||||
if (!clutter_keymap_x11_get_entries_for_keyval (keymap_x11, keyval, &keys, &n_keys))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < n_keys && !found; i++)
|
||||
@@ -930,8 +964,8 @@ meta_keymap_x11_keycode_for_keyval (MetaKeymapX11 *keymap_x11,
|
||||
g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes);
|
||||
while (!found && g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
uint32_t reserved_keycode = GPOINTER_TO_UINT (key);
|
||||
uint32_t reserved_keysym = GPOINTER_TO_UINT (value);
|
||||
guint reserved_keycode = GPOINTER_TO_UINT (key);
|
||||
guint reserved_keysym = GPOINTER_TO_UINT (value);
|
||||
|
||||
if (keyval == reserved_keysym)
|
||||
{
|
68
clutter/clutter/x11/clutter-keymap-x11.h
Normal file
68
clutter/clutter/x11/clutter-keymap-x11.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_KEYMAP_X11_H__
|
||||
#define __CLUTTER_KEYMAP_X11_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <pango/pango.h>
|
||||
#include <clutter/clutter-event.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_KEYMAP_X11 (_clutter_keymap_x11_get_type ())
|
||||
#define CLUTTER_KEYMAP_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_KEYMAP_X11, ClutterKeymapX11))
|
||||
#define CLUTTER_IS_KEYMAP_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_KEYMAP_X11))
|
||||
|
||||
typedef struct _ClutterKeymapX11 ClutterKeymapX11;
|
||||
|
||||
GType _clutter_keymap_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
gint _clutter_keymap_x11_get_key_group (ClutterKeymapX11 *keymap,
|
||||
ClutterModifierType state);
|
||||
gboolean _clutter_keymap_x11_get_num_lock_state (ClutterKeymapX11 *keymap);
|
||||
gboolean _clutter_keymap_x11_get_caps_lock_state (ClutterKeymapX11 *keymap);
|
||||
gint _clutter_keymap_x11_translate_key_state (ClutterKeymapX11 *keymap,
|
||||
guint hardware_keycode,
|
||||
ClutterModifierType *modifier_state_p,
|
||||
ClutterModifierType *mods_p);
|
||||
gboolean _clutter_keymap_x11_get_is_modifier (ClutterKeymapX11 *keymap,
|
||||
gint keycode);
|
||||
|
||||
PangoDirection _clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap);
|
||||
|
||||
gboolean clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
|
||||
guint keyval,
|
||||
guint *keycode_out,
|
||||
guint *level_out);
|
||||
void clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
|
||||
uint32_t level,
|
||||
gboolean enable);
|
||||
gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11,
|
||||
guint keyval,
|
||||
guint *keycode_out);
|
||||
void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11,
|
||||
guint keycode);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_KEYMAP_X11_H__ */
|
File diff suppressed because it is too large
Load Diff
96
clutter/clutter/x11/clutter-stage-x11.h
Normal file
96
clutter/clutter/x11/clutter-stage-x11.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* Clutter.
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
* Copyright (C) 2006-2007 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_STAGE_X11_H__
|
||||
#define __CLUTTER_STAGE_X11_H__
|
||||
|
||||
#include <clutter/clutter-group.h>
|
||||
#include <clutter/clutter-stage.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include "clutter-backend-x11.h"
|
||||
#include "cogl/clutter-stage-cogl.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_STAGE_X11 (_clutter_stage_x11_get_type ())
|
||||
#define CLUTTER_STAGE_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_STAGE_X11, ClutterStageX11))
|
||||
#define CLUTTER_IS_STAGE_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_STAGE_X11))
|
||||
#define CLUTTER_STAGE_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_STAGE_X11, ClutterStageX11Class))
|
||||
#define CLUTTER_IS_STAGE_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_STAGE_X11))
|
||||
#define CLUTTER_STAGE_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_STAGE_X11, ClutterStageX11Class))
|
||||
|
||||
typedef struct _ClutterStageX11 ClutterStageX11;
|
||||
typedef struct _ClutterStageX11Class ClutterStageX11Class;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterStageX11, g_object_unref)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STAGE_X11_WITHDRAWN = 1 << 1
|
||||
} ClutterStageX11State;
|
||||
|
||||
struct _ClutterStageX11
|
||||
{
|
||||
ClutterStageCogl parent_instance;
|
||||
|
||||
CoglOnscreen *onscreen;
|
||||
Window xwin;
|
||||
gint xwin_width;
|
||||
gint xwin_height; /* FIXME target_width / height */
|
||||
|
||||
ClutterStageView *legacy_view;
|
||||
GList *legacy_views;
|
||||
|
||||
CoglFrameClosure *frame_closure;
|
||||
|
||||
gchar *title;
|
||||
|
||||
guint clipped_redraws_cool_off;
|
||||
|
||||
ClutterStageX11State wm_state;
|
||||
|
||||
guint is_foreign_xwin : 1;
|
||||
guint is_cursor_visible : 1;
|
||||
guint viewport_initialized : 1;
|
||||
guint accept_focus : 1;
|
||||
};
|
||||
|
||||
struct _ClutterStageX11Class
|
||||
{
|
||||
ClutterStageCoglClass parent_class;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType _clutter_stage_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _clutter_stage_x11_events_device_changed (ClutterStageX11 *stage_x11,
|
||||
ClutterInputDevice *device,
|
||||
ClutterDeviceManager *device_manager);
|
||||
|
||||
/* Private to subclasses */
|
||||
void _clutter_stage_x11_set_user_time (ClutterStageX11 *stage_x11,
|
||||
guint32 user_time);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_STAGE_H__ */
|
219
clutter/clutter/x11/clutter-virtual-input-device-x11.c
Normal file
219
clutter/clutter/x11/clutter-virtual-input-device-x11.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2016 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "clutter-x11.h"
|
||||
#include "X11/extensions/XTest.h"
|
||||
|
||||
#include "clutter-virtual-input-device.h"
|
||||
#include "x11/clutter-virtual-input-device-x11.h"
|
||||
#include "x11/clutter-backend-x11.h"
|
||||
#include "x11/clutter-keymap-x11.h"
|
||||
|
||||
struct _ClutterVirtualInputDeviceX11
|
||||
{
|
||||
ClutterVirtualInputDevice parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ClutterVirtualInputDeviceX11,
|
||||
clutter_virtual_input_device_x11,
|
||||
CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE)
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy)
|
||||
{
|
||||
XTestFakeRelativeMotionEvent (clutter_x11_get_default_display (),
|
||||
(int) dx,
|
||||
(int) dy,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
XTestFakeMotionEvent (clutter_x11_get_default_display (),
|
||||
clutter_x11_get_default_screen (),
|
||||
(int) x,
|
||||
(int) y,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_button (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t button,
|
||||
ClutterButtonState button_state)
|
||||
{
|
||||
XTestFakeButtonEvent (clutter_x11_get_default_display (),
|
||||
button, button_state == CLUTTER_BUTTON_STATE_PRESSED, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
Display *xdisplay = clutter_x11_get_default_display ();
|
||||
int button;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case CLUTTER_SCROLL_UP:
|
||||
button = 4;
|
||||
break;
|
||||
case CLUTTER_SCROLL_DOWN:
|
||||
button = 5;
|
||||
break;
|
||||
case CLUTTER_SCROLL_LEFT:
|
||||
button = 6;
|
||||
break;
|
||||
case CLUTTER_SCROLL_RIGHT:
|
||||
button = 7;
|
||||
break;
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
return;
|
||||
}
|
||||
|
||||
XTestFakeButtonEvent (xdisplay, button, True, 0);
|
||||
XTestFakeButtonEvent (xdisplay, button, False, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t key,
|
||||
ClutterKeyState key_state)
|
||||
{
|
||||
XTestFakeKeyEvent (clutter_x11_get_default_display (),
|
||||
key, key_state == CLUTTER_KEY_STATE_PRESSED, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t keyval,
|
||||
ClutterKeyState key_state)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||
ClutterKeymapX11 *keymap = backend_x11->keymap;
|
||||
uint32_t keycode, level;
|
||||
|
||||
if (!clutter_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level))
|
||||
{
|
||||
level = 0;
|
||||
|
||||
if (!clutter_keymap_x11_reserve_keycode (keymap, keyval, &keycode))
|
||||
{
|
||||
g_warning ("No keycode found for keyval %x in current group", keyval);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) &&
|
||||
key_state == CLUTTER_KEY_STATE_PRESSED)
|
||||
clutter_keymap_x11_latch_modifiers (keymap, level, TRUE);
|
||||
|
||||
XTestFakeKeyEvent (clutter_x11_get_default_display (),
|
||||
(KeyCode) keycode,
|
||||
key_state == CLUTTER_KEY_STATE_PRESSED, 0);
|
||||
|
||||
|
||||
if (key_state == CLUTTER_KEY_STATE_RELEASED)
|
||||
{
|
||||
if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode))
|
||||
clutter_keymap_x11_latch_modifiers (keymap, level, FALSE);
|
||||
clutter_keymap_x11_release_keycode_if_needed (keymap, keycode);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
g_warning ("Virtual touch motion not implemented under X11");
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
g_warning ("Virtual touch motion not implemented under X11");
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot)
|
||||
{
|
||||
g_warning ("Virtual touch motion not implemented under X11");
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_init (ClutterVirtualInputDeviceX11 *virtual_device_x11)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_class_init (ClutterVirtualInputDeviceX11Class *klass)
|
||||
{
|
||||
ClutterVirtualInputDeviceClass *virtual_input_device_class =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_CLASS (klass);
|
||||
|
||||
virtual_input_device_class->notify_relative_motion = clutter_virtual_input_device_x11_notify_relative_motion;
|
||||
virtual_input_device_class->notify_absolute_motion = clutter_virtual_input_device_x11_notify_absolute_motion;
|
||||
virtual_input_device_class->notify_button = clutter_virtual_input_device_x11_notify_button;
|
||||
virtual_input_device_class->notify_discrete_scroll = clutter_virtual_input_device_x11_notify_discrete_scroll;
|
||||
virtual_input_device_class->notify_scroll_continuous = clutter_virtual_input_device_x11_notify_scroll_continuous;
|
||||
virtual_input_device_class->notify_key = clutter_virtual_input_device_x11_notify_key;
|
||||
virtual_input_device_class->notify_keyval = clutter_virtual_input_device_x11_notify_keyval;
|
||||
virtual_input_device_class->notify_touch_down = clutter_virtual_input_device_x11_notify_touch_down;
|
||||
virtual_input_device_class->notify_touch_motion = clutter_virtual_input_device_x11_notify_touch_motion;
|
||||
virtual_input_device_class->notify_touch_up = clutter_virtual_input_device_x11_notify_touch_up;
|
||||
}
|
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2016 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -17,15 +21,15 @@
|
||||
* Author: Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_VIRTUAL_INPUT_DEVICE_X11_H
|
||||
#define META_VIRTUAL_INPUT_DEVICE_X11_H
|
||||
#ifndef __CLUTTER_VIRTUAL_INPUT_DEVICE_X11_H__
|
||||
#define __CLUTTER_VIRTUAL_INPUT_DEVICE_X11_H__
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
#include "clutter-virtual-input-device.h"
|
||||
|
||||
#define META_TYPE_VIRTUAL_INPUT_DEVICE_X11 (meta_virtual_input_device_x11_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaVirtualInputDeviceX11,
|
||||
meta_virtual_input_device_x11,
|
||||
META, VIRTUAL_INPUT_DEVICE_X11,
|
||||
#define CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_X11 (clutter_virtual_input_device_x11_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (ClutterVirtualInputDeviceX11,
|
||||
clutter_virtual_input_device_x11,
|
||||
CLUTTER, VIRTUAL_INPUT_DEVICE_X11,
|
||||
ClutterVirtualInputDevice)
|
||||
|
||||
#endif /* META_VIRTUAL_INPUT_DEVICE_X11_H */
|
||||
#endif /* __CLUTTER_VIRTUAL_INPUT_DEVICE_X11_H__ */
|
@@ -100,8 +100,16 @@ int clutter_x11_get_default_screen (void);
|
||||
CLUTTER_EXPORT
|
||||
Window clutter_x11_get_root_window (void);
|
||||
CLUTTER_EXPORT
|
||||
XVisualInfo *clutter_x11_get_visual_info (void);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_x11_set_display (Display * xdpy);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
Window clutter_x11_get_stage_window (ClutterStage *stage);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_x11_set_stage_foreign (ClutterStage *stage,
|
||||
Window xwindow);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_x11_add_filter (ClutterX11FilterFunc func,
|
||||
gpointer data);
|
||||
@@ -109,6 +117,20 @@ CLUTTER_EXPORT
|
||||
void clutter_x11_remove_filter (ClutterX11FilterFunc func,
|
||||
gpointer data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterX11FilterReturn clutter_x11_handle_event (XEvent *xevent);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_x11_disable_event_retrieval (void);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_x11_has_event_retrieval (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterStage *clutter_x11_get_stage_from_window (Window win);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_x11_has_xinput (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_x11_has_composite_extension (void);
|
||||
|
||||
@@ -122,6 +144,15 @@ void clutter_x11_set_use_stereo_stage (gboolean use_stereo);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_x11_get_use_stereo_stage (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
Time clutter_x11_get_current_event_time (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gint clutter_x11_event_get_key_group (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_x11_event_sequence_get_touch_detail (const ClutterEventSequence *sequence);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_X11_H__ */
|
||||
|
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
*
|
||||
* Copyright © 2001 Ximian, Inc.
|
||||
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||
* Copyright (C) 2017 Red Hat
|
||||
@@ -20,16 +21,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-xkb-a11y-x11.h"
|
||||
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/XKBstr.h>
|
||||
|
||||
#include "backends/x11/meta-xkb-a11y-x11.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
#include "core/display-private.h"
|
||||
#include "meta/meta-x11-errors.h"
|
||||
|
||||
#define DEFAULT_XKB_SET_CONTROLS_MASK XkbSlowKeysMask | \
|
||||
XkbBounceKeysMask | \
|
||||
XkbStickyKeysMask | \
|
||||
@@ -43,17 +40,17 @@
|
||||
static int _xkb_event_base;
|
||||
|
||||
static XkbDescRec *
|
||||
get_xkb_desc_rec (Display *xdisplay)
|
||||
get_xkb_desc_rec (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
XkbDescRec *desc;
|
||||
Status status = Success;
|
||||
|
||||
clutter_x11_trap_x_errors ();
|
||||
desc = XkbGetMap (xdisplay, XkbAllMapComponentsMask, XkbUseCoreKbd);
|
||||
desc = XkbGetMap (backend_x11->xdpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
|
||||
if (desc != NULL)
|
||||
{
|
||||
desc->ctrls = NULL;
|
||||
status = XkbGetControls (xdisplay, XkbAllControlsMask, desc);
|
||||
status = XkbGetControls (backend_x11->xdpy, XkbAllControlsMask, desc);
|
||||
}
|
||||
clutter_x11_untrap_x_errors ();
|
||||
|
||||
@@ -65,24 +62,25 @@ get_xkb_desc_rec (Display *xdisplay)
|
||||
}
|
||||
|
||||
static void
|
||||
set_xkb_desc_rec (Display *xdisplay,
|
||||
XkbDescRec *desc)
|
||||
set_xkb_desc_rec (ClutterBackendX11 *backend_x11,
|
||||
XkbDescRec *desc)
|
||||
{
|
||||
clutter_x11_trap_x_errors ();
|
||||
XkbSetControls (xdisplay, DEFAULT_XKB_SET_CONTROLS_MASK, desc);
|
||||
XSync (xdisplay, FALSE);
|
||||
XkbSetControls (backend_x11->xdpy, DEFAULT_XKB_SET_CONTROLS_MASK, desc);
|
||||
XSync (backend_x11->xdpy, FALSE);
|
||||
clutter_x11_untrap_x_errors ();
|
||||
}
|
||||
|
||||
static void
|
||||
check_settings_changed (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
Display *xdisplay = clutter_x11_get_default_display ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
||||
ClutterKeyboardA11yFlags what_changed = 0;
|
||||
XkbDescRec *desc;
|
||||
|
||||
desc = get_xkb_desc_rec (xdisplay);
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||
desc = get_xkb_desc_rec (backend_x11);
|
||||
if (!desc)
|
||||
return;
|
||||
|
||||
@@ -147,14 +145,14 @@ xkb_a11y_event_filter (XEvent *xevent,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_xkb_available (Display *xdisplay)
|
||||
is_xkb_available (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
int opcode, error_base, event_base, major, minor;
|
||||
gint opcode, error_base, event_base, major, minor;
|
||||
|
||||
if (_xkb_event_base)
|
||||
return TRUE;
|
||||
|
||||
if (!XkbQueryExtension (xdisplay,
|
||||
if (!XkbQueryExtension (backend_x11->xdpy,
|
||||
&opcode,
|
||||
&event_base,
|
||||
&error_base,
|
||||
@@ -162,7 +160,7 @@ is_xkb_available (Display *xdisplay)
|
||||
&minor))
|
||||
return FALSE;
|
||||
|
||||
if (!XkbUseExtension (xdisplay, &major, &minor))
|
||||
if (!XkbUseExtension (backend_x11->xdpy, &major, &minor))
|
||||
return FALSE;
|
||||
|
||||
_xkb_event_base = event_base;
|
||||
@@ -194,20 +192,18 @@ set_xkb_ctrl (XkbDescRec *desc,
|
||||
}
|
||||
|
||||
void
|
||||
meta_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *kbd_a11y_settings)
|
||||
clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *kbd_a11y_settings)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
Display *xdisplay = clutter_x11_get_default_display ();
|
||||
XkbDescRec *desc;
|
||||
gboolean enable_accessX;
|
||||
ClutterBackendX11 *backend_x11;
|
||||
XkbDescRec *desc;
|
||||
gboolean enable_accessX;
|
||||
|
||||
desc = get_xkb_desc_rec (xdisplay);
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||
desc = get_xkb_desc_rec (backend_x11);
|
||||
if (!desc)
|
||||
return;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
|
||||
/* general */
|
||||
enable_accessX = kbd_a11y_settings->controls & CLUTTER_A11Y_KEYBOARD_ENABLED;
|
||||
|
||||
@@ -245,7 +241,7 @@ meta_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_
|
||||
}
|
||||
|
||||
/* mouse keys */
|
||||
if (clutter_keymap_get_num_lock_state (clutter_backend_get_keymap (backend)))
|
||||
if (clutter_keymap_get_num_lock_state (CLUTTER_KEYMAP (backend_x11->keymap)))
|
||||
{
|
||||
/* Disable mousekeys when NumLock is ON */
|
||||
desc->ctrls->enabled_ctrls &= ~(XkbMouseKeysMask | XkbMouseKeysAccelMask);
|
||||
@@ -253,8 +249,8 @@ meta_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_
|
||||
else if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
|
||||
{
|
||||
int mk_max_speed;
|
||||
int mk_accel_time;
|
||||
gint mk_max_speed;
|
||||
gint mk_accel_time;
|
||||
|
||||
desc->ctrls->mk_interval = 100; /* msec between mousekey events */
|
||||
desc->ctrls->mk_curve = 50;
|
||||
@@ -311,22 +307,25 @@ meta_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_IndicatorFBMask);
|
||||
|
||||
set_xkb_desc_rec (xdisplay, desc);
|
||||
set_xkb_desc_rec (backend_x11, desc);
|
||||
XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_device_manager_x11_a11y_init (ClutterDeviceManager *device_manager)
|
||||
clutter_device_manager_x11_a11y_init (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
Display *xdisplay = clutter_x11_get_default_display ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
guint event_mask;
|
||||
|
||||
if (!is_xkb_available (xdisplay))
|
||||
backend_x11 =
|
||||
CLUTTER_BACKEND_X11 (_clutter_device_manager_get_backend (device_manager));
|
||||
|
||||
if (!is_xkb_available (backend_x11))
|
||||
return FALSE;
|
||||
|
||||
event_mask = XkbControlsNotifyMask | XkbAccessXNotifyMask;
|
||||
|
||||
XkbSelectEvents (xdisplay, XkbUseCoreKbd, event_mask, event_mask);
|
||||
XkbSelectEvents (backend_x11->xdpy, XkbUseCoreKbd, event_mask, event_mask);
|
||||
|
||||
clutter_x11_add_filter (xkb_a11y_event_filter, device_manager);
|
||||
|
@@ -21,18 +21,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef META_XKB_A11Y_X11_H
|
||||
#define META_XKB_A11Y_X11_H
|
||||
#ifndef CLUTTER_XKB_A11Y_X11_H
|
||||
#define CLUTTER_XKB_A11Y_X11_H
|
||||
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-backend-x11.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
|
||||
void
|
||||
meta_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *kbd_a11y_settings);
|
||||
clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *kbd_a11y_settings);
|
||||
|
||||
gboolean
|
||||
meta_device_manager_x11_a11y_init (ClutterDeviceManager *device_manager);
|
||||
clutter_device_manager_x11_a11y_init (ClutterDeviceManager *device_manager);
|
||||
|
||||
#endif /* META_XKB_A11Y_X11_H */
|
||||
#endif /* CLUTTER_XKB_A11Y_X11_H */
|
@@ -71,6 +71,14 @@ if have_x11
|
||||
]
|
||||
endif
|
||||
|
||||
if have_native_backend
|
||||
clutter_pkg_private_deps += [
|
||||
libudev_dep,
|
||||
libinput_dep,
|
||||
xkbcommon_dep,
|
||||
]
|
||||
endif
|
||||
|
||||
if have_libwacom
|
||||
clutter_pkg_private_deps += [
|
||||
libwacom_dep,
|
||||
@@ -86,3 +94,6 @@ clutter_deps = [
|
||||
|
||||
subdir('clutter')
|
||||
|
||||
if have_clutter_tests
|
||||
subdir('tests')
|
||||
endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user