Compare commits

...

144 Commits

Author SHA1 Message Date
63e618479c cogl: Include DRM 4CC conversions into CoglPixelFormat
This is at the moment still part of both MetaRendererNative and
MetaDmaBuf, which means duplicated effort in code sections only barely
related to color formats. By doing this, we can keep more of the pixel
format code together, which is more future-proof as we want to add
support for new pixel formats (like YUV-based ones).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/594
2019-06-24 13:51:27 +02:00
151c6fdd84 cogl: Split CoglTextureComponents into its own header
CoglTextureComponents is an enum that mostly makes sense in
`cogl_texture_set_components()`, but it's as prevalent as
`CoglPixelFormat` due to its intimate relation with it. For example: as
of now, there is no way to distinguish between ARGB and XRGB; this needs
an extra using CoglTextureComponents to enforce (not) using the alpha
channel.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/594
2019-06-24 13:51:27 +02:00
e14613e74e window: Warn if try to focus unmanaging windows
https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
2019-06-24 09:42:07 +00:00
f71151a5dd window-x11: Focus the default window with delay while waiting for take-focus
When requesting to a take-focus window to acquire the input, the client may or
may not respond with a SetInputFocus (this doesn't happen for no-input gtk
windows in fact [to be fixed there too]), in such case we were unsetting the
focus while waiting the reply.

In case the client won't respond, we wait for a small delay (set to 250 ms) for
the take-focus window to grab the input focus before setting it to the default
window.

Added a test for this behavior and for the case in which a window takes the
focus meanwhile we're waiting to focus the default window.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
2019-06-24 09:42:07 +00:00
6022b23923 test-runner: Add 'dispatch' command
This will only wait for events to be dispatched and processed by the server
without waiting for client processing.

Reuse the code for the wait command too.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
2019-06-24 09:42:07 +00:00
d08763c18c test-runner: Add 'sleep' command
This allows to sleep for a given timeout in milliseconds.

Rename test_case_before_redraw to test_case_loop_quit since it's a generic
function and use it for the timeout too.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
2019-06-24 09:42:07 +00:00
fcb408ad5d tests: Verify focused window in closed-transient tests
Ensure that we have a focused window when closing transient windows with
no-focus or no-take-focus atoms

https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
2019-06-24 09:42:07 +00:00
51f9e04ef1 test-runner: Add 'assert_focused' command
This allows to verify which window should have the focus, which might not
be the same as the top of the stack.

It's possible to assert the case where there's no focused window using
"NONE" as parameter.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
2019-06-24 09:42:07 +00:00
2fc7760cee tests, stacking: Add tests with no-input and no-take-focus windows
When a window with no frame, that doesn't accept focus and that has no
take-focus atom set is destroyed, we ended up in not changing the current_focus
window, causing a crash.

Added test cases that verify this situation.

Related to https://gitlab.gnome.org/GNOME/mutter/issues/308
https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
2019-06-24 09:42:07 +00:00
f2d2d473b7 tests: Add 'can_take_focus' command to runner and client
Allow to set/unset WM_TAKE_FOCUS from client window.
This is added by default by gtk, but this might not happen in other toolkits,
so add an ability to (un)set this.

So fetch the protocols with XGetWMProtocols and unset the atom.

test-client now needs to depend on Xlib directly in meson build.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
2019-06-24 09:42:07 +00:00
e1f839f48f tests: Add 'accept_focus' command to runner and client
Under the hood, calls gtk_window_set_accept_focus in the client

https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
2019-06-24 09:42:07 +00:00
eccc791f3b workspace: Focus only ancestors that are focusable
When destroying a window that has a parent, we initially try to focus one of
its ancestors. However if no ancestor can be focused, then we should instead
focus the default focus window instead of trying to request focus for a window
that can't get focus anyways.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/308
2019-06-24 09:42:07 +00:00
6055f04814 display: Remove _XOPEN_SOURCE definition
There is no gethostname call in this file.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/638
2019-06-24 09:35:02 +00:00
0185909ee3 window-x11: Fix _XOPEN_SOURCE usage for gethostname on FreeBSD
On FreeBSD, gethostname is guarded by '__POSIX_VISIBLE >= 200112', which
requires either '_POSIX_C_SOURCE >= 200112' or '_XOPEN_SOURCE >= 600'.
Defining _XOPEN_SOURCE to 500 does not break the build because of
implicit declaration, but it defeats the purpose of defining the macro.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/638
2019-06-24 09:35:02 +00:00
c35e56196a xwayland: Use g_get_host_name instead of gethostname
Since the xauth file is never going to be changed after it is generated,
it is safe to use g_get_host_name here.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/626
https://gitlab.gnome.org/GNOME/mutter/merge_requests/638
2019-06-24 09:35:02 +00:00
181c7cab32 wayland: Use right sign for workspace ID
We get a signed integer (-1 meaning "no workspace specified"), store it in
an unsigned integer, check for >= 0 (of course it is!) and set as the window
workspace (signed integer, -1 meaning "show on all workspaces"). What could
possibly go wrong?

https://gitlab.gnome.org/GNOME/mutter/merge_requests/639
2019-06-24 09:21:49 +00:00
740a62044e wayland/pointer-constraints: Fix build when native backend is disabled
https://gitlab.gnome.org/GNOME/mutter/merge_requests/636
2019-06-22 16:12:42 +00:00
0bf0366933 Update Croatian translation 2019-06-22 16:01:11 +00:00
70bacb9402 cogl: Remove CoglError wrapper
CoglError was added at a certain point to remove the hard dependency on
GLib, but since this can't be avoided inside mutter, let's remove this
whole abstraction.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/631
2019-06-20 18:25:04 +02:00
57dfe4696d kms-update: Seal updates when posting them
This makes sure that we won't accidentally change KMS transaction
updates after they have been posted.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
22a91f23ad backends/native: Add some KMS debug logging
Using the g_debug() macro. Set G_DEBUG_MESSAGES to "mutter" to activate
log.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
6aa1026600 kms: Add high level code documentation
Document the high level components of the KMS abstraction.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
75dff3e7c9 backend/native: Add and use transactional KMS API
This commit introduces, and makes use of, a transactional API used for
setting up KMS state, later to be applied, potentially atomically. From
an API point of view, so is always the case, but in the current
implementation, it still uses legacy drmMode* API to apply the state
non-atomically.

The API consists of various buliding blocks:

 * MetaKmsUpdate - a set of configuration changes, the higher level
handle for handing over configuration to the impl backend. It's used to
set mode, assign framebuffers to planes, queue page flips and set
connector properties.
 * MetaKmsPlaneAssignment - the assignment of a framebuffer to a plane.
Currently used to map a framebuffer to the primary plane of a CRTC. In
the legacy KMS implementation, the plane assignment is used to derive
the framebuffer used for mode setting and page flipping.

This also means various high level changes:

State, excluding configuring the cursor plane and creating/destroying
DRM framebuffer handles, are applied in the end of a clutter frame, in
one go. From an API point of view, this is done atomically, but as
mentioned, only the non-atomic implementation exists so far.

From MetaRendererNative's point of view, a page flip now initially
always succeeds; the handling of EBUSY errors are done asynchronously in
the MetaKmsImpl backend (still by retrying at refresh rate, but
postponing flip callbacks instead of manipulating the frame clock).
Handling of falling back to mode setting instead of page flipping is
notified after the fact by a more precise page flip feedback API.

EGLStream based page flipping relies on the impl backend not being
atomic, as the page flipping is done in the EGLStream backend (e.g.
nvidia driver). It uses a 'custom' page flip queueing method, keeping
the EGLStream logic inside meta-renderer-native.c.

Page flip handling is moved to meta-kms-impl-device.c from
meta-gpu-kms.c. It goes via an extra idle callback before reaching
meta-renderer-native.c to make sure callbacks are invoked outside of the
impl context.

While dummy power save page flipping is kept in meta-renderer-native.c, the
EBUSY handling is moved to meta-kms-impl-simple.c. Instead of freezing the
frame clock, actual page flip callbacks are postponed until all EBUSY retries
have either succeeded or failed due to some other error than EBUSY. This
effectively inhibits new frames to be drawn, meaning we won't stall waiting on
the file descriptor for pending page flips.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
bea7600471 logical-monitor: Pass output when iterating over CRTCs
While not currently used by any users, it'll be useful in future
commits.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
8932388dda backend/native: Move some KMS utilities to its own file
They are not strictly related to any of the KMS objects, and should be
reusable without adding a dependency on the non-meta-kms-* files in
meta-kms-*.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
2238c9f180 kms: Add API to register impl file descriptors
To let the MetaKmsImpl implementation register file descriptor GSource
where the invoke function is ensured to be executed in the impl context.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
ca21ca6745 kms: Add API to add a GSource that'll be invoked in the impl context
The MetaKmsImpl implementation may need to add a GSource that should be
invoked in the right context; e.g. a idle callback, timeout etc. It
cannot just add it itself, since it's the responsibility of MetaKms to
determine what is the impl context and what is the main context, so add
API to MetaKms to ensure the callback is invoked correctly.

It's the responsibility of the caller to eventually remove and destroy
the GSource.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
2bbd2e5563 kms: Add API to post callbacks out of the impl context
While the current impl context is in the same thread as the main
context, the separation still exists, and to post callbacks from the
impl context, it must pass MetaKms to make sure the callback is invoked
in the right context.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
691d58e69b gpu/kms: Remove unused typedef
https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
d84c7269b2 crtc/kms: Use MetaKmsPlane to check supported rotations and formats
Instead of manually retrieving supported transforms and formats from the
primary plane of the CRTC, use the MetaKmsPlane abstraction to find the
primary plane of the CRTC and check compatibility using the
MetaKmsPlane API. This removes the last user of direct KMS API usage
except for applying configuration.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
aba689312f gpu/kms: Init global mode list from MetaKmsConnectors
Instead of iterating over the available drmModeConnector objects to
construct a GPU wide mode list, use the state managed by
MetaKmsConnector. This also removes the last user of drmModeRes from
MetaGpuKms.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
f2d9a11013 output/kms: Outsource connector state fetching to MetaKmsConnector
As with CRTC state, variable connector state is now fetched via the
MetaKmsConnector. The existance of a connector state is equivalent of
the connector being connected. MetaOutputKms is changed to fetch
variable connector state via MetaKmsConnector intsead of KMS directly.
The drmModeConnector is still used for constructing the MetaOutputKms to
find properties used for applying configuration.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:56 +00:00
596376c408 crtc/kms: Outsource CRTC state fetching to MetaKmsCrtc
Move reading state into a struct for MetaCrtcKms to use instead of
querying KMS itself. The state is fetched in the impl context, but
consists of only simple data types, so is made accessible publicly. As
of this, MetaCrtcKms construction does not involve any manual KMS
interaction outside of the MetaKms abstraction.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
1f62a8dbd9 crtc/kms: Don't redefine META_MONITOR_N_TRANSFORMS
https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
f59d62bc8f kms: Add connector representation
Represents drmModeConnector; both connected and disconnected. Currently
only provides non-changing meta data. MetaOutputKms is changed to use
MetaKmsConnector to get basic metadata, but variable metadata, those
changing depending on what is connected (e.g. physical dimension, EDID,
etc), are still manually retrieved by MetaOutputKms.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
5d5d296551 gpu/kms: Fix connector id type in helper
It's a uint32_t, not a long.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
065bf752f4 output/kms: Make drmModeEncoderPtr array local
It was only used within one function, where it was always created, but
still was kept around indefinitely for no reason. Lets get rid of it
from the MetaOutputKms struct.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
4d3e804391 kms: Add plane representation
A plane is one of three possible: primary, overlay and cursor. Each
plane can have various properties, such as possible rotations, formats
etc. Each plane can also be used with a set of CRTCs.

A primary plane is the "backdrop" of a CRTC, i.e. the primary output for
the composited frame that covers the whole CRTC. In general, mutter
composites to a stage view frame onto a framebuffer that is then put on
the primary plane.

An overlay plane is a rectangular area that can be displayed on top of
the primary plane. Eventually it will be used to place non-fullscreen
surfaces, potentially avoiding stage redraws.

A cursor plane is a plane placed on top of all the other planes, usually
used to put the mouse cursor sprite.

Initially, we only fetch the rotation properties, and we so far
blacklist all rotations except ones that ends up with the same
dimensions as with no rotations. This is because non-180° rotations
doesn't work yet due to incorrect buffer modifiers. To make it possible
to use non-180° rotations, changes necessary include among other things
finding compatible modifiers using atomic modesetting. Until then,
simply blacklist the ones we know doesn't work.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
15a2ccd21b kms: Add CRTC representation
Add MetaKmsCrtc to represent a CRTC on the associated device. Change
MetaCrtcKms to use the ones discovered by the KMS abstraction. It still
reads the resources handed over by MetaGpuKms, but eventually it will
use only MetaKmsCrtc.

MetaKmsCrtc is a type of object that is usable both from an impl task
and from outside. All the API exposed via the non-private header is
expected to be accessible from outside of the meta-kms namespace.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
fef5753a19 backends/native: Add basic KMS abstraction building blocks
The intention with KMS abstraction is to hide away accessing the drm
functions behind an API that allows us to have different kind of KMS
implementations, including legacy non-atomic and atomic. The intention
is also that the code interacting with the drm device should be able to
be run in a different thread than the main thread. This means that we
need to make sure that all drm*() API usage must only occur from within
tasks that eventually can be run in the dedicated thread.

The idea here is that MetaKms provides a outward facing API other places
of mutter can use (e.g. MetaGpuKms and friends), while MetaKmsImpl is
an internal implementation that only gets interacted with via "tasks"
posted via the MetaKms object. These tasks will in the future
potentially be run on the dedicated KMS thread. Initially, we don't
create any new threads.

Likewise, MetaKmsDevice is a outward facing representation of a KMS
device, while MetaKmsImplDevice is the corresponding implementation,
which only runs from within the MetaKmsImpl tasks.

This commit only moves opening and closing the device to this new API,
while leaking the fd outside of the impl enclosure, effectively making
the isolation for drm*() calls pointless. This, however, is necessary to
allow gradual porting of drm interaction, and eventually the file
descriptor in MetaGpuKms will be removed. For now, it's harmless, since
everything still run in the main thread.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
f3fd7cf92b gpu/kms: Remove max buffer size getter
It was unused.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
5c500ad402 backend: Move GPU ownership from the monitor manager to the backend
Lets work towards making MetaMonitorManager about managing monitors, and
not about managing GPUs. This changes other units to keep a pointer to
the backend instead of a monitor manager, in case their ownership
changed, or their main usage of the monitor manager was to look up GPUs.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
e7fd068a78 monitor-manager/kms: Use 'hotplug' event from MetaUdev
Instead of dealing with udev details here, use the newly added 'hotplug'
event emitted from MetaUdev.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
171e5fc3c2 udev: Add 'hotplug' event
To be used my the monitor manager to handle hotplugs.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
7b7d881386 udev: Add helpers to list DRM devices
Will be used to move out some udev related logic when adding GPUs.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
44905d96da backends/native: Move some initialization from init() to initable_init()
This means we can report the errors properly, instead of logging a
warning and calling exit(1).

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
73e8127d5d backends/native: Add udev abstraction layer
To be used to signal devices added, hotplugs and other udev events.
Currently the only event emitted is when a device is added.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
11e2005563 backends/native: Remove instance private
The object struct definition itself is private, so the object instance
private serves no purpose. Thus, move the fields into the object struct
and remove the instance private struct.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
2019-06-20 13:31:55 +00:00
02fc0b4533 clutter/evdev: Implement togglekeys notification
Notify with a system sound when the modifiers lock state is changed.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/637
2019-06-20 11:40:13 +00:00
36155f72d0 clutter/evdev: Do not reset timers on togglekeys
The “togglekeys” setting is to emit a sounds whenever the state of one
of the modifiers keys (CAPS lock, NUM Lock, SCROLL lock) is changed, it
has nothing to do with the rest of the accessibility settings.

Therefore, there is no need to reset the various timers used by
accessibility whenever the “togglekeys” setting is changed.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/614
2019-06-20 11:40:13 +00:00
c63d0173b5 xwayland: Fix build without <sys/random.h>
The include <sys/random.h> was added to glibc-2.25, previously was
<linux/random.h>.

Adjust meson build and code to accomodate both.

Fixes: a8984a81c "xwayland: Generate a Xauth file and pass this to
                  Xwayland when starting it"

https://gitlab.gnome.org/GNOME/mutter/merge_requests/633
2019-06-20 12:37:18 +02:00
7fcdd60ac5 renderer-native: Fix compiler warning
Fix the following compiler warning:
../src/backends/native/meta-renderer-native.c: In function ‘meta_renderer_native_create_view’:
/usr/include/glib-2.0/glib/gmacros.h:523:17: warning: ‘formats’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  523 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }                                                              \
      |                 ^
../src/backends/native/meta-renderer-native.c:773:22: note: ‘formats’ was declared here
  773 |   g_autoptr (GArray) formats;
      |                      ^~~~~~~

https://gitlab.gnome.org/GNOME/mutter/merge_requests/632
2019-06-20 10:32:52 +02:00
a8984a81c2 xwayland: Generate a Xauth file and pass this to Xwayland when starting it
Before this commit, sudo x11-app, e.g. sudo gvim /etc/some-file, fails
when running a Wayland session. Where as doing this under a "GNOME on Xorg"
session works fine. For a user switching from the Xorg session to the
Wayland session, this is regression, which we want to avoid.

This commit fixes this by creating and passing an xauth file to Xwayland when
mutter starts it. Just like gdm or startx pass a xauth file to Xorg when they
start Xorg.

Fixes #643

https://gitlab.gnome.org/GNOME/mutter/issues/643
2019-06-20 10:16:21 +02:00
769a02b630 cogl: Drop _COGL_RETURN_VAL_IF_FAIL macro
This was introduced when the Cogl maintainers tried to move away from
GLib. Since we always require it, we can just use
`g_return_val_if_fail()` immediately.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/629
2019-06-19 21:46:22 +02:00
576330edce cogl: Drop _COGL_RETURN_IF_FAIL macro
This was introduced when the Cogl maintainers tried to move away from
GLib. Since we always require it, we can just use `g_return_if_fail()`
immediately.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/629
2019-06-19 21:36:19 +02:00
a2a114e79c cogl: Remove unused _COGL_TYPEDEF_ASSERT() macro
We can safely remove it since it's used nowhere in the code base. If you
would still like to use someting similar, there's `G_STATIC_ASSERT`.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/629
2019-06-19 21:03:31 +02:00
79e22853ea cogl: Remove cogl_util_ffs macro
Since commit 46942c24, we don't need the wrapper macro as we always
require its implementation to be available on the build system.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/629
2019-06-19 21:03:28 +02:00
be72b22964 cogl: Remove cogl_util_memmem() macro
`cogl_util_memmem` was used as a wrapper in case `memmem` wasn't
defined, but since commit 46942c24 these are required. In case of
`memmem`, we didn't explicitly require this in the meson build files, so
add that as well.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/629
2019-06-19 21:03:23 +02:00
2464f00902 screen-cast-monitor-stream-src: Watch monitors using MetaStageWatch
This uses the API introduced by the previous commit. By watching specific
monitors directly, and not whole stage views, we avoid showing artifacts
on multi-monitor setups.

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

https://gitlab.gnome.org/GNOME/mutter/merge_requests/623
2019-06-19 13:12:18 -03:00
9b5d9f3cb3 stage: Introduce MetaStageWatch and family
MetaStageWatch, watch modes and the watch function are part
of the new stage view watching API. It's design does not
rely on signals on purpose; the number of signals that would
be emitted would be too high, and would impact performance.

MetaStageWatch is an opaque structure outside of MetaStage.

This will be used by the screencast code to monitor a single
view, which has a one-to-one relatioship to logical monitors.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/623
2019-06-19 13:12:17 -03:00
088117a619 clutter/tests: Connect to ClutterStage:paint-view
ClutterStage:after-paint now does not guarantee a valid
implicit framebuffer pushed to the stack. Instead, use
the new 'paint-view' signal, that is emitted at a point
in the drawing routine where a framebuffer is pushed.

In addition to that, stop using the implicit framebuffer
API and port the actor-shader-effect test to read from
the view's framebuffer directly.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/623
2019-06-19 13:12:17 -03:00
4a19628829 clutter/stage: Add ClutterStage:paint-view
Now that ClutterStageView is embraced as part of the public
set of Clutter classes, is it possible to give consumers
of this API more information and control over the drawing
routines of ClutterStage.

Introduce ClutterStage:paint-view, a signal that is emitted
for painting a specific view. It's defined as a RUN_LAST
signal to give anyone connecting to it the ability to run
before the view is actually painted, or after (using the
G_CONNECT_AFTER flag, or g_signal_connect_after).

This signal has a corresponding class handler, which allows
Mutter to have much finer control over the painting routines.
In fact, this will allow us to implement a "paint phase watcher"
mechanism in the following patches.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/623
2019-06-19 13:12:17 -03:00
0cd54c5735 clutter/stage: Emit after-paint after painting
ClutterStage:after-paint is supposed to be emitted after all
painting is done, but before the frame is finished. However,
as it is right now, it is being emitted after each view is
painted -- on multi-monitor setups, after-frame is being
emitted multiple times.

Send after-paint only once, after all views are painted and
before finishing the frame.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/623
2019-06-19 12:35:29 -03:00
cc2c670a5e clutter/stage: Own clutter_stage_get_view_at()
This function is exported as a Mutter-specific function,
but now that ClutterStageView is part of the public API,
ClutterStage can own this function.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/623
2019-06-19 12:35:29 -03:00
769a01f4e9 clutter: Make ClutterStageView a public class
As a compositor toolkit, it makes sense to allow consumers
of Clutter interact with the stage views themselves. As such,
ClutterStageView should be a public class.

As such, it is now included in clutter.h and should not be
included directly.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/623
2019-06-19 12:35:29 -03:00
9c1afbbb67 clutter/stage-view: Annotate some functions
The GIR parser cannot figure out the ownership model of
ClutterStageView.get_framebuffer() and .get_offscreen()
without them, and throws us a couple of warnings.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/623
2019-06-19 12:35:28 -03:00
376725e30e clutter/stage-view: Move unexported functions to private header
Next commits will expose ClutterStageView as a public class, so
move the functions private to Clutter to a private header.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/623
2019-06-19 12:35:27 -03:00
b836e661cf wayland: Don't export non-public API not used by tests
https://gitlab.gnome.org/GNOME/mutter/merge_requests/628
2019-06-19 15:19:05 +00:00
446e82e86d test-utils: Fix compiler warning
This fixes the following compiler warning:

In file included from /usr/include/glib-2.0/glib.h:114,
                 from ../src/tests/test-utils.h:23,
                 from ../src/tests/test-utils.c:22:
../src/tests/test-utils.c: In function ‘test_init’:
/usr/include/glib-2.0/glib/glib-autocleanups.h:28:3: warning: ‘basename’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   28 |   g_free (*pp);
      |   ^~~~~~~~~~~~
../src/tests/test-utils.c:73:24: note: ‘basename’ was declared here
   73 |       g_autofree char *basename;
      |                        ^~~~~~~~

https://gitlab.gnome.org/GNOME/mutter/merge_requests/627
2019-06-19 13:00:17 +02:00
f2020913fd Updated Spanish translation 2019-06-19 10:10:45 +02:00
d9fb11b043 renderer/native: Fix EGLSurface destruction order
Make sure to destroy the EGL surface after releasing held buffers,
otherwise we'll get the following valgrind warnings:

