Compare commits

..

1 Commits

Author SHA1 Message Date
f1484fa6c2 Add dcvviewer to xwayland_grab_default_access_rules
dcvviewer does not have native wayland support yet

https://gitlab.gnome.org/GNOME/mutter/merge_requests/587
2019-05-22 14:55:03 +00:00
664 changed files with 28215 additions and 25692 deletions

View File

@ -28,20 +28,6 @@ build-mutter:
- merge_requests
- /^.*$/
build-without-native-backend:
stage: build
script:
- meson . build -Dbuildtype=debugoptimized -Dnative_backend=false -Dudev=false --werror --prefix /usr
- ninja -C build
- ninja -C build install
artifacts:
expire_in: 1 day
paths:
- build
only:
- merge_requests
- /^.*$/
test-mutter:
stage: test
dependencies:
@ -49,17 +35,15 @@ test-mutter:
variables:
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data"
G_SLICE: "always-malloc"
MALLOC_CHECK_: "3"
NO_AT_BRIDGE: "1"
MALLOC_PERTURB_: "123"
script:
- dconf update
- mkdir -m 700 $XDG_RUNTIME_DIR
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
- >
env MALLOC_PERTURB_="$((RANDOM % 256 + 1))"
dbus-run-session -- xvfb-run -s '+iglx -noreset'
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --print-errorlogs --wrap catchsegv
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --wrap catchsegv
only:
- merge_requests
- /^.*$/
@ -72,7 +56,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

View File

@ -1,39 +1,25 @@
# Rebuild and push with
#
# cd .gitlab-ci/
# docker build --no-cache -t registry.gitlab.gnome.org/gnome/mutter/master:v2 .
# docker push registry.gitlab.gnome.org/gnome/mutter/master:v2
#
FROM fedora:30
RUN dnf -y update && dnf -y upgrade && \
dnf install -y 'dnf-command(builddep)' && \
dnf install -y 'dnf-command(copr)' && \
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 && \
# Until Fedora catches up with meson build-deps
dnf install -y meson xorg-x11-server-Xorg gnome-settings-daemon-devel egl-wayland-devel xorg-x11-server-Xwayland && \
# Until Fedora catches up with mesa bug fixes
dnf upgrade -y mesa-dri-drivers mesa-libEGL && \
# For running unit tests
dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 '*/xvfb-run' gdm-lib accountsservice-libs && \
dnf install -y sysprof-devel && \
# Unpackaged versions
dnf install -y https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00834984-gsettings-desktop-schemas/gsettings-desktop-schemas-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00834984-gsettings-desktop-schemas/gsettings-desktop-schemas-devel-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm && \
dnf install -y intltool redhat-rpm-config make && \
# 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 && \

120
NEWS
View File

@ -1,123 +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]
* Add xdg-output v2 support [Olivier; #645]
* Restore DRM format fallbacks [Jonas; !662]
* Don't emit ::size-changed when only position changed [Daniel; !568]
* Expose workspace layout properties [Florian; !618]
* Don't use grab modifiers when shortcuts are inhibited [Olivier; #642]
* Fix stuttering due to unchanged power save mode notifications [Georges; !674]
* Add API to reorder workspaces [Adam; !670]
* Make picking a new focus window more reliable [Marco; !669]
* Defer actor allocation till shown [Carlos; !677]
* Try to use primary GPU for copy instead of glReadPixels [Pekka; !615]
* Unset pointer focus when the cursor is hidden [Jonas D.; !448]
* Fix modifier-drag on wayland subsurfaces [Robert; !604]
* Fix background corruption on Nvidia after resuming from suspend [Daniel; !600]
* Only grab the locate-pointer key when necessary [Olivier; !685, #647]
* Misc. bug fixes and cleanups [Florian, Jonas, Daniel, Robert, Olivier,
Georges, Marco, Carlos, Emmanuele; !648, !650, !647, !656, !658, !637,
!663, !660, !659, !665, !666, !668, !667, #667, !676, !678, #672, !680,
!683, !688, !689, !687]
Contributors:
Jonas Ådahl, Emmanuele Bassi, Adam Bieńkowski, Piotr Drąg, Jonas Dreßler,
Olivier Fourdan, Carlos Garnacho, Robert Mader, Florian Müllner,
Georges Basile Stavracas Neto, Pekka Paalanen, Marco Trevisan (Treviño),
Daniel van Vugt
Translators:
Fabio Tomat [fur], Kukuh Syafaat [id]
3.33.3
======
* Prepare for running Xwayland on demand [Carlos; !420]
* Fix text selection color rendering [Florian; #494]
* Fix black shadows when using fractional scaling [Robert; #609]
* Honor startup sequence workspace on wayland [Carlos; gnome-shell#674]
* Only emit 'grab-op-end` signal after dropping grabs [Marco; !596]
* Add a Sysprof-based profiler [Jonas, Georges; !197, !603]
* Relax "xwayland-allow-grabs" setting [Olivier; #597]
* Implement locate-pointer accessibility feature [Olivier; !453]
* Implement mouse accessibility [Olivier; !512]
* Consolidate frame throttling [Daniel, Georges; !363]
* Fix setting blank cursor under wayland [Jonas; #630]
* Pixel-align OpenGL cursors [Jonas; !610]
* Handle returning from fullscreen/maximization better [Jonas; !621]
* Improve screencast support on multi-monitor systems [Georges; !623]
* Fix running X11 applications with sudo under wayland [Hans; #643]
* Implement toggle-keys notification [Olivier; #637]
* Add initial KMS transactional support [Jonas; !525]
* Improve finding new focus window when the old one is closed [Marco; #308]
* Misc. bug fixes and cleanups [Jonas, Carlos, Marco, Florian, Pekka, Robert,
Douglas, Georges, Daniel, Emil, Niels, Hans, Olivier, Ting-Wei, Corentin;
!591, #398, !592, !581, !597, !598, !593, !497, #591, !545, gtk#1675, !601,
#568, !564, !605, !609, !115, !214, !611, !617, !616, !619, !624, !622, !627,
!628, !629, !632, !633, !631, !636, !639, !638, !634, !640, !529, !644, !590]
Contributors:
Jonas Ådahl, Piotr Drąg, Olivier Fourdan, Carlos Garnacho, Hans de Goede,
Niels De Graef, Ting-Wei Lan, Robert Mader, Florian Müllner,
Georges Basile Stavracas Neto, Corentin Noël, Pekka Paalanen, Douglas R. Reno,
Marco Trevisan (Treviño), Emil Velikov, Daniel van Vugt
Translators:
Balázs Úr [hu], Daniel Mustieles [es], Nathan Follens [nl], Goran Vidović [hr]
3.33.2
======
* Fix rendering lag on Xorg [Daniel; !520, !281]
* Misc. bug fixes and cleanups [Carlos, Marco, Jonas D., Florian, Niels,
Daniel, Benjamin, Jonas Å., Ignacio, Vasilis; #598, !576, !547, !578,
!583, !582, !469, !524, !119, !571, !584, !585, !586, #425]
Contributors:
Jonas Ådahl, Benjamin Berg, Jonas Dreßler, Carlos Garnacho, Niels De Graef,
Vasilis Liaskovitis, Florian Müllner, Ignacio Casal Quinteiro,
Marco Trevisan (Treviño), Daniel van Vugt
Translators:
Daniel Mustieles [es]
3.33.1
======
* Remove unused APIs and outdated driver support

View File

@ -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 */

View File

@ -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);

View File

@ -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;
@ -10210,9 +10107,6 @@ clutter_actor_allocate (ClutterActor *self,
return;
}
if (!clutter_actor_is_visible (self))
return;
priv = self->priv;
old_allocation = priv->allocation;
@ -15022,30 +14916,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 +14978,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 +15010,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 +15171,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);
@ -17712,7 +17551,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
l != NULL && l->data != priv->current_effect;
l = l->next)
{
if (!_clutter_effect_modify_paint_volume (l->data, pv))
if (!_clutter_effect_get_paint_volume (l->data, pv))
{
clutter_paint_volume_free (pv);
CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "
@ -17730,7 +17569,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
/* otherwise, get the cumulative volume */
effects = _clutter_meta_group_peek_metas (priv->effects);
for (l = effects; l != NULL; l = l->next)
if (!_clutter_effect_modify_paint_volume (l->data, pv))
if (!_clutter_effect_get_paint_volume (l->data, pv))
{
clutter_paint_volume_free (pv);
CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "

View File

@ -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__ */

View File

@ -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)

View File

@ -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__ */

View File

@ -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
@ -1014,7 +1111,7 @@ _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend)
{
if (backend->dummy_onscreen == COGL_INVALID_HANDLE)
{
GError *internal_error = NULL;
CoglError *internal_error = NULL;
backend->dummy_onscreen = cogl_onscreen_new (backend->cogl_context, 1, 1);
@ -1022,7 +1119,7 @@ _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend)
&internal_error))
{
g_critical ("Unable to create dummy onscreen: %s", internal_error->message);
g_error_free (internal_error);
cogl_error_free (internal_error);
return;
}
}
@ -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;
}

View File

@ -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;
}
/*

View File

@ -178,8 +178,8 @@ clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
}
static gboolean
clutter_blur_effect_modify_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume)
clutter_blur_effect_get_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume)
{
gfloat cur_width, cur_height;
ClutterVertex origin;
@ -223,7 +223,7 @@ clutter_blur_effect_class_init (ClutterBlurEffectClass *klass)
gobject_class->dispose = clutter_blur_effect_dispose;
effect_class->pre_paint = clutter_blur_effect_pre_paint;
effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume;
effect_class->get_paint_volume = clutter_blur_effect_get_paint_volume;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->paint_target = clutter_blur_effect_paint_target;

View File

@ -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);

View File

@ -252,13 +252,6 @@ clutter_clone_allocate (ClutterActor *self,
if (priv->clone_source == NULL)
return;
/* ClutterActor delays allocating until the actor is shown; however
* we cannot paint it correctly in that case, so force an allocation.
*/
if (clutter_actor_get_parent (priv->clone_source) != NULL &&
!clutter_actor_has_allocation (priv->clone_source))
clutter_actor_allocate_preferred_size (priv->clone_source, flags);
#if 0
/* XXX - this is wrong: ClutterClone cannot clone unparented
* actors, as it will break all invariants

View File

@ -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);

View File

@ -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);
}

View File

@ -30,6 +30,7 @@ typedef enum
typedef enum
{
CLUTTER_DEBUG_NOP_PICKING = 1 << 0,
CLUTTER_DEBUG_DUMP_PICK_BUFFERS = 1 << 1
} ClutterPickDebugFlag;
typedef enum

View File

@ -17,6 +17,7 @@
#include "deprecated/clutter-container.h"
#include "deprecated/clutter-group.h"
#include "deprecated/clutter-keysyms.h"
#include "deprecated/clutter-main.h"
#include "deprecated/clutter-rectangle.h"
#include "deprecated/clutter-stage-manager.h"
#include "deprecated/clutter-stage.h"

View File

@ -69,23 +69,6 @@ typedef struct _ClutterTouchInfo
gfloat current_y;
} ClutterTouchInfo;
typedef struct _ClutterPtrA11yData
{
int n_btn_pressed;
float current_x;
float current_y;
float dwell_x;
float dwell_y;
gboolean dwell_drag_started;
gboolean dwell_gesture_started;
guint dwell_timer;
guint dwell_position_timer;
guint secondary_click_timer;
gboolean secondary_click_triggered;
} ClutterPtrA11yData;
struct _ClutterInputDevice
{
GObject parent_instance;
@ -160,10 +143,6 @@ struct _ClutterInputDevice
guint has_cursor : 1;
guint is_enabled : 1;
/* Accessiblity */
ClutterVirtualInputDevice *accessibility_virtual_device;
ClutterPtrA11yData *ptr_a11y_data;
};
typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,
@ -194,15 +173,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 +210,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 +235,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);

View File

@ -47,7 +47,6 @@
#include "clutter-stage-private.h"
#include "clutter-virtual-input-device.h"
#include "clutter-input-device-tool.h"
#include "clutter-input-pointer-a11y-private.h"
struct _ClutterDeviceManagerPrivate
{
@ -56,8 +55,6 @@ struct _ClutterDeviceManagerPrivate
/* Keyboard a11y */
ClutterKbdA11ySettings kbd_a11y_settings;
/* Pointer a11y */
ClutterPointerA11ySettings pointer_a11y_settings;
};
enum
@ -78,9 +75,6 @@ enum
TOOL_CHANGED,
KBD_A11Y_MASK_CHANGED,
KBD_A11Y_FLAGS_CHANGED,
PTR_A11Y_DWELL_CLICK_TYPE_CHANGED,
PTR_A11Y_TIMEOUT_STARTED,
PTR_A11Y_TIMEOUT_STOPPED,
LAST_SIGNAL
};
@ -91,14 +85,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 +119,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 +165,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 +185,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);
@ -236,74 +239,12 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
G_TYPE_NONE, 2,
G_TYPE_UINT,
G_TYPE_UINT);
/**
* ClutterDeviceManager::ptr-a11y-dwell-click-type-changed:
* @manager: the #ClutterDeviceManager that emitted the signal
* @click_type: the new #ClutterPointerA11yDwellClickType mode
*
* The ::ptr-a11y-dwell-click-type-changed signal is emitted each time
* the ClutterPointerA11yDwellClickType mode is changed as the result
* of pointer accessibility operations.
*/
manager_signals[PTR_A11Y_DWELL_CLICK_TYPE_CHANGED] =
g_signal_new (I_("ptr-a11y-dwell-click-type-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__FLAGS,
G_TYPE_NONE, 1,
CLUTTER_TYPE_POINTER_A11Y_DWELL_CLICK_TYPE);
/**
* ClutterDeviceManager::ptr-a11y-timeout-started:
* @manager: the #ClutterDeviceManager that emitted the signal
* @device: the core pointer #ClutterInputDevice
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
* @delay: the delay in ms before secondary-click is triggered.
*
* The ::ptr-a11y-timeout-started signal is emitted when a
* pointer accessibility timeout delay is started, so that upper
* layers can notify the user with some visual feedback.
*/
manager_signals[PTR_A11Y_TIMEOUT_STARTED] =
g_signal_new (I_("ptr-a11y-timeout-started"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__OBJECT_FLAGS_UINT,
G_TYPE_NONE, 3,
CLUTTER_TYPE_INPUT_DEVICE,
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
G_TYPE_UINT);
/**
* ClutterDeviceManager::ptr-a11y-timeout-stopped:
* @manager: the #ClutterDeviceManager that emitted the signal
* @device: the core pointer #ClutterInputDevice
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
* @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
* it's triggered at the end of the delay or cancelled, so that
* upper layers can notify the user with some visual feedback.
*/
manager_signals[PTR_A11Y_TIMEOUT_STOPPED] =
g_signal_new (I_("ptr-a11y-timeout-stopped"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__OBJECT_FLAGS_BOOLEAN,
G_TYPE_NONE, 3,
CLUTTER_TYPE_INPUT_DEVICE,
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
G_TYPE_BOOLEAN);
}
static void
clutter_device_manager_init (ClutterDeviceManager *self)
{
self->priv = clutter_device_manager_get_instance_private (self);
}
/**
@ -322,7 +263,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 +487,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 +558,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,103 +575,7 @@ 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;
}
static gboolean
are_pointer_a11y_settings_equal (ClutterPointerA11ySettings *a,
ClutterPointerA11ySettings *b)
{
return (memcmp (a, b, sizeof (ClutterPointerA11ySettings)) == 0);
}
static void
clutter_device_manager_enable_pointer_a11y (ClutterDeviceManager *device_manager)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device_manager,
CLUTTER_POINTER_DEVICE);
_clutter_input_pointer_a11y_add_device (core_pointer);
}
static void
clutter_device_manager_disable_pointer_a11y (ClutterDeviceManager *device_manager)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device_manager,
CLUTTER_POINTER_DEVICE);
_clutter_input_pointer_a11y_remove_device (core_pointer);
}
/**
* clutter_device_manager_set_pointer_a11y_settings:
* @device_manager: a #ClutterDeviceManager
* @settings: a pointer to a #ClutterPointerA11ySettings
*
* Sets the pointer accessibility settings
**/
void
clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings)
{
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))
return;
if (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)
clutter_device_manager_disable_pointer_a11y (device_manager);
priv->pointer_a11y_settings = *settings;
}
/**
* clutter_device_manager_get_pointer_a11y_settings:
* @device_manager: a #ClutterDeviceManager
* @settings: a pointer to a #ClutterPointerA11ySettings
*
* Gets the current pointer accessibility settings
**/
void
clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings)
{
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;
}
/**
* clutter_device_manager_set_pointer_a11y_dwell_click_type:
* @device_manager: a #ClutterDeviceManager
* @click_type: type of click as #ClutterPointerA11yDwellClickType
*
* Sets the dwell click type
**/
void
clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
ClutterPointerA11yDwellClickType click_type)
{
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;
*settings = device_manager->priv->kbd_a11y_settings;
}

