Compare commits

..

147 Commits

Author SHA1 Message Date
Ray Strode
625ea86672 MetaShapedTexture: save and restore textures on suspend
The proprietary nvidia driver garbles GPU memory on suspend.

In order to workaround that limitation, this commit copies all
textures to host memory on suspend and restores them on resume.

One complication comes from external textures (such as those
given to us by Xwayland for X clients).  We can't just restore
those textures, since they aren't writable.

This commit addresses that complication by keeping a local texture
around for those external textures, and using it instead for parts
of the window that haven't been redrawn since resume.
2019-01-15 11:54:58 -05:00
Ray Strode
395d463c08 background: purge all background textures on suspend
This commit makes sure all background textures get purged
on suspend, which is important for nvidia.
2019-01-15 11:37:54 -05:00
Ray Strode
2fc0652886 backends/native: update cursor on resume
As mentioned in a previous commit, the proprietary NVIDIA
driver garbles memory on suspend. That behavior, means that
the cursor gets corrupted on suspend.

This commit forces the cursor to redraw itself when the
logind session becomes active (on VT switch and resume).
2019-01-15 11:37:54 -05:00
Ray Strode
6ff42c2ab2 backends/native: update glyph cache on resume
As mentioned in a previous commit, the proprietary NVIDIA
driver garbles memory on suspend. That behavior, means that
clutter's glyph cache (which is stored in GPU memory) gets
corrupted on suspend.

This commit ensures the glyph cache is blown away when
the logind session becomes active (on VT switch and resume).
2019-01-15 11:37:53 -05:00
Ray Strode
f9907d1978 backends/native: emit gl-video-memory-purged when becoming active
The proprietary NVIDIA driver garbles memory on suspend.  In order
to work around that limitation, mutter needs to refresh all its
textures on resuem.

This commit lays the way toward doing that by emitting the
"gl-video-memory-purged" signal when the compositor becomes active
by logind (which happens on VT switch and on resume).
2019-01-15 11:37:39 -05:00
Ray Strode
45c5f557bd wayland: force X clients to redraw on resume
On nvidia, the textures backing Xwayland client window contents get
corrupted on suspend.  Xwayland currently doesn't handle this situation
itself.

For now, in order to work around this issue, send an empty output
change event to Xwayland.  This will cause it to force Expose events
to get sent to all clients and get them to redraw.
2019-01-15 11:37:08 -05:00
Ray Strode
53d63ea72b backend: add signals for reporting suspend and resume
This commit adds "suspending" and "resuming" signals
to MetaBackend.

It's preliminary work needed for tracking when to purge
and recreate all textures (needed by nvidia).
2019-01-15 11:35:08 -05:00
Ray Strode
f6e8e867b4 backend: switch to using generated logind proxy
Right now we listen to prepare-for-sleep using
raw gdbus calls.

This commit switches it over to use a generated
proxy, which will become useful in a future commit,
for adding suspending inhibitors.
2019-01-15 11:35:08 -05:00
Ray Strode
a566c6677c cogl: add new UNSTABLE_TEXTURES feature
The proprietary nvidia driver garbles texture memory on suspend.

Before we can address that, we need to be able to detect it.

This commit adds a new UNSTABLE_TEXTURES feature that gets set if
the proprietary nvidia driver is in use.
2019-01-15 11:35:08 -05:00
Ray Strode
cb06e1ef33 fixup! wayland: Don't crash if wl_output resource is destroyed after being removed 2019-01-14 15:44:18 -05:00
Ray Strode
a30c8fb83d Revert "window/wayland: Always update monitor for non-user ops"
This reverts commit e0db7d75c924a07da2b366c9c9e5075dd7bea6e6.
2019-01-14 10:08:04 -05:00
Ray Strode
e3a42dc873 screen-cast-cursor-side-channel.patch 2019-01-14 10:06:59 -05:00
Jonas Ådahl
efd7b8987f renderer/native: Make the EGLStreams operate in mailbox mode
This means eglSwapBuffers() wont dead lock if there is an old buffer pending
page flip. This could happen after e.g. mode changes or for other reasons.
2019-01-14 10:06:58 -05:00
Jonas Ådahl
c96aacabf7 renderer/native: Make EGLStream page flip errors non-fatal
Just continue rendering; we don't care if we were busy once, as it'll most
likely work when we flip the next time.
2019-01-14 10:06:58 -05:00
Ray Strode
af61b66953 shaped-texture-get-image-via-offscreen.patch 2019-01-14 10:06:58 -05:00
Jonas Ådahl
baf11d2471 window: Fix introspection warnings
(transfer none) was added for fundamental types, which can't be
transfered.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/356
(cherry picked from commit 781ec74fd2bb505de7abde6e0641a62ab6ef728a)
2019-01-14 10:06:57 -05:00
Olivier Fourdan
01c763470e window: Expose the client type in the API
We already have the enum exposed, but no accessor function.

Add `meta_window_get_client_type()` which returns the
`MetaWindowClientType` of a window.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/306
(cherry picked from commit 7a5e0c78244b31052edfe3ea4ce1a1f48c94f93f)
2019-01-14 10:06:56 -05:00
Olivier Fourdan
c9065da442 screen-cast-session: Add window-id support
Use the "window-id" property to select the window to cast using
RecordWindow.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/306
(cherry picked from commit c786b6c13cf9cb1bb9d7f7d2ca0ead0bf28a5fcd)
2019-01-14 10:06:56 -05:00
Olivier Fourdan
5f8a4f560f window: Add window id
Generate a unique 64bit window-id which is unrelated to any windowing
backend.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/306
(cherry picked from commit bbcb66ddf4f5eeff379f250b361de0366459b4a3)
2019-01-14 10:06:56 -05:00
Olivier Fourdan
47577432e4 screen-cast-session: Add support for RecordWindow
Add support for the RecordWindow screencast method, casting the
currently focused window.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/306
(cherry picked from commit ec25f3a6b7923627484c6c1c65f8af0bebe56423)
2019-01-14 10:06:56 -05:00
Olivier Fourdan
4ee9462fcd screen-cast-session: Add screen-cast window mode
Window mode will cast the content of a single window using the
`MetaScreenCastWindow` interface.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/306
(cherry picked from commit dbe7279c7fe6fb793292cd6740c900e6f0c21975)
2019-01-14 10:06:55 -05:00
Olivier Fourdan
c275c1de52 window-actor: Implement MetaScreenCastWindow interface
Implements the `MetaScreenCastWindow` interface for screen-cast
`RecordWindow` mode.

`meta_window_actor_capture_into()` implementation is still pretty crude
and doesn't take into account subsurfaces and O-R windows so menus,
popups and other tooltips won't show in the capture.

This is left as a future improvement for now.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/306
(cherry picked from commit 931934511c8e885d5f607ba90187286a0a7ec3a3)
2019-01-14 10:06:55 -05:00
Olivier Fourdan
a9965bb57a screen-cast: Add screen-cast-window interface
Typically, to stream the content of a window, we need a way to copy the
content of its window-actor into a buffer, transform relative input
coordinates to relative position within the window-actor and a mean to
get the window bounds within the buffer.

For this purpose, add a new GType interface `MetaScreenCastWindow` with
the methods needed for screen-cast window mode:

 * meta_screen_cast_window_get_buffer_bounds()
 * meta_screen_cast_window_get_frame_bounds()
 * meta_screen_cast_window_transform_relative_position()
 * meta_screen_cast_window_capture_into()

This interface is meant to be implemented by `MetaWindowActor` which has
access to all the necessary bits to implement them.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/306
(cherry picked from commit 20c9ca25c01a9160d4a2ddfad29b48eb86a9142a)
2019-01-14 10:06:55 -05:00
Olivier Fourdan
9cc2fa2526 screen-cast-src: Add VideoCrop support
To be able to cast windows, which by definition can change in size
dynamically, we need a way to specify the video crop meta to adjust to
the window size whenever it changes.

Add VideoCrop support with a new optional hook `get_videocrop()` in the
`ScreenCastStreamSrcClass` which, if defined, can let the child specify
a rectangle for the video cropping area.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/306
(cherry picked from commit f64eba57ce3fb67a65a5c5755469d4b97067030f)
2019-01-14 10:06:55 -05:00
Olivier Fourdan
f439b0432d remote-desktop: Do not leak the virtual touchscreen
Virtual keyboard and pointer are freed on session close, but the
virtual touchscreen isn't.

Avoid a leak by freeing the virtual touchscreen along with the rest of
virtual devices.
2019-01-14 10:06:54 -05:00
Olivier Fourdan
ab39558506 clutter: Keep a device reference with events
If a device (virtual or real) is removed while there are remaining
events queued for that device, the event loop may try to access the
event freed memory.

To avoid the issue, add a reference to the device when the event is
created or copied, and remove the reference once the device is freed.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/393
2019-01-14 10:06:54 -05:00
Olivier Fourdan
9d72eeeb58 clutter/evdev: Use clutter_event_set_device()
Use the relevant clutter device API `clutter_event_set_device()` instead
of setting the device directly in the event field.
2019-01-14 10:06:54 -05:00
Jonas Ådahl
eea0a2b11d renderer/native: Use shadow fb on software GL if preferred
If a KMS device has the DRM_CAP_DUMB_PREFER_SHADOW and a software based
GL driver is used, always use a shadow fb. This will speed up read backs
in the llvmpipe OpenGL implementation, making blend operations faster.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/106
2019-01-14 10:06:53 -05:00
Jonas Ådahl
bcacaf4562 renderer/native: Also wrap flip closures for EGLStreams
When using the EGLStream backend, the MetaRendererNative passed a
GClosure to KMS when using EGLStreams, but KMS flip callback event
handler in meta-gpu-kms.c expected a closure wrapped in a closure
container, meaning it'd instead crash when using EGLStreams. Make the
flip handler get what it expects also when using EGLStreams by wrapping
the flip closure in the container before handing it over to EGL.

https://bugzilla.gnome.org/show_bug.cgi?id=790316
(cherry picked from commit 8ee14a7cb7e8f072d2731d59c7dc735f83a9bb0b)
2019-01-14 10:06:53 -05:00
Miguel A. Vico
5ae7a67b36 wayland: Create EGLStream-backed buffers through wl_eglstream_controller
One of the current limitations of EGLStreams is that there's no way to
resize a surface consumer without re-creating the entire stream.

Therefore, while resizing, clients will send wl_surface::attach requests
so the compositor can re-create its endpoint of the stream, but no
buffer will be available actually. If we proceed with the rest of the
attach operation we'll be presenting an empty buffer.

In order to fix this, a separate wl_eglstream_controller protocol has
been introduced that clients can use to request a stream re-creation
without overloading wl_surface::attach for that purpose.

This change adds the required logic to create the corresponding
wl_eglstream_controller global interface that clients can bind to.

Whenever a client requests a stream to be created, we just need to
create and realize the new EGLStream buffer. The same buffer resource
will be given at a later time to wl_surface::attach, whenever new
content is made available by the application, so we can proceed to
acquire the stream buffer and update the surface state.

https://bugzilla.gnome.org/show_bug.cgi?id=782575

(cherry picked from commit 435b3c4bdb62edcbb4b400223ddf7e44613efa54)
2019-01-14 10:06:53 -05:00
Miguel A. Vico
7d8ff61069 wayland: Realize dmabuf buffers before trying to attach them
Commit 22723ca37 moved buffer realization to
meta_wayland_surface_commit() so that it wouldn't be part of
meta_wayland_buffer_attach().

However, creation of dmabuf buffers would call into
meta_wayland_buffer_attach() directly without realizing the buffer
first. attach() would then fail and mutter would effectively shut down
any clients using the zwp_linux_dmabuf protocol (note that if such
client was Xwayland, mutter itself would shut down as well).

Add the missing bit in order to make zwp_linux_dmabuf protocol work
again.

(cherry picked from commit 54709c16b56a308d2254c56a35d042bf8b8e124f)
2019-01-14 10:06:53 -05:00
Miguel A. Vico
79b3f56bd3 wayland: Always realize buffers at surface commit time
Clients using EGLStream-backed buffers will expect the stream to be
functional after wl_surface::attach(). That means the compositor-side
stream must be created and a consumer attached to it.

To resolve the above, this change realizes buffers even when the attach
operation is deferred (e.g. synchronized subsurfaces).

https://bugzilla.gnome.org/show_bug.cgi?id=782575

(cherry picked from commit 22723ca37173955d8ef4c6981795e91a85f4feb9)
2019-01-14 10:06:52 -05:00
Miguel A. Vico
e371bacd7f wayland-buffer: Create EGLStream texture at buffer_realize time
When dealing with synchronized subsurfaces, we defer buffer attachments
until the parent surface state is applied.

That causes interaction issues with EGLStream backed buffers, as the
client expects the compositor-side stream to be functional after it
requests a wl_surface::attach.

By allowing the compositor to realize buffers without attaching them, we
could resolve the issue above if we define a realized EGLStream buffer
as a functional EGLStream (EGLStream + attached consumer).

This change moves the texture consumer creation part from the attach
function to the realize one.

https://bugzilla.gnome.org/show_bug.cgi?id=782575

(cherry picked from commit edd3634bb52a8efc687c612152fda5c996e94d26)
2019-01-14 10:06:52 -05:00
Miguel A. Vico
62fd182272 renderer/native: Choose first EGL config for non-GBM backends
Commit 712ec30cd9be1f180c3789e7e6a042c5f7b5781d added the logic to only
choose EGL configs that match the GBM_FORMAT_XRGB8888 pixel format.
However, there won't be any EGL config satisfying such criteria for
non-GBM backends, such as EGLDevice.

This change will let us choose the first EGL config for the EGLDevice
backend, while still forcing GBM_FORMAT_XRGB8888 configs for the GBM
one.

Related to: https://gitlab.gnome.org/GNOME/mutter/issues/2

(cherry picked from commit 1bf2eb95b502ed0419b0fe8979c022cacaf79e84)
2019-01-14 10:06:52 -05:00
Florian Müllner
f48c8c5824 xprops: Make sure text_property_to_utf8() returns UTF8
Commit 840378ae682 changed the code to use XmbTextPropertyToTextList()
instead of gdk_text_property_to_utf8_list_for_display(), but didn't
take into account that the replacement returns text in the current
locale's encoding, while any callers (rightfully) expect UTF8.

Fix this by converting the text if necessary.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/227
2019-01-14 10:06:52 -05:00
Florian Müllner
e3d7b3828e x11/window-props: Do not convert WM_NAME
The WM_NAME property is of type TEXT_PROPERTY, which is supposed to be
returned as UTF-8. Commit 840378ae68 broke that assumption, resulting
in crashes with non-UTF8 locales; however the "fix" of converting from
LATIN1 to UTF8 is wrong as well, as the conversion will spit out garbage
when the input encoding isn't actually LATIN1.

Now that the original issue in text_property_to_utf8() has been fixed,
we can simply revert the relevant bits of commit d62491f46eba748e.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/227
2019-01-14 10:06:51 -05:00
Jonas Ådahl
6e14403ac8 wayland/gtk-shell: Handle requests after toplevel was unmanaged
As with xdg-toplevel, a gtk-surface can be unmanaged by the compositor
without the client knowing about it, meaning the client may still send
updates and make requests. Handle this gracefully by ignoring them. The
client needs to reset all the state anyway, if it wants to remap the
same surface.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit ca5b27baf517f00354ff8811ba204fd90f1ddb38)
2019-01-14 10:06:51 -05:00
Jonas Ådahl
ec2471a356 wayland/legacy-xdg-shell: Handle requests after toplevel was unmanaged
As with xdg-toplevel proper, a legacy xdg-toplevel can be unmanaged by
the compositor without the client knowing about it, meaning the client
may still send updates and make requests. Handle this gracefully by
ignoring them. The client needs to reassign the surface the legacy
xdg-toplevel role again, if it wants to remap the same surface, meaning
all state would be reset anyway.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit 64df6276881c5f42c6d2054d556d8cd391f7ee70)
2019-01-14 10:06:51 -05:00
Jonas Ådahl
30820ab19e wayland/legacy-xdg-shell: Cache frame callbacks if toplevel is unmanaged
A toplevel window can be unmanaged without the client knowing it (e.g. a
modal dialog being unmapped together with its parent. When this has
happened, take frame callbacks queued on a commit and cache them on the
generic surface queue. If the toplevel is to be remapped because the
surface was reassigned the toplevel role, the cached frame callbacks
will be queued on the surface actor and dispatched accordingly.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit a740f50cd7d05582a251c23a7025999e55e4aba1)
2019-01-14 10:06:51 -05:00
Jonas Ådahl
58cc091134 wayland/xdg-shell: Handle requests after toplevel was unmanaged
A window can be unmanaged without asking the client to do it, for
example as a side effect of a parent window being unmanaged, if the
child window was a attached dialog.

This means that the client might still make requests post updates to it
after that it was unmapped. Handle this gracefully by NULL-checking the
surface's MetaWindow pointer. We're not loosing any state due to this,
as if the client wants to map the same surface again, it needs to either
reassign it the toplevel role, or reset the xdg-toplevel, both resulting
in all state being lost anyway.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit 5fd0f62a62a194ffd8e64d177f389912a582f8e1)
2019-01-14 10:06:50 -05:00
Jonas Ådahl
0105dca586 wayland/xdg-shell: Cache frame callbacks if toplevel is unmanaged
A toplevel window can be unmanaged without the client knowing it (e.g. a
modal dialog being unmapped together with its parent. When this has
happened, take frame callbacks queued on a commit and cache them on the
generic surface queue. If the toplevel is to be remapped, either because
the surface was reassigned the toplevel role, or if it was reset and
remapped, the cached frame callbacks will be queued on the surface actor
and dispatched accordingly.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit 80d420ff430e8e9495fd29d68084cb050600b26f)
2019-01-14 10:06:50 -05:00
Jonas Ådahl
17dd4d32da wayland/xdg-shell: Cache pending frame callbacks on popup reset
A popup can be reset, and when that happens, window and actor are
destroyed, and won't be created again unless it is reassigned the
popup role.

If a client queued frame callbacks when resetting a popup, the frame
callbacks would be left in the pending state, as they were not queued on
the actor, meaning we'd hit an assert about the frame callbacks not
being handled. Fix this by caching them on the MetaWaylandSurface, so
that they either are cleaned up on destruction, or queued on the actor
would the surface be re-assigned the popup role.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit 407d62943c1c0bbb34df5943b6b2d91c5723b6c4)
2019-01-14 10:06:50 -05:00
Jonas Ådahl
5b95f809ca wayland/surface: Add API to cache frame callbacks
Sometimes it may be useful for roles to put callbacks in the generic
surface frame callback queue. The surface frame callback queue will
either eventually be processed on the next surface role assignment that
places the frame callbacks in a role specific queue, processed at some
other point in time by a role, or cleaned up on surface destruction.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit 0ace58d05f3e50f4fdcf4971baab163e6ae5a1e9)
2019-01-14 10:06:49 -05:00
Jonas Ådahl
3934793255 wayland/xdg-shell: Queue frame callbacks on new actor after resetting
When a xdg-toplevel is reset, the window and actor are recreated, and
all state is cleared. When this happened, we earlied out from the
xdg-toplevel commit handler, which would mean that if the client had
queued frame callbacks when resetting, they'd be left in the pending
commit state, later hitting an assert as they were not handled.

Fix this by queuing the frame callbacks no the new actor, so that they
are emitted whenever the actor is eventually painted.

https://gitlab.gnome.org/GNOME/mutter/issues/240
(cherry picked from commit d791710197205028be40750d6ee4119f2b7f0e26)
2019-01-14 10:06:49 -05:00
Olivier Fourdan
f3655737bc window: unmanage dialog when clearing transient_for
On Wayland, xdg-foreign would leave a modal dialog managed even after
the imported surface is destroyed.

This is sub-optimal and this breaks the atomic relationship one would
expect between the parent and its modal dialog.

Make sure we unmanage the dialog if transient_for is unset even for
Wayland native windows.

Related: https://gitlab.gnome.org/GNOME/mutter/issues/174
Related: https://gitlab.gnome.org/GNOME/mutter/issues/221

(cherry picked from commit b443bd42ac738092817addf48e0b363d140cad26)
2019-01-14 10:06:49 -05:00
Florian Müllner
728ed4fe38 idle-monitor: Don't try to auto-start SessionManager
The interface is provided by gnome-session and not activatable.

https://gitlab.gnome.org/GNOME/mutter/issues/134

(cherry picked from commit 2319cd9c4014fcc0c2487d7c02e67857f940687e)
2019-01-14 10:06:49 -05:00
Sebastian Keller
bcba6571f0 backends/x11: Only free cursor if it was created successfully
XcursorLibraryLoadCursor can return 'None' if the current cursor theme
is missing the requested icon. If XFreeCursor is then called on this
cursor, it generates a BadCursor error causing gnome-shell to crash.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/254

(cherry picked from commit 1bfa20929b36d06cc23667d1122175149615b56d)
2019-01-14 10:06:48 -05:00
Sam Spilsbury
4525a74e59 window: Return -1 if meta_window_get_monitor is called on an unmanaged window
As opposed to crashing. In this case, letting the caller deal with
it is the best policy, since this is public API.

https://bugzilla.gnome.org/show_bug.cgi?id=788834

(cherry picked from commit 8626c69c2ffa806f854041a3738340c6fb20c112)
2019-01-14 10:06:48 -05:00
Jonas Ådahl
0dd58540b2 wayland/keyboard: Create a separate keymap shm file per resource
By using the shm file when sending the keymap to all clients, we
effectively allows any client to change the keymap, as any client has
the ability to change the content of the file. Sending a read-only file
descriptor, or making the file itself read-only before unlinking, can
be worked around by the client by using chmod(2) and open(2) on
/proc/<pid>/<fd>.

Using memfd could potentially solve this issue, but as the usage of
mmap with MAP_SHARED is wide spread among clients, such a change can
not be introduced without causing wide spread compatibility issues.

So, to avoid allowing clients to interfere with each other, create a
separate shm file for each wl_keyboard resource when sending the
keymap. We could eventually do this per client, but in most cases,
there will only be one wl_keyboard resource per client anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=784206
2019-01-14 10:06:48 -05:00
Alex Villacís Lasso
ac27fca3ef renderer/native: Fallback to non-planar API if gbm_bo_get_handle_for_plane fails
Commit c0d9b08ef9bf2be865aad9bf1bc74ba24c655d9f replaced the old GBM API calls
with the multi-plane GBM API. However, the call to gbm_bo_get_handle_for_plane
fails for some DRI drivers (in particular i915). Due to missing error checks,
the subsequent call to drmModeAddFB[2] fails and the screen output locks up.

This commit adds the missing error checks and falls back to the old GBM API
(non-planar) if necessary.

v5: test success of gbm_bo_get_handle_for_plane instead of errno

This commit adopts solution proposed by Daniel van Vugt to check the return
value of gbm_bo_get_handle_for_plane on plane 0 and fall back to old
non-planar method if the call fails. This removes the errno check (for
ENOSYS) that could abort if mesa ever sets a different value.

Related to: https://gitlab.gnome.org/GNOME/mutter/issues/127

(cherry picked from commit f7af32a3eaefabbea3ebbda3a93eff98dd105ab9)
2019-01-14 10:06:48 -05:00
Iain Lane
99bbe001f5 monitor-manager-kms: Check if GPUs can have outputs
We need a way for mutter to exit if no available GPUs are going to work.
For example if gdm starts gnome-shell and we're using a DRM driver that
doesn't work with KMS then we should exit so that GDM can try with Xorg,
rather than operating in headless mode.

Related: https://gitlab.gnome.org/GNOME/mutter/issues/223

(cherry picked from commit deb541ef5ac2cc07d0259c259bff8d1523388d47)
2019-01-14 10:06:47 -05:00
Iain Lane
30c09c84c4 gpu-kms: Handle drmModeGetResources() failing
Avoid dereferencing the NULL return value if it fails. We still create
the MetaGpu, but we treat it as if it has no outputs.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/223

(cherry picked from commit 29cc526e2eab65d856d1fd0a652f22dcdb5d72dd)
2019-01-14 10:06:47 -05:00
Aaron Plattner
81c63df853 gpu-kms: Don't crash if drmModeGetResources returns NULL
DRM drivers can be opened by meta_launcher_open_restricted() even if they don't
implement modesetting. However, drmModeGetResources() will return NULL.

Check whether that happened in meta_gpu_kms_new() and return with an error
instead of crashing.

Fixes #223.
2019-01-14 10:06:47 -05:00
Jonas Ådahl
3104abba57 monitor: Use current monitor mode to check whether active
For historical reasons meta_monitor_is_active() checked whether it is
active by checking whether the main output have a CRTC assigned and
whether that CRTC has a current mode. At a later point, the MetaMonitor
got its own mode abstraction (MetaMonitorMode), but
meta_monitor_is_active() was never updated to use this.

An issue with checking the main output's CRTC state is that, if there is
some CRTC mode combination that for some reason isn't properly detected
by the MetaMonitorMode abstraction (e.g. some tiling configuration not
yet handled), meta_monitor_is_active() would return TRUE, even though no
(abstracted) mode was set. This would cause confusion here and there,
leading to NULL pointer dereferences due to the assumption that if a
monitor is active, it has an active mode.

Instead, change meta_monitor_is_active() to directly check the current
monitor mode, and log a warning if the main output still happen to have
a CRTC with a mode assigned to it. This way, when an not undrestood CRTC
mode combination is encountered, instead of dereferencing NULL pointers,
simply assume the monitor is not active, which means that it will not be
managed or rendered by mutter at all.

https://gitlab.gnome.org/GNOME/mutter/issues/130

(cherry picked from commit 4d465eac0806eb1ead375e2852d4a9d6bc24524f)
2019-01-14 10:06:47 -05:00
Florian Müllner
13eb4f51c7 tests: Add "closed-transient" test
When a transient window is destroyed, the expected behavior is that
focus is passed to the ancestor if possible. This was broken for
quite a while until the previous commit, so add a test case to make
sure it doesn't happen again.

https://gitlab.gnome.org/GNOME/mutter/issues/15

(cherry-picked from commit 137f22236cba5f2583d8db3d957e3926d1f7f668)
2019-01-14 10:06:46 -05:00
Florian Müllner
7969c473ac window: Explicitly exclude unmanaging window from focus again
Since commit b3b9d9e16 we no longer have to pass the unmanaging window
to make sure we don't try to focus it again, however the parameter also
influences the focus policy by giving ancestors preference over the normal
stack order.

https://gitlab.gnome.org/GNOME/mutter/issues/15

(cherry picked from commit d99442d6e6b7c9b383863cc754db609398d4e65b)
2019-01-14 10:06:46 -05:00
Florian Müllner
a83e72d7c1 window: Don't refuse to move focus to the grab window
We refuse to move focus while a grab operation is in place. While this
generally makes sense, there's no reason why the window that owns the
grab shouldn't be given the regular input focus as well - we pretty
much assume that the grab window is also the focus window anyway.

In fact there's a strong reason for allowing the focus change here:
If the grab window isn't the focus window, it probably has a modal
transient that is focused instead, and a likely reason for the focus
request is that the transient is being unmanaged and we must move
the focus elsewhere.

https://gitlab.gnome.org/GNOME/mutter/issues/15

(cherry picked from commit 148da24f9510ebd23d750b8224aa0ab3a549e69e)
2019-01-14 10:06:46 -05:00
Jonas Ådahl
910c4e9fe7 native/gpu: Handle drmModeSetCrtc() failing gracefully
If drmModeSetCrtc() is called with no fb, mode or connectors for some
CRTC it may still fail, and we should handle that gracefully instead of
assuming it failed to set a non-disabled state.

Closes https://gitlab.gnome.org/GNOME/mutter/issues/70

(cherry picked from commit 6e953e2725d5d5b10d14c7bd479bd99f6853addc)
2019-01-14 10:06:45 -05:00
Olivier Fourdan
2fb5b65e94 wayland: Clean up xwayland grabs even if surface is gone
If the surface is gone before `meta_xwayland_keyboard_grab_end()` is
called, we would bail out early leaving an empty grab, which will cause
a segfault as soon as a key is pressed later on.

Make sure we clean up the keyboard grab even if the surface is gone.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/255
(cherry picked from commit 252dd524390dcdbdd89534c0014d22a796957f55)
2019-01-14 10:06:45 -05:00
Olivier Fourdan
e00d6c6273 wayland: No xdg-output events without a logical monitor
To avoid a known race condition in the wl_output protocol documented in
https://phabricator.freedesktop.org/T7722, mutter delays the `wl_output`
destruction but nullify the `logical_monitor` associated with the
`wl_output` and the binding routine `bind_output()` makes sure not to
send wl_output events if the `logical_monitor` is `NULL` (see commit
1923db97).

The binding routine for `xdg_output` however does not check for such a
condition, hence if the output configuration changes while a client is
binding to xdg-output (typically Xwayland at startup), mutter would
crash while trying to access the `logical_monitor` which was nullified
by the change in configuration.

Just like `bind_output()` does for wl_output, do not send xdg-output
events if there is no `logical_monitor` yet.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/194

(cherry picked from commit 68ec9ac017157def9b7c25dd8141dc0e93d9f918)
2019-01-14 10:06:45 -05:00
Olivier Fourdan
733ab3b2bc wayland: Nullify monitor resources when updating outputs
If a client asks for xdg-output before we have set the output's logical
monitor, we would end up crashing with a NULL pointer dereference.

Make sure we clear the resource's user data when marking an output as
inert on monitor change so that we don't end up with a Wayland output
without a logical monitor.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/194

(cherry picked from commit 48eaa36d41bb88d4831e40e9c3ef3c7afda195bc)
2019-01-14 10:06:45 -05:00
Jonas Ådahl
a208d7c33e window/wayland: Don't recursive indefinitely when updating monitor
When we update the main monitor, there is a rule that makes it so that
popup windows use the same main monitor as their parent. In the commit
f4d07caa38e51d09ee73bab20334a6b5c28952d6 the call that updates and
fetches the main monitor of the toplevel accidentally changed to update
from itself, causing a indefinite recursion eventually resulting in a
crash.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/279
(cherry picked from commit e191c21e04cfaa560f8dd51f4f91013af98ccf4e)
2019-01-14 10:06:44 -05:00
Ray Strode
37bbea649b 0002-window-Force-update-monitor-on-hot-plugs.patch 2019-01-14 10:06:44 -05:00
Ray Strode
4035955fc0 0001-window-Pass-flag-to-meta_window_update_monitor-inste.patch 2019-01-14 10:06:44 -05:00
Olivier Fourdan
a8db59908f window/wayland: Always update monitor for non-user ops
meta_window_wayland_update_main_monitor() would skip the monitor update
if the difference in scale between the old and the new monitor would
cause another monitor change.

While this is suitable when the monitor change results from a user
interactively moving the surface between monitors of different scales,
this can leave dangling pointers to freed monitors when this is
triggered by a change of monitor configuration.

Make sure we update the monitor unconditionally if not from a user
operation.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/189

(cherry picked from commit a3da4b8d5bd217c0262fd9361036877d155a300f)
2019-01-14 10:06:43 -05:00
Olivier Fourdan
a477c73a97 window/wayland: Always update monitor for non-user ops
meta_window_wayland_update_main_monitor() would skip the monitor update
if the difference in scale between the old and the new monitor would
cause another monitor change.

While this is suitable when the monitor change results from a user
interactively moving the surface between monitors of different scales,
this can leave dangling pointers to freed monitors when this is
triggered by a change of monitor configuration.

Make sure we update the monitor unconditionally if not from a user
operation.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/189

(cherry picked from commit a3da4b8d5bd217c0262fd9361036877d155a300f)
2019-01-14 10:06:43 -05:00
Olivier Fourdan
ae228c0556 wayland: Allow Xwayland grabs on selected apps
Allow Xwayland grabs on a selected set of X11 applications.
2019-01-14 10:06:43 -05:00
Jonas Ådahl
978cb5b21c Add remote access controller API
Add API to let GNOME Shell have the ability to get notified about remote
access sessions (remote desktop, remote control and screen cast), and
with a way to close them.

This is done by adding an abstraction above the remote desktop and
screen cast session objects, to avoid exposing their objects to outside
of mutter. Doing that would result in external parts holding references
to the objects, complicating their lifetimes. By using separate wrapper
objects, we avoid this issue all together.
2019-01-14 10:06:43 -05:00
Jonas Ådahl
e792eca2f5 Make screen cast and remote desktop non-experimental
It's time to make this feature more accessible by not requiring editing
an array in gsettings.
2019-01-14 10:06:42 -05:00
Jonas Ådahl
b9614f0797 virtual-input/evdev: Translate from button codes internal to evdev
Sending button events to a ClutterVirtualInputDevice, the API expects
button codes to be of the internal clutter type. The evdev
implementation incorrectly assumed it was already prepared evdev event
codes, which was not the case. Fix the evdev implementation to translate
from the internal representation to evdev before passing it along to
ClutterSeatEvdev.
2019-01-14 10:06:42 -05:00
Ray Strode
6d7bbeddd7 mutter-pipewire-0_2-API.patch 2019-01-14 10:06:42 -05:00
Ray Strode
68570353fd mutter-search-for-libpipewire-0_2.patch 2019-01-14 10:06:42 -05:00
Jonas Ådahl
566cdcc94b renderer/native: Check calculated transform when creating view
The "backends: Move MetaOutput::crtc field into private struct"
accidentally changed the view transform calculation code to assume that
"MetaCrtc::transform" corresponds to the transform of the CRTC; so is
not the case yet; one must calculate the transform from the logical
monitor, and check whether it is supported by the CRTC using
meta_monitor_manager_is_transform_handled(). This commit restores the
old behaviour that doesn't use MetaCrtc::transform when calculating the
view transform.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/216
2019-01-14 10:04:23 -05:00
Ray Strode
37dc2e5b1b hw-cursor-on-demand-gnome-3-28.patch 2019-01-14 10:04:23 -05:00
Florian Müllner
66b9150771 gtk-shell: Work around non-working startup notifications
GNOME Shell relies on the MetaScreen::startup-sequence-changed signal,
which is tied to (lib)startup-notification and therefore X11. As a result,
when we remove the startup sequence of a wayland client, GNOME Shell will
not be notified about this until startup-notification's timeout is hit.
As a temporary stop-gap, go through XWayland even for wayland clients,
so that the signal is emitted when expected.

https://bugzilla.gnome.org/show_bug.cgi?id=768531
2019-01-14 10:04:01 -05:00
Florian Müllner
34f5bdeea3 Bump version to 3.28.3
Update NEWS.
2018-07-18 23:12:51 +02:00
Jonas Ådahl
ca71b0eb1a monitor-manager: Add back warning messages
For some reason "backends: Remove X11 idle-monitor backend" removed
unrelated warning messages for when generated monitor configurations
that should work didn't, which also made the unit tests fail.

This commit adds them back, which also makes the tests pass again.


(cherry picked from commit d9c18fd5bbd6b06453bb06a64eb8b31866d2f963)
2018-07-18 20:21:12 +00:00
Jonas Ådahl
ca4209d88a screen-cast-src: Allow negotiating the framerate
The framerate for screen cast sources was set to variable within 1 FPS
and the framerate of the monitor being screen casted. This meant that if
the sink didn't match the framerate (e.g. had a lower max framerate),
the formats would not match and a stream would not be established.

Allow letting the sink clamp the framerate range by setting it as
'unset', allowing it to be negotiated.
2018-07-13 14:39:43 +02:00
Olivier Fourdan
3288edf677 contraints: Do not constrain modals without parent
xdg-foreign clears the `transient_for` of a modal dialog when its
imported parent is destroyed, which would later cause a crash in
`constrain_modal_dialog()` because the transient `NULL`.

So in case a modal dialog has no parent, do not try to constrain it
against its parent.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/174
(cherry picked from commit 912a6f5e3f86040b75c18ce2e2c26ffd9a7925ee)
2018-07-10 17:03:20 +02:00
Jonas Ådahl
fe1616668e backends: Add logical monitor -> monitor -> output -> crtc ref chain
Make it so that each logical monitor has a reference to all the
monitors that are assigned to it.

All monitors has a reference to each output that belongs to it.

Each output has a reference to any CRTC it has been assigned.

https://bugzilla.gnome.org/show_bug.cgi?id=786929


(cherry picked from commit 768ec15ea072df21dd6caeb2507d41223ade9116)
2018-06-28 11:52:10 +00:00
Jonas Ådahl
7d01aec48d backends: Move MetaOutput::crtc field into private struct
No functional changes. This is only done so that changes to reference
counting can done more reliably.

https://bugzilla.gnome.org/show_bug.cgi?id=786929


(cherry picked from commit 1200182d706d5144df49a221b26225c729c2a60b)
2018-06-28 11:50:37 +00:00
Marco Trevisan (Treviño)
a41d84db00 renderer-native: Don't crash if the FB surface can't be locked
(cherry picked from commit 0332b7394e56f71c15692663ab05f8c84a4b9eff)
2018-05-29 22:14:31 +00:00
Marco Trevisan (Treviño)
e73b321c2e device-manager-evdev: Add main seat to seats by default
Treat the main seat as other seats, so we don't have to handle it differently
in specific places. This was already the case before when a real device
was plugged before the startup, but not applied when hotplugging a device.


(cherry picked from commit 15f41c9f68abfbb5408205a45f9f578e2ff5ee86)
2018-05-29 10:48:56 +00:00
Marco Trevisan (Treviño)
b6dc2052c3 device-manager-evdev: Free the main seat on finalize
(cherry picked from commit 2a38601b4211f9b1dedd45261a040e51de13b838)
2018-05-29 10:47:20 +00:00
Marco Trevisan (Treviño)
72965aaaf0 device-manager-evdev: Set and unset the stage for the main seat too
When no input devices are available on startup the device manager might be fast
enough to be constructed so that no default stage is set yet, and thus when
main seat virtual devices are created they won't have a proper stage set.
If then we plug a real device, the events that an input manager could generate
won't be associated to any stage and thus won't be processed.

We need then ensure that when we update the stage for the device manager we
(un)associate it also to the main seat devices.


(cherry picked from commit d7bdc1591fba5353b23a28ebf676da0e7b58c84e)
2018-05-29 10:46:03 +00:00
Marco Trevisan (Treviño)
2a6782dc10 clutter-device-evdev: Get devices from main seat if no real seat is set
In devices such as ARM boards there could be no input devices connected on
startup, leading to a crash when we try to process artificial events that
could be queued (as gnome-shell does when syncing pointer).

Those events still should refer to a device and, in case we don't have one
provided by libinput we should still return the core devices defined in the
main seat.


(cherry picked from commit 3e85ac8131fc76312a2382d83df6926b88a37415)
2018-05-29 10:43:41 +00:00
Marco Trevisan (Treviño)
5142c8c7e7 clutter-seat-evdev: Add function to get device by id
(cherry picked from commit 5f83d9a5c854873746a31d0cc4d118c9a6d87ddd)
2018-05-29 10:43:17 +00:00
Changwoo Ryu
abc7ad8e9f wayland: Don't reset input focus on text commit
Preedit text can be active even after text commit. Resetting the input
focus will lead to unintended commit of the preedit text.

https://gitlab.gnome.org/GNOME/mutter/issues/152

Closes: #152
2018-05-26 15:26:09 +02:00
Olivier Fourdan
1a3f9a3323 frames: Allow for unknown mouse buttons
Commit 47131b1d ("frames: Handle touch events") introduced an assert to
make sure that all mouse button actions are handled in mutter.

However, mice can have a more than 5 buttons, so simply ignore the
"other" actions instead of aborting.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/160
(cherry picked from commit 473bf38753221dc0002fae309d2f3f217e96c5f5)
2018-05-25 11:35:45 +02:00
Olivier Fourdan
235c35182b wayland: update enter/leave output after effects
Compositor effects change the actor size and position, which can lead to
inconsistent output enter/leave notifications, leaving clients' surfaces
without any output set.

Update output enter/leave notifications after all compositor effects are
completed so that we give clients accurate output location.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/104
(cherry picked from commit 17a745bf81c24dae9c081e93ae1593e2bb81efd6)
2018-05-22 13:01:13 +02:00
Olivier Fourdan
e4661d7870 window-actor: add new signal "effects-completed"
When using plugins, the effects will affect the MetaWindowActor size
and position.

Add a new signal "effects-completed" wired to the corresponding
MetaWindowActor which is emitted when all effects are completed so that
derived objects can be notified when all effects are completed and use
the actual size and position.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/104
(cherry picked from commit 85bbd82ae847eed0bba943c119a356d9493f7da2)
2018-05-22 13:01:05 +02:00
Georges Basile Stavracas Neto
9d4c7e4e75 wayland: Compare geometries after chaining up
After 20176d03, the Wayland backend only synchronizes with the
compositor after a geometry was set, and it was different from
the current geometry.

That commit was mistakenly comparing the geometry before chaining
up, which would yield a false negative on the case where the
client didn't call set_geometry() before commit().

Fix that by caching the old geometry locally, chain up (and thus
apply the new geometry rectangle), then comparing the old and
current geometry rectangles.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/150


(cherry picked from commit cf734999fb9e342811896f70f7c1f415462728a7)
2018-05-18 13:53:20 +00:00
Carlos Garnacho
47131b1dad frames: Handle touch events
This is just done on wayland as it'll break horribly on X11, we let
this happen through pointer emulated events in XISelectEvents evmask
instead.

Some things had to be made slightly more generic to accomodate touch
events. The MetaFrames shall lock onto a single touch at a time, we
don't allow crazy stuff like multi-window drag nor multi-edge resizes.

https://bugzilla.gnome.org/show_bug.cgi?id=770185
2018-05-15 16:07:07 +01:00
Carlos Garnacho
51c0130645 frames: Make 1st button/motion handlers take generic events
This will ease handling of touch events through these same handlers.

https://bugzilla.gnome.org/show_bug.cgi?id=770185
2018-05-15 16:06:59 +01:00
Olivier Fourdan
2dd9fc17c1 clutter/evdev: Don't ignore CAPS lock as modifier
Mark CAPS lock as a modifier (as it should) so that when using XKB
options to change the default behaviour of CAPS lock, the new assigned
key can by used as a sticky key as well.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/112
(cherry picked from commit 6df2b7af556bf01f8d564b86c66c293678ab6b90)
2018-05-15 10:26:29 +02:00
Olivier Fourdan
c7a38c3139 clutter/evdev: ignore injected events from IM
Input method can inject key events, which leads to multiple reported key
press/release events for a single user action.

Ignore those events as this confuses keyboard accessibility.

(cherry picked from commit c01b099dbdfee4b2a98864bc76bfa1b96a55c8fb)
2018-05-15 10:25:51 +02:00
Olivier Fourdan
7d52be0229 wayland: Use cursor position in logical monitor
When using two monitors size by side with different scales, once the
cursor moves from one output to another one, its size changes based on
the scale of the given output.

Changing the size of the cursor can cause the cursor area to change
output again if the hotspot is not exactly at the top left corner of the
area, causing the texture of the cursor to change, which will trigger
another output change, so on and so forth causing continuous surface
enter/leave event which flood the clients and eventually kill them.

Change the logic to use only the actual cursor position to determine if
its on the given logical monitor, so that it remains immune to scale
changes induced by output scale differences.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/83
(cherry picked from commit 67917db45f96befb777e5f331a775ea3c2b53012)
2018-05-14 16:08:16 +02:00
Florian Müllner
41303bc01b Bump version to 3.28.2
Update NEWS.
2018-05-07 22:29:42 +02:00
Florian Müllner
0d188c3898 build: Adjust to filename changes
The meta-stage and meta-window-group headers got split into a public
and private part, but the Makefiles still reference the old files.
2018-05-07 22:29:42 +02:00
Florian Müllner
28eff93143 build: Introspect some more types
While MetaStage, MetaWindowGroup and MetaDBusDisplayConfigSkeleton don't
appear explicitly in the public API, their gtypes are still exposed via
meta_get_stage_for_screen(), meta_get_*window_group_for_screen() and
MetaMonitorManager's parent type. Newer versions of gjs will warn about
undefined properties if it encounters a gtype without introspection
information, so expose those types to shut up the warnings.

https://bugzilla.gnome.org/show_bug.cgi?id=781471
2018-05-07 22:06:02 +02:00
Florian Müllner
b380aa72aa window-group: Remove undefined function declaration
Ever since the function has been made public, its name has been
meta_actor_is_untransformed() ...

https://bugzilla.gnome.org/show_bug.cgi?id=781471
2018-05-07 22:06:02 +02:00
Florian Müllner
920dc9e5a1 clutter: Don't reference invalid pc in gir
Cally is built into clutter itself rather than exposed as a separate
library.

https://bugzilla.gnome.org/show_bug.cgi?id=781471
2018-05-07 22:06:02 +02:00
Jonas Ådahl
32f02010ae screen-cast: Handle PipeWire errors more gracefully
Various code assumed PipeWire function calls would never fail. Some can
actually fail for real reasons, and some currently can only fail due to
OOM situations, but we should still not assume that will always be the
case.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/102


(cherry picked from commit 0f9c6aef99b223a6f520071d640cf34c92046f7a)
2018-05-07 19:28:27 +00:00
Jonas Ådahl
889c56c776 wayland/xdg-foreign: Fix child surface validation check
The role type should be either an xdg-shell toplevel, or a
xdg-shell unstable v6 toplevel.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/138


(cherry picked from commit 332d55f7f6b5d646ea9bc2586b2135113c9d3074)
2018-05-07 19:20:56 +00:00
Jonas Ådahl
67a4cd898e wayland/xdg-foreign: Send immediate destroy event to correct resource
The destroyed signal that was emitted if an imported surface was not
available when created, for example if the handle was invalid or
already unexported, was emitted on the wrong resource.


(cherry picked from commit 98d702428857c79770b159137835622e33b84ba9)
2018-05-07 19:20:09 +00:00
Florian Müllner
43d6c0ea61 build: Don't fail immediately when logind is missing
We require logind for the native backend, but the backend itself is
optional. However since commit 06c357d78, we will always throw an
error if neither logind nor elogind are available, even when the
backend is disabled.

As we still support "auto" - that is, whether the native backend is
enabled depends on whether its dependencies are available - the
easiest option is to make sure we always include either elogind or
libsystemd in the dependency check rather than erring out explicitly
if neither is found.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/96


(cherry picked from commit 82564772dc27c9b86270e5a694b04945d3f5e3a1)
2018-05-07 19:14:11 +00:00
Georges Basile Stavracas Neto
2872bb1f2a wayland: Check if state and size changed before calling move_resize()
The current implementation of the XdgSurface v6 protocol does not check
if the window changed before calling meta_window_wayland_move_resize().

The problem with this approach is that calling this function is a costly
operation since we enter the compositor side. In GNOME Shell case, it is
in JavaScript, which triggers a GJS trampoline. Calling this function on
every mouse movement is naturally as terrible as it could be - and is
exactly what happens now.

This commit adds the necessary checks to only call move_resize() when
the window actually changed, or when it needs to be updated.

https://bugzilla.gnome.org/show_bug.cgi?id=780292
Issue: #78
2018-05-04 15:57:57 -03:00
Georges Basile Stavracas Neto
1c00cd5ca3 wayland: Add function to query if window needs move or resize
This will be used by the next commit to determine when a window
geometry change should be ignored or not. Normally, it would be
enough to just check if the position and sizes changed.

The position, in this case, is relative to the client buffer, not
the global position. But because it is not global, there is one,
admitedly unlikely, situation where the window state is updated
while the client size and relative positions don't change.

One can trigger this by e.g. tiling the window to the half-left of
the monitor, then immediately tile it to half-right. In this case,
the window didn't change, just it's state, but nonetheless we need
to notify the compositor and run the full move/resize routines.

When that case happens, though, the MetaWindowWayland is tracking
the pending state change or a move. And this is what we need to
expose.

https://bugzilla.gnome.org/show_bug.cgi?id=780292
Issue: #78
2018-05-04 15:57:50 -03:00
Georges Basile Stavracas Neto
2919a7f25f window: Let implementations finish state changes
In the old, synchronous X.org world, we could assume that
a state change always meant a synchronizing the window
geometry right after. After firing an operation that
would change the window state, such as maximizing or
tiling the window,

With Wayland, however, this is not valid anymore, since
Wayland is asynchronous. In this scenario, we call
meta_window_move_resize_internal() twice: when the user
executes an state-changing operation, and when the server
ACKs this operation. This breaks the previous assumptions,
and as a consequence, it breaks the GNOME Shell animations
in Wayland.

The solution is giving the MetaWindow control over the time
when the window geometry is synchronized with the compositor.
That is done by introducing a new result flag. Wayland asks
for a compositor sync after receiving an ACK from the server,
while X11 asks for it right away.

Fixes #78
2018-05-04 15:57:43 -03:00
Olivier Fourdan
ca0d56a3a4 wayland: avoid a crash in is_effectively_synchronized()
To check if a subsurface is effectively synchronized, we walk the
subsurface hierarchy to look for a non-subsurface parent or a subsurface
being synchronized.

However, when client is closing, the parent surface might already be
gone, in which case we end up with a surface being NULL which causes a
NULL pointer dereference and a crash.

Check if the parent surface is NULL to avoid the crash, and consider
it's already synchronized if it is NULL to avoid further updates.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/124


(cherry picked from commit 52fdd24467fa8d6f97bd5f9eb6d5509fa43436c6)
2018-05-03 17:49:26 +00:00
Jonas Ådahl
a89baa44ab native: Restore previous EGL state after blitting onto secondary GPU
Before we just set it to "none", but this was not enough since various
calls will depend on not just the context being active, but the main
rendering surface.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/21


(cherry picked from commit ae26cd07740e45ae16a3503004933d1cc295df29)
2018-04-25 15:24:14 +00:00
Marco Trevisan (Treviño)
7076a48bcf cogl: Do not unref a NULL object
Add return-if-fail statement to avoid deferencing NULL object


(cherry picked from commit 3104d697c0c66748ba0b005c145061499b3f1090)
2018-04-25 09:09:04 +00:00
Jonas Ådahl
1b439c42d1 monitor-manager: Find active monitor when deriving global scale
When deriving the global scale directly from the current hardware state
(as done when using the X11 backend) we are inspecting the logical
state they had prior to the most recent hot plug. That means that a
primary monitor might have been disabled, and a new primary monitor may
not have been assigned yet.

Stop assuming a primary monitor has an active mode before having
reconstructed the logical state by finding some active monitor if the
old primary monitor was disabled. This avoids a crash when trying to
derive the global scale from a disabled monitor.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/130


(cherry picked from commit 0b3a1c9c314a88c57668437245d54b200537e619)
2018-04-25 08:58:15 +00:00
Carlos Garnacho
928a40f328 wayland: Let IM events go through
These paths implicitly relied on the forwarded IM key events having
a source_device backed by a real HW device. This assumption is no
longer held true since commit b5328c977.

Explicitly check the INPUT_METHOD flag so they are handled as they
should despite not being "real HW" events.
2018-04-24 23:59:21 +02:00
Mario Sanchez Prada
59397266ed backend: Don't center the pointers on monitor changes
As a follow up to the patch from a95cbd0a, we need to make sure
that the pointer is out of the way as well when monitors changed,
since that's the event that will prevail in some cases. Besides,
this is also consistent with what the code before a95cbd0a was,
which initialized the pointer position in the same way both in
this case and in the real_post_init() function.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/157
2018-04-24 23:14:38 +02:00
Mario Sanchez Prada
d0147591b3 backends: Don't center the pointer on initialization
Centering the pointer at startup causes undesired behaviour if
it ends up hovering over reactive elements, that might react
to that positioning, causing confusion. This is the case of
the login dialog when a list of different users is shown, as
centering the pointer at startup in that case will get the
user in the center of the screen pre-selected, which is not
the expected behaviour (i.e. pre-selecting the first one).

Fix this by simply moving the pointer out of the way, close
to the bottom-right corner, during initialization.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/157
2018-04-24 23:14:37 +02:00
Ray Strode
25c7e52ada xwayland: Don't abort if Xwayland crashes
Right now if Xwayland crashes, we crash, too.

On some level that makes sense, since we're supposed to control the
lifecycle of Xwayland, and by it crashing we've lost that control.

But practically speaking, the knock-on crash adds noise to the logs,
bug trackers, and retrace servers that only makes debugging harder.
And the crash isn't something mutter can "fix", since it's
ultimately from a bug in Xwayland anyway.

This commit makes mutter exit instead of crash if Xwayland goes away
unexpectedly.


(cherry picked from commit 2d80fd02e76bbe17dc52072299dda92ab88c99c0)
2018-04-24 05:08:22 +00:00
Ray Strode
99d766c044 xwayland: use g_autoptr for GError in xserver_died
Right now we explicitly g_clear_error any error we find, but that
makes it tricky to return early from the function, which a
subsequent commit will want to to do.

This commit switches GError to use g_autoptr so the error clearing
happens automatically.


(cherry picked from commit bb6585406543688f3df48aea3211726ce52a8f29)
2018-04-24 05:07:41 +00:00
Marco Trevisan (Treviño)
fcd4c816c4 theme, frames: Use surface device scale instead of cairo_scale
Gtk now is caching the themed cairo surfaces, then as per
commit gtk@e36b629c the surface device scale is used to figure
out the current paint scaling.

Without this when using background-image's for window buttons
the -gtk-scaled icons isn't properly resized.

Fixes #99


(cherry picked from commit 4339b23dd08b2bb7de8a6f01b176c40c6fca082f)
2018-04-22 20:45:29 +00:00
Carlos Garnacho
2a63a47d5a wayland: Do not reset frame list when merging pending state
In the synchronized subsurface case, the destination list may
contain other elements from previous wl_surface.commit calls.
Resetting the list will leave those dangling frame callbacks
that will lead to invalid writes when those get to be destroyed
(eg. on client shutdown).
2018-04-22 12:14:37 +02:00
Carlos Garnacho
c80e2c9ae5 clutter: Set slave=master in IM forwarded key events
The fix is twofold. On one hand, it makes sense not to relate IM (nor
any other) generated events to a HW device. On the other hand, if we
are unfortunate that an IM event is in flight when we are switching
to another TTY, it may arrive at a time when the source device is no
longer existent.
2018-04-22 12:14:37 +02:00
Bastien Nocera
d3d5eb8e1b idle-monitor: Add ResetIdletime API, for testing purposes
The ResetIdletime API can be used instead of an "XTest" binary to
programmatically reset the idle time, as if the user pressed a button on
a keyboard.

This is necessary since we stopped using the XSync extension to monitor
idletimes, as it didn't consider inhibitors as busy, and mutter's
clutter code ignores "Core Events" as generated by XTest.

This patch will require minimal changes to gnome-settings-daemon's power
test suite so that "key press" idletime resets are triggered through
this D-Bus interface rather than through XTest and a roundtrip through
the X server.

https://bugzilla.gnome.org/show_bug.cgi?id=705942
2018-04-16 16:03:56 +02:00
Bastien Nocera
4837cec89f backend: Reset idle when lid is opened or resuming from suspend
There's no particular reason for this code to only ever be triggered on
Wayland, and allows removing X11-specific work-arounds from
gnome-settings-daemon.

See https://bugs.freedesktop.org/show_bug.cgi?id=59576

https://bugzilla.gnome.org/show_bug.cgi?id=705942
2018-04-16 16:03:56 +02:00
Bastien Nocera
32329e6c00 idle-monitor: Take idle inhibition into account
Take idle inhibitions into account for when to fire idle watches as
requested by OS components.

This should stop gnome-session and gnome-settings-daemon considering
the session idle when they have been inhibited for longer than their
timeout, for example to avoid the screensaver activating, or the
computer suspending after watching a film.

https://bugzilla.gnome.org/show_bug.cgi?id=705942
2018-04-16 16:03:56 +02:00
Bastien Nocera
89261be556 x11: Allow XTest and core events to reset idletime
Now that we've removed the X11 specific backend of the idle monitor,
add back a cut-down version of it for the explicit purpose of being
told about idle time resets when XTest events are used.

XTest events are usually used by test suites and remote display software
to inject events into an X11 session. We should consider somebody moving
the mouse remotely to be just as "active" as somebody moving it locally.

https://bugzilla.gnome.org/show_bug.cgi?id=705942
2018-04-16 16:03:56 +02:00
Bastien Nocera
e3e76d658b backends: Remove X11 idle-monitor backend
And use the old "native" backend for both X11 and Wayland. This will
allow us to share fixes between implementations without having to delve
into the XSync X11 extension code.

https://bugzilla.gnome.org/show_bug.cgi?id=705942
2018-04-16 16:03:56 +02:00
Florian Müllner
34644b2133 Bump version to 3.28.1
Update NEWS.
2018-04-13 19:11:57 +02:00
Carlos Garnacho
7da4e8cf14 wayland: Plug surface pending state contents leak
When moving the pending state of an effectively synchronized subsurface
so it is applied together with the parent, perform a merge of the source
MetaWaylandPendingState into the destination one, instead of simply
overwriting the struct.

The other approach had 2 kind of leaks, one that would happen everytime
a wl_surface.commit happens on a sync subsurface (both surface/buffer
damage regions are leaked). The other more unlikely one would apply on
the rest of pending state data, happening whenever the compositor gets
>1 wl_surface.commit calls on the subsurface before the parent surface
gets its own.

The function has also been renamed to use the more descriptive "merge"
term.

Related: gnome-shell#64
2018-04-13 00:10:03 +02:00
Aleksandr Mezin
23c3f8bb18 monitor-manager: fix output ids returned by GetResources
Output ID is set equal to 'i' later in the loop. But 'i' was never
incremented, so all outputs were getting the same ID (equal to
the number of CRTCs, because 'i' was reused from the previous loop).
2018-04-11 17:55:41 +00:00
Jonas Ådahl
60866e0f85 native: Disable the use of KMS modifiers by default
Make it re-enable:able by a hidden "experimental feature". To enable,
add "kms-modifiers" to the org.gnome.mutter.experimental-features
GSettings entry.

https://gitlab.gnome.org/GNOME/mutter/issues/81
2018-04-11 16:34:59 +02:00
Matej Urbančič
45c02645f3 Updated Slovenian translation 2018-04-10 17:58:12 +02:00
Benjamin Otte
e515e37a7e screen-cast: Fix compile error
Credit goes to gcc for finding this typo.


(cherry picked from commit 98dfd5b8871596612db2a1dc8b5e886d01c86c50)
2018-04-10 12:10:19 +00:00
Marco Trevisan (Treviño)
957f4ec69d theme: Scale titlebar spacing when computing x
The value is not scaled by default so it needs to be adjusted
depending on the window scaling, as it's done in other places.

Fixes: #87


(cherry picked from commit deda7a52355566723b45dad3d18108d326c06633)
2018-04-03 20:42:28 +00:00
Marco Trevisan (Treviño)
a98eb107be theme: add ".appmenu" class to the appmenu button
So it does gtk headerbar, so mutter should do.


(cherry picked from commit 96141e28f9c5721e30c89eec34650c9f676fb608)
2018-04-03 20:22:52 +00:00
Daniel Stone
1851fa2bd0 renderer-native: Fall back to non-modifier GBM surfaces
If we attempt GBM surface allocation with a set of modifiers but the
allocation fails, fall back to non-modifier allocations. This fixes
startup on Pineview-based Atom systems, where KMS provides us a set of
modifiers but the GBM implementation doesn't support modifier use.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/84


(cherry picked from commit e6109cfc22f06412e67bd3c1f9f0dfa6ad7e0b19)
2018-04-03 18:18:31 +00:00
Carlos Garnacho
de7d7bbf3d clutter: Apply input hints/purpose on ClutterTextInputFocus focus in
And make the ClutterText-level properties independent from the input
focus, as those properties can be set anytime, not just when the
ClutterText actor is focused.

https://gitlab.gnome.org/GNOME/mutter/issues/66

Closes: #66


(cherry picked from commit 3684f6b0ac6157f2f85e0ae473d834fa474fd72d)
2018-04-03 15:00:01 +00:00
Alberts Muktupāvels
7ac551cd05 input-settings: Fix a typo in tap-and-drag setting
(cherry picked from commit 31b5059068722b22b7043e45775cc17e7fd71438)
2018-03-29 14:54:00 +00:00
Olivier Fourdan
8696a79477 cursor-renderer-native: take rotation into account
Rotating an output would show duplicate cursors when the pointer is
located over an area which would be within the output if not rotated.

Make sure to swap the width/height of the output when rotated.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/85


(cherry picked from commit ebff7fd7f4ee2c9636412fe661a1fbdf51f218a0)
2018-03-29 06:49:14 +00:00
Daniel van Vugt
b2f9de98d0 renderer-native: Swap then await earlier flips.
Rendering the next frame (which mostly happens as part of the flush done
in swap buffers) is a task that the GPU can complete independently of
the CPU having to wait for previous page flips. So reverse their order
to get the GPU started earlier, with the aim of greater GPU-CPU
parallelism.


(cherry picked from commit 6e415353e311655be9936b9dfb9e23c80ef1eae6)
2018-03-29 05:41:02 +00:00
Georges Basile Stavracas Neto
2da2489da5 window: Fix a small memory leak
(cherry picked from commit 63e2c0329f12401ef3c93201b53c463142e7a9ca)
2018-03-29 05:24:08 +00:00
Yussuf Khalil
31779404f0 clutter: Avoid unnecessary relayouts in ClutterText
We can save an unnecessary relayout if the required size to fully draw the text
is equal to the currently allocated size after the underlying text buffer or
attributes that only affect the PangoLayout have changed.
2018-03-22 23:35:27 +01:00
Rasmus Thomsen
b096c0ac33 mutter: allow building with elogind
This commit allows building mutter with elogind, which is
systemd-logind extracted into a standalone package. This
allows using mutter with its native-backend ( and consequently
wayland ) enabled on distros which use init systems other than
systemd.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/46
2018-03-21 23:07:46 +01:00
Carlos Garnacho
44a7f74dcd cogl: Read pixels as per the stored format
By the looks of it, commit 95e9fa10ef was taping over an Intel DRI bug
that would make it return post-swizzling pixel data on glReadPixels().
There's been reports over time of that commit resulting in wrong colors
on other drivers, and lately Mesa >17.3 started showing the same symptoms
on Intel.

But texture swizzling works by changing parameters before fragment shaders
and reading pixels from an already drawn FBO/texture doesn't involve those.
This should thus use pixel_format_to_gl_with_target(), which will result in
correctly requesting the same pixel format than the underlying texture,
while still considering it BGRA for the upper layers in the swizzling case.

https://gitlab.gnome.org/GNOME/mutter/issues/72

Closes: #72
2018-03-21 20:37:34 +01:00
Georges Basile Stavracas Neto
3832c6b607 gpu-kms: Ignore GPUs with no connectors
Mutter recently gained the ability to deal with multiple GPUs
rendering at different displays. These GPUs would have a display
connected to them, and Mutter was adapted in order to be aware
of different GPUs and their outputs.

However, one specific edge case appeared: PRIME systems. PRIME
systems have two GPUs:

 * The integrated GPU (iGPU), usually Intel, which has connectors
   and deals with the routine load.

 * The dedicated GPU (dGPU), usually AMD or NVidia, which has no
   connectors at all and are there just to aid heavy loads.

On those systems, the dGPU is aggressively put to sleep by the
kernel to avoid energy waste. Waking it up is a costly operation.

With Mutter's adaptation to deal with multiple GPUs, Mutter began
wakening the dGPU every time some rendering had to be done. This
was causing stuttering every time the dGPU was put to sleep, and
Mutter asked it to wake up again.

To fix this situation, this commit ignores GPUs with no connectors
attached.

Issue: #77
2018-03-21 18:50:14 +00:00
Georges Basile Stavracas Neto
14b7e79d3c gpu-kms: Return NULL, not FALSE
Another small mistake spotted while working on #77. This
function returns a pointer, thus we should return NULL,
not FALSE.

Issue: #77
2018-03-21 18:50:13 +00:00
Georges Basile Stavracas Neto
e99b0b9368 monitor-manager-kms: Don't add GPU if it fails
This is a small mistake spotted while working on a solution
for #77. When a GPU fails to initialize, we're adding them
anyway, which might have pretty bad consequences when trying
to use these NULL GPUs.

Issue: #77
2018-03-21 18:50:13 +00:00
Georges Basile Stavracas Neto
de294f34bb monitor-manager-kms: Use g_autoptr for error
A minor code cleanup.
2018-03-21 18:50:13 +00:00
1871 changed files with 227722 additions and 184215 deletions

34
.gitignore vendored
View File

@ -1,9 +1,25 @@
Makefile
Makefile.in
Makefile.in.in
aclocal.m4
autom4te.cache
build-aux build-aux
compile compile
config.guess
config.h config.h
config.h.in config.h.in
config.log
config.status
config.sub
configure
depcomp
install-sh
intltool-extract.in
intltool-merge.in
libtool
ltmain.sh ltmain.sh
missing missing
.deps
50-mutter-navigation.xml 50-mutter-navigation.xml
50-mutter-system.xml 50-mutter-system.xml
50-mutter-windows.xml 50-mutter-windows.xml
@ -17,11 +33,15 @@ mutter-wayland.desktop
*.swp *.swp
*.gir *.gir
*.typelib *.typelib
stamp-h1
*.gmo *.gmo
*.make *.make
*.log *.log
*.trs *.trs
*~ *~
stamp-it
.intltool-merge-cache
ABOUT-NLS
POTFILES POTFILES
Makevars.template Makevars.template
po/*.header po/*.header
@ -44,7 +64,9 @@ org.gnome.mutter.wayland.gschema.xml
testasyncgetprop testasyncgetprop
testboxes testboxes
testgradient testgradient
m4/*
INSTALL INSTALL
mkinstalldirs
meta-enum-types.[ch] meta-enum-types.[ch]
src/stamp-meta-enum-types.h src/stamp-meta-enum-types.h
src/meta-dbus-display-config.[ch] src/meta-dbus-display-config.[ch]
@ -72,15 +94,12 @@ src/xwayland-keyboard-grab-unstable-v1-protocol.c
src/xwayland-keyboard-grab-unstable-v1-server-protocol.h src/xwayland-keyboard-grab-unstable-v1-server-protocol.h
src/tablet-unstable-v*-protocol.c src/tablet-unstable-v*-protocol.c
src/tablet-unstable-v*-server-protocol.h src/tablet-unstable-v*-server-protocol.h
src/text-input-unstable-v*-protocol.c
src/text-input-unstable-v*-server-protocol.h
src/keyboard-shortcuts-inhibit-unstable-v*-protocol.c src/keyboard-shortcuts-inhibit-unstable-v*-protocol.c
src/keyboard-shortcuts-inhibit-unstable-v*-server-protocol.h src/keyboard-shortcuts-inhibit-unstable-v*-server-protocol.h
src/linux-dmabuf-unstable-v*-protocol.c src/linux-dmabuf-unstable-v*-protocol.c
src/linux-dmabuf-unstable-v*-server-protocol.h src/linux-dmabuf-unstable-v*-server-protocol.h
src/xdg-shell-protocol.c src/xdg-shell-protocol.c
src/xdg-shell-server-protocol.h src/xdg-shell-server-protocol.h
src/wayland-eglstream-controller-server-protocol.h
src/meta/meta-version.h src/meta/meta-version.h
src/libmutter-*.pc src/libmutter-*.pc
doc/reference/*.args doc/reference/*.args
@ -100,7 +119,12 @@ doc/reference/meta-undocumented.txt
doc/reference/meta-unused.txt doc/reference/meta-unused.txt
doc/reference/meta-docs.sgml doc/reference/meta-docs.sgml
doc/reference/meta.types doc/reference/meta.types
gtk-doc.m4
intltool.m4
libtool.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
lt~obsolete.m4
.dirstamp .dirstamp
**/tags.* **/tags.*
build/
subprojects/sysprof/

View File

@ -1,372 +0,0 @@
include:
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/bbe5232986c9b98eb1efe62484e07216f7d1a4df/templates/fedora.yml'
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/bbe5232986c9b98eb1efe62484e07216f7d1a4df/templates/ci-fairy.yml'
stages:
- review
- prepare
- code-review
- build
- test
- analyze
- deploy
variables:
FDO_UPSTREAM_REPO: GNOME/mutter
.mutter.fedora:34@common:
variables:
FDO_DISTRIBUTION_VERSION: 34
BASE_TAG: '2021-09-04.1'
FDO_DISTRIBUTION_PACKAGES:
asciidoc
clang
gcovr
gdm
gnome-shell
python3-dbusmock
sassc
uncrustify
xorg-x11-server-Xvfb
FDO_DISTRIBUTION_EXEC: |
dnf install -y 'dnf-command(builddep)' &&
dnf builddep -y mutter --setopt=install_weak_deps=False &&
dnf builddep -y gnome-shell --setopt=install_weak_deps=False &&
./.gitlab-ci/install-meson-project.sh \
https://gitlab.gnome.org/GNOME/glib.git \
main . 02742ef957b532789c003eef80ec7f51c370e3d5 &&
./.gitlab-ci/install-meson-project.sh \
https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas.git \
41.alpha . &&
./.gitlab-ci/install-meson-project.sh \
https://gitlab.gnome.org/GNOME/gjs.git \
1.69.2 . &&
rpm -e --nodeps gnome-bluetooth-libs-devel \
mutter mutter-devel \
gnome-shell &&
dnf clean all
default:
# Cancel jobs if newer commits are pushed to the branch
interruptible: true
# Auto-retry jobs in case of infra failures
retry:
max: 1
when:
- 'runner_system_failure'
- 'stuck_or_timeout_failure'
- 'scheduler_failure'
- 'api_failure'
.mutter.fedora:34@x86_64:
extends: .mutter.fedora:34@common
variables:
FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}"
.mutter.fedora:34@aarch64:
extends: .mutter.fedora:34@common
variables:
FDO_DISTRIBUTION_TAG: "aarch64-${BASE_TAG}"
tags:
- aarch64
workflow:
rules:
- if: '$CI_MERGE_REQUEST_IID'
- if: '$CI_COMMIT_TAG'
- if: '$CI_COMMIT_BRANCH'
.pipline-guard: &pipline-guard
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_TAG'
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- if: '$CI_COMMIT_BRANCH =~ /^gnome-[0-9-]+$/'
- when: 'manual'
check-commit-log:
extends:
- .fdo.ci-fairy
stage: review
variables:
GIT_DEPTH: "100"
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
ci-fairy check-commits --junit-xml=commit-message-junit-report.xml ;
else
echo "Not a merge request" ;
fi
artifacts:
expire_in: 1 week
paths:
- commit-message-junit-report.xml
reports:
junit: commit-message-junit-report.xml
<<: *pipline-guard
check-merge-request:
extends:
- .fdo.ci-fairy
stage: review
variables:
GIT_STRATEGY: none
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml ;
else
echo "Not a merge request" ;
fi
artifacts:
expire_in: 1 week
paths:
- check-merge-request-report.xml
reports:
junit: check-merge-request-report.xml
<<: *pipline-guard
build-fedora-container@x86_64:
extends:
- .fdo.container-build@fedora@x86_64
- .mutter.fedora:34@x86_64
stage: prepare
needs:
- check-commit-log
- check-merge-request
variables:
GIT_STRATEGY: none
build-fedora-container@aarch64:
extends:
- .fdo.container-build@fedora@aarch64
- .mutter.fedora:34@aarch64
stage: prepare
needs:
- check-commit-log
- check-merge-request
variables:
GIT_STRATEGY: none
check-code-style:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora:34@x86_64
stage: code-review
needs:
- build-fedora-container@x86_64
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
git remote add target $CI_MERGE_REQUEST_PROJECT_URL.git ;
git fetch target $CI_MERGE_REQUEST_TARGET_BRANCH_NAME ;
export common_parent_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "target/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME") <(git rev-list --first-parent HEAD) | head -1) ;
python3 -u ./check-style.py --dry-run --sha $common_parent_sha ;
else
echo "Not a merge request" ;
fi
allow_failure: true
.build-mutter:
extends:
- .fdo.distribution-image@fedora
stage: build
script:
- meson . build -Dbuildtype=debugoptimized -Db_coverage=true -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
- meson compile -C build
- meson install -C build
artifacts:
expire_in: 1 day
paths:
- build
build-mutter@x86_64:
extends:
- .build-mutter
- .mutter.fedora:34@x86_64
needs:
- build-fedora-container@x86_64
build-mutter@aarch64:
extends:
- .build-mutter
- .mutter.fedora:34@aarch64
needs:
- build-fedora-container@aarch64
build-without-opengl-and-glx@x86_64:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora:34@x86_64
stage: build
needs:
- build-fedora-container@x86_64
script:
- meson . build -Dbuildtype=debugoptimized -Dopengl=false -Dglx=false -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
- meson compile -C build
- meson install -C build
artifacts:
paths:
- build/meson-logs
build-without-native-backend-and-wayland@x86_64:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora:34@x86_64
stage: build
needs:
- build-fedora-container@x86_64
script:
- meson . build -Dbuildtype=debugoptimized -Dnative_backend=false -Dudev=false -Dwayland=false -Dcore_tests=false -Dnative_tests=false --werror --prefix /usr
- meson compile -C build
- meson install -C build
artifacts:
paths:
- build/meson-logs
.test-setup: &test-setup
variables:
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data"
MUTTER_DEBUG_DUMMY_MODE_SPECS: "800x600@10.0"
PIPEWIRE_DEBUG: 2
PIPEWIRE_LOG: "$CI_PROJECT_DIR/build/meson-logs/pipewire.log"
XVFB_SERVER_ARGS: "+iglx -noreset"
G_SLICE: "always-malloc"
MALLOC_CHECK_: "3"
NO_AT_BRIDGE: "1"
before_script:
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
# Disable e.g. audio support to not dead lock screen cast tests
- rm -f /usr/share/pipewire/media-session.d/with-*
- mkdir -m 700 $XDG_RUNTIME_DIR
- pipewire & sleep 2
.test-mutter:
extends:
- .fdo.distribution-image@fedora
<<: *test-setup
stage: test
script:
- dbus-run-session -- xvfb-run -a -s "$XVFB_SERVER_ARGS"
catchsegv meson test -C build --no-rebuild -t 10
artifacts:
expire_in: 1 day
reports:
junit: "build/meson-logs/testlog-catchsegv.junit.xml"
name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
when: always
paths:
- build
test-mutter@x86_64:
extends:
- .test-mutter
- .mutter.fedora:34@x86_64
needs:
- build-mutter@x86_64
test-mutter@aarch64:
extends:
- .test-mutter
- .mutter.fedora:34@aarch64
needs:
- build-mutter@aarch64
.test-mutter-coverage:
extends:
- .fdo.distribution-image@fedora
stage: analyze
script:
- ninja -C build coverage
- cat build/meson-logs/coverage.txt
artifacts:
paths:
- build/meson-logs/coveragereport
coverage: '/^TOTAL.*\s+(\d+\%)$/'
test-mutter-coverage@x86_64:
extends:
- .test-mutter-coverage
- .mutter.fedora:34@x86_64
needs:
- test-mutter@x86_64
test-mutter-coverage@aarch64:
extends:
- .test-mutter-coverage
- .mutter.fedora:34@aarch64
needs:
- test-mutter@aarch64
can-build-gnome-shell@x86_64:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora:34@x86_64
stage: test
needs:
- build-mutter@x86_64
before_script:
- meson install --no-rebuild -C build
script:
- .gitlab-ci/checkout-gnome-shell.sh
- meson gnome-shell gnome-shell/build --prefix /usr -Dman=false
- meson install -C gnome-shell/build
test-mutter-coverity:
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule" && $MUTTER_SCHEDULED_JOB == "coverity"'
when: always
- when: manual
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora:34@x86_64
needs:
- build-fedora-container@x86_64
stage: analyze
allow_failure: true
script:
- .gitlab-ci/download-coverity-tarball.sh
- CC=clang meson coverity-build -Dprofiler=false
- ./coverity/cov-analysis-linux64-*/bin/cov-build --dir cov-int meson compile -C coverity-build
- tar czf cov-int.tar.gz cov-int
- curl https://scan.coverity.com/builds?project=mutter
--form token=$COVERITY_TOKEN --form email=carlosg@gnome.org
--form file=@cov-int.tar.gz --form version="`git describe --tags`"
--form description="GitLab CI build"
cache:
key: coverity-tarball
paths:
- coverity
dist-mutter:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora:34@x86_64
<<: *test-setup
stage: deploy
needs:
- build-mutter@x86_64
script:
- dbus-run-session -- xvfb-run -a -s "$XVFB_SERVER_ARGS" meson dist -C build
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- "**/meson.build"
- meson/*
dist-mutter-tarball:
extends: dist-mutter
artifacts:
expose_as: 'Get tarball here'
paths:
- build/meson-dist/$CI_PROJECT_NAME-$CI_COMMIT_TAG.tar.xz
rules:
- if: '$CI_COMMIT_TAG'

View File

@ -1,55 +0,0 @@
#!/usr/bin/bash
fetch() {
local remote=$1
local ref=$2
git fetch --quiet --depth=1 $remote $ref 2>/dev/null
}
gnome_shell_target=
echo -n Cloning into gnome-shell ...
if git clone --quiet --depth=1 https://gitlab.gnome.org/GNOME/gnome-shell.git; then
echo \ done
else
echo \ failed
exit 1
fi
cd gnome-shell
if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//mutter/gnome-shell}
merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
echo -n Looking for $merge_request_branch on remote ...
if fetch $merge_request_remote $merge_request_branch; then
echo \ found
gnome_shell_target=FETCH_HEAD
else
echo \ not found
echo -n Looking for $CI_MERGE_REQUEST_TARGET_BRANCH_NAME instead ...
if fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME; then
echo \ found
gnome_shell_target=FETCH_HEAD
else
echo \ not found
fi
fi
fi
if [ -z "$gnome_shell_target" ]; then
echo -n Looking for $CI_COMMIT_REF_NAME on remote ...
if fetch origin $CI_COMMIT_REF_NAME; then
echo \ found
gnome_shell_target=FETCH_HEAD
else
echo \ not found
gnome_shell_target=HEAD
echo Using $gnome_shell_target instead
fi
fi
git checkout -q $gnome_shell_target

View File

@ -1,19 +0,0 @@
patterns:
deny:
- regex: '^$CI_MERGE_REQUEST_PROJECT_URL/(-/)?merge_requests/$CI_MERGE_REQUEST_IID$'
message: Commit message must not contain a link to its own merge request
- regex: '^(meta-|Meta)'
message: Commit message subject should not be prefixed with 'meta-' or 'Meta'
where: subject
- regex: '^(clutter-|Clutter)'
message: Commit message subject should not be prefixed with 'clutter-' or 'Clutter', use 'clutter/' instead
where: subject
- regex: '^(cogl-|Cogl)'
message: Commit message subject should not be prefixed with 'cogl-' or 'Cogl', use 'cogl/' instead
where: subject
- regex: '^[^:]+: [a-z]'
message: "Commit message subject should be properly Capitalized. E.g. 'window: Marginalize extradicity'"
where: subject
- regex: '^\S*\.[ch]:'
message: Commit message subject prefix should not include .c, .h, etc.
where: subject

View File

@ -1,38 +0,0 @@
#!/usr/bin/bash
# We need a coverity token to fetch the tarball
if [ -x $COVERITY_TOKEN ]
then
echo "No coverity token. Run this job from a protected branch."
exit -1
fi
mkdir -p coverity
# Download and check MD5 first
curl https://scan.coverity.com/download/linux64 \
--data "token=$COVERITY_TOKEN&project=mutter&md5=1" \
--output /tmp/coverity_tool.md5
diff /tmp/coverity_tool.md5 coverity/coverity_tool.md5 >/dev/null 2>&1
if [ $? -eq 0 -a -d coverity/cov-analysis* ]
then
echo "Coverity tarball is up-to-date"
exit 0
fi
# Download and extract coverity tarball
curl https://scan.coverity.com/download/linux64 \
--data "token=$COVERITY_TOKEN&project=mutter" \
--output /tmp/coverity_tool.tgz
rm -rf ./coverity/cov-analysis*
tar zxf /tmp/coverity_tool.tgz -C coverity/
if [ $? -eq 0 ]
then
mv /tmp/coverity_tool.md5 coverity/
fi
rm /tmp/coverity_tool.tgz

View File

@ -1,39 +0,0 @@
#!/bin/bash
set -e
if [[ $# -lt 3 ]]; then
echo Usage: $0 [options] [repo-url] [commit] [subdir]
echo Options:
echo -Dkey=val
exit 1
fi
MESON_OPTIONS=()
while [[ $1 =~ ^-D ]]; do
MESON_OPTIONS+=( "$1" )
shift
done
REPO_URL="$1"
TAG_OR_BRANCH="$2"
SUBDIR="$3"
COMMIT="$4"
REPO_DIR="$(basename ${REPO_URL%.git})"
git clone --depth 1 "$REPO_URL" -b "$TAG_OR_BRANCH"
pushd "$REPO_DIR"
pushd "$SUBDIR"
if [ ! -z "$COMMIT" ]; then
git fetch origin "$COMMIT"
git checkout "$COMMIT"
fi
meson --prefix=/usr _build "${MESON_OPTIONS[@]}"
meson install -C _build
popd
popd
rm -rf "$REPO_DIR"

View File

@ -1,55 +0,0 @@
<!--
Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines
first to ensure that you create a clear and specific issue.
-->
### Affected version
<!--
Provide at least the following information:
* Your OS and version
* Affected Mutter version
* Does this issue appear in XOrg and/or Wayland
-->
### Bug summary
<!--
Provide a short summary of the bug you encountered.
-->
### Steps to reproduce
<!--
1. Step one
2. Step two
3. ...
-->
### What happened
<!--
What did Mutter do that was unexpected?
-->
### What did you expect to happen
<!--
What did you expect Mutter to do?
-->
### Relevant logs, screenshots, screencasts etc.
<!--
If you have further information, such as technical documentation, logs,
screenshots or screencasts related, please provide them here.
If the bug is a crash, please obtain a stack trace with installed debug
symbols (at least for GNOME Shell and Mutter) and attach it to
this issue following the instructions on
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces.
-->
<!-- Do not remove the following line. -->
/label ~"1. Bug"

View File

@ -1,30 +0,0 @@
<!--
Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines
first to ensure that you create a clear and specific issue.
-->
### Feature summary
<!--
Describe what you would like to be able to do with Mutter
that you currently cannot do.
-->
### How would you like it to work
<!--
If you can think of a way Mutter might be able to do this,
let us know here.
-->
### Relevant links, screenshots, screencasts etc.
<!--
If you have further information, such as technical documentation,
code, mockups or a similar feature in another window managers,
please provide them here.
-->
<!-- Do not remove the following line. -->
/label ~"1. Feature"

View File

@ -1,286 +0,0 @@
# Style
The coding style used is primarily the GNU flavor of the [GNOME coding
style][gnome-coding-style], with some additions described below.
## General
* Use this code style on new code. When changing old code with a different
code style, feel free to also adjust it to use this code style.
* Use regular C types and `stdint.h` types instead of GLib fundamental
types, except for `gboolean`, and `guint`/`gulong` for GSource IDs and
signal handler IDs. That means e.g. `uint64_t` instead of `guint64`, `int`
instead of `gint`, `unsigned int` instead of `guint` if unsignedness
is of importance, `uint8_t` instead of `guchar`, and so on.
* Try to to limit line length to 80 characters, although it's not a
strict limit.
* Usage of `g_autofree` and `g_autoptr` is encouraged. The style to use is
```c
g_autofree char *text = NULL;
g_autoptr (MetaSomeThing) thing = NULL;
text = g_strdup_printf ("The text: %d", a_number);
thing = g_object_new (META_TYPE_SOME_THING,
"text", text,
NULL);
thinger_use_thing (rocket, thing);
```
* Declare variables at the top of the block they are used, but avoid
non-trivial logic among variable declarations. Non-trivial logic can be
getting a pointer that may be `NULL`, any kind of math, or anything
that may have side effects.
* Instead of boolean arguments in functions, prefer enums or flags when
they're more expressive. The naming convention for flags is
```c
typedef _MetaSomeThingFlags
{
META_SOME_THING_FLAG_NONE = 0,
META_SOME_THING_FLAG_ALTER_REALITY = 1 << 0,
META_SOME_THING_FLAG_MANIPULATE_PERCEPTION = 1 << 1,
} MetaSomeThingFlags;
```
* Use `g_new0 ()` etc. instead of `g_slice_new0 ()`.
* Initialize and assign floating point variables (i.e. `float` or
`double`) using the form `floating_point = 3.14159` or `ratio = 2.0`.
## Header (.h) files
* The return type and `*` are separated by a space.
* Function name starts one space after the last `*`.
* Parenthesis comes one space after the function name.
As an example, this is how functions in a header file should look like:
```c
gboolean meta_udev_is_drm_device (MetaUdev *udev,
GUdevDevice *device);
GList * meta_udev_list_drm_devices (MetaUdev *udev,
GError **error);
MetaUdev * meta_udev_new (MetaBackendNative *backend_native);
```
## Source code
Keep functions in the following order in source files:
1. GPL header
2. Enums
3. Structures
4. Function prototypes
5. `G_DEFINE_TYPE()`
6. Static variables
7. Auxiliary functions
8. Callbacks
9. Interface implementations
10. Parent vfunc overrides
11. class_init and init
12. Public API
### Structures
Each structure field has a space after their type name. Structure fields aren't
aligned. For example:
```c
struct _MetaFooBar
{
MetaFoo parent;
MetaBar *bar;
MetaSomething *something;
};
```
### Function Prototypes
Function prototypes must be formatted just like in header files.
### Overrides
When overriding parent class vfuncs, or implementing an interface, vfunc
overrides should be named as a composition of the current class prefix,
followed by the vfunc name. For example:
```c
static void
meta_bar_spawn_unicorn (MetaParent *parent)
{
/* ... */
}
static void
meta_bar_dispose (GObject *object)
{
/* ... */
}
static void
meta_bar_finalize (GObject *object)
{
/* ... */
}
static void
meta_bar_class_init (MetaBarClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
MetaParentClass *parent_class = META_PARENT_CLASS (klass);
object_class->dispose = meta_bar_dispose;
object_class->finalize = meta_bar_finalize;
parent_class->spawn_unicorn = meta_bar_spawn_unicorn;
}
```
### Interface Implementations
When implementing interfaces, two groups of functions are involved: the init
function, and the overrides.
The interface init function is named after the interface type in snake case,
followed by the `_iface_init` suffix. For example:
```c
static void meta_foo_iface_init (MetaFooInterface *foo_iface);
G_DEFINE_TYPE_WITH_CODE (MetaBar, meta_bar, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (META_TYPE_FOO,
meta_foo_iface_init));
```
Then, when implementing each vfunc of the interface, follow the same pattern
of the [Overrides](###Overrides) section. Here's an example:
```c
static void
meta_bar_do_something (MetaFoo *foo)
{
/* ... */
}
static void
meta_foo_iface_init (MetaFooInterface *foo_iface)
{
foo_iface->do_something = meta_bar_do_something;
}
```
### Auxiliary Functions
Auxiliary functions are above every other functions to minimize the number of
function prototypes in the file. These functions often grow when factoring out
the same code between two or more functions:
```c
static void
do_something_on_data (Foo *data,
Bar *bar)
{
/* ... */
}
static void
random_function (Foo *foo)
{
do_something_on_data (foo, bar);
}
static void
another_random_function (Foo *foo)
{
do_something_on_data (foo, bar);
}
```
Sometimes, however, auxiliary functions are created to break down otherwise
large functions - in this case, it is appropriate to keep these auxiliary
functions close to the function they are tightly related to.
Auxiliary function names must have a verb in the imperative form, and should
always perform an action over something. They usually don't have the class
prefix (`meta_`, `clutter_`, or `cogl_`). For example:
```c
static void
do_something_on_data (Foo *data,
Bar *bar)
{
/* ... */
}
```
Exceptionally, when converting between types, auxiliary function names may
have the class prefix to this rule. For example:
```c
static MetaFoo *
meta_foo_from_bar (Bar *bar)
{
/* ... */
}
```
### Callback Functions
Callback function names should have the name of the action in imperative
form. They don't have any prefix, but have a `_func` suffix. For example:
```c
static void
filter_something_func (Foo *foo,
Bar *bar,
gpointer user_data)
{
/* ... */
}
```
### Signal Callbacks
Signal callbacks generally have the signal name. They should be prefixed with
`on_`, or suffixed with `_cb`, but not both. For example:
```c
static void
on_realize (ClutterActor *actor,
gpointer user_data)
{
/* ... */
}
static void
destroy_cb (ClutterActor *actor,
gpointer user_data)
{
/* ... */
}
```
When the callback is named after the object that generated it, and the signal,
then passive voice is used. For example:
```c
static void
click_action_clicked_cb (ClutterClickAction *click_action,
ClutterActor *actor,
gpointer user_data)
{
/* ... */
}
```
[gnome-coding-style]: https://developer.gnome.org/programming-guidelines/stable/c-coding-style.html.en

11
Makefile.am Normal file
View File

@ -0,0 +1,11 @@
SUBDIRS = cogl clutter data src po doc
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
DISTCLEANFILES = \
intltool-extract \
intltool-merge \
intltool-update \
po/stamp-it \
po/.intltool-merge-cache

1277
NEWS

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
# Mutter
Mutter is a Wayland display server and X11 window manager and compositor library.
When used as a Wayland display server, it runs on top of KMS and libinput. It
implements the compositor side of the Wayland core protocol as well as various
protocol extensions. It also has functionality related to running X11
applications using Xwayland.
When used on top of Xorg it acts as a X11 window manager and compositing manager.
It contains functionality related to, among other things, window management,
window compositing, focus tracking, workspace management, keybindings and
monitor configuration.
Internally it uses a fork of Cogl, a hardware acceleration abstraction library
used to simplify usage of OpenGL pipelines, as well as a fork af Clutter, a
scene graph and user interface toolkit.
Mutter is used by, for example, GNOME Shell, the GNOME core user interface, and
by Gala, elementary OS's window manager. It can also be run standalone, using
the command "mutter", but just running plain mutter is only intended for
debugging purposes.
## Contributing
To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter.
It can be useful to look at the documentation available at the
[Wiki](https://gitlab.gnome.org/GNOME/mutter/-/wikis/home).
## Coding style and conventions
See [HACKING.md](./HACKING.md).
## Git messages
Commit messages should follow the [GNOME commit message
guidelines](https://wiki.gnome.org/Git/CommitMessages). We require an URL
to either an issue or a merge request in each commit. Try to always prefix
commit subjects with a relevant topic, such as `compositor:` or
`clutter/actor:`, and it's always better to write too much in the commit
message body than too little.
## Default branch
The default development branch is `main`. If you still have a local
checkout under the old name, use:
```sh
git checkout master
git branch -m master main
git fetch
git branch --unset-upstream
git branch -u origin/main
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
```
## License
Mutter is distributed under the terms of the GNU General Public License,
version 2 or later. See the [COPYING][license] file for detalis.
[bug-tracker]: https://gitlab.gnome.org/GNOME/mutter/issues
[license]: COPYING

28
autogen.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
REQUIRED_AUTOMAKE_VERSION=1.11
olddir="$(pwd)"
cd "${srcdir}"
(test -f configure.ac \
&& test -d src) || {
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
echo " top-level mutter directory"
exit 1
}
aclocal --install || exit 1
intltoolize --force --copy --automake || exit 1
autoreconf --verbose --force --install || exit 1
cd "${olddir}"
if [ "$NOCONFIGURE" = "" ]; then
"${srcdir}/configure" "$@" || exit 1
fi

View File

@ -1,138 +0,0 @@
#!/bin/env python3
import argparse
import os
import re
import subprocess
import sys
import tempfile
# Path relative to this script
uncrustify_cfg = 'tools/uncrustify.cfg'
def run_diff(sha):
proc = subprocess.Popen(["git", "diff", "-U0", "--function-context", sha, "HEAD"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
files = proc.stdout.read().strip().decode('utf-8')
return files.split('\n')
def find_chunks(diff):
file_entry_re = re.compile('^\+\+\+ b/(.*)$')
diff_chunk_re = re.compile('^@@ -\d+,\d+ \+(\d+),(\d+)')
file = None
chunks = []
for line in diff:
match = file_entry_re.match(line)
if match:
file = match.group(1)
match = diff_chunk_re.match(line)
if match:
start = int(match.group(1))
len = int(match.group(2))
end = start + len
if len > 0 and (file.endswith('.c') or file.endswith('.h') or file.endswith('.vala')):
chunks.append({ 'file': file, 'start': start, 'end': end })
return chunks
def reformat_chunks(chunks, rewrite):
# Creates temp file with INDENT-ON/OFF comments
def create_temp_file(file, start, end):
with open(file) as f:
tmp = tempfile.NamedTemporaryFile()
tmp.write(b'/** *INDENT-OFF* **/\n')
for i, line in enumerate(f):
if i == start - 2:
tmp.write(b'/** *INDENT-ON* **/\n')
tmp.write(bytes(line, 'utf-8'))
if i == end - 2:
tmp.write(b'/** *INDENT-OFF* **/\n')
tmp.seek(0)
return tmp
# Removes uncrustify INDENT-ON/OFF helper comments
def remove_indent_comments(output):
tmp = tempfile.NamedTemporaryFile()
for line in output:
if line != b'/** *INDENT-OFF* **/\n' and line != b'/** *INDENT-ON* **/\n':
tmp.write(line)
tmp.seek(0)
return tmp
changed = None
for chunk in chunks:
# Add INDENT-ON/OFF comments
tmp = create_temp_file(chunk['file'], chunk['start'], chunk['end'])
# uncrustify chunk
proc = subprocess.Popen(["uncrustify", "-c", uncrustify_cfg, "-f", tmp.name], stdout=subprocess.PIPE)
reindented = proc.stdout.readlines()
proc.wait()
if proc.returncode != 0:
continue
tmp.close()
# Remove INDENT-ON/OFF comments
formatted = remove_indent_comments(reindented)
if dry_run is True:
# Show changes
proc = subprocess.Popen(["diff", "-up", "--color=always", chunk['file'], formatted.name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
diff = proc.stdout.read().decode('utf-8')
if diff != '':
output = re.sub('\t', '\t', diff)
print(output)
changed = True
else:
# Apply changes
diff = subprocess.Popen(["diff", "-up", chunk['file'], formatted.name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
patch = subprocess.Popen(["patch", chunk['file']], stdin=diff.stdout)
diff.stdout.close()
patch.communicate()
formatted.close()
return changed
parser = argparse.ArgumentParser(description='Check code style.')
parser.add_argument('--sha', metavar='SHA', type=str,
help='SHA for the commit to compare HEAD with')
parser.add_argument('--dry-run', '-d', type=bool,
action=argparse.BooleanOptionalAction,
help='Only print changes to stdout, do not change code')
parser.add_argument('--rewrite', '-r', type=bool,
action=argparse.BooleanOptionalAction,
help='Whether to amend the result to the last commit (e.g. \'git rebase --exec "%(prog)s -r"\')')
# Change CWD to script location, necessary for always locating the configuration file
os.chdir(os.path.dirname(os.path.abspath(sys.argv[0])))
args = parser.parse_args()
sha = args.sha or 'HEAD^'
rewrite = args.rewrite
dry_run = args.dry_run
diff = run_diff(sha)
chunks = find_chunks(diff)
changed = reformat_chunks(chunks, rewrite)
if dry_run is not True and rewrite is True:
proc = subprocess.Popen(["git", "commit", "--all", "--amend", "-C", "HEAD"], stdout=subprocess.DEVNULL)
os._exit(0)
elif dry_run is True and changed is True:
print ("\nIssue the following command in your local tree to apply the suggested changes (needs uncrustify installed):\n\n $ git rebase origin/main --exec \"./check-style.py -r\" \n")
os._exit(-1)
os._exit(0)

1
clutter/.gitignore vendored
View File

@ -23,6 +23,7 @@ clutter-build-config.h.in
clutter-config.h clutter-config.h
clutter-enum-types.[ch] clutter-enum-types.[ch]
clutter-marshal.[ch] clutter-marshal.[ch]
clutter-version.h
gcov-report.txt gcov-report.txt
clutter-json.h clutter-json.h
clutter-lcov.info clutter-lcov.info

53
clutter/Makefile.am Normal file
View File

@ -0,0 +1,53 @@
NULL =
SUBDIRS = build clutter tests
if BUILD_EXAMPLES
SUBDIRS += examples
endif
DIST_SUBDIRS = clutter tests examples build
# XXX - this is a massive hack to make autoreconf honour the ACLOCAL_FLAGS
# that jhbuild sets while still retaining build/autotools as the authoritative
# source for m4 macros
ACLOCAL_AMFLAGS = -I build/autotools ${ACLOCAL_FLAGS}
CLEANFILES = $(pcfiles)
DISTCLEANFILES =
DISTCHECK_CONFIGURE_FLAGS = --enable-maintainer-flags
# proxy rules for tests
test-report full-report:
$(MAKE) -C tests/conform $(@)
perf-report:
$(MAKE) -C tests/performance $(@)
if ENABLE_GCOV
# use recursive makes in order to ignore errors during check/perf
lcov:
-$(MAKE) $(AM_MAKEFLAGS) -C clutter check
-$(MAKE) $(AM_MAKEFLAGS) -C tests/conform test
$(MAKE) $(AM_MAKEFLAGS) genlcov
# we have to massage the lcov.info file slightly to hide the effect of libtool
# placing the objects files in the .libs/ directory separate from the *.c
genlcov:
$(LTP) --directory $(top_builddir) --capture --output-file clutter-lcov.info --test-name CLUTTER_TEST --no-checksum
$(SED) -e 's#.libs/##' < clutter-lcov.info > clutter-lcov.info.tmp
LANG=C $(LTP_GENHTML) --prefix $(top_builddir) --output-directory clutter-lcov --title "Clutter Code Coverage" --show-details clutter-lcov.info.tmp
rm -f clutter-lcov.info.tmp
lcov-clean:
-$(LTP) --directory $(top_builddir) -z
-$(RM) -rf clutter-lcov.info clutter-lcov
else
lcov genlcov lcov-clean:
@echo You need to configure Clutter with support for gcov enabled.
@echo e.g., ./configure --enable-gcov
endif
.PHONY: test-report full-report perf-report lcov genlcov lcov-clean

View File

@ -0,0 +1 @@
SUBDIRS = autotools

8
clutter/build/autotools/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
gtk-doc.m4
libtool.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
lt~obsolete.m4
shave
shave-libtool

View File

@ -0,0 +1,10 @@
NULL =
EXTRA_DIST = \
introspection.m4 \
as-compiler-flag.m4 \
glibtests.m4 \
glib-tap.mk \
tap-driver.sh \
tap-test \
$(NULL)

View File

@ -0,0 +1,62 @@
dnl as-compiler-flag.m4 0.1.0
dnl autostars m4 macro for detection of compiler flags
dnl David Schleef <ds@schleef.org>
dnl $Id: as-compiler-flag.m4,v 1.1 2005/12/15 23:35:19 ds Exp $
dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED])
dnl Tries to compile with the given CFLAGS.
dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags,
dnl and ACTION-IF-NOT-ACCEPTED otherwise.
AC_DEFUN([AS_COMPILER_FLAG],
[
AC_MSG_CHECKING([to see if compiler understands $1])
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $1"
AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
CFLAGS="$save_CFLAGS"
if test "X$flag_ok" = Xyes ; then
m4_ifvaln([$2],[$2])
true
else
m4_ifvaln([$3],[$3])
true
fi
AC_MSG_RESULT([$flag_ok])
])
dnl AS_COMPILER_FLAGS(VAR, FLAGS)
dnl Tries to compile with the given CFLAGS.
AC_DEFUN([AS_COMPILER_FLAGS],
[
list=$2
flags_supported=""
flags_unsupported=""
AC_MSG_CHECKING([for supported compiler flags])
for each in $list
do
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $each"
AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
CFLAGS="$save_CFLAGS"
if test "X$flag_ok" = Xyes ; then
flags_supported="$flags_supported $each"
else
flags_unsupported="$flags_unsupported $each"
fi
done
AC_MSG_RESULT([$flags_supported])
if test "X$flags_unsupported" != X ; then
AC_MSG_WARN([unsupported compiler flags: $flags_unsupported])
fi
$1="$$1 $flags_supported"
])

View File

@ -0,0 +1,134 @@
# GLIB - Library of useful C routines
TESTS_ENVIRONMENT= \
G_TEST_SRCDIR="$(abs_srcdir)" \
G_TEST_BUILDDIR="$(abs_builddir)" \
G_DEBUG=gc-friendly \
MALLOC_CHECK_=2 \
MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256))
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/build/autotools/tap-driver.sh
LOG_COMPILER = $(top_srcdir)/build/autotools/tap-test
NULL =
# initialize variables for unconditional += appending
BUILT_SOURCES =
BUILT_EXTRA_DIST =
CLEANFILES = *.log *.trs
DISTCLEANFILES =
MAINTAINERCLEANFILES =
EXTRA_DIST =
TESTS =
installed_test_LTLIBRARIES =
installed_test_PROGRAMS =
installed_test_SCRIPTS =
nobase_installed_test_DATA =
noinst_LTLIBRARIES =
noinst_PROGRAMS =
noinst_SCRIPTS =
noinst_DATA =
check_LTLIBRARIES =
check_PROGRAMS =
check_SCRIPTS =
check_DATA =
# We support a fairly large range of possible variables. It is expected that all types of files in a test suite
# will belong in exactly one of the following variables.
#
# First, we support the usual automake suffixes, but in lowercase, with the customary meaning:
#
# test_programs, test_scripts, test_data, test_ltlibraries
#
# The above are used to list files that are involved in both uninstalled and installed testing. The
# test_programs and test_scripts are taken to be actual testcases and will be run as part of the test suite.
# Note that _data is always used with the nobase_ automake variable name to ensure that installed test data is
# installed in the same way as it appears in the package layout.
#
# In order to mark a particular file as being only for one type of testing, use 'installed' or 'uninstalled',
# like so:
#
# installed_test_programs, uninstalled_test_programs
# installed_test_scripts, uninstalled_test_scripts
# installed_test_data, uninstalled_test_data
# installed_test_ltlibraries, uninstalled_test_ltlibraries
#
# Additionally, we support 'extra' infixes for programs and scripts. This is used for support programs/scripts
# that should not themselves be run as testcases (but exist to be used from other testcases):
#
# test_extra_programs, installed_test_extra_programs, uninstalled_test_extra_programs
# test_extra_scripts, installed_test_extra_scripts, uninstalled_test_extra_scripts
#
# Additionally, for _scripts and _data, we support the customary dist_ prefix so that the named script or data
# file automatically end up in the tarball.
#
# dist_test_scripts, dist_test_data, dist_test_extra_scripts
# dist_installed_test_scripts, dist_installed_test_data, dist_installed_test_extra_scripts
# dist_uninstalled_test_scripts, dist_uninstalled_test_data, dist_uninstalled_test_extra_scripts
#
# Note that no file is automatically disted unless it appears in one of the dist_ variables. This follows the
# standard automake convention of not disting programs scripts or data by default.
#
# test_programs, test_scripts, uninstalled_test_programs and uninstalled_test_scripts (as well as their disted
# variants) will be run as part of the in-tree 'make check'. These are all assumed to be runnable under
# gtester. That's a bit strange for scripts, but it's possible.
TESTS += $(test_programs) $(test_scripts) $(uninstalled_test_programs) $(uninstalled_test_scripts) \
$(dist_test_scripts) $(dist_uninstalled_test_scripts)
# Note: build even the installed-only targets during 'make check' to ensure that they still work.
# We need to do a bit of trickery here and manage disting via EXTRA_DIST instead of using dist_ prefixes to
# prevent automake from mistreating gmake functions like $(wildcard ...) and $(addprefix ...) as if they were
# filenames, including removing duplicate instances of the opening part before the space, eg. '$(addprefix'.
all_test_programs = $(test_programs) $(uninstalled_test_programs) $(installed_test_programs) \
$(test_extra_programs) $(uninstalled_test_extra_programs) $(installed_test_extra_programs)
all_test_scripts = $(test_scripts) $(uninstalled_test_scripts) $(installed_test_scripts) \
$(test_extra_scripts) $(uninstalled_test_extra_scripts) $(installed_test_extra_scripts)
all_dist_test_scripts = $(dist_test_scripts) $(dist_uninstalled_test_scripts) $(dist_installed_test_scripts) \
$(dist_test_extra_scripts) $(dist_uninstalled_test_extra_scripts) $(dist_installed_test_extra_scripts)
all_test_scripts += $(all_dist_test_scripts)
EXTRA_DIST += $(all_dist_test_scripts)
all_test_data = $(test_data) $(uninstalled_test_data) $(installed_test_data)
all_dist_test_data = $(dist_test_data) $(dist_uninstalled_test_data) $(dist_installed_test_data)
all_test_data += $(all_dist_test_data)
EXTRA_DIST += $(all_dist_test_data)
all_test_ltlibs = $(test_ltlibraries) $(uninstalled_test_ltlibraries) $(installed_test_ltlibraries)
if ENABLE_ALWAYS_BUILD_TESTS
noinst_LTLIBRARIES += $(all_test_ltlibs)
noinst_PROGRAMS += $(all_test_programs)
noinst_SCRIPTS += $(all_test_scripts)
noinst_DATA += $(all_test_data)
else
check_LTLIBRARIES += $(all_test_ltlibs)
check_PROGRAMS += $(all_test_programs)
check_SCRIPTS += $(all_test_scripts)
check_DATA += $(all_test_data)
endif
if ENABLE_INSTALLED_TESTS
installed_test_PROGRAMS += $(test_programs) $(installed_test_programs) \
$(test_extra_programs) $(installed_test_extra_programs)
installed_test_SCRIPTS += $(test_scripts) $(installed_test_scripts) \
$(test_extra_scripts) $(test_installed_extra_scripts)
installed_test_SCRIPTS += $(dist_test_scripts) $(dist_test_extra_scripts) \
$(dist_installed_test_scripts) $(dist_installed_test_extra_scripts)
nobase_installed_test_DATA += $(test_data) $(installed_test_data)
nobase_installed_test_DATA += $(dist_test_data) $(dist_installed_test_data)
installed_test_LTLIBRARIES += $(test_ltlibraries) $(installed_test_ltlibraries)
installed_testcases = $(test_programs) $(installed_test_programs) \
$(test_scripts) $(installed_test_scripts) \
$(dist_test_scripts) $(dist_installed_test_scripts)
installed_test_meta_DATA = $(installed_testcases:=.test)
%.test: %$(EXEEXT) Makefile
$(AM_V_GEN) (echo '[Test]' > $@.tmp; \
echo 'Type=session' >> $@.tmp; \
echo 'Exec=env G_ENABLE_DIAGNOSTIC=0 CLUTTER_ENABLE_DIAGNOSTIC=0 $(installed_testdir)/$<' >> $@.tmp; \
mv $@.tmp $@)
CLEANFILES += $(installed_test_meta_DATA)
endif

View File

@ -0,0 +1,28 @@
dnl GLIB_TESTS
dnl
AC_DEFUN([GLIB_TESTS],
[
AC_ARG_ENABLE(installed-tests,
AS_HELP_STRING([--enable-installed-tests],
[Enable installation of some test cases]),
[case ${enableval} in
yes) ENABLE_INSTALLED_TESTS="1" ;;
no) ENABLE_INSTALLED_TESTS="" ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-installed-tests]) ;;
esac])
AM_CONDITIONAL([ENABLE_INSTALLED_TESTS], test "$ENABLE_INSTALLED_TESTS" = "1")
AC_ARG_ENABLE(always-build-tests,
AS_HELP_STRING([--enable-always-build-tests],
[Enable always building tests during 'make all']),
[case ${enableval} in
yes) ENABLE_ALWAYS_BUILD_TESTS="1" ;;
no) ENABLE_ALWAYS_BUILD_TESTS="" ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-always-build-tests]) ;;
esac])
AM_CONDITIONAL([ENABLE_ALWAYS_BUILD_TESTS], test "$ENABLE_ALWAYS_BUILD_TESTS" = "1")
if test "$ENABLE_INSTALLED_TESTS" = "1"; then
AC_SUBST(installed_test_metadir, [${datadir}/installed-tests/]AC_PACKAGE_NAME)
AC_SUBST(installed_testdir, [${libexecdir}/installed-tests/]AC_PACKAGE_NAME)
fi
])

View File

@ -0,0 +1,96 @@
dnl -*- mode: autoconf -*-
dnl Copyright 2009 Johan Dahlin
dnl
dnl This file is free software; the author(s) gives unlimited
dnl permission to copy and/or distribute it, with or without
dnl modifications, as long as this notice is preserved.
dnl
# serial 1
m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL],
[
AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
AC_BEFORE([LT_INIT],[$0])dnl setup libtool first
dnl enable/disable introspection
m4_if([$2], [require],
[dnl
enable_introspection=yes
],[dnl
AC_ARG_ENABLE(introspection,
AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]],
[Enable introspection for this build]),,
[enable_introspection=auto])
])dnl
AC_MSG_CHECKING([for gobject-introspection])
dnl presence/version checking
AS_CASE([$enable_introspection],
[no], [dnl
found_introspection="no (disabled, use --enable-introspection to enable)"
],dnl
[yes],[dnl
PKG_CHECK_EXISTS([gobject-introspection-1.0],,
AC_MSG_ERROR([gobject-introspection-1.0 is not installed]))
PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1],
found_introspection=yes,
AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME]))
],dnl
[auto],[dnl
PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no)
dnl Canonicalize enable_introspection
enable_introspection=$found_introspection
],dnl
[dnl
AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@])
])dnl
AC_MSG_RESULT([$found_introspection])
INTROSPECTION_SCANNER=
INTROSPECTION_COMPILER=
INTROSPECTION_GENERATE=
INTROSPECTION_GIRDIR=
INTROSPECTION_TYPELIBDIR=
if test "x$found_introspection" = "xyes"; then
INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0`
INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0`
INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0`
INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0`
INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0`
INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection
fi
AC_SUBST(INTROSPECTION_SCANNER)
AC_SUBST(INTROSPECTION_COMPILER)
AC_SUBST(INTROSPECTION_GENERATE)
AC_SUBST(INTROSPECTION_GIRDIR)
AC_SUBST(INTROSPECTION_TYPELIBDIR)
AC_SUBST(INTROSPECTION_CFLAGS)
AC_SUBST(INTROSPECTION_LIBS)
AC_SUBST(INTROSPECTION_MAKEFILE)
AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes")
])
dnl Usage:
dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version])
AC_DEFUN([GOBJECT_INTROSPECTION_CHECK],
[
_GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1])
])
dnl Usage:
dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version])
AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE],
[
_GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require])
])

View File

@ -0,0 +1,652 @@
#! /bin/sh
# Copyright (C) 2011-2013 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
scriptversion=2011-12-27.17; # UTC
# Make unconditional expansion of undefined variables an error. This
# helps a lot in preventing typo-related bugs.
set -u
me=tap-driver.sh
fatal ()
{
echo "$me: fatal: $*" >&2
exit 1
}
usage_error ()
{
echo "$me: $*" >&2
print_usage >&2
exit 2
}
print_usage ()
{
cat <<END
Usage:
tap-driver.sh --test-name=NAME --log-file=PATH --trs-file=PATH
[--expect-failure={yes|no}] [--color-tests={yes|no}]
[--enable-hard-errors={yes|no}] [--ignore-exit]
[--diagnostic-string=STRING] [--merge|--no-merge]
[--comments|--no-comments] [--] TEST-COMMAND
The \`--test-name', \`--log-file' and \`--trs-file' options are mandatory.
END
}
# TODO: better error handling in option parsing (in particular, ensure
# TODO: $log_file, $trs_file and $test_name are defined).
test_name= # Used for reporting.
log_file= # Where to save the result and output of the test script.
trs_file= # Where to save the metadata of the test run.
expect_failure=0
color_tests=0
merge=0
ignore_exit=0
comments=0
diag_string='#'
while test $# -gt 0; do
case $1 in
--help) print_usage; exit $?;;
--version) echo "$me $scriptversion"; exit $?;;
--test-name) test_name=$2; shift;;
--log-file) log_file=$2; shift;;
--trs-file) trs_file=$2; shift;;
--color-tests) color_tests=$2; shift;;
--expect-failure) expect_failure=$2; shift;;
--enable-hard-errors) shift;; # No-op.
--merge) merge=1;;
--no-merge) merge=0;;
--ignore-exit) ignore_exit=1;;
--comments) comments=1;;
--no-comments) comments=0;;
--diagnostic-string) diag_string=$2; shift;;
--) shift; break;;
-*) usage_error "invalid option: '$1'";;
esac
shift
done
test $# -gt 0 || usage_error "missing test command"
case $expect_failure in
yes) expect_failure=1;;
*) expect_failure=0;;
esac
if test $color_tests = yes; then
init_colors='
color_map["red"]="" # Red.
color_map["grn"]="" # Green.
color_map["lgn"]="" # Light green.
color_map["blu"]="" # Blue.
color_map["mgn"]="" # Magenta.
color_map["std"]="" # No color.
color_for_result["ERROR"] = "mgn"
color_for_result["PASS"] = "grn"
color_for_result["XPASS"] = "red"
color_for_result["FAIL"] = "red"
color_for_result["XFAIL"] = "lgn"
color_for_result["SKIP"] = "blu"'
else
init_colors=''
fi
# :; is there to work around a bug in bash 3.2 (and earlier) which
# does not always set '$?' properly on redirection failure.
# See the Autoconf manual for more details.
:;{
(
# Ignore common signals (in this subshell only!), to avoid potential
# problems with Korn shells. Some Korn shells are known to propagate
# to themselves signals that have killed a child process they were
# waiting for; this is done at least for SIGINT (and usually only for
# it, in truth). Without the `trap' below, such a behaviour could
# cause a premature exit in the current subshell, e.g., in case the
# test command it runs gets terminated by a SIGINT. Thus, the awk
# script we are piping into would never seen the exit status it
# expects on its last input line (which is displayed below by the
# last `echo $?' statement), and would thus die reporting an internal
# error.
# For more information, see the Autoconf manual and the threads:
# <http://lists.gnu.org/archive/html/bug-autoconf/2011-09/msg00004.html>
# <http://mail.opensolaris.org/pipermail/ksh93-integration-discuss/2009-February/004121.html>
trap : 1 3 2 13 15
if test $merge -gt 0; then
exec 2>&1
else
exec 2>&3
fi
"$@"
echo $?
) | LC_ALL=C ${AM_TAP_AWK-awk} \
-v me="$me" \
-v test_script_name="$test_name" \
-v log_file="$log_file" \
-v trs_file="$trs_file" \
-v expect_failure="$expect_failure" \
-v merge="$merge" \
-v ignore_exit="$ignore_exit" \
-v comments="$comments" \
-v diag_string="$diag_string" \
'
# FIXME: the usages of "cat >&3" below could be optimized when using
# FIXME: GNU awk, and/on on systems that supports /dev/fd/.
# Implementation note: in what follows, `result_obj` will be an
# associative array that (partly) simulates a TAP result object
# from the `TAP::Parser` perl module.
## ----------- ##
## FUNCTIONS ##
## ----------- ##
function fatal(msg)
{
print me ": " msg | "cat >&2"
exit 1
}
function abort(where)
{
fatal("internal error " where)
}
# Convert a boolean to a "yes"/"no" string.
function yn(bool)
{
return bool ? "yes" : "no";
}
function add_test_result(result)
{
if (!test_results_index)
test_results_index = 0
test_results_list[test_results_index] = result
test_results_index += 1
test_results_seen[result] = 1;
}
# Whether the test script should be re-run by "make recheck".
function must_recheck()
{
for (k in test_results_seen)
if (k != "XFAIL" && k != "PASS" && k != "SKIP")
return 1
return 0
}
# Whether the content of the log file associated to this test should
# be copied into the "global" test-suite.log.
function copy_in_global_log()
{
for (k in test_results_seen)
if (k != "PASS")
return 1
return 0
}
# FIXME: this can certainly be improved ...
function get_global_test_result()
{
if ("ERROR" in test_results_seen)
return "ERROR"
if ("FAIL" in test_results_seen || "XPASS" in test_results_seen)
return "FAIL"
all_skipped = 1
for (k in test_results_seen)
if (k != "SKIP")
all_skipped = 0
if (all_skipped)
return "SKIP"
return "PASS";
}
function stringify_result_obj(result_obj)
{
if (result_obj["is_unplanned"] || result_obj["number"] != testno)
return "ERROR"
if (plan_seen == LATE_PLAN)
return "ERROR"
if (result_obj["directive"] == "TODO")
return result_obj["is_ok"] ? "XPASS" : "XFAIL"
if (result_obj["directive"] == "SKIP")
return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL;
if (length(result_obj["directive"]))
abort("in function stringify_result_obj()")
return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL
}
function decorate_result(result)
{
color_name = color_for_result[result]
if (color_name)
return color_map[color_name] "" result "" color_map["std"]
# If we are not using colorized output, or if we do not know how
# to colorize the given result, we should return it unchanged.
return result
}
function report(result, details)
{
if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/)
{
msg = ": " test_script_name
add_test_result(result)
}
else if (result == "#")
{
msg = " " test_script_name ":"
}
else
{
abort("in function report()")
}
if (length(details))
msg = msg " " details
# Output on console might be colorized.
print decorate_result(result) msg
# Log the result in the log file too, to help debugging (this is
# especially true when said result is a TAP error or "Bail out!").
print result msg | "cat >&3";
}
function testsuite_error(error_message)
{
report("ERROR", "- " error_message)
}
function handle_tap_result()
{
details = result_obj["number"];
if (length(result_obj["description"]))
details = details " " result_obj["description"]
if (plan_seen == LATE_PLAN)
{
details = details " # AFTER LATE PLAN";
}
else if (result_obj["is_unplanned"])
{
details = details " # UNPLANNED";
}
else if (result_obj["number"] != testno)
{
details = sprintf("%s # OUT-OF-ORDER (expecting %d)",
details, testno);
}
else if (result_obj["directive"])
{
details = details " # " result_obj["directive"];
if (length(result_obj["explanation"]))
details = details " " result_obj["explanation"]
}
report(stringify_result_obj(result_obj), details)
}
# `skip_reason` should be empty whenever planned > 0.
function handle_tap_plan(planned, skip_reason)
{
planned += 0 # Avoid getting confused if, say, `planned` is "00"
if (length(skip_reason) && planned > 0)
abort("in function handle_tap_plan()")
if (plan_seen)
{
# Error, only one plan per stream is acceptable.
testsuite_error("multiple test plans")
return;
}
planned_tests = planned
# The TAP plan can come before or after *all* the TAP results; we speak
# respectively of an "early" or a "late" plan. If we see the plan line
# after at least one TAP result has been seen, assume we have a late
# plan; in this case, any further test result seen after the plan will
# be flagged as an error.
plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN)
# If testno > 0, we have an error ("too many tests run") that will be
# automatically dealt with later, so do not worry about it here. If
# $plan_seen is true, we have an error due to a repeated plan, and that
# has already been dealt with above. Otherwise, we have a valid "plan
# with SKIP" specification, and should report it as a particular kind
# of SKIP result.
if (planned == 0 && testno == 0)
{
if (length(skip_reason))
skip_reason = "- " skip_reason;
report("SKIP", skip_reason);
}
}
function extract_tap_comment(line)
{
if (index(line, diag_string) == 1)
{
# Strip leading `diag_string` from `line`.
line = substr(line, length(diag_string) + 1)
# And strip any leading and trailing whitespace left.
sub("^[ \t]*", "", line)
sub("[ \t]*$", "", line)
# Return what is left (if any).
return line;
}
return "";
}
# When this function is called, we know that line is a TAP result line,
# so that it matches the (perl) RE "^(not )?ok\b".
function setup_result_obj(line)
{
# Get the result, and remove it from the line.
result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0)
sub("^(not )?ok[ \t]*", "", line)
# If the result has an explicit number, get it and strip it; otherwise,
# automatically assing the next progresive number to it.
if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/)
{
match(line, "^[0-9]+")
# The final `+ 0` is to normalize numbers with leading zeros.
result_obj["number"] = substr(line, 1, RLENGTH) + 0
line = substr(line, RLENGTH + 1)
}
else
{
result_obj["number"] = testno
}
if (plan_seen == LATE_PLAN)
# No further test results are acceptable after a "late" TAP plan
# has been seen.
result_obj["is_unplanned"] = 1
else if (plan_seen && testno > planned_tests)
result_obj["is_unplanned"] = 1
else
result_obj["is_unplanned"] = 0
# Strip trailing and leading whitespace.
sub("^[ \t]*", "", line)
sub("[ \t]*$", "", line)
# This will have to be corrected if we have a "TODO"/"SKIP" directive.
result_obj["description"] = line
result_obj["directive"] = ""
result_obj["explanation"] = ""
if (index(line, "#") == 0)
return # No possible directive, nothing more to do.
# Directives are case-insensitive.
rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*"
# See whether we have the directive, and if yes, where.
pos = match(line, rx "$")
if (!pos)
pos = match(line, rx "[^a-zA-Z0-9_]")
# If there was no TAP directive, we have nothing more to do.
if (!pos)
return
# Let`s now see if the TAP directive has been escaped. For example:
# escaped: ok \# SKIP
# not escaped: ok \\# SKIP
# escaped: ok \\\\\# SKIP
# not escaped: ok \ # SKIP
if (substr(line, pos, 1) == "#")
{
bslash_count = 0
for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--)
bslash_count += 1
if (bslash_count % 2)
return # Directive was escaped.
}
# Strip the directive and its explanation (if any) from the test
# description.
result_obj["description"] = substr(line, 1, pos - 1)
# Now remove the test description from the line, that has been dealt
# with already.
line = substr(line, pos)
# Strip the directive, and save its value (normalized to upper case).
sub("^[ \t]*#[ \t]*", "", line)
result_obj["directive"] = toupper(substr(line, 1, 4))
line = substr(line, 5)
# Now get the explanation for the directive (if any), with leading
# and trailing whitespace removed.
sub("^[ \t]*", "", line)
sub("[ \t]*$", "", line)
result_obj["explanation"] = line
}
function get_test_exit_message(status)
{
if (status == 0)
return ""
if (status !~ /^[1-9][0-9]*$/)
abort("getting exit status")
if (status < 127)
exit_details = ""
else if (status == 127)
exit_details = " (command not found?)"
else if (status >= 128 && status <= 255)
exit_details = sprintf(" (terminated by signal %d?)", status - 128)
else if (status > 256 && status <= 384)
# We used to report an "abnormal termination" here, but some Korn
# shells, when a child process die due to signal number n, can leave
# in $? an exit status of 256+n instead of the more standard 128+n.
# Apparently, both behaviours are allowed by POSIX (2008), so be
# prepared to handle them both. See also Austing Group report ID
# 0000051 <http://www.austingroupbugs.net/view.php?id=51>
exit_details = sprintf(" (terminated by signal %d?)", status - 256)
else
# Never seen in practice.
exit_details = " (abnormal termination)"
return sprintf("exited with status %d%s", status, exit_details)
}
function write_test_results()
{
print ":global-test-result: " get_global_test_result() > trs_file
print ":recheck: " yn(must_recheck()) > trs_file
print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file
for (i = 0; i < test_results_index; i += 1)
print ":test-result: " test_results_list[i] > trs_file
close(trs_file);
}
BEGIN {
## ------- ##
## SETUP ##
## ------- ##
'"$init_colors"'
# Properly initialized once the TAP plan is seen.
planned_tests = 0
COOKED_PASS = expect_failure ? "XPASS": "PASS";
COOKED_FAIL = expect_failure ? "XFAIL": "FAIL";
# Enumeration-like constants to remember which kind of plan (if any)
# has been seen. It is important that NO_PLAN evaluates "false" as
# a boolean.
NO_PLAN = 0
EARLY_PLAN = 1
LATE_PLAN = 2
testno = 0 # Number of test results seen so far.
bailed_out = 0 # Whether a "Bail out!" directive has been seen.
# Whether the TAP plan has been seen or not, and if yes, which kind
# it is ("early" is seen before any test result, "late" otherwise).
plan_seen = NO_PLAN
## --------- ##
## PARSING ##
## --------- ##
is_first_read = 1
while (1)
{
# Involutions required so that we are able to read the exit status
# from the last input line.
st = getline
if (st < 0) # I/O error.
fatal("I/O error while reading from input stream")
else if (st == 0) # End-of-input
{
if (is_first_read)
abort("in input loop: only one input line")
break
}
if (is_first_read)
{
is_first_read = 0
nextline = $0
continue
}
else
{
curline = nextline
nextline = $0
$0 = curline
}
# Copy any input line verbatim into the log file.
print | "cat >&3"
# Parsing of TAP input should stop after a "Bail out!" directive.
if (bailed_out)
continue
# TAP test result.
if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/)
{
testno += 1
setup_result_obj($0)
handle_tap_result()
}
# TAP plan (normal or "SKIP" without explanation).
else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/)
{
# The next two lines will put the number of planned tests in $0.
sub("^1\\.\\.", "")
sub("[^0-9]*$", "")
handle_tap_plan($0, "")
continue
}
# TAP "SKIP" plan, with an explanation.
else if ($0 ~ /^1\.\.0+[ \t]*#/)
{
# The next lines will put the skip explanation in $0, stripping
# any leading and trailing whitespace. This is a little more
# tricky in truth, since we want to also strip a potential leading
# "SKIP" string from the message.
sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "")
sub("[ \t]*$", "");
handle_tap_plan(0, $0)
}
# "Bail out!" magic.
# Older versions of prove and TAP::Harness (e.g., 3.17) did not
# recognize a "Bail out!" directive when preceded by leading
# whitespace, but more modern versions (e.g., 3.23) do. So we
# emulate the latter, "more modern" behaviour.
else if ($0 ~ /^[ \t]*Bail out!/)
{
bailed_out = 1
# Get the bailout message (if any), with leading and trailing
# whitespace stripped. The message remains stored in `$0`.
sub("^[ \t]*Bail out![ \t]*", "");
sub("[ \t]*$", "");
# Format the error message for the
bailout_message = "Bail out!"
if (length($0))
bailout_message = bailout_message " " $0
testsuite_error(bailout_message)
}
# Maybe we have too look for dianogtic comments too.
else if (comments != 0)
{
comment = extract_tap_comment($0);
if (length(comment))
report("#", comment);
}
}
## -------- ##
## FINISH ##
## -------- ##
# A "Bail out!" directive should cause us to ignore any following TAP
# error, as well as a non-zero exit status from the TAP producer.
if (!bailed_out)
{
if (!plan_seen)
{
testsuite_error("missing test plan")
}
else if (planned_tests != testno)
{
bad_amount = testno > planned_tests ? "many" : "few"
testsuite_error(sprintf("too %s tests run (expected %d, got %d)",
bad_amount, planned_tests, testno))
}
if (!ignore_exit)
{
# Fetch exit status from the last line.
exit_message = get_test_exit_message(nextline)
if (exit_message)
testsuite_error(exit_message)
}
}
write_test_results()
exit 0
} # End of "BEGIN" block.
'
# TODO: document that we consume the file descriptor 3 :-(
} 3>"$log_file"
test $? -eq 0 || fatal "I/O or internal error"
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -0,0 +1,5 @@
#! /bin/sh
# run a GTest in tap mode. The test binary is passed as $1
$1 -k --tap

727
clutter/clutter/Makefile.am Normal file
View File

@ -0,0 +1,727 @@
AUTOMAKE_OPTIONS = subdir-objects
# preamble
NULL =
# common definitions
CLEANFILES =
DISTCLEANFILES =
EXTRA_DIST =
BUILT_SOURCES =
AM_CPPFLAGS = \
-DCLUTTER_PREFIX=\""$(prefix)"\" \
-DCLUTTER_LIBDIR=\""$(libdir)"\" \
-DCLUTTER_DATADIR=\""$(datadir)"\" \
-DCLUTTER_LOCALEDIR=\""$(localedir)"\" \
-DCLUTTER_SYSCONFDIR=\""$(sysconfdir)"\" \
-DCLUTTER_COMPILATION=1 \
-DCOGL_DISABLE_DEPRECATION_WARNINGS \
-DG_LOG_DOMAIN=\"Clutter\" \
-I$(top_srcdir) \
-I$(top_srcdir)/clutter \
-I$(top_srcdir)/clutter/cally \
-I$(top_builddir) \
-I$(top_builddir)/clutter \
-I$(top_srcdir)/../cogl \
-I$(top_builddir)/../cogl \
-I$(top_builddir)/../cogl/cogl \
$(CLUTTER_DEPRECATED_CFLAGS) \
$(CLUTTER_DEBUG_CFLAGS) \
$(CLUTTER_HIDDEN_VISIBILITY_CFLAGS) \
$(NULL)
AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS)
# these are the gir files we generate using g-ir-scanner
INTROSPECTION_GIRS =
# the base include path for headers
clutter_base_includedir = $(includedir)/mutter/clutter-$(LIBMUTTER_API_VERSION)
clutter_includedir = $(clutter_base_includedir)/clutter
clutter_deprecateddir = $(clutter_base_includedir)/clutter/deprecated
# pkg-config files
pc_files =
# common sources - please, keep these sorted alphabetically
source_h = \
clutter-action.h \
clutter-actor-meta.h \
clutter-actor.h \
clutter-align-constraint.h \
clutter-animatable.h \
clutter-backend.h \
clutter-bind-constraint.h \
clutter-binding-pool.h \
clutter-bin-layout.h \
clutter-blur-effect.h \
clutter-box-layout.h \
clutter-brightness-contrast-effect.h \
clutter-cairo.h \
clutter-canvas.h \
clutter-child-meta.h \
clutter-click-action.h \
clutter-clone.h \
clutter-color-static.h \
clutter-color.h \
clutter-colorize-effect.h \
clutter-constraint.h \
clutter-container.h \
clutter-content.h \
clutter-deform-effect.h \
clutter-deprecated.h \
clutter-desaturate-effect.h \
clutter-device-manager.h \
clutter-drag-action.h \
clutter-drop-action.h \
clutter-effect.h \
clutter-enums.h \
clutter-event.h \
clutter-feature.h \
clutter-fixed-layout.h \
clutter-flow-layout.h \
clutter-gesture-action.h \
clutter-grid-layout.h \
clutter-group.h \
clutter-image.h \
clutter-input-device.h \
clutter-input-device-tool.h \
clutter-input-focus.h \
clutter-input-method.h \
clutter-interval.h \
clutter-keyframe-transition.h \
clutter-keysyms.h \
clutter-layout-manager.h \
clutter-layout-meta.h \
clutter-macros.h \
clutter-main.h \
clutter-offscreen-effect.h \
clutter-page-turn-effect.h \
clutter-paint-nodes.h \
clutter-paint-node.h \
clutter-pan-action.h \
clutter-path-constraint.h \
clutter-path.h \
clutter-property-transition.h \
clutter-rotate-action.h \
clutter-script.h \
clutter-scriptable.h \
clutter-scroll-actor.h \
clutter-settings.h \
clutter-shader-effect.h \
clutter-shader-types.h \
clutter-swipe-action.h \
clutter-snap-constraint.h \
clutter-stage.h \
clutter-stage-manager.h \
clutter-tap-action.h \
clutter-test-utils.h \
clutter-texture.h \
clutter-text.h \
clutter-text-buffer.h \
clutter-timeline.h \
clutter-transition-group.h \
clutter-transition.h \
clutter-types.h \
clutter-units.h \
clutter-virtual-input-device.h \
clutter-zoom-action.h \
$(NULL)
source_c = \
clutter-action.c \
clutter-actor-box.c \
clutter-actor-meta.c \
clutter-actor.c \
clutter-align-constraint.c \
clutter-animatable.c \
clutter-backend.c \
clutter-base-types.c \
clutter-bezier.c \
clutter-bind-constraint.c \
clutter-binding-pool.c \
clutter-bin-layout.c \
clutter-blur-effect.c \
clutter-box-layout.c \
clutter-brightness-contrast-effect.c \
clutter-cairo.c \
clutter-canvas.c \
clutter-child-meta.c \
clutter-click-action.c \
clutter-clone.c \
clutter-color.c \
clutter-colorize-effect.c \
clutter-constraint.c \
clutter-container.c \
clutter-content.c \
clutter-deform-effect.c \
clutter-desaturate-effect.c \
clutter-device-manager.c \
clutter-drag-action.c \
clutter-drop-action.c \
clutter-effect.c \
clutter-event.c \
clutter-feature.c \
clutter-fixed-layout.c \
clutter-flatten-effect.c \
clutter-flow-layout.c \
clutter-gesture-action.c \
clutter-grid-layout.c \
clutter-image.c \
clutter-input-device.c \
clutter-input-device-tool.c \
clutter-input-focus.c \
clutter-input-method.c \
clutter-virtual-input-device.c \
clutter-interval.c \
clutter-keyframe-transition.c \
clutter-keysyms-table.c \
clutter-layout-manager.c \
clutter-layout-meta.c \
clutter-main.c \
clutter-master-clock.c \
clutter-master-clock-default.c \
clutter-offscreen-effect.c \
clutter-page-turn-effect.c \
clutter-paint-nodes.c \
clutter-paint-node.c \
clutter-pan-action.c \
clutter-path-constraint.c \
clutter-path.c \
clutter-property-transition.c \
clutter-rotate-action.c \
clutter-script.c \
clutter-script-parser.c \
clutter-scriptable.c \
clutter-scroll-actor.c \
clutter-settings.c \
clutter-shader-effect.c \
clutter-shader-types.c \
clutter-swipe-action.c \
clutter-snap-constraint.c \
clutter-stage.c \
clutter-stage-manager.c \
clutter-stage-window.c \
clutter-tap-action.c \
clutter-test-utils.c \
clutter-text.c \
clutter-text-buffer.c \
clutter-transition-group.c \
clutter-transition.c \
clutter-timeline.c \
clutter-units.c \
clutter-util.c \
clutter-paint-volume.c \
clutter-zoom-action.c \
$(NULL)
# private headers; these should not be distributed or introspected
source_h_priv = \
clutter-actor-meta-private.h \
clutter-actor-private.h \
clutter-backend-private.h \
clutter-bezier.h \
clutter-constraint-private.h \
clutter-content-private.h \
clutter-debug.h \
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-master-clock.h \
clutter-master-clock-default.h \
clutter-offscreen-effect-private.h \
clutter-paint-node-private.h \
clutter-paint-volume-private.h \
clutter-private.h \
clutter-script-private.h \
clutter-settings-private.h \
clutter-stage-manager-private.h \
clutter-stage-private.h \
clutter-stage-view.h \
clutter-stage-window.h \
$(NULL)
# private source code; these should not be introspected
source_c_priv = \
clutter-easing.c \
clutter-event-translator.c \
clutter-id-pool.c \
clutter-stage-view.c \
$(NULL)
# deprecated installed headers
deprecated_h = \
deprecated/clutter-actor.h \
deprecated/clutter-alpha.h \
deprecated/clutter-animatable.h \
deprecated/clutter-animation.h \
deprecated/clutter-animator.h \
deprecated/clutter-backend.h \
deprecated/clutter-behaviour.h \
deprecated/clutter-behaviour-depth.h \
deprecated/clutter-behaviour-ellipse.h \
deprecated/clutter-behaviour-opacity.h \
deprecated/clutter-behaviour-path.h \
deprecated/clutter-behaviour-rotate.h \
deprecated/clutter-behaviour-scale.h \
deprecated/clutter-bin-layout.h \
deprecated/clutter-box.h \
deprecated/clutter-cairo-texture.h \
deprecated/clutter-container.h \
deprecated/clutter-frame-source.h \
deprecated/clutter-group.h \
deprecated/clutter-input-device.h \
deprecated/clutter-keysyms.h \
deprecated/clutter-list-model.h \
deprecated/clutter-main.h \
deprecated/clutter-media.h \
deprecated/clutter-model.h \
deprecated/clutter-rectangle.h \
deprecated/clutter-score.h \
deprecated/clutter-shader.h \
deprecated/clutter-stage-manager.h \
deprecated/clutter-stage.h \
deprecated/clutter-state.h \
deprecated/clutter-table-layout.h \
deprecated/clutter-texture.h \
deprecated/clutter-timeline.h \
deprecated/clutter-timeout-pool.h \
deprecated/clutter-util.h \
$(NULL)
# deprecated source code
deprecated_c = \
deprecated/clutter-actor-deprecated.c \
deprecated/clutter-alpha.c \
deprecated/clutter-animation.c \
deprecated/clutter-animator.c \
deprecated/clutter-behaviour.c \
deprecated/clutter-behaviour-depth.c \
deprecated/clutter-behaviour-ellipse.c \
deprecated/clutter-behaviour-opacity.c \
deprecated/clutter-behaviour-path.c \
deprecated/clutter-behaviour-rotate.c \
deprecated/clutter-behaviour-scale.c \
deprecated/clutter-box.c \
deprecated/clutter-cairo-texture.c \
deprecated/clutter-frame-source.c \
deprecated/clutter-group.c \
deprecated/clutter-input-device-deprecated.c \
deprecated/clutter-layout-manager-deprecated.c \
deprecated/clutter-list-model.c \
deprecated/clutter-media.c \
deprecated/clutter-model.c \
deprecated/clutter-rectangle.c \
deprecated/clutter-score.c \
deprecated/clutter-shader.c \
deprecated/clutter-state.c \
deprecated/clutter-table-layout.c \
deprecated/clutter-texture.c \
deprecated/clutter-timeout-pool.c \
$(NULL)
# deprecated private headers; these should not be installed
deprecated_h_priv = \
deprecated/clutter-model-private.h \
deprecated/clutter-timeout-interval.h \
$(NULL)
# deprecated private source code; these should not be introspected
deprecated_c_priv = \
deprecated/clutter-timeout-interval.c \
$(NULL)
# built sources
built_source_c = \
clutter-enum-types.c \
clutter-marshal.c \
$(NULL)
# built headers
built_source_h = \
clutter-enum-types.h \
clutter-marshal.h \
$(NULL)
# config header
DISTCLEANFILES += clutter-config.h
EXTRA_DIST += clutter-config.h.in
# version header
DISTCLEANFILES += clutter-version.h
EXTRA_DIST += clutter-version.h.in clutter-version.h
# key symbol update script
EXTRA_DIST += clutter-keysyms-update.pl
pc_files += mutter-clutter-$(LIBMUTTER_API_VERSION).pc
# in order to be compatible with Clutter < 1.10, when we shipped a single
# shared library whose name was determined by the single backend it
# supported, we need to install symbolic links so that existing applications
# using Clutter won't break in the Brave New World of multi-backend support
# in the same shared object.
compat_libs =
# backends source listings
#
# backend_source_c := source code
# backend_source_h := installed public headers
# backend_source_c_priv := source that should not be scanned by g-i
# backend_source_h_priv := private headers
# backend_source_built := built sources
#
backend_source_c =
backend_source_h =
backend_source_c_priv =
backend_source_h_priv =
backend_source_built =
# X11 backend rules
x11_source_c = \
x11/clutter-backend-x11.c \
x11/clutter-device-manager-core-x11.c \
x11/clutter-event-x11.c \
x11/clutter-input-device-core-x11.c \
x11/clutter-keymap-x11.c \
x11/clutter-stage-x11.c \
x11/clutter-x11-texture-pixmap.c \
x11/clutter-xkb-a11y-x11.c \
$(NULL)
x11_source_h = \
x11/clutter-x11.h \
x11/clutter-x11-texture-pixmap.h \
$(NULL)
x11_source_h_priv = \
x11/clutter-backend-x11.h \
x11/clutter-device-manager-core-x11.h \
x11/clutter-input-device-core-x11.h \
x11/clutter-keymap-x11.h \
x11/clutter-settings-x11.h \
x11/clutter-stage-x11.h \
x11/clutter-xkb-a11y-x11.h \
$(NULL)
x11_source_c_priv = \
x11/xsettings/xsettings-client.c \
x11/xsettings/xsettings-client.h \
x11/xsettings/xsettings-common.c \
x11/xsettings/xsettings-common.h \
$(NULL)
x11_source_c += \
x11/clutter-device-manager-xi2.c \
x11/clutter-input-device-xi2.c \
x11/clutter-input-device-tool-xi2.c \
$(NULL)
x11_source_h_priv += \
x11/clutter-device-manager-xi2.h \
x11/clutter-input-device-xi2.h \
x11/clutter-input-device-tool-xi2.h \
$(NULL)
x11_source_c += \
x11/clutter-virtual-input-device-x11.c \
$(NULL)
x11_source_h_priv += \
x11/clutter-virtual-input-device-x11.h \
$(NULL)
backend_source_h += $(x11_source_h)
backend_source_c += $(x11_source_c)
backend_source_h_priv += $(x11_source_h_priv)
backend_source_c_priv += $(x11_source_c_priv)
# the list of files we want to introspect on X11
x11_introspection = $(x11_source_c) $(x11_source_h)
clutterx11_includedir = $(clutter_includedir)/x11
clutterx11_include_HEADERS = $(x11_source_h)
mutter-clutter-x11-@LIBMUTTER_API_VERSION@.pc: mutter-clutter-$(LIBMUTTER_API_VERSION).pc
$(QUIET_GEN)cp -f $< $(@F)
pc_files += mutter-clutter-x11-$(LIBMUTTER_API_VERSION).pc
# Shared cogl backend files
cogl_source_h =
cogl_source_c = \
cogl/clutter-stage-cogl.c \
$(NULL)
cogl_source_h_priv = \
cogl/clutter-stage-cogl.h \
$(NULL)
cogl_source_c_priv =
backend_source_h += $(cogl_source_h)
backend_source_c += $(cogl_source_c)
backend_source_h_priv += $(cogl_source_h_priv)
backend_source_c_priv += $(cogl_source_c_priv)
backend_source_h += $(glx_source_h)
backend_source_c += $(glx_source_c)
evdev_c_priv = \
evdev/clutter-device-manager-evdev.c \
evdev/clutter-input-device-evdev.c \
evdev/clutter-seat-evdev.c \
evdev/clutter-virtual-input-device-evdev.c \
evdev/clutter-event-evdev.c \
evdev/clutter-input-device-tool-evdev.c \
$(NULL)
evdev_h_priv = \
evdev/clutter-device-manager-evdev.h \
evdev/clutter-input-device-evdev.h \
evdev/clutter-seat-evdev.h \
evdev/clutter-input-device-tool-evdev.h \
evdev/clutter-virtual-input-device-evdev.h \
$(NULL)
evdev_h = evdev/clutter-evdev.h
if SUPPORT_WAYLAND
backend_source_c_priv += $(evdev_c_priv)
backend_source_h_priv += $(evdev_h_priv)
backend_source_h += $(evdev_h)
clutterevdev_includedir = $(clutter_includedir)/evdev
clutterevdev_include_HEADERS = $(evdev_h)
backend_source_c += evdev/clutter-xkb-utils.c
backend_source_h_priv += evdev/clutter-xkb-utils.h
# EGL backend rules
egl_source_h = \
egl/clutter-egl-headers.h \
egl/clutter-egl.h \
$(NULL)
egl_source_h_priv = egl/clutter-backend-eglnative.h
egl_source_c = egl/clutter-backend-eglnative.c
wayland_compositor_source_h = \
wayland/clutter-wayland-compositor.h \
wayland/clutter-wayland-surface.h
backend_source_h += $(wayland_compositor_source_h)
backend_source_c += \
wayland/clutter-wayland-surface.c
wayland_compositor_includedir = $(clutter_includedir)/wayland
wayland_compositor_include_HEADERS = $(wayland_compositor_source_h)
backend_source_h += $(egl_source_h)
backend_source_c += $(egl_source_c)
backend_source_h_priv += $(egl_source_h_priv)
clutteregl_includedir = $(clutter_includedir)/egl
clutteregl_include_HEADERS = $(egl_source_h)
endif # SUPPORT_WAYLAND
# cally
cally_sources_h = \
cally/cally-actor.h \
cally/cally-clone.h \
cally/cally-factory.h \
cally/cally-group.h \
cally/cally.h \
cally/cally-main.h \
cally/cally-rectangle.h \
cally/cally-root.h \
cally/cally-stage.h \
cally/cally-text.h \
cally/cally-texture.h \
cally/cally-util.h \
$(NULL)
cally_sources_c = \
cally/cally-actor.c \
cally/cally.c \
cally/cally-clone.c \
cally/cally-group.c \
cally/cally-rectangle.c \
cally/cally-root.c \
cally/cally-stage.c \
cally/cally-text.c \
cally/cally-texture.c \
cally/cally-util.c \
$(NULL)
cally_sources_private = \
cally/cally-actor-private.h \
$(NULL)
cally_includedir = $(clutter_base_includedir)/cally
cally_include_HEADERS = $(cally_sources_h)
# general build rules:
# you should not need to modify anything below this point
# glib-genmarshal rules
glib_marshal_list = clutter-marshal.list
glib_marshal_prefix = _clutter_marshal
include $(srcdir)/Makefile.am.marshal
# glib-mkenums rules
glib_enum_h = clutter-enum-types.h
glib_enum_c = clutter-enum-types.c
glib_enum_headers = $(source_h) $(deprecated_h)
include $(srcdir)/Makefile.am.enums
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = $(pc_files)
DISTCLEANFILES += $(pc_files)
clutter_include_HEADERS = $(source_h) clutter.h clutter-version.h clutter-autocleanups.h clutter-mutter.h
nodist_clutter_include_HEADERS = clutter-config.h $(built_source_h)
clutter_deprecated_HEADERS = $(deprecated_h)
mutterlibdir = $(libdir)/mutter
mutterlib_LTLIBRARIES = libmutter-clutter-@LIBMUTTER_API_VERSION@.la
libmutter_clutter_@LIBMUTTER_API_VERSION@_la_LIBADD = \
$(LIBM) \
$(CLUTTER_LIBS) \
$(top_builddir)/../cogl/cogl/libmutter-cogl-$(LIBMUTTER_API_VERSION).la \
$(top_builddir)/../cogl/cogl-pango/libmutter-cogl-pango-$(LIBMUTTER_API_VERSION).la \
$(top_builddir)/../cogl/cogl-path/libmutter-cogl-path-$(LIBMUTTER_API_VERSION).la \
$(NULL)
libmutter_clutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
$(backend_source_c) \
$(backend_source_h) \
$(backend_source_c_priv) \
$(backend_source_h_priv) \
$(source_c) \
$(source_h) \
$(source_c_priv) \
$(source_h_priv) \
$(deprecated_c) \
$(deprecated_h) \
$(deprecated_c_priv) \
$(deprecated_h_priv) \
$(cally_sources_c) \
$(cally_sources_h) \
$(cally_sources_private) \
$(NULL)
nodist_libmutter_clutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
$(backend_source_built) \
$(built_source_c) \
$(built_source_h)
libmutter_clutter_@LIBMUTTER_API_VERSION@_la_LDFLAGS = \
$(CLUTTER_LINK_FLAGS) \
$(CLUTTER_LT_LDFLAGS) \
-export-dynamic \
-rpath $(mutterlibdir) \
$(NULL)
install-exec-local:
test -z "$(mutterlibdir)" || $(MKDIR_P) "$(DESTDIR)$(mutterlibdir)"
for lib in `echo $(compat_libs)`; do \
(cd $(DESTDIR)$(mutterlibdir) && \
rm -f $$lib.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION); \
) ; \
(cd $(DESTDIR)$(mutterlibdir) && \
{ ln -s -f libmutter-clutter-$(LIBMUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib.0 || \
{ rm -f $$lib.0 && ln -s libmutter-clutter-$(LIBMUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib.0; }; \
} \
) ; \
(cd $(DESTDIR)$(mutterlibdir) && \
{ ln -s -f libmutter-clutter-$(LIBMUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib || \
{ rm -f $$lib && ln -s libmutter-clutter-$(LIBMUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib; }; \
} \
) ; \
done
# gobject-introspection rules
-include $(INTROSPECTION_MAKEFILE)
INTROSPECTION_SCANNER_ARGS = \
--add-include-path=$(top_builddir)/../cogl/cogl \
--add-include-path=$(top_builddir)/../cogl/cogl-pango
INTROSPECTION_COMPILER_ARGS = \
--includedir=$(top_builddir)/../cogl/cogl \
--includedir=$(top_builddir)/../cogl/cogl-pango
INTROSPECTION_SCANNER_ENV = \
PKG_CONFIG_PATH=$(top_builddir)/../cogl/cogl/:$(top_builddir)/../cogl/cogl-pango/:$${PKG_CONFIG_PATH}
Clutter-@LIBMUTTER_API_VERSION@.gir: libmutter-clutter-@LIBMUTTER_API_VERSION@.la Makefile
Clutter_@LIBMUTTER_API_VERSION@_gir_NAMESPACE = Clutter
Clutter_@LIBMUTTER_API_VERSION@_gir_VERSION = @LIBMUTTER_API_VERSION@
Clutter_@LIBMUTTER_API_VERSION@_gir_LIBS = libmutter-clutter-@LIBMUTTER_API_VERSION@.la
Clutter_@LIBMUTTER_API_VERSION@_gir_FILES = \
$(clutter_include_HEADERS) \
$(clutter_deprecated_HEADERS) \
$(nodist_clutter_include_HEADERS) \
$(source_c) \
$(deprecated_c) \
$(built_source_c)
Clutter_@LIBMUTTER_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
Clutter_@LIBMUTTER_API_VERSION@_gir_INCLUDES = GL-1.0 GObject-2.0 cairo-1.0 Cogl-@LIBMUTTER_API_VERSION@ CoglPango-@LIBMUTTER_API_VERSION@ Atk-1.0 Json-1.0
Clutter_@LIBMUTTER_API_VERSION@_gir_SCANNERFLAGS = \
--warn-all \
--c-include='clutter/clutter.h' \
--pkg-export=mutter-clutter-@LIBMUTTER_API_VERSION@
INTROSPECTION_GIRS += Clutter-@LIBMUTTER_API_VERSION@.gir
Cally-@LIBMUTTER_API_VERSION@.gir: Makefile Clutter-@LIBMUTTER_API_VERSION@.gir
Cally_@LIBMUTTER_API_VERSION@_gir_NAMESPACE = Cally
Cally_@LIBMUTTER_API_VERSION@_gir_VERSION = @LIBMUTTER_API_VERSION@
Cally_@LIBMUTTER_API_VERSION@_gir_LIBS = libmutter-clutter-@LIBMUTTER_API_VERSION@.la
Cally_@LIBMUTTER_API_VERSION@_gir_FILES = $(cally_sources_h) $(cally_sources_c)
Cally_@LIBMUTTER_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
Cally_@LIBMUTTER_API_VERSION@_gir_SCANNERFLAGS = \
--warn-all \
--c-include='cally/cally.h' \
--pkg-export=mutter-clutter-@LIBMUTTER_API_VERSION@ \
--include-uninstalled=$(top_builddir)/clutter/Clutter-@LIBMUTTER_API_VERSION@.gir
INTROSPECTION_GIRS += Cally-@LIBMUTTER_API_VERSION@.gir
ClutterX11-@LIBMUTTER_API_VERSION@.gir: Makefile Clutter-@LIBMUTTER_API_VERSION@.gir
ClutterX11_@LIBMUTTER_API_VERSION@_gir_NAMESPACE = ClutterX11
ClutterX11_@LIBMUTTER_API_VERSION@_gir_INCLUDES = xlib-2.0
ClutterX11_@LIBMUTTER_API_VERSION@_gir_LIBS = libmutter-clutter-@LIBMUTTER_API_VERSION@.la
ClutterX11_@LIBMUTTER_API_VERSION@_gir_FILES = $(x11_introspection)
ClutterX11_@LIBMUTTER_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
ClutterX11_@LIBMUTTER_API_VERSION@_gir_SCANNERFLAGS = \
--warn-all \
--c-include='clutter/x11/clutter-x11.h' \
--pkg-export=mutter-clutter-x11-@LIBMUTTER_API_VERSION@ \
--include-uninstalled=$(top_builddir)/clutter/Clutter-@LIBMUTTER_API_VERSION@.gir
INTROSPECTION_GIRS += ClutterX11-@LIBMUTTER_API_VERSION@.gir
# INTROSPECTION_GIRDIR/INTROSPECTION_TYPELIBDIR aren't the right place to
# install anything - we need to install inside our prefix.
girdir = $(mutterlibdir)
gir_DATA = $(INTROSPECTION_GIRS)
typelibdir = $(mutterlibdir)
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
EXTRA_DIST += \
Makefile.am.marshal \
Makefile.am.enums
CLEANFILES += $(gir_DATA) $(typelib_DATA)

View File

@ -0,0 +1,52 @@
# Rules for generating enumeration types using glib-mkenums
#
# Define:
# glib_enum_h = header template file
# glib_enum_c = source template file
# glib_enum_headers = list of headers to parse
#
# before including Makefile.am.enums. You will also need to have
# the following targets already defined:
#
# CLEANFILES
# DISTCLEANFILES
# BUILT_SOURCES
# EXTRA_DIST
#
# Author: Emmanuele Bassi <ebassi@linux.intel.com>
# Basic sanity checks
$(if $(GLIB_MKENUMS),,$(error Need to define GLIB_MKENUMS))
$(if $(or $(glib_enum_h), \
$(glib_enum_c)),, \
$(error Need to define glib_enum_h and glib_enum_c))
$(if $(glib_enum_headers),,$(error Need to define glib_enum_headers))
enum_tmpl_h=$(addprefix $(srcdir)/, $(glib_enum_h:.h=.h.in))
enum_tmpl_c=$(addprefix $(srcdir)/, $(glib_enum_c:.c=.c.in))
enum_headers=$(addprefix $(srcdir)/, $(glib_enum_headers))
CLEANFILES += stamp-enum-types
DISTCLEANFILES += $(glib_enum_h) $(glib_enum_c)
BUILT_SOURCES += $(glib_enum_h) $(glib_enum_c)
EXTRA_DIST += $(enum_tmpl_h) $(enum_tmpl_c)
stamp-enum-types: $(enum_headers) $(enum_tmpl_h)
$(AM_V_GEN)$(GLIB_MKENUMS) \
--template $(enum_tmpl_h) \
$(enum_headers) > xgen-eh \
&& (cmp -s xgen-eh $(glib_enum_h) || cp -f xgen-eh $(glib_enum_h)) \
&& rm -f xgen-eh \
&& echo timestamp > $(@F)
$(glib_enum_h): stamp-enum-types
@true
$(glib_enum_c): $(enum_headers) $(enum_tmpl_h) $(enum_tmpl_c)
$(AM_V_GEN)$(GLIB_MKENUMS) \
--template $(enum_tmpl_c) \
$(enum_headers) > xgen-ec \
&& cp -f xgen-ec $(glib_enum_c) \
&& rm -f xgen-ec

View File

@ -0,0 +1,54 @@
# Rules for generating marshal files using glib-genmarshal
#
# Define:
# glib_marshal_list = marshal list file
# glib_marshal_prefix = prefix for marshal functions
#
# before including Makefile.am.marshal. You will also need to have
# the following targets already defined:
#
# CLEANFILES
# DISTCLEANFILES
# BUILT_SOURCES
# EXTRA_DIST
#
# Author: Emmanuele Bassi <ebassi@linux.intel.com>
# Basic sanity checks
$(if $(GLIB_GENMARSHAL),,$(error Need to define GLIB_GENMARSHAL))
$(if $(or $(glib_marshal_list), \
$(glib_marshal_prefix)),, \
$(error Need to define glib_marshal_list and glib_marshal_prefix))
marshal_h = $(glib_marshal_list:.list=.h)
marshal_c = $(glib_marshal_list:.list=.c)
marshal_list = $(addprefix $(srcdir)/, $(glib_marshal_list))
CLEANFILES += stamp-marshal
DISTCLEANFILES += $(marshal_h) $(marshal_c)
BUILT_SOURCES += $(marshal_h) $(marshal_c)
EXTRA_DIST += $(marshal_list)
stamp-marshal: $(marshal_list)
$(AM_V_GEN)$(GLIB_GENMARSHAL) \
--prefix=$(glib_marshal_prefix) \
--header \
--valist-marshallers \
$(marshal_list) > xgen-mh \
&& (cmp -s xgen-mh $(marshal_h) || cp -f xgen-mh $(marshal_h)) \
&& rm -f xgen-mh \
&& echo timestamp > $(@F)
$(marshal_h): stamp-marshal
@true
$(marshal_c): $(marshal_h)
$(AM_V_GEN)$(GLIB_GENMARSHAL) \
--prefix=$(glib_marshal_prefix) \
--body \
--valist-marshallers \
--prototypes \
$(marshal_list) > xgen-mc \
&& (cmp -s xgen-mc $(marshal_c) || cp -f xgen-mc $(marshal_c)) \
&& rm -f xgen-mc

View File

@ -28,7 +28,7 @@
#include "cally-actor.h" #include "cally-actor.h"
/* /*
* Auxiliary define, in order to get the clutter actor from the AtkObject using * Auxiliar define, in order to get the clutter actor from the AtkObject using
* AtkGObject methods * AtkGObject methods
* *
*/ */

View File

@ -67,12 +67,16 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include <glib.h> #include <glib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include "clutter/clutter-actor-private.h" #ifdef CLUTTER_WINDOWING_X11
#include <clutter/x11/clutter-x11.h>
#endif
#include <math.h> #include <math.h>
@ -308,7 +312,11 @@ cally_actor_finalize (GObject *obj)
_cally_actor_clean_action_list (cally_actor); _cally_actor_clean_action_list (cally_actor);
g_clear_handle_id (&priv->action_idle_handler, g_source_remove); if (priv->action_idle_handler)
{
g_source_remove (priv->action_idle_handler);
priv->action_idle_handler = 0;
}
if (priv->action_queue) if (priv->action_queue)
{ {
@ -598,11 +606,10 @@ cally_actor_real_remove_actor (ClutterActor *container,
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0); g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0);
atk_parent = ATK_OBJECT (data); atk_parent = ATK_OBJECT (data);
atk_child = clutter_actor_get_accessible (actor);
if (clutter_actor_has_accessible (actor)) if (atk_child)
{ {
atk_child = clutter_actor_get_accessible (actor);
g_value_init (&values.old_value, G_TYPE_POINTER); g_value_init (&values.old_value, G_TYPE_POINTER);
g_value_set_pointer (&values.old_value, atk_parent); g_value_set_pointer (&values.old_value, atk_parent);
@ -652,7 +659,7 @@ cally_actor_get_extents (AtkComponent *component,
ClutterActor *actor = NULL; ClutterActor *actor = NULL;
gint top_level_x, top_level_y; gint top_level_x, top_level_y;
gfloat f_width, f_height; gfloat f_width, f_height;
graphene_point3d_t verts[4]; ClutterVertex verts[4];
ClutterActor *stage = NULL; ClutterActor *stage = NULL;
g_return_if_fail (CALLY_IS_ACTOR (component)); g_return_if_fail (CALLY_IS_ACTOR (component));
@ -732,7 +739,11 @@ cally_actor_grab_focus (AtkComponent *component)
* *
* This gets the top level origin, it is, the position of the stage in * 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 * 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 void
_cally_actor_get_top_level_origin (ClutterActor *actor, _cally_actor_get_top_level_origin (ClutterActor *actor,
@ -740,11 +751,54 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
gint *yp) gint *yp)
{ {
/* default values */ /* 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) if (xp)
*xp = 0; *xp = x;
if (yp) if (yp)
*yp = 0; *yp = y;
} }
/* AtkAction implementation */ /* AtkAction implementation */
@ -765,11 +819,10 @@ static gboolean
cally_actor_action_do_action (AtkAction *action, cally_actor_action_do_action (AtkAction *action,
gint index) gint index)
{ {
CallyActor *cally_actor = NULL; CallyActor *cally_actor = NULL;
AtkStateSet *set = NULL; AtkStateSet *set = NULL;
CallyActorPrivate *priv = NULL; CallyActorPrivate *priv = NULL;
CallyActorActionInfo *info = NULL; CallyActorActionInfo *info = NULL;
gboolean did_action = FALSE;
cally_actor = CALLY_ACTOR (action); cally_actor = CALLY_ACTOR (action);
priv = cally_actor->priv; priv = cally_actor->priv;
@ -777,19 +830,21 @@ cally_actor_action_do_action (AtkAction *action,
set = atk_object_ref_state_set (ATK_OBJECT (cally_actor)); set = atk_object_ref_state_set (ATK_OBJECT (cally_actor));
if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT)) if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT))
goto out; return FALSE;
if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) || if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) ||
!atk_state_set_contains_state (set, ATK_STATE_SHOWING)) !atk_state_set_contains_state (set, ATK_STATE_SHOWING))
goto out; return FALSE;
g_object_unref (set);
info = _cally_actor_get_action_info (cally_actor, index); info = _cally_actor_get_action_info (cally_actor, index);
if (info == NULL) if (info == NULL)
goto out; return FALSE;
if (info->do_action_func == NULL) if (info->do_action_func == NULL)
goto out; return FALSE;
if (!priv->action_queue) if (!priv->action_queue)
priv->action_queue = g_queue_new (); priv->action_queue = g_queue_new ();
@ -799,12 +854,7 @@ cally_actor_action_do_action (AtkAction *action,
if (!priv->action_idle_handler) if (!priv->action_idle_handler)
priv->action_idle_handler = g_idle_add (idle_do_action, cally_actor); priv->action_idle_handler = g_idle_add (idle_do_action, cally_actor);
did_action = TRUE; return TRUE;
out:
g_clear_object (&set);
return did_action;
} }
static gboolean static gboolean
@ -970,7 +1020,7 @@ cally_actor_real_notify_clutter (GObject *obj,
* paint it; we don't want this to generate an ATK * paint it; we don't want this to generate an ATK
* state change * state change
*/ */
if (clutter_actor_is_painting_unmapped (actor)) if (clutter_actor_is_in_clone_paint (actor))
return; return;
state = ATK_STATE_SHOWING; state = ATK_STATE_SHOWING;
@ -996,8 +1046,10 @@ _cally_actor_clean_action_list (CallyActor *cally_actor)
if (priv->action_list) if (priv->action_list)
{ {
g_list_free_full (priv->action_list, g_list_foreach (priv->action_list,
(GDestroyNotify) _cally_actor_destroy_action_info); (GFunc) _cally_actor_destroy_action_info,
NULL);
g_list_free (priv->action_list);
priv->action_list = NULL; priv->action_list = NULL;
} }
} }
@ -1086,7 +1138,7 @@ cally_actor_add_action_full (CallyActor *cally_actor,
priv = cally_actor->priv; priv = cally_actor->priv;
info = g_new0 (CallyActorActionInfo, 1); info = g_slice_new (CallyActorActionInfo);
info->name = g_strdup (action_name); info->name = g_strdup (action_name);
info->description = g_strdup (action_description); info->description = g_strdup (action_description);
info->keybinding = g_strdup (action_keybinding); info->keybinding = g_strdup (action_keybinding);
@ -1106,7 +1158,7 @@ cally_actor_add_action_full (CallyActor *cally_actor,
* *
* Removes a action, using the @action_id returned by cally_actor_add_action() * Removes a action, using the @action_id returned by cally_actor_add_action()
* *
* Return value: %TRUE if the operation was successful, %FALSE otherwise * Return value: %TRUE if the operation was succesful, %FALSE otherwise
* *
* Since: 1.4 * Since: 1.4
*/ */
@ -1140,7 +1192,7 @@ cally_actor_remove_action (CallyActor *cally_actor,
* Removes an action, using the @action_name used when the action was added * Removes an action, using the @action_name used when the action was added
* with cally_actor_add_action() * with cally_actor_add_action()
* *
* Return value: %TRUE if the operation was successful, %FALSE otherwise * Return value: %TRUE if the operation was succesful, %FALSE otherwise
* *
* Since: 1.4 * Since: 1.4
*/ */
@ -1191,5 +1243,5 @@ _cally_actor_destroy_action_info (gpointer action_info,
if (info->notify) if (info->notify)
info->notify (info->user_data); info->notify (info->user_data);
g_free (info); g_slice_free (CallyActorActionInfo, info);
} }

View File

@ -126,19 +126,19 @@ struct _CallyActorClass
gpointer _padding_dummy[32]; gpointer _padding_dummy[32];
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType cally_actor_get_type (void) G_GNUC_CONST; GType cally_actor_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
AtkObject* cally_actor_new (ClutterActor *actor); AtkObject* cally_actor_new (ClutterActor *actor);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
guint cally_actor_add_action (CallyActor *cally_actor, guint cally_actor_add_action (CallyActor *cally_actor,
const gchar *action_name, const gchar *action_name,
const gchar *action_description, const gchar *action_description,
const gchar *action_keybinding, const gchar *action_keybinding,
CallyActionFunc action_func); CallyActionFunc action_func);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_6
guint cally_actor_add_action_full (CallyActor *cally_actor, guint cally_actor_add_action_full (CallyActor *cally_actor,
const gchar *action_name, const gchar *action_name,
const gchar *action_description, const gchar *action_description,
@ -147,11 +147,11 @@ guint cally_actor_add_action_full (CallyActor *cally_actor,
gpointer user_data, gpointer user_data,
GDestroyNotify notify); GDestroyNotify notify);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
gboolean cally_actor_remove_action (CallyActor *cally_actor, gboolean cally_actor_remove_action (CallyActor *cally_actor,
gint action_id); gint action_id);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
gboolean cally_actor_remove_action_by_name (CallyActor *cally_actor, gboolean cally_actor_remove_action_by_name (CallyActor *cally_actor,
const gchar *action_name); const gchar *action_name);

View File

@ -74,9 +74,9 @@ struct _CallyCloneClass
gpointer _padding_dummy[8]; gpointer _padding_dummy[8];
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType cally_clone_get_type (void) G_GNUC_CONST; GType cally_clone_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
AtkObject *cally_clone_new (ClutterActor *actor); AtkObject *cally_clone_new (ClutterActor *actor);
G_END_DECLS G_END_DECLS

View File

@ -0,0 +1,147 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* Based on GailContainer from GAIL
* Copyright 2001, 2002, 2003 Sun Microsystems 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, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally-group
* @Title: CallyGroup
* @short_description: Implementation of the ATK interfaces for a #ClutterGroup
* @see_also: #ClutterGroup
*
* #CallyGroup implements the required ATK interfaces of #ClutterGroup
* In particular it exposes each of the Clutter actors contained in the
* group.
*/
#include "clutter-build-config.h"
#include "cally-group.h"
#include "cally-actor-private.h"
static gint cally_group_get_n_children (AtkObject *obj);
static AtkObject* cally_group_ref_child (AtkObject *obj,
gint i);
static void cally_group_real_initialize (AtkObject *obj,
gpointer data);
G_DEFINE_TYPE (CallyGroup, cally_group, CALLY_TYPE_ACTOR)
static void
cally_group_class_init (CallyGroupClass *klass)
{
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
class->get_n_children = cally_group_get_n_children;
class->ref_child = cally_group_ref_child;
class->initialize = cally_group_real_initialize;
}
static void
cally_group_init (CallyGroup *group)
{
/* nothing to do yet */
}
/**
* cally_group_new:
* @actor: a #ClutterGroup
*
* Creates a #CallyGroup for @actor
*
* Return value: the newly created #CallyGroup
*
* Since: 1.4
*/
AtkObject *
cally_group_new (ClutterActor *actor)
{
GObject *object = NULL;
AtkObject *accessible = NULL;
g_return_val_if_fail (CLUTTER_IS_GROUP (actor), NULL);
object = g_object_new (CALLY_TYPE_GROUP, NULL);
accessible = ATK_OBJECT (object);
atk_object_initialize (accessible, actor);
return accessible;
}
static gint
cally_group_get_n_children (AtkObject *obj)
{
ClutterActor *actor = NULL;
gint count = 0;
g_return_val_if_fail (CALLY_IS_GROUP (obj), count);
actor = CALLY_GET_CLUTTER_ACTOR (obj);
if (actor == NULL) /* defunct */
return 0;
g_return_val_if_fail (CLUTTER_IS_GROUP(actor), count);
count = clutter_actor_get_n_children (actor);
return count;
}
static AtkObject*
cally_group_ref_child (AtkObject *obj,
gint i)
{
AtkObject *accessible = NULL;
ClutterActor *actor = NULL;
ClutterActor *child = NULL;
g_return_val_if_fail (CALLY_IS_GROUP (obj), NULL);
g_return_val_if_fail ((i >= 0), NULL);
actor = CALLY_GET_CLUTTER_ACTOR (obj);
g_return_val_if_fail (CLUTTER_IS_GROUP(actor), NULL);
child = clutter_actor_get_child_at_index (actor, i);
if (!child)
return NULL;
accessible = clutter_actor_get_accessible (child);
if (accessible != NULL)
g_object_ref (accessible);
return accessible;
}
static void
cally_group_real_initialize (AtkObject *obj,
gpointer data)
{
ATK_OBJECT_CLASS (cally_group_parent_class)->initialize (obj, data);
obj->role = ATK_ROLE_PANEL;
}

View File

@ -0,0 +1,87 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* Based on GailContainer from GAIL
* Copyright 2001, 2002, 2003 Sun Microsystems 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 __CALLY_GROUP_H__
#define __CALLY_GROUP_H__
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cally/cally.h> can be included directly."
#endif
#include <cally/cally-actor.h>
#include <clutter/clutter.h>
G_BEGIN_DECLS
#define CALLY_TYPE_GROUP (cally_group_get_type ())
#define CALLY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_GROUP, CallyGroup))
#define CALLY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_GROUP, CallyGroupClass))
#define CALLY_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_GROUP))
#define CALLY_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_GROUP))
#define CALLY_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_GROUP, CallyGroupClass))
typedef struct _CallyGroup CallyGroup;
typedef struct _CallyGroupClass CallyGroupClass;
typedef struct _CallyGroupPrivate CallyGroupPrivate;
/**
* CallyGroup:
*
* The <structname>CallyGroup</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyGroup
{
/*< private >*/
CallyActor parent;
CallyGroupPrivate *priv;
};
/**
* CallyGroupClass:
*
* The <structname>CallyGroupClass</structname> structure contains only
* private data
*
* Since: 1.4
*/
struct _CallyGroupClass
{
/*< private >*/
CallyActorClass parent_class;
/* padding for future expansion */
gpointer _padding_dummy[8];
};
CLUTTER_AVAILABLE_IN_1_4
GType cally_group_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
AtkObject* cally_group_new (ClutterActor *actor);
G_END_DECLS
#endif /* __CALLY_GROUP_H__ */

View File

@ -34,9 +34,9 @@
G_BEGIN_DECLS G_BEGIN_DECLS
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
gboolean cally_get_cally_initialized (void); gboolean cally_get_cally_initialized (void);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
gboolean cally_accessibility_init (void); gboolean cally_accessibility_init (void);
G_END_DECLS G_END_DECLS

View File

@ -0,0 +1,98 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2009 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* 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, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally-rectangle
* @short_description: Implementation of the ATK interfaces for a #ClutterRectangle
* @see_also: #ClutterRectangle
*
* #CallyRectangle implements the required ATK interfaces of #ClutterRectangle
*
* In particular it sets a proper role for the rectangle.
*/
#include "clutter-build-config.h"
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "cally-rectangle.h"
#include "cally-actor-private.h"
#include "clutter-color.h"
#include "deprecated/clutter-rectangle.h"
/* AtkObject */
static void cally_rectangle_real_initialize (AtkObject *obj,
gpointer data);
G_DEFINE_TYPE (CallyRectangle, cally_rectangle, CALLY_TYPE_ACTOR)
static void
cally_rectangle_class_init (CallyRectangleClass *klass)
{
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
class->initialize = cally_rectangle_real_initialize;
}
static void
cally_rectangle_init (CallyRectangle *rectangle)
{
/* nothing to do yet */
}
/**
* cally_rectangle_new:
* @actor: a #ClutterActor
*
* Creates a new #CallyRectangle for the given @actor. @actor must be
* a #ClutterRectangle.
*
* Return value: the newly created #AtkObject
*
* Since: 1.4
*/
AtkObject*
cally_rectangle_new (ClutterActor *actor)
{
GObject *object = NULL;
AtkObject *accessible = NULL;
g_return_val_if_fail (CLUTTER_IS_RECTANGLE (actor), NULL);
object = g_object_new (CALLY_TYPE_RECTANGLE, NULL);
accessible = ATK_OBJECT (object);
atk_object_initialize (accessible, actor);
return accessible;
}
static void
cally_rectangle_real_initialize (AtkObject *obj,
gpointer data)
{
ATK_OBJECT_CLASS (cally_rectangle_parent_class)->initialize (obj, data);
obj->role = ATK_ROLE_IMAGE;
}

View File

@ -0,0 +1,84 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2009 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* 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 __CALLY_RECTANGLE_H__
#define __CALLY_RECTANGLE_H__
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cally/cally.h> can be included directly."
#endif
#include <cally/cally-actor.h>
#include <clutter/clutter.h>
G_BEGIN_DECLS
#define CALLY_TYPE_RECTANGLE (cally_rectangle_get_type ())
#define CALLY_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_RECTANGLE, CallyRectangle))
#define CALLY_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_RECTANGLE, CallyRectangleClass))
#define CALLY_IS_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_RECTANGLE))
#define CALLY_IS_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_RECTANGLE))
#define CALLY_RECTANGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_RECTANGLE, CallyRectangleClass))
typedef struct _CallyRectangle CallyRectangle;
typedef struct _CallyRectangleClass CallyRectangleClass;
typedef struct _CallyRectanglePrivate CallyRectanglePrivate;
/**
* CallyRectangle:
*
* The <structname>CallyRectangle</structname> structure contains only private
* data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyRectangle
{
/*< private >*/
CallyActor parent;
CallyRectanglePrivate *priv;
};
/**
* CallyRectangleClass:
*
* The <structname>CallyRectangleClass</structname> structure contains
* only private data
*
* Since: 1.4
*/
struct _CallyRectangleClass
{
/*< private >*/
CallyActorClass parent_class;
/* padding for future expansion */
gpointer _padding_dummy[8];
};
CLUTTER_AVAILABLE_IN_1_4
GType cally_rectangle_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
AtkObject* cally_rectangle_new (ClutterActor *actor);
G_END_DECLS
#endif /* __CALLY_RECTANGLE_H__ */

View File

@ -75,8 +75,8 @@ struct _CallyRootPrivate
GSList *stage_list; GSList *stage_list;
/* signals id */ /* signals id */
gulong stage_added_id; guint stage_added_id;
gulong stage_removed_id; guint stage_removed_id;
}; };
G_DEFINE_TYPE_WITH_PRIVATE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE) G_DEFINE_TYPE_WITH_PRIVATE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE)
@ -149,9 +149,11 @@ cally_root_finalize (GObject *object)
stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root)); stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root));
g_clear_signal_handler (&root->priv->stage_added_id, stage_manager); g_signal_handler_disconnect (stage_manager,
root->priv->stage_added_id);
g_clear_signal_handler (&root->priv->stage_removed_id, stage_manager); g_signal_handler_disconnect (stage_manager,
root->priv->stage_added_id);
G_OBJECT_CLASS (cally_root_parent_class)->finalize (object); G_OBJECT_CLASS (cally_root_parent_class)->finalize (object);
} }

View File

@ -74,9 +74,9 @@ struct _CallyRootClass
gpointer _padding_dummy[16]; gpointer _padding_dummy[16];
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType cally_root_get_type (void) G_GNUC_CONST; GType cally_root_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
AtkObject *cally_root_new (void); AtkObject *cally_root_new (void);
G_END_DECLS G_END_DECLS

View File

@ -47,7 +47,7 @@ static AtkStateSet* cally_stage_ref_state_set (AtkObject *obj);
/* AtkWindow */ /* AtkWindow */
static void cally_stage_window_interface_init (AtkWindowIface *iface); static void cally_stage_window_interface_init (AtkWindowIface *iface);
/* Auxiliary */ /* Auxiliar */
static void cally_stage_activate_cb (ClutterStage *stage, static void cally_stage_activate_cb (ClutterStage *stage,
gpointer data); gpointer data);
static void cally_stage_deactivate_cb (ClutterStage *stage, static void cally_stage_deactivate_cb (ClutterStage *stage,
@ -63,7 +63,7 @@ struct _CallyStagePrivate
G_DEFINE_TYPE_WITH_CODE (CallyStage, G_DEFINE_TYPE_WITH_CODE (CallyStage,
cally_stage, cally_stage,
CALLY_TYPE_ACTOR, CALLY_TYPE_GROUP,
G_ADD_PRIVATE (CallyStage) G_ADD_PRIVATE (CallyStage)
G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW, G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW,
cally_stage_window_interface_init)); cally_stage_window_interface_init));
@ -134,11 +134,8 @@ cally_stage_notify_key_focus_cb (ClutterStage *stage,
if (self->priv->key_focus != NULL) if (self->priv->key_focus != NULL)
{ {
if (self->priv->key_focus != CLUTTER_ACTOR (stage)) g_object_remove_weak_pointer (G_OBJECT (self->priv->key_focus),
{ (gpointer *) &self->priv->key_focus);
g_object_remove_weak_pointer (G_OBJECT (self->priv->key_focus),
(gpointer *) &self->priv->key_focus);
}
old = clutter_actor_get_accessible (self->priv->key_focus); old = clutter_actor_get_accessible (self->priv->key_focus);
} }
else else
@ -163,11 +160,8 @@ cally_stage_notify_key_focus_cb (ClutterStage *stage,
* *
* we remove the weak pointer above. * we remove the weak pointer above.
*/ */
if (key_focus != CLUTTER_ACTOR (stage)) g_object_add_weak_pointer (G_OBJECT (self->priv->key_focus),
{ (gpointer *) &self->priv->key_focus);
g_object_add_weak_pointer (G_OBJECT (self->priv->key_focus),
(gpointer *) &self->priv->key_focus);
}
new = clutter_actor_get_accessible (key_focus); new = clutter_actor_get_accessible (key_focus);
} }
@ -228,7 +222,7 @@ cally_stage_window_interface_init (AtkWindowIface *iface)
/* At this moment AtkWindow is just about signals */ /* At this moment AtkWindow is just about signals */
} }
/* Auxiliary */ /* Auxiliar */
static void static void
cally_stage_activate_cb (ClutterStage *stage, cally_stage_activate_cb (ClutterStage *stage,
gpointer data) gpointer data)

View File

@ -25,7 +25,7 @@
#error "Only <cally/cally.h> can be included directly." #error "Only <cally/cally.h> can be included directly."
#endif #endif
#include <cally/cally-actor.h> #include <cally/cally-group.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -52,7 +52,7 @@ typedef struct _CallyStagePrivate CallyStagePrivate;
struct _CallyStage struct _CallyStage
{ {
/*< private >*/ /*< private >*/
CallyActor parent; CallyGroup parent;
CallyStagePrivate *priv; CallyStagePrivate *priv;
}; };
@ -68,15 +68,15 @@ struct _CallyStage
struct _CallyStageClass struct _CallyStageClass
{ {
/*< private >*/ /*< private >*/
CallyActorClass parent_class; CallyGroupClass parent_class;
/* padding for future expansion */ /* padding for future expansion */
gpointer _padding_dummy[16]; gpointer _padding_dummy[16];
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType cally_stage_get_type (void) G_GNUC_CONST; GType cally_stage_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
AtkObject *cally_stage_new (ClutterActor *actor); AtkObject *cally_stage_new (ClutterActor *actor);
G_END_DECLS G_END_DECLS

View File

@ -39,7 +39,9 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include "cally-text.h" #include "cally-text.h"
#include "cally-actor-private.h" #include "cally-actor-private.h"
@ -247,7 +249,11 @@ cally_text_finalize (GObject *obj)
/* g_object_unref (cally_text->priv->textutil); */ /* g_object_unref (cally_text->priv->textutil); */
/* cally_text->priv->textutil = NULL; */ /* cally_text->priv->textutil = NULL; */
g_clear_handle_id (&cally_text->priv->insert_idle_handler, g_source_remove); if (cally_text->priv->insert_idle_handler)
{
g_source_remove (cally_text->priv->insert_idle_handler);
cally_text->priv->insert_idle_handler = 0;
}
G_OBJECT_CLASS (cally_text_parent_class)->finalize (obj); G_OBJECT_CLASS (cally_text_parent_class)->finalize (obj);
} }
@ -1434,7 +1440,7 @@ static void cally_text_get_character_extents (AtkText *text,
PangoLayout *layout; PangoLayout *layout;
PangoRectangle extents; PangoRectangle extents;
const gchar *text_value; const gchar *text_value;
graphene_point3d_t verts[4]; ClutterVertex verts[4];
actor = CALLY_GET_CLUTTER_ACTOR (text); actor = CALLY_GET_CLUTTER_ACTOR (text);
if (actor == NULL) /* State is defunct */ if (actor == NULL) /* State is defunct */
@ -1513,7 +1519,7 @@ cally_text_get_offset_at_point (AtkText *text,
} }
/******** Auxiliary private methods ******/ /******** Auxiliar private methods ******/
/* ClutterText only maintains the current cursor position and a extra selection /* ClutterText only maintains the current cursor position and a extra selection
bound, but this could be before or after the cursor. This method returns bound, but this could be before or after the cursor. This method returns
@ -1552,7 +1558,7 @@ _cally_text_delete_text_cb (ClutterText *clutter_text,
g_return_if_fail (CALLY_IS_TEXT (data)); g_return_if_fail (CALLY_IS_TEXT (data));
/* Ignore zero length deletions */ /* Ignore zero lengh deletions */
if (end_pos - start_pos == 0) if (end_pos - start_pos == 0)
return; return;
@ -1653,7 +1659,7 @@ cally_text_insert_text (AtkEditableText *text,
clutter_text_insert_text (CLUTTER_TEXT (actor), clutter_text_insert_text (CLUTTER_TEXT (actor),
string, *position); string, *position);
/* we suppose that the text insertion will be successful, /* we suppose that the text insertion will be succesful,
clutter-text doesn't warn about it. A option would be search for clutter-text doesn't warn about it. A option would be search for
the text, but it seems not really required */ the text, but it seems not really required */
*position += length; *position += length;
@ -1866,7 +1872,7 @@ static gint
_cally_atk_attribute_lookup_func (gconstpointer data, _cally_atk_attribute_lookup_func (gconstpointer data,
gconstpointer user_data) gconstpointer user_data)
{ {
AtkTextAttribute attr = (AtkTextAttribute) GPOINTER_TO_INT (user_data); AtkTextAttribute attr = (AtkTextAttribute) user_data;
AtkAttribute *at = (AtkAttribute *) data; AtkAttribute *at = (AtkAttribute *) data;
if (!g_strcmp0 (at->name, atk_text_attribute_get_name (attr))) if (!g_strcmp0 (at->name, atk_text_attribute_get_name (attr)))
return 0; return 0;
@ -2290,7 +2296,7 @@ _cally_misc_get_index_at_point (ClutterText *clutter_text,
gint index, x_window, y_window, x_toplevel, y_toplevel; gint index, x_window, y_window, x_toplevel, y_toplevel;
gint x_temp, y_temp; gint x_temp, y_temp;
gboolean ret; gboolean ret;
graphene_point3d_t verts[4]; ClutterVertex verts[4];
PangoLayout *layout; PangoLayout *layout;
gint x_layout, y_layout; gint x_layout, y_layout;

View File

@ -74,9 +74,9 @@ struct _CallyTextClass
gpointer _padding_dummy[8]; gpointer _padding_dummy[8];
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType cally_text_get_type (void) G_GNUC_CONST; GType cally_text_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
AtkObject* cally_text_new (ClutterActor *actor); AtkObject* cally_text_new (ClutterActor *actor);
G_END_DECLS G_END_DECLS

View File

@ -0,0 +1,98 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2009 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* 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, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally-texture
* @Title: CallyTexture
* @short_description: Implementation of the ATK interfaces for a #ClutterTexture
* @see_also: #ClutterTexture
*
* #CallyTexture implements the required ATK interfaces of #ClutterTexture
*
* In particular it sets a proper role for the texture.
*/
#include "clutter-build-config.h"
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "cally-texture.h"
#include "cally-actor-private.h"
#include "deprecated/clutter-texture.h"
/* AtkObject */
static void cally_texture_real_initialize (AtkObject *obj,
gpointer data);
G_DEFINE_TYPE (CallyTexture, cally_texture, CALLY_TYPE_ACTOR)
static void
cally_texture_class_init (CallyTextureClass *klass)
{
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
class->initialize = cally_texture_real_initialize;
}
static void
cally_texture_init (CallyTexture *texture)
{
/* nothing to do yet */
}
/**
* cally_texture_new:
* @actor: a #ClutterActor
*
* Creates a new #CallyTexture for the given @actor. @actor must be
* a #ClutterTexture.
*
* Return value: the newly created #AtkObject
*
* Since: 1.4
*/
AtkObject*
cally_texture_new (ClutterActor *actor)
{
GObject *object = NULL;
AtkObject *accessible = NULL;
g_return_val_if_fail (CLUTTER_IS_TEXTURE (actor), NULL);
object = g_object_new (CALLY_TYPE_TEXTURE, NULL);
accessible = ATK_OBJECT (object);
atk_object_initialize (accessible, actor);
return accessible;
}
static void
cally_texture_real_initialize (AtkObject *obj,
gpointer data)
{
ATK_OBJECT_CLASS (cally_texture_parent_class)->initialize (obj, data);
/* default role */
obj->role = ATK_ROLE_IMAGE;
}

View File

@ -0,0 +1,84 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2009 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* 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 __CALLY_TEXTURE_H__
#define __CALLY_TEXTURE_H__
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cally/cally.h> can be included directly."
#endif
#include <clutter/clutter.h>
#include <cally/cally-actor.h>
G_BEGIN_DECLS
#define CALLY_TYPE_TEXTURE (cally_texture_get_type ())
#define CALLY_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_TEXTURE, CallyTexture))
#define CALLY_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_TEXTURE, CallyTextureClass))
#define CALLY_IS_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_TEXTURE))
#define CALLY_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_TEXTURE))
#define CALLY_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_TEXTURE, CallyTextureClass))
typedef struct _CallyTexture CallyTexture;
typedef struct _CallyTextureClass CallyTextureClass;
typedef struct _CallyTexturePrivate CallyTexturePrivate;
/**
* CallyTexture:
*
* The <structname>CallyTexture</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyTexture
{
/*< private >*/
CallyActor parent;
CallyTexturePrivate *priv;
};
/**
* CallyTextureClass:
*
* The <structname>CallyTextureClass</structname> structure contains
* only private data
*
* Since: 1.4
*/
struct _CallyTextureClass
{
/*< private >*/
CallyActorClass parent_class;
/* padding for future expansion */
gpointer _padding_dummy[8];
};
CLUTTER_AVAILABLE_IN_1_4
GType cally_texture_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
AtkObject *cally_texture_new (ClutterActor *actor);
G_END_DECLS
#endif /* __CALLY_TEXTURE_H__ */

View File

@ -38,7 +38,9 @@
* available any accessible object. * available any accessible object.
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -142,7 +144,7 @@ cally_util_get_toolkit_name (void)
static const gchar * static const gchar *
cally_util_get_toolkit_version (void) cally_util_get_toolkit_version (void)
{ {
return MUTTER_VERSION; return CLUTTER_VERSION_S;
} }
static guint static guint
@ -212,8 +214,6 @@ cally_util_simulate_snooper_install (void)
G_CALLBACK (cally_util_stage_added_cb), cally_key_snooper); G_CALLBACK (cally_util_stage_added_cb), cally_key_snooper);
g_signal_connect (G_OBJECT (stage_manager), "stage-removed", g_signal_connect (G_OBJECT (stage_manager), "stage-removed",
G_CALLBACK (cally_util_stage_removed_cb), cally_key_snooper); G_CALLBACK (cally_util_stage_removed_cb), cally_key_snooper);
g_slist_free (stage_list);
} }
static void static void

View File

@ -74,7 +74,7 @@ struct _CallyUtilClass
gpointer _padding_dummy[8]; gpointer _padding_dummy[8];
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType cally_util_get_type (void) G_GNUC_CONST; GType cally_util_get_type (void) G_GNUC_CONST;
void _cally_util_override_atk_util (void); void _cally_util_override_atk_util (void);

View File

@ -29,15 +29,20 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS #define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "cally.h" #include "cally.h"
#include "cally-actor.h" #include "cally-actor.h"
#include "cally-group.h"
#include "cally-stage.h" #include "cally-stage.h"
#include "cally-text.h" #include "cally-text.h"
#include "cally-texture.h"
#include "cally-rectangle.h"
#include "cally-clone.h" #include "cally-clone.h"
#include "cally-factory.h" #include "cally-factory.h"
@ -50,8 +55,11 @@
/* factories initialization*/ /* factories initialization*/
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_GROUP, cally_group, cally_group_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXTURE, cally_texture, cally_texture_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_RECTANGLE, cally_rectangle, cally_rectangle_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new)
/** /**
@ -69,8 +77,11 @@ cally_accessibility_init (void)
{ {
/* setting the factories */ /* setting the factories */
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_GROUP, cally_group);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXTURE, cally_texture);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_RECTANGLE, cally_rectangle);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone);
/* Initialize the CallyUtility class */ /* Initialize the CallyUtility class */

View File

@ -26,10 +26,13 @@
#include "cally-actor.h" #include "cally-actor.h"
#include "cally-clone.h" #include "cally-clone.h"
#include "cally-factory.h" #include "cally-factory.h"
#include "cally-group.h"
#include "cally-main.h" #include "cally-main.h"
#include "cally-rectangle.h"
#include "cally-root.h" #include "cally-root.h"
#include "cally-stage.h" #include "cally-stage.h"
#include "cally-text.h" #include "cally-text.h"
#include "cally-texture.h"
#include "cally-util.h" #include "cally-util.h"
#undef __CALLY_H_INSIDE__ #undef __CALLY_H_INSIDE__

View File

@ -41,7 +41,9 @@
* #ClutterAction is available since Clutter 1.4 * #ClutterAction is available since Clutter 1.4
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include "clutter-action.h" #include "clutter-action.h"

View File

@ -33,11 +33,28 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_ACTION (clutter_action_get_type ()) #define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
#define CLUTTER_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTION, ClutterAction))
#define CLUTTER_IS_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTION))
#define CLUTTER_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTION, ClutterActionClass))
#define CLUTTER_IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTION))
#define CLUTTER_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTION, ClutterActionClass))
CLUTTER_EXPORT typedef struct _ClutterActionClass ClutterActionClass;
G_DECLARE_DERIVABLE_TYPE (ClutterAction, clutter_action,
CLUTTER, ACTION, ClutterActorMeta); /**
* ClutterAction:
*
* The #ClutterAction structure contains only private data and
* should be accessed using the provided API.
*
* Since: 1.4
*/
struct _ClutterAction
{
/*< private >*/
ClutterActorMeta parent_instance;
};
/** /**
* ClutterActionClass: * ClutterActionClass:
@ -61,29 +78,32 @@ struct _ClutterActionClass
void (* _clutter_action8) (void); void (* _clutter_action8) (void);
}; };
CLUTTER_AVAILABLE_IN_1_4
GType clutter_action_get_type (void) G_GNUC_CONST;
/* ClutterActor API */ /* ClutterActor API */
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_add_action (ClutterActor *self, void clutter_actor_add_action (ClutterActor *self,
ClutterAction *action); ClutterAction *action);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_add_action_with_name (ClutterActor *self, void clutter_actor_add_action_with_name (ClutterActor *self,
const gchar *name, const gchar *name,
ClutterAction *action); ClutterAction *action);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_remove_action (ClutterActor *self, void clutter_actor_remove_action (ClutterActor *self,
ClutterAction *action); ClutterAction *action);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_remove_action_by_name (ClutterActor *self, void clutter_actor_remove_action_by_name (ClutterActor *self,
const gchar *name); const gchar *name);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterAction *clutter_actor_get_action (ClutterActor *self, ClutterAction *clutter_actor_get_action (ClutterActor *self,
const gchar *name); const gchar *name);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GList * clutter_actor_get_actions (ClutterActor *self); GList * clutter_actor_get_actions (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_clear_actions (ClutterActor *self); void clutter_actor_clear_actions (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
gboolean clutter_actor_has_actions (ClutterActor *self); gboolean clutter_actor_has_actions (ClutterActor *self);
G_END_DECLS G_END_DECLS

View File

@ -1,12 +0,0 @@
#ifndef __CLUTTER_ACTOR_BOX_PRIVATE_H__
#define __CLUTTER_ACTOR_BOX_PRIVATE_H__
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
void _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box);
G_END_DECLS
#endif /* __CLUTTER_ACTOR_BOX_PRIVATE_H__ */

View File

@ -1,11 +1,12 @@
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include <math.h> #include <math.h>
#include "clutter-types.h" #include "clutter-types.h"
#include "clutter-interval.h" #include "clutter-interval.h"
#include "clutter-private.h" #include "clutter-private.h"
#include "clutter-actor-box-private.h"
/** /**
* clutter_actor_box_new: * clutter_actor_box_new:
@ -54,7 +55,7 @@ clutter_actor_box_new (gfloat x_1,
ClutterActorBox * ClutterActorBox *
clutter_actor_box_alloc (void) clutter_actor_box_alloc (void)
{ {
return g_new0 (ClutterActorBox, 1); return g_slice_new0 (ClutterActorBox);
} }
/** /**
@ -130,7 +131,7 @@ ClutterActorBox *
clutter_actor_box_copy (const ClutterActorBox *box) clutter_actor_box_copy (const ClutterActorBox *box)
{ {
if (G_LIKELY (box != NULL)) if (G_LIKELY (box != NULL))
return g_memdup2 (box, sizeof (ClutterActorBox)); return g_slice_dup (ClutterActorBox, box);
return NULL; return NULL;
} }
@ -148,7 +149,7 @@ void
clutter_actor_box_free (ClutterActorBox *box) clutter_actor_box_free (ClutterActorBox *box)
{ {
if (G_LIKELY (box != NULL)) if (G_LIKELY (box != NULL))
g_free (box); g_slice_free (ClutterActorBox, box);
} }
/** /**
@ -320,7 +321,7 @@ clutter_actor_box_get_area (const ClutterActorBox *box)
* @y: Y coordinate of the point * @y: Y coordinate of the point
* *
* Checks whether a point with @x, @y coordinates is contained * Checks whether a point with @x, @y coordinates is contained
* within @box * withing @box
* *
* Return value: %TRUE if the point is contained by the #ClutterActorBox * Return value: %TRUE if the point is contained by the #ClutterActorBox
* *
@ -340,7 +341,7 @@ clutter_actor_box_contains (const ClutterActorBox *box,
/** /**
* clutter_actor_box_from_vertices: * clutter_actor_box_from_vertices:
* @box: a #ClutterActorBox * @box: a #ClutterActorBox
* @verts: (array fixed-size=4): array of four #graphene_point3d_t * @verts: (array fixed-size=4): array of four #ClutterVertex
* *
* Calculates the bounding box represented by the four vertices; for details * Calculates the bounding box represented by the four vertices; for details
* of the vertex array see clutter_actor_get_abs_allocation_vertices(). * of the vertex array see clutter_actor_get_abs_allocation_vertices().
@ -348,8 +349,8 @@ clutter_actor_box_contains (const ClutterActorBox *box,
* Since: 1.0 * Since: 1.0
*/ */
void void
clutter_actor_box_from_vertices (ClutterActorBox *box, clutter_actor_box_from_vertices (ClutterActorBox *box,
const graphene_point3d_t verts[]) const ClutterVertex verts[])
{ {
gfloat x_1, x_2, y_1, y_2; gfloat x_1, x_2, y_1, y_2;
@ -543,104 +544,6 @@ clutter_actor_box_set_size (ClutterActorBox *box,
box->y2 = box->y1 + height; box->y2 = box->y1 + height;
} }
void
_clutter_actor_box_enlarge_for_effects (ClutterActorBox *box)
{
float width, height;
/* The aim here is that for a given rectangle defined with floating point
* coordinates we want to determine a stable quantized size in pixels
* that doesn't vary due to the original box's sub-pixel position.
*
* The reason this is important is because effects will use this
* API to determine the size of offscreen framebuffers and so for
* a fixed-size object that may be animated across the screen we
* want to make sure that the stage paint-box has an equally stable
* size so that effects aren't made to continuously re-allocate
* a corresponding fbo.
*
* The other thing we consider is that the calculation of this box is
* subject to floating point precision issues that might be slightly
* different to the precision issues involved with actually painting the
* actor, which might result in painting slightly leaking outside the
* user's calculated paint-volume. For this we simply aim to pad out the
* paint-volume by at least half a pixel all the way around.
*/
width = box->x2 - box->x1;
height = box->y2 - box->y1;
width = CLUTTER_NEARBYINT (width);
height = CLUTTER_NEARBYINT (height);
/* XXX: NB the width/height may now be up to 0.5px too small so we
* must also pad by 0.25px all around to account for this. In total we
* must padd by at least 0.75px around all sides. */
/* XXX: The furthest that we can overshoot the bottom right corner by
* here is 1.75px in total if you consider that the 0.75 padding could
* just cross an integer boundary and so ceil will effectively add 1.
*/
box->x2 = ceilf (box->x2 + 0.75);
box->y2 = ceilf (box->y2 + 0.75);
/* Now we redefine the top-left relative to the bottom right based on the
* rounded width/height determined above + a constant so that the overall
* size of the box will be stable and not dependent on the box's
* position.
*
* Adding 3px to the width/height will ensure we cover the maximum of
* 1.75px padding on the bottom/right and still ensure we have > 0.75px
* padding on the top/left.
*/
box->x1 = box->x2 - width - 3;
box->y1 = box->y2 - height - 3;
}
/**
* clutter_actor_box_scale:
* @box: a #ClutterActorBox
* @scale: scale factor for resizing this box
*
* Rescale the @box by provided @scale factor.
*
* Since: 1.6
*/
void
clutter_actor_box_scale (ClutterActorBox *box,
gfloat scale)
{
g_return_if_fail (box != NULL);
box->x1 *= scale;
box->x2 *= scale;
box->y1 *= scale;
box->y2 *= scale;
}
/**
* clutter_actor_box_is_initialized:
* @box: a #ClutterActorBox
*
* Checks if @box has been initialized, a #ClutterActorBox is uninitialized
* if it has a size of -1 at an origin of 0, 0.
*
* Returns: %TRUE if the box is uninitialized, %FALSE if it isn't
*/
gboolean
clutter_actor_box_is_initialized (ClutterActorBox *box)
{
gboolean x1_uninitialized, x2_uninitialized;
gboolean y1_uninitialized, y2_uninitialized;
g_return_val_if_fail (box != NULL, TRUE);
x1_uninitialized = isinf (box->x1);
x2_uninitialized = isinf (box->x2) && signbit (box->x2);
y1_uninitialized = isinf (box->y1);
y2_uninitialized = isinf (box->y2) && signbit (box->y2);
return !x1_uninitialized || !x2_uninitialized ||
!y1_uninitialized || !y2_uninitialized;
}
G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterActorBox, clutter_actor_box, G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterActorBox, clutter_actor_box,
clutter_actor_box_copy, clutter_actor_box_copy,
clutter_actor_box_free, clutter_actor_box_free,

View File

@ -41,7 +41,9 @@
* #ClutterActorMeta is available since Clutter 1.4 * #ClutterActorMeta is available since Clutter 1.4
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include "clutter-actor-meta-private.h" #include "clutter-actor-meta-private.h"
@ -51,7 +53,7 @@
struct _ClutterActorMetaPrivate struct _ClutterActorMetaPrivate
{ {
ClutterActor *actor; ClutterActor *actor;
gulong destroy_id; guint destroy_id;
gchar *name; gchar *name;
@ -81,49 +83,28 @@ static void
on_actor_destroy (ClutterActor *actor, on_actor_destroy (ClutterActor *actor,
ClutterActorMeta *meta) ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv = meta->priv->actor = NULL;
clutter_actor_meta_get_instance_private (meta);
priv->actor = NULL;
} }
static void static void
clutter_actor_meta_real_set_actor (ClutterActorMeta *meta, clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
ClutterActor *actor) ClutterActor *actor)
{ {
ClutterActorMetaPrivate *priv = if (meta->priv->actor == actor)
clutter_actor_meta_get_instance_private (meta);
g_warn_if_fail (!priv->actor ||
!CLUTTER_ACTOR_IN_PAINT (priv->actor));
g_warn_if_fail (!actor || !CLUTTER_ACTOR_IN_PAINT (actor));
if (priv->actor == actor)
return; return;
g_clear_signal_handler (&priv->destroy_id, priv->actor); if (meta->priv->destroy_id != 0)
{
g_signal_handler_disconnect (meta->priv->actor, meta->priv->destroy_id);
meta->priv->destroy_id = 0;
}
priv->actor = actor; meta->priv->actor = actor;
if (priv->actor != NULL) if (meta->priv->actor != NULL)
priv->destroy_id = g_signal_connect (priv->actor, "destroy", meta->priv->destroy_id = g_signal_connect (meta->priv->actor, "destroy",
G_CALLBACK (on_actor_destroy), G_CALLBACK (on_actor_destroy),
meta); meta);
}
static void
clutter_actor_meta_real_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled)
{
ClutterActorMetaPrivate *priv =
clutter_actor_meta_get_instance_private (meta);
g_warn_if_fail (!priv->actor ||
!CLUTTER_ACTOR_IN_PAINT (priv->actor));
priv->is_enabled = is_enabled;
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
} }
static void static void
@ -156,21 +137,20 @@ clutter_actor_meta_get_property (GObject *gobject,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
ClutterActorMetaPrivate *priv = ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
switch (prop_id) switch (prop_id)
{ {
case PROP_ACTOR: case PROP_ACTOR:
g_value_set_object (value, priv->actor); g_value_set_object (value, meta->priv->actor);
break; break;
case PROP_NAME: case PROP_NAME:
g_value_set_string (value, priv->name); g_value_set_string (value, meta->priv->name);
break; break;
case PROP_ENABLED: case PROP_ENABLED:
g_value_set_boolean (value, priv->is_enabled); g_value_set_boolean (value, meta->priv->is_enabled);
break; break;
default: default:
@ -182,11 +162,10 @@ clutter_actor_meta_get_property (GObject *gobject,
static void static void
clutter_actor_meta_finalize (GObject *gobject) clutter_actor_meta_finalize (GObject *gobject)
{ {
ClutterActorMetaPrivate *priv = ClutterActorMetaPrivate *priv = CLUTTER_ACTOR_META (gobject)->priv;
clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
if (priv->actor != NULL) if (priv->destroy_id != 0 && priv->actor != NULL)
g_clear_signal_handler (&priv->destroy_id, priv->actor); g_signal_handler_disconnect (priv->actor, priv->destroy_id);
g_free (priv->name); g_free (priv->name);
@ -199,7 +178,6 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
klass->set_actor = clutter_actor_meta_real_set_actor; klass->set_actor = clutter_actor_meta_real_set_actor;
klass->set_enabled = clutter_actor_meta_real_set_enabled;
/** /**
* ClutterActorMeta:actor: * ClutterActorMeta:actor:
@ -254,11 +232,9 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
void void
clutter_actor_meta_init (ClutterActorMeta *self) clutter_actor_meta_init (ClutterActorMeta *self)
{ {
ClutterActorMetaPrivate *priv = self->priv = clutter_actor_meta_get_instance_private (self);
clutter_actor_meta_get_instance_private (self); self->priv->is_enabled = TRUE;
self->priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
priv->is_enabled = TRUE;
priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
} }
/** /**
@ -276,17 +252,13 @@ void
clutter_actor_meta_set_name (ClutterActorMeta *meta, clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar *name) const gchar *name)
{ {
ClutterActorMetaPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
priv = clutter_actor_meta_get_instance_private (meta); if (g_strcmp0 (meta->priv->name, name) == 0)
if (g_strcmp0 (priv->name, name) == 0)
return; return;
g_free (priv->name); g_free (meta->priv->name);
priv->name = g_strdup (name); meta->priv->name = g_strdup (name);
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]); g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]);
} }
@ -307,13 +279,9 @@ clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar * const gchar *
clutter_actor_meta_get_name (ClutterActorMeta *meta) clutter_actor_meta_get_name (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL); g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
priv = clutter_actor_meta_get_instance_private (meta); return meta->priv->name;
return priv->name;
} }
/** /**
@ -329,17 +297,16 @@ void
clutter_actor_meta_set_enabled (ClutterActorMeta *meta, clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled) gboolean is_enabled)
{ {
ClutterActorMetaPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
priv = clutter_actor_meta_get_instance_private (meta);
is_enabled = !!is_enabled; is_enabled = !!is_enabled;
if (priv->is_enabled == is_enabled) if (meta->priv->is_enabled == is_enabled)
return; return;
CLUTTER_ACTOR_META_GET_CLASS (meta)->set_enabled (meta, is_enabled); meta->priv->is_enabled = is_enabled;
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
} }
/** /**
@ -355,13 +322,9 @@ clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
gboolean gboolean
clutter_actor_meta_get_enabled (ClutterActorMeta *meta) clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE); g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE);
priv = clutter_actor_meta_get_instance_private (meta); return meta->priv->is_enabled;
return priv->is_enabled;
} }
/* /*
@ -397,54 +360,40 @@ _clutter_actor_meta_set_actor (ClutterActorMeta *meta,
ClutterActor * ClutterActor *
clutter_actor_meta_get_actor (ClutterActorMeta *meta) clutter_actor_meta_get_actor (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL); g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
priv = clutter_actor_meta_get_instance_private (meta); return meta->priv->actor;
return priv->actor;
} }
void void
_clutter_actor_meta_set_priority (ClutterActorMeta *meta, _clutter_actor_meta_set_priority (ClutterActorMeta *meta,
gint priority) gint priority)
{ {
ClutterActorMetaPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
priv = clutter_actor_meta_get_instance_private (meta);
/* This property shouldn't be modified after the actor meta is in /* This property shouldn't be modified after the actor meta is in
use because ClutterMetaGroup doesn't resort the list when it use because ClutterMetaGroup doesn't resort the list when it
changes. If we made the priority public then we could either make changes. If we made the priority public then we could either make
the priority a construct-only property or listen for the priority a construct-only property or listen for
notifications on the property from the ClutterMetaGroup and notifications on the property from the ClutterMetaGroup and
resort. */ resort. */
g_return_if_fail (priv->actor == NULL); g_return_if_fail (meta->priv->actor == NULL);
priv->priority = priority; meta->priv->priority = priority;
} }
gint gint
_clutter_actor_meta_get_priority (ClutterActorMeta *meta) _clutter_actor_meta_get_priority (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0); g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0);
priv = clutter_actor_meta_get_instance_private (meta); return meta->priv->priority;
return priv->priority;
} }
gboolean gboolean
_clutter_actor_meta_is_internal (ClutterActorMeta *meta) _clutter_actor_meta_is_internal (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv = gint priority = meta->priv->priority;
clutter_actor_meta_get_instance_private (meta);
gint priority = priv->priority;
return (priority <= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW || return (priority <= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW ||
priority >= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH); priority >= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH);
@ -491,21 +440,19 @@ void
_clutter_meta_group_add_meta (ClutterMetaGroup *group, _clutter_meta_group_add_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta) ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv =
clutter_actor_meta_get_instance_private (meta);
GList *prev = NULL, *l; GList *prev = NULL, *l;
if (priv->actor != NULL) if (meta->priv->actor != NULL)
{ {
g_warning ("The meta of type '%s' with name '%s' is " g_warning ("The meta of type '%s' with name '%s' is "
"already attached to actor '%s'", "already attached to actor '%s'",
G_OBJECT_TYPE_NAME (meta), G_OBJECT_TYPE_NAME (meta),
priv->name != NULL meta->priv->name != NULL
? priv->name ? meta->priv->name
: "<unknown>", : "<unknown>",
clutter_actor_get_name (priv->actor) != NULL clutter_actor_get_name (meta->priv->actor) != NULL
? clutter_actor_get_name (priv->actor) ? clutter_actor_get_name (meta->priv->actor)
: G_OBJECT_TYPE_NAME (priv->actor)); : G_OBJECT_TYPE_NAME (meta->priv->actor));
return; return;
} }
@ -541,16 +488,13 @@ void
_clutter_meta_group_remove_meta (ClutterMetaGroup *group, _clutter_meta_group_remove_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta) ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv = if (meta->priv->actor != group->actor)
clutter_actor_meta_get_instance_private (meta);
if (priv->actor != group->actor)
{ {
g_warning ("The meta of type '%s' with name '%s' is not " g_warning ("The meta of type '%s' with name '%s' is not "
"attached to the actor '%s'", "attached to the actor '%s'",
G_OBJECT_TYPE_NAME (meta), G_OBJECT_TYPE_NAME (meta),
priv->name != NULL meta->priv->name != NULL
? priv->name ? meta->priv->name
: "<unknown>", : "<unknown>",
clutter_actor_get_name (group->actor) != NULL clutter_actor_get_name (group->actor) != NULL
? clutter_actor_get_name (group->actor) ? clutter_actor_get_name (group->actor)
@ -635,7 +579,8 @@ _clutter_meta_group_clear_metas (ClutterMetaGroup *group)
{ {
g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL); g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL);
g_list_free_full (group->meta, g_object_unref); g_list_foreach (group->meta, (GFunc) g_object_unref, NULL);
g_list_free (group->meta);
group->meta = NULL; group->meta = NULL;
} }
@ -693,10 +638,8 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group,
for (l = group->meta; l != NULL; l = l->next) for (l = group->meta; l != NULL; l = l->next)
{ {
ClutterActorMeta *meta = l->data; ClutterActorMeta *meta = l->data;
ClutterActorMetaPrivate *priv =
clutter_actor_meta_get_instance_private (meta);
if (g_strcmp0 (priv->name, name) == 0) if (g_strcmp0 (meta->priv->name, name) == 0)
return meta; return meta;
} }
@ -716,8 +659,6 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group,
const gchar * const gchar *
_clutter_actor_meta_get_debug_name (ClutterActorMeta *meta) _clutter_actor_meta_get_debug_name (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv = return meta->priv->name != NULL ? meta->priv->name
clutter_actor_meta_get_instance_private (meta); : G_OBJECT_TYPE_NAME (meta);
return priv->name != NULL ? priv->name : G_OBJECT_TYPE_NAME (meta);
} }

View File

@ -33,13 +33,31 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ()) #define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
#define CLUTTER_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMeta))
#define CLUTTER_IS_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_META))
#define CLUTTER_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
#define CLUTTER_IS_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR_META))
#define CLUTTER_ACTOR_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
CLUTTER_EXPORT typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
G_DECLARE_DERIVABLE_TYPE (ClutterActorMeta, clutter_actor_meta, typedef struct _ClutterActorMetaClass ClutterActorMetaClass;
CLUTTER, ACTOR_META, GInitiallyUnowned);
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate; /**
* ClutterActorMeta:
*
* The #ClutterActorMeta structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterActorMeta
{
/*< private >*/
GInitiallyUnowned parent_instance;
ClutterActorMetaPrivate *priv;
};
/** /**
* ClutterActorMetaClass: * ClutterActorMetaClass:
@ -69,9 +87,6 @@ struct _ClutterActorMetaClass
void (* set_actor) (ClutterActorMeta *meta, void (* set_actor) (ClutterActorMeta *meta,
ClutterActor *actor); ClutterActor *actor);
void (* set_enabled) (ClutterActorMeta *meta,
gboolean is_enabled);
/*< private >*/ /*< private >*/
void (* _clutter_meta1) (void); void (* _clutter_meta1) (void);
void (* _clutter_meta2) (void); void (* _clutter_meta2) (void);
@ -79,20 +94,24 @@ struct _ClutterActorMetaClass
void (* _clutter_meta4) (void); void (* _clutter_meta4) (void);
void (* _clutter_meta5) (void); void (* _clutter_meta5) (void);
void (* _clutter_meta6) (void); void (* _clutter_meta6) (void);
void (* _clutter_meta7) (void);
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType clutter_actor_meta_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_meta_set_name (ClutterActorMeta *meta, void clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar *name); const gchar *name);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
const gchar * clutter_actor_meta_get_name (ClutterActorMeta *meta); const gchar * clutter_actor_meta_get_name (ClutterActorMeta *meta);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_meta_set_enabled (ClutterActorMeta *meta, void clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled); gboolean is_enabled);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
gboolean clutter_actor_meta_get_enabled (ClutterActorMeta *meta); gboolean clutter_actor_meta_get_enabled (ClutterActorMeta *meta);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterActor * clutter_actor_meta_get_actor (ClutterActorMeta *meta); ClutterActor * clutter_actor_meta_get_actor (ClutterActorMeta *meta);
G_END_DECLS G_END_DECLS

View File

@ -26,6 +26,23 @@
G_BEGIN_DECLS G_BEGIN_DECLS
/*< private >
* ClutterRedrawFlags:
* @CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION: Tells clutter the maximum
* extents of what needs to be redrawn lies within the actors
* current allocation. (Only use this for 2D actors though because
* any actor with depth may be projected outside of its allocation)
*
* Flags passed to the clutter_actor_queue_redraw_with_clip ()
* function
*
* Since: 1.6
*/
typedef enum
{
CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION = 1 << 0
} ClutterRedrawFlags;
/*< private > /*< private >
* ClutterActorTraverseFlags: * ClutterActorTraverseFlags:
* CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST: Traverse the graph in * CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST: Traverse the graph in
@ -36,8 +53,7 @@ G_BEGIN_DECLS
* Controls some options for how clutter_actor_traverse() iterates * Controls some options for how clutter_actor_traverse() iterates
* through the graph. * through the graph.
*/ */
typedef enum typedef enum {
{
CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST = 1L<<0, CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST = 1L<<0,
CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST = 1L<<1 CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST = 1L<<1
} ClutterActorTraverseFlags; } ClutterActorTraverseFlags;
@ -58,8 +74,7 @@ typedef enum
* the continuing traversal. It may stop traversal completely, just * the continuing traversal. It may stop traversal completely, just
* skip over children for the current actor or continue as normal. * skip over children for the current actor or continue as normal.
*/ */
typedef enum typedef enum {
{
CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE = 1L<<0, CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE = 1L<<0,
CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN = 1L<<1, CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN = 1L<<1,
CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK = 1L<<2 CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK = 1L<<2
@ -93,12 +108,35 @@ typedef ClutterActorTraverseVisitFlags (*ClutterTraverseCallback) (ClutterActor
typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor, typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor,
gpointer user_data); gpointer user_data);
typedef struct _AnchorCoord AnchorCoord;
typedef struct _SizeRequest SizeRequest; typedef struct _SizeRequest SizeRequest;
typedef struct _ClutterLayoutInfo ClutterLayoutInfo; typedef struct _ClutterLayoutInfo ClutterLayoutInfo;
typedef struct _ClutterTransformInfo ClutterTransformInfo; typedef struct _ClutterTransformInfo ClutterTransformInfo;
typedef struct _ClutterAnimationInfo ClutterAnimationInfo; typedef struct _ClutterAnimationInfo ClutterAnimationInfo;
/* Internal helper struct to represent a point that can be stored in
either direct pixel coordinates or as a fraction of the actor's
size. It is used for the anchor point, scale center and rotation
centers. */
struct _AnchorCoord
{
gboolean is_fractional;
union
{
/* Used when is_fractional == TRUE */
struct
{
gdouble x;
gdouble y;
} fraction;
/* Use when is_fractional == FALSE */
ClutterVertex units;
} v;
};
struct _SizeRequest struct _SizeRequest
{ {
guint age; guint age;
@ -123,7 +161,7 @@ struct _SizeRequest
struct _ClutterLayoutInfo struct _ClutterLayoutInfo
{ {
/* fixed position coordinates */ /* fixed position coordinates */
graphene_point_t fixed_pos; ClutterPoint fixed_pos;
ClutterMargin margin; ClutterMargin margin;
@ -133,8 +171,8 @@ struct _ClutterLayoutInfo
guint x_expand : 1; guint x_expand : 1;
guint y_expand : 1; guint y_expand : 1;
graphene_size_t minimum; ClutterSize minimum;
graphene_size_t natural; ClutterSize natural;
}; };
const ClutterLayoutInfo * _clutter_actor_get_layout_info_or_defaults (ClutterActor *self); const ClutterLayoutInfo * _clutter_actor_get_layout_info_or_defaults (ClutterActor *self);
@ -143,30 +181,39 @@ ClutterLayoutInfo * _clutter_actor_peek_layout_info
struct _ClutterTransformInfo struct _ClutterTransformInfo
{ {
/* rotation */ /* rotation (angle and center) */
gdouble rx_angle; gdouble rx_angle;
AnchorCoord rx_center;
gdouble ry_angle; gdouble ry_angle;
AnchorCoord ry_center;
gdouble rz_angle; gdouble rz_angle;
AnchorCoord rz_center;
/* scaling */ /* scaling */
gdouble scale_x; gdouble scale_x;
gdouble scale_y; gdouble scale_y;
gdouble scale_z; gdouble scale_z;
AnchorCoord scale_center;
/* anchor point */
AnchorCoord anchor;
/* translation */ /* translation */
graphene_point3d_t translation; ClutterVertex translation;
/* z_position */ /* z_position */
gfloat z_position; gfloat z_position;
/* transformation center */ /* transformation center */
graphene_point_t pivot; ClutterPoint pivot;
gfloat pivot_z; gfloat pivot_z;
graphene_matrix_t transform; CoglMatrix transform;
guint transform_set : 1; guint transform_set : 1;
graphene_matrix_t child_transform; CoglMatrix child_transform;
guint child_transform_set : 1; guint child_transform_set : 1;
}; };
@ -193,6 +240,9 @@ ClutterAnimationInfo * _clutter_actor_get_animation_info
ClutterTransition * _clutter_actor_create_transition (ClutterActor *self, ClutterTransition * _clutter_actor_create_transition (ClutterActor *self,
GParamSpec *pspec, GParamSpec *pspec,
...); ...);
ClutterTransition * _clutter_actor_get_transition (ClutterActor *self,
GParamSpec *pspec);
gboolean _clutter_actor_foreach_child (ClutterActor *self, gboolean _clutter_actor_foreach_child (ClutterActor *self,
ClutterForeachCallback callback, ClutterForeachCallback callback,
gpointer user_data); gpointer user_data);
@ -203,11 +253,11 @@ void _clutter_actor_traverse
gpointer user_data); gpointer user_data);
ClutterActor * _clutter_actor_get_stage_internal (ClutterActor *actor); ClutterActor * _clutter_actor_get_stage_internal (ClutterActor *actor);
void _clutter_actor_apply_modelview_transform (ClutterActor *self, void _clutter_actor_apply_modelview_transform (ClutterActor *self,
graphene_matrix_t *matrix); CoglMatrix *matrix);
void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self, void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
ClutterActor *ancestor, ClutterActor *ancestor,
graphene_matrix_t *matrix); CoglMatrix *matrix);
void _clutter_actor_rerealize (ClutterActor *self, void _clutter_actor_rerealize (ClutterActor *self,
ClutterCallback callback, ClutterCallback callback,
@ -225,24 +275,35 @@ void _clutter_actor_set_enable_paint_unmapped
void _clutter_actor_set_has_pointer (ClutterActor *self, void _clutter_actor_set_has_pointer (ClutterActor *self,
gboolean has_pointer); gboolean has_pointer);
void _clutter_actor_set_has_key_focus (ClutterActor *self, void _clutter_actor_queue_redraw_with_clip (ClutterActor *self,
gboolean has_key_focus); ClutterRedrawFlags flags,
ClutterPaintVolume *clip_volume);
void _clutter_actor_queue_redraw_full (ClutterActor *self,
ClutterRedrawFlags flags,
ClutterPaintVolume *volume,
ClutterEffect *effect);
void _clutter_actor_queue_redraw_full (ClutterActor *self, ClutterPaintVolume * _clutter_actor_get_queue_redraw_clip (ClutterActor *self);
const ClutterPaintVolume *volume, void _clutter_actor_set_queue_redraw_clip (ClutterActor *self,
ClutterEffect *effect); ClutterPaintVolume *clip_volume);
void _clutter_actor_finish_queue_redraw (ClutterActor *self,
void _clutter_actor_finish_queue_redraw (ClutterActor *self); ClutterPaintVolume *clip);
gboolean _clutter_actor_set_default_paint_volume (ClutterActor *self, gboolean _clutter_actor_set_default_paint_volume (ClutterActor *self,
GType check_gtype, GType check_gtype,
ClutterPaintVolume *volume); ClutterPaintVolume *volume);
const char * _clutter_actor_get_debug_name (ClutterActor *self); const gchar * _clutter_actor_get_debug_name (ClutterActor *self);
void _clutter_actor_push_clone_paint (void); void _clutter_actor_push_clone_paint (void);
void _clutter_actor_pop_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);
ClutterActorAlign _clutter_actor_get_effective_x_align (ClutterActor *self); ClutterActorAlign _clutter_actor_get_effective_x_align (ClutterActor *self);
void _clutter_actor_handle_event (ClutterActor *actor, void _clutter_actor_handle_event (ClutterActor *actor,
@ -252,25 +313,15 @@ void _clutter_actor_attach_clone
ClutterActor *clone); ClutterActor *clone);
void _clutter_actor_detach_clone (ClutterActor *actor, void _clutter_actor_detach_clone (ClutterActor *actor,
ClutterActor *clone); ClutterActor *clone);
void _clutter_actor_queue_redraw_on_clones (ClutterActor *actor);
void _clutter_actor_queue_relayout_on_clones (ClutterActor *actor);
void _clutter_actor_queue_only_relayout (ClutterActor *actor); void _clutter_actor_queue_only_relayout (ClutterActor *actor);
void clutter_actor_clear_stage_views_recursive (ClutterActor *actor);
float clutter_actor_get_real_resource_scale (ClutterActor *actor); CoglFramebuffer * _clutter_actor_get_active_framebuffer (ClutterActor *actor);
ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self, ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self,
CoglTexture *texture); CoglTexture *texture);
void clutter_actor_finish_layout (ClutterActor *self,
int phase);
void clutter_actor_queue_immediate_relayout (ClutterActor *self);
gboolean clutter_actor_is_painting_unmapped (ClutterActor *self);
gboolean clutter_actor_get_redraw_clip (ClutterActor *self,
ClutterPaintVolume *dst_old_pv,
ClutterPaintVolume *dst_new_pv);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */ #endif /* __CLUTTER_ACTOR_PRIVATE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -39,8 +39,6 @@
#include <clutter/clutter-types.h> #include <clutter/clutter-types.h>
#include <clutter/clutter-event.h> #include <clutter/clutter-event.h>
#include <clutter/clutter-paint-context.h>
#include <clutter/clutter-pick-context.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -63,7 +61,7 @@ G_BEGIN_DECLS
* internal state. * internal state.
*/ */
#define CLUTTER_ACTOR_SET_FLAGS(a,f) \ #define CLUTTER_ACTOR_SET_FLAGS(a,f) \
CLUTTER_MACRO_DEPRECATED \ CLUTTER_MACRO_DEPRECATED_IN_1_24 \
(((ClutterActor*)(a))->flags |= (f)) (((ClutterActor*)(a))->flags |= (f))
/** /**
@ -78,23 +76,23 @@ G_BEGIN_DECLS
* internal state. * internal state.
*/ */
#define CLUTTER_ACTOR_UNSET_FLAGS(a,f) \ #define CLUTTER_ACTOR_UNSET_FLAGS(a,f) \
CLUTTER_MACRO_DEPRECATED \ CLUTTER_MACRO_DEPRECATED_IN_1_24 \
(((ClutterActor*)(a))->flags &= ~(f)) (((ClutterActor*)(a))->flags &= ~(f))
#define CLUTTER_ACTOR_IS_MAPPED(a) \ #define CLUTTER_ACTOR_IS_MAPPED(a) \
CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_is_mapped instead") \ CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_is_mapped instead") \
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_MAPPED) != FALSE) ((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_MAPPED) != FALSE)
#define CLUTTER_ACTOR_IS_REALIZED(a) \ #define CLUTTER_ACTOR_IS_REALIZED(a) \
CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_is_realized instead") \ CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_is_realized instead") \
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_REALIZED) != FALSE) ((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_REALIZED) != FALSE)
#define CLUTTER_ACTOR_IS_VISIBLE(a) \ #define CLUTTER_ACTOR_IS_VISIBLE(a) \
CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_is_visible instead") \ CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_is_visible instead") \
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_VISIBLE) != FALSE) ((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_VISIBLE) != FALSE)
#define CLUTTER_ACTOR_IS_REACTIVE(a) \ #define CLUTTER_ACTOR_IS_REACTIVE(a) \
CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_get_reactive instead") \ CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_get_reactive instead") \
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_REACTIVE) != FALSE) ((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_REACTIVE) != FALSE)
typedef struct _ClutterActorClass ClutterActorClass; typedef struct _ClutterActorClass ClutterActorClass;
@ -142,6 +140,11 @@ struct _ClutterActor
* ClutterActorClass: * ClutterActorClass:
* @show: signal class handler for #ClutterActor::show; it must chain * @show: signal class handler for #ClutterActor::show; it must chain
* up to the parent's implementation * up to the parent's implementation
* @show_all: virtual function for containers and composite actors, to
* determine which children should be shown when calling
* clutter_actor_show_all() on the actor. Defaults to calling
* clutter_actor_show(). This virtual function is deprecated and it
* should not be overridden.
* @hide: signal class handler for #ClutterActor::hide; it must chain * @hide: signal class handler for #ClutterActor::hide; it must chain
* up to the parent's implementation * up to the parent's implementation
* @hide_all: virtual function for containers and composite actors, to * @hide_all: virtual function for containers and composite actors, to
@ -170,23 +173,18 @@ struct _ClutterActor
* @get_preferred_height: virtual function, used when querying the minimum * @get_preferred_height: virtual function, used when querying the minimum
* and natural heights of an actor for a given width; it is used by * and natural heights of an actor for a given width; it is used by
* clutter_actor_get_preferred_height() * clutter_actor_get_preferred_height()
* @allocate: virtual function, used when setting the coordinates of an * @allocate: virtual function, used when settings the coordinates of an
* actor; it is used by clutter_actor_allocate(); when overriding this * actor; it is used by clutter_actor_allocate(); it must chain up to
* function without chaining up, clutter_actor_set_allocation() must be * the parent's implementation, or call clutter_actor_set_allocation()
* called and children must be allocated by the implementation, when
* chaining up though, those things will be done by the parent's
* implementation.
* @apply_transform: virtual function, used when applying the transformations * @apply_transform: virtual function, used when applying the transformations
* to an actor before painting it or when transforming coordinates or * to an actor before painting it or when transforming coordinates or
* the allocation; if the transformation calculated by this function may * the allocation; it must chain up to the parent's implementation
* have changed, the cached transformation must be invalidated by calling
* clutter_actor_invalidate_transform(); it must chain up to the parent's
* implementation
* @parent_set: signal class handler for the #ClutterActor::parent-set * @parent_set: signal class handler for the #ClutterActor::parent-set
* @destroy: signal class handler for #ClutterActor::destroy. It must * @destroy: signal class handler for #ClutterActor::destroy. It must
* chain up to the parent's implementation * chain up to the parent's implementation
* @pick: virtual function, used to draw an outline of the actor with * @pick: virtual function, used to draw an outline of the actor with
* the given color * the given color
* @queue_redraw: class handler for #ClutterActor::queue-redraw
* @event: class handler for #ClutterActor::event * @event: class handler for #ClutterActor::event
* @button_press_event: class handler for #ClutterActor::button-press-event * @button_press_event: class handler for #ClutterActor::button-press-event
* @button_release_event: class handler for * @button_release_event: class handler for
@ -223,20 +221,23 @@ struct _ClutterActorClass
/*< public >*/ /*< public >*/
void (* show) (ClutterActor *self); void (* show) (ClutterActor *self);
void (* show_all) (ClutterActor *self);
void (* hide) (ClutterActor *self); void (* hide) (ClutterActor *self);
void (* hide_all) (ClutterActor *self); void (* hide_all) (ClutterActor *self);
void (* realize) (ClutterActor *self); void (* realize) (ClutterActor *self);
void (* unrealize) (ClutterActor *self); void (* unrealize) (ClutterActor *self);
void (* map) (ClutterActor *self); void (* map) (ClutterActor *self);
void (* unmap) (ClutterActor *self); void (* unmap) (ClutterActor *self);
void (* paint) (ClutterActor *self, void (* paint) (ClutterActor *self);
ClutterPaintContext *paint_context);
void (* parent_set) (ClutterActor *actor, void (* parent_set) (ClutterActor *actor,
ClutterActor *old_parent); ClutterActor *old_parent);
void (* destroy) (ClutterActor *self); void (* destroy) (ClutterActor *self);
void (* pick) (ClutterActor *actor, void (* pick) (ClutterActor *actor,
ClutterPickContext *pick_context); const ClutterColor *color);
void (* queue_redraw) (ClutterActor *actor,
ClutterActor *leaf_that_queued);
/* size negotiation */ /* size negotiation */
void (* get_preferred_width) (ClutterActor *self, void (* get_preferred_width) (ClutterActor *self,
@ -248,11 +249,12 @@ struct _ClutterActorClass
gfloat *min_height_p, gfloat *min_height_p,
gfloat *natural_height_p); gfloat *natural_height_p);
void (* allocate) (ClutterActor *self, void (* allocate) (ClutterActor *self,
const ClutterActorBox *box); const ClutterActorBox *box,
ClutterAllocationFlags flags);
/* transformations */ /* transformations */
void (* apply_transform) (ClutterActor *actor, void (* apply_transform) (ClutterActor *actor,
graphene_matrix_t *matrix); ClutterMatrix *matrix);
/* event signals */ /* event signals */
gboolean (* event) (ClutterActor *actor, gboolean (* event) (ClutterActor *actor,
@ -293,14 +295,10 @@ struct _ClutterActorClass
gboolean (* touch_event) (ClutterActor *self, gboolean (* touch_event) (ClutterActor *self,
ClutterTouchEvent *event); ClutterTouchEvent *event);
gboolean (* has_accessible) (ClutterActor *self);
void (* resource_scale_changed) (ClutterActor *self);
float (* calculate_resource_scale) (ClutterActor *self,
int phase);
/*< private >*/ /*< private >*/
/* padding for future expansion */ /* padding for future expansion */
gpointer _padding_dummy[25]; gpointer _padding_dummy[26];
}; };
/** /**
@ -324,570 +322,548 @@ struct _ClutterActorIter
gpointer CLUTTER_PRIVATE_FIELD (dummy5); gpointer CLUTTER_PRIVATE_FIELD (dummy5);
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
GType clutter_actor_get_type (void) G_GNUC_CONST; GType clutter_actor_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_new (void); ClutterActor * clutter_actor_new (void);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_flags (ClutterActor *self, void clutter_actor_set_flags (ClutterActor *self,
ClutterActorFlags flags); ClutterActorFlags flags);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_unset_flags (ClutterActor *self, void clutter_actor_unset_flags (ClutterActor *self,
ClutterActorFlags flags); ClutterActorFlags flags);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
ClutterActorFlags clutter_actor_get_flags (ClutterActor *self); ClutterActorFlags clutter_actor_get_flags (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_show (ClutterActor *self); void clutter_actor_show (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_hide (ClutterActor *self); void clutter_actor_hide (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_realize (ClutterActor *self); void clutter_actor_realize (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_unrealize (ClutterActor *self); void clutter_actor_unrealize (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_map (ClutterActor *self); void clutter_actor_map (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_unmap (ClutterActor *self); void clutter_actor_unmap (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_paint (ClutterActor *self, void clutter_actor_paint (ClutterActor *self);
ClutterPaintContext *paint_context); CLUTTER_AVAILABLE_IN_ALL
CLUTTER_EXPORT void clutter_actor_continue_paint (ClutterActor *self);
void clutter_actor_continue_paint (ClutterActor *self, CLUTTER_AVAILABLE_IN_ALL
ClutterPaintContext *paint_context);
CLUTTER_EXPORT
void clutter_actor_pick (ClutterActor *actor,
ClutterPickContext *pick_context);
CLUTTER_EXPORT
void clutter_actor_continue_pick (ClutterActor *actor,
ClutterPickContext *pick_context);
CLUTTER_EXPORT
void clutter_actor_queue_redraw (ClutterActor *self); void clutter_actor_queue_redraw (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_queue_redraw_with_clip (ClutterActor *self, void clutter_actor_queue_redraw_with_clip (ClutterActor *self,
const cairo_rectangle_int_t *clip); const cairo_rectangle_int_t *clip);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_queue_relayout (ClutterActor *self); void clutter_actor_queue_relayout (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_destroy (ClutterActor *self); void clutter_actor_destroy (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_name (ClutterActor *self, void clutter_actor_set_name (ClutterActor *self,
const gchar *name); const gchar *name);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
const gchar * clutter_actor_get_name (ClutterActor *self); const gchar * clutter_actor_get_name (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
AtkObject * clutter_actor_get_accessible (ClutterActor *self); AtkObject * clutter_actor_get_accessible (ClutterActor *self);
CLUTTER_EXPORT
gboolean clutter_actor_has_accessible (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_24
gboolean clutter_actor_is_visible (ClutterActor *self); gboolean clutter_actor_is_visible (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_24
gboolean clutter_actor_is_mapped (ClutterActor *self); gboolean clutter_actor_is_mapped (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_24
gboolean clutter_actor_is_realized (ClutterActor *self); gboolean clutter_actor_is_realized (ClutterActor *self);
/* Size negotiation */ /* Size negotiation */
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_request_mode (ClutterActor *self, void clutter_actor_set_request_mode (ClutterActor *self,
ClutterRequestMode mode); ClutterRequestMode mode);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
ClutterRequestMode clutter_actor_get_request_mode (ClutterActor *self); ClutterRequestMode clutter_actor_get_request_mode (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_preferred_width (ClutterActor *self, void clutter_actor_get_preferred_width (ClutterActor *self,
gfloat for_height, gfloat for_height,
gfloat *min_width_p, gfloat *min_width_p,
gfloat *natural_width_p); gfloat *natural_width_p);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_preferred_height (ClutterActor *self, void clutter_actor_get_preferred_height (ClutterActor *self,
gfloat for_width, gfloat for_width,
gfloat *min_height_p, gfloat *min_height_p,
gfloat *natural_height_p); gfloat *natural_height_p);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_preferred_size (ClutterActor *self, void clutter_actor_get_preferred_size (ClutterActor *self,
gfloat *min_width_p, gfloat *min_width_p,
gfloat *min_height_p, gfloat *min_height_p,
gfloat *natural_width_p, gfloat *natural_width_p,
gfloat *natural_height_p); gfloat *natural_height_p);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_allocate (ClutterActor *self, void clutter_actor_allocate (ClutterActor *self,
const ClutterActorBox *box); const ClutterActorBox *box,
CLUTTER_EXPORT ClutterAllocationFlags flags);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_allocate_preferred_size (ClutterActor *self, void clutter_actor_allocate_preferred_size (ClutterActor *self,
float x, ClutterAllocationFlags flags);
float y); CLUTTER_AVAILABLE_IN_ALL
CLUTTER_EXPORT
void clutter_actor_allocate_available_size (ClutterActor *self, void clutter_actor_allocate_available_size (ClutterActor *self,
gfloat x, gfloat x,
gfloat y, gfloat y,
gfloat available_width, gfloat available_width,
gfloat available_height); gfloat available_height,
CLUTTER_EXPORT ClutterAllocationFlags flags);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_allocate_align_fill (ClutterActor *self, void clutter_actor_allocate_align_fill (ClutterActor *self,
const ClutterActorBox *box, const ClutterActorBox *box,
gdouble x_align, gdouble x_align,
gdouble y_align, gdouble y_align,
gboolean x_fill, gboolean x_fill,
gboolean y_fill); gboolean y_fill,
CLUTTER_EXPORT ClutterAllocationFlags flags);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_allocation (ClutterActor *self, void clutter_actor_set_allocation (ClutterActor *self,
const ClutterActorBox *box); const ClutterActorBox *box,
CLUTTER_EXPORT ClutterAllocationFlags flags);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_allocation_box (ClutterActor *self, void clutter_actor_get_allocation_box (ClutterActor *self,
ClutterActorBox *box); ClutterActorBox *box);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_allocation_vertices (ClutterActor *self,
ClutterActor *ancestor,
ClutterVertex verts[]);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_has_allocation (ClutterActor *self); gboolean clutter_actor_has_allocation (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_size (ClutterActor *self, void clutter_actor_set_size (ClutterActor *self,
gfloat width, gfloat width,
gfloat height); gfloat height);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_size (ClutterActor *self, void clutter_actor_get_size (ClutterActor *self,
gfloat *width, gfloat *width,
gfloat *height); gfloat *height);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_position (ClutterActor *self, void clutter_actor_set_position (ClutterActor *self,
gfloat x, gfloat x,
gfloat y); gfloat y);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_fixed_position (ClutterActor *self,
float *x,
float *y);
CLUTTER_EXPORT
void clutter_actor_get_position (ClutterActor *self, void clutter_actor_get_position (ClutterActor *self,
gfloat *x, gfloat *x,
gfloat *y); gfloat *y);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_fixed_position_set (ClutterActor *self); gboolean clutter_actor_get_fixed_position_set (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_fixed_position_set (ClutterActor *self, void clutter_actor_set_fixed_position_set (ClutterActor *self,
gboolean is_set); gboolean is_set);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_move_by (ClutterActor *self, void clutter_actor_move_by (ClutterActor *self,
gfloat dx, gfloat dx,
gfloat dy); gfloat dy);
/* Actor geometry */ /* Actor geometry */
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gfloat clutter_actor_get_width (ClutterActor *self); gfloat clutter_actor_get_width (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gfloat clutter_actor_get_height (ClutterActor *self); gfloat clutter_actor_get_height (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_width (ClutterActor *self, void clutter_actor_set_width (ClutterActor *self,
gfloat width); gfloat width);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_height (ClutterActor *self, void clutter_actor_set_height (ClutterActor *self,
gfloat height); gfloat height);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gfloat clutter_actor_get_x (ClutterActor *self); gfloat clutter_actor_get_x (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gfloat clutter_actor_get_y (ClutterActor *self); gfloat clutter_actor_get_y (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_x (ClutterActor *self, void clutter_actor_set_x (ClutterActor *self,
gfloat x); gfloat x);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_y (ClutterActor *self, void clutter_actor_set_y (ClutterActor *self,
gfloat y); gfloat y);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_z_position (ClutterActor *self, void clutter_actor_set_z_position (ClutterActor *self,
gfloat z_position); gfloat z_position);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
gfloat clutter_actor_get_z_position (ClutterActor *self); gfloat clutter_actor_get_z_position (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_layout_manager (ClutterActor *self, void clutter_actor_set_layout_manager (ClutterActor *self,
ClutterLayoutManager *manager); ClutterLayoutManager *manager);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterLayoutManager * clutter_actor_get_layout_manager (ClutterActor *self); ClutterLayoutManager * clutter_actor_get_layout_manager (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_x_align (ClutterActor *self, void clutter_actor_set_x_align (ClutterActor *self,
ClutterActorAlign x_align); ClutterActorAlign x_align);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterActorAlign clutter_actor_get_x_align (ClutterActor *self); ClutterActorAlign clutter_actor_get_x_align (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_y_align (ClutterActor *self, void clutter_actor_set_y_align (ClutterActor *self,
ClutterActorAlign y_align); ClutterActorAlign y_align);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterActorAlign clutter_actor_get_y_align (ClutterActor *self); ClutterActorAlign clutter_actor_get_y_align (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_margin_top (ClutterActor *self, void clutter_actor_set_margin_top (ClutterActor *self,
gfloat margin); gfloat margin);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
gfloat clutter_actor_get_margin_top (ClutterActor *self); gfloat clutter_actor_get_margin_top (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_margin_bottom (ClutterActor *self, void clutter_actor_set_margin_bottom (ClutterActor *self,
gfloat margin); gfloat margin);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
gfloat clutter_actor_get_margin_bottom (ClutterActor *self); gfloat clutter_actor_get_margin_bottom (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_margin_left (ClutterActor *self, void clutter_actor_set_margin_left (ClutterActor *self,
gfloat margin); gfloat margin);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
gfloat clutter_actor_get_margin_left (ClutterActor *self); gfloat clutter_actor_get_margin_left (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_margin_right (ClutterActor *self, void clutter_actor_set_margin_right (ClutterActor *self,
gfloat margin); gfloat margin);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
gfloat clutter_actor_get_margin_right (ClutterActor *self); gfloat clutter_actor_get_margin_right (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_margin (ClutterActor *self, void clutter_actor_set_margin (ClutterActor *self,
const ClutterMargin *margin); const ClutterMargin *margin);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_get_margin (ClutterActor *self, void clutter_actor_get_margin (ClutterActor *self,
ClutterMargin *margin); ClutterMargin *margin);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_x_expand (ClutterActor *self, void clutter_actor_set_x_expand (ClutterActor *self,
gboolean expand); gboolean expand);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
gboolean clutter_actor_get_x_expand (ClutterActor *self); gboolean clutter_actor_get_x_expand (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_y_expand (ClutterActor *self, void clutter_actor_set_y_expand (ClutterActor *self,
gboolean expand); gboolean expand);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
gboolean clutter_actor_get_y_expand (ClutterActor *self); gboolean clutter_actor_get_y_expand (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
gboolean clutter_actor_needs_expand (ClutterActor *self, gboolean clutter_actor_needs_expand (ClutterActor *self,
ClutterOrientation orientation); ClutterOrientation orientation);
/* Paint */ /* Paint */
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_clip (ClutterActor *self, void clutter_actor_set_clip (ClutterActor *self,
gfloat xoff, gfloat xoff,
gfloat yoff, gfloat yoff,
gfloat width, gfloat width,
gfloat height); gfloat height);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_remove_clip (ClutterActor *self); void clutter_actor_remove_clip (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_has_clip (ClutterActor *self); gboolean clutter_actor_has_clip (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_clip (ClutterActor *self, void clutter_actor_get_clip (ClutterActor *self,
gfloat *xoff, gfloat *xoff,
gfloat *yoff, gfloat *yoff,
gfloat *width, gfloat *width,
gfloat *height); gfloat *height);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_clip_to_allocation (ClutterActor *self, void clutter_actor_set_clip_to_allocation (ClutterActor *self,
gboolean clip_set); gboolean clip_set);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_clip_to_allocation (ClutterActor *self); gboolean clutter_actor_get_clip_to_allocation (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_opacity (ClutterActor *self, void clutter_actor_set_opacity (ClutterActor *self,
guint8 opacity); guint8 opacity);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
guint8 clutter_actor_get_opacity (ClutterActor *self); guint8 clutter_actor_get_opacity (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
guint8 clutter_actor_get_paint_opacity (ClutterActor *self); guint8 clutter_actor_get_paint_opacity (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_paint_visibility (ClutterActor *self); gboolean clutter_actor_get_paint_visibility (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_8
void clutter_actor_set_offscreen_redirect (ClutterActor *self, void clutter_actor_set_offscreen_redirect (ClutterActor *self,
ClutterOffscreenRedirect redirect); ClutterOffscreenRedirect redirect);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_8
ClutterOffscreenRedirect clutter_actor_get_offscreen_redirect (ClutterActor *self); ClutterOffscreenRedirect clutter_actor_get_offscreen_redirect (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_should_pick (ClutterActor *self, gboolean clutter_actor_should_pick_paint (ClutterActor *self);
ClutterPickContext *pick_context); CLUTTER_AVAILABLE_IN_ALL
CLUTTER_EXPORT
gboolean clutter_actor_is_in_clone_paint (ClutterActor *self); gboolean clutter_actor_is_in_clone_paint (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_paint_box (ClutterActor *self, gboolean clutter_actor_get_paint_box (ClutterActor *self,
ClutterActorBox *box); ClutterActorBox *box);
CLUTTER_AVAILABLE_IN_1_8
CLUTTER_EXPORT
float clutter_actor_get_resource_scale (ClutterActor *self);
CLUTTER_EXPORT
gboolean clutter_actor_has_overlaps (ClutterActor *self); gboolean clutter_actor_has_overlaps (ClutterActor *self);
/* Content */ /* Content */
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_content (ClutterActor *self, void clutter_actor_set_content (ClutterActor *self,
ClutterContent *content); ClutterContent *content);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterContent * clutter_actor_get_content (ClutterActor *self); ClutterContent * clutter_actor_get_content (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_content_gravity (ClutterActor *self, void clutter_actor_set_content_gravity (ClutterActor *self,
ClutterContentGravity gravity); ClutterContentGravity gravity);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterContentGravity clutter_actor_get_content_gravity (ClutterActor *self); ClutterContentGravity clutter_actor_get_content_gravity (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_content_scaling_filters (ClutterActor *self, void clutter_actor_set_content_scaling_filters (ClutterActor *self,
ClutterScalingFilter min_filter, ClutterScalingFilter min_filter,
ClutterScalingFilter mag_filter); ClutterScalingFilter mag_filter);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_get_content_scaling_filters (ClutterActor *self, void clutter_actor_get_content_scaling_filters (ClutterActor *self,
ClutterScalingFilter *min_filter, ClutterScalingFilter *min_filter,
ClutterScalingFilter *mag_filter); ClutterScalingFilter *mag_filter);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_content_repeat (ClutterActor *self, void clutter_actor_set_content_repeat (ClutterActor *self,
ClutterContentRepeat repeat); ClutterContentRepeat repeat);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
ClutterContentRepeat clutter_actor_get_content_repeat (ClutterActor *self); ClutterContentRepeat clutter_actor_get_content_repeat (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_get_content_box (ClutterActor *self, void clutter_actor_get_content_box (ClutterActor *self,
ClutterActorBox *box); ClutterActorBox *box);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_background_color (ClutterActor *self, void clutter_actor_set_background_color (ClutterActor *self,
const ClutterColor *color); const ClutterColor *color);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_get_background_color (ClutterActor *self, void clutter_actor_get_background_color (ClutterActor *self,
ClutterColor *color); ClutterColor *color);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_6
const ClutterPaintVolume * clutter_actor_get_paint_volume (ClutterActor *self); const ClutterPaintVolume * clutter_actor_get_paint_volume (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_6
const ClutterPaintVolume * clutter_actor_get_transformed_paint_volume (ClutterActor *self, const ClutterPaintVolume * clutter_actor_get_transformed_paint_volume (ClutterActor *self,
ClutterActor *relative_to_ancestor); ClutterActor *relative_to_ancestor);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
const ClutterPaintVolume * clutter_actor_get_default_paint_volume (ClutterActor *self); const ClutterPaintVolume * clutter_actor_get_default_paint_volume (ClutterActor *self);
/* Events */ /* Events */
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_reactive (ClutterActor *actor, void clutter_actor_set_reactive (ClutterActor *actor,
gboolean reactive); gboolean reactive);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_reactive (ClutterActor *actor); gboolean clutter_actor_get_reactive (ClutterActor *actor);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_has_key_focus (ClutterActor *self); gboolean clutter_actor_has_key_focus (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_grab_key_focus (ClutterActor *self); void clutter_actor_grab_key_focus (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_event (ClutterActor *actor, gboolean clutter_actor_event (ClutterActor *actor,
const ClutterEvent *event, const ClutterEvent *event,
gboolean capture); gboolean capture);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_has_pointer (ClutterActor *self); gboolean clutter_actor_has_pointer (ClutterActor *self);
/* Text */ /* Text */
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
PangoContext * clutter_actor_get_pango_context (ClutterActor *self); PangoContext * clutter_actor_get_pango_context (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
PangoContext * clutter_actor_create_pango_context (ClutterActor *self); PangoContext * clutter_actor_create_pango_context (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
PangoLayout * clutter_actor_create_pango_layout (ClutterActor *self, PangoLayout * clutter_actor_create_pango_layout (ClutterActor *self,
const gchar *text); const gchar *text);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_text_direction (ClutterActor *self, void clutter_actor_set_text_direction (ClutterActor *self,
ClutterTextDirection text_dir); ClutterTextDirection text_dir);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
ClutterTextDirection clutter_actor_get_text_direction (ClutterActor *self); ClutterTextDirection clutter_actor_get_text_direction (ClutterActor *self);
/* Actor hierarchy */ /* Actor hierarchy */
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_add_child (ClutterActor *self, void clutter_actor_add_child (ClutterActor *self,
ClutterActor *child); ClutterActor *child);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_insert_child_at_index (ClutterActor *self, void clutter_actor_insert_child_at_index (ClutterActor *self,
ClutterActor *child, ClutterActor *child,
gint index_); gint index_);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_insert_child_above (ClutterActor *self, void clutter_actor_insert_child_above (ClutterActor *self,
ClutterActor *child, ClutterActor *child,
ClutterActor *sibling); ClutterActor *sibling);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_insert_child_below (ClutterActor *self, void clutter_actor_insert_child_below (ClutterActor *self,
ClutterActor *child, ClutterActor *child,
ClutterActor *sibling); ClutterActor *sibling);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_replace_child (ClutterActor *self, void clutter_actor_replace_child (ClutterActor *self,
ClutterActor *old_child, ClutterActor *old_child,
ClutterActor *new_child); ClutterActor *new_child);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_remove_child (ClutterActor *self, void clutter_actor_remove_child (ClutterActor *self,
ClutterActor *child); ClutterActor *child);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_remove_all_children (ClutterActor *self); void clutter_actor_remove_all_children (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_destroy_all_children (ClutterActor *self); void clutter_actor_destroy_all_children (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
GList * clutter_actor_get_children (ClutterActor *self); GList * clutter_actor_get_children (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
gint clutter_actor_get_n_children (ClutterActor *self); gint clutter_actor_get_n_children (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_get_child_at_index (ClutterActor *self, ClutterActor * clutter_actor_get_child_at_index (ClutterActor *self,
gint index_); gint index_);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_get_previous_sibling (ClutterActor *self); ClutterActor * clutter_actor_get_previous_sibling (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_get_next_sibling (ClutterActor *self); ClutterActor * clutter_actor_get_next_sibling (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_get_first_child (ClutterActor *self); ClutterActor * clutter_actor_get_first_child (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_get_last_child (ClutterActor *self); ClutterActor * clutter_actor_get_last_child (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
ClutterActor * clutter_actor_get_parent (ClutterActor *self); ClutterActor * clutter_actor_get_parent (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
gboolean clutter_actor_contains (ClutterActor *self, gboolean clutter_actor_contains (ClutterActor *self,
ClutterActor *descendant); ClutterActor *descendant);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
ClutterActor* clutter_actor_get_stage (ClutterActor *actor); ClutterActor* clutter_actor_get_stage (ClutterActor *actor);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_child_below_sibling (ClutterActor *self, void clutter_actor_set_child_below_sibling (ClutterActor *self,
ClutterActor *child, ClutterActor *child,
ClutterActor *sibling); ClutterActor *sibling);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_child_above_sibling (ClutterActor *self, void clutter_actor_set_child_above_sibling (ClutterActor *self,
ClutterActor *child, ClutterActor *child,
ClutterActor *sibling); ClutterActor *sibling);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_child_at_index (ClutterActor *self, void clutter_actor_set_child_at_index (ClutterActor *self,
ClutterActor *child, ClutterActor *child,
gint index_); gint index_);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_iter_init (ClutterActorIter *iter, void clutter_actor_iter_init (ClutterActorIter *iter,
ClutterActor *root); ClutterActor *root);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
gboolean clutter_actor_iter_next (ClutterActorIter *iter, gboolean clutter_actor_iter_next (ClutterActorIter *iter,
ClutterActor **child); ClutterActor **child);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
gboolean clutter_actor_iter_prev (ClutterActorIter *iter, gboolean clutter_actor_iter_prev (ClutterActorIter *iter,
ClutterActor **child); ClutterActor **child);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_iter_remove (ClutterActorIter *iter); void clutter_actor_iter_remove (ClutterActorIter *iter);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_iter_destroy (ClutterActorIter *iter); void clutter_actor_iter_destroy (ClutterActorIter *iter);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
gboolean clutter_actor_iter_is_valid (const ClutterActorIter *iter); gboolean clutter_actor_iter_is_valid (const ClutterActorIter *iter);
/* Transformations */ /* Transformations */
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_is_rotated (ClutterActor *self); gboolean clutter_actor_is_rotated (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_is_scaled (ClutterActor *self); gboolean clutter_actor_is_scaled (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_pivot_point (ClutterActor *self, void clutter_actor_set_pivot_point (ClutterActor *self,
gfloat pivot_x, gfloat pivot_x,
gfloat pivot_y); gfloat pivot_y);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_get_pivot_point (ClutterActor *self, void clutter_actor_get_pivot_point (ClutterActor *self,
gfloat *pivot_x, gfloat *pivot_x,
gfloat *pivot_y); gfloat *pivot_y);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_pivot_point_z (ClutterActor *self, void clutter_actor_set_pivot_point_z (ClutterActor *self,
gfloat pivot_z); gfloat pivot_z);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
gfloat clutter_actor_get_pivot_point_z (ClutterActor *self); gfloat clutter_actor_get_pivot_point_z (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_rotation_angle (ClutterActor *self, void clutter_actor_set_rotation_angle (ClutterActor *self,
ClutterRotateAxis axis, ClutterRotateAxis axis,
gdouble angle); gdouble angle);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
gdouble clutter_actor_get_rotation_angle (ClutterActor *self, gdouble clutter_actor_get_rotation_angle (ClutterActor *self,
ClutterRotateAxis axis); ClutterRotateAxis axis);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_scale (ClutterActor *self, void clutter_actor_set_scale (ClutterActor *self,
gdouble scale_x, gdouble scale_x,
gdouble scale_y); gdouble scale_y);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_scale (ClutterActor *self, void clutter_actor_get_scale (ClutterActor *self,
gdouble *scale_x, gdouble *scale_x,
gdouble *scale_y); gdouble *scale_y);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_scale_z (ClutterActor *self, void clutter_actor_set_scale_z (ClutterActor *self,
gdouble scale_z); gdouble scale_z);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
gdouble clutter_actor_get_scale_z (ClutterActor *self); gdouble clutter_actor_get_scale_z (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_translation (ClutterActor *self, void clutter_actor_set_translation (ClutterActor *self,
gfloat translate_x, gfloat translate_x,
gfloat translate_y, gfloat translate_y,
gfloat translate_z); gfloat translate_z);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_get_translation (ClutterActor *self, void clutter_actor_get_translation (ClutterActor *self,
gfloat *translate_x, gfloat *translate_x,
gfloat *translate_y, gfloat *translate_y,
gfloat *translate_z); gfloat *translate_z);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_transform (ClutterActor *self, void clutter_actor_set_transform (ClutterActor *self,
const graphene_matrix_t *transform); const ClutterMatrix *transform);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_get_transform (ClutterActor *self, void clutter_actor_get_transform (ClutterActor *self,
graphene_matrix_t *transform); ClutterMatrix *transform);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_child_transform (ClutterActor *self, void clutter_actor_set_child_transform (ClutterActor *self,
const graphene_matrix_t *transform); const ClutterMatrix *transform);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_get_child_transform (ClutterActor *self, void clutter_actor_get_child_transform (ClutterActor *self,
graphene_matrix_t *transform); ClutterMatrix *transform);
CLUTTER_AVAILABLE_IN_ALL
CLUTTER_EXPORT
void clutter_actor_get_transformed_extents (ClutterActor *self,
graphene_rect_t *rect);
CLUTTER_EXPORT
void clutter_actor_get_transformed_position (ClutterActor *self, void clutter_actor_get_transformed_position (ClutterActor *self,
gfloat *x, gfloat *x,
gfloat *y); gfloat *y);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_transformed_size (ClutterActor *self, void clutter_actor_get_transformed_size (ClutterActor *self,
gfloat *width, gfloat *width,
gfloat *height); gfloat *height);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_transform_stage_point (ClutterActor *self, gboolean clutter_actor_transform_stage_point (ClutterActor *self,
gfloat x, gfloat x,
gfloat y, gfloat y,
gfloat *x_out, gfloat *x_out,
gfloat *y_out); gfloat *y_out);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_abs_allocation_vertices (ClutterActor *self, void clutter_actor_get_abs_allocation_vertices (ClutterActor *self,
graphene_point3d_t *verts); ClutterVertex verts[]);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_apply_transform_to_point (ClutterActor *self, void clutter_actor_apply_transform_to_point (ClutterActor *self,
const graphene_point3d_t *point, const ClutterVertex *point,
graphene_point3d_t *vertex); ClutterVertex *vertex);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_apply_relative_transform_to_point (ClutterActor *self, void clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
ClutterActor *ancestor, ClutterActor *ancestor,
const graphene_point3d_t *point, const ClutterVertex *point,
graphene_point3d_t *vertex); ClutterVertex *vertex);
/* Implicit animations */ /* Implicit animations */
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_save_easing_state (ClutterActor *self); void clutter_actor_save_easing_state (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_restore_easing_state (ClutterActor *self); void clutter_actor_restore_easing_state (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_easing_mode (ClutterActor *self, void clutter_actor_set_easing_mode (ClutterActor *self,
ClutterAnimationMode mode); ClutterAnimationMode mode);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterAnimationMode clutter_actor_get_easing_mode (ClutterActor *self); ClutterAnimationMode clutter_actor_get_easing_mode (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_easing_duration (ClutterActor *self, void clutter_actor_set_easing_duration (ClutterActor *self,
guint msecs); guint msecs);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
guint clutter_actor_get_easing_duration (ClutterActor *self); guint clutter_actor_get_easing_duration (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_easing_delay (ClutterActor *self, void clutter_actor_set_easing_delay (ClutterActor *self,
guint msecs); guint msecs);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
guint clutter_actor_get_easing_delay (ClutterActor *self); guint clutter_actor_get_easing_delay (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterTransition * clutter_actor_get_transition (ClutterActor *self, ClutterTransition * clutter_actor_get_transition (ClutterActor *self,
const char *name); const char *name);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_add_transition (ClutterActor *self, void clutter_actor_add_transition (ClutterActor *self,
const char *name, const char *name,
ClutterTransition *transition); ClutterTransition *transition);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_remove_transition (ClutterActor *self, void clutter_actor_remove_transition (ClutterActor *self,
const char *name); const char *name);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_remove_all_transitions (ClutterActor *self); void clutter_actor_remove_all_transitions (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_16
gboolean clutter_actor_has_mapped_clones (ClutterActor *self); gboolean clutter_actor_has_mapped_clones (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_22
void clutter_actor_set_opacity_override (ClutterActor *self, void clutter_actor_set_opacity_override (ClutterActor *self,
gint opacity); gint opacity);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_22
gint clutter_actor_get_opacity_override (ClutterActor *self); gint clutter_actor_get_opacity_override (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_inhibit_culling (ClutterActor *actor);
CLUTTER_EXPORT
void clutter_actor_uninhibit_culling (ClutterActor *actor);
/** /**
* ClutterActorCreateChildFunc: * ClutterActorCreateChildFunc:
* @item: (type GObject): the item in the model * @item: (type GObject): the item in the model
@ -907,33 +883,19 @@ void clutter_actor_uninhibit_culling
typedef ClutterActor * (* ClutterActorCreateChildFunc) (gpointer item, typedef ClutterActor * (* ClutterActorCreateChildFunc) (gpointer item,
gpointer user_data); gpointer user_data);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_24
void clutter_actor_bind_model (ClutterActor *self, void clutter_actor_bind_model (ClutterActor *self,
GListModel *model, GListModel *model,
ClutterActorCreateChildFunc create_child_func, ClutterActorCreateChildFunc create_child_func,
gpointer user_data, gpointer user_data,
GDestroyNotify notify); GDestroyNotify notify);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_24
void clutter_actor_bind_model_with_properties (ClutterActor *self, void clutter_actor_bind_model_with_properties (ClutterActor *self,
GListModel *model, GListModel *model,
GType child_type, GType child_type,
const char *first_model_property, const char *first_model_property,
...); ...);
CLUTTER_EXPORT
void clutter_actor_pick_box (ClutterActor *self,
ClutterPickContext *pick_context,
const ClutterActorBox *box);
CLUTTER_EXPORT
GList * clutter_actor_peek_stage_views (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_invalidate_transform (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_invalidate_paint_volume (ClutterActor *self);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_ACTOR_H__ */ #endif /* __CLUTTER_ACTOR_H__ */

View File

@ -34,7 +34,9 @@
* #ClutterAlignConstraint is available since Clutter 1.4 * #ClutterAlignConstraint is available since Clutter 1.4
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include "clutter-align-constraint.h" #include "clutter-align-constraint.h"
@ -58,7 +60,6 @@ struct _ClutterAlignConstraint
ClutterActor *actor; ClutterActor *actor;
ClutterActor *source; ClutterActor *source;
ClutterAlignAxis align_axis; ClutterAlignAxis align_axis;
graphene_point_t pivot;
gfloat factor; gfloat factor;
}; };
@ -73,7 +74,6 @@ enum
PROP_SOURCE, PROP_SOURCE,
PROP_ALIGN_AXIS, PROP_ALIGN_AXIS,
PROP_PIVOT_POINT,
PROP_FACTOR, PROP_FACTOR,
PROP_LAST PROP_LAST
@ -86,11 +86,13 @@ G_DEFINE_TYPE (ClutterAlignConstraint,
CLUTTER_TYPE_CONSTRAINT); CLUTTER_TYPE_CONSTRAINT);
static void static void
source_queue_relayout (ClutterActor *actor, source_position_changed (ClutterActor *actor,
ClutterAlignConstraint *align) const ClutterActorBox *allocation,
ClutterAllocationFlags flags,
ClutterAlignConstraint *align)
{ {
if (align->actor != NULL) if (align->actor != NULL)
_clutter_actor_queue_only_relayout (align->actor); clutter_actor_queue_relayout (align->actor);
} }
static void static void
@ -135,41 +137,35 @@ clutter_align_constraint_update_allocation (ClutterConstraint *constraint,
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint); ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint);
gfloat source_width, source_height; gfloat source_width, source_height;
gfloat actor_width, actor_height; gfloat actor_width, actor_height;
gfloat offset_x_start, offset_y_start; gfloat source_x, source_y;
gfloat pivot_x, pivot_y;
if (align->source == NULL) if (align->source == NULL)
return; return;
clutter_actor_box_get_size (allocation, &actor_width, &actor_height); clutter_actor_box_get_size (allocation, &actor_width, &actor_height);
clutter_actor_get_position (align->source, &source_x, &source_y);
clutter_actor_get_size (align->source, &source_width, &source_height); clutter_actor_get_size (align->source, &source_width, &source_height);
pivot_x = align->pivot.x == -1.f
? align->factor
: align->pivot.x;
pivot_y = align->pivot.y == -1.f
? align->factor
: align->pivot.y;
offset_x_start = pivot_x * -actor_width;
offset_y_start = pivot_y * -actor_height;
switch (align->align_axis) switch (align->align_axis)
{ {
case CLUTTER_ALIGN_X_AXIS: case CLUTTER_ALIGN_X_AXIS:
allocation->x1 += offset_x_start + (source_width * align->factor); allocation->x1 = ((source_width - actor_width) * align->factor)
+ source_x;
allocation->x2 = allocation->x1 + actor_width; allocation->x2 = allocation->x1 + actor_width;
break; break;
case CLUTTER_ALIGN_Y_AXIS: case CLUTTER_ALIGN_Y_AXIS:
allocation->y1 += offset_y_start + (source_height * align->factor); allocation->y1 = ((source_height - actor_height) * align->factor)
+ source_y;
allocation->y2 = allocation->y1 + actor_height; allocation->y2 = allocation->y1 + actor_height;
break; break;
case CLUTTER_ALIGN_BOTH: case CLUTTER_ALIGN_BOTH:
allocation->x1 += offset_x_start + (source_width * align->factor); allocation->x1 = ((source_width - actor_width) * align->factor)
allocation->y1 += offset_y_start + (source_height * align->factor); + source_x;
allocation->y1 = ((source_height - actor_height) * align->factor)
+ source_y;
allocation->x2 = allocation->x1 + actor_width; allocation->x2 = allocation->x1 + actor_width;
allocation->y2 = allocation->y1 + actor_height; allocation->y2 = allocation->y1 + actor_height;
break; break;
@ -193,7 +189,7 @@ clutter_align_constraint_dispose (GObject *gobject)
G_CALLBACK (source_destroyed), G_CALLBACK (source_destroyed),
align); align);
g_signal_handlers_disconnect_by_func (align->source, g_signal_handlers_disconnect_by_func (align->source,
G_CALLBACK (source_queue_relayout), G_CALLBACK (source_position_changed),
align); align);
align->source = NULL; align->source = NULL;
} }
@ -219,10 +215,6 @@ clutter_align_constraint_set_property (GObject *gobject,
clutter_align_constraint_set_align_axis (align, g_value_get_enum (value)); clutter_align_constraint_set_align_axis (align, g_value_get_enum (value));
break; break;
case PROP_PIVOT_POINT:
clutter_align_constraint_set_pivot_point (align, g_value_get_boxed (value));
break;
case PROP_FACTOR: case PROP_FACTOR:
clutter_align_constraint_set_factor (align, g_value_get_float (value)); clutter_align_constraint_set_factor (align, g_value_get_float (value));
break; break;
@ -251,16 +243,6 @@ clutter_align_constraint_get_property (GObject *gobject,
g_value_set_enum (value, align->align_axis); g_value_set_enum (value, align->align_axis);
break; break;
case PROP_PIVOT_POINT:
{
graphene_point_t point;
clutter_align_constraint_get_pivot_point (align, &point);
g_value_set_boxed (value, &point);
}
break;
case PROP_FACTOR: case PROP_FACTOR:
g_value_set_float (value, align->factor); g_value_set_float (value, align->factor);
break; break;
@ -314,30 +296,6 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
CLUTTER_ALIGN_X_AXIS, CLUTTER_ALIGN_X_AXIS,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT); CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
/**
* ClutterAlignConstraint:pivot-point:
*
* The pivot point used by the constraint. The pivot point is the
* point in the constraint actor around which the aligning is applied,
* with (0, 0) being the top left corner of the actor and (1, 1) the
* bottom right corner of the actor.
*
* For example, setting the pivot point to (0.5, 0.5) and using a factor
* of 1 for both axes will align the actors horizontal and vertical
* center point with the bottom right corner of the source actor.
*
* By default, the pivot point is set to (-1, -1), which means it's not
* used and the constrained actor will be aligned to always stay inside
* the source actor.
*/
obj_props[PROP_PIVOT_POINT] =
g_param_spec_boxed ("pivot-point",
P_("Pivot point"),
P_("The pivot point"),
GRAPHENE_TYPE_POINT,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/** /**
* ClutterAlignConstraint:factor: * ClutterAlignConstraint:factor:
* *
@ -370,8 +328,6 @@ clutter_align_constraint_init (ClutterAlignConstraint *self)
self->actor = NULL; self->actor = NULL;
self->source = NULL; self->source = NULL;
self->align_axis = CLUTTER_ALIGN_X_AXIS; self->align_axis = CLUTTER_ALIGN_X_AXIS;
self->pivot.x = -1.f;
self->pivot.y = -1.f;
self->factor = 0.0f; self->factor = 0.0f;
} }
@ -449,15 +405,15 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align,
G_CALLBACK (source_destroyed), G_CALLBACK (source_destroyed),
align); align);
g_signal_handlers_disconnect_by_func (old_source, g_signal_handlers_disconnect_by_func (old_source,
G_CALLBACK (source_queue_relayout), G_CALLBACK (source_position_changed),
align); align);
} }
align->source = source; align->source = source;
if (align->source != NULL) if (align->source != NULL)
{ {
g_signal_connect (align->source, "queue-relayout", g_signal_connect (align->source, "allocation-changed",
G_CALLBACK (source_queue_relayout), G_CALLBACK (source_position_changed),
align); align);
g_signal_connect (align->source, "destroy", g_signal_connect (align->source, "destroy",
G_CALLBACK (source_destroyed), G_CALLBACK (source_destroyed),
@ -534,60 +490,6 @@ clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align)
return align->align_axis; return align->align_axis;
} }
/**
* clutter_align_constraint_set_pivot_point:
* @align: a #ClutterAlignConstraint
* @pivot_point: A #GraphenePoint
*
* Sets the pivot point used by the constraint, the pivot point is the
* point in the constraint actor around which the aligning is applied,
* with (0, 0) being the top left corner of the actor and (1, 1) the
* bottom right corner of the actor.
*
* If -1 is used, the pivot point is unset and the constrained actor
* will be aligned to always stay inside the source actor.
*/
void
clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
const graphene_point_t *pivot_point)
{
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
g_return_if_fail (pivot_point != NULL);
g_return_if_fail (pivot_point->x == -1.f ||
(pivot_point->x >= 0.f && pivot_point->x <= 1.f));
g_return_if_fail (pivot_point->y == -1.f ||
(pivot_point->y >= 0.f && pivot_point->y <= 1.f));
if (graphene_point_equal (&align->pivot, pivot_point))
return;
align->pivot = *pivot_point;
if (align->actor != NULL)
clutter_actor_queue_relayout (align->actor);
g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_PIVOT_POINT]);
}
/**
* clutter_align_constraint_get_pivot_point
* @align: a #ClutterAlignConstraint
* @pivot_point: (out caller-allocates): return location for a #GraphenePoint
*
* Gets the pivot point used by the constraint set with
* clutter_align_constraint_set_pivot_point(). If no custom pivot
* point is set, -1 is set.
*/
void
clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
graphene_point_t *pivot_point)
{
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
g_return_if_fail (pivot_point != NULL);
*pivot_point = align->pivot;
}
/** /**
* clutter_align_constraint_set_factor: * clutter_align_constraint_set_factor:
* @align: a #ClutterAlignConstraint * @align: a #ClutterAlignConstraint

View File

@ -48,34 +48,28 @@ G_BEGIN_DECLS
typedef struct _ClutterAlignConstraint ClutterAlignConstraint; typedef struct _ClutterAlignConstraint ClutterAlignConstraint;
typedef struct _ClutterAlignConstraintClass ClutterAlignConstraintClass; typedef struct _ClutterAlignConstraintClass ClutterAlignConstraintClass;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType clutter_align_constraint_get_type (void) G_GNUC_CONST; GType clutter_align_constraint_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterConstraint *clutter_align_constraint_new (ClutterActor *source, ClutterConstraint *clutter_align_constraint_new (ClutterActor *source,
ClutterAlignAxis axis, ClutterAlignAxis axis,
gfloat factor); gfloat factor);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_align_constraint_set_source (ClutterAlignConstraint *align, void clutter_align_constraint_set_source (ClutterAlignConstraint *align,
ClutterActor *source); ClutterActor *source);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterActor * clutter_align_constraint_get_source (ClutterAlignConstraint *align); ClutterActor * clutter_align_constraint_get_source (ClutterAlignConstraint *align);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align, void clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
ClutterAlignAxis axis); ClutterAlignAxis axis);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align); ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
const graphene_point_t *pivot_point);
CLUTTER_EXPORT
void clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
graphene_point_t *pivot_point);
CLUTTER_EXPORT
void clutter_align_constraint_set_factor (ClutterAlignConstraint *align, void clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
gfloat factor); gfloat factor);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
gfloat clutter_align_constraint_get_factor (ClutterAlignConstraint *align); gfloat clutter_align_constraint_get_factor (ClutterAlignConstraint *align);
G_END_DECLS G_END_DECLS

View File

@ -27,23 +27,39 @@
* @short_description: Interface for animatable classes * @short_description: Interface for animatable classes
* *
* #ClutterAnimatable is an interface that allows a #GObject class * #ClutterAnimatable is an interface that allows a #GObject class
* to control how an actor will animate a property. * to control how a #ClutterAnimation will animate a property.
* *
* Each #ClutterAnimatable should implement the * Each #ClutterAnimatable should implement the
* #ClutterAnimatableInterface.interpolate_property() virtual function of the * #ClutterAnimatableIface.interpolate_property() virtual function of the
* interface to compute the animation state between two values of an interval * interface to compute the animation state between two values of an interval
* depending on a progress factor, expressed as a floating point value. * depending on a progress factor, expressed as a floating point value.
* *
* If a #ClutterAnimatable is animated by a #ClutterAnimation
* instance, the #ClutterAnimation will call
* clutter_animatable_interpolate_property() passing the name of the
* currently animated property; the values interval; and the progress factor.
* The #ClutterAnimatable implementation should return the computed value for
* the animated
* property.
*
* #ClutterAnimatable is available since Clutter 1.0 * #ClutterAnimatable is available since Clutter 1.0
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "clutter-animatable.h" #include "clutter-animatable.h"
#include "clutter-interval.h" #include "clutter-interval.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-private.h" #include "clutter-private.h"
#include "deprecated/clutter-animatable.h"
#include "deprecated/clutter-animation.h"
typedef ClutterAnimatableIface ClutterAnimatableInterface;
G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT); G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT);
static void static void
@ -51,6 +67,80 @@ clutter_animatable_default_init (ClutterAnimatableInterface *iface)
{ {
} }
/**
* clutter_animatable_animate_property:
* @animatable: a #ClutterAnimatable
* @animation: a #ClutterAnimation
* @property_name: the name of the animated property
* @initial_value: the initial value of the animation interval
* @final_value: the final value of the animation interval
* @progress: the progress factor
* @value: return location for the animation value
*
* Calls the animate_property() virtual function for @animatable.
*
* The @initial_value and @final_value #GValue<!-- -->s must contain
* the same type; @value must have been initialized to the same
* type of @initial_value and @final_value.
*
* All implementation of the #ClutterAnimatable interface must
* implement this function.
*
* Return value: %TRUE if the value has been validated and can
* be applied to the #ClutterAnimatable, and %FALSE otherwise
*
* Since: 1.0
*
* Deprecated: 1.8: Use clutter_animatable_interpolate_value()
* instead
*/
gboolean
clutter_animatable_animate_property (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *initial_value,
const GValue *final_value,
gdouble progress,
GValue *value)
{
ClutterAnimatableIface *iface;
gboolean res;
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE);
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), FALSE);
g_return_val_if_fail (property_name != NULL, FALSE);
g_return_val_if_fail (initial_value != NULL && final_value != NULL, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (initial_value) != G_TYPE_INVALID, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (final_value) != G_TYPE_INVALID, FALSE);
g_return_val_if_fail (value != NULL, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (value) == G_VALUE_TYPE (initial_value) &&
G_VALUE_TYPE (value) == G_VALUE_TYPE (final_value),
FALSE);
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
if (iface->animate_property == NULL)
{
ClutterInterval *interval;
interval = clutter_animation_get_interval (animation, property_name);
if (interval == NULL)
return FALSE;
res = clutter_animatable_interpolate_value (animatable, property_name,
interval,
progress,
value);
}
else
res = iface->animate_property (animatable, animation,
property_name,
initial_value, final_value,
progress,
value);
return res;
}
/** /**
* clutter_animatable_find_property: * clutter_animatable_find_property:
* @animatable: a #ClutterAnimatable * @animatable: a #ClutterAnimatable
@ -67,7 +157,7 @@ GParamSpec *
clutter_animatable_find_property (ClutterAnimatable *animatable, clutter_animatable_find_property (ClutterAnimatable *animatable,
const gchar *property_name) const gchar *property_name)
{ {
ClutterAnimatableInterface *iface; ClutterAnimatableIface *iface;
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL); g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL);
g_return_val_if_fail (property_name != NULL, NULL); g_return_val_if_fail (property_name != NULL, NULL);
@ -97,7 +187,7 @@ clutter_animatable_get_initial_state (ClutterAnimatable *animatable,
const gchar *property_name, const gchar *property_name,
GValue *value) GValue *value)
{ {
ClutterAnimatableInterface *iface; ClutterAnimatableIface *iface;
g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable));
g_return_if_fail (property_name != NULL); g_return_if_fail (property_name != NULL);
@ -126,7 +216,7 @@ clutter_animatable_set_final_state (ClutterAnimatable *animatable,
const gchar *property_name, const gchar *property_name,
const GValue *value) const GValue *value)
{ {
ClutterAnimatableInterface *iface; ClutterAnimatableIface *iface;
g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable));
g_return_if_fail (property_name != NULL); g_return_if_fail (property_name != NULL);
@ -172,7 +262,7 @@ clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
gdouble progress, gdouble progress,
GValue *value) GValue *value)
{ {
ClutterAnimatableInterface *iface; ClutterAnimatableIface *iface;
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE); g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE);
g_return_val_if_fail (property_name != NULL, FALSE); g_return_val_if_fail (property_name != NULL, FALSE);
@ -194,25 +284,3 @@ clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
else else
return clutter_interval_compute_value (interval, progress, value); return clutter_interval_compute_value (interval, progress, value);
} }
/**
* clutter_animatable_get_actor:
* @animatable: a #ClutterAnimatable
*
* Get animated actor.
*
* Return value: (transfer none): a #ClutterActor
*/
ClutterActor *
clutter_animatable_get_actor (ClutterAnimatable *animatable)
{
ClutterAnimatableInterface *iface;
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL);
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
g_return_val_if_fail (iface->get_actor, NULL);
return iface->get_actor (animatable);
}

View File

@ -33,15 +33,26 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_ANIMATABLE (clutter_animatable_get_type ()) #define CLUTTER_TYPE_ANIMATABLE (clutter_animatable_get_type ())
#define CLUTTER_ANIMATABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ANIMATABLE, ClutterAnimatable))
#define CLUTTER_IS_ANIMATABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ANIMATABLE))
#define CLUTTER_ANIMATABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_ANIMATABLE, ClutterAnimatableIface))
CLUTTER_EXPORT typedef struct _ClutterAnimatableIface ClutterAnimatableIface;
G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable,
CLUTTER, ANIMATABLE,
GObject)
/** /**
* ClutterAnimatableInterface: * ClutterAnimatable:
*
* #ClutterAnimatable is an opaque structure whose members cannot be directly
* accessed
*
* Since: 1.0
*/
/**
* ClutterAnimatableIface:
* @animate_property: virtual function for custom interpolation of a
* property. This virtual function is deprecated
* @find_property: virtual function for retrieving the #GParamSpec of * @find_property: virtual function for retrieving the #GParamSpec of
* an animatable property * an animatable property
* @get_initial_state: virtual function for retrieving the initial * @get_initial_state: virtual function for retrieving the initial
@ -50,16 +61,25 @@ G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable,
* animatable property * animatable property
* @interpolate_value: virtual function for interpolating the progress * @interpolate_value: virtual function for interpolating the progress
* of a property * of a property
* @get_actor: virtual function for getting associated actor *
* Base interface for #GObject<!-- -->s that can be animated by a
* a #ClutterAnimation.
* *
* Since: 1.0 * Since: 1.0
*/ */
struct _ClutterAnimatableInterface struct _ClutterAnimatableIface
{ {
/*< private >*/ /*< private >*/
GTypeInterface parent_iface; GTypeInterface parent_iface;
/*< public >*/ /*< public >*/
gboolean (* animate_property) (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *initial_value,
const GValue *final_value,
gdouble progress,
GValue *value);
GParamSpec *(* find_property) (ClutterAnimatable *animatable, GParamSpec *(* find_property) (ClutterAnimatable *animatable,
const gchar *property_name); const gchar *property_name);
void (* get_initial_state) (ClutterAnimatable *animatable, void (* get_initial_state) (ClutterAnimatable *animatable,
@ -73,30 +93,29 @@ struct _ClutterAnimatableInterface
ClutterInterval *interval, ClutterInterval *interval,
gdouble progress, gdouble progress,
GValue *value); GValue *value);
ClutterActor * (* get_actor) (ClutterAnimatable *animatable);
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
GType clutter_animatable_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_0
GParamSpec *clutter_animatable_find_property (ClutterAnimatable *animatable, GParamSpec *clutter_animatable_find_property (ClutterAnimatable *animatable,
const gchar *property_name); const gchar *property_name);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_animatable_get_initial_state (ClutterAnimatable *animatable, void clutter_animatable_get_initial_state (ClutterAnimatable *animatable,
const gchar *property_name, const gchar *property_name,
GValue *value); GValue *value);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_animatable_set_final_state (ClutterAnimatable *animatable, void clutter_animatable_set_final_state (ClutterAnimatable *animatable,
const gchar *property_name, const gchar *property_name,
const GValue *value); const GValue *value);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_8
gboolean clutter_animatable_interpolate_value (ClutterAnimatable *animatable, gboolean clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
const gchar *property_name, const gchar *property_name,
ClutterInterval *interval, ClutterInterval *interval,
gdouble progress, gdouble progress,
GValue *value); GValue *value);
CLUTTER_EXPORT
ClutterActor * clutter_animatable_get_actor (ClutterAnimatable *animatable);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_ANIMATABLE_H__ */ #endif /* __CLUTTER_ANIMATABLE_H__ */

View File

@ -30,8 +30,11 @@
#ifndef __GI_SCANNER__ #ifndef __GI_SCANNER__
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorMeta, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAlignConstraint, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAlignConstraint, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAnimatable, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindConstraint, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindConstraint, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindingPool, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindingPool, g_object_unref)
@ -41,15 +44,21 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBoxLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBrightnessContrastEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBrightnessContrastEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterCanvas, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterCanvas, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterChildMeta, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterChildMeta, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClickAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClone, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClone, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColorizeEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColorizeEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContent, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeformEffect, 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 (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) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGestureAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGridLayout, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGridLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterImage, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterImage, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInputDevice, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInputDevice, g_object_unref)
@ -83,10 +92,14 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterZoomAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintContext, clutter_paint_context_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMatrix, clutter_matrix_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathNode, clutter_path_node_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathNode, clutter_path_node_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPoint, clutter_point_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterRect, clutter_rect_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterSize, clutter_size_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterVertex, clutter_vertex_free)
#endif /* __GI_SCANNER__ */ #endif /* __GI_SCANNER__ */

View File

@ -23,9 +23,11 @@
#define __CLUTTER_BACKEND_PRIVATE_H__ #define __CLUTTER_BACKEND_PRIVATE_H__
#include <clutter/clutter-backend.h> #include <clutter/clutter-backend.h>
#include <clutter/clutter-seat.h> #include <clutter/clutter-device-manager.h>
#include <clutter/clutter-stage-window.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_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_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)) #define CLUTTER_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND, ClutterBackendClass))
@ -46,6 +48,8 @@ struct _ClutterBackend
CoglOnscreen *dummy_onscreen; CoglOnscreen *dummy_onscreen;
ClutterDeviceManager *device_manager;
cairo_font_options_t *font_options; cairo_font_options_t *font_options;
gchar *font_name; gchar *font_name;
@ -53,9 +57,7 @@ struct _ClutterBackend
gfloat units_per_em; gfloat units_per_em;
gint32 units_serial; gint32 units_serial;
float fallback_resource_scale; GList *event_translators;
ClutterStageWindow *stage_window;
ClutterInputMethod *input_method; ClutterInputMethod *input_method;
}; };
@ -73,6 +75,7 @@ struct _ClutterBackendClass
ClutterStageWindow * (* create_stage) (ClutterBackend *backend, ClutterStageWindow * (* create_stage) (ClutterBackend *backend,
ClutterStage *wrapper, ClutterStage *wrapper,
GError **error); GError **error);
void (* init_events) (ClutterBackend *backend);
void (* init_features) (ClutterBackend *backend); void (* init_features) (ClutterBackend *backend);
void (* add_options) (ClutterBackend *backend, void (* add_options) (ClutterBackend *backend,
GOptionGroup *group); GOptionGroup *group);
@ -85,14 +88,21 @@ struct _ClutterBackendClass
GError **error); GError **error);
gboolean (* create_context) (ClutterBackend *backend, gboolean (* create_context) (ClutterBackend *backend,
GError **error); 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, gboolean (* translate_event) (ClutterBackend *backend,
gpointer native, gpointer native,
ClutterEvent *event); ClutterEvent *event);
ClutterSeat * (* get_default_seat) (ClutterBackend *backend); PangoDirection (* get_keymap_direction) (ClutterBackend *backend);
gboolean (* is_display_server) (ClutterBackend *backend); void (* bell_notify) (ClutterBackend *backend);
/* signals */ /* signals */
void (* resolution_changed) (ClutterBackend *backend); void (* resolution_changed) (ClutterBackend *backend);
@ -115,32 +125,37 @@ gboolean _clutter_backend_pre_parse (Clutter
gboolean _clutter_backend_post_parse (ClutterBackend *backend, gboolean _clutter_backend_post_parse (ClutterBackend *backend,
GError **error); GError **error);
CLUTTER_EXPORT void _clutter_backend_init_events (ClutterBackend *backend);
void _clutter_backend_copy_event_data (ClutterBackend *backend,
const ClutterEvent *src,
ClutterEvent *dest);
void _clutter_backend_free_event_data (ClutterBackend *backend,
ClutterEvent *event);
gboolean _clutter_backend_translate_event (ClutterBackend *backend, gboolean _clutter_backend_translate_event (ClutterBackend *backend,
gpointer native, gpointer native,
ClutterEvent *event); ClutterEvent *event);
CLUTTER_AVAILABLE_IN_MUTTER
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); ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend, gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend,
PangoFontDescription *font_desc); PangoFontDescription *font_desc);
gint32 _clutter_backend_get_units_serial (ClutterBackend *backend); gint32 _clutter_backend_get_units_serial (ClutterBackend *backend);
PangoDirection _clutter_backend_get_keymap_direction (ClutterBackend *backend);
CLUTTER_AVAILABLE_IN_MUTTER
void _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend);
void clutter_set_allowed_drivers (const char *drivers); void clutter_set_allowed_drivers (const char *drivers);
CLUTTER_EXPORT void clutter_try_set_windowing_backend (const char *drivers);
ClutterStageWindow * clutter_backend_get_stage_window (ClutterBackend *backend);
CLUTTER_EXPORT
void clutter_backend_set_fallback_resource_scale (ClutterBackend *backend,
float fallback_resource_scale);
float clutter_backend_get_fallback_resource_scale (ClutterBackend *backend);
gboolean clutter_backend_is_display_server (ClutterBackend *backend);
CLUTTER_EXPORT
void clutter_backend_destroy (ClutterBackend *backend);
G_END_DECLS G_END_DECLS

View File

@ -38,7 +38,11 @@
* #ClutterBackend is available since Clutter 0.4 * #ClutterBackend is available since Clutter 0.4
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-backend-private.h" #include "clutter-backend-private.h"
#include "clutter-debug.h" #include "clutter-debug.h"
@ -49,9 +53,34 @@
#include "clutter-stage-manager-private.h" #include "clutter-stage-manager-private.h"
#include "clutter-stage-private.h" #include "clutter-stage-private.h"
#include "clutter-stage-window.h" #include "clutter-stage-window.h"
#include "clutter-version.h"
#include "clutter-device-manager-private.h"
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "deprecated/clutter-backend.h"
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
#include "wayland/clutter-wayland-compositor.h"
#endif
#include <cogl/cogl.h> #include <cogl/cogl.h>
#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
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
#include <cogl/cogl-wayland-server.h>
#include <wayland-server.h>
#include "wayland/clutter-wayland-compositor.h"
#endif
#define DEFAULT_FONT_NAME "Sans 10" #define DEFAULT_FONT_NAME "Sans 10"
enum enum
@ -67,6 +96,12 @@ G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT)
static guint backend_signals[LAST_SIGNAL] = { 0, }; static guint backend_signals[LAST_SIGNAL] = { 0, };
/* Global for being able to specify a compositor side wayland display
* pointer before clutter initialization */
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
static struct wl_display *_wayland_compositor_display;
#endif
static void static void
clutter_backend_dispose (GObject *gobject) clutter_backend_dispose (GObject *gobject)
{ {
@ -75,22 +110,28 @@ clutter_backend_dispose (GObject *gobject)
/* clear the events still in the queue of the main context */ /* clear the events still in the queue of the main context */
_clutter_clear_events_queue (); _clutter_clear_events_queue ();
g_clear_object (&backend->dummy_onscreen); /* remove all event translators */
if (backend->stage_window) g_clear_pointer (&backend->event_translators, g_list_free);
{
g_object_remove_weak_pointer (G_OBJECT (backend->stage_window),
(gpointer *) &backend->stage_window);
backend->stage_window = NULL;
}
g_clear_pointer (&backend->cogl_source, g_source_destroy); g_clear_pointer (&backend->dummy_onscreen, cogl_object_unref);
g_clear_pointer (&backend->font_name, g_free);
g_clear_pointer (&backend->font_options, cairo_font_options_destroy);
g_clear_object (&backend->input_method);
G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject);
} }
static void
clutter_backend_finalize (GObject *gobject)
{
ClutterBackend *backend = CLUTTER_BACKEND (gobject);
g_source_destroy (backend->cogl_source);
g_free (backend->font_name);
clutter_backend_set_font_options (backend, NULL);
g_clear_object (&backend->input_method);
G_OBJECT_CLASS (clutter_backend_parent_class)->finalize (gobject);
}
static gfloat static gfloat
get_units_per_em (ClutterBackend *backend, get_units_per_em (ClutterBackend *backend,
PangoFontDescription *font_desc) PangoFontDescription *font_desc)
@ -189,20 +230,22 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
{ {
ClutterBackendClass *klass; ClutterBackendClass *klass;
CoglSwapChain *swap_chain; CoglSwapChain *swap_chain;
GError *internal_error;
klass = CLUTTER_BACKEND_GET_CLASS (backend); klass = CLUTTER_BACKEND_GET_CLASS (backend);
swap_chain = NULL; swap_chain = NULL;
internal_error = NULL;
CLUTTER_NOTE (BACKEND, "Creating Cogl renderer"); CLUTTER_NOTE (BACKEND, "Creating Cogl renderer");
backend->cogl_renderer = klass->get_renderer (backend, error); backend->cogl_renderer = klass->get_renderer (backend, &internal_error);
if (backend->cogl_renderer == NULL) if (backend->cogl_renderer == NULL)
goto error; goto error;
CLUTTER_NOTE (BACKEND, "Connecting the renderer"); CLUTTER_NOTE (BACKEND, "Connecting the renderer");
cogl_renderer_set_driver (backend->cogl_renderer, driver_id); cogl_renderer_set_driver (backend->cogl_renderer, driver_id);
if (!cogl_renderer_connect (backend->cogl_renderer, error)) if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error))
goto error; goto error;
CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain"); CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain");
@ -214,7 +257,7 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
backend->cogl_display = klass->get_display (backend, backend->cogl_display = klass->get_display (backend,
backend->cogl_renderer, backend->cogl_renderer,
swap_chain, swap_chain,
error); &internal_error);
} }
else else
{ {
@ -230,7 +273,7 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
*/ */
res = cogl_renderer_check_onscreen_template (backend->cogl_renderer, res = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
tmpl, tmpl,
error); &internal_error);
if (!res) if (!res)
goto error; goto error;
@ -244,12 +287,17 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
if (backend->cogl_display == NULL) if (backend->cogl_display == NULL)
goto error; goto error;
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
cogl_wayland_display_set_compositor_display (backend->cogl_display,
_wayland_compositor_display);
#endif
CLUTTER_NOTE (BACKEND, "Setting up the display"); CLUTTER_NOTE (BACKEND, "Setting up the display");
if (!cogl_display_setup (backend->cogl_display, error)) if (!cogl_display_setup (backend->cogl_display, &internal_error))
goto error; goto error;
CLUTTER_NOTE (BACKEND, "Creating the Cogl context"); CLUTTER_NOTE (BACKEND, "Creating the Cogl context");
backend->cogl_context = cogl_context_new (backend->cogl_display, error); backend->cogl_context = cogl_context_new (backend->cogl_display, &internal_error);
if (backend->cogl_context == NULL) if (backend->cogl_context == NULL)
goto error; goto error;
@ -355,7 +403,7 @@ clutter_backend_real_create_context (ClutterBackend *backend,
else else
g_set_error_literal (error, CLUTTER_INIT_ERROR, g_set_error_literal (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND, 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; return FALSE;
} }
@ -382,6 +430,14 @@ clutter_backend_real_get_features (ClutterBackend *backend)
flags |= CLUTTER_FEATURE_STAGE_STATIC; flags |= CLUTTER_FEATURE_STAGE_STATIC;
} }
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE))
{
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling");
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
}
else
CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling");
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT)) if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT))
{ {
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers complete events"); CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers complete events");
@ -391,8 +447,23 @@ clutter_backend_real_get_features (ClutterBackend *backend)
return flags; return flags;
} }
static const char *allowed_backends;
static ClutterBackend * (* custom_backend_func) (void); static ClutterBackend * (* custom_backend_func) (void);
static const struct {
const char *name;
ClutterBackend * (* create_backend) (void);
} available_backends[] = {
#ifdef CLUTTER_WINDOWING_X11
{ CLUTTER_WINDOWING_X11, clutter_backend_x11_new },
#endif
#ifdef CLUTTER_WINDOWING_EGL
{ CLUTTER_WINDOWING_EGL, clutter_backend_egl_native_new },
#endif
{ NULL, NULL },
};
void void
clutter_set_custom_backend_func (ClutterBackend *(* func) (void)) clutter_set_custom_backend_func (ClutterBackend *(* func) (void))
{ {
@ -402,23 +473,148 @@ clutter_set_custom_backend_func (ClutterBackend *(* func) (void))
ClutterBackend * ClutterBackend *
_clutter_create_backend (void) _clutter_create_backend (void)
{ {
const char *backends_list;
ClutterBackend *retval; ClutterBackend *retval;
gboolean allow_any;
char **backends;
int i;
g_return_val_if_fail (custom_backend_func, NULL); if (custom_backend_func)
{
retval = custom_backend_func ();
retval = custom_backend_func (); if (!retval)
if (!retval) g_error ("Failed to create custom backend.");
g_error ("Failed to create custom backend.");
return retval;
}
if (allowed_backends == NULL)
allowed_backends = "*";
allow_any = strstr (allowed_backends, "*") != NULL;
backends_list = g_getenv ("CLUTTER_BACKEND");
if (backends_list == NULL)
backends_list = allowed_backends;
backends = g_strsplit (backends_list, ",", 0);
retval = NULL;
for (i = 0; retval == NULL && backends[i] != NULL; i++)
{
const char *backend = backends[i];
gboolean is_any = g_str_equal (backend, "*");
int j;
for (j = 0; available_backends[j].name != NULL; j++)
{
if ((is_any && allow_any) ||
(is_any && strstr (allowed_backends, available_backends[j].name)) ||
g_str_equal (backend, available_backends[j].name))
{
retval = available_backends[j].create_backend ();
if (retval != NULL)
break;
}
}
}
g_strfreev (backends);
if (retval == NULL)
g_error ("No default Clutter backend found.");
return retval; return retval;
} }
static void
clutter_backend_real_init_events (ClutterBackend *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 *
clutter_backend_real_get_device_manager (ClutterBackend *backend)
{
if (G_UNLIKELY (backend->device_manager == NULL))
{
g_critical ("No device manager available, expect broken input");
return NULL;
}
return backend->device_manager;
}
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 static void
clutter_backend_class_init (ClutterBackendClass *klass) clutter_backend_class_init (ClutterBackendClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = clutter_backend_dispose; gobject_class->dispose = clutter_backend_dispose;
gobject_class->finalize = clutter_backend_finalize;
/** /**
* ClutterBackend::resolution-changed: * ClutterBackend::resolution-changed:
@ -434,7 +630,8 @@ clutter_backend_class_init (ClutterBackendClass *klass)
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed), G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed),
NULL, NULL, NULL, NULL, NULL,
_clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
/** /**
@ -451,7 +648,8 @@ clutter_backend_class_init (ClutterBackendClass *klass)
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterBackendClass, font_changed), G_STRUCT_OFFSET (ClutterBackendClass, font_changed),
NULL, NULL, NULL, NULL, NULL,
_clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
/** /**
@ -468,12 +666,16 @@ clutter_backend_class_init (ClutterBackendClass *klass)
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterBackendClass, settings_changed), G_STRUCT_OFFSET (ClutterBackendClass, settings_changed),
NULL, NULL, NULL, NULL, NULL,
_clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
klass->resolution_changed = clutter_backend_real_resolution_changed; klass->resolution_changed = clutter_backend_real_resolution_changed;
klass->font_changed = clutter_backend_real_font_changed; klass->font_changed = clutter_backend_real_font_changed;
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->create_context = clutter_backend_real_create_context;
klass->get_features = clutter_backend_real_get_features; klass->get_features = clutter_backend_real_get_features;
} }
@ -484,9 +686,7 @@ clutter_backend_init (ClutterBackend *self)
self->units_per_em = -1.0; self->units_per_em = -1.0;
self->units_serial = 1; self->units_serial = 1;
self->dummy_onscreen = NULL; self->dummy_onscreen = COGL_INVALID_HANDLE;
self->fallback_resource_scale = 1.f;
} }
void void
@ -554,10 +754,6 @@ _clutter_backend_create_stage (ClutterBackend *backend,
g_assert (CLUTTER_IS_STAGE_WINDOW (stage_window)); 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; return stage_window;
} }
@ -612,6 +808,17 @@ _clutter_backend_get_features (ClutterBackend *backend)
return 0; return 0;
} }
void
_clutter_backend_init_events (ClutterBackend *backend)
{
ClutterBackendClass *klass;
g_assert (CLUTTER_IS_BACKEND (backend));
klass = CLUTTER_BACKEND_GET_CLASS (backend);
klass->init_events (backend);
}
gfloat gfloat
_clutter_backend_get_units_per_em (ClutterBackend *backend, _clutter_backend_get_units_per_em (ClutterBackend *backend,
PangoFontDescription *font_desc) PangoFontDescription *font_desc)
@ -626,6 +833,44 @@ _clutter_backend_get_units_per_em (ClutterBackend *backend,
return backend->units_per_em; return backend->units_per_em;
} }
void
_clutter_backend_copy_event_data (ClutterBackend *backend,
const ClutterEvent *src,
ClutterEvent *dest)
{
ClutterEventExtenderInterface *iface;
ClutterBackendClass *klass;
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)
{
ClutterEventExtenderInterface *iface;
ClutterBackendClass *klass;
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);
}
/** /**
* clutter_get_default_backend: * clutter_get_default_backend:
* *
@ -648,6 +893,129 @@ clutter_get_default_backend (void)
return clutter_context->backend; return clutter_context->backend;
} }
/**
* clutter_backend_set_double_click_time:
* @backend: a #ClutterBackend
* @msec: milliseconds between two button press events
*
* Sets the maximum time between two button press events, used to
* verify whether it's a double click event or not.
*
* Since: 0.4
*
* Deprecated: 1.4: Use #ClutterSettings:double-click-time instead
*/
void
clutter_backend_set_double_click_time (ClutterBackend *backend,
guint msec)
{
ClutterSettings *settings = clutter_settings_get_default ();
g_object_set (settings, "double-click-time", msec, NULL);
}
/**
* clutter_backend_get_double_click_time:
* @backend: a #ClutterBackend
*
* Gets the maximum time between two button press events, as set
* by clutter_backend_set_double_click_time().
*
* Return value: a time in milliseconds
*
* Since: 0.4
*
* Deprecated: 1.4: Use #ClutterSettings:double-click-time instead
*/
guint
clutter_backend_get_double_click_time (ClutterBackend *backend)
{
ClutterSettings *settings = clutter_settings_get_default ();
gint retval;
g_object_get (settings, "double-click-time", &retval, NULL);
return retval;
}
/**
* clutter_backend_set_double_click_distance:
* @backend: a #ClutterBackend
* @distance: a distance, in pixels
*
* Sets the maximum distance used to verify a double click event.
*
* Since: 0.4
*
* Deprecated: 1.4: Use #ClutterSettings:double-click-distance instead
*/
void
clutter_backend_set_double_click_distance (ClutterBackend *backend,
guint distance)
{
ClutterSettings *settings = clutter_settings_get_default ();
g_object_set (settings, "double-click-distance", distance, NULL);
}
/**
* clutter_backend_get_double_click_distance:
* @backend: a #ClutterBackend
*
* Retrieves the distance used to verify a double click event
*
* Return value: a distance, in pixels.
*
* Since: 0.4
*
* Deprecated: 1.4: Use #ClutterSettings:double-click-distance instead
*/
guint
clutter_backend_get_double_click_distance (ClutterBackend *backend)
{
ClutterSettings *settings = clutter_settings_get_default ();
gint retval;
g_object_get (settings, "double-click-distance", &retval, NULL);
return retval;
}
/**
* clutter_backend_set_resolution:
* @backend: a #ClutterBackend
* @dpi: the resolution in "dots per inch" (Physical inches aren't
* actually involved; the terminology is conventional).
*
* Sets the resolution for font handling on the screen. This is a
* scale factor between points specified in a #PangoFontDescription
* and cairo units. The default value is 96, meaning that a 10 point
* font will be 13 units high. (10 * 96. / 72. = 13.3).
*
* Applications should never need to call this function.
*
* Since: 0.4
*
* Deprecated: 1.4: Use #ClutterSettings:font-dpi instead
*/
void
clutter_backend_set_resolution (ClutterBackend *backend,
gdouble dpi)
{
ClutterSettings *settings;
gint resolution;
g_return_if_fail (CLUTTER_IS_BACKEND (backend));
if (dpi < 0)
resolution = -1;
else
resolution = dpi * 1024;
settings = clutter_settings_get_default ();
g_object_set (settings, "font-dpi", resolution, NULL);
}
/** /**
* clutter_backend_get_resolution: * clutter_backend_get_resolution:
* @backend: a #ClutterBackend * @backend: a #ClutterBackend
@ -753,6 +1121,61 @@ clutter_backend_get_font_options (ClutterBackend *backend)
return backend->font_options; return backend->font_options;
} }
/**
* clutter_backend_set_font_name:
* @backend: a #ClutterBackend
* @font_name: the name of the font
*
* Sets the default font to be used by Clutter. The @font_name string
* must either be %NULL, which means that the font name from the
* default #ClutterBackend will be used; or be something that can
* be parsed by the pango_font_description_from_string() function.
*
* Since: 1.0
*
* Deprecated: 1.4: Use #ClutterSettings:font-name instead
*/
void
clutter_backend_set_font_name (ClutterBackend *backend,
const gchar *font_name)
{
ClutterSettings *settings = clutter_settings_get_default ();
g_object_set (settings, "font-name", font_name, NULL);
}
/**
* clutter_backend_get_font_name:
* @backend: a #ClutterBackend
*
* Retrieves the default font name as set by
* clutter_backend_set_font_name().
*
* Return value: the font name for the backend. The returned string is
* owned by the #ClutterBackend and should never be modified or freed
*
* Since: 1.0
*
* Deprecated: 1.4: Use #ClutterSettings:font-name instead
*/
const gchar *
clutter_backend_get_font_name (ClutterBackend *backend)
{
ClutterSettings *settings;
g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL);
settings = clutter_settings_get_default ();
/* XXX yuck. but we return a const pointer, so we need to
* store it in the backend
*/
g_free (backend->font_name);
g_object_get (settings, "font-name", &backend->font_name, NULL);
return backend->font_name;
}
gint32 gint32
_clutter_backend_get_units_serial (ClutterBackend *backend) _clutter_backend_get_units_serial (ClutterBackend *backend)
{ {
@ -769,6 +1192,28 @@ _clutter_backend_translate_event (ClutterBackend *backend,
event); 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) * clutter_backend_get_cogl_context: (skip)
* @backend: a #ClutterBackend * @backend: a #ClutterBackend
@ -795,6 +1240,119 @@ clutter_backend_get_cogl_context (ClutterBackend *backend)
return backend->cogl_context; return backend->cogl_context;
} }
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
/**
* clutter_wayland_set_compositor_display:
* @display: A compositor side struct wl_display pointer
*
* This informs Clutter of your compositor side Wayland display
* object. This must be called before calling clutter_init().
*
* Since: 1.8
* Stability: unstable
*/
void
clutter_wayland_set_compositor_display (void *display)
{
if (_clutter_context_is_initialized ())
{
g_warning ("%s() can only be used before calling clutter_init()",
G_STRFUNC);
return;
}
_wayland_compositor_display = display;
}
#endif
/**
* clutter_set_windowing_backend:
* @backend_type: a comma separated list of windowing backends
*
* Restricts Clutter to only use the specified backend or list of backends.
*
* You can use one of the `CLUTTER_WINDOWING_*` symbols, e.g.
*
* |[<!-- language="C" -->
* clutter_set_windowing_backend (CLUTTER_WINDOWING_X11);
* ]|
*
* Will force Clutter to use the X11 windowing and input backend, and terminate
* if the X11 backend could not be initialized successfully.
*
* Since Clutter 1.26, you can also use a comma-separated list of windowing
* system backends to provide a fallback in case backends are not available or
* enabled, e.g.:
*
* |[<!-- language="C" -->
* clutter_set_windowing_backend ("gdk,wayland,x11");
* ]|
*
* Will make Clutter test for the GDK, Wayland, and X11 backends in that order.
*
* You can use the `*` special value to ask Clutter to use the internally
* defined list of backends. For instance:
*
* |[<!-- language="C" -->
* clutter_set_windowing_backend ("x11,wayland,*");
* ]|
*
* Will make Clutter test the X11 and Wayland backends, and then fall back
* to the internal list of available backends.
*
* This function must be called before the first API call to Clutter, including
* clutter_get_option_context()
*
* Since: 1.16
*/
void
clutter_set_windowing_backend (const char *backend_type)
{
g_return_if_fail (backend_type != NULL);
allowed_backends = g_strdup (backend_type);
}
void
clutter_try_set_windowing_backend (const char *backend_type)
{
if (allowed_backends == NULL)
clutter_set_windowing_backend (backend_type);
}
PangoDirection
_clutter_backend_get_keymap_direction (ClutterBackend *backend)
{
ClutterBackendClass *klass;
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->get_keymap_direction != NULL)
return klass->get_keymap_direction (backend);
return PANGO_DIRECTION_NEUTRAL;
}
void
_clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend)
{
if (backend->dummy_onscreen == COGL_INVALID_HANDLE)
{
CoglError *internal_error = NULL;
backend->dummy_onscreen = cogl_onscreen_new (backend->cogl_context, 1, 1);
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (backend->dummy_onscreen),
&internal_error))
{
g_critical ("Unable to create dummy onscreen: %s", internal_error->message);
cogl_error_free (internal_error);
return;
}
}
cogl_set_framebuffer (COGL_FRAMEBUFFER (backend->dummy_onscreen));
}
void void
clutter_set_allowed_drivers (const char *drivers) clutter_set_allowed_drivers (const char *drivers)
{ {
@ -807,6 +1365,16 @@ clutter_set_allowed_drivers (const char *drivers)
allowed_drivers = g_strdup (drivers); allowed_drivers = g_strdup (drivers);
} }
void
clutter_backend_bell_notify (ClutterBackend *backend)
{
ClutterBackendClass *klass;
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->bell_notify)
klass->bell_notify (backend);
}
/** /**
* clutter_backend_get_input_method: * clutter_backend_get_input_method:
* @backend: the #CLutterBackend * @backend: the #CLutterBackend
@ -834,51 +1402,3 @@ clutter_backend_set_input_method (ClutterBackend *backend,
{ {
g_set_object (&backend->input_method, method); g_set_object (&backend->input_method, method);
} }
ClutterStageWindow *
clutter_backend_get_stage_window (ClutterBackend *backend)
{
return backend->stage_window;
}
/**
* clutter_backend_get_default_seat:
* @backend: the #ClutterBackend
*
* Returns the default seat
*
* Returns: (transfer none): the default seat
**/
ClutterSeat *
clutter_backend_get_default_seat (ClutterBackend *backend)
{
g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL);
return CLUTTER_BACKEND_GET_CLASS (backend)->get_default_seat (backend);
}
void
clutter_backend_set_fallback_resource_scale (ClutterBackend *backend,
float fallback_resource_scale)
{
backend->fallback_resource_scale = fallback_resource_scale;
}
float
clutter_backend_get_fallback_resource_scale (ClutterBackend *backend)
{
return backend->fallback_resource_scale;
}
gboolean
clutter_backend_is_display_server (ClutterBackend *backend)
{
return CLUTTER_BACKEND_GET_CLASS (backend)->is_display_server (backend);
}
void
clutter_backend_destroy (ClutterBackend *backend)
{
g_object_run_dispose (G_OBJECT (backend));
g_object_unref (backend);
}

View File

@ -33,9 +33,8 @@
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <clutter/clutter-keymap.h> #include <clutter/clutter-config.h>
#include <clutter/clutter-types.h> #include <clutter/clutter-types.h>
#include <clutter/clutter-seat.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -54,33 +53,36 @@ G_BEGIN_DECLS
typedef struct _ClutterBackend ClutterBackend; typedef struct _ClutterBackend ClutterBackend;
typedef struct _ClutterBackendClass ClutterBackendClass; typedef struct _ClutterBackendClass ClutterBackendClass;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
GType clutter_backend_get_type (void) G_GNUC_CONST; GType clutter_backend_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
ClutterBackend * clutter_get_default_backend (void); ClutterBackend * clutter_get_default_backend (void);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_16
void clutter_set_windowing_backend (const char *backend_type);
CLUTTER_AVAILABLE_IN_ALL
gdouble clutter_backend_get_resolution (ClutterBackend *backend); gdouble clutter_backend_get_resolution (ClutterBackend *backend);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_backend_set_font_options (ClutterBackend *backend, void clutter_backend_set_font_options (ClutterBackend *backend,
const cairo_font_options_t *options); const cairo_font_options_t *options);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
const cairo_font_options_t * clutter_backend_get_font_options (ClutterBackend *backend); const cairo_font_options_t * clutter_backend_get_font_options (ClutterBackend *backend);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_8
CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend); CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_backend_bell_notify (ClutterBackend *backend);
CLUTTER_AVAILABLE_IN_MUTTER
ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend); ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_MUTTER
void clutter_backend_set_input_method (ClutterBackend *backend, void clutter_backend_set_input_method (ClutterBackend *backend,
ClutterInputMethod *method); ClutterInputMethod *method);
CLUTTER_EXPORT
ClutterSeat * clutter_backend_get_default_seat (ClutterBackend *backend);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_BACKEND_H__ */ #endif /* __CLUTTER_BACKEND_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@
#undef CBZ_L2T_INTERPOLATION #undef CBZ_L2T_INTERPOLATION
/**************************************************************************** /****************************************************************************
* ClutterBezier -- representation of a cubic bezier curve * * ClutterBezier -- represenation of a cubic bezier curve *
* (private; a building block for the public bspline object) * * (private; a building block for the public bspline object) *
****************************************************************************/ ****************************************************************************/
@ -104,7 +104,7 @@ struct _ClutterBezier
ClutterBezier * ClutterBezier *
_clutter_bezier_new (void) _clutter_bezier_new (void)
{ {
return g_new0 (ClutterBezier, 1); return g_slice_new0 (ClutterBezier);
} }
void void
@ -112,7 +112,7 @@ _clutter_bezier_free (ClutterBezier * b)
{ {
if (G_LIKELY (b)) if (G_LIKELY (b))
{ {
g_free (b); g_slice_free (ClutterBezier, b);
} }
} }
@ -213,7 +213,7 @@ sqrti (int number)
* algorithm does not calculate the square root, but its reciprocal ('y' * algorithm does not calculate the square root, but its reciprocal ('y'
* below), which is only at the end turned to the inverse value. In order * below), which is only at the end turned to the inverse value. In order
* for the algorithm to produce satisfactory results, the reciprocal value * for the algorithm to produce satisfactory results, the reciprocal value
* must be represented with sufficient precision; the 16.16 we use * must be represented with sufficient precission; the 16.16 we use
* elsewhere in clutter is not good enough, and 10.22 is used instead. * elsewhere in clutter is not good enough, and 10.22 is used instead.
*/ */
_FixedT x; _FixedT x;
@ -236,7 +236,7 @@ sqrti (int number)
/* Now, we convert the float to 10.22 fixed. We exploit the mechanism /* Now, we convert the float to 10.22 fixed. We exploit the mechanism
* described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf. * described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf.
* *
* We want 22 bit fraction; a single precision float uses 23 bit * We want 22 bit fraction; a single precission float uses 23 bit
* mantisa, so we only need to add 2^(23-22) (no need for the 1.5 * mantisa, so we only need to add 2^(23-22) (no need for the 1.5
* multiplier as we are only dealing with positive numbers). * multiplier as we are only dealing with positive numbers).
* *
@ -256,7 +256,7 @@ sqrti (int number)
flt2.i = (flt2.i >> 11) * (y_1 >> 11); flt2.i = (flt2.i >> 11) * (y_1 >> 11);
/* If the original argument is less than 342, we do another /* If the original argument is less than 342, we do another
* iteration to improve precision (for arguments >= 342, the single * iteration to improve precission (for arguments >= 342, the single
* iteration produces generally better results). * iteration produces generally better results).
*/ */
if (x < 171) if (x < 171)

View File

@ -36,7 +36,7 @@ G_BEGIN_DECLS
typedef struct _ClutterBezier ClutterBezier; typedef struct _ClutterBezier ClutterBezier;
ClutterBezier *_clutter_bezier_new (void); ClutterBezier *_clutter_bezier_new ();
void _clutter_bezier_free (ClutterBezier * b); void _clutter_bezier_free (ClutterBezier * b);

View File

@ -43,16 +43,18 @@
* #ClutterBinLayout is available since Clutter 1.2 * #ClutterBinLayout is available since Clutter 1.2
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include <math.h> #include <math.h>
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS #define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "deprecated/clutter-container.h" #include "deprecated/clutter-container.h"
#include "deprecated/clutter-bin-layout.h"
#include "clutter-actor-private.h" #include "clutter-actor-private.h"
#include "clutter-animatable.h" #include "clutter-animatable.h"
#include "clutter-bin-layout.h"
#include "clutter-child-meta.h" #include "clutter-child-meta.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-enum-types.h" #include "clutter-enum-types.h"
@ -406,7 +408,8 @@ get_actor_align_factor (ClutterActorAlign alignment)
static void static void
clutter_bin_layout_allocate (ClutterLayoutManager *manager, clutter_bin_layout_allocate (ClutterLayoutManager *manager,
ClutterContainer *container, ClutterContainer *container,
const ClutterActorBox *allocation) const ClutterActorBox *allocation,
ClutterAllocationFlags flags)
{ {
gfloat allocation_x, allocation_y; gfloat allocation_x, allocation_y;
gfloat available_w, available_h; gfloat available_w, available_h;
@ -514,7 +517,8 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
clutter_actor_allocate_align_fill (child, &child_alloc, clutter_actor_allocate_align_fill (child, &child_alloc,
x_align, y_align, x_align, y_align,
x_fill, y_fill); x_fill, y_fill,
flags);
} }
} }
@ -696,3 +700,187 @@ clutter_bin_layout_new (ClutterBinAlignment x_align,
"y-align", y_align, "y-align", y_align,
NULL); NULL);
} }
/**
* clutter_bin_layout_set_alignment:
* @self: a #ClutterBinLayout
* @child: (allow-none): a child of @container
* @x_align: the horizontal alignment policy to be used for the @child
* inside @container
* @y_align: the vertical aligment policy to be used on the @child
* inside @container
*
* Sets the horizontal and vertical alignment policies to be applied
* to a @child of @self
*
* If @child is %NULL then the @x_align and @y_align values will
* be set as the default alignment policies
*
* Since: 1.2
*
* Deprecated: 1.12: Use the #ClutterActor:x-align and
* #ClutterActor:y-align properties of #ClutterActor instead.
*/
void
clutter_bin_layout_set_alignment (ClutterBinLayout *self,
ClutterActor *child,
ClutterBinAlignment x_align,
ClutterBinAlignment y_align)
{
ClutterBinLayoutPrivate *priv;
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
g_return_if_fail (child == NULL || CLUTTER_IS_ACTOR (child));
priv = self->priv;
if (priv->container == NULL)
{
if (child == NULL)
{
set_x_align (self, x_align);
set_y_align (self, y_align);
}
else
g_warning ("The layout of type '%s' must be associated to "
"a ClutterContainer before setting the alignment "
"on its children",
G_OBJECT_TYPE_NAME (self));
return;
}
manager = CLUTTER_LAYOUT_MANAGER (self);
meta = clutter_layout_manager_get_child_meta (manager,
priv->container,
child);
g_assert (CLUTTER_IS_BIN_LAYER (meta));
set_layer_x_align (CLUTTER_BIN_LAYER (meta), x_align);
set_layer_y_align (CLUTTER_BIN_LAYER (meta), y_align);
}
/**
* clutter_bin_layout_get_alignment:
* @self: a #ClutterBinLayout
* @child: (allow-none): a child of @container
* @x_align: (out) (allow-none): return location for the horizontal
* alignment policy
* @y_align: (out) (allow-none): return location for the vertical
* alignment policy
*
* Retrieves the horizontal and vertical alignment policies for
* a child of @self
*
* If @child is %NULL the default alignment policies will be returned
* instead
*
* Since: 1.2
*
* Deprecated: 1.12: Use the #ClutterActor:x-align and the
* #ClutterActor:y-align properties of #ClutterActor instead.
*/
void
clutter_bin_layout_get_alignment (ClutterBinLayout *self,
ClutterActor *child,
ClutterBinAlignment *x_align,
ClutterBinAlignment *y_align)
{
ClutterBinLayoutPrivate *priv;
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
ClutterBinLayer *layer;
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
priv = self->priv;
if (priv->container == NULL)
{
if (child == NULL)
{
if (x_align)
*x_align = priv->x_align;
if (y_align)
*y_align = priv->y_align;
}
else
g_warning ("The layout of type '%s' must be associated to "
"a ClutterContainer before getting the alignment "
"of its children",
G_OBJECT_TYPE_NAME (self));
return;
}
manager = CLUTTER_LAYOUT_MANAGER (self);
meta = clutter_layout_manager_get_child_meta (manager,
priv->container,
child);
g_assert (CLUTTER_IS_BIN_LAYER (meta));
layer = CLUTTER_BIN_LAYER (meta);
if (x_align)
*x_align = layer->x_align;
if (y_align)
*y_align = layer->y_align;
}
/**
* clutter_bin_layout_add:
* @self: a #ClutterBinLayout
* @child: a #ClutterActor
* @x_align: horizontal alignment policy for @child
* @y_align: vertical alignment policy for @child
*
* Adds a #ClutterActor to the container using @self and
* sets the alignment policies for it
*
* This function is equivalent to clutter_container_add_actor()
* and clutter_layout_manager_child_set_property() but it does not
* require a pointer to the #ClutterContainer associated to the
* #ClutterBinLayout
*
* Since: 1.2
*
* Deprecated: 1.12: Use clutter_actor_add_child() instead.
*/
void
clutter_bin_layout_add (ClutterBinLayout *self,
ClutterActor *child,
ClutterBinAlignment x_align,
ClutterBinAlignment y_align)
{
ClutterBinLayoutPrivate *priv;
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
g_return_if_fail (CLUTTER_IS_ACTOR (child));
priv = self->priv;
if (priv->container == NULL)
{
g_warning ("The layout of type '%s' must be associated to "
"a ClutterContainer before adding children",
G_OBJECT_TYPE_NAME (self));
return;
}
clutter_container_add_actor (priv->container, child);
manager = CLUTTER_LAYOUT_MANAGER (self);
meta = clutter_layout_manager_get_child_meta (manager,
priv->container,
child);
g_assert (CLUTTER_IS_BIN_LAYER (meta));
set_layer_x_align (CLUTTER_BIN_LAYER (meta), x_align);
set_layer_y_align (CLUTTER_BIN_LAYER (meta), y_align);
}

View File

@ -74,10 +74,10 @@ struct _ClutterBinLayoutClass
ClutterLayoutManagerClass parent_class; ClutterLayoutManagerClass parent_class;
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_2
GType clutter_bin_layout_get_type (void) G_GNUC_CONST; GType clutter_bin_layout_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_2
ClutterLayoutManager * clutter_bin_layout_new (ClutterBinAlignment x_align, ClutterLayoutManager * clutter_bin_layout_new (ClutterBinAlignment x_align,
ClutterBinAlignment y_align); ClutterBinAlignment y_align);

View File

@ -38,14 +38,12 @@
* *
* |[<!-- language="C" --> * |[<!-- language="C" -->
* // source * // source
* rect[0] = clutter_actor_new (); * rect[0] = clutter_rectangle_new_with_color (&red_color);
* clutter_actor_set_background_color (rect[0], &red_color);
* clutter_actor_set_position (rect[0], x_pos, y_pos); * clutter_actor_set_position (rect[0], x_pos, y_pos);
* clutter_actor_set_size (rect[0], 100, 100); * clutter_actor_set_size (rect[0], 100, 100);
* *
* // second rectangle * // second rectangle
* rect[1] = clutter_actor_new (); * rect[1] = clutter_rectangle_new_with_color (&green_color);
* clutter_actor_set_background_color (rect[1], &green_color);
* clutter_actor_set_size (rect[1], 100, 100); * clutter_actor_set_size (rect[1], 100, 100);
* clutter_actor_set_opacity (rect[1], 0); * clutter_actor_set_opacity (rect[1], 0);
* *
@ -55,8 +53,7 @@
* clutter_actor_add_constraint_with_name (rect[1], "green-y", constraint); * clutter_actor_add_constraint_with_name (rect[1], "green-y", constraint);
* *
* // third rectangle * // third rectangle
* rect[2] = clutter_actor_new (); * rect[2] = clutter_rectangle_new_with_color (&blue_color);
* clutter_actor_set_background_color (rect[2], &blue_color);
* clutter_actor_set_size (rect[2], 100, 100); * clutter_actor_set_size (rect[2], 100, 100);
* clutter_actor_set_opacity (rect[2], 0); * clutter_actor_set_opacity (rect[2], 0);
* *
@ -83,7 +80,9 @@
* #ClutterBindConstraint is available since Clutter 1.4 * #ClutterBindConstraint is available since Clutter 1.4
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include <math.h> #include <math.h>
@ -147,58 +146,6 @@ source_destroyed (ClutterActor *actor,
bind->source = NULL; bind->source = NULL;
} }
static void
clutter_bind_constraint_update_preferred_size (ClutterConstraint *constraint,
ClutterActor *actor,
ClutterOrientation direction,
float for_size,
float *minimum_size,
float *natural_size)
{
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint);
float source_min, source_nat;
if (bind->source == NULL)
return;
/* only these bindings affect the preferred size */
if (!(bind->coordinate == CLUTTER_BIND_WIDTH ||
bind->coordinate == CLUTTER_BIND_HEIGHT ||
bind->coordinate == CLUTTER_BIND_SIZE ||
bind->coordinate == CLUTTER_BIND_ALL))
return;
if (clutter_actor_contains (bind->source, actor))
return;
switch (direction)
{
case CLUTTER_ORIENTATION_HORIZONTAL:
if (bind->coordinate != CLUTTER_BIND_HEIGHT)
{
clutter_actor_get_preferred_width (bind->source, for_size,
&source_min,
&source_nat);
*minimum_size = source_min;
*natural_size = source_nat;
}
break;
case CLUTTER_ORIENTATION_VERTICAL:
if (bind->coordinate != CLUTTER_BIND_WIDTH)
{
clutter_actor_get_preferred_height (bind->source, for_size,
&source_min,
&source_nat);
*minimum_size = source_min;
*natural_size = source_nat;
}
break;
}
}
static void static void
clutter_bind_constraint_update_allocation (ClutterConstraint *constraint, clutter_bind_constraint_update_allocation (ClutterConstraint *constraint,
ClutterActor *actor, ClutterActor *actor,
@ -207,9 +154,7 @@ clutter_bind_constraint_update_allocation (ClutterConstraint *constraint,
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint); ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint);
gfloat source_width, source_height; gfloat source_width, source_height;
gfloat actor_width, actor_height; gfloat actor_width, actor_height;
graphene_point3d_t source_position; ClutterVertex source_position = { 0., };
source_position = GRAPHENE_POINT3D_INIT (0.f, 0.f, 0.f);
if (bind->source == NULL) if (bind->source == NULL)
return; return;
@ -383,8 +328,6 @@ clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass)
meta_class->set_actor = clutter_bind_constraint_set_actor; meta_class->set_actor = clutter_bind_constraint_set_actor;
constraint_class->update_allocation = clutter_bind_constraint_update_allocation; constraint_class->update_allocation = clutter_bind_constraint_update_allocation;
constraint_class->update_preferred_size = clutter_bind_constraint_update_preferred_size;
/** /**
* ClutterBindConstraint:source: * ClutterBindConstraint:source:
* *

View File

@ -48,28 +48,28 @@ G_BEGIN_DECLS
typedef struct _ClutterBindConstraint ClutterBindConstraint; typedef struct _ClutterBindConstraint ClutterBindConstraint;
typedef struct _ClutterBindConstraintClass ClutterBindConstraintClass; typedef struct _ClutterBindConstraintClass ClutterBindConstraintClass;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType clutter_bind_constraint_get_type (void) G_GNUC_CONST; GType clutter_bind_constraint_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterConstraint * clutter_bind_constraint_new (ClutterActor *source, ClutterConstraint * clutter_bind_constraint_new (ClutterActor *source,
ClutterBindCoordinate coordinate, ClutterBindCoordinate coordinate,
gfloat offset); gfloat offset);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_bind_constraint_set_source (ClutterBindConstraint *constraint, void clutter_bind_constraint_set_source (ClutterBindConstraint *constraint,
ClutterActor *source); ClutterActor *source);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterActor * clutter_bind_constraint_get_source (ClutterBindConstraint *constraint); ClutterActor * clutter_bind_constraint_get_source (ClutterBindConstraint *constraint);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint, void clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint,
ClutterBindCoordinate coordinate); ClutterBindCoordinate coordinate);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterBindCoordinate clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint); ClutterBindCoordinate clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint, void clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint,
gfloat offset); gfloat offset);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
gfloat clutter_bind_constraint_get_offset (ClutterBindConstraint *constraint); gfloat clutter_bind_constraint_get_offset (ClutterBindConstraint *constraint);
G_END_DECLS G_END_DECLS

View File

@ -94,7 +94,9 @@
* #ClutterBindingPool is available since Clutter 1.0 * #ClutterBindingPool is available since Clutter 1.0
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include "clutter-binding-pool.h" #include "clutter-binding-pool.h"
#include "clutter-debug.h" #include "clutter-debug.h"
@ -189,7 +191,7 @@ binding_entry_new (const gchar *name,
modifiers = modifiers & BINDING_MOD_MASK; modifiers = modifiers & BINDING_MOD_MASK;
entry = g_new0 (ClutterBindingEntry, 1); entry = g_slice_new (ClutterBindingEntry);
entry->key_val = key_val; entry->key_val = key_val;
entry->modifiers = modifiers; entry->modifiers = modifiers;
entry->name = (gchar *) g_intern_string (name); entry->name = (gchar *) g_intern_string (name);
@ -221,7 +223,7 @@ binding_entry_free (gpointer data)
g_closure_unref (entry->closure); g_closure_unref (entry->closure);
g_free (entry); g_slice_free (ClutterBindingEntry, entry);
} }
} }
@ -235,7 +237,8 @@ clutter_binding_pool_finalize (GObject *gobject)
g_hash_table_destroy (pool->entries_hash); g_hash_table_destroy (pool->entries_hash);
g_slist_free_full (pool->entries, (GDestroyNotify) binding_entry_free); g_slist_foreach (pool->entries, (GFunc) binding_entry_free, NULL);
g_slist_free (pool->entries);
G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject); G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject);
} }

View File

@ -71,17 +71,17 @@ typedef gboolean (* ClutterBindingActionFunc) (GObject *gobject,
ClutterModifierType modifiers, ClutterModifierType modifiers,
gpointer user_data); gpointer user_data);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
GType clutter_binding_pool_get_type (void) G_GNUC_CONST; GType clutter_binding_pool_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
ClutterBindingPool * clutter_binding_pool_new (const gchar *name); ClutterBindingPool * clutter_binding_pool_new (const gchar *name);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
ClutterBindingPool * clutter_binding_pool_get_for_class (gpointer klass); ClutterBindingPool * clutter_binding_pool_get_for_class (gpointer klass);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
ClutterBindingPool * clutter_binding_pool_find (const gchar *name); ClutterBindingPool * clutter_binding_pool_find (const gchar *name);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_install_action (ClutterBindingPool *pool, void clutter_binding_pool_install_action (ClutterBindingPool *pool,
const gchar *action_name, const gchar *action_name,
guint key_val, guint key_val,
@ -89,44 +89,44 @@ void clutter_binding_pool_install_action (ClutterBindingPool
GCallback callback, GCallback callback,
gpointer data, gpointer data,
GDestroyNotify notify); GDestroyNotify notify);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_install_closure (ClutterBindingPool *pool, void clutter_binding_pool_install_closure (ClutterBindingPool *pool,
const gchar *action_name, const gchar *action_name,
guint key_val, guint key_val,
ClutterModifierType modifiers, ClutterModifierType modifiers,
GClosure *closure); GClosure *closure);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_override_action (ClutterBindingPool *pool, void clutter_binding_pool_override_action (ClutterBindingPool *pool,
guint key_val, guint key_val,
ClutterModifierType modifiers, ClutterModifierType modifiers,
GCallback callback, GCallback callback,
gpointer data, gpointer data,
GDestroyNotify notify); GDestroyNotify notify);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_override_closure (ClutterBindingPool *pool, void clutter_binding_pool_override_closure (ClutterBindingPool *pool,
guint key_val, guint key_val,
ClutterModifierType modifiers, ClutterModifierType modifiers,
GClosure *closure); GClosure *closure);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
const gchar * clutter_binding_pool_find_action (ClutterBindingPool *pool, const gchar * clutter_binding_pool_find_action (ClutterBindingPool *pool,
guint key_val, guint key_val,
ClutterModifierType modifiers); ClutterModifierType modifiers);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_remove_action (ClutterBindingPool *pool, void clutter_binding_pool_remove_action (ClutterBindingPool *pool,
guint key_val, guint key_val,
ClutterModifierType modifiers); ClutterModifierType modifiers);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
gboolean clutter_binding_pool_activate (ClutterBindingPool *pool, gboolean clutter_binding_pool_activate (ClutterBindingPool *pool,
guint key_val, guint key_val,
ClutterModifierType modifiers, ClutterModifierType modifiers,
GObject *gobject); GObject *gobject);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_block_action (ClutterBindingPool *pool, void clutter_binding_pool_block_action (ClutterBindingPool *pool,
const gchar *action_name); const gchar *action_name);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_unblock_action (ClutterBindingPool *pool, void clutter_binding_pool_unblock_action (ClutterBindingPool *pool,
const gchar *action_name); const gchar *action_name);

View File

@ -37,7 +37,11 @@
#define CLUTTER_IS_BLUR_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BLUR_EFFECT)) #define CLUTTER_IS_BLUR_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BLUR_EFFECT))
#define CLUTTER_BLUR_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffectClass)) #define CLUTTER_BLUR_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffectClass))
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-blur-effect.h" #include "clutter-blur-effect.h"
@ -79,6 +83,9 @@ struct _ClutterBlurEffect
gint pixel_step_uniform; gint pixel_step_uniform;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline; CoglPipeline *pipeline;
}; };
@ -93,42 +100,19 @@ G_DEFINE_TYPE (ClutterBlurEffect,
clutter_blur_effect, clutter_blur_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT); CLUTTER_TYPE_OFFSCREEN_EFFECT);
static CoglPipeline *
clutter_blur_effect_create_pipeline (ClutterOffscreenEffect *effect,
CoglTexture *texture)
{
ClutterBlurEffect *blur_effect = CLUTTER_BLUR_EFFECT (effect);
if (blur_effect->pixel_step_uniform > -1)
{
float pixel_step[2];
int tex_width, tex_height;
tex_width = cogl_texture_get_width (texture);
tex_height = cogl_texture_get_height (texture);
pixel_step[0] = 1.0f / tex_width;
pixel_step[1] = 1.0f / tex_height;
cogl_pipeline_set_uniform_float (blur_effect->pipeline,
blur_effect->pixel_step_uniform,
2, /* n_components */
1, /* count */
pixel_step);
}
cogl_pipeline_set_layer_texture (blur_effect->pipeline, 0, texture);
return cogl_object_ref (blur_effect->pipeline);
}
static gboolean static gboolean
clutter_blur_effect_pre_paint (ClutterEffect *effect, clutter_blur_effect_pre_paint (ClutterEffect *effect)
ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
ClutterEffectClass *parent_class; ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
if (self->actor == NULL)
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{ {
/* if we don't have support for GLSL shaders then we /* if we don't have support for GLSL shaders then we
@ -142,15 +126,64 @@ clutter_blur_effect_pre_paint (ClutterEffect *effect,
} }
parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class); parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class);
return parent_class->pre_paint (effect, node, paint_context); if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
if (self->pixel_step_uniform > -1)
{
gfloat pixel_step[2];
pixel_step[0] = 1.0f / self->tex_width;
pixel_step[1] = 1.0f / self->tex_height;
cogl_pipeline_set_uniform_float (self->pipeline,
self->pixel_step_uniform,
2, /* n_components */
1, /* count */
pixel_step);
}
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return TRUE;
}
else
return FALSE;
}
static void
clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
guint8 paint_opacity;
paint_opacity = clutter_actor_get_paint_opacity (self->actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_push_source (self->pipeline);
cogl_rectangle (0, 0, self->tex_width, self->tex_height);
cogl_pop_source ();
} }
static gboolean static gboolean
clutter_blur_effect_modify_paint_volume (ClutterEffect *effect, clutter_blur_effect_get_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume) ClutterPaintVolume *volume)
{ {
gfloat cur_width, cur_height; gfloat cur_width, cur_height;
graphene_point3d_t origin; ClutterVertex origin;
clutter_paint_volume_get_origin (volume, &origin); clutter_paint_volume_get_origin (volume, &origin);
cur_width = clutter_paint_volume_get_width (volume); cur_width = clutter_paint_volume_get_width (volume);
@ -191,10 +224,10 @@ clutter_blur_effect_class_init (ClutterBlurEffectClass *klass)
gobject_class->dispose = clutter_blur_effect_dispose; gobject_class->dispose = clutter_blur_effect_dispose;
effect_class->pre_paint = clutter_blur_effect_pre_paint; 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 = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->create_pipeline = clutter_blur_effect_create_pipeline; offscreen_class->paint_target = clutter_blur_effect_paint_target;
} }
static void static void
@ -217,7 +250,9 @@ clutter_blur_effect_init (ClutterBlurEffect *self)
cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet); cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet);
cogl_object_unref (snippet); cogl_object_unref (snippet);
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
0, /* layer number */
COGL_TEXTURE_TYPE_2D);
} }
self->pipeline = cogl_pipeline_copy (klass->base_pipeline); self->pipeline = cogl_pipeline_copy (klass->base_pipeline);

View File

@ -48,10 +48,10 @@ G_BEGIN_DECLS
typedef struct _ClutterBlurEffect ClutterBlurEffect; typedef struct _ClutterBlurEffect ClutterBlurEffect;
typedef struct _ClutterBlurEffectClass ClutterBlurEffectClass; typedef struct _ClutterBlurEffectClass ClutterBlurEffectClass;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType clutter_blur_effect_get_type (void) G_GNUC_CONST; GType clutter_blur_effect_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterEffect *clutter_blur_effect_new (void); ClutterEffect *clutter_blur_effect_new (void);
G_END_DECLS G_END_DECLS

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2020 Endless OS Foundation, LLC
*
* 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_BLUR_PRIVATE_H
#define CLUTTER_BLUR_PRIVATE_H
#include <glib-object.h>
#include <cogl/cogl.h>
G_BEGIN_DECLS
typedef struct _ClutterBlur ClutterBlur;
ClutterBlur * clutter_blur_new (CoglTexture *texture,
float sigma);
void clutter_blur_apply (ClutterBlur *blur);
CoglTexture * clutter_blur_get_texture (ClutterBlur *blur);
void clutter_blur_free (ClutterBlur *blur);
G_END_DECLS
#endif /* CLUTTER_BLUR_PRIVATE_H */

View File

@ -1,431 +0,0 @@
/*
* Copyright (C) 2020 Endless OS Foundation, LLC
*
* 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/>.
*/
#include "clutter-blur-private.h"
#include "clutter-backend.h"
/**
* SECTION:clutter-blur
* @short_description: Blur textures
*
* #ClutterBlur is a moderately fast gaussian blur implementation.
*
* # Optimizations
*
* There are a number of optimizations in place to make this blur implementation
* real-time. All in all, the implementation performs best when using large
* blur-radii that allow downscaling the texture to smaller sizes, at small
* radii where no downscaling is possible this can easily halve the framerate.
*
* ## Multipass
*
* It is implemented in 2 passes: vertical and horizontal.
*
* ## Downscaling
*
* #ClutterBlur uses dynamic downscaling to speed up blurring. Downscaling
* happens in factors of 2 (the image is downscaled either by 2, 4, 8, 16, )
* and depends on the blur radius, the texture size, among others.
*
* The texture is drawn into a downscaled framebuffer; the blur passes are
* applied on the downscaled texture contents; and finally, the blurred
* contents are drawn
* upscaled again.
*
* ## Hardware Interpolation
*
* This blur implementation cuts down the number of sampling operations by
* exploiting the hardware interpolation that is performed when sampling between
* pixel boundaries. This technique is described at:
*
* http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
*
* ## Incremental gauss-factor calculation
*
* The kernel values for the gaussian kernel are computed incrementally instead
* of running the expensive calculations multiple times inside the blur shader.
* The implementation is based on the algorithm presented by K. Turkowski in
* GPU Gems 3, chapter 40:
*
* https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch40.html
*
*/
static const char *gaussian_blur_glsl_declarations =
"uniform float sigma; \n"
"uniform float pixel_step; \n"
"uniform vec2 direction; \n";
static const char *gaussian_blur_glsl =
" vec2 uv = vec2 (cogl_tex_coord.st); \n"
" \n"
" vec3 gauss_coefficient; \n"
" gauss_coefficient.x = 1.0 / (sqrt (2.0 * 3.14159265) * sigma); \n"
" gauss_coefficient.y = exp (-0.5 / (sigma * sigma)); \n"
" gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y; \n"
" \n"
" float gauss_coefficient_total = gauss_coefficient.x; \n"
" \n"
" vec4 ret = texture2D (cogl_sampler, uv) * gauss_coefficient.x; \n"
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
" \n"
" int n_steps = int (ceil (1.5 * sigma)) * 2; \n"
" \n"
" for (int i = 1; i <= n_steps; i += 2) { \n"
" float coefficient_subtotal = gauss_coefficient.x; \n"
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
" coefficient_subtotal += gauss_coefficient.x; \n"
" \n"
" float gauss_ratio = gauss_coefficient.x / coefficient_subtotal; \n"
" \n"
" float foffset = float (i) + gauss_ratio; \n"
" vec2 offset = direction * foffset * pixel_step; \n"
" \n"
" ret += texture2D (cogl_sampler, uv + offset) * coefficient_subtotal; \n"
" ret += texture2D (cogl_sampler, uv - offset) * coefficient_subtotal; \n"
" \n"
" gauss_coefficient_total += 2.0 * coefficient_subtotal; \n"
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
" } \n"
" \n"
" cogl_texel = ret / gauss_coefficient_total; \n";
#define MIN_DOWNSCALE_SIZE 256.f
#define MAX_SIGMA 6.f
enum
{
VERTICAL,
HORIZONTAL,
};
typedef struct
{
CoglFramebuffer *framebuffer;
CoglPipeline *pipeline;
CoglTexture *texture;
int orientation;
} BlurPass;
struct _ClutterBlur
{
CoglTexture *source_texture;
float sigma;
float downscale_factor;
BlurPass pass[2];
};
static CoglPipeline*
create_blur_pipeline (void)
{
static CoglPipelineKey blur_pipeline_key = "clutter-blur-pipeline-private";
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
CoglPipeline *blur_pipeline;
blur_pipeline =
cogl_context_get_named_pipeline (ctx, &blur_pipeline_key);
if (G_UNLIKELY (blur_pipeline == NULL))
{
CoglSnippet *snippet;
blur_pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_layer_null_texture (blur_pipeline, 0);
cogl_pipeline_set_layer_filters (blur_pipeline,
0,
COGL_PIPELINE_FILTER_LINEAR,
COGL_PIPELINE_FILTER_LINEAR);
cogl_pipeline_set_layer_wrap_mode (blur_pipeline,
0,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
gaussian_blur_glsl_declarations,
NULL);
cogl_snippet_set_replace (snippet, gaussian_blur_glsl);
cogl_pipeline_add_layer_snippet (blur_pipeline, 0, snippet);
cogl_object_unref (snippet);
cogl_context_set_named_pipeline (ctx, &blur_pipeline_key, blur_pipeline);
}
return cogl_pipeline_copy (blur_pipeline);
}
static void
update_blur_uniforms (ClutterBlur *blur,
BlurPass *pass)
{
gboolean vertical = pass->orientation == VERTICAL;
int sigma_uniform;
int pixel_step_uniform;
int direction_uniform;
pixel_step_uniform =
cogl_pipeline_get_uniform_location (pass->pipeline, "pixel_step");
if (pixel_step_uniform > -1)
{
float pixel_step;
if (vertical)
pixel_step = 1.f / cogl_texture_get_height (pass->texture);
else
pixel_step = 1.f / cogl_texture_get_width (pass->texture);
cogl_pipeline_set_uniform_1f (pass->pipeline,
pixel_step_uniform,
pixel_step);
}
sigma_uniform = cogl_pipeline_get_uniform_location (pass->pipeline, "sigma");
if (sigma_uniform > -1)
{
cogl_pipeline_set_uniform_1f (pass->pipeline,
sigma_uniform,
blur->sigma / blur->downscale_factor);
}
direction_uniform =
cogl_pipeline_get_uniform_location (pass->pipeline, "direction");
if (direction_uniform > -1)
{
gboolean horizontal = !vertical;
float direction[2] = {
horizontal,
vertical,
};
cogl_pipeline_set_uniform_float (pass->pipeline,
direction_uniform,
2, 1,
direction);
}
}
static gboolean
create_fbo (ClutterBlur *blur,
BlurPass *pass)
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
float scaled_height;
float scaled_width;
float height;
float width;
g_clear_pointer (&pass->texture, cogl_object_unref);
g_clear_object (&pass->framebuffer);
width = cogl_texture_get_width (blur->source_texture);
height = cogl_texture_get_height (blur->source_texture);
scaled_width = floorf (width / blur->downscale_factor);
scaled_height = floorf (height / blur->downscale_factor);
pass->texture = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
scaled_width,
scaled_height));
if (!pass->texture)
return FALSE;
pass->framebuffer =
COGL_FRAMEBUFFER (cogl_offscreen_new_with_texture (pass->texture));
if (!pass->framebuffer)
{
g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC);
return FALSE;
}
cogl_framebuffer_orthographic (pass->framebuffer,
0.0, 0.0,
scaled_width,
scaled_height,
0.0, 1.0);
return TRUE;
}
static gboolean
setup_blur_pass (ClutterBlur *blur,
BlurPass *pass,
int orientation,
CoglTexture *texture)
{
pass->orientation = orientation;
pass->pipeline = create_blur_pipeline ();
cogl_pipeline_set_layer_texture (pass->pipeline, 0, texture);
if (!create_fbo (blur, pass))
return FALSE;
update_blur_uniforms (blur, pass);
return TRUE;
}
static float
calculate_downscale_factor (float width,
float height,
float sigma)
{
float downscale_factor = 1.f;
float scaled_width = width;
float scaled_height = height;
float scaled_sigma = sigma;
/* This is the algorithm used by Firefox; keep downscaling until either the
* blur radius is lower than the threshold, or the downscaled texture is too
* small.
*/
while (scaled_sigma > MAX_SIGMA &&
scaled_width > MIN_DOWNSCALE_SIZE &&
scaled_height > MIN_DOWNSCALE_SIZE)
{
downscale_factor *= 2.f;
scaled_width = width / downscale_factor;
scaled_height = height / downscale_factor;
scaled_sigma = sigma / downscale_factor;
}
return downscale_factor;
}
static void
apply_blur_pass (BlurPass *pass)
{
CoglColor transparent;
cogl_color_init_from_4ub (&transparent, 0, 0, 0, 0);
cogl_framebuffer_clear (pass->framebuffer,
COGL_BUFFER_BIT_COLOR,
&transparent);
cogl_framebuffer_draw_rectangle (pass->framebuffer,
pass->pipeline,
0, 0,
cogl_texture_get_width (pass->texture),
cogl_texture_get_height (pass->texture));
}
static void
clear_blur_pass (BlurPass *pass)
{
g_clear_pointer (&pass->pipeline, cogl_object_unref);
g_clear_pointer (&pass->texture, cogl_object_unref);
g_clear_object (&pass->framebuffer);
}
/**
* clutter_blur_new:
* @texture: a #CoglTexture
* @sigma: blur sigma
*
* Creates a new #ClutterBlur.
*
* Returns: (transfer full) (nullable): A newly created #ClutterBlur
*/
ClutterBlur *
clutter_blur_new (CoglTexture *texture,
float sigma)
{
ClutterBlur *blur;
unsigned int height;
unsigned int width;
BlurPass *hpass;
BlurPass *vpass;
g_return_val_if_fail (texture != NULL, NULL);
g_return_val_if_fail (sigma >= 0.0, NULL);
width = cogl_texture_get_width (texture);
height = cogl_texture_get_height (texture);
blur = g_new0 (ClutterBlur, 1);
blur->sigma = sigma;
blur->source_texture = cogl_object_ref (texture);
blur->downscale_factor = calculate_downscale_factor (width, height, sigma);
if (G_APPROX_VALUE (sigma, 0.0, FLT_EPSILON))
goto out;
vpass = &blur->pass[VERTICAL];
hpass = &blur->pass[HORIZONTAL];
if (!setup_blur_pass (blur, vpass, VERTICAL, texture) ||
!setup_blur_pass (blur, hpass, HORIZONTAL, vpass->texture))
{
clutter_blur_free (blur);
return NULL;
}
out:
return g_steal_pointer (&blur);
}
/**
* clutter_blur_apply:
* @blur: a #ClutterBlur
*
* Applies the blur. The resulting texture can be retrieved by
* clutter_blur_get_texture().
*/
void
clutter_blur_apply (ClutterBlur *blur)
{
if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON))
return;
apply_blur_pass (&blur->pass[VERTICAL]);
apply_blur_pass (&blur->pass[HORIZONTAL]);
}
/**
* clutter_blur_get_texture:
* @blur: a #ClutterBlur
*
* Retrieves the texture where the blurred contents are stored. The
* contents are undefined until clutter_blur_apply() is called.
*
* Returns: (transfer none): a #CoglTexture
*/
CoglTexture *
clutter_blur_get_texture (ClutterBlur *blur)
{
if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON))
return blur->source_texture;
else
return blur->pass[HORIZONTAL].texture;
}
/**
* clutter_blur_free:
* @blur: A #ClutterBlur
*
* Frees @blur.
*/
void
clutter_blur_free (ClutterBlur *blur)
{
g_assert (blur);
clear_blur_pass (&blur->pass[VERTICAL]);
clear_blur_pass (&blur->pass[HORIZONTAL]);
cogl_clear_object (&blur->source_texture);
g_free (blur);
}

File diff suppressed because it is too large Load Diff

View File

@ -77,34 +77,92 @@ struct _ClutterBoxLayoutClass
ClutterLayoutManagerClass parent_class; ClutterLayoutManagerClass parent_class;
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_2
GType clutter_box_layout_get_type (void) G_GNUC_CONST; GType clutter_box_layout_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_2
ClutterLayoutManager * clutter_box_layout_new (void); ClutterLayoutManager * clutter_box_layout_new (void);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_box_layout_set_orientation (ClutterBoxLayout *layout, void clutter_box_layout_set_orientation (ClutterBoxLayout *layout,
ClutterOrientation orientation); ClutterOrientation orientation);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
ClutterOrientation clutter_box_layout_get_orientation (ClutterBoxLayout *layout); ClutterOrientation clutter_box_layout_get_orientation (ClutterBoxLayout *layout);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_2
void clutter_box_layout_set_spacing (ClutterBoxLayout *layout, void clutter_box_layout_set_spacing (ClutterBoxLayout *layout,
guint spacing); guint spacing);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_2
guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout); guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_2
void clutter_box_layout_set_homogeneous (ClutterBoxLayout *layout, void clutter_box_layout_set_homogeneous (ClutterBoxLayout *layout,
gboolean homogeneous); gboolean homogeneous);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_2
gboolean clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout); gboolean clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_2
void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout, void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout,
gboolean pack_start); gboolean pack_start);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_2
gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout); gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout);
CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_box_layout_set_orientation)
void clutter_box_layout_set_vertical (ClutterBoxLayout *layout,
gboolean vertical);
CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_box_layout_get_orientation)
gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout);
CLUTTER_AVAILABLE_IN_1_2
void clutter_box_layout_pack (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean expand,
gboolean x_fill,
gboolean y_fill,
ClutterBoxAlignment x_align,
ClutterBoxAlignment y_align);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_alignment (ClutterBoxLayout *layout,
ClutterActor *actor,
ClutterBoxAlignment x_align,
ClutterBoxAlignment y_align);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_get_alignment (ClutterBoxLayout *layout,
ClutterActor *actor,
ClutterBoxAlignment *x_align,
ClutterBoxAlignment *y_align);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_fill (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean x_fill,
gboolean y_fill);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_get_fill (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean *x_fill,
gboolean *y_fill);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_expand (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean expand);
CLUTTER_DEPRECATED_IN_1_12
gboolean clutter_box_layout_get_expand (ClutterBoxLayout *layout,
ClutterActor *actor);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_use_animations (ClutterBoxLayout *layout,
gboolean animate);
CLUTTER_DEPRECATED_IN_1_12
gboolean clutter_box_layout_get_use_animations (ClutterBoxLayout *layout);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
gulong mode);
CLUTTER_DEPRECATED_IN_1_12
gulong clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout,
guint msecs);
CLUTTER_DEPRECATED_IN_1_12
guint clutter_box_layout_get_easing_duration (ClutterBoxLayout *layout);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_BOX_LAYOUT_H__ */ #endif /* __CLUTTER_BOX_LAYOUT_H__ */

View File

@ -37,10 +37,14 @@
#define CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT)) #define CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT))
#define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffectClass)) #define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffectClass))
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include <math.h> #include <math.h>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-brightness-contrast-effect.h" #include "clutter-brightness-contrast-effect.h"
#include <cogl/cogl.h> #include <cogl/cogl.h>
@ -67,6 +71,9 @@ struct _ClutterBrightnessContrastEffect
gint brightness_offset_uniform; gint brightness_offset_uniform;
gint contrast_uniform; gint contrast_uniform;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline; CoglPipeline *pipeline;
}; };
@ -116,34 +123,23 @@ G_DEFINE_TYPE (ClutterBrightnessContrastEffect,
static gboolean static gboolean
will_have_no_effect (ClutterBrightnessContrastEffect *self) will_have_no_effect (ClutterBrightnessContrastEffect *self)
{ {
return (G_APPROX_VALUE (self->brightness_red, no_change, FLT_EPSILON) && return (self->brightness_red == no_change &&
G_APPROX_VALUE (self->brightness_green, no_change, FLT_EPSILON) && self->brightness_green == no_change &&
G_APPROX_VALUE (self->brightness_blue, no_change, FLT_EPSILON) && self->brightness_blue == no_change &&
G_APPROX_VALUE (self->contrast_red, no_change, FLT_EPSILON) && self->contrast_red == no_change &&
G_APPROX_VALUE (self->contrast_green, no_change, FLT_EPSILON) && self->contrast_green == no_change &&
G_APPROX_VALUE (self->contrast_blue, no_change, FLT_EPSILON)); self->contrast_blue == no_change);
}
static CoglPipeline *
clutter_brightness_contrast_effect_create_pipeline (ClutterOffscreenEffect *effect,
CoglTexture *texture)
{
ClutterBrightnessContrastEffect *self =
CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return cogl_object_ref (self->pipeline);
} }
static gboolean static gboolean
clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect, clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect)
ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
ClutterEffectClass *parent_class; ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
if (will_have_no_effect (self)) if (will_have_no_effect (self))
return FALSE; return FALSE;
@ -162,8 +158,44 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect,
parent_class = parent_class =
CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class); CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class);
if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
return parent_class->pre_paint (effect, node, paint_context); texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return TRUE;
}
else
return FALSE;
}
static void
clutter_brightness_contrast_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
ClutterActor *actor;
guint8 paint_opacity;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
paint_opacity = clutter_actor_get_paint_opacity (actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_push_source (self->pipeline);
cogl_rectangle (0, 0, self->tex_width, self->tex_height);
cogl_pop_source ();
} }
static void static void
@ -263,7 +295,7 @@ clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectCl
ClutterOffscreenEffectClass *offscreen_class; ClutterOffscreenEffectClass *offscreen_class;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->create_pipeline = clutter_brightness_contrast_effect_create_pipeline; offscreen_class->paint_target = clutter_brightness_contrast_effect_paint_target;
effect_class->pre_paint = clutter_brightness_contrast_effect_pre_paint; effect_class->pre_paint = clutter_brightness_contrast_effect_pre_paint;
@ -407,7 +439,9 @@ clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self)
cogl_pipeline_add_snippet (klass->base_pipeline, snippet); cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
cogl_object_unref (snippet); cogl_object_unref (snippet);
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
0, /* layer number */
COGL_TEXTURE_TYPE_2D);
} }
self->pipeline = cogl_pipeline_copy (klass->base_pipeline); self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
@ -463,9 +497,9 @@ clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContras
{ {
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
if (G_APPROX_VALUE (red, effect->brightness_red, FLT_EPSILON) && if (red == effect->brightness_red &&
G_APPROX_VALUE (green, effect->brightness_green, FLT_EPSILON) && green == effect->brightness_green &&
G_APPROX_VALUE (blue, effect->brightness_blue, FLT_EPSILON)) blue == effect->brightness_blue)
return; return;
effect->brightness_red = red; effect->brightness_red = red;
@ -553,9 +587,9 @@ clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastE
{ {
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
if (G_APPROX_VALUE (red, effect->contrast_red, FLT_EPSILON) && if (red == effect->contrast_red &&
G_APPROX_VALUE (green, effect->contrast_green, FLT_EPSILON) && green == effect->contrast_green &&
G_APPROX_VALUE (blue, effect->contrast_blue, FLT_EPSILON)) blue == effect->contrast_blue)
return; return;
effect->contrast_red = red; effect->contrast_red = red;

View File

@ -49,35 +49,35 @@ G_BEGIN_DECLS
typedef struct _ClutterBrightnessContrastEffect ClutterBrightnessContrastEffect; typedef struct _ClutterBrightnessContrastEffect ClutterBrightnessContrastEffect;
typedef struct _ClutterBrightnessContrastEffectClass ClutterBrightnessContrastEffectClass; typedef struct _ClutterBrightnessContrastEffectClass ClutterBrightnessContrastEffectClass;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
GType clutter_brightness_contrast_effect_get_type (void) G_GNUC_CONST; GType clutter_brightness_contrast_effect_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterEffect * clutter_brightness_contrast_effect_new (void); ClutterEffect * clutter_brightness_contrast_effect_new (void);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect, void clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect,
float red, float red,
float green, float green,
float blue); float blue);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect, void clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect,
float brightness); float brightness);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect, void clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect,
float *red, float *red,
float *green, float *green,
float *blue); float *blue);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect, void clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect,
float red, float red,
float green, float green,
float blue); float blue);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect, void clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect,
float contrast); float contrast);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect, void clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect,
float *red, float *red,
float *green, float *green,

View File

@ -1,8 +0,0 @@
/* Mutter version */
#mesondefine MUTTER_VERSION
/* List of Cogl drivers */
#mesondefine CLUTTER_DRIVERS
/* Supports PangoFt2 */
#mesondefine HAVE_PANGO_FT2

View File

@ -27,7 +27,9 @@
* Clutter provides some utility functions for using Cairo. * Clutter provides some utility functions for using Cairo.
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include "clutter-cairo.h" #include "clutter-cairo.h"
#include "clutter-color.h" #include "clutter-color.h"

View File

@ -50,9 +50,9 @@ G_BEGIN_DECLS
#define CLUTTER_CAIRO_FORMAT_ARGB32 (COGL_PIXEL_FORMAT_ARGB_8888_PRE) #define CLUTTER_CAIRO_FORMAT_ARGB32 (COGL_PIXEL_FORMAT_ARGB_8888_PRE)
#endif #endif
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
void clutter_cairo_clear (cairo_t *cr); void clutter_cairo_clear (cairo_t *cr);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_cairo_set_source_color (cairo_t *cr, void clutter_cairo_set_source_color (cairo_t *cr,
const ClutterColor *color); const ClutterColor *color);

View File

@ -42,14 +42,17 @@
* #ClutterCanvas is available since Clutter 1.10. * #ClutterCanvas is available since Clutter 1.10.
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include <math.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <cairo-gobject.h> #include <cairo-gobject.h>
#include "clutter-canvas.h" #include "clutter-canvas.h"
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-actor-private.h" #include "clutter-actor-private.h"
#include "clutter-backend.h" #include "clutter-backend.h"
#include "clutter-cairo.h" #include "clutter-cairo.h"
@ -68,7 +71,6 @@ struct _ClutterCanvasPrivate
int width; int width;
int height; int height;
float scale_factor;
CoglTexture *texture; CoglTexture *texture;
gboolean dirty; gboolean dirty;
@ -82,7 +84,6 @@ enum
PROP_WIDTH, PROP_WIDTH,
PROP_HEIGHT, PROP_HEIGHT,
PROP_SCALE_FACTOR,
LAST_PROP LAST_PROP
}; };
@ -98,7 +99,7 @@ enum
static guint canvas_signals[LAST_SIGNAL] = { 0, }; static guint canvas_signals[LAST_SIGNAL] = { 0, };
static void clutter_content_iface_init (ClutterContentInterface *iface); static void clutter_content_iface_init (ClutterContentIface *iface);
G_DEFINE_TYPE_WITH_CODE (ClutterCanvas, clutter_canvas, G_TYPE_OBJECT, G_DEFINE_TYPE_WITH_CODE (ClutterCanvas, clutter_canvas, G_TYPE_OBJECT,
G_ADD_PRIVATE (ClutterCanvas) G_ADD_PRIVATE (ClutterCanvas)
@ -179,19 +180,6 @@ clutter_canvas_set_property (GObject *gobject,
} }
break; break;
case PROP_SCALE_FACTOR:
{
gfloat new_scale_factor = g_value_get_float (value);
if (priv->scale_factor != new_scale_factor)
{
priv->scale_factor = new_scale_factor;
clutter_content_invalidate (CLUTTER_CONTENT (gobject));
}
}
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break; break;
@ -216,10 +204,6 @@ clutter_canvas_get_property (GObject *gobject,
g_value_set_int (value, priv->height); g_value_set_int (value, priv->height);
break; break;
case PROP_SCALE_FACTOR:
g_value_set_float (value, priv->scale_factor);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break; break;
@ -263,19 +247,6 @@ clutter_canvas_class_init (ClutterCanvasClass *klass)
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS); G_PARAM_STATIC_STRINGS);
/**
* ClutterCanvas:scale-factor:
*
* The height of the canvas.
*/
obj_props[PROP_SCALE_FACTOR] =
g_param_spec_float ("scale-factor",
P_("Scale Factor"),
P_("The Scale factor of the canvas"),
0.01f, G_MAXFLOAT,
1.0f,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/** /**
* ClutterCanvas::draw: * ClutterCanvas::draw:
@ -322,14 +293,12 @@ clutter_canvas_init (ClutterCanvas *self)
self->priv->width = -1; self->priv->width = -1;
self->priv->height = -1; self->priv->height = -1;
self->priv->scale_factor = 1.0f;
} }
static void static void
clutter_canvas_paint_content (ClutterContent *content, clutter_canvas_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *root, ClutterPaintNode *root)
ClutterPaintContext *paint_context)
{ {
ClutterCanvas *self = CLUTTER_CANVAS (content); ClutterCanvas *self = CLUTTER_CANVAS (content);
ClutterCanvasPrivate *priv = self->priv; ClutterCanvasPrivate *priv = self->priv;
@ -350,7 +319,7 @@ clutter_canvas_paint_content (ClutterContent *content,
return; return;
node = clutter_actor_create_texture_paint_node (actor, priv->texture); node = clutter_actor_create_texture_paint_node (actor, priv->texture);
clutter_paint_node_set_static_name (node, "Canvas Content"); clutter_paint_node_set_name (node, "Canvas Content");
clutter_paint_node_add_child (root, node); clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node); clutter_paint_node_unref (node);
@ -373,8 +342,8 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
priv->dirty = TRUE; priv->dirty = TRUE;
real_width = ceilf (priv->width * priv->scale_factor); real_width = priv->width;
real_height = ceilf (priv->height * priv->scale_factor); real_height = priv->height;
CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d", CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d",
priv->width, priv->height); priv->width, priv->height);
@ -420,10 +389,6 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
mapped_buffer = FALSE; mapped_buffer = FALSE;
} }
cairo_surface_set_device_scale (surface,
priv->scale_factor,
priv->scale_factor);
self->priv->cr = cr = cairo_create (surface); self->priv->cr = cr = cairo_create (surface);
g_signal_emit (self, canvas_signals[DRAW], 0, g_signal_emit (self, canvas_signals[DRAW], 0,
@ -485,16 +450,16 @@ clutter_canvas_get_preferred_size (ClutterContent *content,
return FALSE; return FALSE;
if (width != NULL) if (width != NULL)
*width = ceilf (priv->width * priv->scale_factor); *width = priv->width;
if (height != NULL) if (height != NULL)
*height = ceilf (priv->height * priv->scale_factor); *height = priv->height;
return TRUE; return TRUE;
} }
static void static void
clutter_content_iface_init (ClutterContentInterface *iface) clutter_content_iface_init (ClutterContentIface *iface)
{ {
iface->invalidate = clutter_canvas_invalidate; iface->invalidate = clutter_canvas_invalidate;
iface->paint_content = clutter_canvas_paint_content; iface->paint_content = clutter_canvas_paint_content;
@ -597,48 +562,3 @@ clutter_canvas_set_size (ClutterCanvas *canvas,
return clutter_canvas_invalidate_internal (canvas, width, height); return clutter_canvas_invalidate_internal (canvas, width, height);
} }
/**
* clutter_canvas_set_scale_factor:
* @canvas: a #ClutterCanvas
* @scale: the integer scaling factor of the canvas
*
* Sets the scaling factor of the @canvas, and invalidates the content.
*
* This function will cause the @canvas to be invalidated only
* if the scale factor of the canvas surface has changed.
*/
void
clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
float scale)
{
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
g_return_if_fail (scale > 0.0f);
if (canvas->priv->scale_factor != scale)
{
canvas->priv->scale_factor = scale;
g_object_freeze_notify (G_OBJECT (canvas));
clutter_content_invalidate (CLUTTER_CONTENT (canvas));
g_object_thaw_notify (G_OBJECT (canvas));
g_object_notify_by_pspec (G_OBJECT (canvas), obj_props[PROP_SCALE_FACTOR]);
}
}
/**
* clutter_canvas_get_scale_factor:
* @canvas: a #ClutterCanvas
*
* Gets the scale factor of the @canvas.
*
* Return value: the current @canvas scale factor or -1 if invalid
*/
float
clutter_canvas_get_scale_factor (ClutterCanvas *canvas)
{
g_return_val_if_fail (CLUTTER_IS_CANVAS (canvas), -1.0f);
return canvas->priv->scale_factor;
}

View File

@ -85,21 +85,21 @@ struct _ClutterCanvasClass
gpointer _padding[16]; gpointer _padding[16];
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
GType clutter_canvas_get_type (void) G_GNUC_CONST; GType clutter_canvas_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
ClutterContent * clutter_canvas_new (void); ClutterContent * clutter_canvas_new (void);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_10
gboolean clutter_canvas_set_size (ClutterCanvas *canvas, gboolean clutter_canvas_set_size (ClutterCanvas *canvas,
int width, int width,
int height); int height);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_18
void clutter_canvas_set_scale_factor (ClutterCanvas *canvas, void clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
float scale); int scale);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_18
float clutter_canvas_get_scale_factor (ClutterCanvas *canvas); int clutter_canvas_get_scale_factor (ClutterCanvas *canvas);
G_END_DECLS G_END_DECLS

View File

@ -36,8 +36,9 @@
* *
* #ClutterChildMeta is available since Clutter 0.8 * #ClutterChildMeta is available since Clutter 0.8
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include "clutter-child-meta.h" #include "clutter-child-meta.h"
#include "clutter-container.h" #include "clutter-container.h"

View File

@ -109,12 +109,12 @@ struct _ClutterChildMetaClass
GObjectClass parent_class; GObjectClass parent_class;
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
GType clutter_child_meta_get_type (void) G_GNUC_CONST; GType clutter_child_meta_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
ClutterContainer * clutter_child_meta_get_container (ClutterChildMeta *data); ClutterContainer * clutter_child_meta_get_container (ClutterChildMeta *data);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
ClutterActor * clutter_child_meta_get_actor (ClutterChildMeta *data); ClutterActor * clutter_child_meta_get_actor (ClutterChildMeta *data);
G_END_DECLS G_END_DECLS

View File

@ -92,7 +92,9 @@
* #ClutterClickAction is available since Clutter 1.4 * #ClutterClickAction is available since Clutter 1.4
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include "clutter-click-action.h" #include "clutter-click-action.h"
@ -105,8 +107,8 @@ struct _ClutterClickActionPrivate
{ {
ClutterActor *stage; ClutterActor *stage;
gulong event_id; guint event_id;
gulong capture_id; guint capture_id;
guint long_press_id; guint long_press_id;
gint long_press_threshold; gint long_press_threshold;
@ -114,7 +116,7 @@ struct _ClutterClickActionPrivate
gint drag_threshold; gint drag_threshold;
guint press_button; guint press_button;
ClutterInputDevice *press_device; gint press_device_id;
ClutterEventSequence *press_sequence; ClutterEventSequence *press_sequence;
ClutterModifierType modifier_state; ClutterModifierType modifier_state;
gfloat press_x; gfloat press_x;
@ -159,8 +161,7 @@ static inline void
click_action_set_pressed (ClutterClickAction *action, click_action_set_pressed (ClutterClickAction *action,
gboolean is_pressed) gboolean is_pressed)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
is_pressed = !!is_pressed; is_pressed = !!is_pressed;
@ -175,8 +176,7 @@ static inline void
click_action_set_held (ClutterClickAction *action, click_action_set_held (ClutterClickAction *action,
gboolean is_held) gboolean is_held)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
is_held = !!is_held; is_held = !!is_held;
@ -191,8 +191,7 @@ static gboolean
click_action_emit_long_press (gpointer data) click_action_emit_long_press (gpointer data)
{ {
ClutterClickAction *action = data; ClutterClickAction *action = data;
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
ClutterActor *actor; ClutterActor *actor;
gboolean result; gboolean result;
@ -205,7 +204,11 @@ click_action_emit_long_press (gpointer data)
CLUTTER_LONG_PRESS_ACTIVATE, CLUTTER_LONG_PRESS_ACTIVATE,
&result); &result);
g_clear_signal_handler (&priv->capture_id, priv->stage); if (priv->capture_id != 0)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
click_action_set_pressed (action, FALSE); click_action_set_pressed (action, FALSE);
click_action_set_held (action, FALSE); click_action_set_held (action, FALSE);
@ -216,8 +219,7 @@ click_action_emit_long_press (gpointer data)
static inline void static inline void
click_action_query_long_press (ClutterClickAction *action) click_action_query_long_press (ClutterClickAction *action)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
ClutterActor *actor; ClutterActor *actor;
gboolean result = FALSE; gboolean result = FALSE;
gint timeout; gint timeout;
@ -242,7 +244,6 @@ click_action_query_long_press (ClutterClickAction *action)
if (result) if (result)
{ {
g_clear_handle_id (&priv->long_press_id, g_source_remove);
priv->long_press_id = priv->long_press_id =
clutter_threads_add_timeout (timeout, clutter_threads_add_timeout (timeout,
click_action_emit_long_press, click_action_emit_long_press,
@ -253,8 +254,7 @@ click_action_query_long_press (ClutterClickAction *action)
static inline void static inline void
click_action_cancel_long_press (ClutterClickAction *action) click_action_cancel_long_press (ClutterClickAction *action)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
if (priv->long_press_id != 0) if (priv->long_press_id != 0)
{ {
@ -263,7 +263,8 @@ click_action_cancel_long_press (ClutterClickAction *action)
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
g_clear_handle_id (&priv->long_press_id, g_source_remove); g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
g_signal_emit (action, click_signals[LONG_PRESS], 0, g_signal_emit (action, click_signals[LONG_PRESS], 0,
actor, actor,
@ -272,30 +273,12 @@ click_action_cancel_long_press (ClutterClickAction *action)
} }
} }
static inline gboolean
event_within_drag_threshold (ClutterClickAction *click_action,
ClutterEvent *event)
{
ClutterClickActionPrivate *priv =
clutter_click_action_get_instance_private (click_action);
float motion_x, motion_y;
float delta_x, delta_y;
clutter_event_get_coords (event, &motion_x, &motion_y);
delta_x = ABS (motion_x - priv->press_x);
delta_y = ABS (motion_y - priv->press_y);
return delta_x <= priv->drag_threshold && delta_y <= priv->drag_threshold;
}
static gboolean static gboolean
on_event (ClutterActor *actor, on_event (ClutterActor *actor,
ClutterEvent *event, ClutterEvent *event,
ClutterClickAction *action) ClutterClickAction *action)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
gboolean has_button = TRUE; gboolean has_button = TRUE;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action))) if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
@ -316,7 +299,7 @@ on_event (ClutterActor *actor,
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
priv->press_button = has_button ? clutter_event_get_button (event) : 0; priv->press_button = has_button ? clutter_event_get_button (event) : 0;
priv->press_device = clutter_event_get_device (event); priv->press_device_id = clutter_event_get_device_id (event);
priv->press_sequence = clutter_event_get_event_sequence (event); priv->press_sequence = clutter_event_get_event_sequence (event);
priv->modifier_state = clutter_event_get_state (event); priv->modifier_state = clutter_event_get_state (event);
clutter_event_get_coords (event, &priv->press_x, &priv->press_y); clutter_event_get_coords (event, &priv->press_x, &priv->press_y);
@ -365,8 +348,7 @@ on_captured_event (ClutterActor *stage,
ClutterEvent *event, ClutterEvent *event,
ClutterClickAction *action) ClutterClickAction *action)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
ClutterActor *actor; ClutterActor *actor;
ClutterModifierType modifier_state; ClutterModifierType modifier_state;
gboolean has_button = TRUE; gboolean has_button = TRUE;
@ -375,10 +357,6 @@ on_captured_event (ClutterActor *stage,
switch (clutter_event_type (event)) switch (clutter_event_type (event))
{ {
case CLUTTER_TOUCH_CANCEL:
clutter_click_action_release (action);
break;
case CLUTTER_TOUCH_END: case CLUTTER_TOUCH_END:
has_button = FALSE; has_button = FALSE;
case CLUTTER_BUTTON_RELEASE: case CLUTTER_BUTTON_RELEASE:
@ -387,7 +365,7 @@ on_captured_event (ClutterActor *stage,
if ((has_button && clutter_event_get_button (event) != priv->press_button) || if ((has_button && clutter_event_get_button (event) != priv->press_button) ||
(has_button && clutter_event_get_click_count (event) != 1) || (has_button && clutter_event_get_click_count (event) != 1) ||
clutter_event_get_device (event) != priv->press_device || clutter_event_get_device_id (event) != priv->press_device_id ||
clutter_event_get_event_sequence (event) != priv->press_sequence) clutter_event_get_event_sequence (event) != priv->press_sequence)
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
@ -395,9 +373,17 @@ on_captured_event (ClutterActor *stage,
click_action_cancel_long_press (action); click_action_cancel_long_press (action);
/* disconnect the capture */ /* disconnect the capture */
g_clear_signal_handler (&priv->capture_id, priv->stage); if (priv->capture_id != 0)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
g_clear_handle_id (&priv->long_press_id, g_source_remove); if (priv->long_press_id != 0)
{
g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
}
if (!clutter_actor_contains (actor, clutter_event_get_source (event))) if (!clutter_actor_contains (actor, clutter_event_get_source (event)))
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
@ -419,23 +405,30 @@ on_captured_event (ClutterActor *stage,
priv->modifier_state = 0; priv->modifier_state = 0;
click_action_set_pressed (action, FALSE); click_action_set_pressed (action, FALSE);
g_signal_emit (action, click_signals[CLICKED], 0, actor);
if (event_within_drag_threshold (action, event))
g_signal_emit (action, click_signals[CLICKED], 0, actor);
break; break;
case CLUTTER_MOTION: case CLUTTER_MOTION:
case CLUTTER_TOUCH_UPDATE: case CLUTTER_TOUCH_UPDATE:
{ {
if (clutter_event_get_device (event) != priv->press_device || gfloat motion_x, motion_y;
gfloat delta_x, delta_y;
if (clutter_event_get_device_id (event) != priv->press_device_id ||
clutter_event_get_event_sequence (event) != priv->press_sequence) clutter_event_get_event_sequence (event) != priv->press_sequence)
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
if (!priv->is_held) if (!priv->is_held)
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
if (!event_within_drag_threshold (action, event)) clutter_event_get_coords (event, &motion_x, &motion_y);
clutter_click_action_release (action);
delta_x = ABS (motion_x - priv->press_x);
delta_y = ABS (motion_y - priv->press_y);
if (delta_x > priv->drag_threshold ||
delta_y > priv->drag_threshold)
click_action_cancel_long_press (action);
} }
break; break;
@ -451,15 +444,14 @@ clutter_click_action_set_actor (ClutterActorMeta *meta,
ClutterActor *actor) ClutterActor *actor)
{ {
ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta); ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta);
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
if (priv->event_id != 0) if (priv->event_id != 0)
{ {
ClutterActor *old_actor = clutter_actor_meta_get_actor (meta); ClutterActor *old_actor = clutter_actor_meta_get_actor (meta);
if (old_actor != NULL) if (old_actor != NULL)
g_clear_signal_handler (&priv->event_id, old_actor); g_signal_handler_disconnect (old_actor, priv->event_id);
priv->event_id = 0; priv->event_id = 0;
} }
@ -467,13 +459,17 @@ clutter_click_action_set_actor (ClutterActorMeta *meta,
if (priv->capture_id != 0) if (priv->capture_id != 0)
{ {
if (priv->stage != NULL) if (priv->stage != NULL)
g_clear_signal_handler (&priv->capture_id, priv->stage); g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0; priv->capture_id = 0;
priv->stage = NULL; priv->stage = NULL;
} }
g_clear_handle_id (&priv->long_press_id, g_source_remove); if (priv->long_press_id != 0)
{
g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
}
click_action_set_pressed (action, FALSE); click_action_set_pressed (action, FALSE);
click_action_set_held (action, FALSE); click_action_set_held (action, FALSE);
@ -486,28 +482,13 @@ clutter_click_action_set_actor (ClutterActorMeta *meta,
CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class)->set_actor (meta, actor); CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class)->set_actor (meta, actor);
} }
static void
clutter_click_action_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled)
{
ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (meta);
ClutterActorMetaClass *parent_class =
CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class);
if (!is_enabled)
clutter_click_action_release (click_action);
parent_class->set_enabled (meta, is_enabled);
}
static void static void
clutter_click_action_set_property (GObject *gobject, clutter_click_action_set_property (GObject *gobject,
guint prop_id, guint prop_id,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
switch (prop_id) switch (prop_id)
{ {
@ -531,8 +512,7 @@ clutter_click_action_get_property (GObject *gobject,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
switch (prop_id) switch (prop_id)
{ {
@ -561,15 +541,26 @@ clutter_click_action_get_property (GObject *gobject,
static void static void
clutter_click_action_dispose (GObject *gobject) clutter_click_action_dispose (GObject *gobject)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
g_clear_signal_handler (&priv->event_id, if (priv->event_id)
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject))); {
g_signal_handler_disconnect (clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject)),
priv->event_id);
priv->event_id = 0;
}
g_clear_signal_handler (&priv->capture_id, priv->stage); if (priv->capture_id)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
g_clear_handle_id (&priv->long_press_id, g_source_remove); if (priv->long_press_id)
{
g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
}
G_OBJECT_CLASS (clutter_click_action_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_click_action_parent_class)->dispose (gobject);
} }
@ -582,7 +573,6 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
meta_class->set_actor = clutter_click_action_set_actor; meta_class->set_actor = clutter_click_action_set_actor;
meta_class->set_enabled = clutter_click_action_set_enabled;
gobject_class->dispose = clutter_click_action_dispose; gobject_class->dispose = clutter_click_action_dispose;
gobject_class->set_property = clutter_click_action_set_property; gobject_class->set_property = clutter_click_action_set_property;
@ -674,7 +664,8 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterClickActionClass, clicked), G_STRUCT_OFFSET (ClutterClickActionClass, clicked),
NULL, NULL, NULL, NULL, NULL,
_clutter_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_NONE, 1,
CLUTTER_TYPE_ACTOR); CLUTTER_TYPE_ACTOR);
@ -720,11 +711,9 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
static void static void
clutter_click_action_init (ClutterClickAction *self) clutter_click_action_init (ClutterClickAction *self)
{ {
ClutterClickActionPrivate *priv = self->priv = clutter_click_action_get_instance_private (self);
clutter_click_action_get_instance_private (self); self->priv->long_press_threshold = -1;
self->priv->long_press_duration = -1;
priv->long_press_threshold = -1;
priv->long_press_duration = -1;
} }
/** /**
@ -764,13 +753,17 @@ clutter_click_action_release (ClutterClickAction *action)
g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action)); g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action));
priv = clutter_click_action_get_instance_private (action); priv = action->priv;
if (!priv->is_held) if (!priv->is_held)
return; return;
/* disconnect the capture */ /* disconnect the capture */
g_clear_signal_handler (&priv->capture_id, priv->stage); if (priv->capture_id != 0)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
click_action_cancel_long_press (action); click_action_cancel_long_press (action);
click_action_set_held (action, FALSE); click_action_set_held (action, FALSE);
@ -790,13 +783,9 @@ clutter_click_action_release (ClutterClickAction *action)
guint guint
clutter_click_action_get_button (ClutterClickAction *action) clutter_click_action_get_button (ClutterClickAction *action)
{ {
ClutterClickActionPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0); g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
priv = clutter_click_action_get_instance_private (action); return action->priv->press_button;
return priv->press_button;
} }
/** /**
@ -812,13 +801,9 @@ clutter_click_action_get_button (ClutterClickAction *action)
ClutterModifierType ClutterModifierType
clutter_click_action_get_state (ClutterClickAction *action) clutter_click_action_get_state (ClutterClickAction *action)
{ {
ClutterClickActionPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0); g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
priv = clutter_click_action_get_instance_private (action); return action->priv->modifier_state;
return priv->modifier_state;
} }
/** /**
@ -836,15 +821,11 @@ clutter_click_action_get_coords (ClutterClickAction *action,
gfloat *press_x, gfloat *press_x,
gfloat *press_y) gfloat *press_y)
{ {
ClutterClickActionPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTION (action)); g_return_if_fail (CLUTTER_IS_ACTION (action));
priv = clutter_click_action_get_instance_private (action);
if (press_x != NULL) if (press_x != NULL)
*press_x = priv->press_x; *press_x = action->priv->press_x;
if (press_y != NULL) if (press_y != NULL)
*press_y = priv->press_y; *press_y = action->priv->press_y;
} }

View File

@ -37,13 +37,32 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ()) #define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ())
#define CLUTTER_CLICK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickAction))
#define CLUTTER_IS_CLICK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CLICK_ACTION))
#define CLUTTER_CLICK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
#define CLUTTER_IS_CLICK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CLICK_ACTION))
#define CLUTTER_CLICK_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
CLUTTER_EXPORT typedef struct _ClutterClickAction ClutterClickAction;
G_DECLARE_DERIVABLE_TYPE (ClutterClickAction, clutter_click_action, typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
CLUTTER, CLICK_ACTION, ClutterAction); typedef struct _ClutterClickActionClass ClutterClickActionClass;
typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate; /**
* ClutterClickAction:
*
* The #ClutterClickAction structure contains
* only private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterClickAction
{
/*< private >*/
ClutterAction parent_instance;
ClutterClickActionPrivate *priv;
};
/** /**
* ClutterClickActionClass: * ClutterClickActionClass:
@ -78,19 +97,22 @@ struct _ClutterClickActionClass
void (* _clutter_click_action7) (void); void (* _clutter_click_action7) (void);
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType clutter_click_action_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
ClutterAction * clutter_click_action_new (void); ClutterAction * clutter_click_action_new (void);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
guint clutter_click_action_get_button (ClutterClickAction *action); guint clutter_click_action_get_button (ClutterClickAction *action);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterModifierType clutter_click_action_get_state (ClutterClickAction *action); ClutterModifierType clutter_click_action_get_state (ClutterClickAction *action);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_8
void clutter_click_action_get_coords (ClutterClickAction *action, void clutter_click_action_get_coords (ClutterClickAction *action,
gfloat *press_x, gfloat *press_x,
gfloat *press_y); gfloat *press_y);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_click_action_release (ClutterClickAction *action); void clutter_click_action_release (ClutterClickAction *action);
G_END_DECLS G_END_DECLS

View File

@ -37,8 +37,11 @@
* #ClutterClone is available since Clutter 1.0 * #ClutterClone is available since Clutter 1.0
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-actor-private.h" #include "clutter-actor-private.h"
#include "clutter-clone.h" #include "clutter-clone.h"
#include "clutter-debug.h" #include "clutter-debug.h"
@ -51,8 +54,6 @@
struct _ClutterClonePrivate struct _ClutterClonePrivate
{ {
ClutterActor *clone_source; ClutterActor *clone_source;
float x_scale, y_scale;
gulong source_destroy_id; gulong source_destroy_id;
}; };
@ -120,22 +121,40 @@ clutter_clone_get_preferred_height (ClutterActor *self,
} }
static void static void
clutter_clone_apply_transform (ClutterActor *self, clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix)
graphene_matrix_t *matrix)
{ {
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv; ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
ClutterActorBox box, source_box;
gfloat x_scale, y_scale;
/* First chain up and apply all the standard ClutterActor
if (priv->clone_source) * transformations... */
graphene_matrix_scale (matrix, priv->x_scale, priv->y_scale, 1.f);
CLUTTER_ACTOR_CLASS (clutter_clone_parent_class)->apply_transform (self, CLUTTER_ACTOR_CLASS (clutter_clone_parent_class)->apply_transform (self,
matrix); matrix);
/* if we don't have a source, nothing else to do */
if (priv->clone_source == NULL)
return;
/* get our allocated size */
clutter_actor_get_allocation_box (self, &box);
/* and get the allocated size of the source */
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
/* We need to scale what the clone-source actor paints to fill our own
* allocation...
*/
x_scale = clutter_actor_box_get_width (&box)
/ clutter_actor_box_get_width (&source_box);
y_scale = clutter_actor_box_get_height (&box)
/ clutter_actor_box_get_height (&source_box);
cogl_matrix_scale (matrix, x_scale, y_scale, x_scale);
} }
static void static void
clutter_clone_paint (ClutterActor *actor, clutter_clone_paint (ClutterActor *actor)
ClutterPaintContext *paint_context)
{ {
ClutterClone *self = CLUTTER_CLONE (actor); ClutterClone *self = CLUTTER_CLONE (actor);
ClutterClonePrivate *priv = self->priv; ClutterClonePrivate *priv = self->priv;
@ -172,7 +191,7 @@ clutter_clone_paint (ClutterActor *actor,
if (clutter_actor_is_realized (priv->clone_source)) if (clutter_actor_is_realized (priv->clone_source))
{ {
_clutter_actor_push_clone_paint (); _clutter_actor_push_clone_paint ();
clutter_actor_paint (priv->clone_source, paint_context); clutter_actor_paint (priv->clone_source);
_clutter_actor_pop_clone_paint (); _clutter_actor_pop_clone_paint ();
} }
@ -195,7 +214,7 @@ clutter_clone_get_paint_volume (ClutterActor *actor,
if (priv->clone_source == NULL) if (priv->clone_source == NULL)
return TRUE; return TRUE;
/* query the volume of the source actor and simply masquerade it as /* query the volume of the source actor and simply masquarade it as
* the clones volume... */ * the clones volume... */
source_volume = clutter_actor_get_paint_volume (priv->clone_source); source_volume = clutter_actor_get_paint_volume (priv->clone_source);
if (source_volume == NULL) if (source_volume == NULL)
@ -222,51 +241,19 @@ clutter_clone_has_overlaps (ClutterActor *actor)
static void static void
clutter_clone_allocate (ClutterActor *self, clutter_clone_allocate (ClutterActor *self,
const ClutterActorBox *box) const ClutterActorBox *box,
ClutterAllocationFlags flags)
{ {
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv; ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
ClutterActorClass *parent_class; ClutterActorClass *parent_class;
ClutterActorBox source_box;
float x_scale, y_scale;
/* chain up */ /* chain up */
parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class); parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class);
parent_class->allocate (self, box); parent_class->allocate (self, box, flags);
if (priv->clone_source == NULL) if (priv->clone_source == NULL)
return; 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))
{
float x = 0.f;
float y = 0.f;
clutter_actor_get_fixed_position (priv->clone_source, &x, &y);
clutter_actor_allocate_preferred_size (priv->clone_source, x, y);
}
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
/* We need to scale what the clone-source actor paints to fill our own
* allocation...
*/
x_scale = clutter_actor_box_get_width (box)
/ clutter_actor_box_get_width (&source_box);
y_scale = clutter_actor_box_get_height (box)
/ clutter_actor_box_get_height (&source_box);
if (!G_APPROX_VALUE (priv->x_scale, x_scale, FLT_EPSILON) ||
!G_APPROX_VALUE (priv->y_scale, y_scale, FLT_EPSILON))
{
priv->x_scale = x_scale;
priv->y_scale = y_scale;
clutter_actor_invalidate_transform (CLUTTER_ACTOR (self));
}
#if 0 #if 0
/* XXX - this is wrong: ClutterClone cannot clone unparented /* XXX - this is wrong: ClutterClone cannot clone unparented
* actors, as it will break all invariants * actors, as it will break all invariants
@ -280,7 +267,7 @@ clutter_clone_allocate (ClutterActor *self,
* paint cycle, we can safely give it as much size as it requires * paint cycle, we can safely give it as much size as it requires
*/ */
if (clutter_actor_get_parent (priv->clone_source) == NULL) if (clutter_actor_get_parent (priv->clone_source) == NULL)
clutter_actor_allocate_preferred_size (priv->clone_source); clutter_actor_allocate_preferred_size (priv->clone_source, flags);
#endif #endif
} }
@ -372,9 +359,6 @@ static void
clutter_clone_init (ClutterClone *self) clutter_clone_init (ClutterClone *self)
{ {
self->priv = clutter_clone_get_instance_private (self); self->priv = clutter_clone_get_instance_private (self);
self->priv->x_scale = 1.f;
self->priv->y_scale = 1.f;
} }
/** /**
@ -411,7 +395,8 @@ clutter_clone_set_source_internal (ClutterClone *self,
if (priv->clone_source != NULL) if (priv->clone_source != NULL)
{ {
g_clear_signal_handler (&priv->source_destroy_id, priv->clone_source); g_signal_handler_disconnect (priv->clone_source, priv->source_destroy_id);
priv->source_destroy_id = 0;
_clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self)); _clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self));
g_object_unref (priv->clone_source); g_object_unref (priv->clone_source);
priv->clone_source = NULL; priv->clone_source = NULL;

View File

@ -78,15 +78,15 @@ struct _ClutterCloneClass
void (*_clutter_actor_clone4) (void); void (*_clutter_actor_clone4) (void);
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
GType clutter_clone_get_type (void) G_GNUC_CONST; GType clutter_clone_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
ClutterActor * clutter_clone_new (ClutterActor *source); ClutterActor * clutter_clone_new (ClutterActor *source);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_clone_set_source (ClutterClone *self, void clutter_clone_set_source (ClutterClone *self,
ClutterActor *source); ClutterActor *source);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
ClutterActor * clutter_clone_get_source (ClutterClone *self); ClutterActor * clutter_clone_get_source (ClutterClone *self);
G_END_DECLS G_END_DECLS

View File

@ -33,7 +33,9 @@
* The alpha channel is fully opaque at 255 and fully transparent at 0. * The alpha channel is fully opaque at 255 and fully transparent at 0.
*/ */
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#include <math.h> #include <math.h>
@ -611,7 +613,7 @@ parse_hsla (ClutterColor *color,
/** /**
* clutter_color_from_string: * clutter_color_from_string:
* @color: (out caller-allocates): return location for a #ClutterColor * @color: (out caller-allocates): return location for a #ClutterColor
* @str: a string specifying a color * @str: a string specifiying a color
* *
* Parses a string definition of a color, filling the #ClutterColor.red, * Parses a string definition of a color, filling the #ClutterColor.red,
* #ClutterColor.green, #ClutterColor.blue and #ClutterColor.alpha fields * #ClutterColor.green, #ClutterColor.blue and #ClutterColor.alpha fields
@ -911,7 +913,7 @@ ClutterColor *
clutter_color_copy (const ClutterColor *color) clutter_color_copy (const ClutterColor *color)
{ {
if (G_LIKELY (color != NULL)) if (G_LIKELY (color != NULL))
return g_memdup2 (color, sizeof (ClutterColor)); return g_slice_dup (ClutterColor, color);
return NULL; return NULL;
} }
@ -928,7 +930,7 @@ void
clutter_color_free (ClutterColor *color) clutter_color_free (ClutterColor *color)
{ {
if (G_LIKELY (color != NULL)) if (G_LIKELY (color != NULL))
g_free (color); g_slice_free (ClutterColor, color);
} }
/** /**
@ -977,7 +979,7 @@ clutter_color_new (guint8 red,
ClutterColor * ClutterColor *
clutter_color_alloc (void) clutter_color_alloc (void)
{ {
return g_new0 (ClutterColor, 1); return g_slice_new0 (ClutterColor);
} }
/** /**

View File

@ -68,76 +68,76 @@ struct _ClutterColor
*/ */
#define CLUTTER_COLOR_INIT(r,g,b,a) { (r), (g), (b), (a) } #define CLUTTER_COLOR_INIT(r,g,b,a) { (r), (g), (b), (a) }
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
GType clutter_color_get_type (void) G_GNUC_CONST; GType clutter_color_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
ClutterColor *clutter_color_new (guint8 red, ClutterColor *clutter_color_new (guint8 red,
guint8 green, guint8 green,
guint8 blue, guint8 blue,
guint8 alpha); guint8 alpha);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
ClutterColor *clutter_color_alloc (void); ClutterColor *clutter_color_alloc (void);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_12
ClutterColor *clutter_color_init (ClutterColor *color, ClutterColor *clutter_color_init (ClutterColor *color,
guint8 red, guint8 red,
guint8 green, guint8 green,
guint8 blue, guint8 blue,
guint8 alpha); guint8 alpha);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
ClutterColor *clutter_color_copy (const ClutterColor *color); ClutterColor *clutter_color_copy (const ClutterColor *color);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_color_free (ClutterColor *color); void clutter_color_free (ClutterColor *color);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_color_add (const ClutterColor *a, void clutter_color_add (const ClutterColor *a,
const ClutterColor *b, const ClutterColor *b,
ClutterColor *result); ClutterColor *result);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_color_subtract (const ClutterColor *a, void clutter_color_subtract (const ClutterColor *a,
const ClutterColor *b, const ClutterColor *b,
ClutterColor *result); ClutterColor *result);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_color_lighten (const ClutterColor *color, void clutter_color_lighten (const ClutterColor *color,
ClutterColor *result); ClutterColor *result);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_color_darken (const ClutterColor *color, void clutter_color_darken (const ClutterColor *color,
ClutterColor *result); ClutterColor *result);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_color_shade (const ClutterColor *color, void clutter_color_shade (const ClutterColor *color,
gdouble factor, gdouble factor,
ClutterColor *result); ClutterColor *result);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gchar * clutter_color_to_string (const ClutterColor *color); gchar * clutter_color_to_string (const ClutterColor *color);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
gboolean clutter_color_from_string (ClutterColor *color, gboolean clutter_color_from_string (ClutterColor *color,
const gchar *str); const gchar *str);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_color_to_hls (const ClutterColor *color, void clutter_color_to_hls (const ClutterColor *color,
gfloat *hue, gfloat *hue,
gfloat *luminance, gfloat *luminance,
gfloat *saturation); gfloat *saturation);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_color_from_hls (ClutterColor *color, void clutter_color_from_hls (ClutterColor *color,
gfloat hue, gfloat hue,
gfloat luminance, gfloat luminance,
gfloat saturation); gfloat saturation);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
guint32 clutter_color_to_pixel (const ClutterColor *color); guint32 clutter_color_to_pixel (const ClutterColor *color);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
void clutter_color_from_pixel (ClutterColor *color, void clutter_color_from_pixel (ClutterColor *color,
guint32 pixel); guint32 pixel);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
guint clutter_color_hash (gconstpointer v); guint clutter_color_hash (gconstpointer v);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_color_equal (gconstpointer v1, gboolean clutter_color_equal (gconstpointer v1,
gconstpointer v2); gconstpointer v2);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_6
void clutter_color_interpolate (const ClutterColor *initial, void clutter_color_interpolate (const ClutterColor *initial,
const ClutterColor *final, const ClutterColor *final,
gdouble progress, gdouble progress,
@ -177,22 +177,22 @@ struct _ClutterParamSpecColor
ClutterColor *default_value; ClutterColor *default_value;
}; };
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
void clutter_value_set_color (GValue *value, void clutter_value_set_color (GValue *value,
const ClutterColor *color); const ClutterColor *color);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
const ClutterColor * clutter_value_get_color (const GValue *value); const ClutterColor * clutter_value_get_color (const GValue *value);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
GType clutter_param_color_get_type (void) G_GNUC_CONST; GType clutter_param_color_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_0
GParamSpec * clutter_param_spec_color (const gchar *name, GParamSpec * clutter_param_spec_color (const gchar *name,
const gchar *nick, const gchar *nick,
const gchar *blurb, const gchar *blurb,
const ClutterColor *default_value, const ClutterColor *default_value,
GParamFlags flags); GParamFlags flags);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_6
const ClutterColor *clutter_color_get_static (ClutterStaticColor color); const ClutterColor *clutter_color_get_static (ClutterStaticColor color);
G_END_DECLS G_END_DECLS

View File

@ -37,7 +37,11 @@
#define CLUTTER_IS_COLORIZE_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_COLORIZE_EFFECT)) #define CLUTTER_IS_COLORIZE_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_COLORIZE_EFFECT))
#define CLUTTER_COLORIZE_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_COLORIZE_EFFECT, ClutterColorizeEffectClass)) #define CLUTTER_COLORIZE_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_COLORIZE_EFFECT, ClutterColorizeEffectClass))
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h" #include "clutter-build-config.h"
#endif
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-colorize-effect.h" #include "clutter-colorize-effect.h"
@ -57,6 +61,9 @@ struct _ClutterColorizeEffect
gint tint_uniform; gint tint_uniform;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline; CoglPipeline *pipeline;
}; };
@ -99,24 +106,15 @@ G_DEFINE_TYPE (ClutterColorizeEffect,
clutter_colorize_effect, clutter_colorize_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT); CLUTTER_TYPE_OFFSCREEN_EFFECT);
static CoglPipeline *
clutter_colorize_effect_create_pipeline (ClutterOffscreenEffect *effect,
CoglTexture *texture)
{
ClutterColorizeEffect *colorize_effect = CLUTTER_COLORIZE_EFFECT (effect);
cogl_pipeline_set_layer_texture (colorize_effect->pipeline, 0, texture);
return cogl_object_ref (colorize_effect->pipeline);
}
static gboolean static gboolean
clutter_colorize_effect_pre_paint (ClutterEffect *effect, clutter_colorize_effect_pre_paint (ClutterEffect *effect)
ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
ClutterEffectClass *parent_class; ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{ {
/* if we don't have support for GLSL shaders then we /* if we don't have support for GLSL shaders then we
@ -130,7 +128,44 @@ clutter_colorize_effect_pre_paint (ClutterEffect *effect,
} }
parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class); parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class);
return parent_class->pre_paint (effect, node, paint_context); if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return TRUE;
}
else
return FALSE;
}
static void
clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
ClutterActor *actor;
guint8 paint_opacity;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
paint_opacity = clutter_actor_get_paint_opacity (actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_push_source (self->pipeline);
cogl_rectangle (0, 0, self->tex_width, self->tex_height);
cogl_pop_source ();
} }
static void static void
@ -196,7 +231,7 @@ clutter_colorize_effect_class_init (ClutterColorizeEffectClass *klass)
ClutterOffscreenEffectClass *offscreen_class; ClutterOffscreenEffectClass *offscreen_class;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->create_pipeline = clutter_colorize_effect_create_pipeline; offscreen_class->paint_target = clutter_colorize_effect_paint_target;
effect_class->pre_paint = clutter_colorize_effect_pre_paint; effect_class->pre_paint = clutter_colorize_effect_pre_paint;
@ -259,7 +294,9 @@ clutter_colorize_effect_init (ClutterColorizeEffect *self)
cogl_pipeline_add_snippet (klass->base_pipeline, snippet); cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
cogl_object_unref (snippet); cogl_object_unref (snippet);
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
0, /* layer number */
COGL_TEXTURE_TYPE_2D);
} }
self->pipeline = cogl_pipeline_copy (klass->base_pipeline); self->pipeline = cogl_pipeline_copy (klass->base_pipeline);

View File

@ -49,16 +49,16 @@ G_BEGIN_DECLS
typedef struct _ClutterColorizeEffect ClutterColorizeEffect; typedef struct _ClutterColorizeEffect ClutterColorizeEffect;
typedef struct _ClutterColorizeEffectClass ClutterColorizeEffectClass; typedef struct _ClutterColorizeEffectClass ClutterColorizeEffectClass;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
GType clutter_colorize_effect_get_type (void) G_GNUC_CONST; GType clutter_colorize_effect_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
ClutterEffect *clutter_colorize_effect_new (const ClutterColor *tint); ClutterEffect *clutter_colorize_effect_new (const ClutterColor *tint);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect, void clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect,
const ClutterColor *tint); const ClutterColor *tint);
CLUTTER_EXPORT CLUTTER_AVAILABLE_IN_1_4
void clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect, void clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect,
ClutterColor *tint); ClutterColor *tint);

View File

@ -0,0 +1,16 @@
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_CONFIG_H__
#define __CLUTTER_CONFIG_H__
#include <glib.h>
G_BEGIN_DECLS
@CLUTTER_CONFIG_DEFINES@
G_END_DECLS
#endif /* __CLUTTER_CONFIG_H__ */

View File

@ -30,6 +30,13 @@ gboolean clutter_constraint_update_allocation (ClutterConstraint *constraint,
ClutterActor *actor, ClutterActor *actor,
ClutterActorBox *allocation); ClutterActorBox *allocation);
void clutter_constraint_update_preferred_size (ClutterConstraint *constraint,
ClutterActor *actor,
ClutterOrientation direction,
float for_size,
float *minimum_size,
float *natural_size);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_CONSTRAINT_PRIVATE_H__ */ #endif /* __CLUTTER_CONSTRAINT_PRIVATE_H__ */

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