==24016== Invalid read of size 8
==24016==    at 0x1739943F: release_buffer (platform_drm.c:73)
==24016==    by 0x49AC355: meta_drm_buffer_gbm_finalize (meta-drm-buffer-gbm.c:213)
==24016==    by 0x4B75B61: g_object_unref (gobject.c:3346)
==24016==    by 0x49B4B41: free_current_bo (meta-renderer-native.c:991)
==24016==    by 0x49B816F: meta_renderer_native_release_onscreen (meta-renderer-native.c:2971)
==24016==    by 0x5209441: _cogl_onscreen_free (cogl-onscreen.c:167)
==24016==    by 0x5208D81: _cogl_object_onscreen_indirect_free (cogl-onscreen.c:51)
==24016==    by 0x51C8066: _cogl_object_default_unref (cogl-object.c:103)
==24016==    by 0x5207989: _cogl_framebuffer_unref (cogl-framebuffer.c:1814)
==24016==    by 0x51C80B1: cogl_object_unref (cogl-object.c:115)
==24016==    by 0x53673C7: clutter_stage_view_dispose (clutter-stage-view.c:304)
==24016==    by 0x4B75AF2: g_object_unref (gobject.c:3309)
==24016==  Address 0x18e742a8 is 536 bytes inside a block of size 784 free'd
==24016==    at 0x4839A0C: free (vg_replace_malloc.c:540)
==24016==    by 0x17399764: dri2_drm_destroy_surface (platform_drm.c:231)
==24016==    by 0x1738550A: eglDestroySurface (eglapi.c:1145)
==24016==    by 0x5440286: eglDestroySurface (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
==24016==    by 0x49613A5: meta_egl_destroy_surface (meta-egl.c:432)
==24016==    by 0x49B80F9: meta_renderer_native_release_onscreen (meta-renderer-native.c:2954)
==24016==    by 0x5209441: _cogl_onscreen_free (cogl-onscreen.c:167)
==24016==    by 0x5208D81: _cogl_object_onscreen_indirect_free (cogl-onscreen.c:51)
==24016==    by 0x51C8066: _cogl_object_default_unref (cogl-object.c:103)
==24016==    by 0x5207989: _cogl_framebuffer_unref (cogl-framebuffer.c:1814)
==24016==    by 0x51C80B1: cogl_object_unref (cogl-object.c:115)
==24016==    by 0x53673C7: clutter_stage_view_dispose (clutter-stage-view.c:304)
==24016==  Block was alloc'd at
==24016==    at 0x483AB1A: calloc (vg_replace_malloc.c:762)
==24016==    by 0x173997AE: dri2_drm_create_window_surface (platform_drm.c:145)
==24016==    by 0x17388906: _eglCreateWindowSurfaceCommon (eglapi.c:929)
==24016==    by 0x5440197: eglCreateWindowSurface (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
==24016==    by 0x49612FF: meta_egl_create_window_surface (meta-egl.c:396)
==24016==    by 0x49B752E: meta_renderer_native_create_surface_gbm (meta-renderer-native.c:2538)
==24016==    by 0x49B7E6C: meta_onscreen_native_allocate (meta-renderer-native.c:2870)
==24016==    by 0x49B8BCF: meta_renderer_native_create_view (meta-renderer-native.c:3387)
==24016==    by 0x48D274B: meta_renderer_create_view (meta-renderer.c:78)
==24016==    by 0x48D27DE: meta_renderer_rebuild_views (meta-renderer.c:111)
==24016==    by 0x49BB4FB: meta_stage_native_rebuild_views (meta-stage-native.c:142)
==24016==    by 0x49A733C: meta_backend_native_update_screen_size (meta-backend-native.c:517)

https://gitlab.gnome.org/GNOME/mutter/merge_requests/622
2019-06-18 11:12:03 +02:00
56ddaaa380 renderer/native: Make sure we're not destroying an active EGLSurface
When making a new surface/context pair current, mesa may want to flush
the old context. Make sure we don't try to flush any freed memory by
unmaking a surface/context pair current before freeing it.

Not doing this results in the following valgrind warnings:

==15986== Invalid read of size 8
==15986==    at 0x69A6D80: dri_flush_front_buffer (gbm_dri.c:92)
==15986==    by 0x1750D458: intel_flush_front (brw_context.c:251)
==15986==    by 0x1750D4BB: intel_glFlush (brw_context.c:296)
==15986==    by 0x1739D8DD: dri2_make_current (egl_dri2.c:1461)
==15986==    by 0x17393A3A: eglMakeCurrent (eglapi.c:869)
==15986==    by 0x54381FB: InternalMakeCurrentVendor (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
==15986==    by 0x5438515: eglMakeCurrent (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
==15986==    by 0x522A782: _cogl_winsys_egl_make_current (cogl-winsys-egl.c:303)
==15986==    by 0x49B64C8: meta_renderer_native_create_view (meta-renderer-native.c:3076)
==15986==    by 0x48D26E7: meta_renderer_create_view (meta-renderer.c:78)
==15986==    by 0x48D277A: meta_renderer_rebuild_views (meta-renderer.c:111)
==15986==    by 0x49BF46E: meta_stage_native_rebuild_views (meta-stage-native.c:142)
==15986==  Address 0x1b076600 is 0 bytes inside a block of size 48 free'd
==15986==    at 0x4839A0C: free (vg_replace_malloc.c:540)
==15986==    by 0x49B59F3: meta_renderer_native_release_onscreen (meta-renderer-native.c:2651)
==15986==    by 0x5211441: _cogl_onscreen_free (cogl-onscreen.c:167)
==15986==    by 0x5210D81: _cogl_object_onscreen_indirect_free (cogl-onscreen.c:51)
==15986==    by 0x51D0066: _cogl_object_default_unref (cogl-object.c:103)
==15986==    by 0x520F989: _cogl_framebuffer_unref (cogl-framebuffer.c:1814)
==15986==    by 0x51D00B1: cogl_object_unref (cogl-object.c:115)
==15986==    by 0x536F3C7: clutter_stage_view_dispose (clutter-stage-view.c:304)
==15986==    by 0x4B7DAF2: g_object_unref (gobject.c:3309)
==15986==    by 0x4A9596C: g_list_foreach (glist.c:1013)
==15986==    by 0x4A9599A: g_list_free_full (glist.c:223)
==15986==    by 0x48D2737: meta_renderer_rebuild_views (meta-renderer.c:100)
==15986==  Block was alloc'd at
==15986==    at 0x483AB1A: calloc (vg_replace_malloc.c:762)
==15986==    by 0x69A76B2: gbm_dri_surface_create (gbm_dri.c:1252)
==15986==    by 0x69A6BFE: gbm_surface_create (gbm.c:600)
==15986==    by 0x49B4E29: meta_renderer_native_create_surface_gbm (meta-renderer-native.c:2221)
==15986==    by 0x49B57DB: meta_onscreen_native_allocate (meta-renderer-native.c:2569)
==15986==    by 0x49B6423: meta_renderer_native_create_view (meta-renderer-native.c:3062)
==15986==    by 0x48D26E7: meta_renderer_create_view (meta-renderer.c:78)
==15986==    by 0x48D277A: meta_renderer_rebuild_views (meta-renderer.c:111)
==15986==    by 0x49BF46E: meta_stage_native_rebuild_views (meta-stage-native.c:142)
==15986==    by 0x49A75B5: meta_backend_native_update_screen_size (meta-backend-native.c:520)
==15986==    by 0x48B01BB: meta_backend_sync_screen_size (meta-backend.c:224)
==15986==    by 0x48B09B7: meta_backend_real_post_init (meta-backend.c:501)

https://gitlab.gnome.org/GNOME/mutter/merge_requests/622
2019-06-18 11:12:03 +02:00
1efb32d300 renderer/native: Use g_set_error() instead of _cogl_set_error()
It's even a GError, so lets use the proper API.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/622
2019-06-18 11:12:03 +02:00
6dba56223a Update Dutch translation 2019-06-18 08:22:17 +00:00
2ff6beea35 cogl: Remove cogl_wayland_texture_2d_* functions
These are implemented in the Meta namespace these days, where we have
better abstractions for wayland-related types. They also weren't used
anymore, since we removed the unused ClutterWaylandSurface type in the
previous commit.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/624
2019-06-18 09:54:04 +02:00
689c7f4107 clutter: Remove unused ClutterWaylandSurface
This allows for some further cleanups, since it is the sole consumer of
some functions in Cogl.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/624
2019-06-18 09:54:00 +02:00
59bf1f4838 window/wayland: Don't always use constrained size when unfullscreening
When we're unfullscreening, we might be returning to a window state that
has its size either managed by constraints (tiled, maximized), or not
(floating). Lets just pass the configure size 0x0 when we're not using
constrained sizes (i.e. the window going from being fullscreen to not
maximized) and let the application decide how to size itself.

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

https://gitlab.gnome.org/GNOME/mutter/merge_requests/621
2019-06-13 16:40:57 +00:00
db0f85ba5d window: Add tile mode getter
Lets avoid peeking in the MetaWindow struct itself and add a getter for
the relevant state.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/621
2019-06-13 16:40:57 +00:00
425611eadf window/wayland: Use constrained size when unmaximizing while fullscreen
Otherwise we'll ask the client to use the size 0x0 with the fullscreen
state set.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/621
2019-06-13 16:40:57 +00:00
9213574870 renderer/native: add missing eglTerminate in EGLDevice error path
Currently the EGLDevice code gets the display and calls eglInitialize.
As a follow-up it checks the required EGL extensions - technically it
could check the EGL device extensions earlier.

In either case, eglTerminate is missing. Thus the connection to the
display was still bound.

This was highlighted with Mesa commit d6edccee8da ("egl: add
EGL_platform_device support") + amdgpu.

In that case, since the eglTerminate is missing, we end up reusing the
underlying amdgpu_device due to some caching in libdrm_amdgpu. The
latter in itself being a good solution since it allows buffer sharing
across primary and render node of the same device.

Note: we should really get this in branches all the way back to 3.30.

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

Fixes: 934184e23 ("MetaRendererNative: Add EGLDevice based rendering support")
Cc: Jonas Ådahl <jadahl@gmail.com>
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
2019-06-13 17:12:40 +01:00
3073acc3b0 clutter/stage: Remove offscreen property
It was deprecated, unused and unimplemented, so lets remove it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/616
2019-06-13 14:28:46 +00:00
a61d525111 clutter: Remove stage fullscreening
Another unneeded feature related to clutter originally being an
application library that we have no use for when we're only ever a
compositor.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/616
2019-06-13 14:28:46 +00:00
4064d9a7a7 clutter: Remove ability to be user resizable
It's a functionality from the application centric clutter that we don't
need for compositors.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/616
2019-06-13 14:28:46 +00:00
8a06cfdd81 enum-types: Use @basename@ in header comment
@filename@ may contain arch-specific bits that introduce unnecessary
multi-lib issues.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/617
2019-06-12 18:01:36 +02:00
d3e789e677 Updated Spanish translation 2019-06-11 12:56:38 +02:00
c24d8e856b clutter/x11: Fix build without libwacom
When libwacom is configured disabled, this error appears:

../clutter/clutter/x11/clutter-input-device-xi2.c: In function ‘clutter_input_device_xi2_finalize’:
../clutter/clutter/x11/clutter-input-device-xi2.c:122:7: error: ‘device_xi2’ undeclared (first use in this function)
   if (device_xi2->inhibit_pointer_query_timer)

Fix it with the "obvious" solution.

This code was added in c1303bd642.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/611
2019-06-10 14:25:05 +03:00
9db9793f33 clutter: Clarify clutter_stage_get_actor_at_pos docs
When a user moves their cursor the perceived behaviour is that it will
pick what is under the cursor. However this isn't how picking works.
Picking does a virtual redraw of the screen, so in some cases what gets
picked isn't the same as what the user could see on the previous frame.
It more represents what will be drawn on the next frame than what is on
screen at present.

It may be unsafe to change these semantics, and they are useful anyway.
Just document it better.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/214
2019-06-07 19:58:49 +00:00
c237bc5f45 clutter-effect: Rename get_paint_volume
`_clutter_effect_get_paint_volume` was misleading. Its only purpose is
to modify an existing paint volume. So change `get` to `modify`.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/115
2019-06-07 19:51:53 +00:00
178b975d6a cursor-renderer: Align OpenGL cursor rect to physical pixel grid
When stage views are scaled with fractional scales, the cursor rectangle
won't be aligned with the physical pixel grid, making it potentially
blurry when positioned in between physical pixels. This can be avoided
by aligning the drawn rectangle to the physical pixel grid of the stage
view the cursor is located on.

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

https://gitlab.gnome.org/GNOME/mutter/merge_requests/610
2019-06-07 19:11:34 +00:00
4abca411f3 clutter/stage: Expose stage view getter helper as API
Non-introspected and private to mutter, for getting a stage view from a
coordinate.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/610
2019-06-07 19:11:34 +00:00
e48c7c009a clutter/stage: Make view fetch helper take floats
https://gitlab.gnome.org/GNOME/mutter/merge_requests/610
2019-06-07 19:11:34 +00:00
36b361617d wayland/cursor-surface: Update sprite when attaching NULL
Attaching a NULL buffer should hide the cursor sprite. In these cases,
we we'll have neither surface nor buffer damage, so also update when we
just attached a NULL buffer.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/630
2019-06-07 16:06:47 +00:00
5eac1d696d wayland/surface: Clear texture when attaching NULL
When 252e64a0ea moved the texture
ownership to MetaWaylandSurface, it failed to handle the case when a
NULL-buffer is attached, leaving the texture reference in place. This
caused issues when the surface should have been hidden (e.g. attaching a
NULL buffer to a cursor surface for hiding the cursor sprite).

Related: https://gitlab.gnome.org/GNOME/mutter/issues/630
2019-06-07 16:06:47 +00:00
9b53583945 cogl/trace: Fix typo
https://gitlab.gnome.org/GNOME/mutter/merge_requests/609
2019-06-07 12:58:10 -03:00
1dbf25afa1 clutter/stage-cogl: Protect against extremely high refresh rates
After 4faeb12731, the maximum time allowed for an update to happen
is calculated as:

  max_render_time_allowed = refresh_interval - 1000 * sync_delay;

However, extremely small refresh intervals -- that come as consequence
to extremely high refresh rates -- may fall into an odd numerical range
when refresh_interval < 1000 * sync_delay. That would give us a negative
time.

To be extra cautious about it, add another sanity check for this case.

Change suggested by Jasper St. Pierre.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/363
2019-06-07 12:20:49 -03:00
e415cc538a clutter/master-clock: Remove fallback throttles
The presentation timing logic (via `master_clock_get_swap_wait_time`) now
works unconditionally. By "works" we mean that a result of zero from
`master_clock_get_swap_wait_time` actually means zero now. Previously
zero could mean either a successful result of zero milliseconds or that
the backend couldn't get an answer. And a non-zero result is the same as
before.

This works even if the screen is "idle" and even if the backend doesn't
provide presentation timestamps. So now our two fallback throttling
mechanisms of relying on `CLUTTER_FEATURE_SWAP_THROTTLE` and decimating
to `clutter_get_default_frame_rate` can be deleted.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/406 and
        https://bugzilla.gnome.org/show_bug.cgi?id=781835

https://gitlab.gnome.org/GNOME/mutter/merge_requests/363
2019-06-07 12:08:49 -03:00
67a3715ded clutter/stage-cogl: Reduce while loop iterations
If `last_presentation_time` is zero (unsupported) or just very old
(system was idle) then we would like to avoid that triggering a large
number of loop interations. This will get us closer to the right answer
without iterating.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/363
2019-06-07 12:08:49 -03:00
35aa278194 clutter/stage-cogl: Stop schedule_update repeatedly returning now
That could happen if the backend did not provide presentation timestamps,
or if the screen was not changing other than the hardware cursor:

  if (stage_cogl->last_presentation_time == 0||
      stage_cogl->last_presentation_time < now - 150000)
    {
      stage_cogl->update_time = now;
      return;
    }

By setting `update_time` to `now`, master_clock_get_swap_wait_time()
returns 0:

  gint64 now = g_source_get_time (master_clock->source);
  if (min_update_time < now)
    {
      return 0;
    }
  else
    {
      gint64 delay_us = min_update_time - now;
      return (delay_us + 999) / 1000;
    }

However, zero is a value unsupported by the default master clock
due to:

  if (swap_delay != 0)
    return swap_delay;

All cases are now handled by extrapolating when the next presentation
time would be and calculating an appropriate update time to meet that.

We also need to add a check for `update_time == last_update_time`, which
is a situation that just became possible since we support old (or zero)
values of `last_presentation_time`. This avoids getting more than one
stage update per frame interval when input events arrive without
triggering a stage redraw (e.g. moving the hardware cursor).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/363
2019-06-07 12:03:35 -03:00
a76762a05e clutter/stage-cogl: Use default frame rate instead of hardcoded 60Hz
Instead of 0Hz falling back to 60Hz, use `CLUTTER_DEFAULT_FPS` which is
also 60Hz by default.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/363
2019-06-07 14:42:01 +08:00
ccf27e5f83 clutter/stage-cogl: Schedule immediate update on zero refresh interval
Instead of crazy refresh rates >1MHz falling back to 60Hz, just honour
them by rendering unthrottled (same as `sync_delay < 0`). Although I
wouldn't actually expect that path to ever be needed in reality, it just
ensures an infinite `while` loop never happens.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/363
2019-06-07 14:42:01 +08:00
912a9ecfba clutter/stage-cogl: Use G_USEC_PER_SEC instead of hardcoded number
One million is the number of microseconds in one second, which is also
defined by `G_USEC_PER_SEC`.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/363
2019-06-07 14:42:01 +08:00
0487d672ed x11-display: Handle mapped XIDs per type
Starting from commit 7713006f5, during X11 disposition we also unmanage the
windows using the xids hash table values list.
However, this is also populated by the X11 Meta barrier implementation and then
contains both Windows and Barriers.

So when going through the values list, check whether we're handling a window or
a barrier and based on that, unmanage or destroy it.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/624
https://gitlab.gnome.org/GNOME/mutter/merge_requests/605
2019-06-06 21:35:11 +00:00
e94a0fced9 display: Dispose Stack after Compositor and X11
As per commit 7718e67f, destroying the compositor causes destroying window
actors and this leads to stack changes, but at this point the stack was already
disposed and cleared.

So, clear the stack when any component that could use it (compositor, and X11)
has already been destroyed.
As consequence, also the stamps should be destroyed at later point.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/623
https://gitlab.gnome.org/GNOME/mutter/merge_requests/605
2019-06-06 21:35:11 +00:00
a3b86447f7 backends: Add mouse accessibility settings
Add support for mouse accessibility settings to set the click assist
values.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/512
2019-06-06 13:04:50 +02:00
1d76eace1e clutter: Hook up pointer accessibility
When using evdev (for Wayland), the backend receives all device events
and queue them for clutter.

Hook up the pointer accessibility handlers in clutter's main processing
queue, so that we get better accuracy for pointer location.

We need to avoid doing this on X11 though because X11 relies on the raw
events for this to work reliably, so the same is already done in the
X11 backend when using X11.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/512
2019-06-06 13:04:50 +02:00
c1303bd642 clutter/x11: Hook up pointer accessibility
Pointer accessibility features requires to receive all pointer events
regardless of X11 grabs.

Add XI2 raw events mask and hook up the pointer accessibility handlers
to the raw motion and button press/release events.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/512
2019-06-06 13:04:50 +02:00
db11a37a68 clutter: Add pointer accessibility features
Add support for click assist, namely simulated secondary click (on a
long primary button press) and hover click support (simulate a click when
the pointer remains static for some time).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/512
2019-06-06 13:04:50 +02:00
0d0b9da6f8 clutter: Add pointer accessibility signals
Add the required signaling in place in clutter device manager to notify
the upper layers (namely, the shell) whenever a click assist delay or
gesture is started or stopped.

This will allow the shell to implement a visual feedback for click
assist operations.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/512
2019-06-06 13:04:50 +02:00
ab0b407da4 clutter/enums: Add pointer accessibility types
Add the relevant enumeration types to support pointer accessibility
features.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/512
2019-06-06 13:04:50 +02:00
c33b330799 backends: Rename keyboard accessibility settings
Naming the keyboard accessibility settings `a11y_settings` wrongly
assumes there will never be any other type of accessibility settings.

Rename `a11y_settings` to `keyboard_a11y_settings` to avoid future
confusion.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/512
2019-06-06 13:04:50 +02:00
144b24bfcc clutter/evdev: Use the accessibility virtual device
Instead of adding one specifically for keyboard accessibility in evdev,
use the one from ClutterInputDevice instead.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/512
2019-06-06 13:04:50 +02:00
4d21650d6d clutter: Add an accessibility virtual device
For accessibility features, being either keyboard accessibility to
implement mousekeys, or pointer accessibility to implement simulated
secondary click or dwell click, we need to have a virtual device.

Add that virtual device in ClutterInputDevice so it can be used either
for keyboard or pointer accessibility.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/512
2019-06-06 13:04:50 +02:00
a6fc656e91 window: Emit an error and return when trying to activate an unmanaged
If something (i.e. gnome-shell or an extension) tries to activate an unmanaged
window, we should warn about this and avoid to perform further actions as this
could lead to a crash of mutter, since the window has not valid flags (like
workspace) set anymore at this stage.

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

https://gitlab.gnome.org/GNOME/mutter/merge_requests/564
2019-06-05 17:53:12 +00:00
a38bae259e docs: Update tests instructions
The documentation still refers to autotools, update it to
use the corresponding meson commands.

https://gitlab.gnome.org/GNOME/mutter/issues/568
2019-06-05 14:49:35 -03:00
c53aa89098 keybindings: Small code cleanup
Reuse the name we just set to insert in the hash table, that avoids
duplicating the string.

Suggested-by: Carlos Garnacho <carlosg@gnome.org>

https://gitlab.gnome.org/GNOME/mutter/merge_requests/453
2019-06-05 09:34:39 +00:00
851b7d0639 keybindings: Trigger locate-pointer on key modifier
We trigger the "locate-pointer" mechanism when a special key modifier
(defaults to Control_L) key is pressed and released.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/453
https://gitlab.gnome.org/GNOME/gnome-shell/issues/981
https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas/merge_requests/19
https://gitlab.gnome.org/GNOME/gnome-settings-daemon/merge_requests/86
2019-06-05 09:34:39 +00:00
b4c78726cf compositor: Add "locate_pointer" vmethod
This method is invoked to locate the pointer on screen.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/453
https://gitlab.gnome.org/GNOME/gnome-shell/issues/981
https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas/merge_requests/19
https://gitlab.gnome.org/GNOME/gnome-settings-daemon/merge_requests/86
2019-06-05 09:34:39 +00:00
c9cc07fd3a settings: Slack off “xwayland-allow-grabs” setting
To emulate X11 grabs, mutter as a Wayland compositor would disable its
own keyboard shortcuts and when the X11 window is an override redirect
window (which never receives focus), it also forces keyboard focus onto
that X11 O-R window so that all keyboard events are routed to the
window, just like an X11 server would.

But that's a bit of a “all-or-nothing” approach which prevents
applications that would legitimately grab the keyboard under X11 (like
virtual machine viewers) to work by default.

Change “xwayland-allow-grabs” to control whether the keyboard focus
should be locked onto override redirect windows in case of an X11 grab.

For stringent needs, careful users can still use the blacklisting
feature (i.e. a list containing “!*”) to prevent grabs from any X11
applications to affect other Wayland native applications.

https://gitlab.gnome.org/GNOME/mutter/issues/597
2019-06-03 09:34:31 +02:00
f6eb2a8cf8 settings: Remove space characters
Small code style cleanup.

https://gitlab.gnome.org/GNOME/mutter/issues/597
2019-06-03 09:34:31 +02:00
08e5589836 Update Hungarian translation 2019-06-01 15:48:01 +00:00
4f5a5e84fc Update POTFILES.in 2019-05-31 20:47:46 +02:00
0786683189 meson: Add no-omit-frame-pointer to clutter debug builds
This will help us getting better stacktraces and sysprof integration.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/601
2019-05-31 16:03:43 +00:00
4887de533c meson: Do not use clutter_c_args for GIR
Certain arguments like `-fno-omit-frame-pointer` break GIR creation.
Lets handle this like we do for the rest of mutter and duplicate the
relevant arguments from `clutter_c_args`.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/601
2019-05-31 16:03:43 +00:00
57945a730f backend: Conditionally compile MetaProfiler
MetaProfiler is not built when -Dprofiler=false, and that
breaks the build since MetaBackend unconditionally imports
and uses it.

Fix that by wrapping MetaProfiler in compile-time checks.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/603
2019-05-31 12:54:13 -03:00
78254146f3 build: Rename HAVE_TRACING to HAVE_PROFILER in Mutter
It fits better the name of the build flag. Cogl still uses
HAVE_TRACING since profiler is already used by it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/603
2019-05-31 12:54:10 -03:00
3e2a2cf532 clutter/stage-cogl: Simplify redraw function
Spotted while adding tracing to swap buffers, we only enter
the first part of the if condition when use_clipped_redraw
is TRUE, so it's pretty safe to assume it's TRUE.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
2019-05-31 11:57:09 -03:00
04b240b50c ci: Add sysprof3 to the Docker image
It is now a dependency that we want to build against,
even if optional.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
2019-05-31 11:57:09 -03:00
7810f0e276 cogl/trace: Add user-visible group name
This way, it shows up as "Compositor" in Sysprof instead of
"t:XYZ".

https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
2019-05-31 11:57:09 -03:00
9b8f9b65b8 clutter: Add more descriptive profiling sections
The idea here is to be able to visualize and immediately
understand what is happening. Something like:

```
                   [ view1 ] [ view2 ]
 [---- Layout ---][------ Paint ------][ Pick ]
[================== Update =====================]
```

But with colors. A few of the previous profiling data
sections were removed, since they didn't really add to
reading the graph.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
2019-05-31 11:57:08 -03:00
e741cab3f4 profiler: Support setting output filename
So we can have some control over where the file will
be saved.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
2019-05-31 11:57:08 -03:00
53748e3da7 cogl-trace: Cleanup context after disabling
This allows running the Capture() method multiple times,
with different arguments each time.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
2019-05-31 11:57:07 -03:00
17c5436f6e profile: Add a Sysprof-based profiler
This exposes the /org/gnome/Sysprof3/Profiler object
inside Mutter to allow initiating a Sysprof capture.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
2019-05-31 11:57:07 -03:00
04fb6f7659 clutter: Add some preliminary tracing to clutter
https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
2019-05-31 11:57:07 -03:00
e5e58f8075 cogl: Add libsysprof capture based tracing
Add the ability to add tracing instrumentation to the code. When
enabled, trace entries will generate a file with timing information
that will be processable by sysprof for generating visualization of
traces over time.

While enabled by default at compile time, it is possible to disable the
expansion of the macros completely by passing --disable-tracing to
./configure.

Tracing is so far only actually done if actually enabled on explicitly
specified threads.

This will be used by Mutter passing the write end of a pipe, where the
read end is sent to Sysprof itself via the D-Bus method 'Capture()'.

By passing that, we have to detect EPIPE that is sent when Sysprof stops
recording. Fortunately, we already ignore the signal at meta_init(), so
no need to add a custom signal handler.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
2019-05-31 11:55:56 -03:00
1da0355528 wayland: Update tablet cursor outputs across cursor/proximity changes
Make sure those generic surface events are sent early on when setting a
cursor for any tablet tool, so clients can update to output characteristics.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/545
Related: https://gitlab.gnome.org/GNOME/gtk/issues/1675
2019-05-31 09:57:24 +00:00
e5881156f6 wayland: Handle NULL cursor renderer finding the outputs of a cursor role
Having a cursor role with a NULL renderer is valid state, and even desirable
on tablets (eg. after proximity out). In those cases it should be
interpreted as the cursor surface not being over any output.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/545
2019-05-31 09:57:24 +00:00
60170cff70 compositor: Emit 'grab-op-end' signal after ungrab happened
We're currently emitting the 'grab-op-end' signal when the grab prerequisites
are met, but when display->grab_op is still set to a not-NONE value and thus
meta_display_get_grab_op() would return that in the signal callback.
And more importantly when this is emitted, devices are still grabbed.

Instead, emit this signal as soon as we've unset all the grab properties and
released the devices.

Helps with https://gitlab.gnome.org/GNOME/gnome-shell/issues/1326

https://gitlab.gnome.org/GNOME/mutter/merge_requests/596
2019-05-29 20:09:40 +00:00
e2bea48073 display: Emit 'grab-op-end' signal after ungrab happened
We're currently emitting the 'grab-op-end' signal when the grab prerequisites
are met, but when display->grab_op is still set to a not-NONE value and thus
meta_display_get_grab_op() would return that in the signal callback.
And more importantly when this is emitted, devices are still grabbed.

Instead, emit this signal as soon as we've unset all the grab properties and
released the devices.

Helps with https://gitlab.gnome.org/GNOME/gnome-shell/issues/1326

https://gitlab.gnome.org/GNOME/mutter/merge_requests/596
2019-05-29 20:09:40 +00:00
bbfaf8204b wayland: Honor startup sequence workspace on .request_focus
We handle this in backend specific code for x11, so do the wayland
bits here. We can only honor this on applications that request focus
on a surface after a startup request, as we do need an explicit
surface to apply the workspace on (and we don't have additional clues
like WMCLASS on X11). Notably, gtk_shell1.notify_startup doesn't suffice.

Another gotcha is that the .request_focus happens when the surface is
already "mapped". Due to the way x11 and the GDK api currently work (first
reply on the startup id, then map a window, then request focus on that
window). This means the surface will ignore at this point
window->initial_workspace, so it must be actively changed.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/544
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/674
2019-05-29 16:21:15 +00:00
b3e19ee669 wayland: Unset DnD selection on wl_data_offer destruction
On a successful DnD operation we may expect the wl_data_source and
wl_data_offer to live long enough to finish the data transfer, despite the
grab operation (and other supporting data) being gone.

When that happens, the compositor expects a wl_data_offer.finish request to
notify that it finished. However the client may still chose not to send that
and destroy the wl_data_offer instead, resulting in the MetaSelectionSource
owner for the DnD selection not being unset.

When that happens, the DnD MetaSelectionSource still exists but it's
detached from any grab operation, so will not be unset if eg. the drag
source client destroys the wl_data_source. This may result in crashes when
the next drag operation tries to replace the owner DnD MetaSelectionSource.

Check explicitly for this case, in order to ensure the DnD owner is unset
after such operations.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/591
2019-05-29 16:10:57 +00:00
75e2bfb062 meson: Do not add compiler flags if 'plain' buildtype is used
That is how the 'plain' buildtype is meant in meson.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/497
2019-05-29 15:52:39 +00:00
a859d76c72 meson: Cleanup debug build handling
Add debug flags based on meson's `debug` option instead of `buildtype`.
This allows custom build configurations to behave like a debug or release build.

Add `-fno-omit-frame-pointer` to Mutter/Cogl. Not to Clutter though, as that would
require more changes to how Clutter's gir is created

Remove `-DG_DISABLE_CAST_CHECKS` from Clutter in debug builds

Add `-DG_DISABLE_CHECKS`, `-DG_DISABLE_ASSERT` and `-DG_DISABLE_CAST_CHECKS` to all
non-debug builds but `plain`, which explicitly should not have any compile flags

Use `cc.get_supported_arguments`, so it becomes more obvious to the user which flags
are set during compilation

https://gitlab.gnome.org/GNOME/mutter/merge_requests/497
2019-05-29 15:52:39 +00:00
2145333969 renderer/native: Refactor into secondary_gpu_get_next_dumb_buffer
Extract the next buffer -logic into a new function. This allows to
simplify copy_shared_framebuffer_cpu () making it more readable.

This change is a pure refactoring, no functional changes.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/593
2019-05-29 11:53:00 -03:00
1b61b9cd73 boxes: Fix calculation of rounded rectangles
Since 68fba458 the function is used for more calculations, exposing
a bug when used with fractional scaling.

https://gitlab.gnome.org/GNOME/mutter/issues/609
2019-05-29 00:07:15 +02:00
334 changed files with 11587 additions and 6602 deletions

View File

@ -15,6 +15,7 @@ RUN dnf -y update && dnf -y upgrade && \
# Unpackaged versions
dnf install -y https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00834984-gsettings-desktop-schemas/gsettings-desktop-schemas-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00834984-gsettings-desktop-schemas/gsettings-desktop-schemas-devel-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm && \
dnf install -y https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/libsysprof-ui-3.33.2-1.fc30.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/sysprof-cli-3.33.2-1.fc30.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/sysprof-3.33.2-1.fc30.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/sysprof-devel-3.33.2-1.fc30.x86_64.rpm && \
dnf install -y intltool redhat-rpm-config make && \

View File

@ -17551,7 +17551,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
l != NULL && l->data != priv->current_effect;
l = l->next)
{
if (!_clutter_effect_get_paint_volume (l->data, pv))
if (!_clutter_effect_modify_paint_volume (l->data, pv))
{
clutter_paint_volume_free (pv);
CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "
@ -17569,7 +17569,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
/* otherwise, get the cumulative volume */
effects = _clutter_meta_group_peek_metas (priv->effects);
for (l = effects; l != NULL; l = l->next)
if (!_clutter_effect_get_paint_volume (l->data, pv))
if (!_clutter_effect_modify_paint_volume (l->data, pv))
{
clutter_paint_volume_free (pv);
CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "

View File

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

View File

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

View File

@ -69,6 +69,22 @@ typedef struct _ClutterTouchInfo
gfloat current_y;
} ClutterTouchInfo;
typedef struct _ClutterPtrA11yData
{
int n_btn_pressed;
float current_x;
float current_y;
float dwell_x;
float dwell_y;
gboolean dwell_drag_started;
gboolean dwell_gesture_started;
guint dwell_timer;
guint secondary_click_timer;
gboolean secondary_click_triggered;
} ClutterPtrA11yData;
struct _ClutterInputDevice
{
GObject parent_instance;
@ -143,6 +159,10 @@ struct _ClutterInputDevice
guint has_cursor : 1;
guint is_enabled : 1;
/* Accessiblity */
ClutterVirtualInputDevice *accessibility_virtual_device;
ClutterPtrA11yData *ptr_a11y_data;
};
typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,

View File

@ -47,6 +47,7 @@
#include "clutter-stage-private.h"
#include "clutter-virtual-input-device.h"
#include "clutter-input-device-tool.h"
#include "clutter-input-pointer-a11y-private.h"
struct _ClutterDeviceManagerPrivate
{
@ -55,6 +56,8 @@ struct _ClutterDeviceManagerPrivate
/* Keyboard a11y */
ClutterKbdA11ySettings kbd_a11y_settings;
/* Pointer a11y */
ClutterPointerA11ySettings pointer_a11y_settings;
};
enum
@ -75,6 +78,9 @@ enum
TOOL_CHANGED,
KBD_A11Y_MASK_CHANGED,
KBD_A11Y_FLAGS_CHANGED,
PTR_A11Y_DWELL_CLICK_TYPE_CHANGED,
PTR_A11Y_TIMEOUT_STARTED,
PTR_A11Y_TIMEOUT_STOPPED,
LAST_SIGNAL
};
@ -239,6 +245,67 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
G_TYPE_NONE, 2,
G_TYPE_UINT,
G_TYPE_UINT);
/**
* ClutterDeviceManager::ptr-a11y-dwell-click-type-changed:
* @manager: the #ClutterDeviceManager that emitted the signal
* @click_type: the new #ClutterPointerA11yDwellClickType mode
*
* The ::ptr-a11y-dwell-click-type-changed signal is emitted each time
* the ClutterPointerA11yDwellClickType mode is changed as the result
* of pointer accessibility operations.
*/
manager_signals[PTR_A11Y_DWELL_CLICK_TYPE_CHANGED] =
g_signal_new (I_("ptr-a11y-dwell-click-type-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__FLAGS,
G_TYPE_NONE, 1,
CLUTTER_TYPE_POINTER_A11Y_DWELL_CLICK_TYPE);
/**
* ClutterDeviceManager::ptr-a11y-timeout-started:
* @manager: the #ClutterDeviceManager that emitted the signal
* @device: the core pointer #ClutterInputDevice
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
* @delay: the delay in ms before secondary-click is triggered.
*
* The ::ptr-a11y-timeout-started signal is emitted when a
* pointer accessibility timeout delay is started, so that upper
* layers can notify the user with some visual feedback.
*/
manager_signals[PTR_A11Y_TIMEOUT_STARTED] =
g_signal_new (I_("ptr-a11y-timeout-started"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__OBJECT_FLAGS_UINT,
G_TYPE_NONE, 3,
CLUTTER_TYPE_INPUT_DEVICE,
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
G_TYPE_UINT);
/**
* ClutterDeviceManager::ptr-a11y-timeout-stopped:
* @manager: the #ClutterDeviceManager that emitted the signal
* @device: the core pointer #ClutterInputDevice
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
*
* The ::ptr-a11y-timeout-stopped signal is emitted when a running
* pointer accessibility timeout delay is stopped, either because
* it's triggered at the end of the delay or cancelled, so that
* upper layers can notify the user with some visual feedback.
*/
manager_signals[PTR_A11Y_TIMEOUT_STOPPED] =
g_signal_new (I_("ptr-a11y-timeout-stopped"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__OBJECT_FLAGS,
G_TYPE_NONE, 2,
CLUTTER_TYPE_INPUT_DEVICE,
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE);
}
static void
@ -579,3 +646,88 @@ clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_man
*settings = device_manager->priv->kbd_a11y_settings;
}
static gboolean
are_pointer_a11y_settings_equal (ClutterPointerA11ySettings *a,
ClutterPointerA11ySettings *b)
{
return (memcmp (a, b, sizeof (ClutterPointerA11ySettings)) == 0);
}
static void
clutter_device_manager_enable_pointer_a11y (ClutterDeviceManager *device_manager)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device_manager,
CLUTTER_POINTER_DEVICE);
_clutter_input_pointer_a11y_add_device (core_pointer);
}
static void
clutter_device_manager_disable_pointer_a11y (ClutterDeviceManager *device_manager)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device_manager,
CLUTTER_POINTER_DEVICE);
_clutter_input_pointer_a11y_remove_device (core_pointer);
}
/**
* clutter_device_manager_set_pointer_a11y_settings:
* @device_manager: a #ClutterDeviceManager
* @settings: a pointer to a #ClutterPointerA11ySettings
*
* Sets the pointer accessibility settings
**/
void
clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings)
{
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
if (are_pointer_a11y_settings_equal (&device_manager->priv->pointer_a11y_settings, settings))
return;
if (device_manager->priv->pointer_a11y_settings.controls == 0 && settings->controls != 0)
clutter_device_manager_enable_pointer_a11y (device_manager);
else if (device_manager->priv->pointer_a11y_settings.controls != 0 && settings->controls == 0)
clutter_device_manager_disable_pointer_a11y (device_manager);
device_manager->priv->pointer_a11y_settings = *settings;
}
/**
* clutter_device_manager_get_pointer_a11y_settings:
* @device_manager: a #ClutterDeviceManager
* @settings: a pointer to a #ClutterPointerA11ySettings
*
* Gets the current pointer accessibility settings
**/
void
clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings)
{
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
*settings = device_manager->priv->pointer_a11y_settings;
}
/**
* clutter_device_manager_set_pointer_a11y_dwell_click_type:
* @device_manager: a #ClutterDeviceManager
* @click_type: type of click as #ClutterPointerA11yDwellClickType
*
* Sets the dwell click type
**/
void
clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
ClutterPointerA11yDwellClickType click_type)
{
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
device_manager->priv->pointer_a11y_settings.dwell_click_type = click_type;
}