View File

@ -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:
@ -70,25 +74,19 @@ typedef struct _ClutterKbdA11ySettings
} ClutterKbdA11ySettings;
/**
* ClutterPointerA11ySettings:
* ClutterDeviceManager:
*
* The #ClutterPointerA11ySettings structure contains pointer accessibility
* settings
* The #ClutterDeviceManager structure contains only private data
*
* Since: 1.2
*/
typedef struct _ClutterPointerA11ySettings
struct _ClutterDeviceManager
{
ClutterPointerA11yFlags controls;
ClutterPointerA11yDwellClickType dwell_click_type;
ClutterPointerA11yDwellMode dwell_mode;
ClutterPointerA11yDwellDirection dwell_gesture_single;
ClutterPointerA11yDwellDirection dwell_gesture_double;
ClutterPointerA11yDwellDirection dwell_gesture_drag;
ClutterPointerA11yDwellDirection dwell_gesture_secondary;
gint secondary_click_delay;
gint dwell_delay;
gint dwell_threshold;
} ClutterPointerA11ySettings;
/*< private >*/
GObject parent_instance;
ClutterDeviceManagerPrivate *priv;
};
/**
* ClutterDeviceManagerClass:
@ -123,18 +121,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
@ -159,23 +152,10 @@ ClutterVirtualDeviceType clutter_device_manager_get_supported_virtual_device_typ
CLUTTER_EXPORT
void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
ClutterKbdA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
ClutterKbdA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
ClutterPointerA11yDwellClickType click_type);
G_END_DECLS
#endif /* __CLUTTER_DEVICE_MANAGER_H__ */

View File

@ -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);

View File

@ -7,7 +7,7 @@ G_BEGIN_DECLS
gboolean _clutter_effect_pre_paint (ClutterEffect *effect);
void _clutter_effect_post_paint (ClutterEffect *effect);
gboolean _clutter_effect_modify_paint_volume (ClutterEffect *effect,
gboolean _clutter_effect_get_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume);
gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect);
void _clutter_effect_paint (ClutterEffect *effect,

View File

@ -188,8 +188,8 @@ clutter_effect_real_post_paint (ClutterEffect *effect)
}
static gboolean
clutter_effect_real_modify_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume)
clutter_effect_real_get_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume)
{
return TRUE;
}
@ -252,7 +252,7 @@ clutter_effect_class_init (ClutterEffectClass *klass)
klass->pre_paint = clutter_effect_real_pre_paint;
klass->post_paint = clutter_effect_real_post_paint;
klass->modify_paint_volume = clutter_effect_real_modify_paint_volume;
klass->get_paint_volume = clutter_effect_real_get_paint_volume;
klass->paint = clutter_effect_real_paint;
klass->pick = clutter_effect_real_pick;
}
@ -297,14 +297,13 @@ _clutter_effect_pick (ClutterEffect *effect,
}
gboolean
_clutter_effect_modify_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume)
_clutter_effect_get_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume)
{
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
g_return_val_if_fail (volume != NULL, FALSE);
return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume (effect,
volume);
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume (effect, volume);
}
gboolean
@ -312,7 +311,7 @@ _clutter_effect_has_custom_paint_volume (ClutterEffect *effect)
{
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume != clutter_effect_real_modify_paint_volume;
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume != clutter_effect_real_get_paint_volume;
}
/**

View File

@ -60,7 +60,7 @@ struct _ClutterEffect
* ClutterEffectClass:
* @pre_paint: virtual function
* @post_paint: virtual function
* @modify_paint_volume: virtual function
* @get_paint_volume: virtual function
* @paint: virtual function
* @pick: virtual function
*
@ -74,16 +74,16 @@ struct _ClutterEffectClass
ClutterActorMetaClass parent_class;
/*< public >*/
gboolean (* pre_paint) (ClutterEffect *effect);
void (* post_paint) (ClutterEffect *effect);
gboolean (* pre_paint) (ClutterEffect *effect);
void (* post_paint) (ClutterEffect *effect);
gboolean (* modify_paint_volume) (ClutterEffect *effect,
ClutterPaintVolume *volume);
gboolean (* get_paint_volume) (ClutterEffect *effect,
ClutterPaintVolume *volume);
void (* paint) (ClutterEffect *effect,
ClutterEffectPaintFlags flags);
void (* pick) (ClutterEffect *effect,
ClutterEffectPaintFlags flags);
void (* paint) (ClutterEffect *effect,
ClutterEffectPaintFlags flags);
void (* pick) (ClutterEffect *effect,
ClutterEffectPaintFlags flags);
/*< private >*/
void (* _clutter_effect4) (void);

View File

@ -13,7 +13,7 @@ G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@basename@" */
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/

View File

@ -277,6 +277,24 @@ typedef enum
CLUTTER_ANIMATION_LAST
} ClutterAnimationMode;
/**
* ClutterFontFlags:
* @CLUTTER_FONT_MIPMAPPING: Set to use mipmaps for the glyph cache textures.
* @CLUTTER_FONT_HINTING: Set to enable hinting on the glyphs.
*
* Runtime flags to change the font quality. To be used with
* clutter_set_font_flags().
*
* Since: 1.0
*
* Deprecated: 1.22: Use #cairo_font_options_t instead
*/
typedef enum /*< prefix=CLUTTER_FONT >*/
{
CLUTTER_FONT_MIPMAPPING = (1 << 0),
CLUTTER_FONT_HINTING = (1 << 1)
} ClutterFontFlags;
/**
* ClutterTextDirection:
* @CLUTTER_TEXT_DIRECTION_DEFAULT: Use the default setting, as returned
@ -425,88 +443,6 @@ typedef enum
CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
} ClutterKeyboardA11yFlags;
/**
* ClutterPointerA11yFlags:
* @CLUTTER_A11Y_POINTER_ENABLED:
* @CLUTTER_A11Y_SECONDARY_CLICK_ENABLED:
* @CLUTTER_A11Y_DWELL_ENABLED:
*
* Pointer accessibility features applied to a ClutterInputDevice pointer.
*
*/
typedef enum {
CLUTTER_A11Y_SECONDARY_CLICK_ENABLED = 1 << 0,
CLUTTER_A11Y_DWELL_ENABLED = 1 << 1,
} ClutterPointerA11yFlags;
/**
* ClutterPointerA11yDwellClickType:
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: Internal use only
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
*
* Dwell click types.
*
*/
typedef enum {
CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE,
CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY,
CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY,
CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE,
CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE,
CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG,
} ClutterPointerA11yDwellClickType;
/**
* ClutterPointerA11yDwellDirection:
* @CLUTTER_A11Y_DWELL_DIRECTION_NONE:
* @CLUTTER_A11Y_DWELL_DIRECTION_LEFT:
* @CLUTTER_A11Y_DWELL_DIRECTION_RIGHT:
* @CLUTTER_A11Y_DWELL_DIRECTION_UP:
* @CLUTTER_A11Y_DWELL_DIRECTION_DOWN:
*
* Dwell gesture directions.
*
*/
typedef enum {
CLUTTER_A11Y_DWELL_DIRECTION_NONE,
CLUTTER_A11Y_DWELL_DIRECTION_LEFT,
CLUTTER_A11Y_DWELL_DIRECTION_RIGHT,
CLUTTER_A11Y_DWELL_DIRECTION_UP,
CLUTTER_A11Y_DWELL_DIRECTION_DOWN,
} ClutterPointerA11yDwellDirection;
/**
* ClutterPointerA11yDwellMode:
* @CLUTTER_A11Y_DWELL_MODE_WINDOW:
* @CLUTTER_A11Y_DWELL_MODE_GESTURE:
*
* Dwell mode.
*
*/
typedef enum {
CLUTTER_A11Y_DWELL_MODE_WINDOW,
CLUTTER_A11Y_DWELL_MODE_GESTURE,
} ClutterPointerA11yDwellMode;
/**
* ClutterPointerA11yTimeoutType:
* @CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK:
* @CLUTTER_A11Y_TIMEOUT_TYPE_DWELL:
* @CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE:
*
* Pointer accessibility timeout type.
*
*/
typedef enum {
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
} ClutterPointerA11yTimeoutType;
/**
* ClutterActorFlags:
* @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside
@ -956,6 +892,8 @@ typedef enum /*< prefix=CLUTTER_SCROLL >*/
/**
* ClutterStageState:
* @CLUTTER_STAGE_STATE_FULLSCREEN: Fullscreen mask
* @CLUTTER_STAGE_STATE_OFFSCREEN: Offscreen mask (deprecated)
* @CLUTTER_STAGE_STATE_ACTIVATED: Activated mask
*
* Stage state masks, used by the #ClutterEvent of type %CLUTTER_STAGE_STATE.
@ -964,6 +902,8 @@ typedef enum /*< prefix=CLUTTER_SCROLL >*/
*/
typedef enum
{
CLUTTER_STAGE_STATE_FULLSCREEN = (1 << 1),
CLUTTER_STAGE_STATE_OFFSCREEN = (1 << 2),
CLUTTER_STAGE_STATE_ACTIVATED = (1 << 3)
} ClutterStageState;
@ -973,6 +913,7 @@ typedef enum
* @CLUTTER_FEATURE_TEXTURE_YUV: Set if YUV based textures supported.
* @CLUTTER_FEATURE_TEXTURE_READ_PIXELS: Set if texture pixels can be read.
* @CLUTTER_FEATURE_STAGE_STATIC: Set if stage size if fixed (i.e framebuffer)
* @CLUTTER_FEATURE_STAGE_USER_RESIZE: Set if stage is able to be user resized.
* @CLUTTER_FEATURE_STAGE_CURSOR: Set if stage has a graphical cursor.
* @CLUTTER_FEATURE_SHADERS_GLSL: Set if the backend supports GLSL shaders.
* @CLUTTER_FEATURE_OFFSCREEN: Set if the backend supports offscreen rendering.
@ -990,6 +931,7 @@ typedef enum
CLUTTER_FEATURE_TEXTURE_YUV = (1 << 4),
CLUTTER_FEATURE_TEXTURE_READ_PIXELS = (1 << 5),
CLUTTER_FEATURE_STAGE_STATIC = (1 << 6),
CLUTTER_FEATURE_STAGE_USER_RESIZE = (1 << 7),
CLUTTER_FEATURE_STAGE_CURSOR = (1 << 8),
CLUTTER_FEATURE_SHADERS_GLSL = (1 << 9),
CLUTTER_FEATURE_OFFSCREEN = (1 << 10),