View File

@ -73,6 +73,27 @@ typedef struct _ClutterKbdA11ySettings
gint mousekeys_accel_time;
} ClutterKbdA11ySettings;
/**
* ClutterPointerA11ySettings:
*
* The #ClutterPointerA11ySettings structure contains pointer accessibility
* settings
*
*/
typedef struct _ClutterPointerA11ySettings
{
ClutterPointerA11yFlags controls;
ClutterPointerA11yDwellClickType dwell_click_type;
ClutterPointerA11yDwellMode dwell_mode;
ClutterPointerA11yDwellDirection dwell_gesture_single;
ClutterPointerA11yDwellDirection dwell_gesture_double;
ClutterPointerA11yDwellDirection dwell_gesture_drag;
ClutterPointerA11yDwellDirection dwell_gesture_secondary;
gint secondary_click_delay;
gint dwell_delay;
gint dwell_threshold;
} ClutterPointerA11ySettings;
/**
* ClutterDeviceManager:
*
@ -152,10 +173,23 @@ ClutterVirtualDeviceType clutter_device_manager_get_supported_virtual_device_typ
CLUTTER_EXPORT
void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
ClutterKbdA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
ClutterKbdA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
ClutterPointerA11yDwellClickType click_type);
G_END_DECLS
#endif /* __CLUTTER_DEVICE_MANAGER_H__ */

View File

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

View File

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

View File

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

View File

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

View File

@ -443,6 +443,88 @@ typedef enum
CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
} ClutterKeyboardA11yFlags;
/**
* ClutterPointerA11yFlags:
* @CLUTTER_A11Y_POINTER_ENABLED:
* @CLUTTER_A11Y_SECONDARY_CLICK_ENABLED:
* @CLUTTER_A11Y_DWELL_ENABLED:
*
* Pointer accessibility features applied to a ClutterInputDevice pointer.
*
*/
typedef enum {
CLUTTER_A11Y_SECONDARY_CLICK_ENABLED = 1 << 0,
CLUTTER_A11Y_DWELL_ENABLED = 1 << 1,
} ClutterPointerA11yFlags;
/**
* ClutterPointerA11yDwellClickType:
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: Internal use only
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
*
* Dwell click types.
*
*/
typedef enum {
CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE,
CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY,
CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY,
CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE,
CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE,
CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG,
} ClutterPointerA11yDwellClickType;
/**
* ClutterPointerA11yDwellDirection:
* @CLUTTER_A11Y_DWELL_DIRECTION_NONE:
* @CLUTTER_A11Y_DWELL_DIRECTION_LEFT:
* @CLUTTER_A11Y_DWELL_DIRECTION_RIGHT:
* @CLUTTER_A11Y_DWELL_DIRECTION_UP:
* @CLUTTER_A11Y_DWELL_DIRECTION_DOWN:
*
* Dwell gesture directions.
*
*/
typedef enum {
CLUTTER_A11Y_DWELL_DIRECTION_NONE,
CLUTTER_A11Y_DWELL_DIRECTION_LEFT,
CLUTTER_A11Y_DWELL_DIRECTION_RIGHT,
CLUTTER_A11Y_DWELL_DIRECTION_UP,
CLUTTER_A11Y_DWELL_DIRECTION_DOWN,
} ClutterPointerA11yDwellDirection;
/**
* ClutterPointerA11yDwellMode:
* @CLUTTER_A11Y_DWELL_MODE_WINDOW:
* @CLUTTER_A11Y_DWELL_MODE_GESTURE:
*
* Dwell mode.
*
*/
typedef enum {
CLUTTER_A11Y_DWELL_MODE_WINDOW,
CLUTTER_A11Y_DWELL_MODE_GESTURE,
} ClutterPointerA11yDwellMode;
/**
* ClutterPointerA11yTimeoutType:
* @CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK:
* @CLUTTER_A11Y_TIMEOUT_TYPE_DWELL:
* @CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE:
*
* Pointer accessibility timeout type.
*
*/
typedef enum {
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
} ClutterPointerA11yTimeoutType;
/**
* ClutterActorFlags:
* @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside
@ -892,8 +974,6 @@ typedef enum /*< prefix=CLUTTER_SCROLL >*/
/**
* ClutterStageState:
* @CLUTTER_STAGE_STATE_FULLSCREEN: Fullscreen mask
* @CLUTTER_STAGE_STATE_OFFSCREEN: Offscreen mask (deprecated)
* @CLUTTER_STAGE_STATE_ACTIVATED: Activated mask
*
* Stage state masks, used by the #ClutterEvent of type %CLUTTER_STAGE_STATE.
@ -902,8 +982,6 @@ typedef enum /*< prefix=CLUTTER_SCROLL >*/
*/
typedef enum
{
CLUTTER_STAGE_STATE_FULLSCREEN = (1 << 1),
CLUTTER_STAGE_STATE_OFFSCREEN = (1 << 2),
CLUTTER_STAGE_STATE_ACTIVATED = (1 << 3)
} ClutterStageState;
@ -913,7 +991,6 @@ typedef enum
* @CLUTTER_FEATURE_TEXTURE_YUV: Set if YUV based textures supported.
* @CLUTTER_FEATURE_TEXTURE_READ_PIXELS: Set if texture pixels can be read.
* @CLUTTER_FEATURE_STAGE_STATIC: Set if stage size if fixed (i.e framebuffer)
* @CLUTTER_FEATURE_STAGE_USER_RESIZE: Set if stage is able to be user resized.
* @CLUTTER_FEATURE_STAGE_CURSOR: Set if stage has a graphical cursor.
* @CLUTTER_FEATURE_SHADERS_GLSL: Set if the backend supports GLSL shaders.
* @CLUTTER_FEATURE_OFFSCREEN: Set if the backend supports offscreen rendering.
@ -931,7 +1008,6 @@ typedef enum
CLUTTER_FEATURE_TEXTURE_YUV = (1 << 4),
CLUTTER_FEATURE_TEXTURE_READ_PIXELS = (1 << 5),
CLUTTER_FEATURE_STAGE_STATIC = (1 << 6),
CLUTTER_FEATURE_STAGE_USER_RESIZE = (1 << 7),
CLUTTER_FEATURE_STAGE_CURSOR = (1 << 8),
CLUTTER_FEATURE_SHADERS_GLSL = (1 << 9),
CLUTTER_FEATURE_OFFSCREEN = (1 << 10),

View File

@ -107,6 +107,9 @@ clutter_input_device_dispose (GObject *gobject)
device->associated = NULL;
}
if (device->accessibility_virtual_device)
g_clear_object (&device->accessibility_virtual_device);
g_clear_pointer (&device->axes, g_array_unref);
g_clear_pointer (&device->keys, g_array_unref);
g_clear_pointer (&device->scroll_info, g_array_unref);

View File

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

View File

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

View File

@ -58,6 +58,7 @@
#include "clutter-device-manager-private.h"
#include "clutter-event-private.h"
#include "clutter-feature.h"
#include "clutter-input-pointer-a11y-private.h"
#include "clutter-main.h"
#include "clutter-master-clock.h"
#include "clutter-mutter.h"
@ -2261,6 +2262,21 @@ _clutter_process_event_details (ClutterActor *stage,
break;
case CLUTTER_MOTION:
#ifdef CLUTTER_WINDOWING_X11
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
{
if (_clutter_is_input_pointer_a11y_enabled (device))
{
ClutterInputDevice *core_pointer;
gfloat x, y;
clutter_event_get_coords (event, &x, &y);
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
CLUTTER_POINTER_DEVICE);
_clutter_input_pointer_a11y_on_motion_event (core_pointer, x, y);
}
}
#endif /* CLUTTER_WINDOWING_X11 */
/* only the stage gets motion events if they are enabled */
if (!clutter_stage_get_motion_events_enabled (CLUTTER_STAGE (stage)) &&
event->any.source == NULL)
@ -2299,6 +2315,22 @@ _clutter_process_event_details (ClutterActor *stage,
/* fallthrough from motion */
case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
#ifdef CLUTTER_WINDOWING_X11
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
{
if (_clutter_is_input_pointer_a11y_enabled (device) && (event->type != CLUTTER_MOTION))
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
CLUTTER_POINTER_DEVICE);
_clutter_input_pointer_a11y_on_button_event (core_pointer,
event->button.button,
event->type == CLUTTER_BUTTON_PRESS);
}
}
#endif /* CLUTTER_WINDOWING_X11 */
case CLUTTER_SCROLL:
case CLUTTER_TOUCHPAD_PINCH:
case CLUTTER_TOUCHPAD_SWIPE:
@ -2520,7 +2552,7 @@ _clutter_process_event_details (ClutterActor *stage,
break;
case CLUTTER_STAGE_STATE:
/* fullscreen / focus - forward to stage */
/* focus - forward to stage */
event->any.source = stage;
if (!_clutter_event_process_filters (event))
clutter_stage_event (CLUTTER_STAGE (stage), event);

View File

@ -23,6 +23,7 @@ VOID:FLOAT,FLOAT
VOID:INT,INT,INT,INT
VOID:OBJECT
VOID:OBJECT,FLAGS
VOID:OBJECT,FLAGS,UINT
VOID:OBJECT,FLOAT,FLOAT
VOID:OBJECT,FLOAT,FLOAT,FLAGS
VOID:OBJECT,OBJECT

View File

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

View File

@ -40,6 +40,7 @@ void _clutter_stage_paint_view (ClutterStage
ClutterStageView *view,
const cairo_rectangle_int_t *clip);
void _clutter_stage_emit_after_paint (ClutterStage *stage);
void _clutter_stage_set_window (ClutterStage *stage,
ClutterStageWindow *stage_window);
ClutterStageWindow *_clutter_stage_get_window (ClutterStage *stage);
@ -117,7 +118,6 @@ void _clutter_stage_remove_touch_drag_actor (ClutterStage *st
ClutterStageState _clutter_stage_get_state (ClutterStage *stage);
gboolean _clutter_stage_is_activated (ClutterStage *stage);
gboolean _clutter_stage_is_fullscreen (ClutterStage *stage);
gboolean _clutter_stage_update_state (ClutterStage *stage,
ClutterStageState unset_state,
ClutterStageState set_state);

View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2019 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_STAGE_VIEW_PRIVATE_H__
#define __CLUTTER_STAGE_VIEW_PRIVATE_H__
#include "clutter/clutter-stage-view.h"
void clutter_stage_view_blit_offscreen (ClutterStageView *view,
const cairo_rectangle_int_t *clip);
gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
void clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
gboolean dirty);
gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
gboolean dirty);
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */

View File

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

View File

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

View File

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

View File

@ -30,12 +30,8 @@ struct _ClutterStageWindowInterface
void (* set_title) (ClutterStageWindow *stage_window,
const gchar *title);
void (* set_fullscreen) (ClutterStageWindow *stage_window,
gboolean is_fullscreen);
void (* set_cursor_visible) (ClutterStageWindow *stage_window,
gboolean cursor_visible);
void (* set_user_resizable) (ClutterStageWindow *stage_window,
gboolean is_resizable);
gboolean (* realize) (ClutterStageWindow *stage_window);
void (* unrealize) (ClutterStageWindow *stage_window);
@ -83,12 +79,8 @@ ClutterActor * _clutter_stage_window_get_wrapper (ClutterStageWindow *
void _clutter_stage_window_set_title (ClutterStageWindow *window,
const gchar *title);
void _clutter_stage_window_set_fullscreen (ClutterStageWindow *window,
gboolean is_fullscreen);
void _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
gboolean is_visible);
void _clutter_stage_window_set_user_resizable (ClutterStageWindow *window,
gboolean is_resizable);
gboolean _clutter_stage_window_realize (ClutterStageWindow *window);
void _clutter_stage_window_unrealize (ClutterStageWindow *window);

View File