View File

@ -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);

View 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);
}

View 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__ */

View File

@ -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);
}

View File

@ -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;
}

View File

@ -107,9 +107,6 @@ clutter_input_device_dispose (GObject *gobject)
device->associated = NULL;
}
if (device->accessibility_virtual_device)
g_clear_object (&device->accessibility_virtual_device);
g_clear_pointer (&device->axes, g_array_unref);
g_clear_pointer (&device->keys, g_array_unref);
g_clear_pointer (&device->scroll_info, g_array_unref);
@ -1925,157 +1922,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)

View File

@ -1,47 +0,0 @@
/*
* Copyright (C) 2019 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Author: Olivier Fourdan <ofourdan@redhat.com>
*/
#ifndef __CLUTTER_INPUT_POINTER_A11Y_H__
#define __CLUTTER_INPUT_POINTER_A11Y_H__
#include <clutter/clutter-types.h>
#include "clutter-enum-types.h"
G_BEGIN_DECLS
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
#endif /* __CLUTTER_INPUT_POINTER_A11Y_H__ */

View File

@ -1,710 +0,0 @@
/*
* Copyright (C) 2019 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Author: Olivier Fourdan <ofourdan@redhat.com>
*
* This reimplements in Clutter the same behavior as mousetweaks original
* implementation by Gerd Kohlberger <gerdko gmail com>
* mousetweaks Copyright (C) 2007-2010 Gerd Kohlberger <gerdko gmail com>
*/
#include "clutter-build-config.h"
#include "clutter-device-manager.h"
#include "clutter-device-manager-private.h"
#include "clutter-enum-types.h"
#include "clutter-input-device.h"
#include "clutter-input-pointer-a11y-private.h"
#include "clutter-main.h"
#include "clutter-virtual-input-device.h"
static gboolean
is_secondary_click_enabled (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
return (settings.controls & CLUTTER_A11Y_SECONDARY_CLICK_ENABLED);
}
static gboolean
is_dwell_click_enabled (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
return (settings.controls & CLUTTER_A11Y_DWELL_ENABLED);
}
static unsigned int
get_secondary_click_delay (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
return settings.secondary_click_delay;
}
static unsigned int
get_dwell_delay (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
return settings.dwell_delay;
}
static unsigned int
get_dwell_threshold (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
return settings.dwell_threshold;
}
static ClutterPointerA11yDwellMode
get_dwell_mode (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
return settings.dwell_mode;
}
static ClutterPointerA11yDwellClickType
get_dwell_click_type (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
return settings.dwell_click_type;
}
static ClutterPointerA11yDwellClickType
get_dwell_click_type_for_direction (ClutterInputDevice *device,
ClutterPointerA11yDwellDirection direction)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
if (direction == settings.dwell_gesture_single)
return CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
else if (direction == settings.dwell_gesture_double)
return CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE;
else if (direction == settings.dwell_gesture_drag)
return CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG;
else if (direction == settings.dwell_gesture_secondary)
return CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY;
return CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE;
}
static void
emit_button_press (ClutterInputDevice *device,
gint button)
{
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
g_get_monotonic_time (),
button,
CLUTTER_BUTTON_STATE_PRESSED);
}
static void
emit_button_release (ClutterInputDevice *device,
gint button)
{
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
g_get_monotonic_time (),
button,
CLUTTER_BUTTON_STATE_RELEASED);
}
static void
emit_button_click (ClutterInputDevice *device,
gint button)
{
emit_button_press (device, button);
emit_button_release (device, button);
}
static void
restore_dwell_position (ClutterInputDevice *device)
{
clutter_virtual_input_device_notify_absolute_motion (device->accessibility_virtual_device,
g_get_monotonic_time (),
device->ptr_a11y_data->dwell_x,
device->ptr_a11y_data->dwell_y);
}
static gboolean
trigger_secondary_click (gpointer data)
{
ClutterInputDevice *device = data;
device->ptr_a11y_data->secondary_click_triggered = TRUE;
device->ptr_a11y_data->secondary_click_timer = 0;
g_signal_emit_by_name (device->device_manager,
"ptr-a11y-timeout-stopped",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
TRUE);
return G_SOURCE_REMOVE;
}
static void
start_secondary_click_timeout (ClutterInputDevice *device)
{
unsigned int delay = get_secondary_click_delay (device);
device->ptr_a11y_data->secondary_click_timer =
clutter_threads_add_timeout (delay, trigger_secondary_click, device);
g_signal_emit_by_name (device->device_manager,
"ptr-a11y-timeout-started",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
delay);
}
static void
stop_secondary_click_timeout (ClutterInputDevice *device)
{
if (device->ptr_a11y_data->secondary_click_timer)
{
g_source_remove (device->ptr_a11y_data->secondary_click_timer);
device->ptr_a11y_data->secondary_click_timer = 0;
g_signal_emit_by_name (device->device_manager,
"ptr-a11y-timeout-stopped",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
FALSE);
}
device->ptr_a11y_data->secondary_click_triggered = FALSE;
}
static gboolean
pointer_has_moved (ClutterInputDevice *device)
{
float dx, dy;
gint threshold;
dx = device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x;
dy = device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y;
threshold = get_dwell_threshold (device);
/* Pythagorean theorem */
return ((dx * dx) + (dy * dy)) > (threshold * threshold);
}
static gboolean
is_secondary_click_pending (ClutterInputDevice *device)
{
return device->ptr_a11y_data->secondary_click_timer != 0;
}
static gboolean
is_secondary_click_triggered (ClutterInputDevice *device)
{
return device->ptr_a11y_data->secondary_click_triggered;
}
static gboolean
is_dwell_click_pending (ClutterInputDevice *device)
{
return device->ptr_a11y_data->dwell_timer != 0;
}
static gboolean
is_dwell_dragging (ClutterInputDevice *device)
{
return device->ptr_a11y_data->dwell_drag_started;
}
static gboolean
is_dwell_gesturing (ClutterInputDevice *device)
{
return device->ptr_a11y_data->dwell_gesture_started;
}
static gboolean
has_button_pressed (ClutterInputDevice *device)
{
return device->ptr_a11y_data->n_btn_pressed > 0;
}
static gboolean
should_start_secondary_click_timeout (ClutterInputDevice *device)
{
return !is_dwell_dragging (device);
}
static gboolean
should_start_dwell (ClutterInputDevice *device)
{
/* We should trigger a dwell if we've not already started one, and if
* no button is currently pressed or we are in the middle of a dwell
* drag action.
*/
return !is_dwell_click_pending (device) &&
(is_dwell_dragging (device) ||
!has_button_pressed (device));
}
static gboolean
should_stop_dwell (ClutterInputDevice *device)
{
/* We should stop a dwell if the motion exceeds the threshold, unless
* we've started a gesture, because we want to keep the original dwell
* location to both detect a gesture and restore the original pointer
* location once the gesture is finished.
*/
return pointer_has_moved (device) &&
!is_dwell_gesturing (device);
}
static gboolean
should_update_dwell_position (ClutterInputDevice *device)
{
return !is_dwell_gesturing (device) &&
!is_dwell_click_pending (device) &&
!is_secondary_click_pending (device);
}
static void
update_dwell_click_type (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
ClutterPointerA11yDwellClickType dwell_click_type;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
dwell_click_type = settings.dwell_click_type;
switch (dwell_click_type)
{
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
break;
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
if (!is_dwell_dragging (device))
dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
break;
case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE:
default:
break;
}
if (dwell_click_type != settings.dwell_click_type)
{
settings.dwell_click_type = dwell_click_type;
clutter_device_manager_set_pointer_a11y_settings (device->device_manager,
&settings);
g_signal_emit_by_name (device->device_manager,
"ptr-a11y-dwell-click-type-changed",
dwell_click_type);
}
}
static void
emit_dwell_click (ClutterInputDevice *device,
ClutterPointerA11yDwellClickType dwell_click_type)
{
switch (dwell_click_type)
{
case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
break;
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
break;
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
if (is_dwell_dragging (device))
{
emit_button_release (device, CLUTTER_BUTTON_PRIMARY);
device->ptr_a11y_data->dwell_drag_started = FALSE;
}
else
{
emit_button_press (device, CLUTTER_BUTTON_PRIMARY);
device->ptr_a11y_data->dwell_drag_started = TRUE;
}
break;
case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
emit_button_click (device, CLUTTER_BUTTON_SECONDARY);
break;
case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
emit_button_click (device, CLUTTER_BUTTON_MIDDLE);
break;
case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE:
default:
break;
}
}
static ClutterPointerA11yDwellDirection
get_dwell_direction (ClutterInputDevice *device)
{
float dx, dy;
dx = ABS (device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x);
dy = ABS (device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y);
/* The pointer hasn't moved */
if (!pointer_has_moved (device))
return CLUTTER_A11Y_DWELL_DIRECTION_NONE;
if (device->ptr_a11y_data->dwell_x < device->ptr_a11y_data->current_x)
{
if (dx > dy)
return CLUTTER_A11Y_DWELL_DIRECTION_LEFT;
}
else
{
if (dx > dy)
return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT;
}
if (device->ptr_a11y_data->dwell_y < device->ptr_a11y_data->current_y)
return CLUTTER_A11Y_DWELL_DIRECTION_UP;
return CLUTTER_A11Y_DWELL_DIRECTION_DOWN;
}
static gboolean
trigger_clear_dwell_gesture (gpointer data)
{
ClutterInputDevice *device = data;
device->ptr_a11y_data->dwell_timer = 0;
device->ptr_a11y_data->dwell_gesture_started = FALSE;
return G_SOURCE_REMOVE;
}
static gboolean
trigger_dwell_gesture (gpointer data)
{
ClutterInputDevice *device = data;
ClutterPointerA11yDwellDirection direction;
unsigned int delay = get_dwell_delay (device);
restore_dwell_position (device);
direction = get_dwell_direction (device);
emit_dwell_click (device,
get_dwell_click_type_for_direction (device,
direction));
/* Do not clear the gesture right away, otherwise we'll start another one */
device->ptr_a11y_data->dwell_timer =
clutter_threads_add_timeout (delay, trigger_clear_dwell_gesture, device);
g_signal_emit_by_name (device->device_manager,
"ptr-a11y-timeout-stopped",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
TRUE);
return G_SOURCE_REMOVE;
}
static void
start_dwell_gesture_timeout (ClutterInputDevice *device)
{
unsigned int delay = get_dwell_delay (device);
device->ptr_a11y_data->dwell_timer =
clutter_threads_add_timeout (delay, trigger_dwell_gesture, device);
device->ptr_a11y_data->dwell_gesture_started = TRUE;
g_signal_emit_by_name (device->device_manager,
"ptr-a11y-timeout-started",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
delay);
}
static gboolean
trigger_dwell_click (gpointer data)
{
ClutterInputDevice *device = data;
device->ptr_a11y_data->dwell_timer = 0;
g_signal_emit_by_name (device->device_manager,
"ptr-a11y-timeout-stopped",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
TRUE);
if (get_dwell_mode (device) == CLUTTER_A11Y_DWELL_MODE_GESTURE)
{
if (is_dwell_dragging (device))
emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
else
start_dwell_gesture_timeout (device);
}
else
{
emit_dwell_click (device, get_dwell_click_type (device));
update_dwell_click_type (device);
}
return G_SOURCE_REMOVE;
}
static void
start_dwell_timeout (ClutterInputDevice *device)
{
unsigned int delay = get_dwell_delay (device);
device->ptr_a11y_data->dwell_timer =
clutter_threads_add_timeout (delay, trigger_dwell_click, device);
g_signal_emit_by_name (device->device_manager,
"ptr-a11y-timeout-started",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
delay);
}
static void
stop_dwell_timeout (ClutterInputDevice *device)
{
if (device->ptr_a11y_data->dwell_timer)
{
g_source_remove (device->ptr_a11y_data->dwell_timer);
device->ptr_a11y_data->dwell_timer = 0;
device->ptr_a11y_data->dwell_gesture_started = FALSE;
g_signal_emit_by_name (device->device_manager,
"ptr-a11y-timeout-stopped",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
FALSE);
}
}
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)
{
device->ptr_a11y_data->dwell_x = device->ptr_a11y_data->current_x;
device->ptr_a11y_data->dwell_y = device->ptr_a11y_data->current_y;
}
static void
update_current_position (ClutterInputDevice *device,
float x,
float y)
{
device->ptr_a11y_data->current_x = x;
device->ptr_a11y_data->current_y = y;
}
static gboolean
is_device_core_pointer (ClutterInputDevice *device)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
CLUTTER_POINTER_DEVICE);
if (core_pointer == NULL)
return FALSE;
return (core_pointer == device);
}
void
_clutter_input_pointer_a11y_add_device (ClutterInputDevice *device)
{
if (!is_device_core_pointer (device))
return;
device->accessibility_virtual_device =
clutter_device_manager_create_virtual_device (device->device_manager,
CLUTTER_POINTER_DEVICE);
device->ptr_a11y_data = g_new0 (ClutterPtrA11yData, 1);
}
void
_clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device)
{
if (!is_device_core_pointer (device))
return;
/* Terminate a drag if started */
if (is_dwell_dragging (device))
emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
stop_dwell_position_timeout (device);
stop_dwell_timeout (device);
stop_secondary_click_timeout (device);
g_clear_pointer (&device->ptr_a11y_data, g_free);
}
void
_clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device,
float x,
float y)
{
if (!is_device_core_pointer (device))
return;
if (!_clutter_is_input_pointer_a11y_enabled (device))
return;
update_current_position (device, x, y);
if (is_secondary_click_enabled (device))
{
if (pointer_has_moved (device))
stop_secondary_click_timeout (device);
}
if (is_dwell_click_enabled (device))
{
stop_dwell_position_timeout (device);
if (should_stop_dwell (device))
stop_dwell_timeout (device);
if (should_start_dwell (device))
start_dwell_position_timeout (device);
}
if (should_update_dwell_position (device))
update_dwell_position (device);
}
void
_clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device,
int button,
gboolean pressed)
{
if (!is_device_core_pointer (device))
return;
if (!_clutter_is_input_pointer_a11y_enabled (device))
return;
if (pressed)
{
device->ptr_a11y_data->n_btn_pressed++;
stop_dwell_position_timeout (device);
if (is_dwell_click_enabled (device))
stop_dwell_timeout (device);
if (is_dwell_dragging (device))
stop_dwell_timeout (device);
if (is_secondary_click_enabled (device))
{
if (button == CLUTTER_BUTTON_PRIMARY)
{
if (should_start_secondary_click_timeout (device))
start_secondary_click_timeout (device);
}
else if (is_secondary_click_pending (device))
{
stop_secondary_click_timeout (device);
}
}
}
else
{
if (has_button_pressed (device))
device->ptr_a11y_data->n_btn_pressed--;
if (is_secondary_click_triggered (device))
{
emit_button_click (device, CLUTTER_BUTTON_SECONDARY);
stop_secondary_click_timeout (device);
}
if (is_secondary_click_pending (device))
stop_secondary_click_timeout (device);
if (is_dwell_dragging (device))
emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
}
}
gboolean
_clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device)
{
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
return (is_secondary_click_enabled (device) || is_dwell_click_enabled (device));
}

View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@ -117,6 +117,9 @@ void clutter_disable_accessibility (void);
/* Threading functions */
CLUTTER_EXPORT
void clutter_threads_set_lock_functions (GCallback enter_fn,
GCallback leave_fn);
CLUTTER_EXPORT
guint clutter_threads_add_idle (GSourceFunc func,
gpointer data);
CLUTTER_EXPORT
@ -146,6 +149,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);

View File

@ -12,24 +12,29 @@ 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
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

View File

@ -64,6 +64,9 @@ struct _ClutterMasterClockDefault
/* the current state of the clock, in usecs */
gint64 cur_tick;
/* the previous state of the clock, in usecs, used to compute the delta */
gint64 prev_tick;
#ifdef CLUTTER_ENABLE_DEBUG
gint64 frame_budget;
gint64 remaining_budget;
@ -74,6 +77,12 @@ struct _ClutterMasterClockDefault
*/
GSource *source;
/* If the master clock is idle that means it has
* fallen back to idle polling for timeline
* progressions and it may have been some time since
* the last real stage update.
*/
guint idle : 1;
guint ensure_next_iteration : 1;
guint paused : 1;
@ -266,12 +275,78 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock,
static gint
master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock)
{
gint64 now, next;
gint swap_delay;
if (!master_clock_is_running (master_clock))
return -1;
/* If all of the stages are busy waiting for a swap-buffers to complete
* then we wait for one to be ready.. */
return master_clock_get_swap_wait_time (master_clock);
swap_delay = master_clock_get_swap_wait_time (master_clock);
if (swap_delay != 0)
return swap_delay;
/* When we have sync-to-vblank, we count on swap-buffer requests (or
* swap-buffer-complete events if supported in the backend) to throttle our
* frame rate so no additional delay is needed to start the next frame.
*
* If the master-clock has become idle due to no timeline progression causing
* redraws then we can no longer rely on vblank synchronization because the
* last real stage update/redraw may have happened a long time ago and so we
* fallback to polling for timeline progressions every 1/frame_rate seconds.
*
* (NB: if there aren't even any timelines running then the master clock will
* be completely stopped in master_clock_is_running())
*/
if (clutter_feature_available (CLUTTER_FEATURE_SWAP_THROTTLE) &&
!master_clock->idle)
{
CLUTTER_NOTE (SCHEDULER, "swap throttling available and updated stages");
return 0;
}
if (master_clock->prev_tick == 0)
{
/* If we weren't previously running, then draw the next frame
* immediately
*/
CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately");
return 0;
}
/* Otherwise, wait at least 1/frame_rate seconds since we last
* started a frame
*/
now = g_source_get_time (master_clock->source);
next = master_clock->prev_tick;
/* If time has gone backwards then there's no way of knowing how
long we should wait so let's just dispatch immediately */
if (now <= next)
{
CLUTTER_NOTE (SCHEDULER, "Time has gone backwards");
return 0;
}
next += (1000000L / clutter_get_default_frame_rate ());
if (next <= now)
{
CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs",
1000000L / (gulong) clutter_get_default_frame_rate ());
return 0;
}
else
{
CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs",
(next - now) / 1000);
return (next - now) / 1000;
}
}
static void
@ -455,6 +530,7 @@ clutter_clock_dispatch (GSource *source,
{
ClutterClockSource *clock_source = (ClutterClockSource *) source;
ClutterMasterClockDefault *master_clock = clock_source->master_clock;
gboolean stages_updated = FALSE;
GSList *stages;
CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");
@ -474,6 +550,8 @@ clutter_clock_dispatch (GSource *source,
*/
stages = master_clock_list_ready_stages (master_clock);
master_clock->idle = FALSE;
/* Each frame is split into three separate phases: */
/* 1. process all the events; each stage goes through its events queue
@ -486,12 +564,19 @@ clutter_clock_dispatch (GSource *source,
master_clock_advance_timelines (master_clock);
/* 3. relayout and redraw the stages */
master_clock_update_stages (master_clock, stages);
stages_updated = master_clock_update_stages (master_clock, stages);
/* The master clock goes idle if no stages were updated and falls back
* to polling for timeline progressions... */
if (!stages_updated)
master_clock->idle = TRUE;
master_clock_reschedule_stage_updates (master_clock, stages);
g_slist_free_full (stages, g_object_unref);
master_clock->prev_tick = master_clock->cur_tick;
_clutter_threads_release_lock ();
return TRUE;
@ -523,6 +608,7 @@ clutter_master_clock_default_init (ClutterMasterClockDefault *self)
source = clutter_clock_source_new (self);
self->source = source;
self->idle = FALSE;
self->ensure_next_iteration = FALSE;
self->paused = FALSE;

View File

@ -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));

View File

@ -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))

View File

@ -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)
{

View File

@ -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);

View File

@ -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);
}

View File

@ -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,13 @@ 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;
/* stack of actors with shaders during paint */
GSList *shaders;
/* fb bit masks for col<->id mapping in picking */
gint fb_r_mask;
gint fb_g_mask;
@ -165,6 +173,7 @@ struct _ClutterMainContext
/* boolean flags */
guint is_initialized : 1;
guint motion_events_per_actor : 1;
guint defer_display_setup : 1;
guint options_parsed : 1;
guint show_fps : 1;
@ -181,9 +190,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);
@ -191,6 +198,10 @@ void _clutter_context_lock (void);
void _clutter_context_unlock (void);
gboolean _clutter_context_is_initialized (void);
ClutterPickMode _clutter_context_get_pick_mode (void);
void _clutter_context_push_shader_stack (ClutterActor *actor);
ClutterActor * _clutter_context_pop_shader_stack (ClutterActor *actor);
ClutterActor * _clutter_context_peek_shader_stack (void);
gboolean _clutter_context_get_motion_events_enabled (void);
gboolean _clutter_context_get_show_fps (void);
gboolean _clutter_feature_init (GError **error);
@ -199,7 +210,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 +303,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,

View File