@ -72,9 +72,11 @@
#include "clutter-private.h"
#include "clutter-stage-manager-private.h"
#include "clutter-stage-private.h"
#include "clutter-stage-view-private.h"
#include "clutter-private.h"
#include "cogl/cogl.h"
#include "cogl/cogl-trace.h"
/* <private>
* ClutterStageHint:
@ -147,13 +149,13 @@ struct _ClutterStagePrivate
gpointer paint_data;
GDestroyNotify paint_notify;
cairo_rectangle_int_t view_clip;
int update_freeze_count;
guint relayout_pending : 1;
guint redraw_pending : 1;
guint is_fullscreen : 1;
guint is_cursor_visible : 1;
guint is_user_resizable : 1;
guint use_fog : 1;
guint throttle_motion_events : 1;
guint use_alpha : 1;
@ -169,12 +171,9 @@ enum
PROP_0,
PROP_COLOR,
PROP_FULLSCREEN_SET,
PROP_OFFSCREEN,
PROP_CURSOR_VISIBLE,
PROP_PERSPECTIVE,
PROP_TITLE,
PROP_USER_RESIZABLE,
PROP_USE_FOG,
PROP_FOG,
PROP_USE_ALPHA,
@ -185,12 +184,11 @@ enum
enum
{
FULLSCREEN,
UNFULLSCREEN,
ACTIVATE,
DEACTIVATE,
DELETE_EVENT,
AFTER_PAINT,
PAINT_VIEW,
PRESENTED,
LAST_SIGNAL
@ -403,40 +401,37 @@ clutter_stage_allocate (ClutterActor *self,
flags | CLUTTER_DELEGATE_LAYOUT);
/* Ensure the window is sized correctly */
if (!priv->is_fullscreen)
if (priv->min_size_changed)
{
if (priv->min_size_changed)
{
gfloat min_width, min_height;
gboolean min_width_set, min_height_set;
gfloat min_width, min_height;
gboolean min_width_set, min_height_set;
g_object_get (G_OBJECT (self),
"min-width", &min_width,
"min-width-set", &min_width_set,
"min-height", &min_height,
"min-height-set", &min_height_set,
NULL);
g_object_get (G_OBJECT (self),
"min-width", &min_width,
"min-width-set", &min_width_set,
"min-height", &min_height,
"min-height-set", &min_height_set,
NULL);
if (!min_width_set)
min_width = 1;
if (!min_height_set)
min_height = 1;
if (!min_width_set)
min_width = 1;
if (!min_height_set)
min_height = 1;
if (width < min_width)
width = min_width;
if (height < min_height)
height = min_height;
if (width < min_width)
width = min_width;
if (height < min_height)
height = min_height;
priv->min_size_changed = FALSE;
}
priv->min_size_changed = FALSE;
}
if (window_size.width != CLUTTER_NEARBYINT (width) ||
window_size.height != CLUTTER_NEARBYINT (height))
{
_clutter_stage_window_resize (priv->impl,
CLUTTER_NEARBYINT (width),
CLUTTER_NEARBYINT (height));
}
if (window_size.width != CLUTTER_NEARBYINT (width) ||
window_size.height != CLUTTER_NEARBYINT (height))
{
_clutter_stage_window_resize (priv->impl,
CLUTTER_NEARBYINT (width),
CLUTTER_NEARBYINT (height));
}
}
else
@ -688,7 +683,22 @@ _clutter_stage_paint_view (ClutterStage *stage,
if (!priv->impl)
return;
clutter_stage_do_paint_view (stage, view, clip);
COGL_TRACE_BEGIN_SCOPED (ClutterStagePaintView, "Paint (view)");
priv->view_clip = *clip;
if (g_signal_has_handler_pending (stage, stage_signals[PAINT_VIEW],
0, TRUE))
g_signal_emit (stage, stage_signals[PAINT_VIEW], 0, view);
else
CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view);
priv->view_clip = (cairo_rectangle_int_t) { 0 };
}
void
_clutter_stage_emit_after_paint (ClutterStage *stage)
{
g_signal_emit (stage, stage_signals[AFTER_PAINT], 0);
}
@ -844,40 +854,6 @@ clutter_stage_real_deactivate (ClutterStage *stage)
clutter_stage_emit_key_focus_event (stage, FALSE);
}
static void
clutter_stage_real_fullscreen (ClutterStage *stage)
{
ClutterStagePrivate *priv = stage->priv;
cairo_rectangle_int_t geom;
ClutterActorBox box;
/* we need to force an allocation here because the size
* of the stage might have been changed by the backend
*
* this is a really bad solution to the issues caused by
* the fact that fullscreening the stage on the X11 backends
* is really an asynchronous operation
*/
_clutter_stage_window_get_geometry (priv->impl, &geom);
box.x1 = 0;
box.y1 = 0;
box.x2 = geom.width;
box.y2 = geom.height;
/* we need to blow the caching on the Stage size, given that
* we're about to force an allocation, because if anything
* ends up querying the size of the stage during the allocate()
* call, like constraints or signal handlers, we'll get into an
* inconsistent state: the stage will report the old cached size,
* but the allocation will be updated anyway.
*/
clutter_actor_set_size (CLUTTER_ACTOR (stage), -1.0, -1.0);
clutter_actor_allocate (CLUTTER_ACTOR (stage),
&box,
CLUTTER_ALLOCATION_NONE);
}
void
_clutter_stage_queue_event (ClutterStage *stage,
ClutterEvent *event,
@ -1225,22 +1201,31 @@ _clutter_stage_do_update (ClutterStage *stage)
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
return FALSE;
COGL_TRACE_BEGIN_SCOPED (ClutterStageDoUpdate, "Update");
/* NB: We need to ensure we have an up to date layout *before* we
* check or clear the pending redraws flag since a relayout may
* queue a redraw.
*/
COGL_TRACE_BEGIN (ClutterStageRelayout, "Layout");
_clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage));
COGL_TRACE_END (ClutterStageRelayout);
if (!priv->redraw_pending)
return FALSE;
if (stage_was_relayout)
pointers = _clutter_stage_check_updated_pointers (stage);
clutter_stage_maybe_finish_queue_redraws (stage);
COGL_TRACE_BEGIN (ClutterStagePaint, "Paint");
clutter_stage_maybe_finish_queue_redraws (stage);
clutter_stage_do_redraw (stage);
COGL_TRACE_END (ClutterStagePaint);
/* reset the guard, so that new redraws are possible */
priv->redraw_pending = FALSE;
@ -1254,12 +1239,16 @@ _clutter_stage_do_update (ClutterStage *stage)
}
#endif /* CLUTTER_ENABLE_DEBUG */
COGL_TRACE_BEGIN (ClutterStagePick, "Pick");
while (pointers)
{
_clutter_input_device_update (pointers->data, NULL, TRUE);
pointers = g_slist_delete_link (pointers, pointers);
}
COGL_TRACE_END (ClutterStagePick);
return TRUE;
}
@ -1570,10 +1559,13 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
return retval;
}
static ClutterStageView *
get_view_at (ClutterStage *stage,
int x,
int y)
/**
* clutter_stage_get_view_at: (skip)
*/
ClutterStageView *
clutter_stage_get_view_at (ClutterStage *stage,
float x,
float y)
{
ClutterStagePrivate *priv = stage->priv;
GList *l;
@ -1620,7 +1612,7 @@ _clutter_stage_do_pick (ClutterStage *stage,
if (x < 0 || x >= stage_width || y < 0 || y >= stage_height)
return actor;
view = get_view_at (stage, x, y);
view = clutter_stage_get_view_at (stage, x, y);
if (view)
return _clutter_stage_do_pick_on_view (stage, x, y, mode, view);
@ -1699,11 +1691,6 @@ clutter_stage_set_property (GObject *object,
clutter_value_get_color (value));
break;
case PROP_OFFSCREEN:
if (g_value_get_boolean (value))
g_warning ("Offscreen stages are currently not supported\n");
break;
case PROP_CURSOR_VISIBLE:
if (g_value_get_boolean (value))
clutter_stage_show_cursor (stage);
@ -1719,10 +1706,6 @@ clutter_stage_set_property (GObject *object,
clutter_stage_set_title (stage, g_value_get_string (value));
break;
case PROP_USER_RESIZABLE:
clutter_stage_set_user_resizable (stage, g_value_get_boolean (value));
break;
case PROP_USE_FOG:
clutter_stage_set_use_fog (stage, g_value_get_boolean (value));
break;
@ -1773,14 +1756,6 @@ clutter_stage_get_property (GObject *gobject,
}
break;
case PROP_OFFSCREEN:
g_value_set_boolean (value, FALSE);
break;
case PROP_FULLSCREEN_SET:
g_value_set_boolean (value, priv->is_fullscreen);
break;
case PROP_CURSOR_VISIBLE:
g_value_set_boolean (value, priv->is_cursor_visible);
break;
@ -1793,10 +1768,6 @@ clutter_stage_get_property (GObject *gobject,
g_value_set_string (value, priv->title);
break;
case PROP_USER_RESIZABLE:
g_value_set_boolean (value, priv->is_user_resizable);
break;
case PROP_USE_FOG:
g_value_set_boolean (value, priv->use_fog);
break;
@ -1891,6 +1862,16 @@ clutter_stage_finalize (GObject *object)
G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object);
}
static void
clutter_stage_real_paint_view (ClutterStage *stage,
ClutterStageView *view)
{
ClutterStagePrivate *priv = stage->priv;
const cairo_rectangle_int_t *clip = &priv->view_clip;
clutter_stage_do_paint_view (stage, view, clip);
}
static void
clutter_stage_class_init (ClutterStageClass *klass)
{
@ -1920,42 +1901,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
actor_class->queue_redraw = clutter_stage_real_queue_redraw;
actor_class->apply_transform = clutter_stage_real_apply_transform;
/**
* ClutterStage:fullscreen:
*
* Whether the stage should be fullscreen or not.
*
* This property is set by calling clutter_stage_set_fullscreen()
* but since the actual implementation is delegated to the backend
* you should connect to the notify::fullscreen-set signal in order
* to get notification if the fullscreen state has been successfully
* achieved.
*
* Since: 1.0
*/
pspec = g_param_spec_boolean ("fullscreen-set",
P_("Fullscreen Set"),
P_("Whether the main stage is fullscreen"),
FALSE,
CLUTTER_PARAM_READABLE);
g_object_class_install_property (gobject_class,
PROP_FULLSCREEN_SET,
pspec);
/**
* ClutterStage:offscreen:
*
* Whether the stage should be rendered in an offscreen buffer.
*
* Deprecated: 1.10: This property does not do anything.
*/
pspec = g_param_spec_boolean ("offscreen",
P_("Offscreen"),
P_("Whether the main stage should be rendered offscreen"),
FALSE,
CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED);
g_object_class_install_property (gobject_class,
PROP_OFFSCREEN,
pspec);
klass->paint_view = clutter_stage_real_paint_view;
/**
* ClutterStage:cursor-visible:
*
@ -1969,21 +1916,6 @@ clutter_stage_class_init (ClutterStageClass *klass)
g_object_class_install_property (gobject_class,
PROP_CURSOR_VISIBLE,
pspec);
/**
* ClutterStage:user-resizable:
*
* Whether the stage is resizable via user interaction.
*
* Since: 0.4
*/
pspec = g_param_spec_boolean ("user-resizable",
P_("User Resizable"),
P_("Whether the stage is able to be resized via user interaction"),
FALSE,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_USER_RESIZABLE,
pspec);
/**
* ClutterStage:color:
*
@ -2131,39 +2063,6 @@ clutter_stage_class_init (ClutterStageClass *klass)
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_ACCEPT_FOCUS, pspec);
/**
* ClutterStage::fullscreen:
* @stage: the stage which was fullscreened
*
* The ::fullscreen signal is emitted when the stage is made fullscreen.
*
* Since: 0.6
*/
stage_signals[FULLSCREEN] =
g_signal_new (I_("fullscreen"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterStageClass, fullscreen),
NULL, NULL,
_clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* ClutterStage::unfullscreen:
* @stage: the stage which has left a fullscreen state.
*
* The ::unfullscreen signal is emitted when the stage leaves a fullscreen
* state.
*
* Since: 0.6
*/
stage_signals[UNFULLSCREEN] =
g_signal_new (I_("unfullscreen"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterStageClass, unfullscreen),
NULL, NULL,
_clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* ClutterStage::activate:
* @stage: the stage which was activated
@ -2247,6 +2146,28 @@ clutter_stage_class_init (ClutterStageClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 0);
/**
* ClutterStage::paint-view:
* @stage: the stage that received the event
* @view: a #ClutterStageView
*
* The ::paint-view signal is emitted before a #ClutterStageView is being
* painted.
*
* The view is painted in the default handler. Hence, if you want to perform
* some action after the view is painted, like reading the contents of the
* framebuffer, use g_signal_connect_after() or pass %G_CONNECT_AFTER.
*/
stage_signals[PAINT_VIEW] =
g_signal_new (I_("paint-view"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterStageClass, paint_view),
NULL, NULL,
_clutter_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
CLUTTER_TYPE_STAGE_VIEW);
/**
* ClutterStage::presented: (skip)
* @stage: the stage that received the event
@ -2264,7 +2185,6 @@ clutter_stage_class_init (ClutterStageClass *klass)
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_POINTER);
klass->fullscreen = clutter_stage_real_fullscreen;
klass->activate = clutter_stage_real_activate;
klass->deactivate = clutter_stage_real_deactivate;
klass->delete_event = clutter_stage_real_delete_event;
@ -2315,8 +2235,6 @@ clutter_stage_init (ClutterStage *self)
priv->event_queue = g_queue_new ();
priv->is_fullscreen = FALSE;
priv->is_user_resizable = FALSE;
priv->is_cursor_visible = TRUE;
priv->use_fog = FALSE;
priv->throttle_motion_events = TRUE;
@ -2712,136 +2630,6 @@ _clutter_stage_get_viewport (ClutterStage *stage,
*height = priv->viewport[3];
}
/**
* clutter_stage_set_fullscreen:
* @stage: a #ClutterStage
* @fullscreen: %TRUE to to set the stage fullscreen
*
* Asks to place the stage window in the fullscreen or unfullscreen
* states.
*
( Note that you shouldn't assume the window is definitely full screen
* afterward, because other entities (e.g. the user or window manager)
* could unfullscreen it again, and not all window managers honor
* requests to fullscreen windows.
*
* If you want to receive notification of the fullscreen state you
* should either use the #ClutterStage::fullscreen and
* #ClutterStage::unfullscreen signals, or use the notify signal
* for the #ClutterStage:fullscreen-set property
*
* Since: 1.0
*/
void
clutter_stage_set_fullscreen (ClutterStage *stage,
gboolean fullscreen)
{
ClutterStagePrivate *priv;
g_return_if_fail (CLUTTER_IS_STAGE (stage));
priv = stage->priv;
if (priv->is_fullscreen != fullscreen)
{
ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
ClutterStageWindowInterface *iface;
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
/* Only set if backend implements.
*
* Also see clutter_stage_event() for setting priv->is_fullscreen
* on state change event.
*/
if (iface->set_fullscreen)
iface->set_fullscreen (impl, fullscreen);
}
/* If the backend did fullscreen the stage window then we need to resize
* the stage and update its viewport so we queue a relayout. Note: if the
* fullscreen request is handled asynchronously we can't rely on this
* queue_relayout to update the viewport, but for example the X backend
* will recieve a ConfigureNotify after a successful resize which is how
* we ensure the viewport is updated on X.
*/
clutter_actor_queue_relayout (CLUTTER_ACTOR (stage));
}
/**
* clutter_stage_get_fullscreen:
* @stage: a #ClutterStage
*
* Retrieves whether the stage is full screen or not
*
* Return value: %TRUE if the stage is full screen
*
* Since: 1.0
*/
gboolean
clutter_stage_get_fullscreen (ClutterStage *stage)
{
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
return stage->priv->is_fullscreen;
}
/**
* clutter_stage_set_user_resizable:
* @stage: a #ClutterStage
* @resizable: whether the stage should be user resizable.
*
* Sets if the stage is resizable by user interaction (e.g. via
* window manager controls)
*
* Since: 0.4
*/
void
clutter_stage_set_user_resizable (ClutterStage *stage,
gboolean resizable)
{
ClutterStagePrivate *priv;
g_return_if_fail (CLUTTER_IS_STAGE (stage));
priv = stage->priv;
if (clutter_feature_available (CLUTTER_FEATURE_STAGE_USER_RESIZE)
&& priv->is_user_resizable != resizable)
{
ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
ClutterStageWindowInterface *iface;
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
if (iface->set_user_resizable)
{
priv->is_user_resizable = resizable;
iface->set_user_resizable (impl, resizable);
g_object_notify (G_OBJECT (stage), "user-resizable");
}
}
}
/**
* clutter_stage_get_user_resizable:
* @stage: a #ClutterStage
*
* Retrieves the value set with clutter_stage_set_user_resizable().
*
* Return value: %TRUE if the stage is resizable by the user.
*
* Since: 0.4
*/
gboolean
clutter_stage_get_user_resizable (ClutterStage *stage)
{
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
return stage->priv->is_user_resizable;
}
/**
* clutter_stage_show_cursor:
* @stage: a #ClutterStage
@ -2945,6 +2733,8 @@ clutter_stage_read_pixels (ClutterStage *stage,
float pixel_height;
uint8_t *pixels;
COGL_TRACE_BEGIN_SCOPED (ClutterStageReadPixels, "Read Pixels");
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
priv = stage->priv;
@ -3010,7 +2800,11 @@ clutter_stage_read_pixels (ClutterStage *stage,
* @y: Y coordinate to check
*
* Checks the scene at the coordinates @x and @y and returns a pointer
* to the #ClutterActor at those coordinates.
* to the #ClutterActor at those coordinates. The result is the actor which
* would be at the specified location on the next redraw, and is not
* necessarily that which was there on the previous redraw. This allows the
* function to perform chronologically correctly after any queued changes to
* the scene, and even if nothing has been drawn.
*
* By using @pick_mode it is possible to control which actors will be
* painted and thus available.
@ -3047,13 +2841,9 @@ gboolean
clutter_stage_event (ClutterStage *stage,
ClutterEvent *event)
{
ClutterStagePrivate *priv;
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
priv = stage->priv;
if (event->type == CLUTTER_DELETE)
{
gboolean retval = FALSE;
@ -3073,24 +2863,6 @@ clutter_stage_event (ClutterStage *stage,
if (clutter_actor_event (CLUTTER_ACTOR (stage), event, FALSE))
return TRUE;
if (event->stage_state.changed_mask & CLUTTER_STAGE_STATE_FULLSCREEN)
{
if (event->stage_state.new_state & CLUTTER_STAGE_STATE_FULLSCREEN)
{
priv->is_fullscreen = TRUE;
g_signal_emit (stage, stage_signals[FULLSCREEN], 0);
g_object_notify (G_OBJECT (stage), "fullscreen-set");
}
else
{
priv->is_fullscreen = FALSE;
g_signal_emit (stage, stage_signals[UNFULLSCREEN], 0);
g_object_notify (G_OBJECT (stage), "fullscreen-set");
}
}
if (event->stage_state.changed_mask & CLUTTER_STAGE_STATE_ACTIVATED)
{
if (event->stage_state.new_state & CLUTTER_STAGE_STATE_ACTIVATED)
@ -3945,8 +3717,6 @@ clutter_stage_get_use_alpha (ClutterStage *stage)
* If the current size of @stage is smaller than the minimum size, the
* @stage will be resized to the new @width and @height
*
* This function has no effect if @stage is fullscreen
*
* Since: 1.2
*/
void
@ -4633,20 +4403,6 @@ _clutter_stage_is_activated (ClutterStage *stage)
return (stage->priv->current_state & CLUTTER_STAGE_STATE_ACTIVATED) != 0;
}
/*< private >
* _clutter_stage_is_fullscreen:
* @stage: a #ClutterStage
*
* Checks whether the @stage state includes %CLUTTER_STAGE_STATE_FULLSCREEN.
*
* Return value: %TRUE if the @stage is fullscreen
*/
gboolean
_clutter_stage_is_fullscreen (ClutterStage *stage)
{
return (stage->priv->current_state & CLUTTER_STAGE_STATE_FULLSCREEN) != 0;
}
/*< private >
* _clutter_stage_update_state:
* @stage: a #ClutterStage

View File

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

View File

@ -101,6 +101,7 @@
#include "clutter-snap-constraint.h"
#include "clutter-stage.h"
#include "clutter-stage-manager.h"
#include "clutter-stage-view.h"
#include "clutter-tap-action.h"
#include "clutter-test-utils.h"
#include "clutter-texture.h"

View File

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

View File

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

View File

@ -739,31 +739,33 @@ get_button_index (gint button)
}
static void
emulate_button_press (ClutterInputDeviceEvdev *device)
emulate_button_press (ClutterInputDeviceEvdev *device_evdev)
{
gint btn = device->mousekeys_btn;
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
gint btn = device_evdev->mousekeys_btn;
if (device->mousekeys_btn_states[get_button_index (btn)])
if (device_evdev->mousekeys_btn_states[get_button_index (btn)])
return;
clutter_virtual_input_device_notify_button (device->mousekeys_virtual_device,
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
g_get_monotonic_time (), btn,
CLUTTER_BUTTON_STATE_PRESSED);
device->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_PRESSED;
device_evdev->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_PRESSED;
}
static void
emulate_button_release (ClutterInputDeviceEvdev *device)
emulate_button_release (ClutterInputDeviceEvdev *device_evdev)
{
gint btn = device->mousekeys_btn;
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
gint btn = device_evdev->mousekeys_btn;
if (device->mousekeys_btn_states[get_button_index (btn)] == CLUTTER_BUTTON_STATE_RELEASED)
if (device_evdev->mousekeys_btn_states[get_button_index (btn)] == CLUTTER_BUTTON_STATE_RELEASED)
return;
clutter_virtual_input_device_notify_button (device->mousekeys_virtual_device,
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
g_get_monotonic_time (), btn,
CLUTTER_BUTTON_STATE_RELEASED);
device->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_RELEASED;
device_evdev->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_RELEASED;
}
static void
@ -830,17 +832,18 @@ mousekeys_get_speed_factor (ClutterInputDeviceEvdev *device,
#undef MOUSEKEYS_CURVE
static void
emulate_pointer_motion (ClutterInputDeviceEvdev *device,
emulate_pointer_motion (ClutterInputDeviceEvdev *device_evdev,
gint dx,
gint dy)
{
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
gdouble dx_motion;
gdouble dy_motion;
gdouble speed;
gint64 time_us;
time_us = g_get_monotonic_time ();
speed = mousekeys_get_speed_factor (device, time_us);
speed = mousekeys_get_speed_factor (device_evdev, time_us);
if (dx < 0)
dx_motion = floor (((gdouble) dx) * speed);
@ -852,7 +855,7 @@ emulate_pointer_motion (ClutterInputDeviceEvdev *device,
else
dy_motion = ceil (((gdouble) dy) * speed);
clutter_virtual_input_device_notify_relative_motion (device->mousekeys_virtual_device,
clutter_virtual_input_device_notify_relative_motion (device->accessibility_virtual_device,
time_us, dx_motion, dy_motion);
}
static gboolean
@ -865,51 +868,53 @@ is_numlock_active (ClutterInputDeviceEvdev *device)
}
static void
enable_mousekeys (ClutterInputDeviceEvdev *device)
enable_mousekeys (ClutterInputDeviceEvdev *device_evdev)
{
ClutterDeviceManager *manager;
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
ClutterDeviceManager *manager = device->device_manager;
device->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
device->move_mousekeys_timer = 0;
device->mousekeys_first_motion_time = 0;
device->mousekeys_last_motion_time = 0;
device->last_mousekeys_key = 0;
device_evdev->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
device_evdev->move_mousekeys_timer = 0;
device_evdev->mousekeys_first_motion_time = 0;
device_evdev->mousekeys_last_motion_time = 0;
device_evdev->last_mousekeys_key = 0;
if (device->mousekeys_virtual_device)
if (device->accessibility_virtual_device)
return;
manager = CLUTTER_INPUT_DEVICE (device)->device_manager;
device->mousekeys_virtual_device =
device->accessibility_virtual_device =
clutter_device_manager_create_virtual_device (manager,
CLUTTER_POINTER_DEVICE);
}
static void
disable_mousekeys (ClutterInputDeviceEvdev *device)
disable_mousekeys (ClutterInputDeviceEvdev *device_evdev)
{
stop_mousekeys_move (device);
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
stop_mousekeys_move (device_evdev);
/* Make sure we don't leave button pressed behind... */
if (device->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_PRIMARY)])
if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_PRIMARY)])
{
device->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
emulate_button_release (device);
device_evdev->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
emulate_button_release (device_evdev);
}
if (device->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_MIDDLE)])
if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_MIDDLE)])
{
device->mousekeys_btn = CLUTTER_BUTTON_MIDDLE;
emulate_button_release (device);
device_evdev->mousekeys_btn = CLUTTER_BUTTON_MIDDLE;
emulate_button_release (device_evdev);
}
if (device->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_SECONDARY)])
if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_SECONDARY)])
{
device->mousekeys_btn = CLUTTER_BUTTON_SECONDARY;
emulate_button_release (device);
device_evdev->mousekeys_btn = CLUTTER_BUTTON_SECONDARY;
emulate_button_release (device_evdev);
}
if (device->mousekeys_virtual_device)
g_clear_object (&device->mousekeys_virtual_device);
if (device->accessibility_virtual_device)
g_clear_object (&device->accessibility_virtual_device);
}
static gboolean
@ -1220,7 +1225,7 @@ clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *dev
update_internal_xkb_state (device, 0, 0);
}
if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_TOGGLE_KEYS_ENABLED))
if (changed_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
{
device->toggle_slowkeys_timer = 0;
device->shift_count = 0;
@ -1241,6 +1246,13 @@ clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *dev
device->a11y_flags = settings->controls;
}
void
clutter_evdev_a11y_maybe_notify_toggle_keys (ClutterInputDeviceEvdev *device)
{
if (device->a11y_flags & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED)
clutter_input_device_evdev_bell_notify ();
}
static void
release_device_touch_slot (gpointer value)
{

View File

@ -94,7 +94,6 @@ struct _ClutterInputDeviceEvdev
gdouble mousekeys_curve_factor;
guint move_mousekeys_timer;
guint16 last_mousekeys_key;
ClutterVirtualInputDevice *mousekeys_virtual_device;
};
GType _clutter_input_device_evdev_get_type (void) G_GNUC_CONST;
@ -151,6 +150,7 @@ void clutter_input_device_evdev_release_touch_state (Clutte
void clutter_input_device_evdev_release_touch_slots (ClutterInputDeviceEvdev *device_evdev,
uint64_t time_us);
void clutter_evdev_a11y_maybe_notify_toggle_keys (ClutterInputDeviceEvdev *);
G_END_DECLS

View File

@ -326,6 +326,7 @@ clutter_seat_evdev_notify_key (ClutterSeatEvdev *seat,
backend = clutter_get_default_backend ();
g_signal_emit_by_name (clutter_backend_get_keymap (backend), "state-changed");
clutter_seat_evdev_sync_leds (seat);
clutter_evdev_a11y_maybe_notify_toggle_keys (CLUTTER_INPUT_DEVICE_EVDEV (seat->core_keyboard));
}
if (state == 0 || /* key release */

View File

@ -75,6 +75,7 @@ clutter_headers = [
'clutter-snap-constraint.h',
'clutter-stage.h',
'clutter-stage-manager.h',
'clutter-stage-view.h',
'clutter-tap-action.h',
'clutter-test-utils.h',
'clutter-texture.h',
@ -133,6 +134,7 @@ clutter_sources = [
'clutter-input-device-tool.c',
'clutter-input-focus.c',
'clutter-input-method.c',
'clutter-input-pointer-a11y.c',
'clutter-virtual-input-device.c',
'clutter-interval.c',
'clutter-keyframe-transition.c',
@ -163,6 +165,7 @@ clutter_sources = [
'clutter-snap-constraint.c',
'clutter-stage.c',
'clutter-stage-manager.c',
'clutter-stage-view.c',
'clutter-stage-window.c',
'clutter-tap-action.c',
'clutter-test-utils.c',
@ -195,6 +198,7 @@ clutter_private_headers = [
'clutter-id-pool.h',
'clutter-input-focus-private.h',
'clutter-input-method-private.h',
'clutter-input-pointer-a11y-private.h',
'clutter-master-clock.h',
'clutter-master-clock-default.h',
'clutter-offscreen-effect-private.h',
@ -205,7 +209,7 @@ clutter_private_headers = [
'clutter-settings-private.h',
'clutter-stage-manager-private.h',
'clutter-stage-private.h',
'clutter-stage-view.h',
'clutter-stage-view-private.h',
'clutter-stage-window.h',
]
@ -213,7 +217,6 @@ clutter_nonintrospected_sources = [
'clutter-easing.c',
'clutter-event-translator.c',
'clutter-id-pool.c',
'clutter-stage-view.c',
]
clutter_deprecated_headers = [
@ -341,14 +344,8 @@ if have_native_backend
endif
if have_wayland
clutter_wayland_nonintrospected_sources = [
'wayland/clutter-wayland-surface.c',
]
clutter_backend_nonintrospected_sources += clutter_wayland_nonintrospected_sources
clutter_wayland_private_headers = [
'wayland/clutter-wayland-compositor.h',
'wayland/clutter-wayland-surface.h',
]
clutter_backend_private_headers += clutter_wayland_private_headers
endif
@ -504,7 +501,12 @@ libmutter_clutter_dep = declare_dependency(
)
if have_introspection
clutter_introspection_args = introspection_args + clutter_c_args
clutter_introspection_args = introspection_args + [
'-DCLUTTER_SYSCONFDIR="@0@"'.format(join_paths(prefix, sysconfdir)),
'-DCLUTTER_COMPILATION=1',
'-DCOGL_DISABLE_DEPRECATION_WARNINGS',
'-DG_LOG_DOMAIN="Clutter"'
]
libmutter_clutter_gir = gnome.generate_gir(libmutter_clutter,
sources: [

View File

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

View File

@ -1,117 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*
*/
#ifndef __CLUTTER_WAYLAND_SURFACE_H__
#define __CLUTTER_WAYLAND_SURFACE_H__
#include <glib.h>
#include <glib-object.h>
#include <clutter/clutter.h>
#include <wayland-server.h>
G_BEGIN_DECLS
#define CLUTTER_WAYLAND_TYPE_SURFACE (clutter_wayland_surface_get_type ())
#define CLUTTER_WAYLAND_SURFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_WAYLAND_TYPE_SURFACE, ClutterWaylandSurface))
#define CLUTTER_WAYLAND_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_WAYLAND_TYPE_SURFACE, ClutterWaylandSurfaceClass))
#define CLUTTER_WAYLAND_IS_SURFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_WAYLAND_TYPE_SURFACE))
#define CLUTTER_WAYLAND_IS_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_WAYLAND_TYPE_SURFACE))
#define CLUTTER_WAYLAND_SURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_WAYLAND_TYPE_SURFACE, ClutterWaylandSurfaceClass))
typedef struct _ClutterWaylandSurface ClutterWaylandSurface;
typedef struct _ClutterWaylandSurfaceClass ClutterWaylandSurfaceClass;
typedef struct _ClutterWaylandSurfacePrivate ClutterWaylandSurfacePrivate;
/**
* ClutterWaylandSurface:
*
* The #ClutterWaylandSurface structure contains only private data
*
* Since: 1.10
* Stability: unstable
*/
struct _ClutterWaylandSurface
{
/*< private >*/
ClutterActor parent;
ClutterWaylandSurfacePrivate *priv;
};
/**
* ClutterWaylandSurfaceClass:
* @queue_damage_redraw: class handler of the #ClutterWaylandSurface::queue-damage-redraw signal
*
* The #ClutterWaylandSurfaceClass structure contains only private data
*
* Since: 1.10
* Stability: unstable
*/
struct _ClutterWaylandSurfaceClass
{
/*< private >*/
ClutterActorClass parent_class;
/*< public >*/
void (*queue_damage_redraw) (ClutterWaylandSurface *texture,
gint x,
gint y,
gint width,
gint height);
/*< private >*/
/* padding for future expansion */
gpointer _padding_dummy[8];
};
CLUTTER_EXPORT
GType clutter_wayland_surface_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
ClutterActor *clutter_wayland_surface_new (struct wl_surface *surface);
CLUTTER_EXPORT
void clutter_wayland_surface_set_surface (ClutterWaylandSurface *self,
struct wl_surface *surface);
CLUTTER_EXPORT
struct wl_surface *clutter_wayland_surface_get_surface (ClutterWaylandSurface *self);
CLUTTER_EXPORT
gboolean clutter_wayland_surface_attach_buffer (ClutterWaylandSurface *self,
struct wl_resource *buffer,
GError **error);
CLUTTER_EXPORT
void clutter_wayland_surface_damage_buffer (ClutterWaylandSurface *self,
struct wl_resource *buffer,
gint32 x,
gint32 y,
gint32 width,
gint32 height);
CLUTTER_EXPORT
CoglTexture *clutter_wayland_surface_get_cogl_texture (ClutterWaylandSurface *self);
G_END_DECLS
#endif

View File

@ -89,7 +89,6 @@ static const gchar *atom_names[] = {
"_NET_WM_PID",
"_NET_WM_PING",
"_NET_WM_STATE",
"_NET_WM_STATE_FULLSCREEN",
"_NET_WM_USER_TIME",
"WM_PROTOCOLS",
"WM_DELETE_WINDOW",
@ -441,14 +440,13 @@ clutter_backend_x11_post_parse (ClutterBackend *backend,
backend_x11->atom_NET_WM_PID = atoms[0];
backend_x11->atom_NET_WM_PING = atoms[1];
backend_x11->atom_NET_WM_STATE = atoms[2];
backend_x11->atom_NET_WM_STATE_FULLSCREEN = atoms[3];
backend_x11->atom_NET_WM_USER_TIME = atoms[4];
backend_x11->atom_WM_PROTOCOLS = atoms[5];
backend_x11->atom_WM_DELETE_WINDOW = atoms[6];
backend_x11->atom_XEMBED = atoms[7];
backend_x11->atom_XEMBED_INFO = atoms[8];
backend_x11->atom_NET_WM_NAME = atoms[9];
backend_x11->atom_UTF8_STRING = atoms[10];
backend_x11->atom_NET_WM_USER_TIME = atoms[3];
backend_x11->atom_WM_PROTOCOLS = atoms[4];
backend_x11->atom_WM_DELETE_WINDOW = atoms[5];
backend_x11->atom_XEMBED = atoms[6];
backend_x11->atom_XEMBED_INFO = atoms[7];
backend_x11->atom_NET_WM_NAME = atoms[8];
backend_x11->atom_UTF8_STRING = atoms[9];
g_free (clutter_display_name);
@ -563,8 +561,7 @@ clutter_backend_x11_dispose (GObject *gobject)
static ClutterFeatureFlags
clutter_backend_x11_get_features (ClutterBackend *backend)
{
ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_USER_RESIZE
| CLUTTER_FEATURE_STAGE_CURSOR;
ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_CURSOR;
flags |= CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class)->get_features (backend);

View File

@ -89,7 +89,6 @@ struct _ClutterBackendX11
Atom atom_NET_WM_PID;
Atom atom_NET_WM_PING;
Atom atom_NET_WM_STATE;
Atom atom_NET_WM_STATE_FULLSCREEN;
Atom atom_NET_WM_USER_TIME;
Atom atom_WM_PROTOCOLS;
Atom atom_WM_DELETE_WINDOW;

View File

@ -30,6 +30,7 @@
#include "clutter-backend-x11.h"
#include "clutter-input-device-xi2.h"
#include "clutter-input-device-tool-xi2.h"
#include "clutter-input-pointer-a11y-private.h"
#include "clutter-virtual-input-device-x11.h"
#include "clutter-stage-x11.h"
@ -1273,6 +1274,60 @@ translate_pad_event (ClutterEvent *event,
return TRUE;
}
static void
handle_raw_event (ClutterDeviceManagerXI2 *manager_xi2,
XEvent *xevent)
{
ClutterInputDevice *device;
XGenericEventCookie *cookie;
XIEvent *xi_event;
XIRawEvent *xev;
float x,y;
cookie = &xevent->xcookie;
xi_event = (XIEvent *) cookie->data;
xev = (XIRawEvent *) xi_event;
device = g_hash_table_lookup (manager_xi2->devices_by_id,
GINT_TO_POINTER (xev->deviceid));
if (device == NULL)
return;
if (!_clutter_is_input_pointer_a11y_enabled (device))
return;
switch (cookie->evtype)
{
case XI_RawMotion:
CLUTTER_NOTE (EVENT,
"raw motion: device:%d '%s'",
device->id,
device->device_name);
/* We don't get actual pointer location with raw events, and we cannot
* rely on `clutter_input_device_get_coords()` either because of
* unreparented toplevels (like all client-side decoration windows),
* so we need to explicitely query the pointer here...
*/
if (clutter_input_device_xi2_get_pointer_location (device, &x, &y))
_clutter_input_pointer_a11y_on_motion_event (device, x, y);
break;
case XI_RawButtonPress:
case XI_RawButtonRelease:
CLUTTER_NOTE (EVENT,
"raw button %s: device:%d '%s' button %i",
cookie->evtype == XI_RawButtonPress
? "press "
: "release",
device->id,
device->device_name,
xev->detail);
_clutter_input_pointer_a11y_on_button_event (device,
xev->detail,
(cookie->evtype == XI_RawButtonPress));
break;
}
}
static ClutterTranslateReturn
clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
gpointer native,
@ -1303,6 +1358,14 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
if (!xi_event)
return CLUTTER_TRANSLATE_REMOVE;
if (cookie->evtype == XI_RawMotion ||
cookie->evtype == XI_RawButtonPress ||
cookie->evtype == XI_RawButtonRelease)
{
handle_raw_event (manager_xi2, xevent);
return CLUTTER_TRANSLATE_REMOVE;
}
if (!(xi_event->evtype == XI_HierarchyChanged ||
xi_event->evtype == XI_DeviceChanged ||
xi_event->evtype == XI_PropertyEvent))
@ -2031,7 +2094,7 @@ clutter_device_manager_xi2_constructed (GObject *gobject)
GHashTable *masters, *slaves;
XIDeviceInfo *info;
XIEventMask event_mask;
unsigned char mask[2] = { 0, };
unsigned char mask[(XI_LASTEVENT + 7) / 8] = { 0, };
int n_devices, i;
backend_x11 =
@ -2083,6 +2146,19 @@ clutter_device_manager_xi2_constructed (GObject *gobject)
event_mask.mask_len = sizeof (mask);
event_mask.mask = mask;
clutter_device_manager_xi2_select_events (manager,
clutter_x11_get_root_window (),
&event_mask);
memset(mask, 0, sizeof (mask));
XISetMask (mask, XI_RawMotion);
XISetMask (mask, XI_RawButtonPress);
XISetMask (mask, XI_RawButtonRelease);
event_mask.deviceid = XIAllMasterDevices;
event_mask.mask_len = sizeof (mask);
event_mask.mask = mask;
clutter_device_manager_xi2_select_events (manager,
clutter_x11_get_root_window (),
&event_mask);

View File

@ -46,6 +46,11 @@ struct _ClutterInputDeviceXI2
gint device_id;
ClutterInputDeviceTool *current_tool;
guint inhibit_pointer_query_timer;
gboolean query_status;
float current_x;
float current_y;
#ifdef HAVE_LIBWACOM
WacomDevice *wacom_device;
GArray *group_modes;
@ -112,6 +117,9 @@ clutter_input_device_xi2_finalize (GObject *object)
if (device_xi2->group_modes)
g_array_unref (device_xi2->group_modes);
if (device_xi2->inhibit_pointer_query_timer)
g_source_remove (device_xi2->inhibit_pointer_query_timer);
#endif
G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object);
@ -293,6 +301,75 @@ clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device)
return device_xi2->current_tool;
}
static gboolean
clutter_input_device_xi2_query_pointer_location (ClutterInputDeviceXI2 *device_xi2)
{
Window xroot_window, xchild_window;
double xroot_x, xroot_y, xwin_x, xwin_y;
XIButtonState button_state;
XIModifierState mod_state;
XIGroupState group_state;
int result;
clutter_x11_trap_x_errors ();
result = XIQueryPointer (clutter_x11_get_default_display (),
device_xi2->device_id,
clutter_x11_get_root_window (),
&xroot_window,
&xchild_window,
&xroot_x, &xroot_y,
&xwin_x, &xwin_y,
&button_state,
&mod_state,
&group_state);
clutter_x11_untrap_x_errors ();
if (!result)
return FALSE;
device_xi2->current_x = (float) xroot_x;
device_xi2->current_y = (float) xroot_y;
return TRUE;
}
static gboolean
clear_inhibit_pointer_query_cb (gpointer data)
{
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (data);
device_xi2->inhibit_pointer_query_timer = 0;
return G_SOURCE_REMOVE;
}
gboolean
clutter_input_device_xi2_get_pointer_location (ClutterInputDevice *device,
float *x,
float *y)
{
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_XI2 (device_xi2), FALSE);
g_return_val_if_fail (device->device_type == CLUTTER_POINTER_DEVICE, FALSE);
/* Throttle XServer queries and roundtrips using an idle timeout */
if (device_xi2->inhibit_pointer_query_timer == 0)
{
device_xi2->query_status =
clutter_input_device_xi2_query_pointer_location (device_xi2);
device_xi2->inhibit_pointer_query_timer =
clutter_threads_add_idle (clear_inhibit_pointer_query_cb, device_xi2);
}
*x = device_xi2->current_x;
*y = device_xi2->current_y;
return device_xi2->query_status;
}
#ifdef HAVE_LIBWACOM
void
clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device,

View File

@ -48,6 +48,9 @@ void _clutter_input_device_xi2_translate_state (ClutterEvent *event,
void clutter_input_device_xi2_update_tool (ClutterInputDevice *device,
ClutterInputDeviceTool *tool);
ClutterInputDeviceTool * clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device);
gboolean clutter_input_device_xi2_get_pointer_location (ClutterInputDevice *device,
float *x,
float *y);
#ifdef HAVE_LIBWACOM
void clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device,

View File

@ -87,60 +87,6 @@ G_DEFINE_TYPE_WITH_CODE (ClutterStageX11,
ButtonReleaseMask | \
PointerMotionMask
static void
send_wmspec_change_state (ClutterBackendX11 *backend_x11,
Window window,
Atom state,
gboolean add)
{
XClientMessageEvent xclient;
CLUTTER_NOTE (BACKEND, "%s NET_WM state", add ? "adding" : "removing");
memset (&xclient, 0, sizeof (xclient));
xclient.type = ClientMessage;
xclient.window = window;
xclient.message_type = backend_x11->atom_NET_WM_STATE;
xclient.format = 32;
xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
xclient.data.l[1] = state;
xclient.data.l[2] = 0;
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
XSendEvent (backend_x11->xdpy,
DefaultRootWindow (backend_x11->xdpy),
False,
SubstructureRedirectMask | SubstructureNotifyMask,
(XEvent *)&xclient);
}
static void
update_state (ClutterStageX11 *stage_x11,
ClutterBackendX11 *backend_x11,
Atom *state,
gboolean add)
{
if (add)
{
/* FIXME: This wont work if we support more states */
XChangeProperty (backend_x11->xdpy,
stage_x11->xwin,
backend_x11->atom_NET_WM_STATE, XA_ATOM, 32,
PropModeReplace,
(unsigned char *) state, 1);
}
else
{
/* FIXME: This wont work if we support more states */
XDeleteProperty (backend_x11->xdpy,
stage_x11->xwin,
backend_x11->atom_NET_WM_STATE);
}
}
static void
clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
gint new_width,
@ -153,9 +99,6 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
{
guint min_width, min_height;
XSizeHints *size_hints;
gboolean resize;
resize = clutter_stage_get_user_resizable (stage_cogl->wrapper);
size_hints = XAllocSizeHints();
@ -169,27 +112,11 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
if (new_height <= 0)
new_height = min_height;
size_hints->flags = 0;
/* If we are going fullscreen then we don't want any
restrictions on the window size */
if (!stage_x11->fullscreening)
{
if (resize)
{
size_hints->min_width = min_width;
size_hints->min_height = min_height;
size_hints->flags = PMinSize;
}
else
{
size_hints->min_width = new_width;
size_hints->min_height = new_height;
size_hints->max_width = new_width;
size_hints->max_height = new_height;
size_hints->flags = PMinSize | PMaxSize;
}
}
size_hints->min_width = new_width;
size_hints->min_height = new_height;
size_hints->max_width = new_width;
size_hints->max_height = new_height;
size_hints->flags = PMinSize | PMaxSize;
XSetWMNormalHints (backend_x11->xdpy, stage_x11->xwin, size_hints);
@ -216,28 +143,8 @@ clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window,
cairo_rectangle_int_t *geometry)
{
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
geometry->x = geometry->y = 0;
/* If we're fullscreen, return the size of the display.
*
* FIXME - this is utterly broken for anything that is not a single
* head set up; the window manager will give us the right size in a
* ConfigureNotify, but between the fullscreen signal emission on the
* stage and the following frame, the size returned by the stage will
* be wrong.
*/
if (_clutter_stage_is_fullscreen (stage_cogl->wrapper) &&
stage_x11->fullscreening)
{
geometry->width = DisplayWidth (backend_x11->xdpy, backend_x11->xscreen_num);
geometry->height = DisplayHeight (backend_x11->xdpy, backend_x11->xscreen_num);
return;
}
geometry->width = stage_x11->xwin_width;
geometry->height = stage_x11->xwin_height;
}
@ -263,10 +170,6 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
return;
}
/* If we're going fullscreen, don't mess with the size */
if (stage_x11->fullscreening)
return;
if (width == 0 || height == 0)
{
/* Should not happen, if this turns up we need to debug it and
@ -460,117 +363,6 @@ _clutter_stage_x11_update_foreign_event_mask (CoglOnscreen *onscreen,
&attrs);
}
static void
clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
gboolean is_fullscreen)
{
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
ClutterStage *stage = stage_cogl->wrapper;
gboolean was_fullscreen;
if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return;
was_fullscreen = _clutter_stage_is_fullscreen (stage);
is_fullscreen = !!is_fullscreen;
if (was_fullscreen == is_fullscreen)
return;
CLUTTER_NOTE (BACKEND, "%ssetting fullscreen", is_fullscreen ? "" : "un");
if (is_fullscreen)
{
#if 0
int width, height;
/* FIXME: this will do the wrong thing for dual-headed
displays. This will return the size of the combined display
but Metacity (at least) will fullscreen to only one of the
displays. This will cause the actor to report the wrong size
until the ConfigureNotify for the correct size is received */
width = DisplayWidth (backend_x11->xdpy, backend_x11->xscreen_num);
height = DisplayHeight (backend_x11->xdpy, backend_x11->xscreen_num);
#endif
/* Set the fullscreen hint so we can retain the old size of the window. */
stage_x11->fullscreening = TRUE;
if (stage_x11->xwin != None)
{
/* if the actor is not mapped we resize the stage window to match
* the size of the screen; this is useful for e.g. EGLX to avoid
* a resize when calling clutter_stage_fullscreen() before showing
* the stage
*/
if (!STAGE_X11_IS_MAPPED (stage_x11))
{
CLUTTER_NOTE (BACKEND, "Fullscreening unmapped stage");
update_state (stage_x11, backend_x11,
&backend_x11->atom_NET_WM_STATE_FULLSCREEN,
TRUE);
}
else
{
CLUTTER_NOTE (BACKEND, "Fullscreening mapped stage");
/* We need to fix the window size so that it will remove
the maximum and minimum window hints. Otherwise
metacity will honour the restrictions and not
fullscreen correctly. */
clutter_stage_x11_fix_window_size (stage_x11, -1, -1);
send_wmspec_change_state (backend_x11, stage_x11->xwin,
backend_x11->atom_NET_WM_STATE_FULLSCREEN,
TRUE);
}
}
else
stage_x11->fullscreen_on_realize = TRUE;
}
else
{
stage_x11->fullscreening = FALSE;
if (stage_x11->xwin != None)
{
if (!STAGE_X11_IS_MAPPED (stage_x11))
{
CLUTTER_NOTE (BACKEND, "Un-fullscreening unmapped stage");
update_state (stage_x11, backend_x11,
&backend_x11->atom_NET_WM_STATE_FULLSCREEN,
FALSE);
}
else
{
CLUTTER_NOTE (BACKEND, "Un-fullscreening mapped stage");
send_wmspec_change_state (backend_x11,
stage_x11->xwin,
backend_x11->atom_NET_WM_STATE_FULLSCREEN,
FALSE);
/* Fix the window size to restore the minimum/maximum
restriction */
clutter_stage_x11_fix_window_size (stage_x11,
stage_x11->xwin_width,
stage_x11->xwin_height);
}
}
else
stage_x11->fullscreen_on_realize = FALSE;
}
/* XXX: Note we rely on the ConfigureNotify mechanism as the common
* mechanism to handle notifications of new X window sizes from the
* X server so we don't actively change the stage viewport here or
* queue a relayout etc. */
}
void
_clutter_stage_x11_events_device_changed (ClutterStageX11 *stage_x11,
ClutterInputDevice *device,
@ -722,13 +514,6 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
stage_x11->xwin_height);
clutter_stage_x11_set_wm_protocols (stage_x11);
if (stage_x11->fullscreen_on_realize)
{
stage_x11->fullscreen_on_realize = FALSE;
clutter_stage_x11_set_fullscreen (stage_window, TRUE);
}
CLUTTER_NOTE (BACKEND, "Successfully realized stage");
return TRUE;
@ -755,17 +540,6 @@ clutter_stage_x11_set_title (ClutterStageWindow *stage_window,
set_wm_title (stage_x11);
}
static void
clutter_stage_x11_set_user_resizable (ClutterStageWindow *stage_window,
gboolean is_resizable)
{
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
clutter_stage_x11_fix_window_size (stage_x11,
stage_x11->xwin_width,
stage_x11->xwin_height);
}
static inline void
update_wm_hints (ClutterStageX11 *stage_x11)
{
@ -840,11 +614,6 @@ clutter_stage_x11_show (ClutterStageWindow *stage_window,
set_stage_x11_state (stage_x11, STAGE_X11_WITHDRAWN, 0);
update_wm_hints (stage_x11);
if (stage_x11->fullscreening)
clutter_stage_x11_set_fullscreen (stage_window, TRUE);
else
clutter_stage_x11_set_fullscreen (stage_window, FALSE);
}
g_assert (STAGE_X11_IS_MAPPED (stage_x11));
@ -966,7 +735,6 @@ clutter_stage_x11_init (ClutterStageX11 *stage)
stage->wm_state = STAGE_X11_WITHDRAWN;
stage->is_foreign_xwin = FALSE;
stage->fullscreening = FALSE;
stage->is_cursor_visible = TRUE;
stage->accept_focus = TRUE;
@ -979,9 +747,7 @@ clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface);
iface->set_title = clutter_stage_x11_set_title;
iface->set_fullscreen = clutter_stage_x11_set_fullscreen;
iface->set_cursor_visible = clutter_stage_x11_set_cursor_visible;
iface->set_user_resizable = clutter_stage_x11_set_user_resizable;
iface->set_accept_focus = clutter_stage_x11_set_accept_focus;
iface->show = clutter_stage_x11_show;
iface->hide = clutter_stage_x11_hide;
@ -1101,13 +867,8 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
xevent->xconfigure.width,
xevent->xconfigure.height);
/* When fullscreen, we'll keep the xwin_width/height
variables to track the old size of the window and we'll
assume all ConfigureNotifies constitute a size change */
if (_clutter_stage_is_fullscreen (stage))
size_changed = TRUE;
else if ((stage_x11->xwin_width != xevent->xconfigure.width) ||
(stage_x11->xwin_height != xevent->xconfigure.height))
if ((stage_x11->xwin_width != xevent->xconfigure.width) ||
(stage_x11->xwin_height != xevent->xconfigure.height))
{
size_changed = TRUE;
stage_x11->xwin_width = xevent->xconfigure.width;
@ -1197,57 +958,6 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
}
break;
case PropertyNotify:
if (xevent->xproperty.atom == backend_x11->atom_NET_WM_STATE &&
xevent->xproperty.window == stage_xwindow &&
!stage_x11->is_foreign_xwin)
{
Atom type;
gint format;
gulong n_items, bytes_after;
guchar *data = NULL;
gboolean fullscreen_set = FALSE;
clutter_x11_trap_x_errors ();
XGetWindowProperty (backend_x11->xdpy, stage_xwindow,
backend_x11->atom_NET_WM_STATE,
0, G_MAXLONG,
False, XA_ATOM,
&type, &format, &n_items,
&bytes_after, &data);
clutter_x11_untrap_x_errors ();
if (type != None && data != NULL)
{
gboolean is_fullscreen = FALSE;
Atom *atoms = (Atom *) data;
gulong i;
for (i = 0; i < n_items; i++)
{
if (atoms[i] == backend_x11->atom_NET_WM_STATE_FULLSCREEN)
fullscreen_set = TRUE;
}
is_fullscreen = _clutter_stage_is_fullscreen (stage_cogl->wrapper);
if (fullscreen_set != is_fullscreen)
{
if (fullscreen_set)
_clutter_stage_update_state (stage_cogl->wrapper,
0,
CLUTTER_STAGE_STATE_FULLSCREEN);
else
_clutter_stage_update_state (stage_cogl->wrapper,
CLUTTER_STAGE_STATE_FULLSCREEN,
0);
}
XFree (data);
}
}
break;
case FocusIn:
if (!_clutter_stage_is_activated (stage_cogl->wrapper))
{

View File

@ -70,11 +70,9 @@ struct _ClutterStageX11
ClutterStageX11State wm_state;
guint is_foreign_xwin : 1;
guint fullscreening : 1;
guint is_cursor_visible : 1;
guint viewport_initialized : 1;
guint accept_focus : 1;
guint fullscreen_on_realize : 1;
};
struct _ClutterStageX11Class

View File

@ -12,19 +12,19 @@ clutter_c_args = [
]
clutter_debug_c_args = []
if buildtype.startswith('debug')
clutter_debug_c_args += '-DG_DISABLE_CAST_CHECKS'
if buildtype == 'debug'
clutter_debug_c_args += '-DCLUTTER_ENABLE_DEBUG'
endif
elif buildtype == 'release'
if get_option('debug')
clutter_debug_c_args += [
'-DCLUTTER_ENABLE_DEBUG',
'-fno-omit-frame-pointer'
]
elif buildtype != 'plain'
clutter_debug_c_args += [
'-DG_DISABLE_ASSERT',
'-DG_DISABLE_CHECKS',
'-DG_DISABLE_CAST_CHECKS',
]
endif
supported_clutter_debug_c_args = cc.get_supported_arguments(clutter_debug_c_args)
clutter_c_args += clutter_debug_c_args
clutter_pkg_deps = [

View File

@ -209,14 +209,16 @@ make_actor (GType shader_type)
}
static guint32
get_pixel (int x, int y)
get_pixel (CoglFramebuffer *fb,
int x,
int y)
{
guint8 data[4];
cogl_read_pixels (x, y, 1, 1,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
data);
cogl_framebuffer_read_pixels (fb,
x, y, 1, 1,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
data);
return (((guint32) data[0] << 16) |
((guint32) data[1] << 8) |
@ -224,19 +226,21 @@ get_pixel (int x, int y)
}
static void
paint_cb (ClutterStage *stage,
gpointer data)
view_painted_cb (ClutterStage *stage,
ClutterStageView *view,
gpointer data)
{
CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
gboolean *was_painted = data;
/* old shader effect */
g_assert_cmpint (get_pixel (0, 25), ==, 0xff0000);
g_assert_cmpint (get_pixel (fb, 0, 25), ==, 0xff0000);
/* new shader effect */
g_assert_cmpint (get_pixel (100, 25), ==, 0x00ffff);
g_assert_cmpint (get_pixel (fb, 100, 25), ==, 0x00ffff);
/* another new shader effect */
g_assert_cmpint (get_pixel (200, 25), ==, 0xff00ff);
g_assert_cmpint (get_pixel (fb, 200, 25), ==, 0xff00ff);
/* new shader effect */
g_assert_cmpint (get_pixel (300, 25), ==, 0x00ffff);
g_assert_cmpint (get_pixel (fb, 300, 25), ==, 0x00ffff);
*was_painted = TRUE;
}
@ -271,9 +275,9 @@ actor_shader_effect (void)
clutter_actor_show (stage);
was_painted = FALSE;
g_signal_connect (stage, "after-paint",
G_CALLBACK (paint_cb),
&was_painted);
g_signal_connect_after (stage, "paint-view",
G_CALLBACK (view_painted_cb),
&was_painted);
while (!was_painted)
g_main_context_iteration (NULL, FALSE);

View File

@ -199,7 +199,6 @@ test_actors_main (int argc, char *argv[])
g_signal_connect (oh->stage, "destroy", G_CALLBACK (stop_and_quit), oh);
clutter_stage_set_title (CLUTTER_STAGE (oh->stage), "Actors");
clutter_stage_set_user_resizable (CLUTTER_STAGE (oh->stage), TRUE);
/* Create a timeline to manage animation */
oh->timeline = clutter_timeline_new (6000);

View File

@ -181,7 +181,6 @@ test_bind_constraint_main (int argc, char *argv[])
stage = clutter_stage_new ();
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
clutter_stage_set_title (CLUTTER_STAGE (stage), "Constraints");
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
clutter_actor_set_size (stage, 800, 600);
/* main rectangle */

View File

@ -91,7 +91,6 @@ test_cairo_clock_main (int argc, char *argv[])
/* create a resizable stage */
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "2D Clock");
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue);
clutter_actor_set_size (stage, 300, 300);
clutter_actor_show (stage);

View File

@ -181,7 +181,6 @@ test_content_main (int argc, char *argv[])
stage = clutter_stage_new ();
clutter_actor_set_name (stage, "Stage");
clutter_stage_set_title (CLUTTER_STAGE (stage), "Content");
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
clutter_actor_show (stage);

View File

@ -2,7 +2,7 @@
#include <clutter/clutter.h>
#include <string.h>
gboolean IsFullScreen = FALSE, IsMotion = TRUE;
gboolean IsMotion = TRUE;
int
test_events_main (int argc, char *argv[]);
@ -114,28 +114,6 @@ stage_state_cb (ClutterStage *stage,
printf("[stage signal] %s\n", detail);
}
static gboolean
blue_button_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer data)
{
ClutterActor *stage;
stage = clutter_actor_get_stage (actor);
if (IsFullScreen)
IsFullScreen = FALSE;
else
IsFullScreen = TRUE;
clutter_stage_set_fullscreen (CLUTTER_STAGE (stage), IsFullScreen);
g_print ("*** Fullscreen %s ***\n",
IsFullScreen ? "enabled" : "disabled");
return FALSE;
}
static gboolean
red_button_cb (ClutterActor *actor,
ClutterEvent *event,
@ -429,10 +407,6 @@ test_events_main (int argc, char *argv[])
clutter_actor_set_name (stage, "Stage");
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
g_signal_connect (stage, "event", G_CALLBACK (input_cb), (char *) "stage");
g_signal_connect (stage, "fullscreen",
G_CALLBACK (stage_state_cb), (char *) "fullscreen");
g_signal_connect (stage, "unfullscreen",
G_CALLBACK (stage_state_cb), (char *) "unfullscreen");
g_signal_connect (stage, "activate",
G_CALLBACK (stage_state_cb), (char *) "activate");
g_signal_connect (stage, "deactivate",
@ -468,19 +442,6 @@ test_events_main (int argc, char *argv[])
focus_box);
g_signal_connect (actor, "captured-event", G_CALLBACK (capture_cb), NULL);
actor = clutter_rectangle_new_with_color (CLUTTER_COLOR_Blue);
clutter_actor_set_name (actor, "Blue Box");
clutter_actor_set_size (actor, 100, 100);
clutter_actor_set_position (actor, 400, 100);
clutter_actor_set_reactive (actor, TRUE);
clutter_container_add (CLUTTER_CONTAINER(stage), actor, NULL);
g_signal_connect (actor, "event", G_CALLBACK (input_cb), (char *) "blue box");
g_signal_connect (actor, "key-focus-in", G_CALLBACK (key_focus_in_cb),
focus_box);
/* Fullscreen */
g_signal_connect (actor, "button-press-event",
G_CALLBACK (blue_button_cb), NULL);
/* non reactive */
actor = clutter_rectangle_new_with_color (CLUTTER_COLOR_Black);
clutter_actor_set_name (actor, "Black Box");

View File

@ -218,10 +218,6 @@ test_grab_main (int argc, char *argv[])
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
g_signal_connect (stage, "event",
G_CALLBACK (debug_event_cb), (char *) "stage");
g_signal_connect (stage, "fullscreen",
G_CALLBACK (stage_state_cb), (char *) "fullscreen");
g_signal_connect (stage, "unfullscreen",
G_CALLBACK (stage_state_cb), (char *) "unfullscreen");
g_signal_connect (stage, "activate",
G_CALLBACK (stage_state_cb), (char *) "activate");
g_signal_connect (stage, "deactivate",

View File

@ -189,7 +189,6 @@ test_image_main (int argc, char *argv[])
stage = clutter_stage_new ();
clutter_actor_set_name (stage, "Stage");
clutter_stage_set_title (CLUTTER_STAGE (stage), "Content");
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
clutter_actor_show (stage);

View File

@ -73,7 +73,6 @@ test_rotate_zoom_main (int argc, char *argv[])
stage = clutter_stage_new ();
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
clutter_stage_set_title (CLUTTER_STAGE (stage), "Rotate and Zoom actions");
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
clutter_actor_set_reactive (stage, FALSE);
clutter_actor_show (stage);

View File

@ -8,21 +8,6 @@ test_stage_sizing_main (int argc, char *argv[]);
const char *
test_stage_sizing_describe (void);
static gboolean
fullscreen_clicked_cb (ClutterStage *stage)
{
clutter_stage_set_fullscreen (stage, !clutter_stage_get_fullscreen (stage));
return CLUTTER_EVENT_STOP;
}
static gboolean
resize_clicked_cb (ClutterStage *stage)
{
clutter_stage_set_user_resizable (stage,
!clutter_stage_get_user_resizable (stage));
return CLUTTER_EVENT_STOP;
}
static gboolean
shrink_clicked_cb (ClutterActor *stage)
{
@ -41,22 +26,6 @@ expand_clicked_cb (ClutterActor *stage)
return CLUTTER_EVENT_STOP;
}
static void
on_fullscreen (ClutterStage *stage)
{
float width, height;
gboolean is_fullscreen;
is_fullscreen = clutter_stage_get_fullscreen (stage);
clutter_actor_get_size (CLUTTER_ACTOR (stage), &width, &height);
g_print ("Stage size [%s]: %d x %d\n",
is_fullscreen ? "fullscreen" : "not fullscreen",
(int) width,
(int) height);
}
G_MODULE_EXPORT int
test_stage_sizing_main (int argc, char *argv[])
{
@ -69,40 +38,12 @@ test_stage_sizing_main (int argc, char *argv[])
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "Stage Sizing");
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
g_signal_connect_after (stage, "notify::fullscreen-set", G_CALLBACK (on_fullscreen), NULL);
box = clutter_actor_new ();
clutter_actor_set_layout_manager (box, clutter_box_layout_new ());
clutter_actor_add_constraint (box, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5));
clutter_actor_add_child (stage, box);
rect = clutter_actor_new ();
clutter_actor_set_layout_manager (rect,
clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_BIN_ALIGNMENT_CENTER));
clutter_actor_set_background_color (rect, CLUTTER_COLOR_LightScarletRed);
clutter_actor_set_reactive (rect, TRUE);
g_signal_connect_swapped (rect, "button-press-event",
G_CALLBACK (fullscreen_clicked_cb),
stage);
label = clutter_text_new_with_text ("Sans 16", "Toggle fullscreen");
clutter_actor_set_margin (label, &margin);
clutter_actor_add_child (rect, label);
clutter_actor_add_child (box, rect);
rect = clutter_actor_new ();
clutter_actor_set_layout_manager (rect,
clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_BIN_ALIGNMENT_CENTER));
clutter_actor_set_background_color (rect, CLUTTER_COLOR_Chameleon);
clutter_actor_set_reactive (rect, TRUE);
g_signal_connect_swapped (rect, "button-press-event",
G_CALLBACK (resize_clicked_cb), stage);
label = clutter_text_new_with_text ("Sans 16", "Toggle resizable");
clutter_actor_set_margin (label, &margin);
clutter_actor_add_child (rect, label);
clutter_actor_add_child (box, rect);
rect = clutter_actor_new ();
clutter_actor_set_layout_manager (rect,
clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,

View File

@ -28,7 +28,6 @@ test_state_script_main (int argc, char *argv[])
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "State Script");
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
clutter_actor_show (stage);

View File

@ -179,7 +179,6 @@ test_table_layout_main (int argc, char *argv[])
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "Table Layout");
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
clutter_actor_set_size (stage, 640, 480);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);

View File

@ -146,7 +146,6 @@ test_touch_events_main (int argc, char *argv[])
stage = clutter_stage_new ();
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
clutter_stage_set_title (CLUTTER_STAGE (stage), "Touch events");
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
clutter_actor_set_reactive (stage, TRUE);
clutter_actor_show (stage);

View File

@ -4,6 +4,9 @@
/* Have GLES 2.0 for rendering */
#mesondefine HAVE_COGL_GLES2
/* Building with Sysprof profiling suport */
#mesondefine HAVE_TRACING
/* Enable unit tests */
#mesondefine ENABLE_UNIT_TESTS

View File

@ -94,7 +94,7 @@ cogl_pango_font_map_new (void)
PangoContext *
cogl_pango_font_map_create_context (CoglPangoFontMap *fm)
{
_COGL_RETURN_VAL_IF_FAIL (COGL_PANGO_IS_FONT_MAP (fm), NULL);
g_return_val_if_fail (COGL_PANGO_IS_FONT_MAP (fm), NULL);
#if PANGO_VERSION_CHECK (1, 22, 0)
/* We can just directly use the pango context from the Cairo font
@ -138,7 +138,7 @@ void
cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map,
double dpi)
{
_COGL_RETURN_IF_FAIL (COGL_PANGO_IS_FONT_MAP (font_map));
g_return_if_fail (COGL_PANGO_IS_FONT_MAP (font_map));
pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (font_map), dpi);
}

View File

@ -217,7 +217,7 @@ cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache,
CoglPangoGlyphCacheValue *value)
{
CoglAtlasTexture *texture;
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
if (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SHARED_ATLAS))
return FALSE;
@ -232,7 +232,7 @@ cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache,
value->draw_height);
if (!cogl_texture_allocate (COGL_TEXTURE (texture), &ignore_error))
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
return FALSE;
}

View File

@ -153,7 +153,7 @@ cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv,
{
CoglPangoRendererSliceCbData data;
_COGL_RETURN_IF_FAIL (priv->display_list != NULL);
g_return_if_fail (priv->display_list != NULL);
data.display_list = priv->display_list;
data.x1 = x1;
@ -577,7 +577,7 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font,
/* Glyphs that don't take up any space will end up without a
texture. These should never become dirty so they shouldn't end up
here */
_COGL_RETURN_IF_FAIL (value->texture != NULL);
g_return_if_fail (value->texture != NULL);
if (_cogl_texture_get_format (value->texture) == COGL_PIXEL_FORMAT_A_8)
{
@ -705,7 +705,7 @@ cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout)
context = pango_layout_get_context (layout);
priv = cogl_pango_get_renderer_from_context (context);
_COGL_RETURN_IF_FAIL (PANGO_IS_LAYOUT (layout));
g_return_if_fail (PANGO_IS_LAYOUT (layout));
if ((iter = pango_layout_get_iter (layout)) == NULL)
return;
@ -759,7 +759,7 @@ cogl_pango_renderer_draw_box (PangoRenderer *renderer,
{
CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer);
_COGL_RETURN_IF_FAIL (priv->display_list != NULL);
g_return_if_fail (priv->display_list != NULL);
_cogl_pango_display_list_add_rectangle (priv->display_list,
x,
@ -803,7 +803,7 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer,
CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer);
float x1, x2, y1, y2;
_COGL_RETURN_IF_FAIL (priv->display_list != NULL);
g_return_if_fail (priv->display_list != NULL);
cogl_pango_renderer_set_color_for_part (renderer, part);
@ -830,7 +830,7 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
{
CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer);
_COGL_RETURN_IF_FAIL (priv->display_list != NULL);
g_return_if_fail (priv->display_list != NULL);
cogl_pango_renderer_set_color_for_part (renderer, part);

View File

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

View File

@ -149,7 +149,7 @@ void
cogl2_path_set_fill_rule (CoglPath *path,
CoglPathFillRule fill_rule)
{
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
if (path->data->fill_rule != fill_rule)
{
@ -162,7 +162,7 @@ cogl2_path_set_fill_rule (CoglPath *path,
CoglPathFillRule
cogl2_path_get_fill_rule (CoglPath *path)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_path (path), COGL_PATH_FILL_RULE_NON_ZERO);
g_return_val_if_fail (cogl_is_path (path), COGL_PATH_FILL_RULE_NON_ZERO);
return path->data->fill_rule;
}
@ -225,9 +225,9 @@ _cogl_path_stroke_nodes (CoglPath *path,
int path_num = 0;
CoglPathNode *node;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
_COGL_RETURN_IF_FAIL (cogl_is_framebuffer (framebuffer));
_COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
g_return_if_fail (cogl_is_path (path));
g_return_if_fail (cogl_is_framebuffer (framebuffer));
g_return_if_fail (cogl_is_pipeline (pipeline));
data = path->data;
@ -392,7 +392,7 @@ _cogl_path_fill_nodes (CoglPath *path,
void
cogl2_path_fill (CoglPath *path)
{
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
_cogl_path_fill_nodes (path,
cogl_get_draw_framebuffer (),
@ -407,7 +407,7 @@ cogl2_path_fill (CoglPath *path)
void
cogl2_path_stroke (CoglPath *path)
{
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
if (path->data->path_nodes->len == 0)
return;
@ -424,7 +424,7 @@ cogl2_path_move_to (CoglPath *path,
{
CoglPathData *data;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
_cogl_path_add_node (path, TRUE, x, y);
@ -443,7 +443,7 @@ cogl2_path_rel_move_to (CoglPath *path,
{
CoglPathData *data;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
data = path->data;
@ -459,7 +459,7 @@ cogl2_path_line_to (CoglPath *path,
{
CoglPathData *data;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
_cogl_path_add_node (path, FALSE, x, y);
@ -476,7 +476,7 @@ cogl2_path_rel_line_to (CoglPath *path,
{
CoglPathData *data;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
data = path->data;
@ -488,7 +488,7 @@ cogl2_path_rel_line_to (CoglPath *path,
void
cogl2_path_close (CoglPath *path)
{
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
_cogl_path_add_node (path, FALSE, path->data->path_start.x,
path->data->path_start.y);
@ -514,7 +514,7 @@ cogl2_path_polyline (CoglPath *path,
{
int c = 0;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
cogl2_path_move_to (path, coords[0], coords[1]);
@ -639,7 +639,7 @@ cogl2_path_arc (CoglPath *path,
{
float angle_step = 10;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
/* it is documented that a move to is needed to create a freestanding
* arc
@ -683,7 +683,7 @@ cogl2_path_ellipse (CoglPath *path,
{
float angle_step = 10;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
/* FIXME: if shows to be slow might be optimized
* by mirroring just a quarter of it */
@ -709,7 +709,7 @@ cogl2_path_round_rectangle (CoglPath *path,
float inner_width = x_2 - x_1 - radius * 2;
float inner_height = y_2 - y_1 - radius * 2;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
cogl2_path_move_to (path, x_1, y_1 + radius);
_cogl_path_rel_arc (path,
@ -860,7 +860,7 @@ cogl2_path_curve_to (CoglPath *path,
{
CoglBezCubic cubic;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
/* Prepare cubic curve */
cubic.p1 = path->data->path_pen;
@ -890,7 +890,7 @@ cogl2_path_rel_curve_to (CoglPath *path,
{
CoglPathData *data;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
data = path->data;
@ -932,7 +932,7 @@ cogl_path_copy (CoglPath *old_path)
{
CoglPath *new_path;
_COGL_RETURN_VAL_IF_FAIL (cogl_is_path (old_path), NULL);
g_return_val_if_fail (cogl_is_path (old_path), NULL);
new_path = g_slice_new (CoglPath);
new_path->data = old_path->data;
@ -1053,7 +1053,7 @@ cogl_rel_curve2_to (CoglPath *path,
{
CoglPathData *data;
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_path (path));
data = path->data;
@ -1579,9 +1579,9 @@ cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglPath *path)
{
_COGL_RETURN_IF_FAIL (cogl_is_framebuffer (framebuffer));
_COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_framebuffer (framebuffer));
g_return_if_fail (cogl_is_pipeline (pipeline));
g_return_if_fail (cogl_is_path (path));
_cogl_path_fill_nodes (path, framebuffer, pipeline, 0 /* flags */);
}
@ -1591,9 +1591,9 @@ cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglPath *path)
{
_COGL_RETURN_IF_FAIL (cogl_is_framebuffer (framebuffer));
_COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
_COGL_RETURN_IF_FAIL (cogl_is_path (path));
g_return_if_fail (cogl_is_framebuffer (framebuffer));
g_return_if_fail (cogl_is_pipeline (pipeline));
g_return_if_fail (cogl_is_path (path));
_cogl_path_stroke_nodes (path, framebuffer, pipeline);
}

View File

@ -47,7 +47,6 @@
#include "cogl-atlas.h"
#include "cogl1-context.h"
#include "cogl-sub-texture.h"
#include "cogl-error-private.h"
#include "cogl-gtype-private.h"
#include "driver/gl/cogl-pipeline-opengl-private.h"
#include "driver/gl/cogl-texture-gl-private.h"
@ -453,7 +452,7 @@ _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex,
int dst_width,
int dst_height,
CoglBitmap *bmp,
CoglError **error)
GError **error)
{
CoglAtlas *atlas = atlas_tex->atlas;
@ -524,7 +523,7 @@ _cogl_atlas_texture_convert_bitmap_for_upload (CoglAtlasTexture *atlas_tex,
CoglBitmap *bmp,
CoglPixelFormat internal_format,
gboolean can_convert_in_place,
CoglError **error)
GError **error)
{
CoglBitmap *upload_bmp;
CoglBitmap *override_bmp;
@ -574,7 +573,7 @@ _cogl_atlas_texture_set_region (CoglTexture *tex,
int dst_height,
int level,
CoglBitmap *bmp,
CoglError **error)
GError **error)
{
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
@ -694,7 +693,7 @@ cogl_atlas_texture_new_with_size (CoglContext *ctx,
/* We can't atlas zero-sized textures because it breaks the atlas
* data structure */
_COGL_RETURN_VAL_IF_FAIL (width > 0 && height > 0, NULL);
g_return_val_if_fail (width > 0 && height > 0, NULL);
loader = _cogl_texture_create_loader ();
loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZED;
@ -711,7 +710,7 @@ allocate_space (CoglAtlasTexture *atlas_tex,
int width,
int height,
CoglPixelFormat internal_format,
CoglError **error)
GError **error)
{
CoglTexture *tex = COGL_TEXTURE (atlas_tex);
CoglContext *ctx = tex->context;
@ -723,10 +722,10 @@ allocate_space (CoglAtlasTexture *atlas_tex,
{
COGL_NOTE (ATLAS, "Texture can not be added because the "
"format is unsupported");
_cogl_set_error (error,
COGL_TEXTURE_ERROR,
COGL_TEXTURE_ERROR_FORMAT,
"Texture format unsuitable for atlasing");
g_set_error_literal (error,
COGL_TEXTURE_ERROR,
COGL_TEXTURE_ERROR_FORMAT,
"Texture format unsuitable for atlasing");
return FALSE;
}
@ -734,11 +733,11 @@ allocate_space (CoglAtlasTexture *atlas_tex,
and we shouldn't use the atlas */
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
{
_cogl_set_error (error,
COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_UNSUPPORTED,
"Atlasing disabled because migrations "
"would be too slow");
g_set_error_literal (error,
COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_UNSUPPORTED,
"Atlasing disabled because migrations "
"would be too slow");
return FALSE;
}
@ -777,10 +776,10 @@ allocate_space (CoglAtlasTexture *atlas_tex,
/* Ok, this means we really can't add it to the atlas */
cogl_object_unref (atlas);
_cogl_set_error (error,
COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_NO_MEMORY,
"Not enough memory to atlas texture");
g_set_error_literal (error,
COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_NO_MEMORY,
"Not enough memory to atlas texture");
return FALSE;
}
}
@ -795,7 +794,7 @@ allocate_space (CoglAtlasTexture *atlas_tex,
static gboolean
allocate_with_size (CoglAtlasTexture *atlas_tex,
CoglTextureLoader *loader,
CoglError **error)
GError **error)
{
CoglTexture *tex = COGL_TEXTURE (atlas_tex);
CoglPixelFormat internal_format =
@ -820,7 +819,7 @@ allocate_with_size (CoglAtlasTexture *atlas_tex,
static gboolean
allocate_from_bitmap (CoglAtlasTexture *atlas_tex,
CoglTextureLoader *loader,
CoglError **error)
GError **error)
{
CoglTexture *tex = COGL_TEXTURE (atlas_tex);
CoglBitmap *bmp = loader->src.bitmap.bitmap;
@ -831,7 +830,7 @@ allocate_from_bitmap (CoglAtlasTexture *atlas_tex,
CoglPixelFormat internal_format;
CoglBitmap *upload_bmp;
_COGL_RETURN_VAL_IF_FAIL (atlas_tex->atlas == NULL, FALSE);
g_return_val_if_fail (atlas_tex->atlas == NULL, FALSE);
internal_format = _cogl_texture_determine_internal_format (tex, bmp_format);
@ -880,12 +879,12 @@ allocate_from_bitmap (CoglAtlasTexture *atlas_tex,
static gboolean
_cogl_atlas_texture_allocate (CoglTexture *tex,
CoglError **error)
GError **error)
{
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
CoglTextureLoader *loader = tex->loader;
_COGL_RETURN_VAL_IF_FAIL (loader, FALSE);
g_return_val_if_fail (loader, FALSE);
switch (loader->src_type)
{
@ -906,7 +905,7 @@ _cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
{
CoglTextureLoader *loader;
_COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL);
g_return_val_if_fail (cogl_is_bitmap (bmp), NULL);
loader = _cogl_texture_create_loader ();
loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP;
@ -933,13 +932,13 @@ cogl_atlas_texture_new_from_data (CoglContext *ctx,
CoglPixelFormat format,
int rowstride,
const uint8_t *data,
CoglError **error)
GError **error)
{
CoglBitmap *bmp;
CoglAtlasTexture *atlas_tex;
_COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL);
_COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL);
g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL);
g_return_val_if_fail (data != NULL, NULL);
/* Rowstride from width if not given */
if (rowstride == 0)
@ -969,12 +968,12 @@ cogl_atlas_texture_new_from_data (CoglContext *ctx,
CoglAtlasTexture *
cogl_atlas_texture_new_from_file (CoglContext *ctx,
const char *filename,
CoglError **error)
GError **error)
{
CoglBitmap *bmp;
CoglAtlasTexture *atlas_tex = NULL;
_COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
bmp = cogl_bitmap_new_from_file (filename, error);
if (bmp == NULL)

View File

@ -117,7 +117,7 @@ cogl_atlas_texture_new_with_size (CoglContext *ctx,
* cogl_atlas_texture_new_from_file:
* @ctx: A #CoglContext
* @filename: the file to load
* @error: A #CoglError to catch exceptional errors or %NULL
* @error: A #GError to catch exceptional errors or %NULL
*
* Creates a #CoglAtlasTexture from an image file. A #CoglAtlasTexture
* represents a sub-region within one of Cogl's shared texture
@ -149,7 +149,7 @@ cogl_atlas_texture_new_with_size (CoglContext *ctx,
CoglAtlasTexture *
cogl_atlas_texture_new_from_file (CoglContext *ctx,
const char *filename,
CoglError **error);
GError **error);
/**
* cogl_atlas_texture_new_from_data:
@ -161,7 +161,7 @@ cogl_atlas_texture_new_from_file (CoglContext *ctx,
* row in @data. A value of 0 will make Cogl automatically
* calculate @rowstride from @width and @format.
* @data: pointer to the memory region where the source buffer resides
* @error: A #CoglError to catch exceptional errors or %NULL
* @error: A #GError to catch exceptional errors or %NULL
*
* Creates a new #CoglAtlasTexture texture based on data residing in
* memory. A #CoglAtlasTexture represents a sub-region within one of
@ -198,7 +198,7 @@ cogl_atlas_texture_new_from_data (CoglContext *ctx,
CoglPixelFormat format,
int rowstride,
const uint8_t *data,
CoglError **error);
GError **error);
/**
* cogl_atlas_texture_new_from_bitmap:

View File

@ -283,7 +283,7 @@ _cogl_atlas_create_texture (CoglAtlas *atlas,
int height)
{
CoglTexture2D *tex;
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
_COGL_GET_CONTEXT (ctx, NULL);
@ -309,7 +309,7 @@ _cogl_atlas_create_texture (CoglAtlas *atlas,
if (!cogl_texture_allocate (COGL_TEXTURE (tex), &ignore_error))
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
cogl_object_unref (tex);
tex = NULL;
}
@ -327,7 +327,7 @@ _cogl_atlas_create_texture (CoglAtlas *atlas,
if (!cogl_texture_allocate (COGL_TEXTURE (tex), &ignore_error))
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
cogl_object_unref (tex);
tex = NULL;
}
@ -560,7 +560,7 @@ create_migration_texture (CoglContext *ctx,
CoglPixelFormat internal_format)
{
CoglTexture *tex;
CoglError *skip_error = NULL;
GError *skip_error = NULL;
/* First try creating a fast-path non-sliced texture */
tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height));
@ -573,7 +573,7 @@ create_migration_texture (CoglContext *ctx,
* lazily when uploading data. */
if (!cogl_texture_allocate (tex, &skip_error))
{
cogl_error_free (skip_error);
g_error_free (skip_error);
cogl_object_unref (tex);
tex = NULL;
}
@ -605,7 +605,7 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas,
{
CoglTexture *tex;
CoglBlitData blit_data;
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
_COGL_GET_CONTEXT (ctx, NULL);
@ -613,7 +613,7 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas,
tex = create_migration_texture (ctx, width, height, internal_format);
if (!cogl_texture_allocate (tex, &ignore_error))
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
cogl_object_unref (tex);
return NULL;
}

View File

@ -71,7 +71,7 @@ cogl_attribute_buffer_new (CoglContext *context,
buffer = cogl_attribute_buffer_new_with_size (context, bytes);
/* Note: to keep the common cases simple this API doesn't throw
* CoglErrors, so developers can assume this function never returns
* GErrors, so developers can assume this function never returns
* NULL and we will simply abort on error.
*
* Developers wanting to catch errors can use

View File

@ -309,7 +309,7 @@ _cogl_attribute_new_const (CoglContext *context,
/* FIXME: Up until GL[ES] 3 only square matrices were supported
* and we don't currently expose non-square matrices in Cogl.
*/
_COGL_RETURN_VAL_IF_FAIL (n_columns == n_components, NULL);
g_return_val_if_fail (n_columns == n_components, NULL);
_cogl_boxed_value_set_matrix (&attribute->d.constant.boxed,
n_columns,
1,
@ -469,7 +469,7 @@ cogl_attribute_new_const_4x4fv (CoglContext *context,
gboolean
cogl_attribute_get_normalized (CoglAttribute *attribute)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_attribute (attribute), FALSE);
g_return_val_if_fail (cogl_is_attribute (attribute), FALSE);
return attribute->normalized;
}
@ -490,7 +490,7 @@ void
cogl_attribute_set_normalized (CoglAttribute *attribute,
gboolean normalized)
{
_COGL_RETURN_IF_FAIL (cogl_is_attribute (attribute));
g_return_if_fail (cogl_is_attribute (attribute));
if (G_UNLIKELY (attribute->immutable_ref))
warn_about_midscene_changes ();
@ -501,8 +501,8 @@ cogl_attribute_set_normalized (CoglAttribute *attribute,
CoglAttributeBuffer *
cogl_attribute_get_buffer (CoglAttribute *attribute)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_attribute (attribute), NULL);
_COGL_RETURN_VAL_IF_FAIL (attribute->is_buffered, NULL);
g_return_val_if_fail (cogl_is_attribute (attribute), NULL);
g_return_val_if_fail (attribute->is_buffered, NULL);
return attribute->d.buffered.attribute_buffer;
}
@ -511,8 +511,8 @@ void
cogl_attribute_set_buffer (CoglAttribute *attribute,
CoglAttributeBuffer *attribute_buffer)
{
_COGL_RETURN_IF_FAIL (cogl_is_attribute (attribute));
_COGL_RETURN_IF_FAIL (attribute->is_buffered);
g_return_if_fail (cogl_is_attribute (attribute));
g_return_if_fail (attribute->is_buffered);
if (G_UNLIKELY (attribute->immutable_ref))
warn_about_midscene_changes ();
@ -528,7 +528,7 @@ _cogl_attribute_immutable_ref (CoglAttribute *attribute)
{
CoglBuffer *buffer = COGL_BUFFER (attribute->d.buffered.attribute_buffer);
_COGL_RETURN_VAL_IF_FAIL (cogl_is_attribute (attribute), NULL);
g_return_val_if_fail (cogl_is_attribute (attribute), NULL);
attribute->immutable_ref++;
_cogl_buffer_immutable_ref (buffer);
@ -540,8 +540,8 @@ _cogl_attribute_immutable_unref (CoglAttribute *attribute)
{
CoglBuffer *buffer = COGL_BUFFER (attribute->d.buffered.attribute_buffer);
_COGL_RETURN_IF_FAIL (cogl_is_attribute (attribute));
_COGL_RETURN_IF_FAIL (attribute->immutable_ref > 0);
g_return_if_fail (cogl_is_attribute (attribute));
g_return_if_fail (attribute->immutable_ref > 0);
attribute->immutable_ref--;
_cogl_buffer_immutable_unref (buffer);

View File

@ -361,7 +361,7 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format)
gboolean
_cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
CoglBitmap *dst_bmp,
CoglError **error)
GError **error)
{
uint8_t *src_data;
uint8_t *dst_data;
@ -384,8 +384,8 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
width = cogl_bitmap_get_width (src_bmp);
height = cogl_bitmap_get_height (src_bmp);
_COGL_RETURN_VAL_IF_FAIL (width == cogl_bitmap_get_width (dst_bmp), FALSE);
_COGL_RETURN_VAL_IF_FAIL (height == cogl_bitmap_get_height (dst_bmp), FALSE);
g_return_val_if_fail (width == cogl_bitmap_get_width (dst_bmp), FALSE);
g_return_val_if_fail (height == cogl_bitmap_get_height (dst_bmp), FALSE);
need_premult
= ((src_format & COGL_PREMULT_BIT) != (dst_format & COGL_PREMULT_BIT) &&
@ -488,7 +488,7 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
CoglBitmap *
_cogl_bitmap_convert (CoglBitmap *src_bmp,
CoglPixelFormat dst_format,
CoglError **error)
GError **error)
{
CoglBitmap *dst_bmp;
int width, height;
@ -547,13 +547,13 @@ CoglBitmap *
_cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp,
CoglPixelFormat internal_format,
gboolean can_convert_in_place,
CoglError **error)
GError **error)
{
CoglContext *ctx = _cogl_bitmap_get_context (src_bmp);
CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp);
CoglBitmap *dst_bmp;
_COGL_RETURN_VAL_IF_FAIL (internal_format != COGL_PIXEL_FORMAT_ANY, NULL);
g_return_val_if_fail (internal_format != COGL_PIXEL_FORMAT_ANY, NULL);
/* OpenGL supports specifying a different format for the internal
format when uploading texture data. We should use this to convert
@ -616,7 +616,7 @@ _cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp,
gboolean
_cogl_bitmap_unpremult (CoglBitmap *bmp,
CoglError **error)
GError **error)
{
uint8_t *p, *data;
uint16_t *tmp_row;
@ -684,7 +684,7 @@ _cogl_bitmap_unpremult (CoglBitmap *bmp,
gboolean
_cogl_bitmap_premult (CoglBitmap *bmp,
CoglError **error)
GError **error)
{
uint8_t *p, *data;
uint16_t *tmp_row;

View File

@ -34,7 +34,6 @@
#include "cogl-bitmap-private.h"
#include "cogl-context-private.h"
#include "cogl-private.h"
#include "cogl-error-private.h"
#include <string.h>
@ -45,7 +44,7 @@ _cogl_bitmap_get_size_from_file (const char *filename,
int *width,
int *height)
{
_COGL_RETURN_VAL_IF_FAIL (filename != NULL, FALSE);
g_return_val_if_fail (filename != NULL, FALSE);
if (gdk_pixbuf_get_file_info (filename, width, height) != NULL)
return TRUE;
@ -56,7 +55,7 @@ _cogl_bitmap_get_size_from_file (const char *filename,
CoglBitmap *
_cogl_bitmap_from_file (CoglContext *ctx,
const char *filename,
CoglError **error)
GError **error)
{
static CoglUserDataKey pixbuf_key;
GdkPixbuf *pixbuf;
@ -75,7 +74,7 @@ _cogl_bitmap_from_file (CoglContext *ctx,
pixbuf = gdk_pixbuf_new_from_file (filename, &glib_error);
if (pixbuf == NULL)
{
_cogl_propagate_gerror (error, glib_error);
g_propagate_error (error, glib_error);
return FALSE;
}

View File

@ -70,7 +70,7 @@ struct _CoglBitmap
* @width: width of the bitmap in pixels
* @height: height of the bitmap in pixels
* @format: the format of the pixels the array will store
* @error: A #CoglError for catching exceptional errors or %NULL
* @error: A #GError for catching exceptional errors or %NULL
*
* This is equivalent to cogl_bitmap_new_with_size() except that it
* allocated the buffer using g_malloc() instead of creating a
@ -87,7 +87,7 @@ _cogl_bitmap_new_with_malloc_buffer (CoglContext *context,
unsigned int width,
unsigned int height,
CoglPixelFormat format,
CoglError **error);
GError **error);
/* The idea of this function is that it will create a bitmap that
shares the actual data with another bitmap. This is needed for the
@ -103,53 +103,53 @@ _cogl_bitmap_new_shared (CoglBitmap *shared_bmp,
CoglBitmap *
_cogl_bitmap_convert (CoglBitmap *bmp,
CoglPixelFormat dst_format,
CoglError **error);
CoglPixelFormat dst_format,
GError **error);
CoglBitmap *
_cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp,
CoglPixelFormat internal_format,
gboolean can_convert_in_place,
CoglError **error);
GError **error);
gboolean
_cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
CoglBitmap *dst_bmp,
CoglError **error);
GError **error);
CoglBitmap *
_cogl_bitmap_from_file (CoglContext *ctx,
const char *filename,
CoglError **error);
GError **error);
gboolean
_cogl_bitmap_unpremult (CoglBitmap *dst_bmp,
CoglError **error);
GError **error);
gboolean
_cogl_bitmap_premult (CoglBitmap *dst_bmp,
CoglError **error);
GError **error);
gboolean
_cogl_bitmap_convert_premult_status (CoglBitmap *bmp,
CoglPixelFormat dst_format,
CoglError **error);
GError **error);
gboolean
_cogl_bitmap_copy_subregion (CoglBitmap *src,
CoglBitmap *dst,
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height,
CoglError **error);
CoglBitmap *dst,
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height,
GError **error);
/* Creates a deep copy of the source bitmap */
CoglBitmap *
_cogl_bitmap_copy (CoglBitmap *src_bmp,
CoglError **error);
GError **error);
gboolean
_cogl_bitmap_get_size_from_file (const char *filename,
@ -172,7 +172,7 @@ uint8_t *
_cogl_bitmap_map (CoglBitmap *bitmap,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error);
GError **error);
void
_cogl_bitmap_unmap (CoglBitmap *bitmap);
@ -190,7 +190,7 @@ uint8_t *
_cogl_bitmap_gl_bind (CoglBitmap *bitmap,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error);
GError **error);
void
_cogl_bitmap_gl_unbind (CoglBitmap *bitmap);

View File

@ -37,7 +37,6 @@
#include "cogl-buffer-private.h"
#include "cogl-pixel-buffer.h"
#include "cogl-context-private.h"
#include "cogl-error-private.h"
#include "cogl-gtype-private.h"
#include "driver/gl/cogl-buffer-gl-private.h"
@ -66,7 +65,7 @@ _cogl_bitmap_free (CoglBitmap *bmp)
gboolean
_cogl_bitmap_convert_premult_status (CoglBitmap *bmp,
CoglPixelFormat dst_format,
CoglError **error)
GError **error)
{
/* Do we need to unpremultiply? */
if ((bmp->format & COGL_PREMULT_BIT) > 0 &&
@ -86,7 +85,7 @@ _cogl_bitmap_convert_premult_status (CoglBitmap *bmp,
CoglBitmap *
_cogl_bitmap_copy (CoglBitmap *src_bmp,
CoglError **error)
GError **error)
{
CoglBitmap *dst_bmp;
CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp);
@ -124,7 +123,7 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src,
int dst_y,
int width,
int height,
CoglError **error)
GError **error)
{
uint8_t *srcdata;
uint8_t *dstdata;
@ -133,9 +132,9 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src,
gboolean succeeded = FALSE;
/* Intended only for fast copies when format is equal! */
_COGL_RETURN_VAL_IF_FAIL ((src->format & ~COGL_PREMULT_BIT) ==
(dst->format & ~COGL_PREMULT_BIT),
FALSE);
g_return_val_if_fail ((src->format & ~COGL_PREMULT_BIT) ==
(dst->format & ~COGL_PREMULT_BIT),
FALSE);
bpp = _cogl_pixel_format_get_bytes_per_pixel (src->format);
@ -209,7 +208,7 @@ _cogl_bitmap_new_with_malloc_buffer (CoglContext *context,
unsigned int width,
unsigned int height,
CoglPixelFormat format,
CoglError **error)
GError **error)
{
static CoglUserDataKey bitmap_free_key;
int bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
@ -219,10 +218,9 @@ _cogl_bitmap_new_with_malloc_buffer (CoglContext *context,
if (!data)
{
_cogl_set_error (error,
COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_NO_MEMORY,
"Failed to allocate memory for bitmap");
g_set_error_literal (error, COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_NO_MEMORY,
"Failed to allocate memory for bitmap");
return NULL;
}
@ -261,12 +259,12 @@ _cogl_bitmap_new_shared (CoglBitmap *shared_bmp,
CoglBitmap *
cogl_bitmap_new_from_file (const char *filename,
CoglError **error)
GError **error)
{
_COGL_GET_CONTEXT (ctx, NULL);
_COGL_RETURN_VAL_IF_FAIL (filename != NULL, NULL);
_COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL);
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
return _cogl_bitmap_from_file (ctx, filename, error);
}
@ -281,7 +279,7 @@ cogl_bitmap_new_from_buffer (CoglBuffer *buffer,
{
CoglBitmap *bmp;
_COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL);
g_return_val_if_fail (cogl_is_buffer (buffer), NULL);
bmp = cogl_bitmap_new_for_data (buffer->context,
width, height,
@ -306,7 +304,7 @@ cogl_bitmap_new_with_size (CoglContext *context,
unsigned int rowstride;
/* creating a buffer to store "any" format does not make sense */
_COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL);
g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL);
/* for now we fallback to cogl_pixel_buffer_new, later, we could ask
* libdrm a tiled buffer for instance */
@ -317,7 +315,7 @@ cogl_bitmap_new_with_size (CoglContext *context,
height * rowstride,
NULL); /* data */
_COGL_RETURN_VAL_IF_FAIL (pixel_buffer != NULL, NULL);
g_return_val_if_fail (pixel_buffer != NULL, NULL);
bitmap = cogl_bitmap_new_from_buffer (COGL_BUFFER (pixel_buffer),
format,
@ -380,7 +378,7 @@ uint8_t *
_cogl_bitmap_map (CoglBitmap *bitmap,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error)
GError **error)
{
/* Divert to another bitmap if this data is shared */
if (bitmap->shared_bmp)
@ -437,10 +435,10 @@ uint8_t *
_cogl_bitmap_gl_bind (CoglBitmap *bitmap,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error)
GError **error)
{
uint8_t *ptr;
CoglError *internal_error = NULL;
GError *internal_error = NULL;
g_return_val_if_fail (access & (COGL_BUFFER_ACCESS_READ |
COGL_BUFFER_ACCESS_WRITE),
@ -450,7 +448,7 @@ _cogl_bitmap_gl_bind (CoglBitmap *bitmap,
if (bitmap->shared_bmp)
return _cogl_bitmap_gl_bind (bitmap->shared_bmp, access, hints, error);
_COGL_RETURN_VAL_IF_FAIL (!bitmap->bound, NULL);
g_return_val_if_fail (!bitmap->bound, NULL);
/* If the bitmap wasn't created from a buffer then the
implementation of bind is the same as map */
@ -482,7 +480,7 @@ _cogl_bitmap_gl_bind (CoglBitmap *bitmap,
* if an exception was thrown */
if (internal_error)
{
_cogl_propagate_error (error, internal_error);
g_propagate_error (error, internal_error);
return NULL;
}

View File

@ -70,7 +70,7 @@ GType cogl_bitmap_get_gtype (void);
/**
* cogl_bitmap_new_from_file:
* @filename: the file to load.
* @error: a #CoglError or %NULL.
* @error: a #GError or %NULL.
*
* Loads an image file from disk. This function can be safely called from
* within a thread.
@ -82,7 +82,7 @@ GType cogl_bitmap_get_gtype (void);
*/
CoglBitmap *
cogl_bitmap_new_from_file (const char *filename,
CoglError **error);
GError **error);
/**
* cogl_bitmap_new_from_buffer: (skip)
@ -269,7 +269,7 @@ cogl_is_bitmap (void *object);
/**
* COGL_BITMAP_ERROR:
*
* #CoglError domain for bitmap errors.
* #GError domain for bitmap errors.
*
* Since: 1.4
*/

View File

@ -41,7 +41,6 @@
#include "cogl-context-private.h"
#include "cogl-debug.h"
#include "cogl-blend-string.h"
#include "cogl-error-private.h"
typedef enum _ParserState
{
@ -166,7 +165,7 @@ _cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement,
static gboolean
validate_tex_combine_statements (CoglBlendStringStatement *statements,
int n_statements,
CoglError **error)
GError **error)
{
int i, j;
const char *error_string;
@ -195,11 +194,8 @@ validate_tex_combine_statements (CoglBlendStringStatement *statements,
return TRUE;
error:
_cogl_set_error (error,
COGL_BLEND_STRING_ERROR,
detail,
"Invalid texture combine string: %s",
error_string);
g_set_error (error, COGL_BLEND_STRING_ERROR, detail,
"Invalid texture combine string: %s", error_string);
if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS))
{
@ -212,7 +208,7 @@ error:
static gboolean
validate_blend_statements (CoglBlendStringStatement *statements,
int n_statements,
CoglError **error)
GError **error)
{
int i, j;
const char *error_string;
@ -265,11 +261,8 @@ validate_blend_statements (CoglBlendStringStatement *statements,
return TRUE;
error:
_cogl_set_error (error,
COGL_BLEND_STRING_ERROR,
detail,
"Invalid blend string: %s",
error_string);
g_set_error (error, COGL_BLEND_STRING_ERROR, detail,
"Invalid blend string: %s", error_string);
return FALSE;
}
@ -277,7 +270,7 @@ static gboolean
validate_statements_for_context (CoglBlendStringStatement *statements,
int n_statements,
CoglBlendStringContext context,
CoglError **error)
GError **error)
{
const char *error_string;
@ -303,13 +296,12 @@ validate_statements_for_context (CoglBlendStringStatement *statements,
return validate_tex_combine_statements (statements, n_statements, error);
error:
_cogl_set_error (error,
COGL_BLEND_STRING_ERROR,
COGL_BLEND_STRING_ERROR_INVALID_ERROR,
"Invalid %s string: %s",
context == COGL_BLEND_STRING_CONTEXT_BLENDING ?
"blend" : "texture combine",
error_string);
g_set_error (error, COGL_BLEND_STRING_ERROR,
COGL_BLEND_STRING_ERROR_INVALID_ERROR,
"Invalid %s string: %s",
context == COGL_BLEND_STRING_CONTEXT_BLENDING ?
"blend" : "texture combine",
error_string);
if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS))
{
@ -464,7 +456,7 @@ parse_argument (const char *string, /* original user string */
int current_arg,
CoglBlendStringArgument *arg, /* OUT */
CoglBlendStringContext context,
CoglError **error)
GError **error)
{
const char *p = *ret_p;
const char *mark = NULL;
@ -733,13 +725,13 @@ parse_argument (const char *string, /* original user string */
error:
{
int offset = p - string;
_cogl_set_error (error,
COGL_BLEND_STRING_ERROR,
COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR,
"Syntax error for argument %d at offset %d: %s",
current_arg,
offset,
error_string);
g_set_error (error,
COGL_BLEND_STRING_ERROR,
COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR,
"Syntax error for argument %d at offset %d: %s",
current_arg,
offset,
error_string);
if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS))
{
@ -754,7 +746,7 @@ int
_cogl_blend_string_compile (const char *string,
CoglBlendStringContext context,
CoglBlendStringStatement *statements,
CoglError **error)
GError **error)
{
const char *p = string;
const char *mark = NULL;
@ -914,12 +906,12 @@ finished:
error:
{
int offset = p - string;
_cogl_set_error (error,
COGL_BLEND_STRING_ERROR,
COGL_BLEND_STRING_ERROR_PARSE_ERROR,
"Syntax error at offset %d: %s",
offset,
error_string);
g_set_error (error,
COGL_BLEND_STRING_ERROR,
COGL_BLEND_STRING_ERROR_PARSE_ERROR,
"Syntax error at offset %d: %s",
offset,
error_string);
if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS))
{
@ -971,7 +963,7 @@ _cogl_blend_string_test (void)
};
int i;
CoglError *error = NULL;
GError *error = NULL;
for (i = 0; strings[i].string; i++)
{
CoglBlendStringStatement statements[2];
@ -984,7 +976,7 @@ _cogl_blend_string_test (void)
g_print ("Failed to parse string:\n%s\n%s\n",
strings[i].string,
error->message);
cogl_error_free (error);
g_error_free (error);
error = NULL;
continue;
}

View File

@ -133,7 +133,7 @@ gboolean
_cogl_blend_string_compile (const char *string,
CoglBlendStringContext context,
CoglBlendStringStatement *statements,
CoglError **error);
GError **error);
void
_cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement,

View File

@ -52,7 +52,7 @@ _cogl_blit_texture_render_begin (CoglBlitData *data)
CoglFramebuffer *fb;
CoglPipeline *pipeline;
unsigned int dst_width, dst_height;
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
offscreen = _cogl_offscreen_new_with_texture_full
(data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */);
@ -60,7 +60,7 @@ _cogl_blit_texture_render_begin (CoglBlitData *data)
fb = COGL_FRAMEBUFFER (offscreen);
if (!cogl_framebuffer_allocate (fb, &ignore_error))
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
cogl_object_unref (fb);
return FALSE;
}
@ -150,7 +150,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
CoglContext *ctx = data->src_tex->context;
CoglOffscreen *dst_offscreen = NULL, *src_offscreen = NULL;
CoglFramebuffer *dst_fb, *src_fb;
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
/* We can only blit between FBOs if both textures are the same
format and the blit framebuffer extension is supported */
@ -165,7 +165,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
dst_fb = COGL_FRAMEBUFFER (dst_offscreen);
if (!cogl_framebuffer_allocate (dst_fb, &ignore_error))
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
goto error;
}
@ -177,7 +177,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
src_fb = COGL_FRAMEBUFFER (src_offscreen);
if (!cogl_framebuffer_allocate (src_fb, &ignore_error))
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
goto error;
}
@ -224,7 +224,7 @@ _cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data)
{
CoglOffscreen *offscreen;
CoglFramebuffer *fb;
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
/* This will only work if the target texture is a CoglTexture2D */
if (!cogl_is_texture_2d (data->dst_tex))
@ -236,7 +236,7 @@ _cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data)
fb = COGL_FRAMEBUFFER (offscreen);
if (!cogl_framebuffer_allocate (fb, &ignore_error))
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
cogl_object_unref (fb);
return FALSE;
}
@ -292,7 +292,7 @@ _cogl_blit_get_tex_data_blit (CoglBlitData *data,
int width,
int height)
{
CoglError *ignore = NULL;
GError *ignore = NULL;
int rowstride = data->src_width * data->bpp;
int offset = rowstride * src_y + src_x * data->bpp;
@ -409,7 +409,7 @@ _cogl_blit_begin (CoglBlitData *data,
_cogl_blit_modes[i].name);
/* The last blit mode can't fail so this should never happen */
_COGL_RETURN_IF_FAIL (i < G_N_ELEMENTS (_cogl_blit_modes));
g_return_if_fail (i < G_N_ELEMENTS (_cogl_blit_modes));
}
data->blit_mode = _cogl_blit_default_mode;

View File

@ -53,7 +53,7 @@ struct _CoglBufferVtable
size_t size,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error);
GError **error);
void (* unmap) (CoglBuffer *buffer);
@ -61,7 +61,7 @@ struct _CoglBufferVtable
unsigned int offset,
const void *data,
unsigned int size,
CoglError **error);
GError **error);
};
typedef enum _CoglBufferFlags
@ -153,13 +153,13 @@ _cogl_buffer_set_data (CoglBuffer *buffer,
size_t offset,
const void *data,
size_t size,
CoglError **error);
GError **error);
void *
_cogl_buffer_map (CoglBuffer *buffer,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error);
GError **error);
/* This is a wrapper around cogl_buffer_map_range for internal use
when we want to map the buffer for write only to replace the entire

View File

@ -88,7 +88,7 @@ malloc_map_range (CoglBuffer *buffer,
size_t size,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error)
GError **error)
{
buffer->flags |= COGL_BUFFER_FLAG_MAPPED;
return buffer->data + offset;
@ -105,7 +105,7 @@ malloc_set_data (CoglBuffer *buffer,
unsigned int offset,
const void *data,
unsigned int size,
CoglError **error)
GError **error)
{
memcpy (buffer->data + offset, data, size);
return TRUE;
@ -167,8 +167,8 @@ _cogl_buffer_initialize (CoglBuffer *buffer,
void
_cogl_buffer_fini (CoglBuffer *buffer)
{
_COGL_RETURN_IF_FAIL (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED));
_COGL_RETURN_IF_FAIL (buffer->immutable_ref == 0);
g_return_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED));
g_return_if_fail (buffer->immutable_ref == 0);
if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT)
buffer->context->driver_vtable->buffer_destroy (buffer);
@ -223,9 +223,9 @@ void *
_cogl_buffer_map (CoglBuffer *buffer,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error)
GError **error)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL);
g_return_val_if_fail (cogl_is_buffer (buffer), NULL);
return cogl_buffer_map_range (buffer, 0, buffer->size, access, hints, error);
}
@ -235,12 +235,11 @@ cogl_buffer_map (CoglBuffer *buffer,
CoglBufferAccess access,
CoglBufferMapHint hints)
{
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
void *ptr =
cogl_buffer_map_range (buffer, 0, buffer->size, access, hints,
&ignore_error);
if (!ptr)
cogl_error_free (ignore_error);
g_clear_error (&ignore_error);
return ptr;
}
@ -250,10 +249,10 @@ cogl_buffer_map_range (CoglBuffer *buffer,
size_t size,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error)
GError **error)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL);
_COGL_RETURN_VAL_IF_FAIL (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED), NULL);
g_return_val_if_fail (cogl_is_buffer (buffer), NULL);
g_return_val_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED), NULL);
if (G_UNLIKELY (buffer->immutable_ref))
warn_about_midscene_changes ();
@ -293,9 +292,9 @@ _cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer,
{
CoglContext *ctx = buffer->context;
void *ret;
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
_COGL_RETURN_VAL_IF_FAIL (!ctx->buffer_map_fallback_in_use, NULL);
g_return_val_if_fail (!ctx->buffer_map_fallback_in_use, NULL);
ctx->buffer_map_fallback_in_use = TRUE;
@ -309,7 +308,7 @@ _cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer,
if (ret)
return ret;
cogl_error_free (ignore_error);
g_error_free (ignore_error);
/* If the map fails then we'll use a temporary buffer to fill
the data and then upload it using cogl_buffer_set_data when
@ -328,7 +327,7 @@ _cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer)
{
CoglContext *ctx = buffer->context;
_COGL_RETURN_IF_FAIL (ctx->buffer_map_fallback_in_use);
g_return_if_fail (ctx->buffer_map_fallback_in_use);
ctx->buffer_map_fallback_in_use = FALSE;
@ -364,10 +363,10 @@ _cogl_buffer_set_data (CoglBuffer *buffer,
size_t offset,
const void *data,
size_t size,
CoglError **error)
GError **error)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), FALSE);
_COGL_RETURN_VAL_IF_FAIL ((offset + size) <= buffer->size, FALSE);
g_return_val_if_fail (cogl_is_buffer (buffer), FALSE);
g_return_val_if_fail ((offset + size) <= buffer->size, FALSE);
if (G_UNLIKELY (buffer->immutable_ref))
warn_about_midscene_changes ();
@ -381,18 +380,17 @@ cogl_buffer_set_data (CoglBuffer *buffer,
const void *data,
size_t size)
{
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
gboolean status =
_cogl_buffer_set_data (buffer, offset, data, size, &ignore_error);
if (!status)
cogl_error_free (ignore_error);
g_clear_error (&ignore_error);
return status;
}
CoglBuffer *
_cogl_buffer_immutable_ref (CoglBuffer *buffer)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL);
g_return_val_if_fail (cogl_is_buffer (buffer), NULL);
buffer->immutable_ref++;
return buffer;
@ -401,8 +399,8 @@ _cogl_buffer_immutable_ref (CoglBuffer *buffer)
void
_cogl_buffer_immutable_unref (CoglBuffer *buffer)
{
_COGL_RETURN_IF_FAIL (cogl_is_buffer (buffer));
_COGL_RETURN_IF_FAIL (buffer->immutable_ref > 0);
g_return_if_fail (cogl_is_buffer (buffer));
g_return_if_fail (buffer->immutable_ref > 0);
buffer->immutable_ref--;
}

View File

@ -40,7 +40,6 @@
#define __COGL_BUFFER_H__
#include <cogl/cogl-types.h>
#include <cogl/cogl-error.h>
G_BEGIN_DECLS
@ -258,7 +257,7 @@ cogl_buffer_map (CoglBuffer *buffer,
* @access: how the mapped buffer will be used by the application
* @hints: A mask of #CoglBufferMapHint<!-- -->s that tell Cogl how
* the data will be modified once mapped.
* @error: A #CoglError for catching exceptional errors
* @error: A #GError for catching exceptional errors
*
* Maps a sub-region of the buffer into the application's address space
* for direct access.
@ -288,7 +287,7 @@ cogl_buffer_map_range (CoglBuffer *buffer,
size_t size,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error);
GError **error);
/**
* cogl_buffer_unmap:

View File

@ -350,7 +350,7 @@ _cogl_clip_stack_pop (CoglClipStack *stack)
{
CoglClipStack *new_top;
_COGL_RETURN_VAL_IF_FAIL (stack != NULL, NULL);
g_return_val_if_fail (stack != NULL, NULL);
/* To pop we are moving the top of the stack to the old top's parent
node. The stack always needs to have a reference to the top entry

View File

@ -68,7 +68,7 @@ cogl_color_init_from_4ub (CoglColor *color,
uint8_t blue,
uint8_t alpha)
{
_COGL_RETURN_IF_FAIL (color != NULL);
g_return_if_fail (color != NULL);
color->red = red;
color->green = green;
@ -94,7 +94,7 @@ cogl_color_init_from_4f (CoglColor *color,
float blue,
float alpha)
{
_COGL_RETURN_IF_FAIL (color != NULL);
g_return_if_fail (color != NULL);
color->red = (red * 255);
color->green = (green * 255);
@ -117,7 +117,7 @@ void
cogl_color_init_from_4fv (CoglColor *color,
const float *color_array)
{
_COGL_RETURN_IF_FAIL (color != NULL);
g_return_if_fail (color != NULL);
color->red = (color_array[0] * 255);
color->green = (color_array[1] * 255);
@ -305,8 +305,8 @@ cogl_color_equal (const void *v1, const void *v2)
{
const uint32_t *c1 = v1, *c2 = v2;
_COGL_RETURN_VAL_IF_FAIL (v1 != NULL, FALSE);
_COGL_RETURN_VAL_IF_FAIL (v2 != NULL, FALSE);
g_return_val_if_fail (v1 != NULL, FALSE);
g_return_val_if_fail (v2 != NULL, FALSE);
/* XXX: We don't compare the padding */
return *c1 == *c2 ? TRUE : FALSE;

View File

@ -363,7 +363,7 @@ _cogl_context_get_winsys (CoglContext *context);
* return FALSE and set @error */
gboolean
_cogl_context_update_features (CoglContext *context,
CoglError **error);
GError **error);
/* Obtains the context and returns retval if NULL */
#define _COGL_GET_CONTEXT(ctxvar, retval) \

View File

@ -47,7 +47,6 @@
#include "cogl1-context.h"
#include "cogl-gpu-info-private.h"
#include "cogl-config-private.h"
#include "cogl-error-private.h"
#include "cogl-gtype-private.h"
#include "driver/gl/cogl-pipeline-opengl-private.h"
#include "driver/gl/cogl-util-gl-private.h"
@ -123,7 +122,7 @@ _cogl_context_get_winsys (CoglContext *context)
*/
CoglContext *
cogl_context_new (CoglDisplay *display,
CoglError **error)
GError **error)
{
CoglContext *context;
uint8_t white_pixel[] = { 0xff, 0xff, 0xff, 0xff };
@ -528,7 +527,7 @@ _cogl_context_free (CoglContext *context)
CoglContext *
_cogl_context_get_default (void)
{
CoglError *error = NULL;
GError *error = NULL;
/* Create if doesn't exist yet */
if (_cogl_context == NULL)
{
@ -537,7 +536,7 @@ _cogl_context_get_default (void)
{
g_warning ("Failed to create default context: %s",
error->message);
cogl_error_free (error);
g_error_free (error);
}
}
@ -558,7 +557,7 @@ cogl_context_get_renderer (CoglContext *context)
gboolean
_cogl_context_update_features (CoglContext *context,
CoglError **error)
GError **error)
{
return context->driver_vtable->update_features (context, error);
}

View File

@ -104,7 +104,7 @@ GType cogl_context_get_gtype (void);
/**
* cogl_context_new: (constructor)
* @display: (allow-none): A #CoglDisplay pointer
* @error: A CoglError return location.
* @error: A GError return location.
*
* Creates a new #CoglContext which acts as an application sandbox
* for any state objects that are allocated.
@ -115,7 +115,7 @@ GType cogl_context_get_gtype (void);
*/
CoglContext *
cogl_context_new (CoglDisplay *display,
CoglError **error);
GError **error);
/**
* cogl_context_get_display:

View File

@ -46,3 +46,4 @@
#mesondefine COGL_HAS_X11_SUPPORT
#mesondefine COGL_HAS_XLIB
#mesondefine COGL_HAS_XLIB_SUPPORT
#mesondefine COGL_HAS_LIBDRM

View File

@ -52,14 +52,14 @@ void
cogl_depth_state_set_test_enabled (CoglDepthState *state,
gboolean enabled)
{
_COGL_RETURN_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC);
g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC);
state->test_enabled = enabled;
}
gboolean
cogl_depth_state_get_test_enabled (CoglDepthState *state)
{
_COGL_RETURN_VAL_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);
g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);
return state->test_enabled;
}
@ -67,14 +67,14 @@ void
cogl_depth_state_set_write_enabled (CoglDepthState *state,
gboolean enabled)
{
_COGL_RETURN_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC);
g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC);
state->write_enabled = enabled;
}
gboolean
cogl_depth_state_get_write_enabled (CoglDepthState *state)
{
_COGL_RETURN_VAL_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);
g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);
return state->write_enabled;
}
@ -82,14 +82,14 @@ void
cogl_depth_state_set_test_function (CoglDepthState *state,
CoglDepthTestFunction function)
{
_COGL_RETURN_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC);
g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC);
state->test_function = function;
}
CoglDepthTestFunction
cogl_depth_state_get_test_function (CoglDepthState *state)
{
_COGL_RETURN_VAL_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);
g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);
return state->test_function;
}
@ -98,7 +98,7 @@ cogl_depth_state_set_range (CoglDepthState *state,
float near,
float far)
{
_COGL_RETURN_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC);
g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC);
state->range_near = near;
state->range_far = far;
}
@ -108,7 +108,7 @@ cogl_depth_state_get_range (CoglDepthState *state,
float *near_out,
float *far_out)
{
_COGL_RETURN_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC);
g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC);
*near_out = state->range_near;
*far_out = state->range_far;
}

View File

@ -87,7 +87,7 @@ cogl_display_new (CoglRenderer *renderer,
CoglOnscreenTemplate *onscreen_template)
{
CoglDisplay *display = g_slice_new0 (CoglDisplay);
CoglError *error = NULL;
GError *error = NULL;
_cogl_init ();
@ -119,7 +119,7 @@ void
cogl_display_set_onscreen_template (CoglDisplay *display,
CoglOnscreenTemplate *onscreen_template)
{
_COGL_RETURN_IF_FAIL (display->setup == FALSE);
g_return_if_fail (display->setup == FALSE);
if (onscreen_template)
cogl_object_ref (onscreen_template);
@ -137,7 +137,7 @@ cogl_display_set_onscreen_template (CoglDisplay *display,
gboolean
cogl_display_setup (CoglDisplay *display,
CoglError **error)
GError **error)
{
const CoglWinsysVtable *winsys;
@ -158,7 +158,7 @@ void
cogl_wayland_display_set_compositor_display (CoglDisplay *display,
struct wl_display *wayland_display)
{
_COGL_RETURN_IF_FAIL (display->setup == FALSE);
g_return_if_fail (display->setup == FALSE);
display->wayland_compositor_display = wayland_display;
}

View File

@ -158,7 +158,7 @@ cogl_display_set_onscreen_template (CoglDisplay *display,
/**
* cogl_display_setup:
* @display: a #CoglDisplay
* @error: return location for a #CoglError
* @error: return location for a #GError
*
* Explicitly sets up the given @display object. Use of this api is
* optional since Cogl will internally setup the display if not done
@ -188,7 +188,7 @@ cogl_display_set_onscreen_template (CoglDisplay *display,
*/
gboolean
cogl_display_setup (CoglDisplay *display,
CoglError **error);
GError **error);
/**
* cogl_is_display:

View File

@ -58,11 +58,11 @@ struct _CoglDriverVtable
gboolean
(* update_features) (CoglContext *context,
CoglError **error);
GError **error);
gboolean
(* offscreen_allocate) (CoglOffscreen *offscreen,
CoglError **error);
GError **error);
void
(* offscreen_free) (CoglOffscreen *offscreen);
@ -118,7 +118,7 @@ struct _CoglDriverVtable
int y,
CoglReadPixelsFlags source,
CoglBitmap *bitmap,
CoglError **error);
GError **error);
/* Destroys any driver specific resources associated with the given
* 2D texture. */
@ -146,7 +146,7 @@ struct _CoglDriverVtable
* to the configured size and format of the texture */
gboolean
(* texture_2d_allocate) (CoglTexture *tex,
CoglError **error);
GError **error);
/* Initialize the specified region of storage of the given texture
* with the contents of the specified framebuffer region
@ -190,7 +190,7 @@ struct _CoglDriverVtable
int dst_x,
int dst_y,
int level,
CoglError **error);
GError **error);
gboolean
(* texture_2d_is_get_data_supported) (CoglTexture2D *tex_2d);
@ -239,7 +239,7 @@ struct _CoglDriverVtable
size_t size,
CoglBufferAccess access,
CoglBufferMapHint hints,
CoglError **error);
GError **error);
/* Unmaps a buffer */
void
@ -252,7 +252,7 @@ struct _CoglDriverVtable
unsigned int offset,
const void *data,
unsigned int size,
CoglError **error);
GError **error);
};
#define COGL_DRIVER_ERROR (_cogl_driver_error_quark ())

View File

@ -1,57 +0,0 @@
/*
* Cogl
*
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2012 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __COGL_ERROR_PRIVATE_H__
#define __COGL_ERROR_PRIVATE_H__
#include "cogl-error.h"
void
_cogl_set_error (CoglError **error,
uint32_t domain,
int code,
const char *format,
...) G_GNUC_PRINTF (4, 5);
void
_cogl_set_error_literal (CoglError **error,
uint32_t domain,
int code,
const char *message);
void
_cogl_propagate_error (CoglError **dest,
CoglError *src);
void
_cogl_propagate_gerror (CoglError **dest,
GError *src);
#define _cogl_clear_error(X) g_clear_error ((GError **)X)
#endif /* __COGL_ERROR_PRIVATE_H__ */

View File

@ -1,126 +0,0 @@
/*
* Cogl
*
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2011 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*/
#include "cogl-config.h"
#include "cogl-types.h"
#include "cogl-util.h"
#include "cogl-error-private.h"
#include <glib.h>
void
cogl_error_free (CoglError *error)
{
g_error_free ((GError *)error);
}
CoglError *
cogl_error_copy (CoglError *error)
{
return (CoglError *)g_error_copy ((GError *)error);
}
gboolean
cogl_error_matches (CoglError *error,
uint32_t domain,
int code)
{
return g_error_matches ((GError *)error, domain, code);
}
#define ERROR_OVERWRITTEN_WARNING \
"CoglError set over the top of a previous CoglError or " \
"uninitialized memory.\nThis indicates a bug in someone's " \
"code. You must ensure an error is NULL before it's set.\n" \
"The overwriting error message was: %s"
void
_cogl_set_error (CoglError **error,
uint32_t domain,
int code,
const char *format,
...)
{
GError *new;
va_list args;
va_start (args, format);
if (error == NULL)
{
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args);
va_end (args);
return;
}
new = g_error_new_valist (domain, code, format, args);
va_end (args);
if (*error == NULL)
*error = (CoglError *)new;
else
g_warning (ERROR_OVERWRITTEN_WARNING, new->message);
}
void
_cogl_set_error_literal (CoglError **error,
uint32_t domain,
int code,
const char *message)
{
_cogl_set_error (error, domain, code, "%s", message);
}
void
_cogl_propagate_error (CoglError **dest,
CoglError *src)
{
_COGL_RETURN_IF_FAIL (src != NULL);
if (dest == NULL)
{
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "%s", src->message);
cogl_error_free (src);
}
else if (*dest)
g_warning (ERROR_OVERWRITTEN_WARNING, src->message);
else
*dest = src;
}
void
_cogl_propagate_gerror (CoglError **dest,
GError *src)
{
_cogl_propagate_error (dest, (CoglError *) src);
}

View File

@ -1,169 +0,0 @@
/*
* Cogl
*
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2012 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
#error "Only <cogl/cogl.h> can be included directly."
#endif
#ifndef __COGL_ERROR_H__
#define __COGL_ERROR_H__
#include "cogl-types.h"
G_BEGIN_DECLS
/**
* SECTION:cogl-error
* @short_description: A way for Cogl to throw exceptions
*
* As a general rule Cogl shields non-recoverable errors from
* developers, such as most heap allocation failures (unless for
* exceptionally large resources which we might reasonably expect to
* fail) and this reduces the burden on developers.
*
* There are some Cogl apis though that can fail for exceptional
* reasons that can also potentially be recovered from at runtime
* and for these apis we use a standard convention for reporting
* runtime recoverable errors.
*
* As an example if we look at the cogl_context_new() api which
* takes an error argument:
* |[
* CoglContext *
* cogl_context_new (CoglDisplay *display, CoglError **error);
* ]|
*
* A caller interested in catching any runtime error when creating a
* new #CoglContext would pass the address of a #CoglError pointer
* that has first been initialized to %NULL as follows:
*
* |[
* CoglError *error = NULL;
* CoglContext *context;
*
* context = cogl_context_new (NULL, &error);
* ]|
*
* The return status should usually be enough to determine if there
* was an error set (in this example we can check if context == %NULL)
* but if it's not possible to tell from the function's return status
* you can instead look directly at the error pointer which you
* initialized to %NULL. In this example we now check the error,
* report any error to the user, free the error and then simply
* abort without attempting to recover.
*
* |[
* if (context == NULL)
* {
* fprintf (stderr, "Failed to create a Cogl context: %s\n",
* error->message);
* cogl_error_free (error);
* abort ();
* }
* ]|
*
* All Cogl APIs that accept an error argument can also be passed a
* %NULL pointer. In this case if an exceptional error condition is hit
* then Cogl will simply log the error message and abort the
* application. This can be compared to language execeptions where the
* developer has not attempted to catch the exception. This means the
* above example is essentially redundant because it's what Cogl would
* have done automatically and so, similarly, if your application has
* no way to recover from a particular error you might just as well
* pass a %NULL #CoglError pointer to save a bit of typing.
*
* <note>If you are used to using the GLib API you will probably
* recognize that #CoglError is just like a #GError. In fact if Cogl
* has been built with --enable-glib then it is safe to cast a
* #CoglError to a #GError.</note>
*
* <note>An important detail to be aware of if you are used to using
* GLib's GError API is that Cogl deviates from the GLib GError
* conventions in one noteable way which is that a %NULL error pointer
* does not mean you want to ignore the details of an error, it means
* you are not trying to catch any exceptional errors the function might
* throw which will result in the program aborting with a log message
* if an error is thrown.</note>
*/
#define CoglError GError
/**
* cogl_error_free:
* @error: A #CoglError thrown by the Cogl api
*
* Frees a #CoglError and associated resources.
*/
void
cogl_error_free (CoglError *error);
/**
* cogl_error_copy:
* @error: A #CoglError thrown by the Cogl api
*
* Makes a copy of @error which can later be freed using
* cogl_error_free().
*
* Return value: A newly allocated #CoglError initialized to match the
* contents of @error.
*/
CoglError *
cogl_error_copy (CoglError *error);
/**
* cogl_error_matches:
* @error: A #CoglError thrown by the Cogl api or %NULL
* @domain: The error domain
* @code: The error code
*
* Returns %TRUE if error matches @domain and @code, %FALSE otherwise.
* In particular, when error is %NULL, FALSE will be returned.
*
* Return value: whether the @error corresponds to the given @domain
* and @code.
*/
gboolean
cogl_error_matches (CoglError *error,
uint32_t domain,
int code);
/**
* COGL_GLIB_ERROR:
* @COGL_ERROR: A #CoglError thrown by the Cogl api or %NULL
*
* Simply casts a #CoglError to a #CoglError
*
* If Cogl is built with GLib support then it can safely be assumed
* that a CoglError is a GError and can be used directly with the
* GError api.
*/
#define COGL_GLIB_ERROR(COGL_ERROR) ((CoglError *)COGL_ERROR)
G_END_DECLS
#endif /* __COGL_ERROR_H__ */

View File

@ -164,8 +164,8 @@ cogl_euler_equal (const void *v1, const void *v2)
const CoglEuler *a = v1;
const CoglEuler *b = v2;
_COGL_RETURN_VAL_IF_FAIL (v1 != NULL, FALSE);
_COGL_RETURN_VAL_IF_FAIL (v2 != NULL, FALSE);
g_return_val_if_fail (v1 != NULL, FALSE);
g_return_val_if_fail (v2 != NULL, FALSE);
if (v1 == v2)
return TRUE;

View File

@ -497,7 +497,7 @@ _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
int y,
CoglReadPixelsFlags source,
CoglBitmap *bitmap,
CoglError **error);
GError **error);
/*
* _cogl_framebuffer_get_stencil_bits:

View File

@ -50,7 +50,6 @@
#include "cogl1-context.h"
#include "cogl-private.h"
#include "cogl-primitives-private.h"
#include "cogl-error-private.h"
#include "cogl-gtype-private.h"
#include "driver/gl/cogl-texture-gl-private.h"
#include "winsys/cogl-winsys-private.h"
@ -445,11 +444,11 @@ ensure_size_initialized (CoglFramebuffer *framebuffer)
{
/* Currently we assume the size is always initialized for
* onscreen framebuffers. */
_COGL_RETURN_IF_FAIL (cogl_is_offscreen (framebuffer));
g_return_if_fail (cogl_is_offscreen (framebuffer));
/* We also assume the size would have been initialized if the
* framebuffer were allocated. */
_COGL_RETURN_IF_FAIL (!framebuffer->allocated);
g_return_if_fail (!framebuffer->allocated);
cogl_framebuffer_allocate (framebuffer, NULL);
}
@ -493,7 +492,7 @@ cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer,
{
CoglContext *context = framebuffer->context;
_COGL_RETURN_IF_FAIL (width > 0 && height > 0);
g_return_if_fail (width > 0 && height > 0);
if (framebuffer->viewport_x == x &&
framebuffer->viewport_y == y &&
@ -618,7 +617,7 @@ _cogl_offscreen_new_with_texture_full (CoglTexture *texture,
CoglFramebuffer *fb;
CoglOffscreen *ret;
_COGL_RETURN_VAL_IF_FAIL (cogl_is_texture (texture), NULL);
g_return_val_if_fail (cogl_is_texture (texture), NULL);
offscreen = g_new0 (CoglOffscreen, 1);
offscreen->texture = cogl_object_ref (texture);
@ -650,12 +649,12 @@ CoglOffscreen *
cogl_offscreen_new_to_texture (CoglTexture *texture)
{
CoglOffscreen *ret = _cogl_offscreen_new_with_texture_full (texture, 0, 0);
CoglError *error = NULL;
GError *error = NULL;
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (ret), &error))
{
cogl_object_unref (ret);
cogl_error_free (error);
g_error_free (error);
ret = NULL;
}
@ -696,7 +695,7 @@ _cogl_offscreen_free (CoglOffscreen *offscreen)
gboolean
cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
CoglError **error)
GError **error)
{
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
@ -709,10 +708,10 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
{
if (framebuffer->config.depth_texture_enabled)
{
_cogl_set_error (error, COGL_FRAMEBUFFER_ERROR,
COGL_FRAMEBUFFER_ERROR_ALLOCATE,
"Can't allocate onscreen framebuffer with a "
"texture based depth buffer");
g_set_error_literal (error, COGL_FRAMEBUFFER_ERROR,
COGL_FRAMEBUFFER_ERROR_ALLOCATE,
"Can't allocate onscreen framebuffer with a "
"texture based depth buffer");
return FALSE;
}
@ -732,9 +731,9 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
{
_cogl_set_error (error, COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_UNSUPPORTED,
"Offscreen framebuffers not supported by system");
g_set_error_literal (error, COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_UNSUPPORTED,
"Offscreen framebuffers not supported by system");
return FALSE;
}
@ -745,10 +744,9 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
* determine whether a texture needs slicing... */
if (cogl_texture_is_sliced (offscreen->texture))
{
_cogl_set_error (error, COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_UNSUPPORTED,
"Can't create offscreen framebuffer from "
"sliced texture");
g_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED,
"Can't create offscreen framebuffer from "
"sliced texture");
return FALSE;
}
@ -1069,7 +1067,7 @@ void
cogl_framebuffer_set_depth_texture_enabled (CoglFramebuffer *framebuffer,
gboolean enabled)
{
_COGL_RETURN_IF_FAIL (!framebuffer->allocated);
g_return_if_fail (!framebuffer->allocated);
framebuffer->config.depth_texture_enabled = enabled;
}
@ -1087,7 +1085,7 @@ cogl_framebuffer_get_depth_texture (CoglFramebuffer *framebuffer)
if (!cogl_framebuffer_allocate (framebuffer, NULL))
return NULL;
_COGL_RETURN_VAL_IF_FAIL (cogl_is_offscreen (framebuffer), NULL);
g_return_val_if_fail (cogl_is_offscreen (framebuffer), NULL);
return COGL_OFFSCREEN(framebuffer)->depth_texture;
}
@ -1104,7 +1102,7 @@ void
cogl_framebuffer_set_samples_per_pixel (CoglFramebuffer *framebuffer,
int samples_per_pixel)
{
_COGL_RETURN_IF_FAIL (!framebuffer->allocated);
g_return_if_fail (!framebuffer->allocated);
framebuffer->config.samples_per_pixel = samples_per_pixel;
}
@ -1158,7 +1156,7 @@ cogl_framebuffer_resolve_samples_region (CoglFramebuffer *framebuffer,
CoglContext *
cogl_framebuffer_get_context (CoglFramebuffer *framebuffer)
{
_COGL_RETURN_VAL_IF_FAIL (framebuffer != NULL, NULL);
g_return_val_if_fail (framebuffer != NULL, NULL);
return framebuffer->context;
}
@ -1212,7 +1210,7 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer,
y < framebuffer->clear_clip_y1)
{
uint8_t *pixel;
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
/* we currently only care about cases where the premultiplied or
* unpremultipled colors are equivalent... */
@ -1225,7 +1223,7 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer,
&ignore_error);
if (pixel == NULL)
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
return FALSE;
}
@ -1248,14 +1246,14 @@ _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
int y,
CoglReadPixelsFlags source,
CoglBitmap *bitmap,
CoglError **error)
GError **error)
{
CoglContext *ctx;
int width;
int height;
_COGL_RETURN_VAL_IF_FAIL (source & COGL_READ_PIXELS_COLOR_BUFFER, FALSE);
_COGL_RETURN_VAL_IF_FAIL (cogl_is_framebuffer (framebuffer), FALSE);
g_return_val_if_fail (source & COGL_READ_PIXELS_COLOR_BUFFER, FALSE);
g_return_val_if_fail (cogl_is_framebuffer (framebuffer), FALSE);
if (!cogl_framebuffer_allocate (framebuffer, error))
return FALSE;
@ -1299,13 +1297,12 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
CoglReadPixelsFlags source,
CoglBitmap *bitmap)
{
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
gboolean status =
_cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
x, y, source, bitmap,
&ignore_error);
if (!status)
cogl_error_free (ignore_error);
g_clear_error (&ignore_error);
return status;
}
@ -1355,16 +1352,16 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
{
CoglContext *ctx = src->context;
_COGL_RETURN_IF_FAIL (_cogl_has_private_feature
(ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
g_return_if_fail (_cogl_has_private_feature
(ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
/* We can only support blitting between offscreen buffers because
otherwise we would need to mirror the image and GLES2.0 doesn't
support this */
_COGL_RETURN_IF_FAIL (cogl_is_offscreen (src));
_COGL_RETURN_IF_FAIL (cogl_is_offscreen (dest));
g_return_if_fail (cogl_is_offscreen (src));
g_return_if_fail (cogl_is_offscreen (dest));
/* The buffers must be the same format */
_COGL_RETURN_IF_FAIL (src->internal_format == dest->internal_format);
g_return_if_fail (src->internal_format == dest->internal_format);
/* Make sure the current framebuffers are bound. We explicitly avoid
flushing the clip state so we can bind our own empty state */
@ -1399,7 +1396,7 @@ cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer,
{
CoglContext *ctx = framebuffer->context;
_COGL_RETURN_IF_FAIL (buffers & COGL_BUFFER_BIT_COLOR);
g_return_if_fail (buffers & COGL_BUFFER_BIT_COLOR);
ctx->driver_vtable->framebuffer_discard_buffers (framebuffer, buffers);
}

View File

@ -106,7 +106,7 @@ GType cogl_framebuffer_get_gtype (void);
/**
* cogl_framebuffer_allocate:
* @framebuffer: A #CoglFramebuffer
* @error: A pointer to a #CoglError for returning exceptions.
* @error: A pointer to a #GError for returning exceptions.
*
* Explicitly allocates a configured #CoglFramebuffer allowing developers to
* check and handle any errors that might arise from an unsupported
@ -125,7 +125,7 @@ GType cogl_framebuffer_get_gtype (void);
*/
gboolean
cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
CoglError **error);
GError **error);
/**
* cogl_framebuffer_get_width:

View File

@ -48,7 +48,6 @@
#include "cogl-swap-chain-private.h"
#include "cogl-texture-2d-gl.h"
#include "cogl-texture-2d-private.h"
#include "cogl-error-private.h"
#include "cogl-gtype-private.h"
#include "driver/gl/cogl-framebuffer-gl-private.h"
#include "driver/gl/cogl-pipeline-opengl-private.h"
@ -159,10 +158,10 @@ replace_token (char *string,
/* NOTE: this assumes token and replacement are the same length */
while ((token_pos = _cogl_util_memmem (last_pos,
end - last_pos,
token,
token_length)))
while ((token_pos = memmem (last_pos,
end - last_pos,
token,
token_length)))
{
/* Make sure this isn't in the middle of some longer token */
if ((token_pos <= string ||
@ -908,10 +907,10 @@ gl_get_shader_source_wrapper (GLuint shader,
/* Strip out the wrapper snippet we added when the source was
* specified */
wrapper_start = _cogl_util_memmem (source,
copy_length,
wrapper_marker,
sizeof (wrapper_marker) - 1);
wrapper_start = memmem (source,
copy_length,
wrapper_marker,
sizeof (wrapper_marker) - 1);
if (wrapper_start)
{
length = wrapper_start - source;
@ -1566,16 +1565,16 @@ free_texture_object_data (CoglGLES2TextureObjectData *data)
}
CoglGLES2Context *
cogl_gles2_context_new (CoglContext *ctx, CoglError **error)
cogl_gles2_context_new (CoglContext *ctx, GError **error)
{
CoglGLES2Context *gles2_ctx;
const CoglWinsysVtable *winsys;
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_GLES2_CONTEXT))
{
_cogl_set_error (error, COGL_GLES2_CONTEXT_ERROR,
COGL_GLES2_CONTEXT_ERROR_UNSUPPORTED,
"Backend doesn't support creating GLES2 contexts");
g_set_error_literal (error, COGL_GLES2_CONTEXT_ERROR,
COGL_GLES2_CONTEXT_ERROR_UNSUPPORTED,
"Backend doesn't support creating GLES2 contexts");
return NULL;
}
@ -1693,11 +1692,11 @@ cogl_gles2_context_get_vtable (CoglGLES2Context *gles2_ctx)
static CoglGLES2Offscreen *
_cogl_gles2_offscreen_allocate (CoglOffscreen *offscreen,
CoglGLES2Context *gles2_context,
CoglError **error)
GError **error)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen);
const CoglWinsysVtable *winsys;
CoglError *internal_error = NULL;
GError *internal_error = NULL;
CoglGLES2Offscreen *gles2_offscreen;
int level_width;
int level_height;
@ -1722,10 +1721,10 @@ _cogl_gles2_offscreen_allocate (CoglOffscreen *offscreen,
{
winsys->restore_context (framebuffer->context);
cogl_error_free (internal_error);
_cogl_set_error (error, COGL_FRAMEBUFFER_ERROR,
COGL_FRAMEBUFFER_ERROR_ALLOCATE,
"Failed to bind gles2 context to create framebuffer");
g_error_free (internal_error);
g_set_error_literal (error, COGL_FRAMEBUFFER_ERROR,
COGL_FRAMEBUFFER_ERROR_ALLOCATE,
"Failed to bind gles2 context to create framebuffer");
return NULL;
}
@ -1751,9 +1750,9 @@ _cogl_gles2_offscreen_allocate (CoglOffscreen *offscreen,
g_slice_free (CoglGLES2Offscreen, gles2_offscreen);
_cogl_set_error (error, COGL_FRAMEBUFFER_ERROR,
COGL_FRAMEBUFFER_ERROR_ALLOCATE,
"Failed to create an OpenGL framebuffer object");
g_set_error_literal (error, COGL_FRAMEBUFFER_ERROR,
COGL_FRAMEBUFFER_ERROR_ALLOCATE,
"Failed to create an OpenGL framebuffer object");
return NULL;
}
@ -1781,12 +1780,12 @@ cogl_push_gles2_context (CoglContext *ctx,
CoglGLES2Context *gles2_ctx,
CoglFramebuffer *read_buffer,
CoglFramebuffer *write_buffer,
CoglError **error)
GError **error)
{
const CoglWinsysVtable *winsys = ctx->display->renderer->winsys_vtable;
CoglError *internal_error = NULL;
GError *internal_error = NULL;
_COGL_RETURN_VAL_IF_FAIL (gles2_ctx != NULL, FALSE);
g_return_val_if_fail (gles2_ctx != NULL, FALSE);
/* The read/write buffers are properties of the gles2 context and we
* don't currently track the read/write buffers as part of the stack
@ -1863,10 +1862,10 @@ cogl_push_gles2_context (CoglContext *ctx,
{
winsys->restore_context (ctx);
cogl_error_free (internal_error);
_cogl_set_error (error, COGL_GLES2_CONTEXT_ERROR,
COGL_GLES2_CONTEXT_ERROR_DRIVER,
"Driver failed to make GLES2 context current");
g_error_free (internal_error);
g_set_error_literal (error, COGL_GLES2_CONTEXT_ERROR,
COGL_GLES2_CONTEXT_ERROR_DRIVER,
"Driver failed to make GLES2 context current");
return FALSE;
}
@ -1923,7 +1922,7 @@ cogl_pop_gles2_context (CoglContext *ctx)
CoglGLES2Context *gles2_ctx;
const CoglWinsysVtable *winsys = ctx->display->renderer->winsys_vtable;
_COGL_RETURN_IF_FAIL (ctx->gles2_context_stack.length > 0);
g_return_if_fail (ctx->gles2_context_stack.length > 0);
g_queue_pop_tail (&ctx->gles2_context_stack);

View File

@ -189,7 +189,7 @@ typedef enum /*< prefix=COGL_GLES2_CONTEXT_ERROR >*/
/**
* cogl_gles2_context_new:
* @ctx: A #CoglContext
* @error: A pointer to a #CoglError for returning exceptions
* @error: A pointer to a #GError for returning exceptions
*
* Allocates a new OpenGLES 2.0 context that can be used to render to
* #CoglOffscreen framebuffers (Rendering to #CoglOnscreen
@ -216,7 +216,7 @@ typedef enum /*< prefix=COGL_GLES2_CONTEXT_ERROR >*/
* Stability: unstable
*/
CoglGLES2Context *
cogl_gles2_context_new (CoglContext *ctx, CoglError **error);
cogl_gles2_context_new (CoglContext *ctx, GError **error);
/**
* cogl_gles2_context_get_vtable:
@ -248,7 +248,7 @@ cogl_gles2_context_get_vtable (CoglGLES2Context *gles2_ctx);
* @write_buffer: A #CoglFramebuffer to access for drawing operations
* such as glDrawArrays. (must be a #CoglOffscreen
* framebuffer currently)
* @error: A pointer to a #CoglError for returning exceptions
* @error: A pointer to a #GError for returning exceptions
*
* Pushes the given @gles2_ctx onto a stack associated with @ctx so
* that the OpenGLES 2.0 api can be used instead of the Cogl
@ -272,7 +272,7 @@ cogl_push_gles2_context (CoglContext *ctx,
CoglGLES2Context *gles2_ctx,
CoglFramebuffer *read_buffer,
CoglFramebuffer *write_buffer,
CoglError **error);
GError **error);
/**
* cogl_pop_gles2_context:

View File

@ -91,7 +91,7 @@ cogl_indices_new (CoglContext *context,
CoglIndexBuffer *index_buffer = cogl_index_buffer_new (context, buffer_bytes);
CoglBuffer *buffer = COGL_BUFFER (index_buffer);
CoglIndices *indices;
CoglError *ignore_error = NULL;
GError *ignore_error = NULL;
_cogl_buffer_set_data (buffer,
0,
@ -100,7 +100,7 @@ cogl_indices_new (CoglContext *context,
&ignore_error);
if (ignore_error)
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
cogl_object_unref (index_buffer);
return NULL;
}
@ -120,15 +120,15 @@ cogl_indices_get_buffer (CoglIndices *indices)
CoglIndicesType
cogl_indices_get_type (CoglIndices *indices)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices),
COGL_INDICES_TYPE_UNSIGNED_BYTE);
g_return_val_if_fail (cogl_is_indices (indices),
COGL_INDICES_TYPE_UNSIGNED_BYTE);
return indices->type;
}
size_t
cogl_indices_get_offset (CoglIndices *indices)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices), 0);
g_return_val_if_fail (cogl_is_indices (indices), 0);
return indices->offset;
}
@ -149,7 +149,7 @@ void
cogl_indices_set_offset (CoglIndices *indices,
size_t offset)
{
_COGL_RETURN_IF_FAIL (cogl_is_indices (indices));
g_return_if_fail (cogl_is_indices (indices));
if (G_UNLIKELY (indices->immutable_ref))
warn_about_midscene_changes ();
@ -167,7 +167,7 @@ _cogl_indices_free (CoglIndices *indices)
CoglIndices *
_cogl_indices_immutable_ref (CoglIndices *indices)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices), NULL);
g_return_val_if_fail (cogl_is_indices (indices), NULL);
indices->immutable_ref++;
_cogl_buffer_immutable_ref (COGL_BUFFER (indices->buffer));
@ -177,8 +177,8 @@ _cogl_indices_immutable_ref (CoglIndices *indices)
void
_cogl_indices_immutable_unref (CoglIndices *indices)
{
_COGL_RETURN_IF_FAIL (cogl_is_indices (indices));
_COGL_RETURN_IF_FAIL (indices->immutable_ref > 0);
g_return_if_fail (cogl_is_indices (indices));
g_return_if_fail (indices->immutable_ref > 0);
indices->immutable_ref--;
_cogl_buffer_immutable_unref (COGL_BUFFER (indices->buffer));

View File

@ -1786,7 +1786,7 @@ _cogl_journal_try_read_pixel (CoglJournal *journal,
float poly[16];
CoglFramebuffer *framebuffer = journal->framebuffer;
uint8_t *pixel;
CoglError *ignore_error;
GError *ignore_error;
entry_to_screen_polygon (framebuffer, entry, vertices, poly);
@ -1831,7 +1831,7 @@ _cogl_journal_try_read_pixel (CoglJournal *journal,
&ignore_error);
if (pixel == NULL)
{
cogl_error_free (ignore_error);
g_error_free (ignore_error);
return FALSE;
}

View File

@ -396,10 +396,10 @@ cogl_matrix_stack_pop (CoglMatrixStack *stack)
CoglMatrixEntry *old_top;
CoglMatrixEntry *new_top;
_COGL_RETURN_IF_FAIL (stack != NULL);
g_return_if_fail (stack != NULL);
old_top = stack->last_entry;
_COGL_RETURN_IF_FAIL (old_top != NULL);
g_return_if_fail (old_top != NULL);
/* To pop we are moving the top of the stack to the old top's parent
* node. The stack always needs to have a reference to the top entry

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