@ -1636,17 +1636,14 @@ clutter_script_translate_parameters (ClutterScript *script,
GObject *object,
const gchar *name,
GList *properties,
GPtrArray **param_names,
GArray **param_values)
GArray **params)
{
ClutterScriptable *scriptable = NULL;
ClutterScriptableIface *iface = NULL;
GList *l, *unparsed;
gboolean parse_custom = FALSE;
*param_names = g_ptr_array_new_with_free_func (g_free);
*param_values = g_array_new (FALSE, FALSE, sizeof (GValue));
g_array_set_clear_func (*param_values, (GDestroyNotify) g_value_unset);
*params = g_array_new (FALSE, FALSE, sizeof (GParameter));
if (CLUTTER_IS_SCRIPTABLE (object))
{
@ -1662,7 +1659,7 @@ clutter_script_translate_parameters (ClutterScript *script,
for (l = properties; l != NULL; l = l->next)
{
PropertyInfo *pinfo = l->data;
GValue value = G_VALUE_INIT;
GParameter param = { NULL };
gboolean res = FALSE;
if (pinfo->is_child || pinfo->is_layout)
@ -1679,12 +1676,12 @@ clutter_script_translate_parameters (ClutterScript *script,
pinfo->name);
if (parse_custom)
res = iface->parse_custom_node (scriptable, script, &value,
res = iface->parse_custom_node (scriptable, script, &param.value,
pinfo->name,
pinfo->node);
if (!res)
res = _clutter_script_parse_node (script, &value,
res = _clutter_script_parse_node (script, &param.value,
pinfo->name,
pinfo->node,
pinfo->pspec);
@ -1696,8 +1693,9 @@ clutter_script_translate_parameters (ClutterScript *script,
continue;
}
g_ptr_array_add (*param_names, g_strdup (pinfo->name));
g_array_append_val (*param_values, value);
param.name = g_strdup (pinfo->name);
g_array_append_val (*params, param);
property_info_free (pinfo);
}
@ -1712,8 +1710,7 @@ clutter_script_construct_parameters (ClutterScript *script,
GType gtype,
const gchar *name,
GList *properties,
GPtrArray **construct_param_names,
GArray **construct_param_values)
GArray **construct_params)
{
GObjectClass *klass;
GList *l, *unparsed;
@ -1721,17 +1718,14 @@ clutter_script_construct_parameters (ClutterScript *script,
klass = g_type_class_ref (gtype);
g_assert (klass != NULL);
*construct_param_names = g_ptr_array_new_with_free_func (g_free);
*construct_param_values = g_array_new (FALSE, FALSE, sizeof (GValue));
g_array_set_clear_func (*construct_param_values,
(GDestroyNotify) g_value_unset);
*construct_params = g_array_new (FALSE, FALSE, sizeof (GParameter));
unparsed = NULL;
for (l = properties; l != NULL; l = l->next)
{
PropertyInfo *pinfo = l->data;
GValue value = G_VALUE_INIT;
GParameter param = { NULL };
GParamSpec *pspec = NULL;
/* we allow custom property names for classes, so if we
@ -1755,7 +1749,9 @@ clutter_script_construct_parameters (ClutterScript *script,
continue;
}
if (!_clutter_script_parse_node (script, &value,
param.name = g_strdup (pinfo->name);
if (!_clutter_script_parse_node (script, &param.value,
pinfo->name,
pinfo->node,
pinfo->pspec))
@ -1764,8 +1760,7 @@ clutter_script_construct_parameters (ClutterScript *script,
continue;
}
g_ptr_array_add (*construct_param_names, g_strdup (pinfo->name));
g_array_append_val (*construct_param_values, value);
g_array_append_val (*construct_params, param);
property_info_free (pinfo);
}
@ -2092,8 +2087,7 @@ _clutter_script_apply_properties (ClutterScript *script,
gboolean set_custom_property = FALSE;
GObject *object = oinfo->object;
GList *properties;
g_autoptr (GPtrArray) param_names = NULL;
g_autoptr (GArray) param_values = NULL;
GArray *params;
guint i;
if (!oinfo->has_unresolved)
@ -2117,31 +2111,34 @@ _clutter_script_apply_properties (ClutterScript *script,
object,
oinfo->id,
properties,
&param_names,
&param_values);
&params);
/* consume all the properties we could translate in this pass */
for (i = 0; i < param_names->len; i++)
for (i = 0; i < params->len; i++)
{
char *name = g_ptr_array_index (param_names, i);
GValue *value = &g_array_index (param_values, GValue, i);
GParameter *param = &g_array_index (params, GParameter, i);
CLUTTER_NOTE (SCRIPT,
"Setting %s property '%s' (type:%s) to object '%s' (id:%s)",
set_custom_property ? "custom" : "regular",
name,
g_type_name (G_VALUE_TYPE (value)),
param->name,
g_type_name (G_VALUE_TYPE (&param->value)),
g_type_name (oinfo->gtype),
oinfo->id);
if (set_custom_property)
iface->set_custom_property (scriptable, script,
name,
value);
param->name,
&param->value);
else
g_object_set_property (object, name, value);
g_object_set_property (object, param->name, &param->value);
g_free ((gchar *) param->name);
g_value_unset (&param->value);
}
g_array_free (params, TRUE);
_clutter_script_check_unresolved (script, oinfo);
}
@ -2149,8 +2146,8 @@ void
_clutter_script_construct_object (ClutterScript *script,
ObjectInfo *oinfo)
{
g_autoptr (GPtrArray) param_names = NULL;
g_autoptr (GArray) param_values = NULL;
GArray *params = NULL;
guint i;
/* we have completely updated the object */
if (oinfo->object != NULL)
@ -2193,14 +2190,25 @@ _clutter_script_construct_object (ClutterScript *script,
oinfo->gtype,
oinfo->id,
properties,
&param_names,
&param_values);
&params);
default_stage = clutter_stage_manager_get_default_stage (manager);
oinfo->object = G_OBJECT (default_stage);
for (i = 0; i < params->len; i++)
{
GParameter *param = &g_array_index (params, GParameter, i);
g_free ((gchar *) param->name);
g_value_unset (&param->value);
}
g_array_free (params, TRUE);
}
else
{
g_autoptr (GPtrArray) param_names = NULL;
GArray *param_values;
GList *properties = oinfo->properties;
/* every other object: first, we get the construction parameters */
@ -2209,11 +2217,22 @@ _clutter_script_construct_object (ClutterScript *script,
oinfo->gtype,
oinfo->id,
properties,
&param_names,
&param_values);
&params);
/* Convert GParameter → (GStrv, GValue[]) */
param_names = g_ptr_array_sized_new (params->len);
param_values = g_array_sized_new (TRUE, FALSE, sizeof (GValue), params->len);
for (i = 0; i < params->len; i++)
{
GParameter *param = &g_array_index (params, GParameter, i);
g_ptr_array_add (param_names, (gchar *) param->name);
g_array_append_val (param_values, param->value);
}
g_ptr_array_add (param_names, NULL);
oinfo->object = g_object_new_with_properties (oinfo->gtype,
param_names->len,
params->len,
(const gchar **) param_names->pdata,
(const GValue *) param_values->data);
@ -2222,6 +2241,17 @@ _clutter_script_construct_object (ClutterScript *script,
* else too or only by this ClutterScript object.
*/
g_object_ref_sink (oinfo->object);
for (i = 0; i < params->len; i++)
{
GParameter *param = &g_array_index (params, GParameter, i);
g_free ((gchar *) param->name);
g_value_unset (&param->value);
}
g_array_free (param_values, FALSE);
g_array_free (params, TRUE);
}
g_assert (oinfo->object != NULL);

View File

@ -263,6 +263,8 @@ enum
static GParamSpec *obj_props[PROP_LAST];
#define CLUTTER_SCRIPT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_SCRIPT, ClutterScriptPrivate))
struct _ClutterScriptPrivate
{
GHashTable *objects;
@ -375,7 +377,7 @@ object_info_free (gpointer data)
static void
clutter_script_finalize (GObject *gobject)
{
ClutterScriptPrivate *priv = CLUTTER_SCRIPT (gobject)->priv;
ClutterScriptPrivate *priv = CLUTTER_SCRIPT_GET_PRIVATE (gobject);
g_object_unref (priv->parser);
g_hash_table_destroy (priv->objects);

View File

@ -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);
}

View File

@ -40,12 +40,8 @@ void _clutter_stage_paint_view (ClutterStage
ClutterStageView *view,
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 +63,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 +74,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 +92,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 +115,9 @@ 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_is_fullscreen (ClutterStage *stage);
gboolean _clutter_stage_update_state (ClutterStage *stage,
ClutterStageState unset_state,
ClutterStageState set_state);

View File

@ -1,37 +0,0 @@
/*
* Copyright (C) 2019 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/>.
*/
#ifndef __CLUTTER_STAGE_VIEW_PRIVATE_H__
#define __CLUTTER_STAGE_VIEW_PRIVATE_H__
#include "clutter/clutter-stage-view.h"
void clutter_stage_view_blit_offscreen (ClutterStageView *view,
const cairo_rectangle_int_t *clip);
gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
void clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
gboolean dirty);
gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
gboolean dirty);
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */

View File

@ -18,7 +18,6 @@
#include "clutter-build-config.h"
#include "clutter/clutter-stage-view.h"
#include "clutter/clutter-stage-view-private.h"
#include <cairo-gobject.h>
#include <math.h>
@ -62,14 +61,6 @@ clutter_stage_view_get_layout (ClutterStageView *view,
*rect = priv->layout;
}
/**
* clutter_stage_view_get_framebuffer:
* @view: a #ClutterStageView
*
* Retrieves the framebuffer of @view to draw to.
*
* Returns: (transfer none): a #CoglFramebuffer
*/
CoglFramebuffer *
clutter_stage_view_get_framebuffer (ClutterStageView *view)
{
@ -82,14 +73,6 @@ clutter_stage_view_get_framebuffer (ClutterStageView *view)
return priv->framebuffer;
}
/**
* clutter_stage_view_get_onscreen:
* @view: a #ClutterStageView
*
* Retrieves the onscreen framebuffer of @view if available.
*
* Returns: (transfer none): a #CoglFramebuffer
*/
CoglFramebuffer *
clutter_stage_view_get_onscreen (ClutterStageView *view)
{

View File

@ -18,10 +18,6 @@
#ifndef __CLUTTER_STAGE_VIEW_H__
#define __CLUTTER_STAGE_VIEW_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <cairo.h>
#include <glib-object.h>
#include <cogl/cogl.h>
@ -61,9 +57,22 @@ void clutter_stage_view_transform_to_onscreen (ClutterStageView *vie
gfloat *x,
gfloat *y);
void clutter_stage_view_blit_offscreen (ClutterStageView *view,
const cairo_rectangle_int_t *clip);
CLUTTER_EXPORT
float clutter_stage_view_get_scale (ClutterStageView *view);
gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
void clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
gboolean dirty);
gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
gboolean dirty);
CLUTTER_EXPORT
void clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view,
CoglMatrix *matrix);

View File

@ -62,6 +62,16 @@ _clutter_stage_window_set_title (ClutterStageWindow *window,
iface->set_title (window, title);
}
void
_clutter_stage_window_set_fullscreen (ClutterStageWindow *window,
gboolean is_fullscreen)
{
ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->set_fullscreen)
iface->set_fullscreen (window, is_fullscreen);
}
void
_clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
gboolean is_visible)
@ -72,6 +82,14 @@ _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
iface->set_cursor_visible (window, is_visible);
}
void
_clutter_stage_window_set_user_resizable (ClutterStageWindow *window,
gboolean is_resizable)
{
CLUTTER_STAGE_WINDOW_GET_IFACE (window)->set_user_resizable (window,
is_resizable);
}
gboolean
_clutter_stage_window_realize (ClutterStageWindow *window)
{
@ -275,6 +293,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)
{

View File

@ -30,8 +30,12 @@ struct _ClutterStageWindowInterface
void (* set_title) (ClutterStageWindow *stage_window,
const gchar *title);
void (* set_fullscreen) (ClutterStageWindow *stage_window,
gboolean is_fullscreen);
void (* set_cursor_visible) (ClutterStageWindow *stage_window,
gboolean cursor_visible);
void (* set_user_resizable) (ClutterStageWindow *stage_window,
gboolean is_resizable);
gboolean (* realize) (ClutterStageWindow *stage_window);
void (* unrealize) (ClutterStageWindow *stage_window);
@ -64,6 +68,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);
@ -75,8 +83,12 @@ ClutterActor * _clutter_stage_window_get_wrapper (ClutterStageWindow *
void _clutter_stage_window_set_title (ClutterStageWindow *window,
const gchar *title);
void _clutter_stage_window_set_fullscreen (ClutterStageWindow *window,
gboolean is_fullscreen);
void _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
gboolean is_visible);
void _clutter_stage_window_set_user_resizable (ClutterStageWindow *window,
gboolean is_resizable);
gboolean _clutter_stage_window_realize (ClutterStageWindow *window);
void _clutter_stage_window_unrealize (ClutterStageWindow *window);
@ -88,7 +100,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 +119,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);

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,6 @@
#include <clutter/clutter-types.h>
#include <clutter/clutter-group.h>
#include <clutter/clutter-stage-view.h>
G_BEGIN_DECLS
@ -62,6 +61,8 @@ struct _ClutterStage
};
/**
* ClutterStageClass:
* @fullscreen: handler for the #ClutterStage::fullscreen signal
* @unfullscreen: handler for the #ClutterStage::unfullscreen signal
* @activate: handler for the #ClutterStage::activate signal
* @deactivate: handler for the #ClutterStage::deactivate signal
* @delete_event: handler for the #ClutterStage::delete-event signal
@ -78,18 +79,17 @@ struct _ClutterStageClass
/*< public >*/
/* signals */
void (* fullscreen) (ClutterStage *stage);
void (* unfullscreen) (ClutterStage *stage);
void (* activate) (ClutterStage *stage);
void (* deactivate) (ClutterStage *stage);
gboolean (* delete_event) (ClutterStage *stage,
ClutterEvent *event);
void (* paint_view) (ClutterStage *stage,
ClutterStageView *view);
/*< private >*/
/* padding for future expansion */
gpointer _padding_dummy[30];
gpointer _padding_dummy[31];
};
/**
@ -168,6 +168,11 @@ CLUTTER_EXPORT
void clutter_stage_get_perspective (ClutterStage *stage,
ClutterPerspective *perspective);
CLUTTER_EXPORT
void clutter_stage_set_fullscreen (ClutterStage *stage,
gboolean fullscreen);
CLUTTER_EXPORT
gboolean clutter_stage_get_fullscreen (ClutterStage *stage);
CLUTTER_EXPORT
void clutter_stage_show_cursor (ClutterStage *stage);
CLUTTER_EXPORT
void clutter_stage_hide_cursor (ClutterStage *stage);
@ -176,6 +181,11 @@ void clutter_stage_set_title (ClutterStage
const gchar *title);
CLUTTER_EXPORT
const gchar * clutter_stage_get_title (ClutterStage *stage);
CLUTTER_EXPORT
void clutter_stage_set_user_resizable (ClutterStage *stage,
gboolean resizable);
CLUTTER_EXPORT
gboolean clutter_stage_get_user_resizable (ClutterStage *stage);
CLUTTER_EXPORT
void clutter_stage_set_minimum_size (ClutterStage *stage,
@ -264,10 +274,6 @@ gboolean clutter_stage_capture (ClutterStage *stage,
cairo_rectangle_int_t *rect,
ClutterCapture **captures,
int *n_captures);
CLUTTER_EXPORT
ClutterStageView * clutter_stage_get_view_at (ClutterStage *stage,
float x,
float y);
G_END_DECLS

View File

@ -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);
}

View File

@ -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;

View File

@ -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); \
\
{ \

View File

@ -171,7 +171,7 @@ clutter_text_buffer_normal_insert_text (ClutterTextBuffer *buffer,
/* Actual text insertion */
at = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text;
memmove (pv->normal_text + at + n_bytes, pv->normal_text + at, pv->normal_text_bytes - at);
g_memmove (pv->normal_text + at + n_bytes, pv->normal_text + at, pv->normal_text_bytes - at);
memcpy (pv->normal_text + at, chars, n_bytes);
/* Book keeping */
@ -201,7 +201,7 @@ clutter_text_buffer_normal_delete_text (ClutterTextBuffer *buffer,
start = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text;
end = g_utf8_offset_to_pointer (pv->normal_text, position + n_chars) - pv->normal_text;
memmove (pv->normal_text + start, pv->normal_text + end, pv->normal_text_bytes + 1 - end);
g_memmove (pv->normal_text + start, pv->normal_text + end, pv->normal_text_bytes + 1 - end);
pv->normal_text_chars -= n_chars;
pv->normal_text_bytes -= (end - start);
@ -228,8 +228,8 @@ clutter_text_buffer_real_inserted_text (ClutterTextBuffer *buffer,
const gchar *chars,
guint n_chars)
{
g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_TEXT]);
g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_LENGTH]);
g_object_notify (G_OBJECT (buffer), "text");
g_object_notify (G_OBJECT (buffer), "length");
}
static void
@ -237,8 +237,8 @@ clutter_text_buffer_real_deleted_text (ClutterTextBuffer *buffer,
guint position,
guint n_chars)
{
g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_TEXT]);
g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_LENGTH]);
g_object_notify (G_OBJECT (buffer), "text");
g_object_notify (G_OBJECT (buffer), "length");
}
/* --------------------------------------------------------------------------------
@ -598,7 +598,7 @@ clutter_text_buffer_set_max_length (ClutterTextBuffer *buffer,
clutter_text_buffer_delete_text (buffer, max_length, -1);
buffer->priv->max_length = max_length;
g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_MAX_LENGTH]);
g_object_notify (G_OBJECT (buffer), "max-length");
}
/**

View File

@ -1975,7 +1975,6 @@ selection_paint (ClutterText *self,
else
{
/* Paint selection background first */
CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline);
PangoLayout *layout = clutter_text_get_layout (self);
CoglPath *selection_path = cogl_path_new ();
CoglColor cogl_color = { 0, };
@ -1988,19 +1987,11 @@ selection_paint (ClutterText *self,
else
color = &priv->text_color;
cogl_color_init_from_4ub (&cogl_color,
color->red,
color->green,
color->blue,
paint_opacity * color->alpha / 255);
cogl_color_premultiply (&cogl_color);
cogl_pipeline_set_color (color_pipeline, &cogl_color);
clutter_text_foreach_selection_rectangle_prescaled (self,
add_selection_rectangle_to_path,
selection_path);
cogl_framebuffer_fill_path (fb, color_pipeline, selection_path);
cogl_path_fill (selection_path);
/* Paint selected text */
cogl_framebuffer_push_path_clip (fb, selection_path);
@ -2260,10 +2251,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 +2309,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 +4331,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 +4404,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 +4423,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 +4442,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);
@ -4820,7 +4812,7 @@ buffer_notify_max_length (ClutterTextBuffer *buffer,
GParamSpec *spec,
ClutterText *self)
{
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MAX_LENGTH]);
g_object_notify (G_OBJECT (self), "max-length");
}
static void
@ -4919,9 +4911,9 @@ clutter_text_set_buffer (ClutterText *self,
obj = G_OBJECT (self);
g_object_freeze_notify (obj);
g_object_notify_by_pspec (obj, obj_props[PROP_BUFFER]);
g_object_notify_by_pspec (obj, obj_props[PROP_TEXT]);
g_object_notify_by_pspec (obj, obj_props[PROP_MAX_LENGTH]);
g_object_notify (obj, "buffer");
g_object_notify (obj, "text");
g_object_notify (obj, "max-length");
g_object_thaw_notify (obj);
}

View File

@ -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);
}

View File

@ -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:

View File

@ -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__ */

View File

@ -101,8 +101,8 @@
#include "clutter-snap-constraint.h"
#include "clutter-stage.h"
#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"

View File

@ -45,9 +45,6 @@
#include "clutter-main.h"
#include "clutter-private.h"
#include "clutter-stage-private.h"
#include "clutter-stage-view-private.h"
#include "cogl/cogl-trace.h"
typedef struct _ClutterStageViewCoglPrivate
{
@ -186,56 +183,38 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
return;
}
refresh_rate = stage_cogl->refresh_rate;
if (refresh_rate <= 0.0)
refresh_rate = clutter_get_default_frame_rate ();
refresh_interval = (gint64) (0.5 + G_USEC_PER_SEC / refresh_rate);
if (refresh_interval == 0)
/* We only extrapolate presentation times for 150ms - this is somewhat
* arbitrary. The reasons it might not be accurate for larger times are
* that the refresh interval might be wrong or the vertical refresh
* might be downclocked if nothing is going on onscreen.
*/
if (stage_cogl->last_presentation_time == 0||
stage_cogl->last_presentation_time < now - 150000)
{
stage_cogl->update_time = now;
return;
}
refresh_rate = stage_cogl->refresh_rate;
if (refresh_rate == 0.0)
refresh_rate = 60.0;
refresh_interval = (gint64) (0.5 + 1000000 / refresh_rate);
if (refresh_interval == 0)
refresh_interval = 16667; /* 1/60th second */
min_render_time_allowed = refresh_interval / 2;
max_render_time_allowed = refresh_interval - 1000 * sync_delay;
/* Be robust in the case of incredibly bogus refresh rate */
if (max_render_time_allowed <= 0)
{
g_warning ("Unsupported monitor refresh rate detected. "
"(Refresh rate: %.3f, refresh interval: %ld)",
refresh_rate,
refresh_interval);
stage_cogl->update_time = now;
return;
}
if (min_render_time_allowed > max_render_time_allowed)
min_render_time_allowed = max_render_time_allowed;
next_presentation_time = stage_cogl->last_presentation_time + refresh_interval;
/* Get next_presentation_time closer to its final value, to reduce
* the number of while iterations below.
*/
if (next_presentation_time < now)
{
int64_t last_virtual_presentation_time = now - now % refresh_interval;
int64_t hardware_clock_phase =
stage_cogl->last_presentation_time % refresh_interval;
next_presentation_time =
last_virtual_presentation_time + hardware_clock_phase;
}
while (next_presentation_time < now + min_render_time_allowed)
next_presentation_time += refresh_interval;
stage_cogl->update_time = next_presentation_time - max_render_time_allowed;
if (stage_cogl->update_time == stage_cogl->last_update_time)
stage_cogl->update_time = stage_cogl->last_update_time + refresh_interval;
}
static gint64
@ -254,7 +233,6 @@ clutter_stage_cogl_clear_update_time (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
stage_cogl->last_update_time = stage_cogl->update_time;
stage_cogl->update_time = -1;
}
@ -927,16 +905,26 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
*/
if (use_clipped_redraw)
{
if (clip_region_empty)
if (use_clipped_redraw && clip_region_empty)
{
do_swap_buffer = FALSE;
}
else
else if (use_clipped_redraw)
{
swap_region = fb_clip_region;
g_assert (swap_region.width > 0);
do_swap_buffer = TRUE;
}
else
{
swap_region = (cairo_rectangle_int_t) {
.x = 0,
.y = 0,
.width = view_rect.width * fb_scale,
.height = view_rect.height * fb_scale,
};
do_swap_buffer = TRUE;
}
}
else
{
@ -946,9 +934,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
if (do_swap_buffer)
{
COGL_TRACE_BEGIN_SCOPED (ClutterStageCoglRedrawViewSwapFramebuffer,
"Paint (swap framebuffer)");
if (clutter_stage_view_get_onscreen (view) !=
clutter_stage_view_get_framebuffer (view))
{
@ -973,8 +958,6 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
gboolean swap_event = FALSE;
GList *l;
COGL_TRACE_BEGIN (ClutterStageCoglRedraw, "Paint (Cogl Redraw)");
for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
{
ClutterStageView *view = l->data;
@ -983,8 +966,6 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
clutter_stage_cogl_redraw_view (stage_window, view) || swap_event;
}
_clutter_stage_emit_after_paint (stage_cogl->wrapper);
_clutter_stage_window_finish_frame (stage_window);
if (swap_event)
@ -1000,8 +981,55 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
stage_cogl->initialized_redraw_clip = FALSE;
stage_cogl->frame_count++;
}
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
@ -1021,6 +1049,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

View File

@ -53,7 +53,6 @@ struct _ClutterStageCogl
gint64 last_presentation_time;
gint64 update_time;
int64_t last_update_time;
/* We only enable clipped redraws after 2 frames, since we've seen
* a lot of drivers can struggle to get going and may output some

View File

@ -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);
}

View File

@ -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);
}

View File

@ -0,0 +1,85 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 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/>.
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_MAIN_DEPRECATED_H__
#define __CLUTTER_MAIN_DEPRECATED_H__
#include <clutter/clutter-types.h>
#include <clutter/clutter-input-device.h>
G_BEGIN_DECLS
CLUTTER_DEPRECATED
void clutter_threads_init (void);
CLUTTER_DEPRECATED
void clutter_threads_enter (void);
CLUTTER_DEPRECATED
void clutter_threads_leave (void);
CLUTTER_DEPRECATED_FOR(clutter_stage_set_motion_events_enabled)
void clutter_set_motion_events_enabled (gboolean enable);
CLUTTER_DEPRECATED_FOR(clutter_stage_get_motion_events_enabled)
gboolean clutter_get_motion_events_enabled (void);
CLUTTER_DEPRECATED_FOR(clutter_stage_ensure_redraw)
void clutter_redraw (ClutterStage *stage);
CLUTTER_DEPRECATED_FOR(cogl_pango_font_map_clear_glyph_cache)
void clutter_clear_glyph_cache (void);
CLUTTER_DEPRECATED_FOR(clutter_backend_set_font_options)
void clutter_set_font_flags (ClutterFontFlags flags);
CLUTTER_DEPRECATED_FOR(clutter_backend_get_font_options)
ClutterFontFlags clutter_get_font_flags (void);
CLUTTER_DEPRECATED_FOR(clutter_device_manager_get_device)
ClutterInputDevice * clutter_get_input_device_for_id (gint id_);
CLUTTER_DEPRECATED_FOR(clutter_input_device_grab)
void clutter_grab_pointer_for_device (ClutterActor *actor,
gint id_);
CLUTTER_DEPRECATED_FOR(clutter_input_device_ungrab)
void clutter_ungrab_pointer_for_device (gint id_);
CLUTTER_DEPRECATED
void clutter_set_default_frame_rate (guint frames_per_sec);
CLUTTER_DEPRECATED
gulong clutter_get_timestamp (void);
CLUTTER_DEPRECATED
gboolean clutter_get_debug_enabled (void);
CLUTTER_DEPRECATED
gboolean clutter_get_show_fps (void);
G_END_DECLS
#endif /* __CLUTTER_MAIN_DEPRECATED_H__ */

View File

@ -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);
/**

View File

@ -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

View File

@ -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"

View 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__ */

View 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__ */

View 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;
}

View 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;
ClutterVirtualInputDevice *mousekeys_virtual_device;
};
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);
G_END_DECLS
#endif /* __CLUTTER_INPUT_DEVICE_EVDEV_H__ */

View File

@ -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)));

View 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__ */

View File

@ -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;
}

View File

@ -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);

View File

@ -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,7 @@ 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);
}
if (state == 0 || /* key release */
@ -333,7 +333,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 +348,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 +372,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 +385,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 +404,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 +427,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 +443,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 +477,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 +560,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 +586,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 +613,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 +632,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 +670,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 +684,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 +708,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 +739,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 +780,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 +799,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 +818,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 +842,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 +857,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 +866,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 +884,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;

View 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__ */

View File

@ -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);

View File

@ -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_EVDEV_H__
#define __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_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_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_X11_H */
#endif /* __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_H__ */

View File

@ -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,

View 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__ */

View File

@ -75,8 +75,8 @@ clutter_headers = [
'clutter-snap-constraint.h',
'clutter-stage.h',
'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',
@ -133,7 +133,6 @@ clutter_sources = [
'clutter-input-device-tool.c',
'clutter-input-focus.c',
'clutter-input-method.c',
'clutter-input-pointer-a11y.c',
'clutter-virtual-input-device.c',
'clutter-interval.c',
'clutter-keyframe-transition.c',
@ -164,9 +163,9 @@ clutter_sources = [
'clutter-snap-constraint.c',
'clutter-stage.c',
'clutter-stage-manager.c',
'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,13 +188,13 @@ 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',
'clutter-id-pool.h',
'clutter-input-focus-private.h',
'clutter-input-method-private.h',
'clutter-input-pointer-a11y-private.h',
'clutter-master-clock.h',
'clutter-master-clock-default.h',
'clutter-offscreen-effect-private.h',
@ -206,13 +205,15 @@ clutter_private_headers = [
'clutter-settings-private.h',
'clutter-stage-manager-private.h',
'clutter-stage-private.h',
'clutter-stage-view-private.h',
'clutter-stage-view.h',
'clutter-stage-window.h',
]
clutter_nonintrospected_sources = [
'clutter-easing.c',
'clutter-event-translator.c',
'clutter-id-pool.c',
'clutter-stage-view.c',
]
clutter_deprecated_headers = [
@ -230,6 +231,7 @@ clutter_deprecated_headers = [
'deprecated/clutter-container.h',
'deprecated/clutter-group.h',
'deprecated/clutter-keysyms.h',
'deprecated/clutter-main.h',
'deprecated/clutter-rectangle.h',
'deprecated/clutter-stage-manager.h',
'deprecated/clutter-stage.h',
@ -269,9 +271,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 +293,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,13 +316,39 @@ 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
clutter_wayland_nonintrospected_sources = [
'wayland/clutter-wayland-surface.c',
]
clutter_backend_nonintrospected_sources += clutter_wayland_nonintrospected_sources
clutter_wayland_private_headers = [
'wayland/clutter-wayland-compositor.h',
'wayland/clutter-wayland-surface.h',
]
clutter_backend_private_headers += clutter_wayland_private_headers
endif
@ -457,12 +504,7 @@ libmutter_clutter_dep = declare_dependency(
)
if have_introspection
clutter_introspection_args = introspection_args + [
'-DCLUTTER_SYSCONFDIR="@0@"'.format(join_paths(prefix, sysconfdir)),
'-DCLUTTER_COMPILATION=1',
'-DCOGL_DISABLE_DEPRECATION_WARNINGS',
'-DG_LOG_DOMAIN="Clutter"'
]
clutter_introspection_args = introspection_args + clutter_c_args
libmutter_clutter_gir = gnome.generate_gir(libmutter_clutter,
sources: [

View File

@ -0,0 +1,654 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2011 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:
* Robert Bragg <robert@linux.intel.com>
*/
/**
* SECTION:clutter-wayland-surface
* @Title: ClutterWaylandSurface
* @short_description: An actor which displays the content of a client surface
*
* #ClutterWaylandSurface is an actor for displaying the contents of a client
* surface. It is intended to support developers implementing Clutter based
* wayland compositors.
*/
#include "clutter-build-config.h"
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-wayland-surface.h"
#include "clutter-actor-private.h"
#include "clutter-marshal.h"
#include "clutter-paint-volume-private.h"
#include "clutter-private.h"
#include "clutter-backend.h"
#include <cogl/cogl.h>
#include <cogl/cogl-wayland-server.h>
enum
{
PROP_SURFACE = 1,
PROP_SURFACE_WIDTH,
PROP_SURFACE_HEIGHT,
PROP_COGL_TEXTURE,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
enum
{
QUEUE_DAMAGE_REDRAW,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
struct _ClutterWaylandSurfacePrivate
{
struct wl_surface *surface;
CoglTexture2D *buffer;
int width, height;
CoglPipeline *pipeline;
};
G_DEFINE_TYPE_WITH_PRIVATE (ClutterWaylandSurface,
clutter_wayland_surface,
CLUTTER_TYPE_ACTOR)
static gboolean
clutter_wayland_surface_get_paint_volume (ClutterActor *self,
ClutterPaintVolume *volume)
{
return clutter_paint_volume_set_from_allocation (volume, self);
}
static void
clutter_wayland_surface_queue_damage_redraw (ClutterWaylandSurface *texture,
gint x,
gint y,
gint width,
gint height)
{
ClutterWaylandSurfacePrivate *priv = texture->priv;
ClutterActor *self = CLUTTER_ACTOR (texture);
ClutterActorBox allocation;
float scale_x;
float scale_y;
cairo_rectangle_int_t clip;
/* NB: clutter_actor_queue_redraw_with_clip expects a box in the actor's
* coordinate space so we need to convert from surface coordinates to
* actor coordinates...
*/
/* Calling clutter_actor_get_allocation_box() is enormously expensive
* if the actor has an out-of-date allocation, since it triggers
* a full redraw. clutter_actor_queue_redraw_with_clip() would redraw
* the whole stage anyways in that case, so just go ahead and do
* it here.
*/
if (!clutter_actor_has_allocation (self))
{
clutter_actor_queue_redraw (self);
return;
}
if (priv->width == 0 || priv->height == 0)
return;
clutter_actor_get_allocation_box (self, &allocation);
scale_x = (allocation.x2 - allocation.x1) / priv->width;
scale_y = (allocation.y2 - allocation.y1) / priv->height;
clip.x = x * scale_x;
clip.y = y * scale_y;
clip.width = width * scale_x;
clip.height = height * scale_y;
clutter_actor_queue_redraw_with_clip (self, &clip);
}
static void
free_pipeline (ClutterWaylandSurface *self)
{
ClutterWaylandSurfacePrivate *priv = self->priv;
if (priv->pipeline)
{
cogl_object_unref (priv->pipeline);
priv->pipeline = NULL;
}
}
static void
opacity_change_cb (ClutterWaylandSurface *self)
{
free_pipeline (self);
}
static void
clutter_wayland_surface_init (ClutterWaylandSurface *self)
{
ClutterWaylandSurfacePrivate *priv;
priv = clutter_wayland_surface_get_instance_private (self);
priv->surface = NULL;
priv->width = 0;
priv->height = 0;
self->priv = priv;
g_signal_connect (self, "notify::opacity", G_CALLBACK (opacity_change_cb), NULL);
}
static void
free_surface_buffers (ClutterWaylandSurface *self)
{
ClutterWaylandSurfacePrivate *priv = self->priv;
if (priv->buffer)
{
cogl_object_unref (priv->buffer);
priv->buffer = NULL;
free_pipeline (self);
}
}
static void
clutter_wayland_surface_dispose (GObject *object)
{
ClutterWaylandSurface *self = CLUTTER_WAYLAND_SURFACE (object);
ClutterWaylandSurfacePrivate *priv = self->priv;
free_pipeline (self);
free_surface_buffers (self);
priv->surface = NULL;
G_OBJECT_CLASS (clutter_wayland_surface_parent_class)->dispose (object);
}
static void
set_size (ClutterWaylandSurface *self,
int width,
int height)
{
ClutterWaylandSurfacePrivate *priv = self->priv;
if (priv->width != width)
{
priv->width = width;
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SURFACE_WIDTH]);
}
if (priv->height != height)
{
priv->height = height;
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SURFACE_HEIGHT]);
}
clutter_actor_set_size (CLUTTER_ACTOR (self), priv->width, priv->height);
}
/**
* clutter_wayland_surface_get_surface:
* @self: a #ClutterWaylandSurface
*
* Retrieves a point to the Wayland surface used by the actor.
*
* Return value: (transfer none): a wl_surface pointer, or %NULL
*
* Since: 1.10
*/
struct wl_surface *
clutter_wayland_surface_get_surface (ClutterWaylandSurface *self)
{
ClutterWaylandSurfacePrivate *priv = self->priv;
return priv->surface;
}
/**
* clutter_wayland_surface_set_surface:
* @self: a #ClutterWaylandSurface
* @surface: a Wayland wl_surface pointer
*
* Sets the Wayland surface to be used by the actor.
*
* Since: 1.10
*/
void
clutter_wayland_surface_set_surface (ClutterWaylandSurface *self,
struct wl_surface *surface)
{
ClutterWaylandSurfacePrivate *priv;
g_return_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self));
priv = self->priv;
if (priv->surface == surface)
return;
if (priv->surface)
{
free_pipeline (self);
free_surface_buffers (self);
g_signal_emit (self, signals[QUEUE_DAMAGE_REDRAW],
0,
0, 0, priv->width, priv->height);
}
priv->surface = surface;
/* XXX: should we freeze/thaw notifications? */
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SURFACE]);
/* We have to wait until the next attach event to find out the surface
* geometry... */
set_size (self, 0, 0);
}
static void
clutter_wayland_surface_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterWaylandSurface *self = CLUTTER_WAYLAND_SURFACE (object);
switch (prop_id)
{
case PROP_SURFACE:
clutter_wayland_surface_set_surface (self, g_value_get_pointer (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
clutter_wayland_surface_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterWaylandSurface *self = CLUTTER_WAYLAND_SURFACE (object);
ClutterWaylandSurfacePrivate *priv = self->priv;
switch (prop_id)
{
case PROP_SURFACE:
g_value_set_pointer (value, priv->surface);
break;
case PROP_SURFACE_WIDTH:
g_value_set_uint (value, priv->width);
break;
case PROP_SURFACE_HEIGHT:
g_value_set_uint (value, priv->height);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
clutter_wayland_surface_paint (ClutterActor *self)
{
ClutterWaylandSurfacePrivate *priv;
CoglFramebuffer *framebuffer;
ClutterActorBox box;
g_return_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self));
priv = CLUTTER_WAYLAND_SURFACE (self)->priv;
framebuffer = cogl_get_draw_framebuffer ();
if (G_UNLIKELY (priv->pipeline == NULL))
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
guint8 paint_opacity = clutter_actor_get_paint_opacity (self);
priv->pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_color4ub (priv->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_pipeline_set_layer_texture (priv->pipeline, 0,
COGL_TEXTURE (priv->buffer));
}
clutter_actor_get_allocation_box (self, &box);
cogl_framebuffer_draw_rectangle (framebuffer,
priv->pipeline,
0, 0,
box.x2 - box.x1, box.y2 - box.y1);
}
static void
clutter_wayland_surface_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
ClutterWaylandSurfacePrivate *priv;
g_return_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self));
priv = CLUTTER_WAYLAND_SURFACE (self)->priv;
if (min_width_p)
*min_width_p = 0;
if (natural_width_p)
*natural_width_p = priv->width;
}
static void
clutter_wayland_surface_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
ClutterWaylandSurfacePrivate *priv;
g_return_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self));
priv = CLUTTER_WAYLAND_SURFACE (self)->priv;
if (min_height_p)
*min_height_p = 0;
if (natural_height_p)
*natural_height_p = priv->height;
}
static gboolean
clutter_wayland_surface_has_overlaps (ClutterActor *self)
{
/* Rectangles never need an offscreen redirect because there are
never any overlapping primitives */
return FALSE;
}
static void
clutter_wayland_surface_class_init (ClutterWaylandSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GParamSpec *pspec;
actor_class->get_paint_volume = clutter_wayland_surface_get_paint_volume;
actor_class->paint = clutter_wayland_surface_paint;
actor_class->get_preferred_width =
clutter_wayland_surface_get_preferred_width;
actor_class->get_preferred_height =
clutter_wayland_surface_get_preferred_height;
actor_class->has_overlaps = clutter_wayland_surface_has_overlaps;
object_class->dispose = clutter_wayland_surface_dispose;
object_class->set_property = clutter_wayland_surface_set_property;
object_class->get_property = clutter_wayland_surface_get_property;
pspec = g_param_spec_pointer ("surface",
P_("Surface"),
P_("The underlying wayland surface"),
CLUTTER_PARAM_READWRITE|
G_PARAM_CONSTRUCT_ONLY);
obj_props[PROP_SURFACE] = pspec;
g_object_class_install_property (object_class, PROP_SURFACE, pspec);
pspec = g_param_spec_uint ("surface-width",
P_("Surface width"),
P_("The width of the underlying wayland surface"),
0, G_MAXUINT,
0,
G_PARAM_READABLE);
obj_props[PROP_SURFACE_WIDTH] = pspec;
g_object_class_install_property (object_class, PROP_SURFACE_WIDTH, pspec);
pspec = g_param_spec_uint ("surface-height",
P_("Surface height"),
P_("The height of the underlying wayland surface"),
0, G_MAXUINT,
0,
G_PARAM_READABLE);
obj_props[PROP_SURFACE_HEIGHT] = pspec;
g_object_class_install_property (object_class, PROP_SURFACE_HEIGHT, pspec);
pspec = g_param_spec_boxed ("cogl-texture",
P_("Cogl Texture"),
P_("The underlying Cogl texture handle used to draw this actor"),
COGL_TYPE_HANDLE,
CLUTTER_PARAM_READWRITE);
obj_props[PROP_COGL_TEXTURE] = pspec;
g_object_class_install_property (object_class, PROP_COGL_TEXTURE, pspec);
/**
* ClutterWaylandSurface::queue-damage-redraw:
* @texture: the object which received the signal
* @x: The top left x position of the damage region
* @y: The top left y position of the damage region
* @width: The width of the damage region
* @height: The height of the damage region
*
* ::queue-damage-redraw is emitted to notify that some sub-region
* of the texture has been changed. This usually means a redraw
* needs to be queued for the actor.
*
* The default handler will queue a clipped redraw in response to
* the damage, using the assumption that the pixmap is being painted
* to a rectangle covering the transformed allocation of the actor.
* If you sub-class and change the paint method so this isn't true
* then you must also provide your own damage signal handler to
* queue a redraw that blocks this default behaviour.
*
* Since: 1.10
*/
signals[QUEUE_DAMAGE_REDRAW] =
g_signal_new (g_intern_static_string ("queue-damage-redraw"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterWaylandSurfaceClass, queue_damage_redraw),
NULL, NULL,
_clutter_marshal_VOID__INT_INT_INT_INT,
G_TYPE_NONE, 4,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT);
klass->queue_damage_redraw = clutter_wayland_surface_queue_damage_redraw;
}
/**
* clutter_wayland_surface_new:
* @surface: the Wayland surface this actor should represent
*
* Creates a new #ClutterWaylandSurface for @surface
*
* Return value: A new #ClutterWaylandSurface representing @surface
*
* Since: 1.8
* Stability: unstable
*/
ClutterActor *
clutter_wayland_surface_new (struct wl_surface *surface)
{
ClutterActor *actor;
actor = g_object_new (CLUTTER_WAYLAND_TYPE_SURFACE,
"surface", surface,
NULL);
return actor;
}
/**
* clutter_wayland_surface_attach_buffer:
* @self: A #ClutterWaylandSurface actor
* @buffer: A compositor side resource representing a wl_buffer
* @error: A #GError
*
* This associates a client's buffer with the #ClutterWaylandSurface
* actor @self. This will automatically result in @self being re-drawn
* with the new buffer contents.
*
* Since: 1.8
* Stability: unstable
*/
gboolean
clutter_wayland_surface_attach_buffer (ClutterWaylandSurface *self,
struct wl_resource *buffer,
GError **error)
{
ClutterWaylandSurfacePrivate *priv;
ClutterBackend *backend = clutter_get_default_backend ();
CoglContext *context = clutter_backend_get_cogl_context (backend);
g_return_val_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self), TRUE);
priv = self->priv;
free_surface_buffers (self);
priv->buffer =
cogl_wayland_texture_2d_new_from_buffer (context, buffer, error);
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_COGL_TEXTURE]);
/* NB: We don't queue a redraw of the actor here because we don't
* know how much of the buffer has changed with respect to the
* previous buffer. We only ever queue a redraw in response to
* surface damage. */
if (!priv->buffer)
return FALSE;
set_size (self,
cogl_texture_get_width (COGL_TEXTURE (priv->buffer)),
cogl_texture_get_height (COGL_TEXTURE (priv->buffer)));
return TRUE;
}
/**
* clutter_wayland_surface_damage_buffer:
* @self: A #ClutterWaylandSurface actor
* @buffer: A wayland resource for a buffer
* @x: The x coordinate of the damaged rectangle
* @y: The y coordinate of the damaged rectangle
* @width: The width of the damaged rectangle
* @height: The height of the damaged rectangle
*
* This marks a region of the given @buffer has having been changed by
* the client. This will automatically result in the corresponding damaged
* region of the actor @self being redrawn.
*
* If multiple regions are changed then this should be called multiple
* times with different damage rectangles.
*
* Since: 1.8
* Stability: unstable
*/
void
clutter_wayland_surface_damage_buffer (ClutterWaylandSurface *self,
struct wl_resource *buffer,
gint32 x,
gint32 y,
gint32 width,
gint32 height)
{
ClutterWaylandSurfacePrivate *priv;
struct wl_shm_buffer *shm_buffer;
g_return_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self));
priv = self->priv;
shm_buffer = wl_shm_buffer_get (buffer);
if (priv->buffer && shm_buffer)
{
CoglPixelFormat format;
switch (wl_shm_buffer_get_format (shm_buffer))
{
#if G_BYTE_ORDER == G_BIG_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888;
break;
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888;
break;
#endif
default:
g_warn_if_reached ();
format = COGL_PIXEL_FORMAT_ARGB_8888;
}
cogl_texture_set_region (COGL_TEXTURE (priv->buffer),
x, y,
x, y,
width, height,
width, height,
format,
wl_shm_buffer_get_stride (shm_buffer),
wl_shm_buffer_get_data (shm_buffer));
}
g_signal_emit (self, signals[QUEUE_DAMAGE_REDRAW],
0,
x, y, width, height);
}
/**
* clutter_wayland_surface_get_cogl_texture:
* @self: a #ClutterWaylandSurface
*
* Retrieves the Cogl texture with the contents of the Wayland surface.
*
* Return value: (transfer none): a Cogl texture, or %NULL
*
* Since: 1.10
*/
CoglTexture *
clutter_wayland_surface_get_cogl_texture (ClutterWaylandSurface *self)
{
g_return_val_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self), NULL);
return COGL_TEXTURE (self->priv->buffer);
}

View File

@ -0,0 +1,117 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2011 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:
* Robert Bragg <robert@linux.intel.com>
*
*/
#ifndef __CLUTTER_WAYLAND_SURFACE_H__
#define __CLUTTER_WAYLAND_SURFACE_H__
#include <glib.h>
#include <glib-object.h>
#include <clutter/clutter.h>
#include <wayland-server.h>
G_BEGIN_DECLS
#define CLUTTER_WAYLAND_TYPE_SURFACE (clutter_wayland_surface_get_type ())
#define CLUTTER_WAYLAND_SURFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_WAYLAND_TYPE_SURFACE, ClutterWaylandSurface))
#define CLUTTER_WAYLAND_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_WAYLAND_TYPE_SURFACE, ClutterWaylandSurfaceClass))
#define CLUTTER_WAYLAND_IS_SURFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_WAYLAND_TYPE_SURFACE))
#define CLUTTER_WAYLAND_IS_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_WAYLAND_TYPE_SURFACE))
#define CLUTTER_WAYLAND_SURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_WAYLAND_TYPE_SURFACE, ClutterWaylandSurfaceClass))
typedef struct _ClutterWaylandSurface ClutterWaylandSurface;
typedef struct _ClutterWaylandSurfaceClass ClutterWaylandSurfaceClass;
typedef struct _ClutterWaylandSurfacePrivate ClutterWaylandSurfacePrivate;
/**
* ClutterWaylandSurface:
*
* The #ClutterWaylandSurface structure contains only private data
*
* Since: 1.10
* Stability: unstable
*/
struct _ClutterWaylandSurface
{
/*< private >*/
ClutterActor parent;
ClutterWaylandSurfacePrivate *priv;
};
/**
* ClutterWaylandSurfaceClass:
* @queue_damage_redraw: class handler of the #ClutterWaylandSurface::queue-damage-redraw signal
*
* The #ClutterWaylandSurfaceClass structure contains only private data
*
* Since: 1.10
* Stability: unstable
*/
struct _ClutterWaylandSurfaceClass
{
/*< private >*/
ClutterActorClass parent_class;
/*< public >*/
void (*queue_damage_redraw) (ClutterWaylandSurface *texture,
gint x,
gint y,
gint width,
gint height);
/*< private >*/
/* padding for future expansion */
gpointer _padding_dummy[8];
};
CLUTTER_EXPORT
GType clutter_wayland_surface_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
ClutterActor *clutter_wayland_surface_new (struct wl_surface *surface);
CLUTTER_EXPORT
void clutter_wayland_surface_set_surface (ClutterWaylandSurface *self,
struct wl_surface *surface);
CLUTTER_EXPORT
struct wl_surface *clutter_wayland_surface_get_surface (ClutterWaylandSurface *self);
CLUTTER_EXPORT
gboolean clutter_wayland_surface_attach_buffer (ClutterWaylandSurface *self,
struct wl_resource *buffer,
GError **error);
CLUTTER_EXPORT
void clutter_wayland_surface_damage_buffer (ClutterWaylandSurface *self,
struct wl_resource *buffer,
gint32 x,
gint32 y,
gint32 width,
gint32 height);
CLUTTER_EXPORT
CoglTexture *clutter_wayland_surface_get_cogl_texture (ClutterWaylandSurface *self);
G_END_DECLS
#endif

View File

@ -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)
@ -86,6 +89,7 @@ static const gchar *atom_names[] = {
"_NET_WM_PID",
"_NET_WM_PING",
"_NET_WM_STATE",
"_NET_WM_STATE_FULLSCREEN",
"_NET_WM_USER_TIME",
"WM_PROTOCOLS",
"WM_DELETE_WINDOW",
@ -98,6 +102,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 +230,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)
@ -351,13 +441,14 @@ clutter_backend_x11_post_parse (ClutterBackend *backend,
backend_x11->atom_NET_WM_PID = atoms[0];
backend_x11->atom_NET_WM_PING = atoms[1];
backend_x11->atom_NET_WM_STATE = atoms[2];
backend_x11->atom_NET_WM_USER_TIME = atoms[3];
backend_x11->atom_WM_PROTOCOLS = atoms[4];
backend_x11->atom_WM_DELETE_WINDOW = atoms[5];
backend_x11->atom_XEMBED = atoms[6];
backend_x11->atom_XEMBED_INFO = atoms[7];
backend_x11->atom_NET_WM_NAME = atoms[8];
backend_x11->atom_UTF8_STRING = atoms[9];
backend_x11->atom_NET_WM_STATE_FULLSCREEN = atoms[3];
backend_x11->atom_NET_WM_USER_TIME = atoms[4];
backend_x11->atom_WM_PROTOCOLS = atoms[5];
backend_x11->atom_WM_DELETE_WINDOW = atoms[6];
backend_x11->atom_XEMBED = atoms[7];
backend_x11->atom_XEMBED_INFO = atoms[8];
backend_x11->atom_NET_WM_NAME = atoms[9];
backend_x11->atom_UTF8_STRING = atoms[10];
g_free (clutter_display_name);
@ -372,6 +463,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[] =
{
{
@ -433,7 +563,8 @@ clutter_backend_x11_dispose (GObject *gobject)
static ClutterFeatureFlags
clutter_backend_x11_get_features (ClutterBackend *backend)
{
ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_CURSOR;
ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_USER_RESIZE
| CLUTTER_FEATURE_STAGE_CURSOR;
flags |= CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class)->get_features (backend);
@ -491,6 +622,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 +658,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 +782,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 +835,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 +846,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 +959,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 +1167,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 +1344,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;
}

View File

@ -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,12 +82,14 @@ struct _ClutterBackendX11
Window xwin_root;
/* event source */
GSource *event_source;
GSList *event_filters;
/* props */
Atom atom_NET_WM_PID;
Atom atom_NET_WM_PING;
Atom atom_NET_WM_STATE;
Atom atom_NET_WM_STATE_FULLSCREEN;
Atom atom_NET_WM_USER_TIME;
Atom atom_WM_PROTOCOLS;
Atom atom_WM_DELETE_WINDOW;
@ -87,9 +101,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 +123,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__ */

View 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__ */

View 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);
}

View File

@ -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);

View 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__ */

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