Compare commits

...

131 Commits

Author SHA1 Message Date
8d75ea69e3 wayland: Use weak ref to keep track of buffers
Instead of using a one-shot signal meant to happen then the buffer
is being destroyed.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:10 +02:00
a7ee7559e4 compositor: Use redraw clip region to cull out children
This will avoid repainting too much of the background if the
bounding box turned out to be too large.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:10 +02:00
af3475f65f ClutterStage: Store clip area as a region
This will allow drawing optimizations as a region is more concrete
than the bounding rectangle.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:10 +02:00
77fd682c8b ClutterActor: Preserve valid paint volumes till the next relayout/repaint
Cuts down approximately 55% of paint volumes calculation when there's
windows that redraw frequently, but don't move.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:10 +02:00
fa8e4f60f6 compositor: Ensure to clip partial shadow redraws
Otherwise we end up drawing too far outside the clip area, which
brings in artifacts now that we have tighter regions instead of
an overlapping rect.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:10 +02:00
b98a8d9932 clutter: Avoid rounding compensation when invalidating 2D actors
This allows the redraw clip to be more constrained, so MetaCullable doesn't
end up rendering portions of window shadows, frame and background when a
window invalidates (part of) its contents.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:10 +02:00
864bc793aa cogl: Ensure to only clear the depth buffer if depth testing is enabled
The depth buffer is marked as invalid when 1) the framebuffer is just created,
and 2) whenever GL_DEPTH_TEST is enabled on it. This will ensure the
framebuffers attached depth buffer (if any) is properly cleared before it's
actually used, while saving needless clears while depth testing is disabled
(the default).

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:10 +02:00
e5b06754e0 compositor: Remove MetaSurfaceActor::repaint-scheduled signal
It's unused now.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:09 +02:00
3402c50625 compositor: Use queue_redraw vmethod over repaint-scheduled signal
https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:09 +02:00
060543466c compositor: Avoid changing pipeline/source if shadow is not being painted
Avoids some context invalidations in cogl.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:09 +02:00
65e816908a clutter: Add ClutterPaintVolume argument to ClutterActor::queue_redraw
This is an ABI break, hopefully an unimportant one since this signal/vmethod
is barely overridden.

The signal has been added an extra ClutterPaintVolume argument, and has been
given a boolean return value. The recursion to the parents has been taken
out of the default implementation and into the caller, using the returned
boolean parameter to control further propagation.

Passing the ClutterPaintVolume is easier on performance, as we don't need
setting this pointer as gobject data just to retrieve/unset it further
in propagation.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:43:09 +02:00
27b949d6ba compositor: Remove MetaSurfaceActorWayland::painting signal
It's now unused.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:27:11 +02:00
27ea62a79d wayland: Use notify::allocation to update pointer as per confinements
There is no need to constraint the pointer to the confinement on each redraw
if the surface actor didn't move/resize.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:27:11 +02:00
cf1edff9ed wayland: Use notify::allocation notification to update surface outputs
Instead of updating the surface outputs on each actor ::paint.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:27:11 +02:00
5cb5baa7d4 ClutterActor: Optimize away idempotent scale/position updates
If the actor results in the same scale/position, there's no need to
trigger a transition.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:27:11 +02:00
d620189ae3 ClutterActor: Call queue_redraw vfunc directly if possible
Reduces some signal emission overhead.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:27:11 +02:00
bc041e02b3 cogl: Mark vertex buffers as dynamic
Those are cached and reused across runs, which doesn't qualify to mesa
as "static" indeed. Properly marking those as dynamic is more true, and
brings in slight performance benefits just by avoiding the resulting
(and later silenced) mesa warning.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:27:11 +02:00
4b4c2b1afa ClutterActor: Avoid frequent signal emission if possible
Avoid signal emission for ::paint/::pick if no handlers are connected,
which is the most frequent case.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-22 17:27:11 +02:00
05d15f8885 window/wayland: Don't try to resize window on tear down
When terminating mutter running as a display server, don't try to resize
maximized windows when unmanaging, as at this point, they will have no
MetaWaylandSurface. Originally this was done instead of setting the
net_wm_state to not mess with future window managers, but when we're a
Wayland compositor, this does not matter.

https://bugzilla.gnome.org/show_bug.cgi?id=782156
2017-05-22 21:17:39 +08:00
561d71b8ae wayland: place window if maximized before placement
If a client changes the state of a surface to issue a set_maximize, this
causes apply_pending_state() to be called before mutter has placed the
window.

If the monitor on which the window is to be shown initially is different
from the one where the pointer is placed, this causes the effect to be
played at the wrong location before the window eventually reaches its
location on another monitor.

Force the window to be placed prior to change its state to maximized in
xdg-shell so that mutter won't relocate the window afterwards.

This also avoids sending an xdg_toplevel.configure with a size of 0x0
which would cause the client to initially draw its surface with some
arbitrary size.

https://bugzilla.gnome.org/show_bug.cgi?id=782183
https://bugzilla.gnome.org/show_bug.cgi?id=781353
2017-05-22 09:22:11 +02:00
177e47952a configure.ac: explicitly set link_all_deplibs=yes
Some distros such as Ubuntu and Debian set it to 'no',
while others might keep it to 'unknown' (which defaults to
'yes'). And this causes troubles when linking with mutter-clutter
in some tests.

https://bugzilla.gnome.org/show_bug.cgi?id=782821
2017-05-22 06:14:25 +00:00
374bb630f0 cogl: Use pixel_format_to_gl_with_target in find_best_gl_get_data_format
Fixes cogl_texture_get_data() resorting to the wrong conversions when
extracting the texture data. This notably resulted in RGB/RGBA buffers
copied as-is into BGRA buffers, for instance for the fullscreen animation,
or single-window screenshots of such buffers.

https://bugzilla.gnome.org/show_bug.cgi?id=779234
2017-05-18 23:32:39 +02:00
fe5138dfc4 core: Replace close dialog implementation with MetaCloseDialog
src/core/delete.c now entirely relies on MetaCloseDialog in order
to handle the "Application is not responding" dialog.

https://bugzilla.gnome.org/show_bug.cgi?id=711619
2017-05-15 15:09:15 +02:00
68a9675d42 compositor: Expose MetaPlugin vmethod to create a MetaCloseDialog
So the actual close dialog can be overridden by MetaPlugin implementations.

https://bugzilla.gnome.org/show_bug.cgi?id=711619
2017-05-15 15:09:15 +02:00
020e0bb2ac core: Implement MetaCloseDialogDefault
This is basically a copy of the implementation currently residing
in src/core/delete.c, which will be eventually deleted in favor
of this one.

https://bugzilla.gnome.org/show_bug.cgi?id=711619
2017-05-15 15:09:15 +02:00
b47de58edd core: Add MetaCloseDialog
This is an interface that can be used to implement the "application
is not responding" dialog. One instance is created per window, which
is initially hidden, and can be shown/hidden on demand.

https://bugzilla.gnome.org/show_bug.cgi?id=711619
2017-05-15 15:09:15 +02:00
24195d8d15 Update Hungarian translation 2017-05-14 19:37:49 +00:00
3a7c37c60a Update Turkish translation 2017-05-14 09:49:41 +00:00
c69d5d978c Update German translation 2017-05-12 15:36:19 +00:00
2f30098ab5 build: Fix non-wayland builds
Add the necessary preprocessor guards that were missed in commits
65e9c89ed9 and 6d64123849 ...

https://bugzilla.gnome.org/show_bug.cgi?id=780533
2017-05-11 13:45:44 +02:00
e146428038 Fix bashism in autogen.sh
https://bugzilla.gnome.org/show_bug.cgi?id=780215
2017-05-11 13:45:44 +02:00
5758401443 xwayland: Use the right atom type for further selection requests to X11
If we translate between text/plain;charset-utf-8 from the wayland side to
UTF8_STRING on the X11 side, we want to continue all further X11 selection
requests using the same translated UTF8_STRING atom than we use in the
first XConvertSelection call.

https://bugzilla.gnome.org/show_bug.cgi?id=782472
2017-05-10 21:00:37 +02:00
f241bdba93 wayland: Apply size hints regardless of geometry
Previously we would bail out early in xdg_toplevel_role_commit() if no
geometry change was set, ignoring the possible min/max size hints
changes.

But setting a min/max size hint without changing the geometry is
perfectly valid, so we ought to apply the min/max changes regardless of
a geometry change.

https://bugzilla.gnome.org/show_bug.cgi?id=782213
2017-05-10 10:44:42 +02:00
410d66ca37 wayland: Make sure we have a pending geometry
If the client doesn't set a geometry using xdg_shell, we'll compute its
geometry based on its surface and subsurfaces.

Yet, we translate that as a window (re)size only when there is a pending
geometry, that we don't have when we computed the geometry by ourself.

Make sure we set the pending new geometry flag when computing the
geometry when it actually changed.

https://bugzilla.gnome.org/show_bug.cgi?id=782213
2017-05-10 10:44:37 +02:00
f2309cdb55 backends: Store MUTTER_STAGE_VIEWS envvar content just once
No need to poke this regularly while drawing the stage.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-09 11:53:46 +02:00
3887d25dbc ClutterStage: Use non-generic marshaller for ::presented signal
This signal runs often, so it's better to use a direct marshaler.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-09 11:53:27 +02:00
d6d01c85a6 wayland: Collect frame completion time once for all surfaces
Dispatch all surface frames with the same monotonic time to avoid
querying it too often.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-09 11:53:14 +02:00
d0bfb94ff0 backends/native: Avoid generic closure marshaler for page flip handling
This turns out more expensive than necessary.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-05-09 11:52:57 +02:00
2b1537cdf5 Update Catalan translation 2017-05-05 22:12:38 +02:00
d3362a6f05 clutter: conform/actor-graph: Add missing null-termination
https://bugzilla.gnome.org/show_bug.cgi?id=759085
2017-05-05 09:53:51 -04:00
9cf8aa4584 cally: Fix compilation without X11 backend
Commit 0fd9e38175 fixed setting the out parameter for the x coordinate
when using the X11 backend, but broke compilation when the backend is
not available ...
Really fix the issue by running the X11-specific code when the X11
backend is available and in use, and display the one-time warning
otherwise.

https://bugzilla.gnome.org/show_bug.cgi?id=781902
2017-05-02 14:29:59 +02:00
c76eedd794 Typo fix: missing '\'
Without the backslash, the build breaks.
2017-04-30 15:05:52 +01:00
9131f26cae Generate marshallers without including the generated header
GLib now generates the prototypes for the generated marshallers, so it's
not necessary to include the header any more.

This fixes a build failure in GNOME Continuous with GLib master, caused
by -Werror=redundant-decls.
2017-04-30 14:56:29 +01:00
8ed0dda40d Update Friulian translation 2017-04-30 13:42:52 +00:00
0fd9e38175 cally: Fix translation to screen coordinates
Due to an accidental swap of an else statement and a preprocessor #else,
the output x coordinate is currently only set when not using the X11
windowing system, whoops.

https://bugzilla.gnome.org/show_bug.cgi?id=781902
2017-04-28 17:20:36 +02:00
891cab3bb3 window-props: Fix frame update on hide-titlebar-when-maximized changes
Since we started caching frame borders in commit b4036e061, we need to
invalidate the cache for changes of the GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED
property to take effect immediately.

https://bugzilla.gnome.org/show_bug.cgi?id=781862
2017-04-27 23:04:08 +02:00
454bd88d27 Bump version to 3.25.1
Update NEWS.
2017-04-27 17:46:16 +02:00
3ced749c89 Update Indonesian translation 2017-04-26 02:25:41 +00:00
69b6479502 Update Belarusian translation 2017-04-23 13:58:56 +00:00
a641b59f22 Update Friulian translation 2017-04-21 21:33:20 +00:00
704bd4c331 wayland/subsurface: Handle clients committing on destroyed subsurface
A client can still commit state to a destroyed subsurface. It wont
update anything on the screen, since the subsurface will not be
visible, but mutter should still handle it and not crash.

https://bugzilla.gnome.org/show_bug.cgi?id=781391
2017-04-21 17:46:17 +08:00
229ac9c9dc Consider the right CONTEXT_LOST token on OpenGL ES contexts
The KHR_robustness extension defined the following token as
returned by GetError (see spec at [1]):

  CONTEXT_LOST  0x0507

As noted in the spec, this token must have a "_KHR" suffix in
an OpenGL ES context, which is not being considered here, thus
making this type of builds fail.

[1] https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_robustness.txt

https://bugzilla.gnome.org/show_bug.cgi?id=781398
2017-04-17 12:58:52 +01:00
e435cf301f Define new tokens from the ARB_robustness extension if needed
The ARB_robustness extension defined the following tokens as
returned by GetGraphicsResetStatusARB (see spec at [1]):

  GUILTY_CONTEXT_RESET_ARB    0x8253
  INNOCENT_CONTEXT_RESET_ARB  0x8254
  UNKNOWN_CONTEXT_RESET_ARB   0x8255

These tokens might not be defined in some GL implementations,
such as Mesa 13's implementation of GLES 2.0, so we need to
define them ourselves not to break those builds.

[1] https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_robustness.txt

https://bugzilla.gnome.org/show_bug.cgi?id=781398
2017-04-17 12:58:52 +01:00
0608ae2d4e monitor-config-store: Replace key when replacing config
g_hash_table_insert() doesn't replace the key. This was a problem
because the key was owned by the value inserted into the hash table, so
when a value was removed, the key was freed, meaning that the key in
the hash table was no pointing to freed memory. Fix this by using
g_hash_table_replace() instead, which work the same except that it
replaces the key with the one passed. This means that the key of a
value in the hash table is always the key owned by the value.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-17 13:26:40 +08:00
3f107da479 monitor-config-manager: Handle comparing different sized config keys
The guard for handling size differences between keys were broken, it
only checked if the key passed by the second argument ended up being
shorter.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-17 13:26:40 +08:00
813de50eba Declare clutter version constants as extern
These constants got the CLUTTER_VAR annotations removed when making
it a private library, so the extern modifier needs to be explicitly added.
2017-04-13 13:08:22 +01:00
a4cb1f0f7a build: Require bash for pushd
If using sh, there's no pushd. Make autogen.sh execute with bash instead.

https://bugzilla.gnome.org/show_bug.cgi?id=781242
2017-04-13 10:12:18 +08:00
612432ac3e monitor-manager: Fix format-security gcc warnings 2017-04-12 16:53:30 +02:00
47a01013b1 clutter-color: Shut up a compiler warning 2017-04-07 23:19:22 +02:00
69e7ad4402 Use Unicode in a new translatable string
See https://developer.gnome.org/hig/stable/typography.html

https://bugzilla.gnome.org/show_bug.cgi?id=772218
2017-04-07 19:25:12 +02:00
c214eb15bf monitor-manager: Check active monitors when looking for logical monitor
An inactive monitor will not be assigned to a logical monitor, so don't
try to match against those. This avoids a dereferencing a NULL when the
main output of an inactive monitor doesn't have an assigned CRTC.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 23:53:51 +08:00
e6eac46629 backend: Get the UI scaling factor from the logical monitors
Instead of looking at the GTK+ settings, check the logical monitor
state and determine the UI scaling factor given the maximum logical
monitor scale. This is only enabled when the monitor config manager
feature is enabled, as only then can a scale be explicitly configured.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:51 +08:00
de61da16ae monitor-manager: Reconfigure when 'scale-monitor-framebuffer' is toggled
When the experimental feature 'scale-monitor-framebuffer' is enabled or
disabled, reconfigure the monitors.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:51 +08:00
bdcb395b33 DisplayConfig: Add 'supports-changing-layout-mode' property
This property may be used by a client to determine whether it is
allowed to change the layout mode.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:51 +08:00
1caa7f7627 monitor-manager: Add public API to get logical monitor from connector
This adds a function to be used by gnome-shell to get the logical
monitor given a connector name. For now, use the same index integer
method to reference a logical monitor, but this should be revisited by
providing a better API later.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:51 +08:00
5b4a96e3a3 monitor: Add API to get connector
The connector returned is the one of the main output. In other words,
for tiled monitors, it is the connector of the (0, 0) tile, and for
non-tiled, it is simply the connector of the output.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:51 +08:00
15dd23a323 monitor-manager: Fix gtk-doc of .._get_monitor_for_output
https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:51 +08:00
04d7fcf60d DisplayConfig: Add display-name monitor property
This is the same property as the one associated with an output in
GetResources.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
9755cd469c DisplayConfig: Make naming convention consistent
Always use hyphens as delimit words in property keys. Underscore to
delimit words in method arguments.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
1bdadfa3e1 backend: Add API to get UI scaling
The UI scaling depends on whether the framebuffers are scaled. Enable
the caller to determine the what scale its UI should be drawn in, in
relation to the stage coordinate space by calling this function. A new
singal "ui-scaling-factor-changed" is added in order to liston for for
changes.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
20fcb88632 clutter: Remove window scaling feature
Window scaling is a clutter feature used to enable automatic scaling of
stage windows when running under as an application in windowing system.
Clutter in mutter does not support running as a stand-alone application
toolkit, so lets remove this unused feature.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
6791d1b8e2 backend: Use g_signal_emit instead of g_signal_emit_by_name
No functional changes, just a minor cleanup.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
6c8b103a7b DisplayConfig: Add "is_builtin" monitor property
Add a per-monitor property allowing the application to determine
whether the monitor is builtin or not, e.g. a laptop panel.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
95d0117784 monitor-manager: Hook up config manager to display config confirmation
Make it possible to confirm or cancel the new configuration also when
the new API is used.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
740436ab4d monitor-config-store: Add support for saving configuration
When told to, MetaMonitorConfigStore will save the current
configuration state by replacing the monitors-experimental.xml file
(while backing a backup).

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
89fbf1e1d2 monitor-config-store: Read config file on startup
Read the file "monitors-experimental.xml" on startup and add parsed
configurations to the configuration store.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
c391cefd71 tests: Fix indentation
https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
52af529950 tests: Test non-native monitor transform
Test that configuration works as expected when the backend doesn't
support handling the transform and an intermediate offscreen
framebuffer is used.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
c30cb069f5 tests: Make it possible to emulate backend not supporting tranforms
https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
99a0b43f28 tests: Derive configuration when stage views is disabled
In order to test deriving the logical state from the underlying
configuration, as is always done on X11, make the test backend derive
the state when stage views are disabled.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
af4017de49 monitor-manager: Derive logical monitor position from top left CRTC
Derive the logical monitor position not by looking at the main output
(the (0, 0) tile), but the one that is placed on the top-left corner.
This might be the non-main output on certain transformations.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
d804ecbd95 monitor-config-manager: Only make output primary if logical monitor
Only the first output of the first monitor of the primary logical
monitor should be made primary. This fixes an issue where the wrong
logical monitor ended up as primary when the logical state was derived.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:50 +08:00
1ad3382bff tests: Test rotation of tiled monitors
https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
9787b1cfd5 backends/x11/nested: Emulate per CRTC drawing
Make the nested backend emulate how the real backends actually draw,
i.e. by drawing each CRTC separately. This makes it possible to test
different configuration paths that can take place on different
hardware, without having said hardware.

For example, by setting MUTTER_DEBUG_TILED_DUMMY_MONITORS and
MUTTER_DEBUG_NESTED_OFFSCREEN_TRANSFORM to "1", one can test a system
with MST (tiled) monitors where the GPU doesn't support some transform.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
0ac2eba4d3 DisplayConfig: Add logical monitor transforms
Add the transform as a logical monitor parameter, both when getting the
current state and applying a new configuration. The transform is defined
to be identical to MetaMonitorTransform.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
17c54c6e03 tests: Test that transforms are properly configured
https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
dd14e1cebc tests: Add monitor transform config parsing tests
https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
1e2266aa47 monitor-config-store: Add support for transform in config
Adds a <transform> element to <logicalmonitor>. It has two possible sub
elemenst: <rotation> which can be normal, right, left or upside_down,
and <flipped> which can either be true or false.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
472a434212 monitor-config-manager: Support logical monitor transforms
Add support for rotated monitors. This is done per logical monitor, as
every monitor assigned to a logical monitor must be transformed in the
same way. This includes being transformed on the same level; e.g. if
the backend does not support transforming any monitor of a logical
monitor natively, then all monitors will be transformed using the
offscreen intermediate framebuffer.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
7c226462e0 core: Mark meta_fatal() as not returning
This also makes meta_fatal() not returning, even if a NULL format is
passed.

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

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
93c6a869ec x11/nested: Always draw to an offscreen framebuffer
Always draw the stage to an offscreen framebuffer when using the nested
backend, so that we more emulate things more similarly to how it works
real-world, i.e. it'll work the way whether stage views are enabled or
not.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
9d914091f5 stage-x11-nested: Remove unused field
https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
afcc1bf512 monitor: Don't keep CRTC position in MetaMonitorCrtcMode
The CRTC position depends on the transform and how the transform is
implemented. The function calculating the positions still doesn't
support anything but the non-transformed case; this commit is in
preparation of adding support for transforms.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
8a29c51b73 renderer-view: Add view transform getter
This will later be used by the nested backend to emulate per CRTC
rendering.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
d38c4c1f2d logical-monitor: Track whether the logical monitor is transformed
Keep track of the logical monitor transform. When a logical monitor is
transformed, all of its monitors are also transformed in the same way.
A logical monitor can either be transformed on the CRTC level, or using
an offscreen intermediate buffer. In both cases will the logical
monitor be transformed, but only in the latter will the view be
transformed.

MetaCrtcs::transform currently does not represent whether the CRTC is
configured to be transformed or not; only when the backend can handle
it does it correctly correspond to the actual CRTC configuration. This
is intended to change with MetaMonitorConfigManager.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
2091df3856 renderer-x11: Split up into CM and Nested renderers
Split up the MetaRendererX11 class into one for when running as a
X11 compositing manager, and one for when running as a nested Wayland
compositor.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:49 +08:00
744b4dcb7c tests/monitor-unit-tests: Add tests for custom tiled monitor modes
https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
0c64c35a8a monitor-manager: Make the config manager an 'experimental feature'
Instead of using a environment variable, add a new 'experimental
feature' gsetting keyword "monitor-config-manager" that enables the use
of the new MetaMonitorConfigManager. This commit also makes it possible
to switch between the two systems without restarting mutter.

The D-Bus API is disabled when the experimental feature is not enabled,
and clients trying to access it will get a access-denied error in
response. A new property 'IsExperimentalApiEnabled' is added to let the
D-Bus client know whether it is possible to use the experimental API or
not.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
57acbc53fb legacy-monitor-config: Let the manager listen on lid closed changes
This is in preparation for making config-manager work alongside the
legacy configuration system.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
ac68631f4c monitor-config-store: Don't crash when cleaning up after failing to load
The logical monitor config array ownership was transferred to the
config object when it was created, but was not unset when the config
verification failed, causing the clean up path for invalid configs to
try to clean up the same list again.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
8163ca6821 Add support for scaled logical monitor framebuffers
This commit adds support for rendering onto enlarged per logical
monitor framebuffers, using the scaled clutter stage views, for HiDPI
enabled logical monitors.

This works by scaling the mode of the monitors in a logical monitors by
the scale, no longer relying on scaling the window actors and window
geometry for making windows have the correct size on HiDPI monitors.

It is disabled by default, as in automatically created configurations
will still use the old mode. This is partly because Xwayland clients
will not yet work good enough to make it feasible.

To enable, add the 'scale-monitor-framebuffer' keyword to the
org.gnome.mutter.experimental-features gsettings array.

It is still possible to specify the mode via the new D-Bus API, which
has been adapted.

The adaptations to the D-Bus API means the caller need to be aware of
how to position logical monitors on the stage grid. This depends on the
'layout-mode' property that is used (see the DisplayConfig D-Bus
documentation).

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
094e0356e8 backend: Add 'experimental-features' gsetting
This gsetting will allow the adding of keywords to a array, where each
keyword may enable an experimental feauter, if the given mutter version
supports that particular experimental feature. Emphasis is put on the
lack of guarantee that any such keyword has any effect. Currently no
keywords are defined.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
63450d69d3 clutter: Add ability to scale stage views
This commit adds the ability to set a scale on a scale view. This will
cause the content in the stage view to be painted with the given scale,
while still keeping the configured layout on the stage. In effect, for
a stage view with scale 'n', this means the framebuffer of a given stage
will 'n' times larger, keeping the same size on the stage.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
0952409de4 monitor-manager: Always set current config when apply succeeds
No reason making any caller do it.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
1c54c7a1bb window: Replace monitor scale getter with geometry scale
All places that get the 'main monitor scale' of a window really just
wants the window geometry scale, so call it that.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
f25f14351c monitor-manager: Make max screen size optional
Make the concept of maximum screen size optional, as it is not
necessarily a thing on all systems (e.g. when using the native backend
and stage views).

The meta_monitor_monitor_get_limits() function is replaced by a
meta_monitor_manager_get_max_screen_size() which fails when no screen
limit is available. Callers and other users of the previous max screen
size fields are updated to deal with the fact that the limit is
optional.

The new D-Bus API is changed to move it to the properties bag, where
its absence means there is no applicable limit.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
691e7951ea DisplayConfig: Add new API for configuring monitors
Add a new D-Bus API that uses the state from GetCurrentState to
configure high level monitors, instead of low level CRTCs and
connectors. So far persistent configuration is not implemented, as
writing to the configuration store is still not supported.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
7eaeba520a monitor-config-manager: Verify monitor modes in logical monitor config
Verify that each monitor in a logical monitor has the same dimensions,
i.e. that it they all fill out the same logical monitor space.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
9a5b94a340 monitor-manager: Use better error code when using the wrong API
It has nothing to do with permissions, so 'not-supported' is a bit
better.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
079b125430 DisplayConfig: Group logical monitor parameters a bit better
Move around the parameters, just to put the always-there fields before
the monitor array and property box.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
770a5a5bff DisplayConfig: Drop width/height from logical monitor
It is redundant, and either side still need to do the equivalent
calculations, so lets drop it.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:48 +08:00
0548c9e7d5 MetaMonitorConfig: Rename is_underscanning to enable_underscanning
Use better terminology to imply that the configuration enables
underscanning, not what already "is".

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
68a6cc5976 monitor-config-manager: Verify the layout origin is at (0, 0)
The extent of the layout regions must be a rectangle positioned at
(0, 0).

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
2035f2f2e2 monitor-config-manager: Verify that logical monitors are adjecent
Logical monitors in a configuration must be adjecent to each other,
meaning there will be at least one pixel long side touching some other
logical monitor.

The exception to this is when there is only one logical monitor, which
cannot be adjecent to any other.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
1892a6b0c4 monitor-config-store: Finish logical monitor before verifying
If we verify the logical monitor before completing it (calculating the
size), we can't check what the result of the completion.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
b464004bb3 monitor-config-store: Move config verification to config manager
This way we can re-use it for example when verifying configurations
from D-Bus.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
ea4438284f DisplayConfig: Add 'properties' to GetCurrentState
Adds compositor wide DisplayConfig properties bag, and add a
"supports-mirroring" property.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
d050fdb17f monitor-manager: Add per backend capabilities
Add a private API for querying backend capabilities. For now, only
mirroring capability is reported.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
9003a42df3 monitor-manager: Add supported scales to D-Bus API
Let the configuring client know what scales are supported by the
display server.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
9e8ee491e6 monitor-manager: Add API to get scales supported by the backend
For the Xrandr backend, only scale 1 is supported, for the others, 1
and 2 are reported as supported.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
3b46345db4 monitor-manager: Make scale floats in D-Bus API
We don't want to limit ourself to whole integers for configuration, as
that'd mean it wouldn't be able to provide configurations for
fractional scalings. Thus, change scales to be referred to as floats
instead of ints.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
6b2a111428 DisplayConfig: Add an optional 'is_underscanning' monitor property
Add a 'is_underscanning' entry to the properties map, if the monitor
supports underscanning. The client should assume a monitor does not
support underscanning if no property was added.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
bc56971e18 DisplayConfig: Add new API for getting current state
Add a D-Bus method for getting the current monitor and logical monitor
state. Currently does not contain information about transforms or any
limitations (such as limited CRTCs and cloning).

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
fcc0288f0c monitor-manager: Let the backends handle no configuration
Let the backends decide whether to just rebuild a derived state, or use
the NULL config to rebuild an empty logical state.

This also changes the expected screen size values of the no-outputs
test; as this case is actually handled now.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
4e03e89869 tests: Check that mirroring is configured properly
This test checks that mirroring works when using separate CRTCs. It
does not check cloning.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
4e17017501 monitor-unit-tests: Check custom tiled monitor config
https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
63bc86cd43 tests: Test configured custom logical monitor scale
Check that a configured logical monitor scale overrides any calculated
one.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:47 +08:00
ee32ca3efe monitor-store: Support configuring logical monitor scale
Add support to configure the logical monitor scale. With this, it
becomes possible to override the automatically calculated scaling
number per logical monitor.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:46 +08:00
a393a614a1 monitor-manager: Remove 'scale' from MetaOutput
Replace the 'scale' of an output with a vfunc on the MetaMonitorManager
class that takes a monitor and a monitor mode which calculates the
scale. On X11 this always returns 1, on KMS, the old formula is used.
On the dummy and test backends, the already configured values are
returned.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:46 +08:00
753e9c65a1 meta-monitor-config: Pass logical monitor scale via config
The default (calculated) scale is derived from the output, but
ultimately set via the monitor scale. This will enable config files to
override the scale. Yet to be done is handling when a scale is not
supported by a backend (i.e. the X11 backend).

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:46 +08:00
409c92a68f monitor-manager: Update the monitor mode state before the logical state
This means we can use up to date monitor mode data when generating the
logical state.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-04-07 22:30:46 +08:00
130 changed files with 8373 additions and 4703 deletions

21
NEWS
View File

@ -1,3 +1,24 @@
3.25.1
======
* Always sync window geometry on state changes [Jonas; #780292]
* Use EGL instead of GLX when drawing using GLES [Jonas; #771636]
* Fix HiDPI detection on vertical monitor layouts [Carlos; #777687]
* Get double-click timing from desktop mouse settings [Armin; #771576]
* Scale relative motion deltas with monitor scale [Jonas, Carlos; #778119]
* Use texture fallback when setting hardware cursor fails [Jente; #770020]
* Fix lock-up when using additional theme variants [Shantanu; #780254]
* Rework low-level monitor configuration [Jonas; #777732]
* Fix building with GLES2 instead of GL [Mario; #781398]
* Misc. bug fixes [Jonas, Piotr, Philip; #780304, #772218, #781242, #781391]
Contributors:
Jonas Ådahl, Philip Chimento, Piotr Drąg, Carlos Garnacho, Shantanu Goel,
Jente Hidskes, Armin Krezović, Rui Matos, Florian Müllner, Mario Sanchez Prada
Translations:
Yuras Shumovich [be], Yosef Or Boczko [he], Tom Tryfonidis [el],
Fabio Tomat [fur], Kukuh Syafaat [id]
3.24.0
======

View File

@ -6,7 +6,9 @@ test -z "$srcdir" && srcdir=.
REQUIRED_AUTOMAKE_VERSION=1.11
pushd $srcdir
olddir="$(pwd)"
cd "${srcdir}"
(test -f configure.ac \
&& test -d src) || {
@ -19,8 +21,8 @@ aclocal --install || exit 1
intltoolize --force --copy --automake || exit 1
autoreconf --verbose --force --install || exit 1
popd
cd "${olddir}"
if [ "$NOCONFIGURE" = "" ]; then
$srcdir/configure "$@" || exit 1
"${srcdir}/configure" "$@" || exit 1
fi

View File

@ -43,10 +43,9 @@ $(marshal_h): stamp-marshal
@true
$(marshal_c): $(marshal_h)
$(AM_V_GEN)(echo "#include \"$(marshal_h)\"" ; \
$(GLIB_GENMARSHAL) \
$(AM_V_GEN)$(GLIB_GENMARSHAL) \
--prefix=$(glib_marshal_prefix) \
--body \
$(marshal_list)) > xgen-mc \
&& cp xgen-mc $(marshal_c) \
$(marshal_list) > xgen-mc \
&& (cmp -s xgen-mc $(marshal_c) || cp -f xgen-mc $(marshal_c)) \
&& rm -f xgen-mc

View File

@ -781,7 +781,7 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
"position of the stage");
}
else
#else
#endif
{
static gboolean yet_warned = FALSE;
@ -793,7 +793,6 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
"atk_component_get_extents() with ATK_XY_SCREEN.");
}
}
#endif
if (xp)
*xp = x;

View File

@ -283,9 +283,6 @@ void _clutter_actor_queue_redraw_full
ClutterPaintVolume *volume,
ClutterEffect *effect);
ClutterPaintVolume * _clutter_actor_get_queue_redraw_clip (ClutterActor *self);
void _clutter_actor_set_queue_redraw_clip (ClutterActor *self,
ClutterPaintVolume *clip_volume);
void _clutter_actor_finish_queue_redraw (ClutterActor *self,
ClutterPaintVolume *clip);

View File

@ -840,6 +840,7 @@ struct _ClutterActorPrivate
guint needs_compute_expand : 1;
guint needs_x_expand : 1;
guint needs_y_expand : 1;
guint needs_paint_volume_update : 1;
};
enum
@ -2619,6 +2620,7 @@ clutter_actor_real_allocate (ClutterActor *self,
g_object_freeze_notify (G_OBJECT (self));
changed = clutter_actor_set_allocation_internal (self, box, flags);
priv->needs_paint_volume_update = changed;
/* we allocate our children before we notify changes in our geometry,
* so that people connecting to properties will be able to get valid
@ -2641,9 +2643,12 @@ clutter_actor_real_allocate (ClutterActor *self,
}
static void
_clutter_actor_signal_queue_redraw (ClutterActor *self,
ClutterActor *origin)
_clutter_actor_propagate_queue_redraw (ClutterActor *self,
ClutterActor *origin,
ClutterPaintVolume *pv)
{
gboolean stop = FALSE;
/* no point in queuing a redraw on a destroyed actor */
if (CLUTTER_ACTOR_IN_DESTRUCTION (self))
return;
@ -2652,19 +2657,33 @@ _clutter_actor_signal_queue_redraw (ClutterActor *self,
* the actor bas been cloned. In this case the clone will need to
* receive the signal so it can queue its own redraw.
*/
while (self)
{
_clutter_actor_queue_redraw_on_clones (self);
_clutter_actor_queue_redraw_on_clones (self);
/* calls klass->queue_redraw in default handler */
if (g_signal_has_handler_pending (self, actor_signals[QUEUE_REDRAW],
0, TRUE))
{
g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin, pv, &stop);
}
else
{
stop = CLUTTER_ACTOR_GET_CLASS (self)->queue_redraw (self, origin, pv);
}
/* calls klass->queue_redraw in default handler */
g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin);
if (stop)
break;
self = clutter_actor_get_parent (self);
}
}
static void
clutter_actor_real_queue_redraw (ClutterActor *self,
ClutterActor *origin)
static gboolean
clutter_actor_real_queue_redraw (ClutterActor *self,
ClutterActor *origin,
ClutterPaintVolume *paint_volume)
{
ClutterActor *parent;
CLUTTER_NOTE (PAINT, "Redraw queued on '%s' (from: '%s')",
_clutter_actor_get_debug_name (self),
origin != NULL ? _clutter_actor_get_debug_name (origin)
@ -2672,13 +2691,14 @@ clutter_actor_real_queue_redraw (ClutterActor *self,
/* no point in queuing a redraw on a destroyed actor */
if (CLUTTER_ACTOR_IN_DESTRUCTION (self))
return;
return TRUE;
/* If the queue redraw is coming from a child then the actor has
become dirty and any queued effect is no longer valid */
if (self != origin)
{
self->priv->is_dirty = TRUE;
self->priv->needs_paint_volume_update = TRUE;
self->priv->effect_to_redraw = NULL;
}
@ -2687,7 +2707,7 @@ clutter_actor_real_queue_redraw (ClutterActor *self,
* won't change so we don't have to propagate up the hierarchy.
*/
if (!CLUTTER_ACTOR_IS_VISIBLE (self))
return;
return TRUE;
/* Although we could determine here that a full stage redraw
* has already been queued and immediately bail out, we actually
@ -2701,7 +2721,7 @@ clutter_actor_real_queue_redraw (ClutterActor *self,
ClutterActor *stage = _clutter_actor_get_stage_internal (self);
if (stage != NULL &&
_clutter_stage_has_full_redraw_queued (CLUTTER_STAGE (stage)))
return;
return TRUE;
}
self->priv->propagated_one_redraw = TRUE;
@ -2709,12 +2729,7 @@ clutter_actor_real_queue_redraw (ClutterActor *self,
/* notify parents, if they are all visible eventually we'll
* queue redraw on the stage, which queues the redraw idle.
*/
parent = clutter_actor_get_parent (self);
if (parent != NULL)
{
/* this will go up recursively */
_clutter_actor_signal_queue_redraw (parent, origin);
}
return FALSE;
}
static void
@ -4015,7 +4030,11 @@ clutter_actor_continue_paint (ClutterActor *self)
clutter_paint_node_unref (dummy);
/* XXX:2.0 - Call the paint() virtual directly */
g_signal_emit (self, actor_signals[PAINT], 0);
if (g_signal_has_handler_pending (self, actor_signals[PAINT],
0, TRUE))
g_signal_emit (self, actor_signals[PAINT], 0);
else
CLUTTER_ACTOR_GET_CLASS (self)->paint (self);
}
else
{
@ -4029,7 +4048,11 @@ clutter_actor_continue_paint (ClutterActor *self)
*
* XXX:2.0 - Call the pick() virtual directly
*/
g_signal_emit (self, actor_signals[PICK], 0, &col);
if (g_signal_has_handler_pending (self, actor_signals[PICK],
0, TRUE))
g_signal_emit (self, actor_signals[PICK], 0, &col);
else
CLUTTER_ACTOR_GET_CLASS (self)->pick (self, &col);
}
}
else
@ -4812,7 +4835,8 @@ clutter_actor_set_scale_factor (ClutterActor *self,
g_assert (pspec != NULL);
g_assert (scale_p != NULL);
_clutter_actor_create_transition (self, pspec, *scale_p, factor);
if (*scale_p != factor)
_clutter_actor_create_transition (self, pspec, *scale_p, factor);
}
static inline void
@ -7994,10 +8018,12 @@ clutter_actor_class_init (ClutterActorClass *klass)
G_SIGNAL_RUN_LAST |
G_SIGNAL_NO_HOOKS,
G_STRUCT_OFFSET (ClutterActorClass, queue_redraw),
NULL, NULL,
_clutter_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
CLUTTER_TYPE_ACTOR);
g_signal_accumulator_true_handled,
NULL,
_clutter_marshal_BOOLEAN__OBJECT_BOXED,
G_TYPE_BOOLEAN, 2,
CLUTTER_TYPE_ACTOR,
CLUTTER_TYPE_PAINT_VOLUME);
/**
* ClutterActor::queue-relayout:
@ -8502,6 +8528,7 @@ clutter_actor_init (ClutterActor *self)
priv->needs_width_request = TRUE;
priv->needs_height_request = TRUE;
priv->needs_allocation = TRUE;
priv->needs_paint_volume_update = TRUE;
priv->cached_width_age = 1;
priv->cached_height_age = 1;
@ -8595,8 +8622,7 @@ _clutter_actor_finish_queue_redraw (ClutterActor *self,
ClutterPaintVolume *clip)
{
ClutterActorPrivate *priv = self->priv;
ClutterPaintVolume *pv;
gboolean clipped;
ClutterPaintVolume *pv = NULL;
/* Remove queue entry early in the process, otherwise a new
queue_redraw() during signal handling could put back this
@ -8623,8 +8649,7 @@ _clutter_actor_finish_queue_redraw (ClutterActor *self,
*/
if (clip)
{
_clutter_actor_set_queue_redraw_clip (self, clip);
clipped = TRUE;
pv = clip;
}
else if (G_LIKELY (priv->last_paint_volume_valid))
{
@ -8634,36 +8659,12 @@ _clutter_actor_finish_queue_redraw (ClutterActor *self,
ClutterActor *stage = _clutter_actor_get_stage_internal (self);
/* make sure we redraw the actors old position... */
_clutter_actor_set_queue_redraw_clip (stage,
&priv->last_paint_volume);
_clutter_actor_signal_queue_redraw (stage, stage);
_clutter_actor_set_queue_redraw_clip (stage, NULL);
/* XXX: Ideally the redraw signal would take a clip volume
* argument, but that would be an ABI break. Until we can
* break the ABI we pass the argument out-of-band
*/
/* setup the clip for the actors new position... */
_clutter_actor_set_queue_redraw_clip (self, pv);
clipped = TRUE;
_clutter_actor_propagate_queue_redraw (stage, stage,
&priv->last_paint_volume);
}
else
clipped = FALSE;
}
else
clipped = FALSE;
_clutter_actor_signal_queue_redraw (self, self);
/* Just in case anyone is manually firing redraw signals without
* using the public queue_redraw() API we are careful to ensure that
* our out-of-band clip member is cleared before returning...
*
* Note: A NULL clip denotes a full-stage, un-clipped redraw
*/
if (G_LIKELY (clipped))
_clutter_actor_set_queue_redraw_clip (self, NULL);
_clutter_actor_propagate_queue_redraw (self, self, pv);
}
static void
@ -8824,8 +8825,7 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
{
/* NB: NULL denotes an undefined clip which will result in a
* full redraw... */
_clutter_actor_set_queue_redraw_clip (self, NULL);
_clutter_actor_signal_queue_redraw (self, self);
_clutter_actor_propagate_queue_redraw (self, self, NULL);
return;
}
@ -8899,6 +8899,7 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
}
priv->is_dirty = TRUE;
priv->needs_paint_volume_update = TRUE;
}
/**
@ -10247,9 +10248,10 @@ clutter_actor_set_position (ClutterActor *self,
cur_position.x = clutter_actor_get_x (self);
cur_position.y = clutter_actor_get_y (self);
_clutter_actor_create_transition (self, obj_props[PROP_POSITION],
&cur_position,
&new_position);
if (!clutter_point_equals (&cur_position, &new_position))
_clutter_actor_create_transition (self, obj_props[PROP_POSITION],
&cur_position,
&new_position);
}
/**
@ -12955,6 +12957,7 @@ clutter_actor_add_child_internal (ClutterActor *self,
child->priv->needs_width_request = TRUE;
child->priv->needs_height_request = TRUE;
child->priv->needs_allocation = TRUE;
child->priv->needs_paint_volume_update = TRUE;
/* we only queue a relayout here, because any possible
* redraw has already been queued either by show() or
@ -16632,26 +16635,6 @@ clutter_actor_has_pointer (ClutterActor *self)
return self->priv->has_pointer;
}
/* XXX: This is a workaround for not being able to break the ABI of
* the QUEUE_REDRAW signal. It is an out-of-band argument. See
* clutter_actor_queue_clipped_redraw() for details.
*/
ClutterPaintVolume *
_clutter_actor_get_queue_redraw_clip (ClutterActor *self)
{
return g_object_get_data (G_OBJECT (self),
"-clutter-actor-queue-redraw-clip");
}
void
_clutter_actor_set_queue_redraw_clip (ClutterActor *self,
ClutterPaintVolume *clip)
{
g_object_set_data (G_OBJECT (self),
"-clutter-actor-queue-redraw-clip",
clip);
}
/**
* clutter_actor_has_allocation:
* @self: a #ClutterActor
@ -17498,16 +17481,22 @@ _clutter_actor_get_paint_volume_mutable (ClutterActor *self)
priv = self->priv;
if (priv->paint_volume_valid)
clutter_paint_volume_free (&priv->paint_volume);
{
if (!priv->needs_paint_volume_update)
return &priv->paint_volume;
clutter_paint_volume_free (&priv->paint_volume);
}
if (_clutter_actor_get_paint_volume_real (self, &priv->paint_volume))
{
priv->paint_volume_valid = TRUE;
priv->needs_paint_volume_update = FALSE;
return &priv->paint_volume;
}
else
{
priv->paint_volume_valid = FALSE;
priv->needs_paint_volume_update = FALSE;
return NULL;
}
}

View File

@ -236,8 +236,9 @@ struct _ClutterActorClass
void (* pick) (ClutterActor *actor,
const ClutterColor *color);
void (* queue_redraw) (ClutterActor *actor,
ClutterActor *leaf_that_queued);
gboolean (* queue_redraw) (ClutterActor *actor,
ClutterActor *leaf_that_queued,
ClutterPaintVolume *paint_volume);
/* size negotiation */
void (* get_preferred_width) (ClutterActor *self,

View File

@ -76,9 +76,6 @@ struct _ClutterCanvasPrivate
gboolean dirty;
CoglBitmap *buffer;
int scale_factor;
guint scale_factor_set : 1;
};
enum
@ -87,8 +84,6 @@ enum
PROP_WIDTH,
PROP_HEIGHT,
PROP_SCALE_FACTOR,
PROP_SCALE_FACTOR_SET,
LAST_PROP
};
@ -185,11 +180,6 @@ clutter_canvas_set_property (GObject *gobject,
}
break;
case PROP_SCALE_FACTOR:
clutter_canvas_set_scale_factor (CLUTTER_CANVAS (gobject),
g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@ -214,17 +204,6 @@ clutter_canvas_get_property (GObject *gobject,
g_value_set_int (value, priv->height);
break;
case PROP_SCALE_FACTOR:
if (priv->scale_factor_set)
g_value_set_int (value, priv->scale_factor);
else
g_value_set_int (value, -1);
break;
case PROP_SCALE_FACTOR_SET:
g_value_set_boolean (value, priv->scale_factor_set);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@ -268,46 +247,6 @@ clutter_canvas_class_init (ClutterCanvasClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* ClutterCanvas:scale-factor-set:
*
* Whether the #ClutterCanvas:scale-factor property is set.
*
* If the #ClutterCanvas:scale-factor-set property is %FALSE
* then #ClutterCanvas will use the #ClutterSettings:window-scaling-factor
* property.
*
* Since: 1.18
*/
obj_props[PROP_SCALE_FACTOR_SET] =
g_param_spec_boolean ("scale-factor-set",
P_("Scale Factor Set"),
P_("Whether the scale-factor property is set"),
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* ClutterCanvas:scale-factor:
*
* The scaling factor to be applied to the Cairo surface used for
* drawing.
*
* If #ClutterCanvas:scale-factor is set to a negative value, the
* value of the #ClutterSettings:window-scaling-factor property is
* used instead.
*
* Use #ClutterCanvas:scale-factor-set to check if the scale factor
* is set.
*
* Since: 1.18
*/
obj_props[PROP_SCALE_FACTOR] =
g_param_spec_int ("scale-factor",
P_("Scale Factor"),
P_("The scaling factor for the surface"),
-1, 1000,
-1,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
/**
* ClutterCanvas::draw:
@ -354,7 +293,6 @@ clutter_canvas_init (ClutterCanvas *self)
self->priv->width = -1;
self->priv->height = -1;
self->priv->scale_factor = -1;
}
static void
@ -397,7 +335,6 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
gboolean mapped_buffer;
unsigned char *data;
CoglBuffer *buffer;
int window_scale = 1;
gboolean res;
cairo_t *cr;
@ -405,20 +342,11 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
priv->dirty = TRUE;
if (priv->scale_factor_set)
window_scale = priv->scale_factor;
else
g_object_get (clutter_settings_get_default (),
"window-scaling-factor", &window_scale,
NULL);
real_width = priv->width;
real_height = priv->height;
real_width = priv->width * window_scale;
real_height = priv->height * window_scale;
CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d (real: %d x %d, scale: %d)",
priv->width, priv->height,
real_width, real_height,
window_scale);
CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d",
priv->width, priv->height);
if (priv->buffer == NULL)
{
@ -461,8 +389,6 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
mapped_buffer = FALSE;
}
cairo_surface_set_device_scale (surface, window_scale, window_scale);
self->priv->cr = cr = cairo_create (surface);
g_signal_emit (self, canvas_signals[DRAW], 0,
@ -636,81 +562,3 @@ clutter_canvas_set_size (ClutterCanvas *canvas,
return clutter_canvas_invalidate_internal (canvas, width, height);
}
/**
* clutter_canvas_set_scale_factor:
* @canvas: a #ClutterCanvas
* @scale: the scale factor, or -1 for the default
*
* Sets the scaling factor for the Cairo surface used by @canvas.
*
* This function should rarely be used.
*
* The default scaling factor of a #ClutterCanvas content uses the
* #ClutterSettings:window-scaling-factor property, which is set by
* the windowing system. By using this function it is possible to
* override that setting.
*
* Changing the scale factor will invalidate the @canvas.
*
* Since: 1.18
*/
void
clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
int scale)
{
ClutterCanvasPrivate *priv;
GObject *obj;
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
g_return_if_fail (scale != 0);
priv = canvas->priv;
if (scale < 0)
{
if (!priv->scale_factor_set)
return;
priv->scale_factor_set = FALSE;
priv->scale_factor = -1;
}
else
{
if (priv->scale_factor_set && priv->scale_factor == scale)
return;
priv->scale_factor_set = TRUE;
priv->scale_factor = scale;
}
clutter_content_invalidate (CLUTTER_CONTENT (canvas));
obj = G_OBJECT (canvas);
g_object_notify_by_pspec (obj, obj_props[PROP_SCALE_FACTOR]);
g_object_notify_by_pspec (obj, obj_props[PROP_SCALE_FACTOR_SET]);
}
/**
* clutter_canvas_get_scale_factor:
* @canvas: a #ClutterCanvas
*
* Retrieves the scaling factor of @canvas, as set using
* clutter_canvas_set_scale_factor().
*
* Return value: the scaling factor, or -1 if the @canvas
* uses the default from #ClutterSettings
*
* Since: 1.18
*/
int
clutter_canvas_get_scale_factor (ClutterCanvas *canvas)
{
g_return_val_if_fail (CLUTTER_IS_CANVAS (canvas), -1);
if (!canvas->priv->scale_factor_set)
return -1;
return canvas->priv->scale_factor;
}

View File

@ -48,7 +48,7 @@
#include "clutter-debug.h"
/* XXX - keep in sync with the ClutterStaticColor enumeration order */
static const ClutterColor const static_colors[] = {
static const ClutterColor static_colors[] = {
/* CGA/EGA color palette */
{ 0xff, 0xff, 0xff, 0xff }, /* white */
{ 0x00, 0x00, 0x00, 0xff }, /* black */

View File

@ -1,6 +1,7 @@
BOOLEAN:BOXED
BOOLEAN:BOXED,INT,INT
BOOLEAN:OBJECT,BOOLEAN
BOOLEAN:OBJECT,BOXED
BOOLEAN:OBJECT,BOXED,DOUBLE
BOOLEAN:OBJECT,DOUBLE
BOOLEAN:OBJECT,ENUM
@ -17,6 +18,7 @@ VOID:BOXED,FLAGS
VOID:INT
VOID:INT64,INT64,FLOAT,BOOLEAN
VOID:INT,INT
VOID:INT,POINTER
VOID:FLOAT,FLOAT
VOID:INT,INT,INT,INT
VOID:OBJECT

View File

@ -1166,6 +1166,21 @@ _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv,
_clutter_paint_volume_get_bounding_box (&projected_pv, box);
if (pv->is_2d && pv->actor &&
clutter_actor_get_z_position (pv->actor) == 0)
{
/* If the volume/actor are perfectly 2D, take the bounding box as
* good. We won't need to add any extra room for sub-pixel positioning
* in this case.
*/
clutter_paint_volume_free (&projected_pv);
box->x1 = CLUTTER_NEARBYINT (box->x1);
box->y1 = CLUTTER_NEARBYINT (box->y1);
box->x2 = CLUTTER_NEARBYINT (box->x2);
box->y2 = CLUTTER_NEARBYINT (box->y2);
return;
}
/* The aim here is that for a given rectangle defined with floating point
* coordinates we want to determine a stable quantized size in pixels
* that doesn't vary due to the original box's sub-pixel position.

View File

@ -77,9 +77,7 @@ struct _ClutterSettings
guint password_hint_time;
gint window_scaling_factor;
gint unscaled_font_dpi;
guint fixed_scaling_factor : 1;
};
struct _ClutterSettingsClass
@ -112,7 +110,6 @@ enum
PROP_PASSWORD_HINT_TIME,
PROP_WINDOW_SCALING_FACTOR,
PROP_UNSCALED_FONT_DPI,
PROP_LAST
@ -355,14 +352,6 @@ clutter_settings_set_property (GObject *gobject,
self->password_hint_time = g_value_get_uint (value);
break;
case PROP_WINDOW_SCALING_FACTOR:
if (!self->fixed_scaling_factor)
{
self->window_scaling_factor = g_value_get_int (value);
self->fixed_scaling_factor = TRUE;
}
break;
case PROP_UNSCALED_FONT_DPI:
self->font_dpi = g_value_get_int (value);
settings_update_resolution (self);
@ -382,14 +371,7 @@ clutter_settings_set_property_internal (ClutterSettings *self,
property = g_intern_string (property);
if (property == I_("window-scaling-factor") &&
self->fixed_scaling_factor)
return;
g_object_set_property (G_OBJECT (self), property, value);
if (property == I_("window-scaling-factor"))
self->fixed_scaling_factor = FALSE;
}
static void
@ -446,10 +428,6 @@ clutter_settings_get_property (GObject *gobject,
g_value_set_uint (value, self->password_hint_time);
break;
case PROP_WINDOW_SCALING_FACTOR:
g_value_set_int (value, self->window_scaling_factor);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@ -677,14 +655,6 @@ clutter_settings_class_init (ClutterSettingsClass *klass)
500,
CLUTTER_PARAM_READWRITE);
obj_props[PROP_WINDOW_SCALING_FACTOR] =
g_param_spec_int ("window-scaling-factor",
P_("Window Scaling Factor"),
P_("The scaling factor to be applied to windows"),
1, G_MAXINT,
1,
CLUTTER_PARAM_READWRITE);
obj_props[PROP_FONTCONFIG_TIMESTAMP] =
g_param_spec_uint ("fontconfig-timestamp",
P_("Fontconfig configuration timestamp"),
@ -722,8 +692,6 @@ clutter_settings_class_init (ClutterSettingsClass *klass)
static void
clutter_settings_init (ClutterSettings *self)
{
const char *scale_str;
self->resolution = -1.0;
self->font_dpi = -1;
@ -742,18 +710,6 @@ clutter_settings_init (ClutterSettings *self)
self->xft_rgba = NULL;
self->long_press_duration = 500;
/* if the scaling factor was set by the environment we ignore
* any explicit setting
*/
scale_str = g_getenv ("CLUTTER_SCALE");
if (scale_str != NULL)
{
self->window_scaling_factor = atol (scale_str);
self->fixed_scaling_factor = TRUE;
}
else
self->window_scaling_factor = 1;
}
/**

View File

@ -28,6 +28,7 @@ enum
PROP_LAYOUT,
PROP_FRAMEBUFFER,
PROP_OFFSCREEN,
PROP_SCALE,
PROP_LAST
};
@ -37,6 +38,7 @@ static GParamSpec *obj_props[PROP_LAST];
typedef struct _ClutterStageViewPrivate
{
cairo_rectangle_int_t layout;
int scale;
CoglFramebuffer *framebuffer;
CoglOffscreen *offscreen;
@ -141,6 +143,15 @@ clutter_stage_view_blit_offscreen (ClutterStageView *view,
cogl_framebuffer_pop_matrix (priv->framebuffer);
}
int
clutter_stage_view_get_scale (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
return priv->scale;
}
gboolean
clutter_stage_view_is_dirty_viewport (ClutterStageView *view)
{
@ -229,6 +240,9 @@ clutter_stage_view_get_property (GObject *object,
case PROP_OFFSCREEN:
g_value_set_boxed (value, priv->offscreen);
break;
case PROP_SCALE:
g_value_set_int (value, priv->scale);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@ -257,6 +271,9 @@ clutter_stage_view_set_property (GObject *object,
case PROP_OFFSCREEN:
priv->offscreen = g_value_dup_boxed (value);
break;
case PROP_SCALE:
priv->scale = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@ -284,6 +301,7 @@ clutter_stage_view_init (ClutterStageView *view)
priv->dirty_viewport = TRUE;
priv->dirty_projection = TRUE;
priv->scale = 1;
}
static void
@ -323,5 +341,13 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_SCALE] =
g_param_spec_int ("scale",
"View scale",
"The view scale",
1, G_MAXINT, 1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
}

View File

@ -60,6 +60,9 @@ void clutter_stage_view_transform_to_onscreen (ClutterStageView *vie
void clutter_stage_view_blit_offscreen (ClutterStageView *view,
const cairo_rectangle_int_t *clip);
CLUTTER_AVAILABLE_IN_MUTTER
int 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,

View File

@ -231,19 +231,35 @@ _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window)
return TRUE;
}
gboolean
_clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
cairo_rectangle_int_t *stage_clip)
cairo_region_t *
_clutter_stage_window_get_redraw_clip (ClutterStageWindow *window)
{
ClutterStageWindowIface *iface;
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->get_redraw_clip_bounds != NULL)
return iface->get_redraw_clip_bounds (window, stage_clip);
if (iface->get_redraw_clip != NULL)
return iface->get_redraw_clip (window);
return FALSE;
return NULL;
}
gboolean
_clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
cairo_rectangle_int_t *stage_clip)
{
cairo_region_t *redraw_clip;
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
redraw_clip = _clutter_stage_window_get_redraw_clip (window);
if (!redraw_clip)
return FALSE;
cairo_region_get_extents (redraw_clip, stage_clip);
cairo_region_destroy (redraw_clip);
return TRUE;
}
void
@ -303,33 +319,6 @@ _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window)
return FALSE;
}
void
_clutter_stage_window_set_scale_factor (ClutterStageWindow *window,
int factor)
{
ClutterStageWindowIface *iface;
g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->set_scale_factor != NULL)
iface->set_scale_factor (window, factor);
}
int
_clutter_stage_window_get_scale_factor (ClutterStageWindow *window)
{
ClutterStageWindowIface *iface;
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), 1);
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->get_scale_factor != NULL)
return iface->get_scale_factor (window);
return 1;
}
GList *
_clutter_stage_window_get_views (ClutterStageWindow *window)
{

View File

@ -68,9 +68,7 @@ struct _ClutterStageWindowIface
cairo_rectangle_int_t *stage_rectangle);
gboolean (* has_redraw_clips) (ClutterStageWindow *stage_window);
gboolean (* ignoring_redraw_clips) (ClutterStageWindow *stage_window);
gboolean (* get_redraw_clip_bounds) (ClutterStageWindow *stage_window,
cairo_rectangle_int_t *clip);
cairo_region_t * (* get_redraw_clip) (ClutterStageWindow *stage_window);
void (* set_accept_focus) (ClutterStageWindow *stage_window,
gboolean accept_focus);
@ -83,9 +81,6 @@ struct _ClutterStageWindowIface
gboolean (* can_clip_redraws) (ClutterStageWindow *stage_window);
void (* set_scale_factor) (ClutterStageWindow *stage_window,
int factor);
int (* get_scale_factor) (ClutterStageWindow *stage_window);
GList *(* get_views) (ClutterStageWindow *stage_window);
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
void (* finish_frame) (ClutterStageWindow *stage_window);
@ -128,6 +123,7 @@ gboolean _clutter_stage_window_has_redraw_clips (ClutterStageWin
gboolean _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window);
gboolean _clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
cairo_rectangle_int_t *clip);
cairo_region_t * _clutter_stage_window_get_redraw_clip (ClutterStageWindow *window);
void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
gboolean accept_focus);
@ -140,10 +136,6 @@ void _clutter_stage_window_get_dirty_pixel (ClutterStageWin
gboolean _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window);
void _clutter_stage_window_set_scale_factor (ClutterStageWindow *window,
int factor);
int _clutter_stage_window_get_scale_factor (ClutterStageWindow *window);
GList * _clutter_stage_window_get_views (ClutterStageWindow *window);
void _clutter_stage_window_finish_frame (ClutterStageWindow *window);

View File

@ -364,7 +364,6 @@ clutter_stage_allocate (ClutterActor *self,
float new_width, new_height;
float width, height;
cairo_rectangle_int_t window_size;
int scale_factor;
if (priv->impl == NULL)
return;
@ -465,11 +464,6 @@ clutter_stage_allocate (ClutterActor *self,
*/
_clutter_stage_window_get_geometry (priv->impl, &window_size);
scale_factor = _clutter_stage_window_get_scale_factor (priv->impl);
window_size.width *= scale_factor;
window_size.height *= scale_factor;
cogl_onscreen_clutter_backend_set_size (window_size.width,
window_size.height);
@ -630,15 +624,13 @@ clutter_stage_do_paint_view (ClutterStage *stage,
float clip_poly[8];
float viewport[4];
cairo_rectangle_int_t geom;
int window_scale;
_clutter_stage_window_get_geometry (priv->impl, &geom);
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
viewport[0] = priv->viewport[0] * window_scale;
viewport[1] = priv->viewport[1] * window_scale;
viewport[2] = priv->viewport[2] * window_scale;
viewport[3] = priv->viewport[3] * window_scale;
viewport[0] = priv->viewport[0];
viewport[1] = priv->viewport[1];
viewport[2] = priv->viewport[2];
viewport[3] = priv->viewport[3];
if (!clip)
{
@ -646,16 +638,14 @@ clutter_stage_do_paint_view (ClutterStage *stage,
clip = &view_layout;
}
clip_poly[0] = MAX (clip->x * window_scale, 0);
clip_poly[1] = MAX (clip->y * window_scale, 0);
clip_poly[0] = MAX (clip->x, 0);
clip_poly[1] = MAX (clip->y, 0);
clip_poly[2] = MIN ((clip->x + clip->width) * window_scale,
geom.width * window_scale);
clip_poly[2] = MIN (clip->x + clip->width, geom.width);
clip_poly[3] = clip_poly[1];
clip_poly[4] = clip_poly[2];
clip_poly[5] = MIN ((clip->y + clip->height) * window_scale,
geom.height * window_scale);
clip_poly[5] = MIN (clip->y + clip->height, geom.height);
clip_poly[6] = clip_poly[0];
clip_poly[7] = clip_poly[5];
@ -1209,45 +1199,44 @@ clutter_stage_real_queue_relayout (ClutterActor *self)
parent_class->queue_relayout (self);
}
static void
clutter_stage_real_queue_redraw (ClutterActor *actor,
ClutterActor *leaf)
static gboolean
clutter_stage_real_queue_redraw (ClutterActor *actor,
ClutterActor *leaf,
ClutterPaintVolume *redraw_clip)
{
ClutterStage *stage = CLUTTER_STAGE (actor);
ClutterStageWindow *stage_window;
ClutterPaintVolume *redraw_clip;
ClutterActorBox bounding_box;
ClutterActorBox intersection_box;
cairo_rectangle_int_t geom, stage_clip;
if (CLUTTER_ACTOR_IN_DESTRUCTION (actor))
return;
return TRUE;
/* If the backend can't do anything with redraw clips (e.g. it already knows
* it needs to redraw everything anyway) then don't spend time transforming
* any clip volume into stage coordinates... */
stage_window = _clutter_stage_get_window (stage);
if (stage_window == NULL)
return;
return TRUE;
if (_clutter_stage_window_ignoring_redraw_clips (stage_window))
{
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
return;
return FALSE;
}
/* Convert the clip volume into stage coordinates and then into an
* axis aligned stage coordinates bounding box...
*/
redraw_clip = _clutter_actor_get_queue_redraw_clip (leaf);
if (redraw_clip == NULL)
{
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
return;
return FALSE;
}
if (redraw_clip->is_empty)
return;
return TRUE;
_clutter_paint_volume_get_stage_paint_box (redraw_clip,
stage,
@ -1263,7 +1252,7 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
/* There is no need to track degenerate/empty redraw clips */
if (intersection_box.x2 <= intersection_box.x1 ||
intersection_box.y2 <= intersection_box.y1)
return;
return TRUE;
/* when converting to integer coordinates make sure we round the edges of the
* clip rectangle outwards... */
@ -1273,6 +1262,7 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
stage_clip.height = intersection_box.y2 - stage_clip.y;
_clutter_stage_window_add_redraw_clip (stage_window, &stage_clip);
return FALSE;
}
gboolean
@ -1325,6 +1315,31 @@ clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
}
}
cairo_region_t *
clutter_stage_get_redraw_clip (ClutterStage *stage)
{
ClutterStagePrivate *priv;
cairo_rectangle_int_t clip;
cairo_region_t *region;
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
priv = stage->priv;
region = _clutter_stage_window_get_redraw_clip (priv->impl);
if (region)
return region;
if (!region)
{
/* Set clip to the full extents of the stage */
_clutter_stage_window_get_geometry (priv->impl, &clip);
region = cairo_region_create_rectangle (&clip);
}
return region;
}
static void
read_pixels_to_file (char *filename_stem,
int x,
@ -1378,19 +1393,19 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
gint dirty_y;
gint read_x;
gint read_y;
int window_scale;
float fb_width, fb_height;
int fb_scale;
int viewport_offset_x;
int viewport_offset_y;
priv = stage->priv;
context = _clutter_context_get_default ();
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
fb_scale = clutter_stage_view_get_scale (view);
clutter_stage_view_get_layout (view, &view_layout);
fb_width = view_layout.width;
fb_height = view_layout.height;
fb_width = view_layout.width * fb_scale;
fb_height = view_layout.height * fb_scale;
cogl_push_framebuffer (fb);
/* needed for when a context switch happens */
@ -1400,38 +1415,38 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
* picking to not work at all, so setting it the whole framebuffer content
* for now. */
cogl_framebuffer_push_scissor_clip (fb, 0, 0,
view_layout.width,
view_layout.height);
view_layout.width * fb_scale,
view_layout.height * fb_scale);
_clutter_stage_window_get_dirty_pixel (priv->impl, view, &dirty_x, &dirty_y);
if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
{
CLUTTER_NOTE (PICK, "Pushing pick scissor clip x: %d, y: %d, 1x1",
dirty_x * window_scale,
dirty_y * window_scale);
cogl_framebuffer_push_scissor_clip (fb, dirty_x * window_scale, dirty_y * window_scale, 1, 1);
dirty_x * fb_scale,
dirty_y * fb_scale);
cogl_framebuffer_push_scissor_clip (fb, dirty_x * fb_scale, dirty_y * fb_scale, 1, 1);
}
viewport_offset_x = x * window_scale - dirty_x * window_scale;
viewport_offset_y = y * window_scale - dirty_y * window_scale;
viewport_offset_x = x * fb_scale - dirty_x * fb_scale;
viewport_offset_y = y * fb_scale - dirty_y * fb_scale;
CLUTTER_NOTE (PICK, "Setting viewport to %f, %f, %f, %f",
priv->viewport[0] * window_scale - viewport_offset_x,
priv->viewport[1] * window_scale - viewport_offset_y,
priv->viewport[2] * window_scale,
priv->viewport[3] * window_scale);
cogl_set_viewport (priv->viewport[0] * window_scale - viewport_offset_x,
priv->viewport[1] * window_scale - viewport_offset_y,
priv->viewport[2] * window_scale,
priv->viewport[3] * window_scale);
priv->viewport[0] * fb_scale - viewport_offset_x,
priv->viewport[1] * fb_scale - viewport_offset_y,
priv->viewport[2] * fb_scale,
priv->viewport[3] * fb_scale);
cogl_set_viewport (priv->viewport[0] * fb_scale - viewport_offset_x,
priv->viewport[1] * fb_scale - viewport_offset_y,
priv->viewport[2] * fb_scale,
priv->viewport[3] * fb_scale);
read_x = dirty_x * window_scale;
read_y = dirty_y * window_scale;
read_x = dirty_x * fb_scale;
read_y = dirty_y * fb_scale;
CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d",
CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d s: %d",
x, y,
view_layout.width, view_layout.height,
view_layout.x, view_layout.y);
view_layout.x, view_layout.y, fb_scale);
cogl_color_init_from_4ub (&stage_pick_id, 255, 255, 255, 255);
cogl_clear (&stage_pick_id, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH);
@ -2186,8 +2201,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
g_signal_new (I_("presented"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
0, NULL, NULL,
_clutter_marshal_VOID__INT_POINTER,
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_POINTER);
@ -2210,7 +2225,6 @@ clutter_stage_init (ClutterStage *self)
ClutterStagePrivate *priv;
ClutterStageWindow *impl;
ClutterBackend *backend;
int window_scale = 1;
GError *error;
/* a stage is a top-level object */
@ -2228,7 +2242,6 @@ clutter_stage_init (ClutterStage *self)
{
_clutter_stage_set_window (self, impl);
_clutter_stage_window_get_geometry (priv->impl, &geom);
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
}
else
{
@ -2282,8 +2295,8 @@ clutter_stage_init (ClutterStage *self)
priv->perspective.aspect,
priv->perspective.z_near,
50, /* distance to 2d plane */
geom.width * window_scale,
geom.height * window_scale);
geom.width,
geom.height);
/* FIXME - remove for 2.0 */
@ -3412,16 +3425,6 @@ clutter_stage_ensure_viewport (ClutterStage *stage)
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
}
static void
clutter_stage_apply_scale (ClutterStage *stage)
{
int factor;
factor = _clutter_stage_window_get_scale_factor (stage->priv->impl);
if (factor != 1)
cogl_matrix_scale (&stage->priv->view, factor, factor, 1.f);
}
# define _DEG_TO_RAD(d) ((d) * ((float) G_PI / 180.0f))
/* This calculates a distance into the view frustum to position the
@ -3568,7 +3571,7 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
{
cairo_rectangle_int_t view_layout;
ClutterPerspective perspective;
int window_scale;
int fb_scale;
int viewport_offset_x;
int viewport_offset_y;
float z_2d;
@ -3578,15 +3581,15 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
priv->viewport[2],
priv->viewport[3]);
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
fb_scale = clutter_stage_view_get_scale (view);
clutter_stage_view_get_layout (view, &view_layout);
viewport_offset_x = view_layout.x * window_scale;
viewport_offset_y = view_layout.y * window_scale;
cogl_set_viewport (priv->viewport[0] * window_scale - viewport_offset_x,
priv->viewport[1] * window_scale - viewport_offset_y,
priv->viewport[2] * window_scale,
priv->viewport[3] * window_scale);
viewport_offset_x = view_layout.x * fb_scale;
viewport_offset_y = view_layout.y * fb_scale;
cogl_set_viewport (priv->viewport[0] * fb_scale - viewport_offset_x,
priv->viewport[1] * fb_scale - viewport_offset_y,
priv->viewport[2] * fb_scale,
priv->viewport[3] * fb_scale);
perspective = priv->perspective;
@ -3617,10 +3620,8 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
perspective.aspect,
perspective.z_near,
z_2d,
priv->viewport[2] * window_scale,
priv->viewport[3] * window_scale);
clutter_stage_apply_scale (stage);
priv->viewport[2],
priv->viewport[3]);
clutter_stage_view_set_dirty_viewport (view, FALSE);
}
@ -4635,23 +4636,6 @@ clutter_stage_skip_sync_delay (ClutterStage *stage)
_clutter_stage_window_schedule_update (stage_window, -1);
}
void
_clutter_stage_set_scale_factor (ClutterStage *stage,
int factor)
{
ClutterStagePrivate *priv = stage->priv;
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return;
if (priv->impl == NULL)
return;
_clutter_stage_window_set_scale_factor (priv->impl, factor);
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
}
int64_t
clutter_stage_get_frame_counter (ClutterStage *stage)
{

View File

@ -245,6 +245,9 @@ guchar * clutter_stage_read_pixels (ClutterStage
CLUTTER_AVAILABLE_IN_ALL
void clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
cairo_rectangle_int_t *clip);
CLUTTER_AVAILABLE_IN_MUTTER
cairo_region_t * clutter_stage_get_redraw_clip (ClutterStage *stage);
CLUTTER_AVAILABLE_IN_ALL
void clutter_stage_ensure_viewport (ClutterStage *stage);
CLUTTER_AVAILABLE_IN_ALL

View File

@ -312,7 +312,7 @@ G_BEGIN_DECLS
*
* Since: 1.2
*/
const guint clutter_major_version;
extern const guint clutter_major_version;
/**
* clutter_minor_version:
@ -326,7 +326,7 @@ const guint clutter_major_version;
*
* Since: 1.2
*/
const guint clutter_minor_version;
extern const guint clutter_minor_version;
/**
* clutter_micro_version:
@ -340,7 +340,7 @@ const guint clutter_minor_version;
*
* Since: 1.2
*/
const guint clutter_micro_version;
extern const guint clutter_micro_version;
G_END_DECLS

View File

@ -54,7 +54,7 @@ typedef struct _ClutterStageViewCoglPrivate
/* Stores a list of previous damaged areas in the stage coordinate space */
#define DAMAGE_HISTORY_MAX 16
#define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1))
cairo_rectangle_int_t damage_history[DAMAGE_HISTORY_MAX];
cairo_region_t * damage_history[DAMAGE_HISTORY_MAX];
unsigned int damage_index;
} ClutterStageViewCoglPrivate;
@ -246,13 +246,10 @@ clutter_stage_cogl_has_redraw_clips (ClutterStageWindow *stage_window)
/* NB: at the start of each new frame there is an implied clip that
* clips everything (i.e. nothing would be drawn) so we need to make
* sure we return True in the un-initialized case here.
*
* NB: a clip width of 0 means a full stage redraw has been queued
* so we effectively don't have any redraw clips in that case.
*/
if (!stage_cogl->initialized_redraw_clip ||
(stage_cogl->initialized_redraw_clip &&
stage_cogl->bounding_redraw_clip.width != 0))
stage_cogl->redraw_clip))
return TRUE;
else
return FALSE;
@ -263,9 +260,9 @@ clutter_stage_cogl_ignoring_redraw_clips (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
/* NB: a clip width of 0 means a full stage redraw is required */
/* NB: a NULL clip means a full stage redraw is required */
if (stage_cogl->initialized_redraw_clip &&
stage_cogl->bounding_redraw_clip.width == 0)
!stage_cogl->redraw_clip)
return TRUE;
else
return FALSE;
@ -296,11 +293,11 @@ clutter_stage_cogl_add_redraw_clip (ClutterStageWindow *stage_window,
return;
/* A NULL stage clip means a full stage redraw has been queued and
* we keep track of this by setting a zero width
* stage_cogl->bounding_redraw_clip */
* we keep track of this by setting a NULL redraw_clip.
*/
if (stage_clip == NULL)
{
stage_cogl->bounding_redraw_clip.width = 0;
g_clear_pointer (&stage_cogl->redraw_clip, cairo_region_destroy);
stage_cogl->initialized_redraw_clip = TRUE;
return;
}
@ -309,34 +306,27 @@ clutter_stage_cogl_add_redraw_clip (ClutterStageWindow *stage_window,
if (stage_clip->width == 0 || stage_clip->height == 0)
return;
if (!stage_cogl->initialized_redraw_clip)
if (!stage_cogl->redraw_clip)
{
stage_cogl->bounding_redraw_clip = *stage_clip;
stage_cogl->redraw_clip = cairo_region_create_rectangle (stage_clip);
}
else if (stage_cogl->bounding_redraw_clip.width > 0)
else
{
_clutter_util_rectangle_union (&stage_cogl->bounding_redraw_clip,
stage_clip,
&stage_cogl->bounding_redraw_clip);
cairo_region_union_rectangle (stage_cogl->redraw_clip, stage_clip);
}
stage_cogl->initialized_redraw_clip = TRUE;
}
static gboolean
clutter_stage_cogl_get_redraw_clip_bounds (ClutterStageWindow *stage_window,
cairo_rectangle_int_t *stage_clip)
static cairo_region_t *
clutter_stage_cogl_get_redraw_clip (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
if (stage_cogl->using_clipped_redraw)
{
*stage_clip = stage_cogl->bounding_redraw_clip;
if (stage_cogl->using_clipped_redraw && stage_cogl->redraw_clip)
return cairo_region_copy (stage_cogl->redraw_clip);
return TRUE;
}
return FALSE;
return NULL;
}
static inline gboolean
@ -414,37 +404,51 @@ swap_framebuffer (ClutterStageWindow *stage_window,
static void
paint_stage (ClutterStageCogl *stage_cogl,
ClutterStageView *view,
const cairo_rectangle_int_t *clip)
cairo_region_t *clip)
{
ClutterStage *stage = stage_cogl->wrapper;
cairo_rectangle_int_t clip_rect;
cairo_region_get_extents (clip, &clip_rect);
_clutter_stage_maybe_setup_viewport (stage, view);
_clutter_stage_paint_view (stage, view, clip);
_clutter_stage_paint_view (stage, view, &clip_rect);
if (clutter_stage_view_get_onscreen (view) !=
clutter_stage_view_get_framebuffer (view))
{
clutter_stage_view_blit_offscreen (view, clip);
clutter_stage_view_blit_offscreen (view, &clip_rect);
}
}
static void
fill_current_damage_history_and_step (ClutterStageView *view)
fill_current_damage_history (ClutterStageView *view,
cairo_region_t *damage)
{
ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view);
ClutterStageViewCoglPrivate *view_priv =
clutter_stage_view_cogl_get_instance_private (view_cogl);
cairo_rectangle_int_t view_rect;
cairo_rectangle_int_t *current_damage;
cairo_region_t **current_damage;
current_damage =
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)];
clutter_stage_view_get_layout (view, &view_rect);
*current_damage = view_rect;
g_clear_pointer (current_damage, cairo_region_destroy);
*current_damage = cairo_region_copy (damage);
view_priv->damage_index++;
}
static void
fill_current_damage_history_rectangle (ClutterStageView *view,
const cairo_rectangle_int_t *rect)
{
cairo_region_t *damage;
damage = cairo_region_create_rectangle (rect);
fill_current_damage_history (view, damage);
cairo_region_destroy (damage);
}
static void
transform_swap_region_to_onscreen (ClutterStageView *view,
cairo_rectangle_int_t *swap_region)
@ -499,11 +503,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
gboolean do_swap_buffer;
gboolean swap_with_damage;
ClutterActor *wrapper;
cairo_rectangle_int_t redraw_clip;
cairo_region_t *redraw_clip;
cairo_region_t *clip_region;
cairo_rectangle_int_t swap_region;
cairo_rectangle_int_t clip_region;
cairo_rectangle_int_t clip_rect;
cairo_rectangle_int_t redraw_rect;
gboolean clip_region_empty;
int window_scale;
int fb_scale;
wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
@ -517,20 +523,19 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
cogl_is_onscreen (fb) &&
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
/* NB: a zero width redraw clip == full stage redraw */
if (stage_cogl->bounding_redraw_clip.width == 0)
/* NB: a NULL redraw clip == full stage redraw */
if (!stage_cogl->redraw_clip)
have_clip = FALSE;
else
{
redraw_clip = stage_cogl->bounding_redraw_clip;
_clutter_util_rectangle_intersection (&redraw_clip,
&view_rect,
&redraw_clip);
cairo_region_t *view_region;
redraw_clip = cairo_region_copy (stage_cogl->redraw_clip);
have_clip = !(redraw_clip.x == view_rect.x &&
redraw_clip.y == view_rect.y &&
redraw_clip.width == view_rect.width &&
redraw_clip.height == view_rect.height);
view_region = cairo_region_create_rectangle (&view_rect);
cairo_region_intersect (redraw_clip, view_region);
have_clip = !cairo_region_equal (redraw_clip, view_region);
cairo_region_destroy (view_region);
}
may_use_clipped_redraw = FALSE;
@ -542,11 +547,12 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3)
{
may_use_clipped_redraw = TRUE;
clip_region = redraw_clip;
clip_region = cairo_region_reference (redraw_clip);
}
else
{
clip_region = (cairo_rectangle_int_t){ 0 };
clip_region = cairo_region_create ();
redraw_clip = cairo_region_reference (clip_region);
}
if (may_use_clipped_redraw &&
@ -555,9 +561,9 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
else
use_clipped_redraw = FALSE;
clip_region_empty = may_use_clipped_redraw && clip_region.width == 0;
clip_region_empty = may_use_clipped_redraw && cairo_region_is_empty (clip_region);
window_scale = _clutter_stage_window_get_scale_factor (stage_window);
fb_scale = clutter_stage_view_get_scale (view);
swap_with_damage = FALSE;
if (has_buffer_age)
@ -565,34 +571,26 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
if (use_clipped_redraw && !clip_region_empty)
{
int age, i;
cairo_rectangle_int_t *current_damage =
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index++)];
age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
if (valid_buffer_age (view_cogl, age))
{
*current_damage = clip_region;
fill_current_damage_history (view, clip_region);
for (i = 1; i <= age; i++)
{
cairo_rectangle_int_t *damage =
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - i - 1)];
_clutter_util_rectangle_union (&clip_region, damage, &clip_region);
cairo_region_t *damage =
view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - i - 1)];
cairo_region_union (clip_region, damage);
}
/* Update the bounding redraw clip state with the extra damage. */
_clutter_util_rectangle_union (&stage_cogl->bounding_redraw_clip,
&clip_region,
&stage_cogl->bounding_redraw_clip);
/* Update the redraw clip state with the extra damage. */
cairo_region_union (stage_cogl->redraw_clip, clip_region);
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: x=%d, y=%d, width=%d, height=%d\n",
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
age,
clip_region.x,
clip_region.y,
clip_region.width,
clip_region.height);
cairo_region_num_rectangles (clip_region));
swap_with_damage = TRUE;
}
@ -600,15 +598,17 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
{
CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age);
use_clipped_redraw = FALSE;
*current_damage = view_rect;
fill_current_damage_history_rectangle (view, &view_rect);
}
}
else if (!use_clipped_redraw)
{
fill_current_damage_history_and_step (view);
fill_current_damage_history_rectangle (view, &view_rect);
}
}
cairo_region_get_extents (clip_region, &clip_rect);
cogl_push_framebuffer (fb);
if (use_clipped_redraw && clip_region_empty)
{
@ -621,21 +621,21 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
CLUTTER_NOTE (CLIPPING,
"Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
clip_region.x,
clip_region.y,
clip_region.width,
clip_region.height);
clip_rect.x,
clip_rect.y,
clip_rect.width,
clip_rect.height);
stage_cogl->using_clipped_redraw = TRUE;
scissor_x = (clip_region.x - view_rect.x) * window_scale;
scissor_y = (clip_region.y - view_rect.y) * window_scale;
scissor_x = (clip_rect.x - view_rect.x) * fb_scale;
scissor_y = (clip_rect.y - view_rect.y) * fb_scale;
cogl_framebuffer_push_scissor_clip (fb,
scissor_x,
scissor_y,
clip_region.width * window_scale,
clip_region.height * window_scale);
paint_stage (stage_cogl, view, &clip_region);
clip_rect.width * fb_scale,
clip_rect.height * fb_scale);
paint_stage (stage_cogl, view, clip_region);
cogl_framebuffer_pop_clip (fb);
stage_cogl->using_clipped_redraw = FALSE;
@ -645,7 +645,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
CLUTTER_NOTE (CLIPPING, "Unclipped stage paint\n");
/* If we are trying to debug redraw issues then we want to pass
* the bounding_redraw_clip so it can be visualized */
* the redraw_clip so it can be visualized */
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
may_use_clipped_redraw &&
!clip_region_empty)
@ -653,31 +653,39 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
int scissor_x;
int scissor_y;
scissor_x = (clip_region.x - view_rect.x) * window_scale;;
scissor_y = (clip_region.y - view_rect.y) * window_scale;
scissor_x = (clip_rect.x - view_rect.x) * fb_scale;;
scissor_y = (clip_rect.y - view_rect.y) * fb_scale;
cogl_framebuffer_push_scissor_clip (fb,
scissor_x,
scissor_y,
clip_region.width * window_scale,
clip_region.height * window_scale);
paint_stage (stage_cogl, view, &clip_region);
clip_rect.width * fb_scale,
clip_rect.height * fb_scale);
paint_stage (stage_cogl, view, clip_region);
cogl_framebuffer_pop_clip (fb);
}
else
paint_stage (stage_cogl, view, &view_rect);
{
cairo_region_t *view_region;
view_region = cairo_region_create_rectangle (&view_rect);
paint_stage (stage_cogl, view, view_region);
cairo_region_destroy (view_region);
}
}
cogl_pop_framebuffer ();
cairo_region_get_extents (redraw_clip, &redraw_rect);
if (may_use_clipped_redraw &&
G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)))
{
CoglContext *ctx = cogl_framebuffer_get_context (fb);
static CoglPipeline *outline = NULL;
ClutterActor *actor = CLUTTER_ACTOR (wrapper);
float x_1 = redraw_clip.x;
float x_2 = redraw_clip.x + redraw_clip.width;
float y_1 = redraw_clip.y;
float y_2 = redraw_clip.y + redraw_clip.height;
float x_1 = redraw_rect.x;
float x_2 = redraw_rect.x + redraw_rect.width;
float y_1 = redraw_rect.y;
float y_2 = redraw_rect.y + redraw_rect.height;
CoglVertexP2 quad[4] = {
{ x_1, y_1 },
{ x_2, y_1 },
@ -724,10 +732,10 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
else if (use_clipped_redraw)
{
swap_region = (cairo_rectangle_int_t) {
.x = (clip_region.x - view_rect.x) * window_scale,
.y = (clip_region.y - view_rect.y) * window_scale,
.width = clip_region.width * window_scale,
.height = clip_region.height * window_scale,
.x = (clip_rect.x - view_rect.x) * fb_scale,
.y = (clip_rect.y - view_rect.y) * fb_scale,
.width = clip_rect.width * fb_scale,
.height = clip_rect.height * fb_scale,
};
g_assert (swap_region.width > 0);
do_swap_buffer = TRUE;
@ -737,8 +745,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
swap_region = (cairo_rectangle_int_t) {
.x = 0,
.y = 0,
.width = view_rect.width * window_scale,
.height = view_rect.height * window_scale,
.width = view_rect.width * fb_scale,
.height = view_rect.height * fb_scale,
};
do_swap_buffer = TRUE;
}
@ -749,6 +757,11 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
do_swap_buffer = TRUE;
}
if (redraw_clip)
cairo_region_destroy (redraw_clip);
if (clip_region)
cairo_region_destroy (clip_region);
if (do_swap_buffer)
{
if (clutter_stage_view_get_onscreen (view) !=
@ -796,6 +809,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
/* reset the redraw clipping for the next paint... */
stage_cogl->initialized_redraw_clip = FALSE;
g_clear_pointer (&stage_cogl->redraw_clip, cairo_region_destroy);
stage_cogl->frame_count++;
}
@ -810,7 +824,7 @@ clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
gboolean has_buffer_age =
cogl_is_onscreen (framebuffer) &&
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
cairo_rectangle_int_t *rect;
cairo_rectangle_int_t rect;
if (!has_buffer_age)
{
@ -823,12 +837,18 @@ clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
ClutterStageViewCoglPrivate *view_priv =
clutter_stage_view_cogl_get_instance_private (view_cogl);
cairo_rectangle_int_t view_layout;
cairo_region_t *damage;
clutter_stage_view_get_layout (view, &view_layout);
rect = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
*x = rect->x - view_layout.x;
*y = rect->y - view_layout.y;
damage = view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
if (damage)
cairo_region_get_rectangle (damage, 0, &rect);
else
rect.x = rect.y = 0;
*x = rect.x - view_layout.x;
*y = rect.y - view_layout.y;
}
}
@ -847,7 +867,7 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
iface->add_redraw_clip = clutter_stage_cogl_add_redraw_clip;
iface->has_redraw_clips = clutter_stage_cogl_has_redraw_clips;
iface->ignoring_redraw_clips = clutter_stage_cogl_ignoring_redraw_clips;
iface->get_redraw_clip_bounds = clutter_stage_cogl_get_redraw_clip_bounds;
iface->get_redraw_clip = clutter_stage_cogl_get_redraw_clip;
iface->redraw = clutter_stage_cogl_redraw;
iface->get_dirty_pixel = clutter_stage_cogl_get_dirty_pixel;
}

View File

@ -59,7 +59,7 @@ struct _ClutterStageCogl
* junk frames to start with. */
unsigned int frame_count;
cairo_rectangle_int_t bounding_redraw_clip;
cairo_region_t *redraw_clip;
guint initialized_redraw_clip : 1;

View File

@ -136,7 +136,6 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
ClutterTranslateReturn res;
ClutterStage *stage;
XEvent *xevent;
int window_scale;
manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (translator);
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
@ -152,8 +151,6 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage));
window_scale = stage_x11->scale_factor;
event->any.stage = stage;
res = CLUTTER_TRANSLATE_CONTINUE;
@ -226,8 +223,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
event->scroll.direction = CLUTTER_SCROLL_RIGHT;
event->scroll.time = xevent->xbutton.time;
event->scroll.x = xevent->xbutton.x / window_scale;
event->scroll.y = xevent->xbutton.y / window_scale;
event->scroll.x = xevent->xbutton.x;
event->scroll.y = xevent->xbutton.y;
event->scroll.modifier_state = xevent->xbutton.state;
event->scroll.axes = NULL;
break;
@ -235,8 +232,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
default:
event->button.type = event->type = CLUTTER_BUTTON_PRESS;
event->button.time = xevent->xbutton.time;
event->button.x = xevent->xbutton.x / window_scale;
event->button.y = xevent->xbutton.y / window_scale;
event->button.x = xevent->xbutton.x;
event->button.y = xevent->xbutton.y;
event->button.modifier_state = xevent->xbutton.state;
event->button.button = xevent->xbutton.button;
event->button.axes = NULL;
@ -269,8 +266,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
event->button.time = xevent->xbutton.time;
event->button.x = xevent->xbutton.x / window_scale;
event->button.y = xevent->xbutton.y / window_scale;
event->button.x = xevent->xbutton.x;
event->button.y = xevent->xbutton.y;
event->button.modifier_state = xevent->xbutton.state;
event->button.button = xevent->xbutton.button;
event->button.axes = NULL;
@ -287,8 +284,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
event->motion.type = event->type = CLUTTER_MOTION;
event->motion.time = xevent->xmotion.time;
event->motion.x = xevent->xmotion.x / window_scale;
event->motion.y = xevent->xmotion.y / window_scale;
event->motion.x = xevent->xmotion.x;
event->motion.y = xevent->xmotion.y;
event->motion.modifier_state = xevent->xmotion.state;
event->motion.axes = NULL;
clutter_event_set_device (event, manager_x11->core_pointer);
@ -301,8 +298,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
event->crossing.type = CLUTTER_ENTER;
event->crossing.time = xevent->xcrossing.time;
event->crossing.x = xevent->xcrossing.x / window_scale;
event->crossing.y = xevent->xcrossing.y / window_scale;
event->crossing.x = xevent->xcrossing.x;
event->crossing.y = xevent->xcrossing.y;
event->crossing.source = CLUTTER_ACTOR (stage);
event->crossing.related = NULL;
clutter_event_set_device (event, manager_x11->core_pointer);
@ -327,8 +324,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
event->crossing.type = CLUTTER_LEAVE;
event->crossing.time = xevent->xcrossing.time;
event->crossing.x = xevent->xcrossing.x / window_scale;
event->crossing.y = xevent->xcrossing.y / window_scale;
event->crossing.x = xevent->xcrossing.x;
event->crossing.y = xevent->xcrossing.y;
event->crossing.source = CLUTTER_ACTOR (stage);
event->crossing.related = NULL;
clutter_event_set_device (event, manager_x11->core_pointer);

View File

@ -861,8 +861,8 @@ translate_coords (ClutterStageX11 *stage_x11,
clutter_actor_get_size (stage, &stage_width, &stage_height);
*x_out = CLAMP (event_x / stage_x11->scale_factor, 0, stage_width);
*y_out = CLAMP (event_y / stage_x11->scale_factor, 0, stage_height);
*x_out = CLAMP (event_x, 0, stage_width);
*y_out = CLAMP (event_y, 0, stage_height);
}
static gdouble

View File

@ -15,7 +15,6 @@ static const struct {
{ "Xft/HintStyle", "font-hint-style" },
{ "Xft/RGBA", "font-subpixel-order" },
{ "Fontconfig/Timestamp", "fontconfig-timestamp" },
{ "Gdk/WindowScalingFactor", "window-scaling-factor" },
{ "Gdk/UnscaledDPI", "unscaled-font-dpi" },
};

View File

@ -162,10 +162,10 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
&min_height);
if (new_width <= 0)
new_width = min_width * stage_x11->scale_factor;
new_width = min_width;
if (new_height <= 0)
new_height = min_height * stage_x11->scale_factor;
new_height = min_height;
size_hints->flags = 0;
@ -175,8 +175,8 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
{
if (resize)
{
size_hints->min_width = min_width * stage_x11->scale_factor;
size_hints->min_height = min_height * stage_x11->scale_factor;
size_hints->min_width = min_width;
size_hints->min_height = min_height;
size_hints->flags = PMinSize;
}
else
@ -236,8 +236,8 @@ clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window,
return;
}
geometry->width = stage_x11->xwin_width / stage_x11->scale_factor;
geometry->height = stage_x11->xwin_height / stage_x11->scale_factor;
geometry->width = stage_x11->xwin_width;
geometry->height = stage_x11->xwin_height;
}
static void
@ -255,8 +255,8 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
* so we need to manually set the size and queue a relayout on the
* stage here (as is normally done in response to ConfigureNotify).
*/
stage_x11->xwin_width = width * stage_x11->scale_factor;
stage_x11->xwin_height = height * stage_x11->scale_factor;
stage_x11->xwin_width = width;
stage_x11->xwin_height = height;
clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_cogl->wrapper));
return;
}
@ -277,9 +277,6 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
CLUTTER_NOTE (BACKEND, "New size received: (%d, %d)", width, height);
width *= stage_x11->scale_factor;
height *= stage_x11->scale_factor;
if (stage_x11->xwin != None)
{
clutter_stage_x11_fix_window_size (stage_x11, width, height);
@ -400,20 +397,6 @@ set_cursor_visible (ClutterStageX11 *stage_x11)
}
}
static void
on_window_scaling_factor_notify (GObject *settings,
GParamSpec *pspec,
ClutterStageX11 *stage_x11)
{
g_object_get (settings,
"window-scaling-factor", &stage_x11->scale_factor,
NULL);
clutter_stage_x11_resize (CLUTTER_STAGE_WINDOW (stage_x11),
stage_x11->xwin_width,
stage_x11->xwin_height);
}
static void
clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
{
@ -643,12 +626,8 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
CLUTTER_NOTE (BACKEND, "Wrapper size: %.2f x %.2f", width, height);
width = width * (float) stage_x11->scale_factor;
height = height * (float) stage_x11->scale_factor;
CLUTTER_NOTE (BACKEND, "Creating a new Cogl onscreen surface: %.2f x %.2f (factor: %d)",
width, height,
stage_x11->scale_factor);
CLUTTER_NOTE (BACKEND, "Creating a new Cogl onscreen surface: %.2f x %.2f",
width, height);
stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
@ -909,28 +888,6 @@ clutter_stage_x11_can_clip_redraws (ClutterStageWindow *stage_window)
return stage_x11->clipped_redraws_cool_off == 0;
}
static void
clutter_stage_x11_set_scale_factor (ClutterStageWindow *stage_window,
int factor)
{
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
if (stage_x11->scale_factor == factor)
return;
stage_x11->scale_factor = factor;
clutter_stage_x11_resize (stage_window, stage_x11->xwin_width, stage_x11->xwin_height);
}
static int
clutter_stage_x11_get_scale_factor (ClutterStageWindow *stage_window)
{
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
return stage_x11->scale_factor;
}
static void
ensure_legacy_view (ClutterStageWindow *stage_window)
{
@ -1002,8 +959,6 @@ clutter_stage_x11_class_init (ClutterStageX11Class *klass)
static void
clutter_stage_x11_init (ClutterStageX11 *stage)
{
ClutterSettings *settings;
stage->xwin = None;
stage->xwin_width = 640;
stage->xwin_height = 480;
@ -1016,12 +971,6 @@ clutter_stage_x11_init (ClutterStageX11 *stage)
stage->accept_focus = TRUE;
stage->title = NULL;
settings = clutter_settings_get_default ();
g_signal_connect (settings, "notify::window-scaling-factor",
G_CALLBACK (on_window_scaling_factor_notify),
stage);
on_window_scaling_factor_notify (G_OBJECT (settings), NULL, stage);
}
static void
@ -1041,8 +990,6 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
iface->realize = clutter_stage_x11_realize;
iface->unrealize = clutter_stage_x11_unrealize;
iface->can_clip_redraws = clutter_stage_x11_can_clip_redraws;
iface->set_scale_factor = clutter_stage_x11_set_scale_factor;
iface->get_scale_factor = clutter_stage_x11_get_scale_factor;
iface->get_views = clutter_stage_x11_get_views;
iface->get_frame_counter = clutter_stage_x11_get_frame_counter;
}
@ -1167,8 +1114,8 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
stage_x11->xwin_height = xevent->xconfigure.height;
}
stage_width = xevent->xconfigure.width / stage_x11->scale_factor;
stage_height = xevent->xconfigure.height / stage_x11->scale_factor;
stage_width = xevent->xconfigure.width;
stage_height = xevent->xconfigure.height;
clutter_actor_set_size (CLUTTER_ACTOR (stage), stage_width, stage_height);
if (size_changed)
@ -1335,10 +1282,10 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
expose->width,
expose->height);
clip.x = expose->x / stage_x11->scale_factor;
clip.y = expose->y / stage_x11->scale_factor;
clip.width = expose->width / stage_x11->scale_factor;
clip.height = expose->height / stage_x11->scale_factor;
clip.x = expose->x;
clip.y = expose->y;
clip.width = expose->width;
clip.height = expose->height;
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
}
break;
@ -1504,8 +1451,8 @@ set_foreign_window_callback (ClutterActor *actor,
fwd->stage_x11->xwin = fwd->xwindow;
fwd->stage_x11->is_foreign_xwin = TRUE;
fwd->stage_x11->xwin_width = fwd->geom.width * fwd->stage_x11->scale_factor;
fwd->stage_x11->xwin_height = fwd->geom.height * fwd->stage_x11->scale_factor;
fwd->stage_x11->xwin_width = fwd->geom.width;
fwd->stage_x11->xwin_height = fwd->geom.height;
clutter_actor_set_size (actor, fwd->geom.width, fwd->geom.height);
@ -1599,8 +1546,8 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
fwd.geom.x = x;
fwd.geom.y = y;
fwd.geom.width = width / stage_x11->scale_factor;
fwd.geom.height = height / stage_x11->scale_factor;
fwd.geom.width = width;
fwd.geom.height = height;
actor = CLUTTER_ACTOR (stage);

View File

@ -69,8 +69,6 @@ struct _ClutterStageX11
ClutterStageX11State wm_state;
int scale_factor;
guint is_foreign_xwin : 1;
guint fullscreening : 1;
guint is_cursor_visible : 1;

View File

@ -350,7 +350,8 @@ actor_replace_child (void)
g_assert_cmpstr (clutter_actor_get_name (iter), ==, "qux");
clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
"name", "foo"));
"name", "foo",
NULL));
clutter_actor_replace_child (actor, iter,
g_object_new (CLUTTER_TYPE_ACTOR,

View File

@ -81,6 +81,19 @@
#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
#endif
/* These aren't defined in the GLES2 headers */
#ifndef GL_GUILTY_CONTEXT_RESET_ARB
#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
#endif
#ifndef GL_INNOCENT_CONTEXT_RESET_ARB
#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
#endif
#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB
#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
#endif
static void _cogl_context_free (CoglContext *context);
COGL_OBJECT_DEFINE (Context, context);

View File

@ -193,6 +193,11 @@ struct _CoglFramebuffer
CoglFramebufferBits bits;
int samples_per_pixel;
/* Whether the depth buffer was enabled for this framebuffer,
* usually means it needs to be cleared before being reused next.
*/
CoglBool depth_buffer_clear_needed;
};
typedef enum {

View File

@ -117,6 +117,7 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
framebuffer->viewport_age_for_scissor_workaround = -1;
framebuffer->dither_enabled = TRUE;
framebuffer->depth_writing_enabled = TRUE;
framebuffer->depth_buffer_clear_needed = TRUE;
framebuffer->modelview_stack = cogl_matrix_stack_new (ctx);
framebuffer->projection_stack = cogl_matrix_stack_new (ctx);
@ -268,6 +269,13 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
int scissor_y1;
CoglBool saved_viewport_scissor_workaround;
if (!framebuffer->depth_buffer_clear_needed &&
(buffers & COGL_BUFFER_BIT_DEPTH))
buffers &= ~(COGL_BUFFER_BIT_DEPTH);
if (buffers == 0)
return;
_cogl_clip_stack_get_bounds (clip_stack,
&scissor_x0, &scissor_y0,
&scissor_x1, &scissor_y1);
@ -415,6 +423,9 @@ cleared:
_cogl_framebuffer_mark_mid_scene (framebuffer);
_cogl_framebuffer_mark_clear_clip_dirty (framebuffer);
if (buffers & COGL_BUFFER_BIT_DEPTH)
framebuffer->depth_buffer_clear_needed = FALSE;
if (buffers & COGL_BUFFER_BIT_COLOR && buffers & COGL_BUFFER_BIT_DEPTH)
{
/* For our fast-path for reading back a single pixel of simple

View File

@ -1102,7 +1102,7 @@ upload_vertices (CoglJournal *journal,
attribute_buffer = create_attribute_buffer (journal, needed_vbo_len * 4);
buffer = COGL_BUFFER (attribute_buffer);
cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_STATIC);
cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_DYNAMIC);
vout = _cogl_buffer_map_range_for_fill_or_fallback (buffer,
0, /* offset */

View File

@ -198,6 +198,7 @@ struct _CoglTextureDriver
CoglPixelFormat
(* find_best_gl_get_data_format) (CoglContext *context,
CoglPixelFormat format,
CoglPixelFormat target_format,
GLenum *closest_gl_format,
GLenum *closest_gl_type);
};

View File

@ -1059,6 +1059,7 @@ cogl_texture_get_data (CoglTexture *texture,
closest_format =
ctx->texture_driver->find_best_gl_get_data_format (ctx,
texture_format,
format,
&closest_gl_format,
&closest_gl_type);

View File

@ -418,7 +418,11 @@ flush_depth_state (CoglContext *ctx,
if (ctx->depth_test_enabled_cache != depth_state->test_enabled)
{
if (depth_state->test_enabled == TRUE)
GE (ctx, glEnable (GL_DEPTH_TEST));
{
GE (ctx, glEnable (GL_DEPTH_TEST));
if (ctx->current_draw_buffer)
ctx->current_draw_buffer->depth_buffer_clear_needed = TRUE;
}
else
GE (ctx, glDisable (GL_DEPTH_TEST));
ctx->depth_test_enabled_cache = depth_state->test_enabled;

View File

@ -37,6 +37,11 @@
#include "cogl-gl-header.h"
#include "cogl-texture.h"
/* In OpenGL ES context, GL_CONTEXT_LOST has a _KHR prefix */
#ifndef GL_CONTEXT_LOST
#define GL_CONTEXT_LOST GL_CONTEXT_LOST_KHR
#endif
#ifdef COGL_GL_DEBUG
const char *

View File

@ -533,14 +533,16 @@ static CoglPixelFormat
_cogl_texture_driver_find_best_gl_get_data_format
(CoglContext *context,
CoglPixelFormat format,
CoglPixelFormat target_format,
GLenum *closest_gl_format,
GLenum *closest_gl_type)
{
return context->driver_vtable->pixel_format_to_gl (context,
format,
NULL, /* don't need */
closest_gl_format,
closest_gl_type);
return context->driver_vtable->pixel_format_to_gl_with_target (context,
format,
target_format,
NULL, /* don't need */
closest_gl_format,
closest_gl_type);
}
const CoglTextureDriver

View File

@ -615,6 +615,7 @@ static CoglPixelFormat
_cogl_texture_driver_find_best_gl_get_data_format
(CoglContext *context,
CoglPixelFormat format,
CoglPixelFormat target_format,
GLenum *closest_gl_format,
GLenum *closest_gl_type)
{

View File

@ -1,8 +1,8 @@
AC_PREREQ(2.62)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [24])
m4_define([mutter_micro_version], [0])
m4_define([mutter_minor_version], [25])
m4_define([mutter_micro_version], [1])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@ -57,6 +57,13 @@ AM_GNU_GETTEXT([external])
LT_PREREQ([2.2.6])
LT_INIT([disable-static])
# Debian / Ubuntu set this flag to 'no' in libtool, causing linking errors
# (i.e when linking against mutter-clutter). Not to explicitly redefine such
# deps, we enable this flag for everybody.
link_all_deplibs=yes
link_all_deplibs_CXX=yes
AC_PROG_CC
AC_PROG_CC_C_O
AC_PROG_INSTALL

View File

@ -102,6 +102,27 @@
</description>
</key>
<key name="experimental-features" type="as">
<default>[]</default>
<summary>Enable experimental features</summary>
<description>
To enable experimental features, add the feature keyword to the list.
Whether the feature requires restarting the compositor depends on the
given feature. Any experimental feature is not required to still be
available, or configurable. Dont expect adding anything in this
setting to be future proof.
Currently possible keywords:
• “scale-monitor-framebuffer” — makes mutter default to layout logical
monitors in a logical pixel coordinate
space, while scaling monitor
framebuffers instead of window content,
to manage HiDPI monitors. Does not
require a restart.
</description>
</key>
<child name="keybindings" schema="org.gnome.mutter.keybindings"/>
</schema>

View File

@ -12,11 +12,11 @@ src/compositor/compositor.c
src/compositor/meta-background.c
src/core/bell.c
src/core/core.c
src/core/delete.c
src/core/display.c
src/core/errors.c
src/core/keybindings.c
src/core/main.c
src/core/meta-close-dialog-default.c
src/core/mutter.c
src/core/prefs.c
src/core/screen.c

View File

@ -5,8 +5,8 @@ msgstr ""
"Project-Id-Version: mutter.master\n"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2017-02-28 06:20+0000\n"
"PO-Revision-Date: 2017-03-27 18:08+0300\n"
"POT-Creation-Date: 2017-04-21 21:33+0000\n"
"PO-Revision-Date: 2017-04-23 16:56+0300\n"
"Last-Translator: Yuras Shumovich <shumovichy@gmail.com>\n"
"Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n"
"Language: be\n"
@ -396,11 +396,35 @@ msgstr ""
"Калі ўключана, новыя вокны будуць заўсёды з'яўляцца пасярэдзіне дзейнага "
"манітора."
#: data/org.gnome.mutter.gschema.xml.in:120
#: data/org.gnome.mutter.gschema.xml.in:107
msgid "Enable experimental features"
msgstr "Уключыць эксперыментальныя функцыі"
#: data/org.gnome.mutter.gschema.xml.in:108
msgid ""
"To enable experimental features, add the feature keyword to the list. "
"Whether the feature requires restarting the compositor depends on the given "
"feature. Any experimental feature is not required to still be available, or "
"configurable. Dont expect adding anything in this setting to be future "
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
"mutter default to layout logical monitors in a logical pixel coordinate "
"space, while scaling monitor framebuffers instead of window content, to "
"manage HiDPI monitors. Does not require a restart."
msgstr ""
"Каб уключыць эксперыментальныя функцыі, дадайце адпаведнае ключавое слова ў "
"гэты ліст. Некаторыя функцыі могуць патрабаваць перазапуску кампазітара. "
"Эксперыментальны функцыі могуць быць недаступныя. Не чакайце, што функцыі, "
"дададзеныя ў гэты спіс, будуць працаваць і далей. Магчымыя ключавыя словы: • "
"\"scale-monitor-framebuffer\" - прымушае mutter прадвызначана размяшчаць "
"лагічныя маніторы ў лагічнай прасторы каардынат пікселаў, пры гэтым "
"маштабаваць кадравы буфер, а не змесціва акна, для падтрымкі HiDPI "
"манітораў. Не патрабуе перазапуску."
#: data/org.gnome.mutter.gschema.xml.in:141
msgid "Select window from tab popup"
msgstr "Выбраць акно з выплыўнога акенца"
#: data/org.gnome.mutter.gschema.xml.in:125
#: data/org.gnome.mutter.gschema.xml.in:146
msgid "Cancel tab popup"
msgstr "Закрыць выплыўное акенца"
@ -455,7 +479,7 @@ msgstr "Перайсці ў віртуальны тэрмінал 12"
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:1800
#: src/backends/meta-input-settings.c:1848
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Пераключыць рэжым (група %d)"
@ -463,37 +487,37 @@ msgstr "Пераключыць рэжым (група %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:1822
#: src/backends/meta-input-settings.c:1870
msgid "Switch monitor"
msgstr "Пераключыць манітор"
#: src/backends/meta-input-settings.c:1824
#: src/backends/meta-input-settings.c:1872
msgid "Show on-screen help"
msgstr "Паказаць экранную даведку"
#: src/backends/meta-monitor-manager.c:675
#: src/backends/meta-monitor-manager.c:783
msgid "Built-in display"
msgstr "Убудаваны дысплей"
#: src/backends/meta-monitor-manager.c:698
#: src/backends/meta-monitor-manager.c:806
msgid "Unknown"
msgstr "Невядомы"
#: src/backends/meta-monitor-manager.c:700
#: src/backends/meta-monitor-manager.c:808
msgid "Unknown Display"
msgstr "Невядомы дысплей"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: src/backends/meta-monitor-manager.c:708
#: src/backends/meta-monitor-manager.c:816
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: src/compositor/compositor.c:471
#: src/compositor/compositor.c:474
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."

898
po/ca.po

File diff suppressed because it is too large Load Diff

1197
po/de.po

File diff suppressed because it is too large Load Diff

472
po/fur.po
View File

@ -8,15 +8,255 @@ msgstr ""
"Project-Id-Version: mutter master\n"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2017-02-22 19:28+0000\n"
"PO-Revision-Date: 2017-02-24 16:31+0100\n"
"POT-Creation-Date: 2017-04-21 21:33+0000\n"
"PO-Revision-Date: 2017-04-30 15:41+0200\n"
"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
"Language-Team: Friulian <fur@li.org>\n"
"Language: fur\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.11\n"
"X-Generator: Poedit 1.8.12\n"
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
msgstr "Navigazion"
#: data/50-mutter-navigation.xml:9
msgid "Move window to workspace 1"
msgstr "Sposte barcon tal spazi di lavôr 1"
#: data/50-mutter-navigation.xml:12
msgid "Move window to workspace 2"
msgstr "Sposte barcon tal spazi di lavôr 2"
#: data/50-mutter-navigation.xml:15
msgid "Move window to workspace 3"
msgstr "Sposte barcon tal spazi di lavôr 3"
#: data/50-mutter-navigation.xml:18
msgid "Move window to workspace 4"
msgstr "Sposte barcon tal spazi di lavôr 4"
#: data/50-mutter-navigation.xml:21
msgid "Move window to last workspace"
msgstr "Sposte barcon tal ultin spazi di lavôr"
#: data/50-mutter-navigation.xml:24
msgid "Move window one workspace to the left"
msgstr "Sposte barcon tal spazi di lavôr a çampe"
#: data/50-mutter-navigation.xml:27
msgid "Move window one workspace to the right"
msgstr "Sposte barcon tal spazi di lavôr a drete"
#: data/50-mutter-navigation.xml:30
msgid "Move window one workspace up"
msgstr "Sposte barcon tal spazi di lavôr parsore"
#: data/50-mutter-navigation.xml:33
msgid "Move window one workspace down"
msgstr "Sposte barcon tal spazi di lavôr sot"
#: data/50-mutter-navigation.xml:36
msgid "Move window one monitor to the left"
msgstr "Sposte barcon tal visôr a çampe"
#: data/50-mutter-navigation.xml:39
msgid "Move window one monitor to the right"
msgstr "Sposte barcon tal visôr a drete"
#: data/50-mutter-navigation.xml:42
msgid "Move window one monitor up"
msgstr "Sposte barcon tal visôr parsore"
#: data/50-mutter-navigation.xml:45
msgid "Move window one monitor down"
msgstr "Sposte barcon tal visôr sot"
#: data/50-mutter-navigation.xml:49
msgid "Switch applications"
msgstr "Passâ di une aplicazion in chê altre"
#: data/50-mutter-navigation.xml:54
msgid "Switch to previous application"
msgstr "Passe ae aplicazion prime"
#: data/50-mutter-navigation.xml:58
msgid "Switch windows"
msgstr "Passâ di un barcon in chel altri"
#: data/50-mutter-navigation.xml:63
msgid "Switch to previous window"
msgstr "Passe al barcon prime"
#: data/50-mutter-navigation.xml:67
msgid "Switch windows of an application"
msgstr "Passâ di un barcon in chel altri di une aplicazion"
#: data/50-mutter-navigation.xml:72
msgid "Switch to previous window of an application"
msgstr "Passe al barcon prime di une aplicazion"
#: data/50-mutter-navigation.xml:76
msgid "Switch system controls"
msgstr "Passâ di un control di sisteme in chel altri"
#: data/50-mutter-navigation.xml:81
msgid "Switch to previous system control"
msgstr "Passe al control di sisteme precedent"
#: data/50-mutter-navigation.xml:85
msgid "Switch windows directly"
msgstr "Passe dret ai barcons"
#: data/50-mutter-navigation.xml:90
msgid "Switch directly to previous window"
msgstr "Passe dret al barcon precedent"
#: data/50-mutter-navigation.xml:94
msgid "Switch windows of an app directly"
msgstr "Passe dret a un barcon di une aplicazion"
#: data/50-mutter-navigation.xml:99
msgid "Switch directly to previous window of an app"
msgstr "Passe dret al barcon precedent di une aplicazion"
#: data/50-mutter-navigation.xml:103
msgid "Switch system controls directly"
msgstr "Passe dret ai controi dal sisteme"
#: data/50-mutter-navigation.xml:108
msgid "Switch directly to previous system control"
msgstr "Passe dret al control precedent dal sisteme"
#: data/50-mutter-navigation.xml:111
msgid "Hide all normal windows"
msgstr "Plate ducj i barcons normâi"
#: data/50-mutter-navigation.xml:114
msgid "Switch to workspace 1"
msgstr "Passe al spazi di lavôr 1"
#: data/50-mutter-navigation.xml:117
msgid "Switch to workspace 2"
msgstr "Passe al spazi di lavôr 2"
#: data/50-mutter-navigation.xml:120
msgid "Switch to workspace 3"
msgstr "Passe al spazi di lavôr 3"
#: data/50-mutter-navigation.xml:123
msgid "Switch to workspace 4"
msgstr "Passe al spazi di lavôr 4"
#: data/50-mutter-navigation.xml:126
msgid "Switch to last workspace"
msgstr "Passe al ultin spazi di lavôr"
#: data/50-mutter-navigation.xml:129
msgid "Move to workspace left"
msgstr "Sposte il spazi di lavôr a çampe"
#: data/50-mutter-navigation.xml:132
msgid "Move to workspace right"
msgstr "Sposte il spazi di lavôr a drete"
#: data/50-mutter-navigation.xml:135
msgid "Move to workspace above"
msgstr "Sposte il spazi di lavôr parsore"
#: data/50-mutter-navigation.xml:138
msgid "Move to workspace below"
msgstr "Sposte il spazi di lavôr sot"
#: data/50-mutter-system.xml:6
msgid "System"
msgstr "Sisteme"
#: data/50-mutter-system.xml:8
msgid "Show the run command prompt"
msgstr "Mostre la richieste \"eseguìs comant\""
#: data/50-mutter-system.xml:10
msgid "Show the activities overview"
msgstr "Mostre la panoramiche ativitâts"
#: data/50-mutter-windows.xml:6
msgid "Windows"
msgstr "Barcons"
#: data/50-mutter-windows.xml:8
msgid "Activate the window menu"
msgstr "Ative il menù dal barcon"
#: data/50-mutter-windows.xml:10
msgid "Toggle fullscreen mode"
msgstr "Ative/Disative modalitât plen visôr"
#: data/50-mutter-windows.xml:12
msgid "Toggle maximization state"
msgstr "Ative/Disative il stât slargjât"
#: data/50-mutter-windows.xml:14
msgid "Maximize window"
msgstr "Slargje il barcon"
#: data/50-mutter-windows.xml:16
msgid "Restore window"
msgstr "Ripristine barcon"
#: data/50-mutter-windows.xml:18
msgid "Toggle shaded state"
msgstr "Ative/Disative stât inrodolât"
#: data/50-mutter-windows.xml:20
msgid "Close window"
msgstr "Siere il barcon"
#: data/50-mutter-windows.xml:22
msgid "Hide window"
msgstr "Plate il barcon"
#: data/50-mutter-windows.xml:24
msgid "Move window"
msgstr "Sposte il barcon"
#: data/50-mutter-windows.xml:26
msgid "Resize window"
msgstr "Ridimensione barcon"
#: data/50-mutter-windows.xml:29
msgid "Toggle window on all workspaces or one"
msgstr "Ative/Disative barcon su ducj i spazis di lavôr o nome un"
#: data/50-mutter-windows.xml:31
msgid "Raise window if covered, otherwise lower it"
msgstr "Tire sù il barcon se al è cuviert, se no sbassilu"
#: data/50-mutter-windows.xml:33
msgid "Raise window above other windows"
msgstr "Met il barcon parsore di chei altris"
#: data/50-mutter-windows.xml:35
msgid "Lower window below other windows"
msgstr "Bute il barcon sot di chei altris"
#: data/50-mutter-windows.xml:37
msgid "Maximize window vertically"
msgstr "Slargje il barcon par verticâl"
#: data/50-mutter-windows.xml:39
msgid "Maximize window horizontally"
msgstr "Slargje il barcon par orizontâl"
#: data/50-mutter-windows.xml:43
msgid "View split on left"
msgstr "Slargje dividint ae çampe"
#: data/50-mutter-windows.xml:47
msgid "View split on right"
msgstr "Slargje dividint ae drete"
#: data/mutter.desktop.in:4
msgid "Mutter"
@ -155,11 +395,37 @@ msgstr ""
"Se metût a VÊR, i gnûfs barcons a vegnaran plaçâts simpri tal mieç dal "
"schermi atîf dal visôr."
#: data/org.gnome.mutter.gschema.xml.in:120
#: data/org.gnome.mutter.gschema.xml.in:107
msgid "Enable experimental features"
msgstr "Abilite funzionalitâts sperimentâls"
#: data/org.gnome.mutter.gschema.xml.in:108
msgid ""
"To enable experimental features, add the feature keyword to the list. "
"Whether the feature requires restarting the compositor depends on the given "
"feature. Any experimental feature is not required to still be available, or "
"configurable. Dont expect adding anything in this setting to be future "
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
"mutter default to layout logical monitors in a logical pixel coordinate "
"space, while scaling monitor framebuffers instead of window content, to "
"manage HiDPI monitors. Does not require a restart."
msgstr ""
"Par abilitâ lis funzionalitâts sperimentâls, zonte la peraule clâf de "
"funzionalitât ae liste. Il fat che la funzionalitât e vedi bisugne di tornâ "
"a inviâ il compositôr al dipent de funzionalitât dade. Cualsisei "
"funzionalitât sperimentâl no je necessarie che e sedi disponibile o "
"configurabile. No sta spietâti di zontâ alc in cheste impostazion e pensâ "
"che e duredi tal timp. Atualmentri lis peraulis clâf pussibilis a son: • "
"“scale-monitor-framebuffer” — al rint come predefinît par mutter la "
"disposizion dai visôrs logjics intun spazi logjic di coordenadis dai pixel, "
"intant i framebuffer dai visôrs par scjalâ, invezit dal contignût dal "
"barcon, a gjestissin i visôrs HiDPI. Nol covente tornâ a inviâ."
#: data/org.gnome.mutter.gschema.xml.in:141
msgid "Select window from tab popup"
msgstr "Selezione barcon dal tab popup"
#: data/org.gnome.mutter.gschema.xml.in:125
#: data/org.gnome.mutter.gschema.xml.in:146
msgid "Cancel tab popup"
msgstr "Anule tab popup"
@ -214,7 +480,7 @@ msgstr "Passe al VT 12"
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:1800
#: src/backends/meta-input-settings.c:1848
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Cambie mût (Grup %d)"
@ -222,37 +488,37 @@ msgstr "Cambie mût (Grup %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:1822
#: src/backends/meta-input-settings.c:1870
msgid "Switch monitor"
msgstr "Cambie visôr"
#: src/backends/meta-input-settings.c:1824
#: src/backends/meta-input-settings.c:1872
msgid "Show on-screen help"
msgstr "Mostre jutori a schermi"
#: src/backends/meta-monitor-manager.c:675
#: src/backends/meta-monitor-manager.c:783
msgid "Built-in display"
msgstr "Display integrât"
#: src/backends/meta-monitor-manager.c:698
#: src/backends/meta-monitor-manager.c:806
msgid "Unknown"
msgstr "No cognossût"
#: src/backends/meta-monitor-manager.c:700
#: src/backends/meta-monitor-manager.c:808
msgid "Unknown Display"
msgstr "Display no cognossût"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: src/backends/meta-monitor-manager.c:708
#: src/backends/meta-monitor-manager.c:816
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: src/compositor/compositor.c:471
#: src/compositor/compositor.c:474
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
@ -394,183 +660,3 @@ msgstr ""
#, c-format
msgid "%s (on %s)"
msgstr "%s (su %s)"
#~ msgid "Navigation"
#~ msgstr "Navigazion"
#~ msgid "Move window to workspace 1"
#~ msgstr "Sposte barcon tal spazi di lavôr 1"
#~ msgid "Move window to workspace 2"
#~ msgstr "Sposte barcon tal spazi di lavôr 2"
#~ msgid "Move window to workspace 3"
#~ msgstr "Sposte barcon tal spazi di lavôr 3"
#~ msgid "Move window to workspace 4"
#~ msgstr "Sposte barcon tal spazi di lavôr 4"
#~ msgid "Move window to last workspace"
#~ msgstr "Sposte barcon tal ultin spazi di lavôr"
#~ msgid "Move window one workspace to the left"
#~ msgstr "Sposte barcon tal spazi di lavôr a çampe"
#~ msgid "Move window one workspace to the right"
#~ msgstr "Sposte barcon tal spazi di lavôr a drete"
#~ msgid "Move window one workspace up"
#~ msgstr "Sposte barcon tal spazi di lavôr parsore"
#~ msgid "Move window one workspace down"
#~ msgstr "Sposte barcon tal spazi di lavôr sot"
#~ msgid "Move window one monitor to the left"
#~ msgstr "Sposte barcon tal visôr a çampe"
#~ msgid "Move window one monitor to the right"
#~ msgstr "Sposte barcon tal visôr a drete"
#~ msgid "Move window one monitor up"
#~ msgstr "Sposte barcon tal visôr parsore"
#~ msgid "Move window one monitor down"
#~ msgstr "Sposte barcon tal visôr sot"
#~ msgid "Switch applications"
#~ msgstr "Passâ di une aplicazion in chê altre"
#~ msgid "Switch to previous application"
#~ msgstr "Passe ae aplicazion prime"
#~ msgid "Switch windows"
#~ msgstr "Passâ di un barcon in chel altri"
#~ msgid "Switch to previous window"
#~ msgstr "Passe al barcon prime"
#~ msgid "Switch windows of an application"
#~ msgstr "Passâ di un barcon in chel altri di une aplicazion"
#~ msgid "Switch to previous window of an application"
#~ msgstr "Passe al barcon prime di une aplicazion"
#~ msgid "Switch system controls"
#~ msgstr "Passâ di un control di sisteme in chel altri"
#~ msgid "Switch to previous system control"
#~ msgstr "Passe al control di sisteme precedent"
#~ msgid "Switch windows directly"
#~ msgstr "Passe dret ai barcons"
#~ msgid "Switch directly to previous window"
#~ msgstr "Passe dret al barcon precedent"
#~ msgid "Switch windows of an app directly"
#~ msgstr "Passe dret a un barcon di une aplicazion"
#~ msgid "Switch directly to previous window of an app"
#~ msgstr "Passe dret al barcon precedent di une aplicazion"
#~ msgid "Switch system controls directly"
#~ msgstr "Passe dret ai controi dal sisteme"
#~ msgid "Switch directly to previous system control"
#~ msgstr "Passe dret al control precedent dal sisteme"
#~ msgid "Hide all normal windows"
#~ msgstr "Plate ducj i barcons normâi"
#~ msgid "Switch to workspace 1"
#~ msgstr "Passe al spazi di lavôr 1"
#~ msgid "Switch to workspace 2"
#~ msgstr "Passe al spazi di lavôr 2"
#~ msgid "Switch to workspace 3"
#~ msgstr "Passe al spazi di lavôr 3"
#~ msgid "Switch to workspace 4"
#~ msgstr "Passe al spazi di lavôr 4"
#~ msgid "Switch to last workspace"
#~ msgstr "Passe al ultin spazi di lavôr"
#~ msgid "Move to workspace left"
#~ msgstr "Sposte il spazi di lavôr a çampe"
#~ msgid "Move to workspace right"
#~ msgstr "Sposte il spazi di lavôr a drete"
#~ msgid "Move to workspace above"
#~ msgstr "Sposte il spazi di lavôr parsore"
#~ msgid "Move to workspace below"
#~ msgstr "Sposte il spazi di lavôr sot"
#~ msgid "System"
#~ msgstr "Sisteme"
#~ msgid "Show the run command prompt"
#~ msgstr "Mostre la richieste \"eseguìs comant\""
#~ msgid "Show the activities overview"
#~ msgstr "Mostre la panoramiche ativitâts"
#~ msgid "Windows"
#~ msgstr "Barcons"
#~ msgid "Activate the window menu"
#~ msgstr "Ative il menù dal barcon"
#~ msgid "Toggle fullscreen mode"
#~ msgstr "Ative/Disative modalitât plen visôr"
#~ msgid "Toggle maximization state"
#~ msgstr "Ative/Disative il stât slargjât"
#~ msgid "Maximize window"
#~ msgstr "Slargje il barcon"
#~ msgid "Restore window"
#~ msgstr "Ripristine barcon"
#~ msgid "Toggle shaded state"
#~ msgstr "Ative/Disative stât inrodolât"
#~ msgid "Close window"
#~ msgstr "Siere il barcon"
#~ msgid "Hide window"
#~ msgstr "Plate il barcon"
#~ msgid "Move window"
#~ msgstr "Sposte il barcon"
#~ msgid "Resize window"
#~ msgstr "Ridimensione barcon"
#~ msgid "Toggle window on all workspaces or one"
#~ msgstr "Ative/Disative barcon su ducj i spazis di lavôr o nome un"
#~ msgid "Raise window if covered, otherwise lower it"
#~ msgstr "Tire sù il barcon se al è cuviert, se no sbassilu"
#~ msgid "Raise window above other windows"
#~ msgstr "Met il barcon parsore di chei altris"
#~ msgid "Lower window below other windows"
#~ msgstr "Bute il barcon sot di chei altris"
#~ msgid "Maximize window vertically"
#~ msgstr "Slargje il barcon par verticâl"
#~ msgid "Maximize window horizontally"
#~ msgstr "Slargje il barcon par orizontâl"
#~ msgid "View split on left"
#~ msgstr "Slargje dividint ae çampe"
#~ msgid "View split on right"
#~ msgstr "Slargje dividint ae drete"

1175
po/hu.po

File diff suppressed because it is too large Load Diff

View File

@ -9,17 +9,17 @@
msgid ""
msgstr ""
"Project-Id-Version: mutter master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2017-02-16 01:44+0000\n"
"PO-Revision-Date: 2017-02-20 13:44+0700\n"
"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
"POT-Creation-Date: 2017-04-21 21:33+0000\n"
"PO-Revision-Date: 2017-04-23 14:39+0700\n"
"Last-Translator: Kukuh Syafaat <syafaatkukuh@gmail.com>\n"
"Language-Team: Indonesian <gnome-l10n-id@googlegroups.com>\n"
"Language: id\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.6.10\n"
"X-Generator: Poedit 1.8.11\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: data/50-mutter-navigation.xml:6
@ -398,11 +398,36 @@ msgstr ""
"Ketika berisi true, jendela baru akan selalu diletakkan di tengah dari layar "
"aktif dari monitor."
#: data/org.gnome.mutter.gschema.xml.in:120
#: data/org.gnome.mutter.gschema.xml.in:107
msgid "Enable experimental features"
msgstr "Aktifkan fitur eksperimental"
#: data/org.gnome.mutter.gschema.xml.in:108
msgid ""
"To enable experimental features, add the feature keyword to the list. "
"Whether the feature requires restarting the compositor depends on the given "
"feature. Any experimental feature is not required to still be available, or "
"configurable. Dont expect adding anything in this setting to be future "
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
"mutter default to layout logical monitors in a logical pixel coordinate "
"space, while scaling monitor framebuffers instead of window content, to "
"manage HiDPI monitors. Does not require a restart."
msgstr ""
"Untuk mengaktifkan fitur eksperimental, tambahkan kata kunci fitur ke dalam "
"daftar. Apakah fitur memerlukan nyala ulang kompositor tergantung pada fitur "
"yang diberikan. Setiap fitur eksperimental tidak diharuskan tetap tersedia, "
"atau dapat dikonfigurasi. Jangan berharap menambahkan apapun dalam "
"pengaturan ini sebagai bukti di masa depan. Saat ini kata kunci yang "
"mungkin: • \"scale-monitor-framebuffer\" — membuat mutter bawaan ke tata "
"letak monitor logikal dalam ruang koordinat pixel logikal, sementara skala "
"monitor framebuffer bukan konten jendela, untuk mengatur monitor HiDPI. "
"Tidak perlu nyala ulang."
#: data/org.gnome.mutter.gschema.xml.in:141
msgid "Select window from tab popup"
msgstr "Pilih jendela dari popup tab"
#: data/org.gnome.mutter.gschema.xml.in:125
#: data/org.gnome.mutter.gschema.xml.in:146
msgid "Cancel tab popup"
msgstr "Batalkan popup tab"
@ -457,7 +482,7 @@ msgstr "Bertukar ke VT 12"
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:1759
#: src/backends/meta-input-settings.c:1848
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Tukar Mode: (Grup %d)"
@ -465,37 +490,37 @@ msgstr "Tukar Mode: (Grup %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:1781
#: src/backends/meta-input-settings.c:1870
msgid "Switch monitor"
msgstr "Berpindah monitor"
#: src/backends/meta-input-settings.c:1783
#: src/backends/meta-input-settings.c:1872
msgid "Show on-screen help"
msgstr "Tampilkan bantuan pada layar"
#: src/backends/meta-monitor-manager.c:675
#: src/backends/meta-monitor-manager.c:783
msgid "Built-in display"
msgstr "Tampilan bawaan"
#: src/backends/meta-monitor-manager.c:698
#: src/backends/meta-monitor-manager.c:806
msgid "Unknown"
msgstr "Tak Dikenal"
#: src/backends/meta-monitor-manager.c:700
#: src/backends/meta-monitor-manager.c:808
msgid "Unknown Display"
msgstr "Tampilan Tak Dikenal"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: src/backends/meta-monitor-manager.c:708
#: src/backends/meta-monitor-manager.c:816
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: src/compositor/compositor.c:471
#: src/compositor/compositor.c:474
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."

482
po/tr.po
View File

@ -7,306 +7,312 @@
# İlker DAĞLI <ilker@ilkerdagli.info>, 2011.
# Muhammed EKEN <gnome@m-eken.com>, 2011.
# Muhammet Kara <muhammetk@gmail.com>, 2011, 2012, 2014, 2015, 2016.
# Furkan Ahmet Kara <furkanahmetkara.fk@gmail.com>, 2017.
# Emin Tufan Çetin <etcetin@gmail.com>, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: mutter master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2016-05-10 20:26+0000\n"
"PO-Revision-Date: 2016-05-26 22:25+0300\n"
"Last-Translator: Muhammet Kara <muhammetk@gmail.com>\n"
"Language-Team: Turkish <gnome-turk@gnome.org>\n"
"POT-Creation-Date: 2017-05-11 12:29+0000\n"
"PO-Revision-Date: 2017-05-13 17:23+0300\n"
"Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
"Language-Team: Türkçe <>\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.6\n"
"X-Generator: Gtranslator 2.91.7\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: ../data/50-mutter-navigation.xml.in.h:1
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
msgstr "Gezinme"
#: ../data/50-mutter-navigation.xml.in.h:2
#: data/50-mutter-navigation.xml:9
msgid "Move window to workspace 1"
msgstr "Pencereyi çalışma alanı 1'e taşı"
msgstr "Pencereyi çalışma alanı 1e taşı"
#: ../data/50-mutter-navigation.xml.in.h:3
#: data/50-mutter-navigation.xml:12
msgid "Move window to workspace 2"
msgstr "Pencereyi çalışma alanı 2'ye taşı"
msgstr "Pencereyi çalışma alanı 2ye taşı"
#: ../data/50-mutter-navigation.xml.in.h:4
#: data/50-mutter-navigation.xml:15
msgid "Move window to workspace 3"
msgstr "Pencereyi çalışma alanı 3'e taşı"
msgstr "Pencereyi çalışma alanı 3e taşı"
#: ../data/50-mutter-navigation.xml.in.h:5
#: data/50-mutter-navigation.xml:18
msgid "Move window to workspace 4"
msgstr "Pencereyi çalışma alanı 4'e taşı"
msgstr "Pencereyi çalışma alanı 4e taşı"
#: ../data/50-mutter-navigation.xml.in.h:6
#: data/50-mutter-navigation.xml:21
msgid "Move window to last workspace"
msgstr "Pencereyi son çalışma alanına taşı"
#: ../data/50-mutter-navigation.xml.in.h:7
#: data/50-mutter-navigation.xml:24
msgid "Move window one workspace to the left"
msgstr "Pencereyi soldaki çalışma alanına taşı"
#: ../data/50-mutter-navigation.xml.in.h:8
#: data/50-mutter-navigation.xml:27
msgid "Move window one workspace to the right"
msgstr "Pencereyi sağdaki çalışma alanına taşı"
#: ../data/50-mutter-navigation.xml.in.h:9
#: data/50-mutter-navigation.xml:30
msgid "Move window one workspace up"
msgstr "Pencereyi üstteki çalışma alanına taşı"
#: ../data/50-mutter-navigation.xml.in.h:10
#: data/50-mutter-navigation.xml:33
msgid "Move window one workspace down"
msgstr "Pencereyi alttaki çalışma alanına taşı"
#: ../data/50-mutter-navigation.xml.in.h:11
#: data/50-mutter-navigation.xml:36
msgid "Move window one monitor to the left"
msgstr "Pencereyi soldaki monitöre taşı"
#: ../data/50-mutter-navigation.xml.in.h:12
#: data/50-mutter-navigation.xml:39
msgid "Move window one monitor to the right"
msgstr "Pencereyi sağdaki monitöre taşı"
#: ../data/50-mutter-navigation.xml.in.h:13
#: data/50-mutter-navigation.xml:42
msgid "Move window one monitor up"
msgstr "Pencereyi üstteki monitöre taşı"
#: ../data/50-mutter-navigation.xml.in.h:14
#: data/50-mutter-navigation.xml:45
msgid "Move window one monitor down"
msgstr "Pencereyi alttaki monitöre taşı"
#: ../data/50-mutter-navigation.xml.in.h:15
#: data/50-mutter-navigation.xml:49
msgid "Switch applications"
msgstr "Uygulamalar arasında geçiş yap"
#: ../data/50-mutter-navigation.xml.in.h:16
#: data/50-mutter-navigation.xml:54
msgid "Switch to previous application"
msgstr "Önceki uygulamaya geç"
#: ../data/50-mutter-navigation.xml.in.h:17
#: data/50-mutter-navigation.xml:58
msgid "Switch windows"
msgstr "Pencereler arasında geçiş yap"
#: ../data/50-mutter-navigation.xml.in.h:18
#: data/50-mutter-navigation.xml:63
msgid "Switch to previous window"
msgstr "Önceki pencereye geç"
#: ../data/50-mutter-navigation.xml.in.h:19
#: data/50-mutter-navigation.xml:67
msgid "Switch windows of an application"
msgstr "Uygulamanın pencereleri arasında geçiş yap"
#: ../data/50-mutter-navigation.xml.in.h:20
#: data/50-mutter-navigation.xml:72
msgid "Switch to previous window of an application"
msgstr "Uygulamanın bir önceki penceresine geç"
#: ../data/50-mutter-navigation.xml.in.h:21
#: data/50-mutter-navigation.xml:76
msgid "Switch system controls"
msgstr "Sistem denetimleri arasında geçiş yap"
#: ../data/50-mutter-navigation.xml.in.h:22
#: data/50-mutter-navigation.xml:81
msgid "Switch to previous system control"
msgstr "Önceki sistem denetimine geç"
#: ../data/50-mutter-navigation.xml.in.h:23
#: data/50-mutter-navigation.xml:85
msgid "Switch windows directly"
msgstr "Pencereler arasında doğrudan geçiş yap"
#: ../data/50-mutter-navigation.xml.in.h:24
#: data/50-mutter-navigation.xml:90
msgid "Switch directly to previous window"
msgstr "Önceki pencereye doğrudan geç"
#: ../data/50-mutter-navigation.xml.in.h:25
#: data/50-mutter-navigation.xml:94
msgid "Switch windows of an app directly"
msgstr "Uygulamanın pencereleri arasında anında geçiş yap"
#: ../data/50-mutter-navigation.xml.in.h:26
#: data/50-mutter-navigation.xml:99
msgid "Switch directly to previous window of an app"
msgstr "Bir uygulamanın önceki penceresine doğrudan geç"
#: ../data/50-mutter-navigation.xml.in.h:27
#: data/50-mutter-navigation.xml:103
msgid "Switch system controls directly"
msgstr "Sistem denetimleri arasında doğrudan geçiş yap"
#: ../data/50-mutter-navigation.xml.in.h:28
#: data/50-mutter-navigation.xml:108
msgid "Switch directly to previous system control"
msgstr "Önceki sistem denetimine doğrudan geç"
#: ../data/50-mutter-navigation.xml.in.h:29
#: data/50-mutter-navigation.xml:111
msgid "Hide all normal windows"
msgstr "Tüm normal pencereleri gizle"
#: ../data/50-mutter-navigation.xml.in.h:30
#: data/50-mutter-navigation.xml:114
msgid "Switch to workspace 1"
msgstr "Çalışma alanı 1'e geç"
msgstr "Çalışma alanı 1e geç"
#: ../data/50-mutter-navigation.xml.in.h:31
#: data/50-mutter-navigation.xml:117
msgid "Switch to workspace 2"
msgstr "Çalışma alanı 2'ye geç"
msgstr "Çalışma alanı 2ye geç"
#: ../data/50-mutter-navigation.xml.in.h:32
#: data/50-mutter-navigation.xml:120
msgid "Switch to workspace 3"
msgstr "Çalışma alanı 3'e geç"
msgstr "Çalışma alanı 3e geç"
#: ../data/50-mutter-navigation.xml.in.h:33
#: data/50-mutter-navigation.xml:123
msgid "Switch to workspace 4"
msgstr "Çalışma alanı 4'e geç"
msgstr "Çalışma alanı 4e geç"
#: ../data/50-mutter-navigation.xml.in.h:34
#: data/50-mutter-navigation.xml:126
msgid "Switch to last workspace"
msgstr "Son çalışma alanına geç"
#: ../data/50-mutter-navigation.xml.in.h:35
#: data/50-mutter-navigation.xml:129
msgid "Move to workspace left"
msgstr "Soldaki çalışma alanına taşı"
#: ../data/50-mutter-navigation.xml.in.h:36
#: data/50-mutter-navigation.xml:132
msgid "Move to workspace right"
msgstr "Sağdaki çalışma alanına taşı"
#: ../data/50-mutter-navigation.xml.in.h:37
#: data/50-mutter-navigation.xml:135
msgid "Move to workspace above"
msgstr "Üstteki çalışma alanına taşı"
#: ../data/50-mutter-navigation.xml.in.h:38
#: data/50-mutter-navigation.xml:138
msgid "Move to workspace below"
msgstr "Alttaki çalışma alanına taşı"
#: ../data/50-mutter-system.xml.in.h:1
#: data/50-mutter-system.xml:6
msgid "System"
msgstr "Sistem"
#: ../data/50-mutter-system.xml.in.h:2
#: data/50-mutter-system.xml:8
msgid "Show the run command prompt"
msgstr "Komut çalıştırma istemini göster"
#: ../data/50-mutter-system.xml.in.h:3
#: data/50-mutter-system.xml:10
msgid "Show the activities overview"
msgstr "Etkinlik genel görünümünü göster"
#: ../data/50-mutter-windows.xml.in.h:1
#: data/50-mutter-windows.xml:6
msgid "Windows"
msgstr "Pencereler"
#: ../data/50-mutter-windows.xml.in.h:2
#: data/50-mutter-windows.xml:8
msgid "Activate the window menu"
msgstr "Pencere menüsünü etkinleştir"
#: ../data/50-mutter-windows.xml.in.h:3
#: data/50-mutter-windows.xml:10
msgid "Toggle fullscreen mode"
msgstr "Tam ekran kipini aç veya kapat"
msgstr "Tam ekran kipini değiştir"
#: ../data/50-mutter-windows.xml.in.h:4
#: data/50-mutter-windows.xml:12
msgid "Toggle maximization state"
msgstr "Ekranı kaplama durumunu aç veya kapat"
msgstr "Ekranı kaplama durumunu değiştir"
#: ../data/50-mutter-windows.xml.in.h:5
#: data/50-mutter-windows.xml:14
msgid "Maximize window"
msgstr "Bencereyi büyült"
#: ../data/50-mutter-windows.xml.in.h:6
#: data/50-mutter-windows.xml:16
msgid "Restore window"
msgstr "Pencereyi geri al"
msgstr "Pencereyi eski haline getir"
#: ../data/50-mutter-windows.xml.in.h:7
#: data/50-mutter-windows.xml:18
msgid "Toggle shaded state"
msgstr "Toplanmış durumu aç veya kapat"
msgstr "Toplanmış durumu değiştir"
#: ../data/50-mutter-windows.xml.in.h:8
#: data/50-mutter-windows.xml:20
msgid "Close window"
msgstr "Pencereyi kapat"
#: ../data/50-mutter-windows.xml.in.h:9
#: data/50-mutter-windows.xml:22
msgid "Hide window"
msgstr "Pencereyi gizle"
#: ../data/50-mutter-windows.xml.in.h:10
#: data/50-mutter-windows.xml:24
msgid "Move window"
msgstr "Pencere taşı"
#: ../data/50-mutter-windows.xml.in.h:11
#: data/50-mutter-windows.xml:26
msgid "Resize window"
msgstr "Pencereyi yeniden boyutlandır"
#: ../data/50-mutter-windows.xml.in.h:12
#: data/50-mutter-windows.xml:29
msgid "Toggle window on all workspaces or one"
msgstr ""
"Pencerenin tüm çalışma alanlarında veya sadece bir tanesi üzerinde olmasını "
"seç"
"Pencerenin tüm çalışma alanlarında veya yalnızca bir tanesi üzerinde "
"olmasını seç"
#: ../data/50-mutter-windows.xml.in.h:13
#: data/50-mutter-windows.xml:31
msgid "Raise window if covered, otherwise lower it"
msgstr ""
"Pencere eğer başkası tarafından kapatılmışsa yukarı çıkar, yoksa aşağıya it"
msgstr "Pencere altta kalmışsa yükselt, aksi halde alçalt"
#: ../data/50-mutter-windows.xml.in.h:14
#: data/50-mutter-windows.xml:33
msgid "Raise window above other windows"
msgstr "Pencereyi diğerlerinin üstüne çıkar"
#: ../data/50-mutter-windows.xml.in.h:15
#: data/50-mutter-windows.xml:35
msgid "Lower window below other windows"
msgstr "Pencereyi diğerlerinin altına gönder"
#: ../data/50-mutter-windows.xml.in.h:16
#: data/50-mutter-windows.xml:37
msgid "Maximize window vertically"
msgstr "Pencereyi dikey olarak büyült"
#: ../data/50-mutter-windows.xml.in.h:17
#: data/50-mutter-windows.xml:39
msgid "Maximize window horizontally"
msgstr "Pencereyi yatay olarak büyült"
#: ../data/50-mutter-windows.xml.in.h:18
#: data/50-mutter-windows.xml:43
msgid "View split on left"
msgstr "Solda bölünmüş olarak göster"
#: ../data/50-mutter-windows.xml.in.h:19
#: data/50-mutter-windows.xml:47
msgid "View split on right"
msgstr "Sağda bölünmüş olarak göster"
#: ../data/mutter.desktop.in.h:1
#: data/mutter.desktop.in:4
msgid "Mutter"
msgstr "Mutter"
#: ../data/org.gnome.mutter.gschema.xml.in.h:1
#: data/org.gnome.mutter.gschema.xml.in:7
msgid "Modifier to use for extended window management operations"
msgstr "Genişletilmiş pencere yönetimi işlemleri için kullanılacak değiştirici"
#: ../data/org.gnome.mutter.gschema.xml.in.h:2
#: data/org.gnome.mutter.gschema.xml.in:8
#| msgid ""
#| "This key will initiate the \"overlay\", which is a combination window "
#| "overview and application launching system. The default is intended to be "
#| "the \"Windows key\" on PC hardware. It's expected that this binding "
#| "either the default or set to the empty string."
msgid ""
"This key will initiate the \"overlay\", which is a combination window "
"overview and application launching system. The default is intended to be the "
"\"Windows key\" on PC hardware. It's expected that this binding either the "
"default or set to the empty string."
"This key will initiate the overlay, which is a combination window overview "
"and application launching system. The default is intended to be the “Windows "
"key on PC hardware. Its expected that this binding either the default or "
"set to the empty string."
msgstr ""
"Bu anahtar, pencere genel görünümü ve uygulama başlatma sisteminin bir "
"birleşimi olan \"bindirme\" işlemini başlatır. Öntanımlı olarak PC "
"donanımındaki \"windows tuşu\" olması tasarlanmıştır. Bağlayıcı varsayılan "
"olarak veya boş dize olarak ayarlanması beklenir."
"Bu tuş, pencere genel görünümü ve uygulama başlatma sisteminin bir birleşimi "
"olan bindirme işlemini başlatır. Öntanımlı olarak PC donanımındaki "
"“Windows tuşu olması tasarlanmıştır. Bu bağlayıcının öntanımlı veya boş "
"dizge olarak ayarlanması beklenir."
#: ../data/org.gnome.mutter.gschema.xml.in.h:3
#: data/org.gnome.mutter.gschema.xml.in:20
msgid "Attach modal dialogs"
msgstr "Yardımcı diyalogları ekle"
#: ../data/org.gnome.mutter.gschema.xml.in.h:4
#: data/org.gnome.mutter.gschema.xml.in:21
msgid ""
"When true, instead of having independent titlebars, modal dialogs appear "
"attached to the titlebar of the parent window and are moved together with "
"the parent window."
msgstr ""
"Eğer \"doğru\" ise, bağımsız başlık çubuklarına sahip olduğundan, yardım "
"diyalogları üst pencerenin başlık çubuğunda ekli gözükür ve üst pencere ile "
"birlikte hareket eder."
"Seçili olduğunda, bağımsız başlık çubuklarına sahip olmak yerine, kipsel "
"diyaloglar üst pencerenin başlık çubuğunda ekli gözükür ve üst pencere ile "
"birlikte hareket ettirilebilirler."
#: ../data/org.gnome.mutter.gschema.xml.in.h:5
#: data/org.gnome.mutter.gschema.xml.in:30
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
"Pencereler ekran kenarlarında bırakıldığında kenar döşemeyi etkinleştir."
#: ../data/org.gnome.mutter.gschema.xml.in.h:6
#: data/org.gnome.mutter.gschema.xml.in:31
msgid ""
"If enabled, dropping windows on vertical screen edges maximizes them "
"vertically and resizes them horizontally to cover half of the available "
@ -317,13 +323,13 @@ msgstr ""
"şekilde yeniden boyutlandırılır. Ekranın tepedeki kenarına bırakılan "
"pencereler ekranı tamamen kaplar."
#: ../data/org.gnome.mutter.gschema.xml.in.h:7
#: data/org.gnome.mutter.gschema.xml.in:40
msgid "Workspaces are managed dynamically"
msgstr "Çalışma alanları dinamik olarak yönetilir"
#: ../data/org.gnome.mutter.gschema.xml.in.h:8
#: data/org.gnome.mutter.gschema.xml.in:41
msgid ""
"Determines whether workspaces are managed dynamically or whether there's a "
"Determines whether workspaces are managed dynamically or whether theres a "
"static number of workspaces (determined by the num-workspaces key in org."
"gnome.desktop.wm.preferences)."
msgstr ""
@ -331,23 +337,23 @@ msgstr ""
"çalışma alanı mı olacağını belirler (org.gnome.desktop.wm.preferences "
"içindeki num-workspaces değişkeni tarafından belirlenir)."
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
#: data/org.gnome.mutter.gschema.xml.in:50
msgid "Workspaces only on primary"
msgstr "Sadece birincil monitördeki çalışma alanları"
msgstr "Yalnızca birincil monitördeki çalışma alanları"
#: ../data/org.gnome.mutter.gschema.xml.in.h:10
#: data/org.gnome.mutter.gschema.xml.in:51
msgid ""
"Determines whether workspace switching should happen for windows on all "
"monitors or only for windows on the primary monitor."
msgstr ""
"Çalışma alanı değiştirilmesinin, tüm monitörlerdeki pencerelerde mi yoksa "
"sadece birincil monitördekilerde mi gerçekleşeceğini belirler."
"yalnızca birincil monitördekilerde mi gerçekleşeceğini belirler."
#: ../data/org.gnome.mutter.gschema.xml.in.h:11
#: data/org.gnome.mutter.gschema.xml.in:59
msgid "No tab popup"
msgstr "Sekme açılır penceresi yok"
#: ../data/org.gnome.mutter.gschema.xml.in.h:12
#: data/org.gnome.mutter.gschema.xml.in:60
msgid ""
"Determines whether the use of popup and highlight frame should be disabled "
"for window cycling."
@ -355,37 +361,42 @@ msgstr ""
"Pencere geçişinde çerçeve vurgulanması ve açılır pencere kullanımının "
"kapatılıp kapatılmayacağını belirler."
#: ../data/org.gnome.mutter.gschema.xml.in.h:13
#: data/org.gnome.mutter.gschema.xml.in:68
msgid "Delay focus changes until the pointer stops moving"
msgstr "Odak değişikliklerini işaretçi hareketi durana kadar ertele"
#: ../data/org.gnome.mutter.gschema.xml.in.h:14
#: data/org.gnome.mutter.gschema.xml.in:69
#| msgid ""
#| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
#| "the focus will not be changed immediately when entering a window, but "
#| "only after the pointer stops moving."
msgid ""
"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
"the focus will not be changed immediately when entering a window, but only "
"after the pointer stops moving."
"If set to true, and the focus mode is either sloppy or mouse then the "
"focus will not be changed immediately when entering a window, but only after "
"the pointer stops moving."
msgstr ""
"Eğer seçiliyse ve odaklama kipi \"sloppy\" ya da \"mouse\" ise bir pencereye "
"geçişte odak hemen değil, fakat işaretçi hareket etmeyi bıraktığında değişir."
"Eğer seçiliyse ve odaklama kipi sloppy yada mouse ise bir pencereye "
"geçişte odak hemen değil, yanlızca işaretçi hareket etmeyi bıraktığında "
"değişir."
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
#: data/org.gnome.mutter.gschema.xml.in:79
msgid "Draggable border width"
msgstr "Sürüklenebilir kenarlık genişliği"
#: ../data/org.gnome.mutter.gschema.xml.in.h:16
#: data/org.gnome.mutter.gschema.xml.in:80
msgid ""
"The amount of total draggable borders. If the theme's visible borders are "
"The amount of total draggable borders. If the themes visible borders are "
"not enough, invisible borders will be added to meet this value."
msgstr ""
"Sürüklenebilir kenarlıkların toplam miktarı. Eğer temanın görünür "
"kenarlıkları yetersiz gelirse, bu değere ulaşmak için görünmez kenarlıklar "
"eklenir."
#: ../data/org.gnome.mutter.gschema.xml.in.h:17
#: data/org.gnome.mutter.gschema.xml.in:89
msgid "Auto maximize nearly monitor sized windows"
msgstr "Ekran boyutuna yakın pencereleri otomatik ekranı kaplat"
#: ../data/org.gnome.mutter.gschema.xml.in.h:18
#: data/org.gnome.mutter.gschema.xml.in:90
msgid ""
"If enabled, new windows that are initially the size of the monitor "
"automatically get maximized."
@ -393,11 +404,11 @@ msgstr ""
"Etkinleştirildiğinde ekran boyutunda başlayan yeni pencereler otomatik "
"olarak ekranı kaplar."
#: ../data/org.gnome.mutter.gschema.xml.in.h:19
#: data/org.gnome.mutter.gschema.xml.in:98
msgid "Place new windows in the center"
msgstr "Yeni pencereleri ekranın ortasına yerleştir"
#: ../data/org.gnome.mutter.gschema.xml.in.h:20
#: data/org.gnome.mutter.gschema.xml.in:99
msgid ""
"When true, the new windows will always be put in the center of the active "
"screen of the monitor."
@ -405,218 +416,277 @@ msgstr ""
"Etkinleştirildiğinde, yeni pencereler her zaman monitörün etkin ekranında "
"ortaya yerleştirilir."
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
#: data/org.gnome.mutter.gschema.xml.in:107
msgid "Enable experimental features"
msgstr "Deneysel özellikleri etkinleştir"
#: data/org.gnome.mutter.gschema.xml.in:108
msgid ""
"To enable experimental features, add the feature keyword to the list. "
"Whether the feature requires restarting the compositor depends on the given "
"feature. Any experimental feature is not required to still be available, or "
"configurable. Dont expect adding anything in this setting to be future "
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
"mutter default to layout logical monitors in a logical pixel coordinate "
"space, while scaling monitor framebuffers instead of window content, to "
"manage HiDPI monitors. Does not require a restart."
msgstr ""
"Deneysel özellikleri etkinleştirmek için özelliğin anahtar sözcüğünü listeye "
"ekleyin. Özelliğin yeniden başlatmayı gerektirip gerektirmeyeceği verilen "
"özelliğe bağlıdır. Hiçbir deneysel özellik hala kullanılabilir veya "
"yapılandırılabilir olmak zorunda değildir. Bu ayara eklenecek herhangi bir "
"şeyin gelecekte olabilecek değişikliklerden etkilenmeyeceğini düşünmeyin. Şu "
"anda kullanılabilir anahtar sözcükler: • “scale-monitor-framebuffer” — "
"mutterin HiDPI monitörleri yönetmesi için pencere içeriği yerine monitör "
"çerçeve arabelleğini ölçeklendirirken, mantıksal monitörleri mantıksal "
"piksel koordinat aralığına yerleştirmesini öntanımlı yapar."
#: data/org.gnome.mutter.gschema.xml.in:141
msgid "Select window from tab popup"
msgstr "Pencereyi, sekme açılır penceresinden seç"
#: ../data/org.gnome.mutter.gschema.xml.in.h:22
#: data/org.gnome.mutter.gschema.xml.in:146
msgid "Cancel tab popup"
msgstr "Sekmeyi yeni pencerede açmayı iptal et"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1
#: data/org.gnome.mutter.wayland.gschema.xml.in:6
msgid "Switch to VT 1"
msgstr "VT 1'e geç"
msgstr "VT 1e geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2
#: data/org.gnome.mutter.wayland.gschema.xml.in:10
msgid "Switch to VT 2"
msgstr "VT 2'ye geç"
msgstr "VT 2ye geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3
#: data/org.gnome.mutter.wayland.gschema.xml.in:14
msgid "Switch to VT 3"
msgstr "VT 3'e geç"
msgstr "VT 3e geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4
#: data/org.gnome.mutter.wayland.gschema.xml.in:18
msgid "Switch to VT 4"
msgstr "VT 4'e geç"
msgstr "VT 4e geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5
#: data/org.gnome.mutter.wayland.gschema.xml.in:22
msgid "Switch to VT 5"
msgstr "VT 5'e geç"
msgstr "VT 5e geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6
#: data/org.gnome.mutter.wayland.gschema.xml.in:26
msgid "Switch to VT 6"
msgstr "VT 6'ya geç"
msgstr "VT 6ya geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7
#: data/org.gnome.mutter.wayland.gschema.xml.in:30
msgid "Switch to VT 7"
msgstr "VT 7'ye geç"
msgstr "VT 7ye geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
#: data/org.gnome.mutter.wayland.gschema.xml.in:34
msgid "Switch to VT 8"
msgstr "VT 8'e geç"
msgstr "VT 8e geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
#: data/org.gnome.mutter.wayland.gschema.xml.in:38
msgid "Switch to VT 9"
msgstr "VT 9'a geç"
msgstr "VT 9a geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
#: data/org.gnome.mutter.wayland.gschema.xml.in:42
msgid "Switch to VT 10"
msgstr "VT 10'a geç"
msgstr "VT 10a geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
#: data/org.gnome.mutter.wayland.gschema.xml.in:46
msgid "Switch to VT 11"
msgstr "VT 11'e geç"
msgstr "VT 11e geç"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
#: data/org.gnome.mutter.wayland.gschema.xml.in:50
msgid "Switch to VT 12"
msgstr "VT 12'ye geç"
msgstr "VT 12ye geç"
#: ../src/backends/meta-monitor-manager.c:515
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:1848
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Kip anahtarı (Group %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:1870
msgid "Switch monitor"
msgstr "Monitör değiştir"
#: src/backends/meta-input-settings.c:1872
msgid "Show on-screen help"
msgstr "Ekranda yardımı göster"
#: src/backends/meta-monitor-manager.c:783
msgid "Built-in display"
msgstr "Yerleşik ekran"
#: ../src/backends/meta-monitor-manager.c:538
#: src/backends/meta-monitor-manager.c:806
msgid "Unknown"
msgstr "Bilinmiyor"
#: ../src/backends/meta-monitor-manager.c:540
#: src/backends/meta-monitor-manager.c:808
msgid "Unknown Display"
msgstr "Bilinmeyen Ekran"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c:548
#: src/backends/meta-monitor-manager.c:816
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: ../src/compositor/compositor.c:456
#: src/compositor/compositor.c:476
#, c-format
#| msgid ""
#| "Another compositing manager is already running on screen %i on display "
#| "\"%s\"."
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
"Another compositing manager is already running on screen %i on display “%s”."
msgstr ""
"\"%2$s\" monitöründeki %1$i ekranında zaten başka bir birleştirme yöneticisi "
"çalışıyor."
"%2$s monitöründeki %1$i ekranında zaten başka bir birleştirme yöneticisi çalışıyor."
#: ../src/core/bell.c:194
#: src/core/bell.c:194
msgid "Bell event"
msgstr "Etkinlik zili"
#: ../src/core/delete.c:127
#. Translators: %s is a window title
#: src/core/delete.c:127
#, c-format
msgid "“%s” is not responding."
msgstr "“%s” yanıt vermiyor."
#: ../src/core/delete.c:129
#: src/core/delete.c:129
msgid "Application is not responding."
msgstr "Uygulama cevap vermiyor"
#: ../src/core/delete.c:134
#: src/core/delete.c:134
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Uygulamanın devam etmesi için bir müddet bekleyi seçebilirsiniz ya d a "
"Uygulamanın devam etmesi için bir müddet bekleyi seçebilirsiniz ya da "
"uygulamanın tamamen çıkması için onu zorlayabilirsiniz."
#: ../src/core/delete.c:141
msgid "_Wait"
msgstr "_Bekle"
#: ../src/core/delete.c:141
#: src/core/delete.c:141
msgid "_Force Quit"
msgstr "_Sonlandır"
#: ../src/core/display.c:555
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "X Pencere Sistemi '%s' ekranıılamadı\n"
#: src/core/delete.c:141
msgid "_Wait"
msgstr "_Bekle"
#: ../src/core/main.c:181
#: src/core/display.c:608
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "X Pencere Sistemi “%s” ekranıılamadı\n"
#: src/core/main.c:189
msgid "Disable connection to session manager"
msgstr "Ortam yöneticisine olan bağlantıyı kapat"
#: ../src/core/main.c:187
#: src/core/main.c:195
msgid "Replace the running window manager"
msgstr "Çalışan pencere yöneticisinin yerini al"
#: ../src/core/main.c:193
#: src/core/main.c:201
msgid "Specify session management ID"
msgstr "Ortam yönetim ID'sini belirtin"
msgstr "Ortam yönetim IDsini belirt"
#: ../src/core/main.c:198
#: src/core/main.c:206
msgid "X Display to use"
msgstr "Kullanılacak X Ekranı"
#: ../src/core/main.c:204
#: src/core/main.c:212
msgid "Initialize session from savefile"
msgstr "Ortamı kayıtlı dosyadan başlat"
#: ../src/core/main.c:210
#: src/core/main.c:218
msgid "Make X calls synchronous"
msgstr "X çağrılarını eşazamanlı yap"
#: ../src/core/main.c:217
#: src/core/main.c:225
msgid "Run as a wayland compositor"
msgstr "Bir wayland dizgicisi olarak çalıştır"
#: ../src/core/main.c:223
#: src/core/main.c:231
msgid "Run as a nested compositor"
msgstr "Yuvalanmış dizgici olarak çalıştır"
#: ../src/core/main.c:231
#: src/core/main.c:239
msgid "Run as a full display server, rather than nested"
msgstr "İç içe değil tam ekran sunucusu olarak çalıştır"
#: ../src/core/mutter.c:39
#: src/core/mutter.c:39
#, c-format
#| msgid ""
#| "mutter %s\n"
#| "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
#| "This is free software; see the source for copying conditions.\n"
#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A "
#| "PARTICULAR PURPOSE.\n"
msgid ""
"mutter %s\n"
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"This is free software; see the source for copying conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A "
"PARTICULAR PURPOSE.\n"
msgstr ""
"mutter %s\n"
"Telif Hakkı (C) 2001-%d Havoc Pennington, Red Hat, Inc., ve diğerleri\n"
"Bu bir özgür yazılımdır; telif koşullarını öğrenmek için kaynak koda bakın.\n"
"Hiç bir garantisi, BELİRLİ BİR AMACA UYGUNLUĞU için dahi, YOKTUR.\n"
"Telif Hakkı © 2001-%d Havoc Pennington, Red Hat, Inc., ve diğerleri\n"
"Bu bir özgür yazılımdır; kopyalama koşullarını öğrenmek için kaynağa bakın.\n"
"Hiçbir garanti YOK; BELİRLİ BİR AMACA UYGUNLUK ya da SATILABİLİRLİK için "
"dahi.\n"
#: ../src/core/mutter.c:53
#: src/core/mutter.c:53
msgid "Print version"
msgstr "Sürümü yazdır"
#: ../src/core/mutter.c:59
#: src/core/mutter.c:59
msgid "Mutter plugin to use"
msgstr "Kullanılacak Mutter eklentisi"
#: ../src/core/prefs.c:1997
#: src/core/prefs.c:1997
#, c-format
msgid "Workspace %d"
msgstr "Çalışma Alanı %d"
#: ../src/core/screen.c:521
#: src/core/screen.c:580
#, c-format
msgid ""
"Display \"%s\" already has a window manager; try using the --replace option "
"to replace the current window manager."
"Display “%s” already has a window manager; try using the --replace option to "
"replace the current window manager."
msgstr ""
"\"%s\" ekranı zaten bir pencere yöneticisine sahip; geçerli pencere "
"“%s” ekranı zaten bir pencere yöneticisine sahip; geçerli pencere "
"yöneticisinin yerine bir başkasını koymak için --replace seçeneğini "
"kullanmayı deneyin."
#: ../src/core/screen.c:603
#: src/core/screen.c:665
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "'%2$s' X oturumundaki ekran %1$d geçersiz\n"
#| msgid "Screen %d on display '%s' is invalid\n"
msgid "Screen %d on display “%s” is invalid\n"
msgstr "“%2$s” monitöründeki %1$d ekranı geçersiz\n"
#: ../src/core/util.c:121
#: src/core/util.c:120
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter, ayrıntılı kip desteği olmadan derlenmiş\n"
#: ../src/x11/session.c:1815
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
msgstr ""
"Bu pencereler, &quot;geçerli ayarları kaydet&quot; özelliğini desteklemiyor "
"ve bir dahaki girişinizde elle yeniden başlatmanız gerekecek."
#: src/wayland/meta-wayland-tablet-pad.c:563
#, c-format
msgid "Mode Switch: Mode %d"
msgstr "Kip Anahtarı: Kip %d"
#: ../src/x11/window-props.c:549
#: src/x11/session.c:1815
msgid ""
"These windows do not support “save current setup” and will have to be "
"restarted manually next time you log in."
msgstr ""
"Bu pencereler, “geçerli ayarları kaydet” özelliğini desteklemiyor ve bir "
"dahaki girişinizde elle yeniden başlatılmak zorunda."
#: src/x11/window-props.c:559
#, c-format
msgid "%s (on %s)"
msgstr "%s (%s üzerinde)"

View File

@ -137,10 +137,14 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/x11/meta-cursor-renderer-x11.h \
backends/x11/cm/meta-backend-x11-cm.c \
backends/x11/cm/meta-backend-x11-cm.h \
backends/x11/cm/meta-renderer-x11-cm.c \
backends/x11/cm/meta-renderer-x11-cm.h \
backends/x11/nested/meta-backend-x11-nested.c \
backends/x11/nested/meta-backend-x11-nested.h \
backends/x11/nested/meta-cursor-renderer-x11-nested.c \
backends/x11/nested/meta-cursor-renderer-x11-nested.h \
backends/x11/nested/meta-renderer-x11-nested.c \
backends/x11/nested/meta-renderer-x11-nested.h \
backends/x11/meta-idle-monitor-xsync.c \
backends/x11/meta-idle-monitor-xsync.h \
backends/x11/meta-input-settings-x11.c \
@ -218,6 +222,10 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
core/constraints.c \
core/constraints.h \
core/core.c \
core/meta-close-dialog.c \
meta/meta-close-dialog.h \
core/meta-close-dialog-default.c \
core/meta-close-dialog-default-private.h \
core/delete.c \
core/display.c \
core/display-private.h \
@ -431,6 +439,7 @@ libmutterinclude_headers = \
meta/meta-background-actor.h \
meta/meta-background-image.h \
meta/meta-background-group.h \
meta/meta-close-dialog.h \
meta/meta-cursor-tracker.h \
meta/meta-dnd.h \
meta/meta-idle-monitor.h \

View File

@ -97,8 +97,17 @@ struct _MetaBackendClass
};
typedef enum _MetaExperimentalFeature
{
META_EXPERIMENTAL_FEATURE_NONE = 0,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER = (1 << 1)
} MetaExperimentalFeature;
void meta_init_backend (GType backend_gtype);
void meta_backend_display_opened (MetaBackend *backend);
ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend);
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
@ -146,8 +155,27 @@ ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend);
void meta_backend_monitors_changed (MetaBackend *backend);
gboolean meta_backend_is_experimental_feature_enabled (MetaBackend *backend,
MetaExperimentalFeature feature);
MetaExperimentalFeature meta_backend_get_experimental_features (MetaBackend *backend);
void meta_backend_override_experimental_features (MetaBackend *backend);
void meta_backend_enable_experimental_feature (MetaBackend *backend,
MetaExperimentalFeature feature);
gboolean meta_is_stage_views_enabled (void);
gboolean meta_is_stage_views_scaled (void);
MetaInputSettings *meta_backend_get_input_settings (MetaBackend *backend);
void meta_backend_notify_keymap_changed (MetaBackend *backend);
void meta_backend_notify_keymap_layout_group_changed (MetaBackend *backend,
unsigned int locked_group);
void meta_backend_notify_ui_scaling_factor_changed (MetaBackend *backend);
#endif /* META_BACKEND_PRIVATE_H */

View File

@ -43,9 +43,25 @@
#include "backends/meta-idle-monitor-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor-manager-dummy.h"
#include "ui/theme-private.h"
enum
{
KEYMAP_CHANGED,
KEYMAP_LAYOUT_GROUP_CHANGED,
LAST_DEVICE_CHANGED,
EXPERIMENTAL_FEATURES_CHANGED,
UI_SCALING_FACTOR_CHANGED,
N_SIGNALS
};
static guint signals[N_SIGNALS];
static MetaBackend *_backend;
static gboolean stage_views_disabled = FALSE;
/**
* meta_get_backend:
*
@ -68,6 +84,10 @@ struct _MetaBackendPrivate
MetaRenderer *renderer;
MetaEgl *egl;
GSettings *mutter_settings;
MetaExperimentalFeature experimental_features;
gboolean experimental_features_overridden;
ClutterBackend *clutter_backend;
ClutterActor *stage;
@ -79,6 +99,8 @@ struct _MetaBackendPrivate
MetaPointerConstraint *client_pointer_constraint;
MetaDnd *dnd;
int ui_scaling_factor;
};
typedef struct _MetaBackendPrivate MetaBackendPrivate;
@ -133,6 +155,25 @@ center_pointer (MetaBackend *backend)
primary->rect.y + primary->rect.height / 2);
}
static gboolean
meta_backend_update_ui_scaling_factor (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
int ui_scaling_factor;
ui_scaling_factor = meta_backend_get_ui_scaling_factor (backend);
if (ui_scaling_factor != priv->ui_scaling_factor)
{
priv->ui_scaling_factor = ui_scaling_factor;
return TRUE;
}
else
{
return FALSE;
}
}
void
meta_backend_monitors_changed (MetaBackend *backend)
{
@ -152,6 +193,9 @@ meta_backend_monitors_changed (MetaBackend *backend)
!meta_monitor_manager_is_headless (monitor_manager))
center_pointer (backend);
}
if (meta_backend_update_ui_scaling_factor (backend))
meta_backend_notify_ui_scaling_factor_changed (backend);
}
void
@ -321,6 +365,8 @@ meta_backend_real_post_init (MetaBackend *backend)
meta_backend_sync_screen_size (backend);
meta_backend_update_ui_scaling_factor (backend);
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
priv->device_monitors =
@ -403,9 +449,109 @@ meta_backend_real_get_relative_motion_deltas (MetaBackend *backend,
return FALSE;
}
static gboolean
experimental_features_handler (GVariant *features_variant,
gpointer *result,
gpointer data)
{
MetaBackend *backend = data;
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
GVariantIter features_iter;
char *feature;
MetaExperimentalFeature features = META_EXPERIMENTAL_FEATURE_NONE;
if (priv->experimental_features_overridden)
{
*result = GINT_TO_POINTER (FALSE);
return TRUE;
}
g_variant_iter_init (&features_iter, features_variant);
while (g_variant_iter_loop (&features_iter, "s", &feature))
{
/* So far no experimental features defined. */
if (g_str_equal (feature, "scale-monitor-framebuffer"))
features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER;
else if (g_str_equal (feature, "monitor-config-manager"))
features |= META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER;
else
g_info ("Unknown experimental feature '%s'\n", feature);
}
if (features != priv->experimental_features)
{
priv->experimental_features = features;
*result = GINT_TO_POINTER (TRUE);
}
else
{
*result = GINT_TO_POINTER (FALSE);
}
return TRUE;
}
static gboolean
update_experimental_features (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
return GPOINTER_TO_INT (g_settings_get_mapped (priv->mutter_settings,
"experimental-features",
experimental_features_handler,
backend));
}
static void
mutter_settings_changed (GSettings *settings,
gchar *key,
MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
MetaExperimentalFeature old_experimental_features;
gboolean changed;
if (!g_str_equal (key, "experimental-features"))
return;
old_experimental_features = priv->experimental_features;
changed = update_experimental_features (backend);
if (changed)
g_signal_emit (backend, signals[EXPERIMENTAL_FEATURES_CHANGED], 0,
(unsigned int) old_experimental_features);
}
gboolean
meta_backend_is_experimental_feature_enabled (MetaBackend *backend,
MetaExperimentalFeature feature)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
return !!(priv->experimental_features & feature);
}
void
meta_backend_override_experimental_features (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
priv->experimental_features = META_EXPERIMENTAL_FEATURE_NONE;
priv->experimental_features_overridden = TRUE;
}
void
meta_backend_enable_experimental_feature (MetaBackend *backend,
MetaExperimentalFeature feature)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
priv->experimental_features |= feature;
}
static void
meta_backend_class_init (MetaBackendClass *klass)
{
const gchar *mutter_stage_views;
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_backend_finalize;
@ -417,24 +563,44 @@ meta_backend_class_init (MetaBackendClass *klass)
klass->select_stage_events = meta_backend_real_select_stage_events;
klass->get_relative_motion_deltas = meta_backend_real_get_relative_motion_deltas;
g_signal_new ("keymap-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
g_signal_new ("keymap-layout-group-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT);
g_signal_new ("last-device-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_INT);
signals[KEYMAP_CHANGED] =
g_signal_new ("keymap-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[KEYMAP_LAYOUT_GROUP_CHANGED] =
g_signal_new ("keymap-layout-group-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT);
signals[LAST_DEVICE_CHANGED] =
g_signal_new ("last-device-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_INT);
signals[EXPERIMENTAL_FEATURES_CHANGED] =
g_signal_new ("experimental-features-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT);
signals[UI_SCALING_FACTOR_CHANGED] =
g_signal_new ("ui-scaling-factor-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS");
stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0;
}
static gboolean
@ -445,6 +611,12 @@ meta_backend_initable_init (GInitable *initable,
MetaBackend *backend = META_BACKEND (initable);
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
priv->mutter_settings = g_settings_new ("org.gnome.mutter");
g_signal_connect (priv->mutter_settings, "changed",
G_CALLBACK (mutter_settings_changed),
backend);
update_experimental_features (backend);
priv->egl = g_object_new (META_TYPE_EGL, NULL);
priv->renderer = META_BACKEND_GET_CLASS (backend)->create_renderer (backend);
@ -646,8 +818,8 @@ update_last_device (MetaBackend *backend)
priv->current_device_id);
device_type = clutter_input_device_get_device_type (device);
g_signal_emit_by_name (backend, "last-device-changed",
priv->current_device_id);
g_signal_emit (backend, signals[LAST_DEVICE_CHANGED], 0,
priv->current_device_id);
switch (device_type)
{
@ -821,7 +993,6 @@ meta_init_backend (GType backend_gtype)
void
meta_clutter_init (void)
{
ClutterSettings *clutter_settings;
GSource *source;
clutter_set_custom_backend_func (meta_get_clutter_backend);
@ -832,13 +1003,6 @@ meta_clutter_init (void)
exit (1);
}
/*
* XXX: We cannot handle high dpi scaling yet, so fix the scale to 1
* for now.
*/
clutter_settings = clutter_settings_get_default ();
g_object_set (clutter_settings, "window-scaling-factor", 1, NULL);
source = g_source_new (&event_funcs, sizeof (GSource));
g_source_attach (source, NULL);
g_source_unref (source);
@ -846,20 +1010,52 @@ meta_clutter_init (void)
meta_backend_post_init (_backend);
}
static void
xft_dpi_changed (GtkSettings *settings,
GParamSpec *pspec,
MetaBackend *backend)
{
meta_backend_update_ui_scaling_factor (backend);
meta_backend_notify_ui_scaling_factor_changed (backend);
}
void
meta_backend_display_opened (MetaBackend *backend)
{
/*
* gdk-window-scaling-factor is not exported to gtk-settings
* because it is handled inside gdk, so we use gtk-xft-dpi instead
* which also changes when the scale factor changes.
*
* TODO: Don't rely on GtkSettings for this
*/
g_signal_connect (gtk_settings_get_default (), "notify::gtk-xft-dpi",
G_CALLBACK (xft_dpi_changed), backend);
}
gboolean
meta_is_stage_views_enabled (void)
{
const gchar *mutter_stage_views;
if (!meta_is_wayland_compositor ())
return FALSE;
mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS");
return !stage_views_disabled;
}
if (!mutter_stage_views)
return TRUE;
gboolean
meta_is_stage_views_scaled (void)
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaLogicalMonitorLayoutMode layout_mode;
return !g_str_equal (mutter_stage_views, "0");
if (!meta_is_stage_views_enabled ())
return FALSE;
layout_mode = monitor_manager->layout_mode;
return layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
}
MetaInputSettings *
@ -885,3 +1081,60 @@ meta_backend_get_dnd (MetaBackend *backend)
return priv->dnd;
}
void
meta_backend_notify_keymap_changed (MetaBackend *backend)
{
g_signal_emit (backend, signals[KEYMAP_CHANGED], 0);
}
void
meta_backend_notify_keymap_layout_group_changed (MetaBackend *backend,
unsigned int locked_group)
{
g_signal_emit (backend, signals[KEYMAP_LAYOUT_GROUP_CHANGED], 0,
locked_group);
}
static int
calculate_ui_scaling_factor (MetaBackend *backend)
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
GList *logical_monitors;
GList *l;
int max_scale = 1;
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
max_scale = MAX (logical_monitor->scale, max_scale);
}
return max_scale;
}
int
meta_backend_get_ui_scaling_factor (MetaBackend *backend)
{
if (meta_is_stage_views_scaled ())
{
return 1;
}
else
{
if (meta_is_monitor_config_manager_enabled ())
return calculate_ui_scaling_factor (backend);
else
return meta_theme_get_window_scaling_factor ();
}
}
void
meta_backend_notify_ui_scaling_factor_changed (MetaBackend *backend)
{
g_signal_emit (backend, signals[UI_SCALING_FACTOR_CHANGED], 0);
}

View File

@ -78,7 +78,8 @@ meta_logical_monitor_new (MetaMonitorManager *monitor_manager,
logical_monitor->number = monitor_number;
logical_monitor->winsys_id = main_output->winsys_id;
logical_monitor->scale = main_output->scale;
logical_monitor->scale = logical_monitor_config->scale;
logical_monitor->transform = logical_monitor_config->transform;
logical_monitor->in_fullscreen = -1;
logical_monitor->rect = logical_monitor_config->layout;
@ -92,6 +93,16 @@ meta_logical_monitor_new (MetaMonitorManager *monitor_manager,
return logical_monitor;
}
static MetaMonitorTransform
derive_monitor_transform (MetaMonitor *monitor)
{
MetaOutput *main_output;
main_output = meta_monitor_get_main_output (monitor);
return main_output->crtc->transform;
}
MetaLogicalMonitor *
meta_logical_monitor_new_derived (MetaMonitorManager *monitor_manager,
MetaMonitor *monitor,
@ -100,13 +111,24 @@ meta_logical_monitor_new_derived (MetaMonitorManager *monitor_manager,
{
MetaLogicalMonitor *logical_monitor;
MetaOutput *main_output;
MetaMonitorMode *monitor_mode;
int scale;
MetaMonitorTransform transform;
logical_monitor = g_object_new (META_TYPE_LOGICAL_MONITOR, NULL);
monitor_mode = meta_monitor_get_current_mode (monitor);
scale = meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager,
monitor,
monitor_mode);
transform = derive_monitor_transform (monitor);
main_output = meta_monitor_get_main_output (monitor);
logical_monitor->number = monitor_number;
logical_monitor->winsys_id = main_output->winsys_id;
logical_monitor->scale = main_output->scale;
logical_monitor->scale = scale;
logical_monitor->transform = transform;
logical_monitor->in_fullscreen = -1;
logical_monitor->rect = *layout;

View File

@ -41,6 +41,7 @@ struct _MetaLogicalMonitor
gboolean is_presentation; /* XXX: not yet used */
gboolean in_fullscreen;
int scale;
MetaMonitorTransform transform;
/* The primary or first output for this monitor, 0 if we can't figure out.
It can be matched to a winsys_id of a MetaOutput.
@ -60,9 +61,9 @@ G_DECLARE_FINAL_TYPE (MetaLogicalMonitor, meta_logical_monitor,
META, LOGICAL_MONITOR,
GObject)
MetaLogicalMonitor * meta_logical_monitor_new (MetaMonitorManager *monitor_manager,
MetaLogicalMonitorConfig *logical_monitor_config,
int monitor_number);
MetaLogicalMonitor * meta_logical_monitor_new (MetaMonitorManager *monitor_manager,
MetaLogicalMonitorConfig *logical_monitor_config,
int monitor_number);
MetaLogicalMonitor * meta_logical_monitor_new_derived (MetaMonitorManager *monitor_manager,
MetaMonitor *monitor,

View File

@ -36,6 +36,7 @@ struct _MetaMonitorConfigManager
MetaMonitorConfigStore *config_store;
MetaMonitorsConfig *current_config;
MetaMonitorsConfig *previous_config;
};
G_DEFINE_TYPE (MetaMonitorConfigManager, meta_monitor_config_manager,
@ -51,8 +52,8 @@ meta_monitor_config_manager_new (MetaMonitorManager *monitor_manager)
config_manager = g_object_new (META_TYPE_MONITOR_CONFIG_MANAGER, NULL);
config_manager->monitor_manager = monitor_manager;
config_manager->config_store = g_object_new (META_TYPE_MONITOR_CONFIG_STORE,
NULL);
config_manager->config_store =
meta_monitor_config_store_new (monitor_manager);
return config_manager;
}
@ -101,6 +102,7 @@ find_unassigned_crtc (MetaOutput *output,
typedef struct
{
MetaMonitorManager *monitor_manager;
MetaLogicalMonitorConfig *logical_monitor_config;
MetaMonitorConfig *monitor_config;
GPtrArray *crtc_infos;
@ -117,6 +119,9 @@ assign_monitor_crtc (MetaMonitor *monitor,
MonitorAssignmentData *data = user_data;
MetaOutput *output;
MetaCrtc *crtc;
MetaMonitorTransform transform;
MetaMonitorTransform crtc_transform;
int crtc_x, crtc_y;
MetaCrtcInfo *crtc_info;
MetaOutputInfo *output_info;
MetaMonitorConfig *first_monitor_config;
@ -136,13 +141,24 @@ assign_monitor_crtc (MetaMonitor *monitor,
return FALSE;
}
transform = data->logical_monitor_config->transform;
if (meta_monitor_manager_is_transform_handled (data->monitor_manager,
crtc,
transform))
crtc_transform = transform;
else
crtc_transform = META_MONITOR_TRANSFORM_NORMAL;
meta_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform,
&crtc_x, &crtc_y);
crtc_info = g_slice_new0 (MetaCrtcInfo);
*crtc_info = (MetaCrtcInfo) {
.crtc = crtc,
.mode = monitor_crtc_mode->crtc_mode,
.x = monitor_crtc_mode->x,
.y = monitor_crtc_mode->y,
.transform = META_MONITOR_TRANSFORM_NORMAL,
.x = crtc_x,
.y = crtc_y,
.transform = crtc_transform,
.outputs = g_ptr_array_new ()
};
g_ptr_array_add (crtc_info->outputs, output);
@ -165,7 +181,8 @@ assign_monitor_crtc (MetaMonitor *monitor,
* as such.
*/
first_monitor_config = data->logical_monitor_config->monitor_configs->data;
if (data->monitor_config == first_monitor_config &&
if (data->logical_monitor_config->is_primary &&
data->monitor_config == first_monitor_config &&
meta_monitor_get_main_output (monitor) == output)
assign_output_as_primary = TRUE;
else
@ -181,7 +198,7 @@ assign_monitor_crtc (MetaMonitor *monitor,
.output = output,
.is_primary = assign_output_as_primary,
.is_presentation = assign_output_as_presentation,
.is_underscanning = data->monitor_config->is_underscanning
.is_underscanning = data->monitor_config->enable_underscanning
};
g_ptr_array_add (data->crtc_infos, crtc_info);
@ -225,6 +242,7 @@ assign_monitor_crtcs (MetaMonitorManager *manager,
}
data = (MonitorAssignmentData) {
.monitor_manager = manager,
.logical_monitor_config = logical_monitor_config,
.monitor_config = monitor_config,
.crtc_infos = crtc_infos,
@ -454,24 +472,41 @@ create_monitor_config (MetaMonitor *monitor,
*monitor_config = (MetaMonitorConfig) {
.monitor_spec = meta_monitor_spec_clone (monitor_spec),
.mode_spec = g_memdup (mode_spec, sizeof (MetaMonitorModeSpec)),
.is_underscanning = meta_monitor_is_underscanning (monitor)
.enable_underscanning = meta_monitor_is_underscanning (monitor)
};
return monitor_config;
}
static MetaLogicalMonitorConfig *
create_preferred_logical_monitor_config (MetaMonitor *monitor,
int x,
int y)
create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager,
MetaMonitor *monitor,
int x,
int y,
MetaLogicalMonitorLayoutMode layout_mode)
{
MetaMonitorMode *mode;
int width, height;
int scale;
MetaMonitorConfig *monitor_config;
MetaLogicalMonitorConfig *logical_monitor_config;
mode = meta_monitor_get_preferred_mode (monitor);
meta_monitor_mode_get_resolution (mode, &width, &height);
scale = meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager,
monitor,
mode);
switch (layout_mode)
{
case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
width /= scale;
height /= scale;
break;
case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
break;
}
monitor_config = create_monitor_config (monitor, mode);
logical_monitor_config = g_new0 (MetaLogicalMonitorConfig, 1);
@ -482,6 +517,7 @@ create_preferred_logical_monitor_config (MetaMonitor *monitor,
.width = width,
.height = height
},
.scale = scale,
.monitor_configs = g_list_append (NULL, monitor_config)
};
@ -494,6 +530,7 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
GList *logical_monitor_configs;
MetaMonitor *primary_monitor;
MetaLogicalMonitorLayoutMode layout_mode;
MetaLogicalMonitorConfig *primary_logical_monitor_config;
int x;
GList *monitors;
@ -503,8 +540,13 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
if (!primary_monitor)
return NULL;
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
primary_logical_monitor_config =
create_preferred_logical_monitor_config (primary_monitor, 0, 0);
create_preferred_logical_monitor_config (monitor_manager,
primary_monitor,
0, 0,
layout_mode);
primary_logical_monitor_config->is_primary = TRUE;
logical_monitor_configs = g_list_append (NULL,
primary_logical_monitor_config);
@ -524,14 +566,17 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
continue;
logical_monitor_config =
create_preferred_logical_monitor_config (monitor, x, 0);
create_preferred_logical_monitor_config (monitor_manager,
monitor,
x, 0,
layout_mode);
logical_monitor_configs = g_list_append (logical_monitor_configs,
logical_monitor_config);
x += logical_monitor_config->layout.width;
}
return meta_monitors_config_new (logical_monitor_configs);
return meta_monitors_config_new (logical_monitor_configs, layout_mode);
}
MetaMonitorsConfig *
@ -540,19 +585,25 @@ meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_ma
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
MetaMonitor *primary_monitor;
GList *logical_monitor_configs;
MetaLogicalMonitorLayoutMode layout_mode;
MetaLogicalMonitorConfig *primary_logical_monitor_config;
primary_monitor = find_primary_monitor (monitor_manager);
if (!primary_monitor)
return NULL;
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
primary_logical_monitor_config =
create_preferred_logical_monitor_config (primary_monitor, 0, 0);
create_preferred_logical_monitor_config (monitor_manager,
primary_monitor,
0, 0,
layout_mode);
primary_logical_monitor_config->is_primary = TRUE;
logical_monitor_configs = g_list_append (NULL,
primary_logical_monitor_config);
return meta_monitors_config_new (logical_monitor_configs);
return meta_monitors_config_new (logical_monitor_configs, layout_mode);
}
MetaMonitorsConfig *
@ -561,6 +612,7 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
MetaLogicalMonitorConfig *primary_logical_monitor_config = NULL;
MetaMonitor *primary_monitor;
MetaLogicalMonitorLayoutMode layout_mode;
GList *logical_monitor_configs;
GList *region;
GList *monitors;
@ -570,6 +622,8 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
if (!primary_monitor)
return NULL;
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
logical_monitor_configs = NULL;
region = NULL;
monitors = meta_monitor_manager_get_monitors (monitor_manager);
@ -583,7 +637,10 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
continue;
logical_monitor_config =
create_preferred_logical_monitor_config (monitor, x, y);
create_preferred_logical_monitor_config (monitor_manager,
monitor,
x, y,
layout_mode);
logical_monitor_configs = g_list_append (logical_monitor_configs,
logical_monitor_config);
@ -614,22 +671,39 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
primary_logical_monitor_config->is_primary = TRUE;
return meta_monitors_config_new (logical_monitor_configs);
return meta_monitors_config_new (logical_monitor_configs, layout_mode);
}
void
meta_monitor_config_manager_set_current (MetaMonitorConfigManager *config_manager,
MetaMonitorsConfig *config)
{
g_set_object (&config_manager->previous_config,
config_manager->current_config);
g_set_object (&config_manager->current_config, config);
}
void
meta_monitor_config_manager_save_current (MetaMonitorConfigManager *config_manager)
{
g_return_if_fail (config_manager->current_config);
meta_monitor_config_store_add (config_manager->config_store,
config_manager->current_config);
}
MetaMonitorsConfig *
meta_monitor_config_manager_get_current (MetaMonitorConfigManager *config_manager)
{
return config_manager->current_config;
}
MetaMonitorsConfig *
meta_monitor_config_manager_get_previous (MetaMonitorConfigManager *config_manager)
{
return config_manager->previous_config;
}
static void
meta_monitor_config_manager_dispose (GObject *object)
{
@ -637,6 +711,7 @@ meta_monitor_config_manager_dispose (GObject *object)
META_MONITOR_CONFIG_MANAGER (object);
g_clear_object (&config_manager->current_config);
g_clear_object (&config_manager->previous_config);
G_OBJECT_CLASS (meta_monitor_config_manager_parent_class)->dispose (object);
}
@ -752,20 +827,22 @@ meta_monitors_config_key_equal (gconstpointer data_a,
return FALSE;
}
if (l_b || l_b)
if (l_a || l_b)
return FALSE;
return TRUE;
}
MetaMonitorsConfig *
meta_monitors_config_new (GList *logical_monitor_configs)
meta_monitors_config_new (GList *logical_monitor_configs,
MetaLogicalMonitorLayoutMode layout_mode)
{
MetaMonitorsConfig *config;
config = g_object_new (META_TYPE_MONITORS_CONFIG, NULL);
config->logical_monitor_configs = logical_monitor_configs;
config->key = meta_monitors_config_key_new (logical_monitor_configs);
config->layout_mode = layout_mode;
return config;
}
@ -792,3 +869,232 @@ meta_monitors_config_class_init (MetaMonitorsConfigClass *klass)
object_class->finalize = meta_monitors_config_finalize;
}
gboolean
meta_verify_monitor_mode_spec (MetaMonitorModeSpec *monitor_mode_spec,
GError **error)
{
if (monitor_mode_spec->width > 0 &&
monitor_mode_spec->height > 0 &&
monitor_mode_spec->refresh_rate > 0.0f)
{
return TRUE;
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitor mode invalid");
return FALSE;
}
}
gboolean
meta_verify_monitor_spec (MetaMonitorSpec *monitor_spec,
GError **error)
{
if (monitor_spec->connector &&
monitor_spec->vendor &&
monitor_spec->product &&
monitor_spec->serial)
{
return TRUE;
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitor spec incomplete");
return FALSE;
}
}
gboolean
meta_verify_monitor_config (MetaMonitorConfig *monitor_config,
GError **error)
{
if (monitor_config->monitor_spec && monitor_config->mode_spec)
{
return TRUE;
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitor config incomplete");
return FALSE;
}
}
gboolean
meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
MetaLogicalMonitorLayoutMode layout_mode,
GError **error)
{
GList *l;
int expected_mode_width = 0;
int expected_mode_height = 0;
if (logical_monitor_config->scale < 1)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Invalid logical monitor config scale %d",
logical_monitor_config->scale);
return FALSE;
}
if (logical_monitor_config->layout.x < 0 ||
logical_monitor_config->layout.y < 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Invalid logical monitor position (%d, %d)",
logical_monitor_config->layout.x,
logical_monitor_config->layout.y);
return FALSE;
}
if (!logical_monitor_config->monitor_configs)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitor is empty");
return FALSE;
}
if (meta_monitor_transform_is_rotated (logical_monitor_config->transform))
{
expected_mode_width = logical_monitor_config->layout.height;
expected_mode_height = logical_monitor_config->layout.width;
}
else
{
expected_mode_width = logical_monitor_config->layout.width;
expected_mode_height = logical_monitor_config->layout.height;
}
switch (layout_mode)
{
case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
expected_mode_width *= logical_monitor_config->scale;
expected_mode_height *= logical_monitor_config->scale;
break;
case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
break;
}
for (l = logical_monitor_config->monitor_configs; l; l = l->next)
{
MetaMonitorConfig *monitor_config = l->data;
if (monitor_config->mode_spec->width != expected_mode_width ||
monitor_config->mode_spec->height != expected_mode_height)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitor modes in logical monitor conflict");
return FALSE;
}
}
return TRUE;
}
static gboolean
has_adjecent_neighbour (MetaMonitorsConfig *config,
MetaLogicalMonitorConfig *logical_monitor_config)
{
GList *l;
if (!config->logical_monitor_configs->next)
{
g_assert (config->logical_monitor_configs->data ==
logical_monitor_config);
return TRUE;
}
for (l = config->logical_monitor_configs; l; l = l->next)
{
MetaLogicalMonitorConfig *other_logical_monitor_config = l->data;
if (logical_monitor_config == other_logical_monitor_config)
continue;
if (meta_rectangle_is_adjecent_to (&logical_monitor_config->layout,
&other_logical_monitor_config->layout))
return TRUE;
}
return FALSE;
}
gboolean
meta_verify_monitors_config (MetaMonitorsConfig *config,
GError **error)
{
int min_x, min_y;
gboolean has_primary;
GList *region;
GList *l;
if (!config->logical_monitor_configs)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitors config incomplete");
return FALSE;
}
min_x = INT_MAX;
min_y = INT_MAX;
region = NULL;
has_primary = FALSE;
for (l = config->logical_monitor_configs; l; l = l->next)
{
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
if (meta_rectangle_overlaps_with_region (region,
&logical_monitor_config->layout))
{
g_list_free (region);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors overlap");
return FALSE;
}
if (has_primary && logical_monitor_config->is_primary)
{
g_list_free (region);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Config contains multiple primary logical monitors");
return FALSE;
}
else if (logical_monitor_config->is_primary)
{
has_primary = TRUE;
}
if (!has_adjecent_neighbour (config, logical_monitor_config))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors not adjecent");
return FALSE;
}
min_x = MIN (logical_monitor_config->layout.x, min_x);
min_y = MIN (logical_monitor_config->layout.y, min_y);
region = g_list_prepend (region, &logical_monitor_config->layout);
}
g_list_free (region);
if (min_x != 0 || min_y != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors positions are offset");
return FALSE;
}
if (!has_primary)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Config is missing primary logical");
return FALSE;
}
return TRUE;
}

View File

@ -33,13 +33,15 @@ typedef struct _MetaMonitorConfig
{
MetaMonitorSpec *monitor_spec;
MetaMonitorModeSpec *mode_spec;
gboolean is_underscanning;
gboolean enable_underscanning;
} MetaMonitorConfig;
typedef struct _MetaLogicalMonitorConfig
{
MetaRectangle layout;
GList *monitor_configs;
MetaMonitorTransform transform;
int scale;
gboolean is_primary;
gboolean is_presentation;
} MetaLogicalMonitorConfig;
@ -55,6 +57,8 @@ struct _MetaMonitorsConfig
MetaMonitorsConfigKey *key;
GList *logical_monitor_configs;
MetaLogicalMonitorLayoutMode layout_mode;
};
#define META_TYPE_MONITORS_CONFIG (meta_monitors_config_get_type ())
@ -84,7 +88,12 @@ void meta_monitor_config_manager_set_current (MetaMonitorConfigManager *config_m
MetaMonitorsConfig * meta_monitor_config_manager_get_current (MetaMonitorConfigManager *config_manager);
MetaMonitorsConfig * meta_monitors_config_new (GList *logical_monitor_configs);
MetaMonitorsConfig * meta_monitor_config_manager_get_previous (MetaMonitorConfigManager *config_manager);
void meta_monitor_config_manager_save_current (MetaMonitorConfigManager *config_manager);
MetaMonitorsConfig * meta_monitors_config_new (GList *logical_monitor_configs,
MetaLogicalMonitorLayoutMode layout_mode);
unsigned int meta_monitors_config_key_hash (gconstpointer config_key);
@ -97,4 +106,20 @@ void meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor
void meta_monitor_config_free (MetaMonitorConfig *monitor_config);
gboolean meta_verify_monitor_mode_spec (MetaMonitorModeSpec *monitor_mode_spec,
GError **error);
gboolean meta_verify_monitor_spec (MetaMonitorSpec *monitor_spec,
GError **error);
gboolean meta_verify_monitor_config (MetaMonitorConfig *monitor_config,
GError **error);
gboolean meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
MetaLogicalMonitorLayoutMode layout_mode,
GError **error);
gboolean meta_verify_monitors_config (MetaMonitorsConfig *config,
GError **error);
#endif /* META_MONITOR_CONFIG_MANAGER_H */

View File

@ -27,7 +27,11 @@
#include <string.h>
#include "backends/meta-monitor-config-manager.h"
#include "core/boxes-private.h"
#define MONITORS_CONFIG_XML_FORMAT_VERSION 2
#define QUOTE1(a) #a
#define QUOTE(a) QUOTE1(a)
/*
* Example configuration:
@ -37,6 +41,7 @@
* <logicalmonitor>
* <x>0</x>
* <y>0</y>
* <scale>1</scale>
* <monitor>
* <monitorspec>
* <connector>LVDS1</connector>
@ -50,6 +55,10 @@
* <rate>60.049972534179688</rate>
* </mode>
* </monitor>
* <transform>
* <rotation>right</rotation>
* <flipped>no</flipped>
* </transform>
* <primary>yes</primary>
* <presentation>no</presentation>
* </logicalmonitor>
@ -77,11 +86,29 @@
*
*/
enum
{
PROP_0,
PROP_MONITOR_MANAGER,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
struct _MetaMonitorConfigStore
{
GObject parent;
MetaMonitorManager *monitor_manager;
GHashTable *configs;
GCancellable *save_cancellable;
GFile *user_file;
GFile *custom_file;
};
typedef enum
@ -94,6 +121,10 @@ typedef enum
STATE_LOGICAL_MONITOR_Y,
STATE_LOGICAL_MONITOR_PRIMARY,
STATE_LOGICAL_MONITOR_PRESENTATION,
STATE_LOGICAL_MONITOR_SCALE,
STATE_TRANSFORM,
STATE_TRANSFORM_ROTATION,
STATE_TRANSFORM_FLIPPED,
STATE_MONITOR,
STATE_MONITOR_SPEC,
STATE_MONITOR_SPEC_CONNECTOR,
@ -114,6 +145,8 @@ typedef struct
GList *current_logical_monitor_configs;
MetaMonitorSpec *current_monitor_spec;
gboolean current_transform_flipped;
MetaMonitorTransform current_transform;
MetaMonitorModeSpec *current_monitor_mode_spec;
MetaMonitorConfig *current_monitor_config;
MetaLogicalMonitorConfig *current_logical_monitor_config;
@ -156,7 +189,7 @@ handle_start_element (GMarkupParseContext *context,
/* TODO: Handle converting version 1 configuration files. */
if (!g_str_equal (version, "2"))
if (!g_str_equal (version, QUOTE (MONITORS_CONFIG_XML_FORMAT_VERSION)))
{
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
"Invalid or unsupported version '%s'", version);
@ -206,6 +239,10 @@ handle_start_element (GMarkupParseContext *context,
{
parser->state = STATE_LOGICAL_MONITOR_Y;
}
else if (g_str_equal (element_name, "scale"))
{
parser->state = STATE_LOGICAL_MONITOR_SCALE;
}
else if (g_str_equal (element_name, "primary"))
{
parser->state = STATE_LOGICAL_MONITOR_PRIMARY;
@ -214,6 +251,10 @@ handle_start_element (GMarkupParseContext *context,
{
parser->state = STATE_LOGICAL_MONITOR_PRESENTATION;
}
else if (g_str_equal (element_name, "transform"))
{
parser->state = STATE_TRANSFORM;
}
else if (g_str_equal (element_name, "monitor"))
{
parser->current_monitor_config = g_new0 (MetaMonitorConfig, 1);;
@ -232,6 +273,7 @@ handle_start_element (GMarkupParseContext *context,
case STATE_LOGICAL_MONITOR_X:
case STATE_LOGICAL_MONITOR_Y:
case STATE_LOGICAL_MONITOR_SCALE:
case STATE_LOGICAL_MONITOR_PRIMARY:
case STATE_LOGICAL_MONITOR_PRESENTATION:
{
@ -240,6 +282,28 @@ handle_start_element (GMarkupParseContext *context,
return;
}
case STATE_TRANSFORM:
{
if (g_str_equal (element_name, "rotation"))
{
parser->state = STATE_TRANSFORM_ROTATION;
}
else if (g_str_equal (element_name, "flipped"))
{
parser->state = STATE_TRANSFORM_FLIPPED;
}
return;
}
case STATE_TRANSFORM_ROTATION:
case STATE_TRANSFORM_FLIPPED:
{
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
"Invalid transform element '%s'", element_name);
return;
}
case STATE_MONITOR:
{
if (g_str_equal (element_name, "monitorspec"))
@ -349,88 +413,13 @@ handle_start_element (GMarkupParseContext *context,
}
static gboolean
verify_monitor_spec (MetaMonitorSpec *monitor_spec,
GError **error)
{
if (monitor_spec->connector &&
monitor_spec->vendor &&
monitor_spec->product &&
monitor_spec->serial)
{
return TRUE;
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitor spec incomplete");
return FALSE;
}
}
static gboolean
verify_monitor_mode (MetaMonitorModeSpec *monitor_mode_spec,
GError **error)
{
if (monitor_mode_spec->width > 0 &&
monitor_mode_spec->height > 0 &&
monitor_mode_spec->refresh_rate > 0.0f)
{
return TRUE;
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitor mode invalid");
return FALSE;
}
}
static gboolean
verify_monitor_config (MetaMonitorConfig *monitor_config,
GError **error)
{
if (monitor_config->monitor_spec && monitor_config->mode_spec)
{
return TRUE;
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitor config incomplete");
return FALSE;
}
}
static gboolean
verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
GError **error)
{
if (logical_monitor_config->layout.x < 0 ||
logical_monitor_config->layout.y < 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Invalid logical monitor position (%d, %d)",
logical_monitor_config->layout.x,
logical_monitor_config->layout.y);
return FALSE;
}
if (!logical_monitor_config->monitor_configs)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitor is empty");
return FALSE;
}
return TRUE;
}
static gboolean
derive_logical_monitor_layout (MetaLogicalMonitorConfig *logical_monitor_config,
GError **error)
derive_logical_monitor_layout (MetaLogicalMonitorConfig *logical_monitor_config,
MetaLogicalMonitorLayoutMode layout_mode,
GError **error)
{
MetaMonitorConfig *monitor_config;
int mode_width, mode_height;
int width = 0, height = 0;
GList *l;
monitor_config = logical_monitor_config->monitor_configs->data;
@ -450,65 +439,29 @@ derive_logical_monitor_layout (MetaLogicalMonitorConfig *logical_monitor_config,
}
}
logical_monitor_config->layout.width = mode_width;
logical_monitor_config->layout.height = mode_height;
return TRUE;
}
static gboolean
verify_config (MetaMonitorsConfig *config,
GError **error)
{
gboolean has_primary;
GList *region;
GList *l;
if (!config->logical_monitor_configs)
if (meta_monitor_transform_is_rotated (logical_monitor_config->transform))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitors config incomplete");
return FALSE;
width = mode_height;
height = mode_width;
}
else
{
width = mode_width;
height = mode_height;
}
region = NULL;
has_primary = FALSE;
for (l = config->logical_monitor_configs; l; l = l->next)
switch (layout_mode)
{
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
if (meta_rectangle_overlaps_with_region (region,
&logical_monitor_config->layout))
{
g_list_free (region);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors overlap");
return FALSE;
}
if (has_primary && logical_monitor_config->is_primary)
{
g_list_free (region);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Config contains multiple primary logical monitors");
return FALSE;
}
else if (logical_monitor_config->is_primary)
{
has_primary = TRUE;
}
region = g_list_prepend (region, &logical_monitor_config->layout);
case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
width /= logical_monitor_config->scale;
height /= logical_monitor_config->scale;
break;
case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
break;
}
g_list_free (region);
if (!has_primary)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Config is missing primary logical");
return FALSE;
}
logical_monitor_config->layout.width = width;
logical_monitor_config->layout.height = height;
return TRUE;
}
@ -525,6 +478,7 @@ handle_end_element (GMarkupParseContext *context,
{
case STATE_LOGICAL_MONITOR_X:
case STATE_LOGICAL_MONITOR_Y:
case STATE_LOGICAL_MONITOR_SCALE:
case STATE_LOGICAL_MONITOR_PRIMARY:
case STATE_LOGICAL_MONITOR_PRESENTATION:
{
@ -532,6 +486,32 @@ handle_end_element (GMarkupParseContext *context,
return;
}
case STATE_TRANSFORM:
{
g_assert (g_str_equal (element_name, "transform"));
parser->current_logical_monitor_config->transform =
parser->current_transform;
if (parser->current_transform_flipped)
{
parser->current_logical_monitor_config->transform +=
META_MONITOR_TRANSFORM_FLIPPED;
}
parser->current_transform = META_MONITOR_TRANSFORM_NORMAL;
parser->current_transform_flipped = FALSE;
parser->state = STATE_LOGICAL_MONITOR;
return;
}
case STATE_TRANSFORM_ROTATION:
case STATE_TRANSFORM_FLIPPED:
{
parser->state = STATE_TRANSFORM;
return;
}
case STATE_MONITOR_SPEC_CONNECTOR:
case STATE_MONITOR_SPEC_VENDOR:
case STATE_MONITOR_SPEC_PRODUCT:
@ -545,7 +525,7 @@ handle_end_element (GMarkupParseContext *context,
{
g_assert (g_str_equal (element_name, "monitorspec"));
if (!verify_monitor_spec (parser->current_monitor_spec, error))
if (!meta_verify_monitor_spec (parser->current_monitor_spec, error))
return;
parser->current_monitor_config->monitor_spec =
@ -568,7 +548,8 @@ handle_end_element (GMarkupParseContext *context,
{
g_assert (g_str_equal (element_name, "mode"));
if (!verify_monitor_mode (parser->current_monitor_mode_spec, error))
if (!meta_verify_monitor_mode_spec (parser->current_monitor_mode_spec,
error))
return;
parser->current_monitor_config->mode_spec =
@ -593,7 +574,7 @@ handle_end_element (GMarkupParseContext *context,
g_assert (g_str_equal (element_name, "monitor"));
if (!verify_monitor_config (parser->current_monitor_config, error))
if (!meta_verify_monitor_config (parser->current_monitor_config, error))
return;
logical_monitor_config = parser->current_logical_monitor_config;
@ -614,11 +595,8 @@ handle_end_element (GMarkupParseContext *context,
g_assert (g_str_equal (element_name, "logicalmonitor"));
if (!verify_logical_monitor_config (logical_monitor_config, error))
return;
if (!derive_logical_monitor_layout (logical_monitor_config, error))
return;
if (logical_monitor_config->scale == 0)
logical_monitor_config->scale = 1;
parser->current_logical_monitor_configs =
g_list_append (parser->current_logical_monitor_configs,
@ -631,14 +609,38 @@ handle_end_element (GMarkupParseContext *context,
case STATE_CONFIGURATION:
{
MetaMonitorConfigStore *store = parser->config_store;
MetaMonitorsConfig *config;
GList *l;
MetaLogicalMonitorLayoutMode layout_mode;
g_assert (g_str_equal (element_name, "configuration"));
config =
meta_monitors_config_new (parser->current_logical_monitor_configs);
layout_mode =
meta_monitor_manager_get_default_layout_mode (store->monitor_manager);
if (!verify_config (config, error))
for (l = parser->current_logical_monitor_configs; l; l = l->next)
{
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
if (!derive_logical_monitor_layout (logical_monitor_config,
layout_mode,
error))
return;
if (!meta_verify_logical_monitor_config (logical_monitor_config,
layout_mode,
error))
return;
}
config =
meta_monitors_config_new (parser->current_logical_monitor_configs,
layout_mode);
parser->current_logical_monitor_configs = NULL;
if (!meta_verify_monitors_config (config, error))
{
g_object_unref (config);
return;
@ -647,8 +649,6 @@ handle_end_element (GMarkupParseContext *context,
g_hash_table_replace (parser->config_store->configs,
config->key, config);
parser->current_logical_monitor_configs = NULL;
parser->state = STATE_MONITORS;
return;
}
@ -779,6 +779,7 @@ handle_text (GMarkupParseContext *context,
case STATE_MONITOR:
case STATE_MONITOR_SPEC:
case STATE_MONITOR_MODE:
case STATE_TRANSFORM:
{
if (!is_all_whitespace (text, text_len))
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
@ -824,6 +825,23 @@ handle_text (GMarkupParseContext *context,
return;
}
case STATE_LOGICAL_MONITOR_SCALE:
{
if (!read_int (text, text_len,
&parser->current_logical_monitor_config->scale, error))
return;
if (parser->current_logical_monitor_config->scale <= 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitor scale '%d' invalid",
parser->current_logical_monitor_config->scale);
return;
}
return;
}
case STATE_LOGICAL_MONITOR_PRIMARY:
{
read_bool (text, text_len,
@ -840,6 +858,31 @@ handle_text (GMarkupParseContext *context,
return;
}
case STATE_TRANSFORM_ROTATION:
{
if (strncmp (text, "normal", text_len) == 0)
parser->current_transform = META_MONITOR_TRANSFORM_NORMAL;
else if (strncmp (text, "left", text_len) == 0)
parser->current_transform = META_MONITOR_TRANSFORM_90;
else if (strncmp (text, "upside_down", text_len) == 0)
parser->current_transform = META_MONITOR_TRANSFORM_180;
else if (strncmp (text, "right", text_len) == 0)
parser->current_transform = META_MONITOR_TRANSFORM_270;
else
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
"Invalid rotation type %.*s", (int)text_len, text);
return;
}
case STATE_TRANSFORM_FLIPPED:
{
read_bool (text, text_len,
&parser->current_transform_flipped,
error);
return;
}
case STATE_MONITOR_MODE_WIDTH:
{
read_int (text, text_len,
@ -867,7 +910,7 @@ handle_text (GMarkupParseContext *context,
case STATE_MONITOR_UNDERSCANNING:
{
read_bool (text, text_len,
&parser->current_monitor_config->is_underscanning,
&parser->current_monitor_config->enable_underscanning,
error);
return;
}
@ -930,12 +973,223 @@ meta_monitor_config_store_lookup (MetaMonitorConfigStore *config_store,
key));
}
static void
append_monitors (GString *buffer,
GList *monitor_configs)
{
GList *l;
for (l = monitor_configs; l; l = l->next)
{
MetaMonitorConfig *monitor_config = l->data;
char rate_str[G_ASCII_DTOSTR_BUF_SIZE];
g_ascii_dtostr (rate_str, sizeof (rate_str),
monitor_config->mode_spec->refresh_rate);
g_string_append (buffer, " <monitor>\n");
g_string_append (buffer, " <monitorspec>\n");
g_string_append_printf (buffer, " <connector>%s</connector>\n",
monitor_config->monitor_spec->connector);
g_string_append_printf (buffer, " <vendor>%s</vendor>\n",
monitor_config->monitor_spec->vendor);
g_string_append_printf (buffer, " <product>%s</product>\n",
monitor_config->monitor_spec->product);
g_string_append_printf (buffer, " <serial>%s</serial>\n",
monitor_config->monitor_spec->serial);
g_string_append (buffer, " </monitorspec>\n");
g_string_append (buffer, " <mode>\n");
g_string_append_printf (buffer, " <width>%d</width>\n",
monitor_config->mode_spec->width);
g_string_append_printf (buffer, " <height>%d</height>\n",
monitor_config->mode_spec->height);
g_string_append_printf (buffer, " <rate>%s</rate>\n",
rate_str);
g_string_append (buffer, " </mode>\n");
if (monitor_config->enable_underscanning)
g_string_append (buffer, " <underscanning>yes</underscanning>\n");
g_string_append (buffer, " </monitor>\n");
}
}
static const char *
bool_to_string (gboolean value)
{
return value ? "yes" : "no";
}
static void
append_transform (GString *buffer,
MetaMonitorTransform transform)
{
const char *rotation = NULL;
gboolean flipped = FALSE;
switch (transform)
{
case META_MONITOR_TRANSFORM_NORMAL:
return;
case META_MONITOR_TRANSFORM_90:
rotation = "left";
break;
case META_MONITOR_TRANSFORM_180:
rotation = "upside_down";
break;
case META_MONITOR_TRANSFORM_270:
rotation = "right";
break;
case META_MONITOR_TRANSFORM_FLIPPED:
rotation = "normal";
flipped = TRUE;
break;
case META_MONITOR_TRANSFORM_FLIPPED_90:
rotation = "left";
flipped = TRUE;
break;
case META_MONITOR_TRANSFORM_FLIPPED_180:
rotation = "upside_down";
flipped = TRUE;
break;
case META_MONITOR_TRANSFORM_FLIPPED_270:
rotation = "right";
flipped = TRUE;
break;
}
g_string_append (buffer, " <transform>\n");
g_string_append_printf (buffer, " <rotation>%s</rotation>\n",
rotation);
g_string_append_printf (buffer, " <flipped>%s</flipped>\n",
bool_to_string (flipped));
g_string_append (buffer, " </transform>\n");
}
static void
append_logical_monitor_xml (GString *buffer,
MetaLogicalMonitorConfig *logical_monitor_config)
{
g_string_append (buffer, " <logicalmonitor>\n");
g_string_append_printf (buffer, " <x>%d</x>\n",
logical_monitor_config->layout.x);
g_string_append_printf (buffer, " <y>%d</y>\n",
logical_monitor_config->layout.y);
g_string_append_printf (buffer, " <scale>%d</scale>\n",
logical_monitor_config->scale);
if (logical_monitor_config->is_primary)
g_string_append (buffer, " <primary>yes</primary>\n");
if (logical_monitor_config->is_presentation)
g_string_append (buffer, " <presentation>yes</presentation>\n");
append_transform (buffer, logical_monitor_config->transform);
append_monitors (buffer, logical_monitor_config->monitor_configs);
g_string_append (buffer, " </logicalmonitor>\n");
}
static GString *
generate_config_xml (MetaMonitorConfigStore *config_store)
{
GString *buffer;
GHashTableIter iter;
MetaMonitorsConfig *config;
buffer = g_string_new ("");
g_string_append_printf (buffer, "<monitors version=\"%d\">\n",
MONITORS_CONFIG_XML_FORMAT_VERSION);
g_hash_table_iter_init (&iter, config_store->configs);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &config))
{
GList *l;
g_string_append (buffer, " <configuration>\n");
for (l = config->logical_monitor_configs; l; l = l->next)
{
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
append_logical_monitor_xml (buffer, logical_monitor_config);
}
g_string_append (buffer, " </configuration>\n");
}
g_string_append (buffer, "</monitors>\n");
return buffer;
}
typedef struct _SaveData
{
MetaMonitorConfigStore *config_store;
GString *buffer;
} SaveData;
static void
saved_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
SaveData *data = user_data;
GError *error = NULL;
if (!g_file_replace_contents_finish (G_FILE (object), result, NULL, &error))
{
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
g_warning ("Saving monitor configuration failed: %s\n", error->message);
else
g_clear_object (&data->config_store->save_cancellable);
g_error_free (error);
}
else
{
g_clear_object (&data->config_store->save_cancellable);
}
g_clear_object (&data->config_store);
g_string_free (data->buffer, TRUE);
g_free (data);
}
static void
meta_monitor_config_store_save (MetaMonitorConfigStore *config_store)
{
GString *buffer;
SaveData *data;
if (config_store->save_cancellable)
{
g_cancellable_cancel (config_store->save_cancellable);
g_clear_object (&config_store->save_cancellable);
}
config_store->save_cancellable = g_cancellable_new ();
buffer = generate_config_xml (config_store);
data = g_new0 (SaveData, 1);
*data = (SaveData) {
.config_store = g_object_ref (config_store),
.buffer = buffer
};
g_file_replace_contents_async (config_store->user_file,
buffer->str, buffer->len,
NULL,
TRUE,
G_FILE_CREATE_REPLACE_DESTINATION,
config_store->save_cancellable,
saved_cb, data);
}
void
meta_monitor_config_store_add (MetaMonitorConfigStore *config_store,
MetaMonitorsConfig *config)
{
g_hash_table_insert (config_store->configs,
config->key, g_object_ref (config));
g_hash_table_replace (config_store->configs,
config->key, g_object_ref (config));
if (!config_store->custom_file)
meta_monitor_config_store_save (config_store);
}
gboolean
@ -943,13 +1197,12 @@ meta_monitor_config_store_set_custom (MetaMonitorConfigStore *config_store,
const char *path,
GError **error)
{
g_autoptr (GFile) custom_file = NULL;
g_clear_object (&config_store->custom_file);
g_hash_table_remove_all (config_store->configs);
custom_file = g_file_new_for_path (path);
config_store->custom_file = g_file_new_for_path (path);
return read_config_file (config_store, custom_file, error);
return read_config_file (config_store, config_store->custom_file, error);
}
int
@ -958,6 +1211,39 @@ meta_monitor_config_store_get_config_count (MetaMonitorConfigStore *config_store
return (int) g_hash_table_size (config_store->configs);
}
MetaMonitorConfigStore *
meta_monitor_config_store_new (MetaMonitorManager *monitor_manager)
{
return g_object_new (META_TYPE_MONITOR_CONFIG_STORE,
"monitor-manager", monitor_manager,
NULL);
}
static void
meta_monitor_config_store_constructed (GObject *object)
{
MetaMonitorConfigStore *config_store = META_MONITOR_CONFIG_STORE (object);
char *user_file_path;
GError *error = NULL;
user_file_path = g_build_filename (g_get_user_config_dir (),
"monitors-experimental.xml",
NULL);
config_store->user_file = g_file_new_for_path (user_file_path);
if (g_file_test (user_file_path, G_FILE_TEST_EXISTS))
{
if (!read_config_file (config_store, config_store->user_file, &error))
{
g_warning ("Failed to read monitors config file '%s': %s",
user_file_path, error->message);
g_error_free (error);
}
}
g_free (user_file_path);
}
static void
meta_monitor_config_store_dispose (GObject *object)
{
@ -965,9 +1251,48 @@ meta_monitor_config_store_dispose (GObject *object)
g_clear_pointer (&config_store->configs, g_hash_table_destroy);
g_clear_object (&config_store->user_file);
g_clear_object (&config_store->custom_file);
G_OBJECT_CLASS (meta_monitor_config_store_parent_class)->dispose (object);
}
static void
meta_monitor_config_store_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaMonitorConfigStore *config_store = META_MONITOR_CONFIG_STORE (object);
switch (prop_id)
{
case PROP_MONITOR_MANAGER:
g_value_set_object (value, &config_store->monitor_manager);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
meta_monitor_config_store_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaMonitorConfigStore *config_store = META_MONITOR_CONFIG_STORE (object);
switch (prop_id)
{
case PROP_MONITOR_MANAGER:
config_store->monitor_manager = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
meta_monitor_config_store_init (MetaMonitorConfigStore *config_store)
{
@ -982,5 +1307,19 @@ meta_monitor_config_store_class_init (MetaMonitorConfigStoreClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = meta_monitor_config_store_constructed;
object_class->dispose = meta_monitor_config_store_dispose;
object_class->get_property = meta_monitor_config_store_get_property;
object_class->set_property = meta_monitor_config_store_set_property;
obj_props[PROP_MONITOR_MANAGER] =
g_param_spec_object ("monitor-manager",
"MetaMonitorManager",
"MetaMonitorManager",
META_TYPE_MONITOR_MANAGER,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
}

View File

@ -30,6 +30,8 @@
G_DECLARE_FINAL_TYPE (MetaMonitorConfigStore, meta_monitor_config_store,
META, MONITOR_CONFIG_STORE, GObject)
MetaMonitorConfigStore * meta_monitor_config_store_new (MetaMonitorManager *monitor_manager);
MetaMonitorsConfig * meta_monitor_config_store_lookup (MetaMonitorConfigStore *config_store,
MetaMonitorsConfigKey *key);

View File

@ -96,9 +96,6 @@ static gboolean meta_monitor_config_assign_crtcs (MetaConfiguration *config,
GPtrArray *crtcs,
GPtrArray *outputs);
static void power_client_changed_cb (MetaMonitorManager *manager,
gpointer user_data);
static void
free_output_key (MetaOutputKey *key)
{
@ -794,8 +791,6 @@ meta_monitor_config_new (MetaMonitorManager *manager)
self = g_object_new (META_TYPE_MONITOR_CONFIG, NULL);
self->lid_is_closed = meta_monitor_manager_is_lid_closed (manager);
g_signal_connect_object (manager, "lid-is-closed-changed",
G_CALLBACK (power_client_changed_cb), self, 0);
meta_monitor_config_load (self);
@ -1460,7 +1455,12 @@ meta_monitor_config_make_default (MetaMonitorConfig *self,
gboolean use_stored_config;
outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height);
if (!meta_monitor_manager_get_max_screen_size (manager, &max_width, &max_height))
{
/* No max screen size, just pretend it's something large. */
max_width = 65535;
max_height = 65535;
}
if (n_outputs == 0)
{
@ -1579,11 +1579,10 @@ turn_off_laptop_display (MetaMonitorConfig *self,
self->current_is_for_laptop_lid = TRUE;
}
static void
power_client_changed_cb (MetaMonitorManager *manager,
gpointer user_data)
void
meta_monitor_config_lid_is_closed_changed (MetaMonitorConfig *self,
MetaMonitorManager *manager)
{
MetaMonitorConfig *self = user_data;
gboolean is_closed;
is_closed = meta_monitor_manager_is_lid_closed (manager);

View File

@ -46,4 +46,7 @@ void meta_monitor_config_restore_previous (MetaMonitorConfig *con
gboolean meta_monitor_config_get_is_builtin_display_on (MetaMonitorConfig *config);
void meta_monitor_config_lid_is_closed_changed (MetaMonitorConfig *self,
MetaMonitorManager *manager);
#endif /* META_MONITOR_CONFIG_H */

View File

@ -30,6 +30,7 @@
#include <stdlib.h>
#include <meta/util.h>
#include "backends/meta-backend-private.h"
#include "backends/meta-monitor-config-manager.h"
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
@ -39,6 +40,11 @@
#define MAX_CRTCS (MAX_MONITORS * 2)
#define MAX_MODES (MAX_MONITORS * 4)
static float supported_scales_dummy[] = {
1.0,
2.0
};
struct _MetaMonitorManagerDummy
{
MetaMonitorManager parent_instance;
@ -51,8 +57,16 @@ struct _MetaMonitorManagerDummyClass
MetaMonitorManagerClass parent_class;
};
typedef struct _MetaOutputDummy
{
int scale;
} MetaOutputDummy;
G_DEFINE_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, META_TYPE_MONITOR_MANAGER);
static void
meta_output_dummy_notify_destroy (MetaOutput *output);
#define array_last(a, t) \
g_array_index (a, t, a->len - 1)
@ -75,6 +89,7 @@ append_monitor (GArray *modes,
}
};
MetaCrtc crtc;
MetaOutputDummy *output_dummy;
MetaOutput output;
unsigned int i;
@ -88,6 +103,11 @@ append_monitor (GArray *modes,
};
g_array_append_val (crtcs, crtc);
output_dummy = g_new0 (MetaOutputDummy, 1);
*output_dummy = (MetaOutputDummy) {
.scale = scale
};
output = (MetaOutput) {
.winsys_id = outputs->len + 1,
.name = g_strdup_printf ("LVDS%d", outputs->len + 1),
@ -103,7 +123,9 @@ append_monitor (GArray *modes,
.n_possible_clones = 0,
.backlight = -1,
.connector_type = META_CONNECTOR_TYPE_LVDS,
.scale = scale,
.driver_private = output_dummy,
.driver_notify =
(GDestroyNotify) meta_output_dummy_notify_destroy
};
output.modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (modes_decl));
@ -159,9 +181,15 @@ append_tiled_monitor (GArray *modes,
tile_group_id = outputs->len + 1;
for (i = 0; i < G_N_ELEMENTS (crtcs_decl); i++)
{
MetaOutputDummy *output_dummy;
MetaCrtcMode *preferred_mode;
unsigned int j;
output_dummy = g_new0 (MetaOutputDummy, 1);
*output_dummy = (MetaOutputDummy) {
.scale = scale
};
preferred_mode = &array_last (modes, MetaCrtcMode),
output = (MetaOutput) {
.winsys_id = outputs->len + 1,
@ -187,7 +215,9 @@ append_tiled_monitor (GArray *modes,
.tile_w = preferred_mode->width,
.tile_h = preferred_mode->height
},
.scale = scale
.driver_private = output_dummy,
.driver_notify =
(GDestroyNotify) meta_output_dummy_notify_destroy
};
output.modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (modes_decl));
@ -206,6 +236,12 @@ append_tiled_monitor (GArray *modes,
}
}
static void
meta_output_dummy_notify_destroy (MetaOutput *output)
{
g_clear_pointer (&output->driver_private, g_free);
}
static void
meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
{
@ -289,9 +325,6 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
tiled_monitors_str = g_getenv ("MUTTER_DEBUG_TILED_DUMMY_MONITORS");
tiled_monitors = g_strcmp0 (tiled_monitors_str, "1") == 0;
manager->max_screen_width = 65535;
manager->max_screen_height = 65535;
modes = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtcMode), MAX_MODES);
crtcs = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtc), MAX_CRTCS);
outputs = g_array_sized_new (FALSE, TRUE, sizeof (MetaOutput), MAX_OUTPUTS);
@ -323,7 +356,7 @@ meta_monitor_manager_dummy_ensure_initial_config (MetaMonitorManager *manager)
config = meta_monitor_manager_ensure_configured (manager);
if (manager->config_manager)
if (meta_is_monitor_config_manager_enabled ())
meta_monitor_manager_update_logical_state (manager, config);
else
meta_monitor_manager_update_logical_state_derived (manager);
@ -464,18 +497,34 @@ update_screen_size (MetaMonitorManager *manager,
}
static gboolean
meta_monitor_manager_dummy_apply_monitors_config (MetaMonitorManager *manager,
MetaMonitorsConfig *config,
GError **error)
meta_monitor_manager_dummy_apply_monitors_config (MetaMonitorManager *manager,
MetaMonitorsConfig *config,
MetaMonitorsConfigMethod method,
GError **error)
{
GPtrArray *crtc_infos;
GPtrArray *output_infos;
if (!config)
{
manager->screen_width = 0;
manager->screen_height = 0;
meta_monitor_manager_rebuild (manager, NULL);
}
if (!meta_monitor_config_manager_assign (manager, config,
&crtc_infos, &output_infos,
error))
return FALSE;
if (method == META_MONITORS_CONFIG_METHOD_VERIFY)
{
g_ptr_array_free (crtc_infos, TRUE);
g_ptr_array_free (output_infos, TRUE);
return TRUE;
}
apply_crtc_assignments (manager,
(MetaCrtcInfo **) crtc_infos->pdata,
crtc_infos->len,
@ -533,6 +582,81 @@ meta_monitor_manager_dummy_is_transform_handled (MetaMonitorManager *manager,
return manager_dummy->is_transform_handled;
}
static int
meta_monitor_manager_dummy_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
MetaOutput *output;
MetaOutputDummy *output_dummy;
output = meta_monitor_get_main_output (monitor);
output_dummy = output->driver_private;
return output_dummy->scale;
}
static void
meta_monitor_manager_dummy_get_supported_scales (MetaMonitorManager *manager,
float **scales,
int *n_scales)
{
*scales = supported_scales_dummy;
*n_scales = G_N_ELEMENTS (supported_scales_dummy);
}
static gboolean
is_monitor_framebuffers_scaled (void)
{
MetaBackend *backend = meta_get_backend ();
return meta_backend_is_experimental_feature_enabled (
backend,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
}
static MetaMonitorManagerCapability
meta_monitor_manager_dummy_get_capabilities (MetaMonitorManager *manager)
{
MetaMonitorManagerCapability capabilities =
META_MONITOR_MANAGER_CAPABILITY_NONE;
capabilities |= META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
if (meta_backend_is_experimental_feature_enabled (
meta_get_backend (),
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;
return capabilities;
}
static gboolean
meta_monitor_manager_dummy_get_max_screen_size (MetaMonitorManager *manager,
int *max_width,
int *max_height)
{
if (meta_is_stage_views_enabled ())
return FALSE;
*max_width = 65535;
*max_height = 65535;
return TRUE;
}
static MetaLogicalMonitorLayoutMode
meta_monitor_manager_dummy_get_default_layout_mode (MetaMonitorManager *manager)
{
if (!meta_is_stage_views_enabled ())
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
if (is_monitor_framebuffers_scaled ())
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
else
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
}
static void
meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
{
@ -543,6 +667,11 @@ meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
manager_class->apply_monitors_config = meta_monitor_manager_dummy_apply_monitors_config;
manager_class->apply_configuration = meta_monitor_manager_dummy_apply_config;
manager_class->is_transform_handled = meta_monitor_manager_dummy_is_transform_handled;
manager_class->calculate_monitor_mode_scale = meta_monitor_manager_dummy_calculate_monitor_mode_scale;
manager_class->get_supported_scales = meta_monitor_manager_dummy_get_supported_scales;
manager_class->get_capabilities = meta_monitor_manager_dummy_get_capabilities;
manager_class->get_max_screen_size = meta_monitor_manager_dummy_get_max_screen_size;
manager_class->get_default_layout_mode = meta_monitor_manager_dummy_get_default_layout_mode;
}
static void

View File

@ -59,6 +59,8 @@ typedef struct _MetaMonitorTiled MetaMonitorTiled;
typedef struct _MetaMonitorSpec MetaMonitorSpec;
typedef struct _MetaLogicalMonitor MetaLogicalMonitor;
typedef struct _MetaMonitorMode MetaMonitorMode;
typedef struct _MetaCrtc MetaCrtc;
typedef struct _MetaOutput MetaOutput;
typedef struct _MetaCrtcMode MetaCrtcMode;
@ -66,6 +68,28 @@ typedef struct _MetaCrtcInfo MetaCrtcInfo;
typedef struct _MetaOutputInfo MetaOutputInfo;
typedef struct _MetaTileInfo MetaTileInfo;
typedef enum _MetaMonitorManagerCapability
{
META_MONITOR_MANAGER_CAPABILITY_NONE = 0,
META_MONITOR_MANAGER_CAPABILITY_MIRRORING = (1 << 0),
META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE = (1 << 1)
} MetaMonitorManagerCapability;
/* Equivalent to the 'method' enum in org.gnome.Mutter.DisplayConfig */
typedef enum _MetaMonitorsConfigMethod
{
META_MONITORS_CONFIG_METHOD_VERIFY = 0,
META_MONITORS_CONFIG_METHOD_TEMPORARY = 1,
META_MONITORS_CONFIG_METHOD_PERSISTENT = 2
} MetaMonitorsConfigMethod;
/* Equivalent to the 'layout-mode' enum in org.gnome.Mutter.DisplayConfig */
typedef enum _MetaLogicalMonitorLayoutMode
{
META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL = 1,
META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL = 2
} MetaLogicalMonitorLayoutMode;
typedef enum
{
META_MONITOR_TRANSFORM_NORMAL,
@ -125,7 +149,6 @@ struct _MetaOutput
int width_mm;
int height_mm;
CoglSubpixelOrder subpixel_order;
int scale;
MetaConnectorType connector_type;
@ -237,6 +260,12 @@ struct _MetaOutputInfo
gboolean is_underscanning;
};
typedef enum _MetaMonitorConfigSystem
{
META_MONITOR_CONFIG_SYSTEM_LEGACY,
META_MONITOR_CONFIG_SYSTEM_MANAGER
} MetaMonitorConfigSystem;
#define META_TYPE_MONITOR_MANAGER (meta_monitor_manager_get_type ())
#define META_MONITOR_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER, MetaMonitorManager))
#define META_MONITOR_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_MANAGER, MetaMonitorManagerClass))
@ -259,8 +288,8 @@ struct _MetaMonitorManager
MetaPowerSave power_save_mode;
int max_screen_width;
int max_screen_height;
MetaLogicalMonitorLayoutMode layout_mode;
int screen_width;
int screen_height;
@ -285,13 +314,17 @@ struct _MetaMonitorManager
int dbus_name_id;
MetaMonitorConfigSystem pending_persistent_system;
int persistent_timeout_id;
MetaMonitorConfig *legacy_config;
MetaMonitorConfigManager *config_manager;
GnomePnpIds *pnp_ids;
UpClient *up_client;
gulong experimental_features_changed_handler_id;
};
struct _MetaMonitorManagerClass
@ -309,9 +342,10 @@ struct _MetaMonitorManagerClass
void (*ensure_initial_config) (MetaMonitorManager *);
gboolean (*apply_monitors_config) (MetaMonitorManager *,
MetaMonitorsConfig *,
GError **);
gboolean (*apply_monitors_config) (MetaMonitorManager *,
MetaMonitorsConfig *,
MetaMonitorsConfigMethod ,
GError **);
void (*apply_configuration) (MetaMonitorManager *,
MetaCrtcInfo **,
@ -348,8 +382,26 @@ struct _MetaMonitorManagerClass
gboolean (*is_transform_handled) (MetaMonitorManager *,
MetaCrtc *,
MetaMonitorTransform);
int (*calculate_monitor_mode_scale) (MetaMonitorManager *,
MetaMonitor *,
MetaMonitorMode *);
void (*get_supported_scales) (MetaMonitorManager *,
float **,
int *);
MetaMonitorManagerCapability (*get_capabilities) (MetaMonitorManager *);
gboolean (*get_max_screen_size) (MetaMonitorManager *,
int *,
int *);
MetaLogicalMonitorLayoutMode (*get_default_layout_mode) (MetaMonitorManager *);
};
gboolean meta_is_monitor_config_manager_enabled (void);
void meta_monitor_manager_rebuild (MetaMonitorManager *manager,
MetaMonitorsConfig *config);
void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager);
@ -398,10 +450,6 @@ void meta_monitor_manager_get_screen_size (MetaMonitorManager *
int *width,
int *height);
void meta_monitor_manager_get_screen_limits (MetaMonitorManager *manager,
int *width,
int *height);
void meta_monitor_manager_apply_configuration (MetaMonitorManager *manager,
MetaCrtcInfo **crtcs,
unsigned int n_crtcs,
@ -447,6 +495,17 @@ void meta_monitor_manager_lid_is_closed_changed (MetaMonitorManage
gboolean meta_monitor_manager_is_headless (MetaMonitorManager *manager);
int meta_monitor_manager_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode);
gboolean meta_monitor_manager_get_max_screen_size (MetaMonitorManager *manager,
int *max_width,
int *max_height);
MetaLogicalMonitorLayoutMode
meta_monitor_manager_get_default_layout_mode (MetaMonitorManager *manager);
void meta_monitor_manager_clear_output (MetaOutput *output);
void meta_monitor_manager_clear_mode (MetaCrtcMode *mode);
void meta_monitor_manager_clear_crtc (MetaCrtc *crtc);

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,13 @@ typedef struct _MetaMonitorMode
MetaMonitorCrtcMode *crtc_modes;
} MetaMonitorMode;
typedef struct _MetaMonitorModeTiled
{
MetaMonitorMode parent;
gboolean is_tiled;
} MetaMonitorModeTiled;
typedef struct _MetaMonitorPrivate
{
GList *outputs;
@ -186,6 +193,16 @@ meta_monitor_is_primary (MetaMonitor *monitor)
return output->is_primary;
}
gboolean
meta_monitor_supports_underscanning (MetaMonitor *monitor)
{
MetaOutput *output;
output = meta_monitor_get_main_output (monitor);
return output->supports_underscanning;
}
gboolean
meta_monitor_is_underscanning (MetaMonitor *monitor)
{
@ -254,6 +271,15 @@ meta_monitor_get_subpixel_order (MetaMonitor *monitor)
return output->subpixel_order;
}
const char *
meta_monitor_get_connector (MetaMonitor *monitor)
{
MetaOutput *output;
output = meta_monitor_get_main_output (monitor);
return output->name;
}
const char *
meta_monitor_get_vendor (MetaMonitor *monitor)
{
@ -281,6 +307,15 @@ meta_monitor_get_serial (MetaMonitor *monitor)
return output->serial;
}
MetaConnectorType
meta_monitor_get_connector_type (MetaMonitor *monitor)
{
MetaOutput *output;
output = meta_monitor_get_main_output (monitor);
return output->connector_type;
}
static void
meta_monitor_finalize (GObject *object)
{
@ -328,8 +363,6 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
},
mode->crtc_modes = g_new (MetaMonitorCrtcMode, 1);
mode->crtc_modes[0] = (MetaMonitorCrtcMode) {
.x = 0,
.y = 0,
.output = output,
.crtc_mode = crtc_mode
};
@ -384,6 +417,18 @@ meta_monitor_normal_derive_dimensions (MetaMonitor *monitor,
*height = output->crtc->rect.height;
}
static void
meta_monitor_normal_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
*out_x = 0;
*out_y = 0;
}
static void
meta_monitor_normal_init (MetaMonitorNormal *monitor)
{
@ -396,6 +441,7 @@ meta_monitor_normal_class_init (MetaMonitorNormalClass *klass)
monitor_class->get_main_output = meta_monitor_normal_get_main_output;
monitor_class->derive_dimensions = meta_monitor_normal_derive_dimensions;
monitor_class->calculate_crtc_pos = meta_monitor_normal_calculate_crtc_pos;
}
uint32_t
@ -444,10 +490,11 @@ add_tiled_monitor_outputs (MetaMonitorManager *monitor_manager,
}
static void
calculate_tile_coordinate (MetaMonitor *monitor,
MetaOutput *output,
int *out_x,
int *out_y)
calculate_tile_coordinate (MetaMonitor *monitor,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
@ -459,12 +506,45 @@ calculate_tile_coordinate (MetaMonitor *monitor,
{
MetaOutput *other_output = l->data;
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
x += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
y += other_output->tile_info.tile_h;
switch (crtc_transform)
{
case META_MONITOR_TRANSFORM_NORMAL:
case META_MONITOR_TRANSFORM_FLIPPED:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
x += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
y += other_output->tile_info.tile_h;
break;
case META_MONITOR_TRANSFORM_180:
case META_MONITOR_TRANSFORM_FLIPPED_180:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile)
x += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile)
y += other_output->tile_info.tile_h;
break;
case META_MONITOR_TRANSFORM_270:
case META_MONITOR_TRANSFORM_FLIPPED_270:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
y += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
x += other_output->tile_info.tile_h;
break;
case META_MONITOR_TRANSFORM_90:
case META_MONITOR_TRANSFORM_FLIPPED_90:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile)
y += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile)
x += other_output->tile_info.tile_h;
break;
}
}
*out_x = x;
@ -529,40 +609,35 @@ create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled)
MetaMonitor *monitor = META_MONITOR (monitor_tiled);
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
MetaMonitorMode *mode;
MetaMonitorModeTiled *mode;
GList *l;
int i;
mode = g_new0 (MetaMonitorMode, 1);
mode = g_new0 (MetaMonitorModeTiled, 1);
mode->is_tiled = TRUE;
meta_monitor_tiled_calculate_tiled_size (monitor,
&mode->spec.width,
&mode->spec.height);
mode->crtc_modes = g_new0 (MetaMonitorCrtcMode,
g_list_length (monitor_priv->outputs));
&mode->parent.spec.width,
&mode->parent.spec.height);
mode->parent.crtc_modes = g_new0 (MetaMonitorCrtcMode,
g_list_length (monitor_priv->outputs));
for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++)
{
MetaOutput *output = l->data;
MetaCrtcMode *preferred_crtc_mode = output->preferred_mode;
int x;
int y;
calculate_tile_coordinate (monitor, output, &x, &y);
mode->crtc_modes[i] = (MetaMonitorCrtcMode) {
.x = x,
.y = y,
mode->parent.crtc_modes[i] = (MetaMonitorCrtcMode) {
.output = output,
.crtc_mode = preferred_crtc_mode
};
g_warn_if_fail (mode->spec.refresh_rate == 0.0f ||
(mode->spec.refresh_rate ==
g_warn_if_fail (mode->parent.spec.refresh_rate == 0.0f ||
(mode->parent.spec.refresh_rate ==
preferred_crtc_mode->refresh_rate));
mode->spec.refresh_rate = preferred_crtc_mode->refresh_rate;
mode->parent.spec.refresh_rate = preferred_crtc_mode->refresh_rate;
}
return mode;
return &mode->parent;
}
static MetaMonitorMode *
@ -573,7 +648,7 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
MetaMonitor *monitor = META_MONITOR (monitor_tiled);
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
MetaMonitorMode *mode;
MetaMonitorModeTiled *mode;
GList *l;
int i;
@ -585,14 +660,15 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
crtc_mode->height == (int) main_output->tile_info.tile_h)
return NULL;
mode = g_new0 (MetaMonitorMode, 1);
mode = g_new0 (MetaMonitorModeTiled, 1);
mode->spec = (MetaMonitorModeSpec) {
mode->is_tiled = FALSE;
mode->parent.spec = (MetaMonitorModeSpec) {
.width = crtc_mode->width,
.height = crtc_mode->height,
.refresh_rate = crtc_mode->refresh_rate
};
mode->crtc_modes = g_new0 (MetaMonitorCrtcMode,
mode->parent.crtc_modes = g_new0 (MetaMonitorCrtcMode,
g_list_length (monitor_priv->outputs));
for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++)
@ -601,23 +677,21 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
if (output == main_output)
{
mode->crtc_modes[i] = (MetaMonitorCrtcMode) {
.x = 0,
.y = 0,
mode->parent.crtc_modes[i] = (MetaMonitorCrtcMode) {
.output = output,
.crtc_mode = crtc_mode
};
}
else
{
mode->crtc_modes[i] = (MetaMonitorCrtcMode) {
mode->parent.crtc_modes[i] = (MetaMonitorCrtcMode) {
.output = output,
.crtc_mode = NULL
};
}
}
return mode;
return &mode->parent;
}
static void
@ -725,6 +799,28 @@ meta_monitor_tiled_derive_dimensions (MetaMonitor *monitor,
*out_height = max_y - min_y;
}
static void
meta_monitor_tiled_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
MetaMonitorModeTiled *mode_tiled = (MetaMonitorModeTiled *) monitor_mode;
if (mode_tiled->is_tiled)
{
calculate_tile_coordinate (monitor, output, crtc_transform,
out_x, out_y);
}
else
{
*out_x = 0;
*out_y = 0;
}
}
static void
meta_monitor_tiled_finalize (GObject *object)
{
@ -752,6 +848,7 @@ meta_monitor_tiled_class_init (MetaMonitorTiledClass *klass)
monitor_class->get_main_output = meta_monitor_tiled_get_main_output;
monitor_class->derive_dimensions = meta_monitor_tiled_derive_dimensions;
monitor_class->calculate_crtc_pos = meta_monitor_tiled_calculate_crtc_pos;
}
static void
@ -863,6 +960,22 @@ meta_monitor_get_modes (MetaMonitor *monitor)
return priv->modes;
}
void
meta_monitor_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
META_MONITOR_GET_CLASS (monitor)->calculate_crtc_pos (monitor,
monitor_mode,
output,
crtc_transform,
out_x,
out_y);
}
MetaMonitorModeSpec *
meta_monitor_mode_get_spec (MetaMonitorMode *monitor_mode)
{

View File

@ -26,8 +26,6 @@
#include "backends/meta-monitor-manager-private.h"
typedef struct _MetaMonitorMode MetaMonitorMode;
typedef struct _MetaMonitorSpec
{
char *connector;
@ -45,8 +43,6 @@ typedef struct _MetaMonitorModeSpec
typedef struct _MetaMonitorCrtcMode
{
int x;
int y;
MetaOutput *output;
MetaCrtcMode *crtc_mode;
} MetaMonitorCrtcMode;
@ -68,6 +64,12 @@ struct _MetaMonitorClass
void (* derive_dimensions) (MetaMonitor *monitor,
int *width,
int *height);
void (* calculate_crtc_pos) (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y);
};
#define META_TYPE_MONITOR_NORMAL (meta_monitor_normal_get_type ())
@ -93,6 +95,8 @@ MetaOutput * meta_monitor_get_main_output (MetaMonitor *monitor);
gboolean meta_monitor_is_primary (MetaMonitor *monitor);
gboolean meta_monitor_supports_underscanning (MetaMonitor *monitor);
gboolean meta_monitor_is_underscanning (MetaMonitor *monitor);
gboolean meta_monitor_is_laptop_panel (MetaMonitor *monitor);
@ -113,12 +117,16 @@ void meta_monitor_get_physical_dimensions (MetaMonitor *monitor,
CoglSubpixelOrder meta_monitor_get_subpixel_order (MetaMonitor *monitor);
const char * meta_monitor_get_connector (MetaMonitor *monitor);
const char * meta_monitor_get_vendor (MetaMonitor *monitor);
const char * meta_monitor_get_product (MetaMonitor *monitor);
const char * meta_monitor_get_serial (MetaMonitor *monitor);
MetaConnectorType meta_monitor_get_connector_type (MetaMonitor *monitor);
uint32_t meta_monitor_tiled_get_tile_group_id (MetaMonitorTiled *monitor_tiled);
gboolean meta_monitor_get_suggested_position (MetaMonitor *monitor,
@ -141,6 +149,13 @@ void meta_monitor_set_current_mode (MetaMonitor *monitor,
GList * meta_monitor_get_modes (MetaMonitor *monitor);
void meta_monitor_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y);
MetaMonitorModeSpec * meta_monitor_mode_get_spec (MetaMonitorMode *monitor_mode);
void meta_monitor_mode_get_resolution (MetaMonitorMode *monitor_mode,

View File

@ -51,6 +51,12 @@ meta_renderer_view_get_logical_monitor (MetaRendererView *view)
return view->logical_monitor;
}
MetaMonitorTransform
meta_renderer_view_get_transform (MetaRendererView *view)
{
return view->transform;
}
static void
meta_renderer_view_get_offscreen_transformation_matrix (ClutterStageView *view,
CoglMatrix *matrix)

View File

@ -28,4 +28,6 @@ G_DECLARE_FINAL_TYPE (MetaRendererView, meta_renderer_view,
MetaLogicalMonitor *meta_renderer_view_get_logical_monitor (MetaRendererView *view);
MetaMonitorTransform meta_renderer_view_get_transform (MetaRendererView *view);
#endif /* META_RENDERER_VIEW_H */

View File

@ -485,7 +485,7 @@ meta_backend_native_set_keymap (MetaBackend *backend,
clutter_evdev_set_keyboard_map (manager, keymap);
g_signal_emit_by_name (backend, "keymap-changed", 0);
meta_backend_notify_keymap_changed (backend);
xkb_keymap_unref (keymap);
}
@ -502,8 +502,9 @@ meta_backend_native_lock_layout_group (MetaBackend *backend,
guint idx)
{
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
clutter_evdev_set_keyboard_layout_index (manager, idx);
g_signal_emit_by_name (backend, "keymap-layout-group-changed", idx, 0);
meta_backend_notify_keymap_layout_group_changed (backend, idx);
}
static void

View File

@ -35,6 +35,8 @@
#include <meta/meta-backend.h>
#include "backends/meta-backend-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor.h"
#include "backends/meta-monitor-manager-private.h"
#include "backends/native/meta-renderer-native.h"
#include "meta/boxes.h"
@ -214,50 +216,131 @@ set_crtc_cursor (MetaCursorRendererNative *native,
}
}
typedef struct
{
MetaCursorRendererNative *in_cursor_renderer_native;
MetaLogicalMonitor *in_logical_monitor;
MetaRectangle in_local_cursor_rect;
MetaCursorSprite *in_cursor_sprite;
gboolean out_painted;
} UpdateCrtcCursorData;
static gboolean
update_monitor_crtc_cursor (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaMonitorCrtcMode *monitor_crtc_mode,
gpointer user_data,
GError **error)
{
UpdateCrtcCursorData *data = user_data;
MetaCursorRendererNative *cursor_renderer_native =
data->in_cursor_renderer_native;
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaRectangle scaled_crtc_rect;
int scale;
int crtc_x, crtc_y;
if (meta_is_stage_views_scaled ())
scale = meta_logical_monitor_get_scale (data->in_logical_monitor);
else
scale = 1;
meta_monitor_calculate_crtc_pos (monitor, monitor_mode,
monitor_crtc_mode->output,
META_MONITOR_TRANSFORM_NORMAL,
&crtc_x, &crtc_y);
scaled_crtc_rect = (MetaRectangle) {
.x = crtc_x / scale,
.y = crtc_y / scale,
.width = monitor_crtc_mode->crtc_mode->width / scale,
.height = monitor_crtc_mode->crtc_mode->height / scale
};
if (priv->has_hw_cursor &&
meta_rectangle_overlap (&scaled_crtc_rect,
&data->in_local_cursor_rect))
{
int crtc_cursor_x, crtc_cursor_y;
set_crtc_cursor (data->in_cursor_renderer_native,
monitor_crtc_mode->output->crtc,
data->in_cursor_sprite);
crtc_cursor_x = (data->in_local_cursor_rect.x - scaled_crtc_rect.x) * scale;
crtc_cursor_y = (data->in_local_cursor_rect.y - scaled_crtc_rect.y) * scale;
drmModeMoveCursor (priv->drm_fd,
monitor_crtc_mode->output->crtc->crtc_id,
crtc_cursor_x,
crtc_cursor_y);
data->out_painted = data->out_painted || TRUE;
}
else
{
set_crtc_cursor (data->in_cursor_renderer_native,
monitor_crtc_mode->output->crtc, NULL);
}
return TRUE;
}
static void
update_hw_cursor (MetaCursorRendererNative *native,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
MetaMonitorManager *monitors;
MetaCrtc *crtcs;
unsigned int i, n_crtcs;
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
GList *logical_monitors;
GList *l;
MetaRectangle rect;
gboolean painted = FALSE;
monitors = meta_monitor_manager_get ();
meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
if (cursor_sprite)
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
else
rect = (MetaRectangle) { 0 };
for (i = 0; i < n_crtcs; i++)
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
gboolean crtc_should_use_cursor;
MetaCursorSprite *crtc_cursor;
MetaRectangle *crtc_rect;
MetaLogicalMonitor *logical_monitor = l->data;
UpdateCrtcCursorData data;
GList *monitors;
GList *k;
crtc_rect = &crtcs[i].rect;
data = (UpdateCrtcCursorData) {
.in_cursor_renderer_native = native,
.in_logical_monitor = logical_monitor,
.in_local_cursor_rect = (MetaRectangle) {
.x = rect.x - logical_monitor->rect.x,
.y = rect.y - logical_monitor->rect.y,
.width = rect.width,
.height = rect.height
},
.in_cursor_sprite = cursor_sprite
};
crtc_should_use_cursor = (priv->has_hw_cursor &&
meta_rectangle_overlap (&rect, crtc_rect));
if (crtc_should_use_cursor)
crtc_cursor = cursor_sprite;
else
crtc_cursor = NULL;
set_crtc_cursor (native, &crtcs[i], crtc_cursor);
if (crtc_cursor)
monitors = meta_logical_monitor_get_monitors (logical_monitor);
for (k = monitors; k; k = k->next)
{
drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
rect.x - crtc_rect->x,
rect.y - crtc_rect->y);
painted = TRUE;
MetaMonitor *monitor = k->data;
MetaMonitorMode *monitor_mode;
monitor_mode = meta_monitor_get_current_mode (monitor);
meta_monitor_mode_foreach_crtc (monitor, monitor_mode,
update_monitor_crtc_cursor,
&data,
NULL);
}
painted = painted || data.out_painted;
}
priv->hw_state_invalidated = FALSE;
@ -316,6 +399,55 @@ cursor_over_transformed_crtc (MetaCursorRenderer *renderer,
return FALSE;
}
static float
calculate_cursor_crtc_sprite_scale (MetaCursorSprite *cursor_sprite,
MetaLogicalMonitor *logical_monitor)
{
return (meta_logical_monitor_get_scale (logical_monitor) *
meta_cursor_sprite_get_texture_scale (cursor_sprite));
}
static gboolean
can_draw_cursor_unscaled (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaBackend *backend;
MetaMonitorManager *monitor_manager;
MetaRectangle cursor_rect;
GList *logical_monitors;
GList *l;
gboolean has_visible_crtc_sprite = FALSE;
if (!meta_is_stage_views_scaled ())
return meta_cursor_sprite_get_texture_scale (cursor_sprite) == 1.0;
backend = meta_get_backend ();
monitor_manager = meta_backend_get_monitor_manager (backend);
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
if (!logical_monitors)
return FALSE;
cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
if (!meta_rectangle_overlap (&cursor_rect, &logical_monitor->rect))
continue;
if (calculate_cursor_crtc_sprite_scale (cursor_sprite,
logical_monitor) != 1.0)
return FALSE;
has_visible_crtc_sprite = TRUE;
}
return has_visible_crtc_sprite;
}
static gboolean
should_have_hw_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
@ -337,7 +469,7 @@ should_have_hw_cursor (MetaCursorRenderer *renderer,
if (!texture)
return FALSE;
if (meta_cursor_sprite_get_texture_scale (cursor_sprite) != 1)
if (!can_draw_cursor_unscaled (renderer, cursor_sprite))
return FALSE;
if (!has_valid_cursor_sprite_gbm_bo (cursor_sprite))

View File

@ -52,6 +52,11 @@
#define ALL_TRANSFORMS_MASK ((1 << ALL_TRANSFORMS) - 1)
#define SYNC_TOLERANCE 0.01 /* 1 percent */
static float supported_scales_kms[] = {
1.0,
2.0
};
typedef struct
{
drmModeConnector *connector;
@ -113,6 +118,9 @@ struct _MetaMonitorManagerKms
GSettings *desktop_settings;
gboolean page_flips_not_supported;
int max_buffer_width;
int max_buffer_height;
};
struct _MetaMonitorManagerKmsClass
@ -483,85 +491,6 @@ find_output_by_id (MetaOutput *outputs,
return NULL;
}
/* The minimum resolution at which we turn on a window-scale of 2 */
#define HIDPI_LIMIT 192
/* The minimum screen height at which we turn on a window-scale of 2;
* below this there just isn't enough vertical real estate for GNOME
* apps to work, and it's better to just be tiny */
#define HIDPI_MIN_HEIGHT 1200
/* From http://en.wikipedia.org/wiki/4K_resolution#Resolutions_of_common_formats */
#define SMALLEST_4K_WIDTH 3656
/* Based on code from gnome-settings-daemon */
static int
compute_scale (MetaOutput *output)
{
int scale = 1, width, height;
if (!output->crtc)
goto out;
width = output->crtc->rect.width;
height = output->crtc->rect.height;
/* Swap values on rotated transforms, so pixel and mm sizes
* from the same axes is compared.
*/
if (meta_monitor_transform_is_rotated (output->crtc->transform))
{
int tmp = width;
width = height;
height = tmp;
}
/* Scaling makes no sense */
if (height < HIDPI_MIN_HEIGHT)
goto out;
/* 4K TV */
if (output->name != NULL && strstr(output->name, "HDMI") != NULL &&
width >= SMALLEST_4K_WIDTH)
goto out;
/* Somebody encoded the aspect ratio (16/9 or 16/10)
* instead of the physical size */
if ((output->width_mm == 160 && output->height_mm == 90) ||
(output->width_mm == 160 && output->height_mm == 100) ||
(output->width_mm == 16 && output->height_mm == 9) ||
(output->width_mm == 16 && output->height_mm == 10))
goto out;
if (output->width_mm > 0 && output->height_mm > 0)
{
double dpi_x, dpi_y;
dpi_x = (double)width / (output->width_mm / 25.4);
dpi_y = (double)height / (output->height_mm / 25.4);
/* We don't completely trust these values so both
must be high, and never pick higher ratio than
2 automatically */
if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT)
scale = 2;
}
out:
return scale;
}
static int
get_output_scale (MetaMonitorManager *manager,
MetaOutput *output)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
int scale = g_settings_get_uint (manager_kms->desktop_settings, "scaling-factor");
if (scale > 0)
return scale;
else
return compute_scale (output);
}
static int
find_property_index (MetaMonitorManager *manager,
drmModeObjectPropertiesPtr props,
@ -930,8 +859,6 @@ init_output (MetaOutput *output,
/* MetaConnectorType matches DRM's connector types */
output->connector_type = (MetaConnectorType) connector->connector_type;
output->scale = get_output_scale (manager, output);
output_get_tile_info (manager_kms, output);
/* FIXME: backlight is a very driver specific thing unfortunately,
@ -1195,9 +1122,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
resources = drmModeGetResources (manager_kms->fd);
/* TODO: max screen width only matters for stage views is not enabled. */
manager->max_screen_width = resources->max_width;
manager->max_screen_height = resources->max_height;
manager_kms->max_buffer_width = resources->max_width;
manager_kms->max_buffer_height = resources->max_height;
manager->power_save_mode = META_POWER_SAVE_ON;
@ -1334,7 +1260,7 @@ meta_monitor_manager_kms_ensure_initial_config (MetaMonitorManager *manager)
config = meta_monitor_manager_ensure_configured (manager);
if (manager->config_manager)
if (meta_is_monitor_config_manager_enabled ())
meta_monitor_manager_update_logical_state (manager, config);
else
meta_monitor_manager_update_logical_state_derived (manager);
@ -1399,7 +1325,6 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output->is_dirty = TRUE;
output->crtc = crtc;
output->scale = get_output_scale (manager, output);
}
}
@ -1501,9 +1426,10 @@ update_screen_size (MetaMonitorManager *manager,
}
static gboolean
meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager,
MetaMonitorsConfig *config,
GError **error)
meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager,
MetaMonitorsConfig *config,
MetaMonitorsConfigMethod method,
GError **error)
{
GPtrArray *crtc_infos;
GPtrArray *output_infos;
@ -1512,6 +1438,7 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager,
{
manager->screen_width = 0;
manager->screen_height = 0;
meta_monitor_manager_rebuild (manager, NULL);
return TRUE;
}
@ -1520,6 +1447,13 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager,
error))
return FALSE;
if (method == META_MONITORS_CONFIG_METHOD_VERIFY)
{
g_ptr_array_free (crtc_infos, TRUE);
g_ptr_array_free (output_infos, TRUE);
return TRUE;
}
apply_crtc_assignments (manager,
(MetaCrtcInfo **) crtc_infos->pdata,
crtc_infos->len,
@ -1898,6 +1832,160 @@ meta_monitor_manager_kms_is_transform_handled (MetaMonitorManager *manager,
return FALSE;
}
/* The minimum resolution at which we turn on a window-scale of 2 */
#define HIDPI_LIMIT 192
/* The minimum screen height at which we turn on a window-scale of 2;
* below this there just isn't enough vertical real estate for GNOME
* apps to work, and it's better to just be tiny */
#define HIDPI_MIN_HEIGHT 1200
/* From http://en.wikipedia.org/wiki/4K_resolution#Resolutions_of_common_formats */
#define SMALLEST_4K_WIDTH 3656
static int
compute_scale (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
int resolution_width, resolution_height;
int width_mm, height_mm;
int scale;
scale = 1;
meta_monitor_mode_get_resolution (monitor_mode,
&resolution_width,
&resolution_height);
if (resolution_height < HIDPI_MIN_HEIGHT)
goto out;
/* 4K TV */
switch (meta_monitor_get_connector_type (monitor))
{
case META_CONNECTOR_TYPE_HDMIA:
case META_CONNECTOR_TYPE_HDMIB:
if (resolution_width >= SMALLEST_4K_WIDTH)
goto out;
break;
default:
break;
}
meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm);
/*
* Somebody encoded the aspect ratio (16/9 or 16/10) instead of the physical
* size.
*/
if ((width_mm == 160 && height_mm == 90) ||
(width_mm == 160 && height_mm == 100) ||
(width_mm == 16 && height_mm == 9) ||
(width_mm == 16 && height_mm == 10))
goto out;
if (width_mm > 0 && height_mm > 0)
{
double dpi_x, dpi_y;
dpi_x = (double) resolution_width / (width_mm / 25.4);
dpi_y = (double) resolution_height / (height_mm / 25.4);
/*
* We don't completely trust these values so both must be high, and never
* pick higher ratio than 2 automatically.
*/
if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT)
scale = 2;
}
out:
return scale;
}
static int
meta_monitor_manager_kms_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
int global_scale;
global_scale = g_settings_get_uint (manager_kms->desktop_settings,
"scaling-factor");
if (global_scale > 0)
return global_scale;
else
return compute_scale (monitor, monitor_mode);
}
static void
meta_monitor_manager_kms_get_supported_scales (MetaMonitorManager *manager,
float **scales,
int *n_scales)
{
*scales = supported_scales_kms;
*n_scales = G_N_ELEMENTS (supported_scales_kms);
}
static MetaMonitorManagerCapability
meta_monitor_manager_kms_get_capabilities (MetaMonitorManager *manager)
{
MetaBackend *backend = meta_get_backend ();
MetaRenderer *renderer = meta_backend_get_renderer (backend);
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
MetaMonitorManagerCapability capabilities =
META_MONITOR_MANAGER_CAPABILITY_NONE;
if (meta_backend_is_experimental_feature_enabled (
backend,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;
switch (meta_renderer_native_get_mode (renderer_native))
{
case META_RENDERER_NATIVE_MODE_GBM:
capabilities |= META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
break;
#ifdef HAVE_EGL_DEVICE
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
break;
#endif
}
return capabilities;
}
static gboolean
meta_monitor_manager_kms_get_max_screen_size (MetaMonitorManager *manager,
int *max_width,
int *max_height)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
if (meta_is_stage_views_enabled ())
return FALSE;
*max_width = manager_kms->max_buffer_width;
*max_height = manager_kms->max_buffer_height;
return TRUE;
}
static MetaLogicalMonitorLayoutMode
meta_monitor_manager_kms_get_default_layout_mode (MetaMonitorManager *manager)
{
if (!meta_is_stage_views_enabled ())
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
if (meta_backend_is_experimental_feature_enabled (
meta_get_backend (),
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
else
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
}
static void
meta_monitor_manager_kms_dispose (GObject *object)
{
@ -1938,4 +2026,9 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
manager_class->get_crtc_gamma = meta_monitor_manager_kms_get_crtc_gamma;
manager_class->set_crtc_gamma = meta_monitor_manager_kms_set_crtc_gamma;
manager_class->is_transform_handled = meta_monitor_manager_kms_is_transform_handled;
manager_class->calculate_monitor_mode_scale = meta_monitor_manager_kms_calculate_monitor_mode_scale;
manager_class->get_supported_scales = meta_monitor_manager_kms_get_supported_scales;
manager_class->get_capabilities = meta_monitor_manager_kms_get_capabilities;
manager_class->get_max_screen_size = meta_monitor_manager_kms_get_max_screen_size;
manager_class->get_default_layout_mode = meta_monitor_manager_kms_get_default_layout_mode;
}

View File

@ -703,7 +703,7 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
flip_closure = g_cclosure_new (G_CALLBACK (on_crtc_flipped),
g_object_ref (view),
(GClosureNotify) flip_closure_destroyed);
g_closure_set_marshal (flip_closure, g_cclosure_marshal_generic);
g_closure_set_marshal (flip_closure, g_cclosure_marshal_VOID__VOID);
/* Either flip the CRTC's of the monitor info, if we are drawing just part
* of the stage, or all of the CRTC's if we are drawing the whole stage.
@ -1686,10 +1686,10 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
if (meta_monitor_manager_is_transform_handled (monitor_manager,
main_output->crtc,
main_output->crtc->transform))
logical_monitor->transform))
return META_MONITOR_TRANSFORM_NORMAL;
else
return main_output->crtc->transform;
return logical_monitor->transform;
}
static MetaRendererView *
@ -1707,16 +1707,26 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
MetaMonitorTransform view_transform;
CoglOnscreen *onscreen = NULL;
CoglOffscreen *offscreen = NULL;
int scale;
int width, height;
MetaRendererView *view;
GError *error = NULL;
view_transform = calculate_view_transform (monitor_manager, logical_monitor);
if (meta_is_stage_views_scaled ())
scale = logical_monitor->scale;
else
scale = 1;
width = logical_monitor->rect.width * scale;
height = logical_monitor->rect.height * scale;
onscreen = meta_renderer_native_create_onscreen (META_RENDERER_NATIVE (renderer),
cogl_context,
view_transform,
logical_monitor->rect.width,
logical_monitor->rect.height);
width,
height);
if (!onscreen)
meta_fatal ("Failed to allocate onscreen framebuffer\n");
@ -1725,14 +1735,15 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
offscreen = meta_renderer_native_create_offscreen (META_RENDERER_NATIVE (renderer),
cogl_context,
view_transform,
logical_monitor->rect.width,
logical_monitor->rect.height);
width,
height);
if (!offscreen)
meta_fatal ("Failed to allocate back buffer texture\n");
}
view = g_object_new (META_TYPE_RENDERER_VIEW,
"layout", &logical_monitor->rect,
"scale", scale,
"framebuffer", onscreen,
"offscreen", offscreen,
"logical-monitor", logical_monitor,

View File

@ -29,6 +29,7 @@
#include "backends/meta-backend-private.h"
#include "backends/x11/meta-cursor-renderer-x11.h"
#include "backends/x11/meta-monitor-manager-xrandr.h"
#include "backends/x11/cm/meta-renderer-x11-cm.h"
struct _MetaBackendX11Cm
{
@ -89,6 +90,12 @@ meta_backend_x11_cm_post_init (MetaBackend *backend)
take_touch_grab (backend);
}
static MetaRenderer *
meta_backend_x11_cm_create_renderer (MetaBackend *backend)
{
return g_object_new (META_TYPE_RENDERER_X11_CM, NULL);
}
static MetaMonitorManager *
meta_backend_x11_cm_create_monitor_manager (MetaBackend *backend)
{
@ -380,6 +387,7 @@ meta_backend_x11_cm_class_init (MetaBackendX11CmClass *klass)
MetaBackendX11Class *backend_x11_class = META_BACKEND_X11_CLASS (klass);
backend_class->post_init = meta_backend_x11_cm_post_init;
backend_class->create_renderer = meta_backend_x11_cm_create_renderer;
backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager;
backend_class->create_cursor_renderer = meta_backend_x11_cm_create_cursor_renderer;
backend_class->update_screen_size = meta_backend_x11_cm_update_screen_size;

View File

@ -0,0 +1,43 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2016 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.
*
*/
#include "config.h"
#include "backends/x11/cm/meta-renderer-x11-cm.h"
struct _MetaRendererX11Cm
{
MetaRendererX11 parent;
};
G_DEFINE_TYPE (MetaRendererX11Cm, meta_renderer_x11_cm,
META_TYPE_RENDERER_X11)
static void
meta_renderer_x11_cm_init (MetaRendererX11Cm *renderer_x11_cm)
{
}
static void
meta_renderer_x11_cm_class_init (MetaRendererX11CmClass *klass)
{
}

View File

@ -0,0 +1,33 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2016 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.
*
*/
#ifndef META_RENDERER_X11_CM_H
#define META_RENDERER_X11_CM_H
#include "backends/x11/meta-renderer-x11.h"
#define META_TYPE_RENDERER_X11_CM (meta_renderer_x11_cm_get_type ())
G_DECLARE_FINAL_TYPE (MetaRendererX11Cm, meta_renderer_x11_cm,
META, RENDERER_X11_CM,
MetaRendererX11)
#endif /* META_RENDERER_X11_CM_H */

View File

@ -451,12 +451,6 @@ meta_backend_x11_create_idle_monitor (MetaBackend *backend,
NULL);
}
static MetaRenderer *
meta_backend_x11_create_renderer (MetaBackend *backend)
{
return g_object_new (META_TYPE_RENDERER_X11, NULL);
}
static gboolean
meta_backend_x11_grab_device (MetaBackend *backend,
int device_id,
@ -600,7 +594,6 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
backend_class->create_clutter_backend = meta_backend_x11_create_clutter_backend;
backend_class->post_init = meta_backend_x11_post_init;
backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor;
backend_class->create_renderer = meta_backend_x11_create_renderer;
backend_class->grab_device = meta_backend_x11_grab_device;
backend_class->ungrab_device = meta_backend_x11_ungrab_device;
backend_class->warp_pointer = meta_backend_x11_warp_pointer;

View File

@ -52,6 +52,10 @@
* for the reasoning */
#define DPI_FALLBACK 96.0
static float supported_scales_xrandr[] = {
1.0
};
struct _MetaMonitorManagerXrandr
{
MetaMonitorManager parent_instance;
@ -65,6 +69,9 @@ struct _MetaMonitorManagerXrandr
#ifdef HAVE_XRANDR15
GHashTable *tiled_monitor_atoms;
#endif /* HAVE_XRANDR15 */
int max_screen_width;
int max_screen_height;
};
struct _MetaMonitorManagerXrandrClass
@ -769,8 +776,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
XRRGetScreenSizeRange (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay),
&min_width,
&min_height,
&manager->max_screen_width,
&manager->max_screen_height);
&manager_xrandr->max_screen_width,
&manager_xrandr->max_screen_height);
screen = ScreenOfDisplay (manager_xrandr->xdisplay,
DefaultScreen (manager_xrandr->xdisplay));
@ -1296,23 +1303,33 @@ meta_monitor_manager_xrandr_ensure_initial_config (MetaMonitorManager *manager)
}
static gboolean
meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *manager,
MetaMonitorsConfig *config,
GError **error)
meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *manager,
MetaMonitorsConfig *config,
MetaMonitorsConfigMethod method,
GError **error)
{
GPtrArray *crtc_infos;
GPtrArray *output_infos;
if (!config)
{
meta_monitor_manager_rebuild_derived (manager);
return TRUE;
}
if (!meta_monitor_config_manager_assign (manager, config,
&crtc_infos, &output_infos,
error))
return FALSE;
apply_crtc_assignments (manager,
(MetaCrtcInfo **) crtc_infos->pdata,
crtc_infos->len,
(MetaOutputInfo **) output_infos->pdata,
output_infos->len);
if (method != META_MONITORS_CONFIG_METHOD_VERIFY)
{
apply_crtc_assignments (manager,
(MetaCrtcInfo **) crtc_infos->pdata,
crtc_infos->len,
(MetaOutputInfo **) output_infos->pdata,
output_infos->len);
}
g_ptr_array_free (crtc_infos, TRUE);
g_ptr_array_free (output_infos, TRUE);
@ -1568,6 +1585,54 @@ meta_monitor_manager_xrandr_is_transform_handled (MetaMonitorManager *manager,
return TRUE;
}
static int
meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
/* X11 does not support anything other than scale 1. */
return 1;
}
static void
meta_monitor_manager_xrandr_get_supported_scales (MetaMonitorManager *manager,
float **scales,
int *n_scales)
{
*scales = supported_scales_xrandr;
*n_scales = G_N_ELEMENTS (supported_scales_xrandr);
}
static MetaMonitorManagerCapability
meta_monitor_manager_xrandr_get_capabilities (MetaMonitorManager *manager)
{
return META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
}
static gboolean
meta_monitor_manager_xrandr_get_max_screen_size (MetaMonitorManager *manager,
int *max_width,
int *max_height)
{
MetaMonitorManagerXrandr *manager_xrandr =
META_MONITOR_MANAGER_XRANDR (manager);
*max_width = manager_xrandr->max_screen_width;
*max_height = manager_xrandr->max_screen_height;
return TRUE;
}
static MetaLogicalMonitorLayoutMode
meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager)
{
/*
* Under X11, we still use the 'logical' layout mode, but it is
* eqivalent to 'physical' as the scale is always 1.
*/
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
}
static void
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
{
@ -1644,6 +1709,11 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
manager_class->tiled_monitor_removed = meta_monitor_manager_xrandr_tiled_monitor_removed;
#endif
manager_class->is_transform_handled = meta_monitor_manager_xrandr_is_transform_handled;
manager_class->calculate_monitor_mode_scale = meta_monitor_manager_xrandr_calculate_monitor_mode_scale;
manager_class->get_supported_scales = meta_monitor_manager_xrandr_get_supported_scales;
manager_class->get_capabilities = meta_monitor_manager_xrandr_get_capabilities;
manager_class->get_max_screen_size = meta_monitor_manager_xrandr_get_max_screen_size;
manager_class->get_default_layout_mode = meta_monitor_manager_xrandr_get_default_layout_mode;
quark_meta_monitor_xrandr_data =
g_quark_from_static_string ("-meta-monitor-xrandr-data");

View File

@ -40,11 +40,6 @@
#include "meta/meta-backend.h"
#include "meta/util.h"
struct _MetaRendererX11
{
MetaRenderer parent;
};
G_DEFINE_TYPE (MetaRendererX11, meta_renderer_x11, META_TYPE_RENDERER)
static const CoglWinsysVtable *
@ -90,77 +85,6 @@ meta_renderer_x11_create_cogl_renderer (MetaRenderer *renderer)
return cogl_renderer;
}
static MetaMonitorTransform
calculate_view_transform (MetaMonitorManager *monitor_manager,
MetaLogicalMonitor *logical_monitor)
{
MetaMonitor *main_monitor;
MetaOutput *main_output;
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
main_output = meta_monitor_get_main_output (main_monitor);
/*
* Pick any monitor and output and check; all CRTCs of a logical monitor will
* always have the same transform assigned to them.
*/
if (meta_monitor_manager_is_transform_handled (monitor_manager,
main_output->crtc,
main_output->crtc->transform))
return META_MONITOR_TRANSFORM_NORMAL;
else
return main_output->crtc->transform;
}
static MetaRendererView *
meta_renderer_x11_create_view (MetaRenderer *renderer,
MetaLogicalMonitor *logical_monitor)
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
MetaMonitorTransform view_transform;
int width, height;
CoglTexture2D *texture_2d;
CoglOffscreen *fake_onscreen;
CoglOffscreen *offscreen;
GError *error = NULL;
g_assert (meta_is_wayland_compositor ());
width = logical_monitor->rect.width;
height = logical_monitor->rect.height;
view_transform = calculate_view_transform (monitor_manager, logical_monitor);
texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height);
fake_onscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d));
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (fake_onscreen), &error))
meta_fatal ("Couldn't allocate framebuffer: %s", error->message);
if (view_transform != META_MONITOR_TRANSFORM_NORMAL)
{
texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height);
offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d));
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error))
meta_fatal ("Couldn't allocate offscreen framebuffer: %s", error->message);
}
else
{
offscreen = NULL;
}
return g_object_new (META_TYPE_RENDERER_VIEW,
"layout", &logical_monitor->rect,
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
"offscreen", COGL_FRAMEBUFFER (offscreen),
"transform", view_transform,
NULL);
}
static void
meta_renderer_x11_init (MetaRendererX11 *renderer_x11)
{
@ -172,5 +96,4 @@ meta_renderer_x11_class_init (MetaRendererX11Class *klass)
MetaRendererClass *renderer_class = META_RENDERER_CLASS (klass);
renderer_class->create_cogl_renderer = meta_renderer_x11_create_cogl_renderer;
renderer_class->create_view = meta_renderer_x11_create_view;
}

View File

@ -29,9 +29,14 @@
#include "backends/meta-renderer.h"
struct _MetaRendererX11Class
{
MetaRendererClass parent_class;
};
#define META_TYPE_RENDERER_X11 (meta_renderer_x11_get_type ())
G_DECLARE_FINAL_TYPE (MetaRendererX11, meta_renderer_x11,
META, RENDERER_X11,
MetaRenderer)
G_DECLARE_DERIVABLE_TYPE (MetaRendererX11, meta_renderer_x11,
META, RENDERER_X11,
MetaRenderer)
#endif /* META_RENDERER_X11_H */

View File

@ -27,7 +27,10 @@
#include "backends/x11/meta-stage-x11-nested.h"
#include "backends/meta-backend-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor.h"
#include "backends/meta-renderer.h"
#include "backends/x11/nested/meta-renderer-x11-nested.h"
#include "clutter/clutter-mutter.h"
static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
@ -37,7 +40,6 @@ struct _MetaStageX11Nested
ClutterStageX11 parent;
CoglPipeline *pipeline;
GList *views;
};
static void
@ -54,6 +56,25 @@ typedef struct _ClutterStageX11View
ClutterStageViewCogl *view;
} MetaStageX11NestedView;
static void
meta_stage_x11_nested_resize (ClutterStageWindow *stage_window,
gint width,
gint height)
{
if (!meta_is_stage_views_enabled ())
{
MetaBackend *backend = meta_get_backend ();
MetaRenderer *renderer = meta_backend_get_renderer (backend);
MetaRendererX11Nested *renderer_x11_nested =
META_RENDERER_X11_NESTED (renderer);
meta_renderer_x11_nested_ensure_legacy_view (renderer_x11_nested,
width, height);
}
clutter_stage_window_parent_iface->resize (stage_window, width, height);
}
static gboolean
meta_stage_x11_nested_can_clip_redraws (ClutterStageWindow *stage_window)
{
@ -66,10 +87,150 @@ meta_stage_x11_nested_get_views (ClutterStageWindow *stage_window)
MetaBackend *backend = meta_get_backend ();
MetaRenderer *renderer = meta_backend_get_renderer (backend);
if (meta_is_stage_views_enabled ())
return meta_renderer_get_views (renderer);
return meta_renderer_get_views (renderer);
}
typedef struct
{
MetaStageX11Nested *stage_nested;
CoglTexture *texture;
ClutterStageView *view;
MetaLogicalMonitor *logical_monitor;
} DrawCrtcData;
static gboolean
draw_crtc (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaMonitorCrtcMode *monitor_crtc_mode,
gpointer user_data,
GError **error)
{
DrawCrtcData *data = user_data;
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (data->stage_nested);
CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen);
CoglTexture *texture = data->texture;
MetaLogicalMonitor *logical_monitor = data->logical_monitor;
MetaOutput *output = monitor_crtc_mode->output;
MetaCrtc *crtc = output->crtc;
MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view);
MetaMonitorTransform view_transform;
MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL;
cairo_rectangle_int_t view_layout;
CoglMatrix projection_matrix;
CoglMatrix transform;
float texture_width, texture_height;
float sample_x, sample_y, sample_width, sample_height;
int viewport_x, viewport_y;
int viewport_width, viewport_height;
float s_1, t_1, s_2, t_2;
texture_width = cogl_texture_get_width (texture);
texture_height = cogl_texture_get_height (texture);
clutter_stage_view_get_layout (data->view, &view_layout);
sample_x = crtc->rect.x - view_layout.x;
sample_y = crtc->rect.y - view_layout.y;
sample_width = crtc->rect.width;
sample_height = crtc->rect.height;
clutter_stage_view_get_offscreen_transformation_matrix (data->view,
&transform);
cogl_framebuffer_push_matrix (onscreen);
cogl_matrix_init_identity (&projection_matrix);
cogl_matrix_translate (&projection_matrix, -1, 1, 0);
cogl_matrix_scale (&projection_matrix, 2, -2, 0);
cogl_matrix_multiply (&projection_matrix, &projection_matrix, &transform);
cogl_framebuffer_set_projection_matrix (onscreen, &projection_matrix);
s_1 = sample_x / texture_width;
t_1 = sample_y / texture_height;
s_2 = (sample_x + sample_width) / texture_width;
t_2 = (sample_y + sample_height) / texture_height;
view_transform = meta_renderer_view_get_transform (renderer_view);
if (view_transform == logical_monitor->transform)
{
switch (view_transform)
{
case META_MONITOR_TRANSFORM_NORMAL:
case META_MONITOR_TRANSFORM_FLIPPED:
layout_transform = META_MONITOR_TRANSFORM_NORMAL;
break;
case META_MONITOR_TRANSFORM_270:
case META_MONITOR_TRANSFORM_FLIPPED_270:
layout_transform = META_MONITOR_TRANSFORM_90;
break;
case META_MONITOR_TRANSFORM_180:
case META_MONITOR_TRANSFORM_FLIPPED_180:
layout_transform = META_MONITOR_TRANSFORM_180;
break;
case META_MONITOR_TRANSFORM_90:
case META_MONITOR_TRANSFORM_FLIPPED_90:
layout_transform = META_MONITOR_TRANSFORM_270;
break;
}
}
else
return clutter_stage_window_parent_iface->get_views (stage_window);
{
layout_transform = logical_monitor->transform;
}
meta_monitor_calculate_crtc_pos (monitor, monitor_mode, output,
layout_transform,
&viewport_x,
&viewport_y);
viewport_x += logical_monitor->rect.x;
viewport_y += logical_monitor->rect.y;
if (meta_monitor_transform_is_rotated (logical_monitor->transform))
{
viewport_width = monitor_crtc_mode->crtc_mode->height;
viewport_height = monitor_crtc_mode->crtc_mode->width;
}
else
{
viewport_width = monitor_crtc_mode->crtc_mode->width;
viewport_height = monitor_crtc_mode->crtc_mode->height;
}
cogl_framebuffer_set_viewport (onscreen,
viewport_x, viewport_y,
viewport_width, viewport_height);
cogl_framebuffer_draw_textured_rectangle (onscreen,
data->stage_nested->pipeline,
0, 0, 1, 1,
s_1, t_1, s_2, t_2);
cogl_framebuffer_pop_matrix (onscreen);
return TRUE;
}
static void
draw_logical_monitor (MetaStageX11Nested *stage_nested,
MetaLogicalMonitor *logical_monitor,
CoglTexture *texture,
ClutterStageView *view,
cairo_rectangle_int_t *view_layout)
{
MetaMonitor *monitor;
MetaMonitorMode *current_mode;
cogl_pipeline_set_layer_wrap_mode (stage_nested->pipeline, 0,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
current_mode = meta_monitor_get_current_mode (monitor);
meta_monitor_mode_foreach_crtc (monitor, current_mode,
draw_crtc,
&(DrawCrtcData) {
.stage_nested = stage_nested,
.texture = texture,
.view = view,
.logical_monitor = logical_monitor
},
NULL);
}
static void
@ -83,12 +244,6 @@ meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window)
CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen);
GList *l;
/*
* If we are in legacy mode, the stage is already on the onscreen.
*/
if (!meta_is_stage_views_enabled ())
return;
if (!stage_nested->pipeline)
stage_nested->pipeline = cogl_pipeline_new (clutter_backend->cogl_context);
@ -99,29 +254,40 @@ meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window)
for (l = meta_renderer_get_views (renderer); l; l = l->next)
{
ClutterStageView *view = l->data;
MetaRendererView *renderer_view = META_RENDERER_VIEW (view);
MetaLogicalMonitor *logical_monitor;
cairo_rectangle_int_t view_layout;
CoglFramebuffer *framebuffer;
CoglTexture *texture;
CoglMatrix matrix;
clutter_stage_view_get_layout (view, &view_layout);
framebuffer = clutter_stage_view_get_onscreen (view);
texture = cogl_offscreen_get_texture (COGL_OFFSCREEN (framebuffer));
clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
cogl_matrix_get_inverse (&matrix, &matrix);
cogl_pipeline_set_layer_matrix (stage_nested->pipeline, 0, &matrix);
cogl_framebuffer_set_viewport (onscreen,
view_layout.x,
view_layout.y,
view_layout.width,
view_layout.height);
cogl_pipeline_set_layer_texture (stage_nested->pipeline, 0, texture);
cogl_framebuffer_draw_rectangle (onscreen,
stage_nested->pipeline,
-1, 1, 1, -1);
logical_monitor = meta_renderer_view_get_logical_monitor (renderer_view);
if (logical_monitor)
{
draw_logical_monitor (stage_nested, logical_monitor, texture, view, &view_layout);
}
else
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
GList *logical_monitors;
GList *k;
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (k = logical_monitors; k; k = k->next)
{
logical_monitor = k->data;
draw_logical_monitor (stage_nested, logical_monitor, texture, view, &view_layout);
}
}
}
cogl_onscreen_swap_buffers (stage_x11->onscreen);
@ -178,9 +344,9 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
{
clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface);
iface->resize = meta_stage_x11_nested_resize;
iface->can_clip_redraws = meta_stage_x11_nested_can_clip_redraws;
iface->unrealize = meta_stage_x11_nested_unrealize;
iface->get_views = meta_stage_x11_nested_get_views;
iface->finish_frame = meta_stage_x11_nested_finish_frame;
}

View File

@ -24,12 +24,19 @@
#include "backends/meta-monitor-manager-dummy.h"
#include "backends/x11/nested/meta-backend-x11-nested.h"
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
#include "backends/x11/nested/meta-renderer-x11-nested.h"
#include "wayland/meta-wayland.h"
G_DEFINE_TYPE (MetaBackendX11Nested, meta_backend_x11_nested,
META_TYPE_BACKEND_X11)
static MetaRenderer *
meta_backend_x11_nested_create_renderer (MetaBackend *backend)
{
return g_object_new (META_TYPE_RENDERER_X11_NESTED, NULL);
}
static MetaMonitorManager *
meta_backend_x11_nested_create_monitor_manager (MetaBackend *backend)
{
@ -167,6 +174,7 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
MetaBackendX11Class *backend_x11_class = META_BACKEND_X11_CLASS (klass);
backend_class->create_renderer = meta_backend_x11_nested_create_renderer;
backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager;
backend_class->create_cursor_renderer = meta_backend_x11_nested_create_cursor_renderer;
backend_class->update_screen_size = meta_backend_x11_nested_update_screen_size;

View File

@ -0,0 +1,230 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2016 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.
*
*/
#include "config.h"
#include "backends/x11/nested/meta-renderer-x11-nested.h"
#include <glib-object.h>
#include "clutter/x11/clutter-x11.h"
#include "backends/meta-backend-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-renderer.h"
#include "backends/meta-renderer-view.h"
#include "core/boxes-private.h"
#include "meta/meta-backend.h"
#include "meta/util.h"
struct _MetaRendererX11Nested
{
MetaRendererX11 parent;
};
G_DEFINE_TYPE (MetaRendererX11Nested, meta_renderer_x11_nested,
META_TYPE_RENDERER_X11)
static MetaMonitorTransform
calculate_view_transform (MetaMonitorManager *monitor_manager,
MetaLogicalMonitor *logical_monitor)
{
MetaMonitor *main_monitor;
MetaOutput *main_output;
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
main_output = meta_monitor_get_main_output (main_monitor);
/*
* Pick any monitor and output and check; all CRTCs of a logical monitor will
* always have the same transform assigned to them.
*/
if (meta_monitor_manager_is_transform_handled (monitor_manager,
main_output->crtc,
logical_monitor->transform))
return META_MONITOR_TRANSFORM_NORMAL;
else
return logical_monitor->transform;
}
static MetaRendererView *
get_legacy_view (MetaRenderer *renderer)
{
GList *views;
views = meta_renderer_get_views (renderer);
if (views)
return META_RENDERER_VIEW (views->data);
else
return NULL;
}
static CoglOffscreen *
create_offscreen (CoglContext *cogl_context,
int width,
int height)
{
CoglTexture2D *texture_2d;
CoglOffscreen *offscreen;
GError *error = NULL;
texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height);
offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d));
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error))
meta_fatal ("Couldn't allocate framebuffer: %s", error->message);
return offscreen;
}
static void
meta_renderer_x11_nested_resize_legacy_view (MetaRendererX11Nested *renderer_x11_nested,
int width,
int height)
{
MetaRenderer *renderer = META_RENDERER (renderer_x11_nested);
MetaBackend *backend = meta_get_backend ();
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
MetaRendererView *legacy_view;
cairo_rectangle_int_t view_layout;
CoglOffscreen *fake_onscreen;
legacy_view = get_legacy_view (renderer);
clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (legacy_view),
&view_layout);
if (view_layout.width == width &&
view_layout.height == height)
return;
view_layout = (cairo_rectangle_int_t) {
.width = width,
.height = height
};
fake_onscreen = create_offscreen (cogl_context, width, height);
g_object_set (G_OBJECT (legacy_view),
"layout", &view_layout,
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
NULL);
}
void
meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11_nested,
int width,
int height)
{
MetaRenderer *renderer = META_RENDERER (renderer_x11_nested);
MetaBackend *backend = meta_get_backend ();
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
cairo_rectangle_int_t view_layout;
CoglOffscreen *fake_onscreen;
MetaRendererView *legacy_view;
if (get_legacy_view (renderer))
{
meta_renderer_x11_nested_resize_legacy_view (renderer_x11_nested,
width, height);
return;
}
fake_onscreen = create_offscreen (cogl_context, width, height);
view_layout = (cairo_rectangle_int_t) {
.width = width,
.height = height
};
legacy_view = g_object_new (META_TYPE_RENDERER_VIEW,
"layout", &view_layout,
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
NULL);
meta_renderer_set_legacy_view (renderer, legacy_view);
}
static MetaRendererView *
meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
MetaLogicalMonitor *logical_monitor)
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
MetaMonitorTransform view_transform;
int view_scale;
int width, height;
CoglOffscreen *fake_onscreen;
CoglOffscreen *offscreen;
view_transform = calculate_view_transform (monitor_manager, logical_monitor);
if (meta_is_stage_views_scaled ())
view_scale = logical_monitor->scale;
else
view_scale = 1;
if (meta_monitor_transform_is_rotated (view_transform))
{
width = logical_monitor->rect.height;
height = logical_monitor->rect.width;
}
else
{
width = logical_monitor->rect.width;
height = logical_monitor->rect.height;
}
width *= view_scale;
height *= view_scale;
fake_onscreen = create_offscreen (cogl_context, width, height);
if (view_transform != META_MONITOR_TRANSFORM_NORMAL)
offscreen = create_offscreen (cogl_context, width, height);
else
offscreen = NULL;
return g_object_new (META_TYPE_RENDERER_VIEW,
"layout", &logical_monitor->rect,
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
"offscreen", COGL_FRAMEBUFFER (offscreen),
"transform", view_transform,
"scale", view_scale,
"logical-monitor", logical_monitor,
NULL);
}
static void
meta_renderer_x11_nested_init (MetaRendererX11Nested *renderer_x11_nested)
{
}
static void
meta_renderer_x11_nested_class_init (MetaRendererX11NestedClass *klass)
{
MetaRendererClass *renderer_class = META_RENDERER_CLASS (klass);
renderer_class->create_view = meta_renderer_x11_nested_create_view;
}

View File

@ -0,0 +1,37 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2016 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.
*
*/
#ifndef META_RENDERER_X11_NESTED_H
#define META_RENDERER_X11_NESTED_H
#include "backends/x11/meta-renderer-x11.h"
#define META_TYPE_RENDERER_X11_NESTED (meta_renderer_x11_nested_get_type ())
G_DECLARE_FINAL_TYPE (MetaRendererX11Nested, meta_renderer_x11_nested,
META, RENDERER_X11_NESTED,
MetaRendererX11)
void meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11_nested,
int width,
int height);
#endif /* META_RENDERER_X11_NESTED_H */

View File

@ -62,4 +62,7 @@ gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
void meta_compositor_flash_window (MetaCompositor *compositor,
MetaWindow *window);
MetaCloseDialog * meta_compositor_create_close_dialog (MetaCompositor *compositor,
MetaWindow *window);
#endif /* META_COMPOSITOR_PRIVATE_H */

View File

@ -388,7 +388,9 @@ meta_begin_modal_for_plugin (MetaCompositor *compositor,
meta_display_sync_wayland_input_focus (display);
meta_display_cancel_touch (display);
#ifdef HAVE_WAYLAND
meta_dnd_wayland_handle_begin_modal (compositor);
#endif
}
return TRUE;
@ -1412,3 +1414,11 @@ meta_compositor_show_window_menu_for_rect (MetaCompositor *compositor,
{
meta_plugin_manager_show_window_menu_for_rect (compositor->plugin_mgr, window, menu, rect);
}
MetaCloseDialog *
meta_compositor_create_close_dialog (MetaCompositor *compositor,
MetaWindow *window)
{
return meta_plugin_manager_create_close_dialog (compositor->plugin_mgr,
window);
}

View File

@ -27,6 +27,7 @@
#include <meta/workspace.h>
#include "meta-module.h"
#include "window-private.h"
#include "meta-close-dialog-default-private.h"
#include <string.h>
#include <stdlib.h>
@ -376,3 +377,16 @@ meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *plugin_mgr,
if (klass->show_window_menu_for_rect)
klass->show_window_menu_for_rect (plugin, window, menu, rect);
}
MetaCloseDialog *
meta_plugin_manager_create_close_dialog (MetaPluginManager *plugin_mgr,
MetaWindow *window)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (klass->create_close_dialog)
return klass->create_close_dialog (plugin, window);
return meta_close_dialog_default_new (window);
}

View File

@ -91,5 +91,7 @@ void meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *mgr,
MetaWindowMenuType menu,
MetaRectangle *rect);
MetaCloseDialog * meta_plugin_manager_create_close_dialog (MetaPluginManager *plugin_mgr,
MetaWindow *window);
#endif

View File

@ -220,11 +220,7 @@ meta_shadow_paint (MetaShadow *shadow,
int dest_x[4];
int dest_y[4];
int n_x, n_y;
cogl_pipeline_set_color4ub (shadow->pipeline,
opacity, opacity, opacity, opacity);
cogl_set_source (shadow->pipeline);
gboolean source_updated = FALSE;
if (shadow->scale_width)
{
@ -300,6 +296,17 @@ meta_shadow_paint (MetaShadow *shadow,
else
overlap = CAIRO_REGION_OVERLAP_IN;
if (overlap == CAIRO_REGION_OVERLAP_OUT)
continue;
if (!source_updated)
{
cogl_pipeline_set_color4ub (shadow->pipeline,
opacity, opacity, opacity, opacity);
cogl_set_source (shadow->pipeline);
source_updated = TRUE;
}
/* There's quite a bit of overhead from allocating a new
* region in order to find an exact intersection and
* generating more geometry - we make the assumption that

View File

@ -35,16 +35,9 @@
#include "wayland/meta-wayland-private.h"
#include "wayland/meta-window-wayland.h"
#include "backends/meta-backend-private.h"
#include "compositor/region-utils.h"
enum {
PAINTING,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
struct _MetaSurfaceActorWaylandPrivate
{
MetaWaylandSurface *surface;
@ -98,17 +91,20 @@ meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *self)
{
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
MetaWindow *window;
int output_scale = 1;
int geometry_scale = 1;
g_assert (surface);
window = meta_wayland_surface_get_toplevel_window (surface);
/* XXX: We do not handle x11 clients yet */
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
output_scale = meta_window_wayland_get_main_monitor_scale (window);
if (!meta_is_stage_views_scaled ())
{
/* XXX: We do not handle x11 clients yet */
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
geometry_scale = meta_window_wayland_get_geometry_scale (window);
}
return (double) output_scale / (double) surface->scale;
return (double) geometry_scale / (double) surface->scale;
}
static void
@ -118,16 +114,16 @@ logical_to_actor_position (MetaSurfaceActorWayland *self,
{
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
MetaWindow *toplevel_window;
int monitor_scale = 1;
int geometry_scale = 1;
g_assert (surface);
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
if (toplevel_window)
monitor_scale = meta_window_wayland_get_main_monitor_scale (toplevel_window);
geometry_scale = meta_window_wayland_get_geometry_scale (toplevel_window);
*x = *x * monitor_scale;
*y = *y * monitor_scale;
*x = *x * geometry_scale;
*y = *y * geometry_scale;
}
/* Convert the current actor state to the corresponding subsurface rectangle
@ -140,19 +136,19 @@ meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self,
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
CoglTexture *texture;
MetaWindow *toplevel_window;
int monitor_scale;
int geometry_scale;
float x, y;
g_assert (surface);
texture = buffer->texture;
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
monitor_scale = meta_window_wayland_get_main_monitor_scale (toplevel_window);
geometry_scale = meta_window_wayland_get_geometry_scale (toplevel_window);
clutter_actor_get_position (CLUTTER_ACTOR (self), &x, &y);
*rect = (MetaRectangle) {
.x = x / monitor_scale,
.y = y / monitor_scale,
.x = x / geometry_scale,
.y = y / geometry_scale,
.width = cogl_texture_get_width (texture) / surface->scale,
.height = cogl_texture_get_height (texture) / surface->scale,
};
@ -394,8 +390,6 @@ meta_surface_actor_wayland_paint (ClutterActor *actor)
wl_list_init (&priv->frame_callback_list);
}
g_signal_emit (actor, signals[PAINTING], 0);
CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor);
}
@ -445,13 +439,6 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
surface_actor_class->get_window = meta_surface_actor_wayland_get_window;
object_class->dispose = meta_surface_actor_wayland_dispose;
signals[PAINTING] = g_signal_new ("painting",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
}
static void

View File

@ -35,7 +35,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
enum {
REPAINT_SCHEDULED,
SIZE_CHANGED,
LAST_SIGNAL,
@ -121,13 +120,6 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
object_class->dispose = meta_surface_actor_dispose;
actor_class->pick = meta_surface_actor_pick;
signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
@ -201,8 +193,7 @@ meta_surface_actor_update_area (MetaSurfaceActor *self,
{
MetaSurfaceActorPrivate *priv = self->priv;
if (meta_shaped_texture_update_area (priv->texture, x, y, width, height))
g_signal_emit (self, signals[REPAINT_SCHEDULED], 0);
meta_shaped_texture_update_area (priv->texture, x, y, width, height);
}
gboolean

View File

@ -82,7 +82,6 @@ struct _MetaWindowActorPrivate
guint send_frame_messages_timer;
gint64 frame_drawn_time;
guint repaint_scheduled_id;
guint size_changed_id;
/*
@ -194,6 +193,18 @@ frame_data_free (FrameData *frame)
g_slice_free (FrameData, frame);
}
static gboolean
meta_window_actor_queue_redraw (ClutterActor *actor,
ClutterActor *leaf,
ClutterPaintVolume *paint_volume)
{
MetaWindowActor *self = META_WINDOW_ACTOR (actor);
MetaWindowActorPrivate *priv = self->priv;
priv->repaint_scheduled = TRUE;
return CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->queue_redraw (actor, leaf, paint_volume);
}
static void
meta_window_actor_class_init (MetaWindowActorClass *klass)
{
@ -211,6 +222,7 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
actor_class->paint = meta_window_actor_paint;
actor_class->get_paint_volume = meta_window_actor_get_paint_volume;
actor_class->queue_redraw = meta_window_actor_queue_redraw;
/**
* MetaWindowActor::first-frame:
@ -297,16 +309,6 @@ surface_size_changed (MetaSurfaceActor *actor,
meta_window_actor_update_shape (self);
}
static void
surface_repaint_scheduled (MetaSurfaceActor *actor,
gpointer user_data)
{
MetaWindowActor *self = META_WINDOW_ACTOR (user_data);
MetaWindowActorPrivate *priv = self->priv;
priv->repaint_scheduled = TRUE;
}
static gboolean
is_argb32 (MetaWindowActor *self)
{
@ -396,9 +398,7 @@ set_surface (MetaWindowActor *self,
if (priv->surface)
{
g_signal_handler_disconnect (priv->surface, priv->repaint_scheduled_id);
g_signal_handler_disconnect (priv->surface, priv->size_changed_id);
priv->repaint_scheduled_id = 0;
clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
g_object_unref (priv->surface);
}
@ -408,8 +408,6 @@ set_surface (MetaWindowActor *self,
if (priv->surface)
{
g_object_ref_sink (priv->surface);
priv->repaint_scheduled_id = g_signal_connect (priv->surface, "repaint-scheduled",
G_CALLBACK (surface_repaint_scheduled), self);
priv->size_changed_id = g_signal_connect (priv->surface, "size-changed",
G_CALLBACK (surface_size_changed), self);
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
@ -717,6 +715,7 @@ meta_window_actor_paint (ClutterActor *actor)
cairo_rectangle_int_t shape_bounds;
cairo_region_t *clip = priv->shadow_clip;
MetaWindow *window = priv->window;
gboolean partially_drawn = FALSE;
meta_window_actor_get_shape_bounds (self, &shape_bounds);
meta_window_actor_get_shadow_params (self, appears_focused, &params);
@ -734,6 +733,17 @@ meta_window_actor_paint (ClutterActor *actor)
cairo_region_subtract (clip, frame_bounds);
}
else if (clip)
{
cairo_rectangle_int_t shadow_bounds;
cairo_region_t *shadow_region;
meta_window_actor_get_shadow_bounds (self, appears_focused, &shadow_bounds);
shadow_region = cairo_region_create_rectangle (&shadow_bounds);
cairo_region_intersect (shadow_region, clip);
partially_drawn = !cairo_region_is_empty (shadow_region);
cairo_region_destroy (shadow_region);
}
meta_shadow_paint (shadow,
params.x_offset + shape_bounds.x,
@ -742,7 +752,7 @@ meta_window_actor_paint (ClutterActor *actor)
shape_bounds.height,
(clutter_actor_get_paint_opacity (actor) * params.opacity * window->opacity) / (255 * 255),
clip,
clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */
clip_shadow_under_window (self) || partially_drawn);
if (clip && clip != priv->shadow_clip)
cairo_region_destroy (clip);

View File

@ -57,7 +57,7 @@ meta_window_group_paint (ClutterActor *actor)
{
cairo_region_t *clip_region;
cairo_region_t *unobscured_region;
cairo_rectangle_int_t visible_rect, clip_rect;
cairo_rectangle_int_t visible_rect;
int paint_x_origin, paint_y_origin;
int screen_width, screen_height;
@ -109,11 +109,7 @@ meta_window_group_paint (ClutterActor *actor)
* sizes, we could intersect this with an accurate union of the
* monitors to avoid painting shadows that are visible only in the
* holes. */
clutter_stage_get_redraw_clip_bounds (CLUTTER_STAGE (stage),
&clip_rect);
clip_region = cairo_region_create_rectangle (&clip_rect);
clip_region = clutter_stage_get_redraw_clip (CLUTTER_STAGE (stage));
cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin);
meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);

View File

@ -215,4 +215,7 @@ GList* meta_rectangle_find_nonintersected_monitor_edges (
const GList *monitor_rects,
const GSList *all_struts);
gboolean meta_rectangle_is_adjecent_to (MetaRectangle *rect,
MetaRectangle *other);
#endif /* META_BOXES_PRIVATE_H */

View File

@ -2013,3 +2013,26 @@ meta_rectangle_find_nonintersected_monitor_edges (
return ret;
}
gboolean
meta_rectangle_is_adjecent_to (MetaRectangle *rect,
MetaRectangle *other)
{
int rect_x1 = rect->x;
int rect_y1 = rect->y;
int rect_x2 = rect->x + rect->width;
int rect_y2 = rect->y + rect->height;
int other_x1 = other->x;
int other_y1 = other->y;
int other_x2 = other->x + other->width;
int other_y2 = other->y + other->height;
if ((rect_x1 == other_x2 || rect_x2 == other_x1) &&
!(rect_y2 <= other_y1 || rect_y1 >= other_y2))
return TRUE;
else if ((rect_y1 == other_y2 || rect_y2 == other_y1) &&
!(rect_x2 <= other_x1 || rect_x1 >= other_x2))
return TRUE;
else
return FALSE;
}

View File

@ -25,145 +25,48 @@
#include <config.h>
#include "util-private.h"
#include "window-private.h"
#include "compositor-private.h"
#include <meta/errors.h>
#include <meta/workspace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
static void
dialog_exited (GPid pid, int status, gpointer user_data)
close_dialog_response_cb (MetaCloseDialog *dialog,
MetaCloseDialogResponse response,
MetaWindow *window)
{
MetaWindow *window = user_data;
window->dialog_pid = -1;
/* exit status of 0 means the user pressed "Force Quit" */
if (WIFEXITED (status) && WEXITSTATUS (status) == 0)
if (response == META_CLOSE_DIALOG_RESPONSE_FORCE_CLOSE)
meta_window_kill (window);
}
static void
present_existing_delete_dialog (MetaWindow *window,
guint32 timestamp)
meta_window_ensure_close_dialog (MetaWindow *window)
{
meta_topic (META_DEBUG_PING,
"Presenting existing ping dialog for %s\n",
window->desc);
MetaDisplay *display;
if (window->dialog_pid >= 0)
{
GSList *windows;
GSList *tmp;
if (window->close_dialog)
return;
/* Activate transient for window that belongs to
* mutter-dialog
*/
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
tmp = windows;
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
if (w->transient_for == window && w->res_class &&
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
{
meta_window_activate (w, timestamp);
break;
}
tmp = tmp->next;
}
g_slist_free (windows);
}
}
static void
show_delete_dialog (MetaWindow *window,
guint32 timestamp)
{
char *window_title;
gchar *window_content, *tmp;
GPid dialog_pid;
meta_topic (META_DEBUG_PING,
"Got delete ping timeout for %s\n",
window->desc);
if (window->dialog_pid >= 0)
{
present_existing_delete_dialog (window, timestamp);
return;
}
/* This is to get a better string if the title isn't representable
* in the locale encoding; actual conversion to UTF-8 is done inside
* meta_show_dialog */
if (window->title && window->title[0])
{
tmp = g_locale_from_utf8 (window->title, -1, NULL, NULL, NULL);
if (tmp == NULL)
window_title = NULL;
else
window_title = window->title;
g_free (tmp);
}
else
{
window_title = NULL;
}
if (window_title)
/* Translators: %s is a window title */
tmp = g_strdup_printf (_("“%s” is not responding."), window_title);
else
tmp = g_strdup (_("Application is not responding."));
window_content = g_strdup_printf (
"<big><b>%s</b></big>\n\n%s",
tmp,
_("You may choose to wait a short while for it to "
"continue or force the application to quit entirely."));
dialog_pid =
meta_show_dialog ("--question",
window_content, NULL,
window->screen->screen_name,
_("_Force Quit"), _("_Wait"),
"face-sad-symbolic", window->xwindow,
NULL, NULL);
g_free (window_content);
g_free (tmp);
window->dialog_pid = dialog_pid;
g_child_watch_add (dialog_pid, dialog_exited, window);
}
static void
kill_delete_dialog (MetaWindow *window)
{
if (window->dialog_pid > -1)
kill (window->dialog_pid, SIGTERM);
display = window->display;
window->close_dialog = meta_compositor_create_close_dialog (display->compositor,
window);
g_signal_connect (window->close_dialog, "response",
G_CALLBACK (close_dialog_response_cb), window);
}
void
meta_window_set_alive (MetaWindow *window,
gboolean is_alive)
{
if (is_alive)
kill_delete_dialog (window);
else
show_delete_dialog (window, CurrentTime);
if (is_alive && window->close_dialog)
{
meta_close_dialog_hide (window->close_dialog);
}
else if (!is_alive)
{
meta_window_ensure_close_dialog (window);
meta_close_dialog_show (window->close_dialog);
}
}
void
@ -207,9 +110,5 @@ meta_window_kill (MetaWindow *window)
void
meta_window_free_delete_dialog (MetaWindow *window)
{
if (window->dialog_pid >= 0)
{
kill (window->dialog_pid, 9);
window->dialog_pid = -1;
}
g_clear_object (&window->close_dialog);
}

View File

@ -963,6 +963,8 @@ meta_display_open (void)
meta_screen_init_workspaces (screen);
meta_backend_display_opened (meta_get_backend ());
enable_compositor (display);
meta_screen_create_guard_window (screen);

View File

@ -443,11 +443,13 @@ calculate_compositor_configuration (MetaCompositorType *compositor_type,
#endif /* HAVE_WAYLAND */
*compositor_type = META_COMPOSITOR_TYPE_X11;
#ifdef HAVE_WAYLAND
if (opt_nested)
{
*backend_gtype = META_TYPE_BACKEND_X11_NESTED;
return;
}
#endif /* HAVE_WAYLAND */
#ifdef HAVE_NATIVE_BACKEND
if (opt_display_server)

View File

@ -0,0 +1,33 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2016 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, see <http://www.gnu.org/licenses/>.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
#ifndef META_CLOSE_DIALOG_DEFAULT_H
#define META_CLOSE_DIALOG_DEFAULT_H
#define META_TYPE_CLOSE_DIALOG_DEFAULT (meta_close_dialog_default_get_type ())
G_DECLARE_FINAL_TYPE (MetaCloseDialogDefault,
meta_close_dialog_default,
META, CLOSE_DIALOG_DEFAULT,
GObject)
MetaCloseDialog * meta_close_dialog_default_new (MetaWindow *window);
#endif /* META_CLOSE_DIALOG_DEFAULT_H */

View File

@ -0,0 +1,279 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2001, 2002 Havoc Pennington
* Copyright (C) 2004 Elijah Newren
* Copyright (C) 2016 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, see <http://www.gnu.org/licenses/>.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
#define _XOPEN_SOURCE /* for kill() */
#include <config.h>
#include "util-private.h"
#include "window-private.h"
#include <meta/meta-close-dialog.h>
#include "meta-close-dialog-default-private.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
typedef struct _MetaCloseDialogDefaultPrivate MetaCloseDialogDefaultPrivate;
struct _MetaCloseDialogDefault
{
GObject parent_instance;
MetaWindow *window;
int dialog_pid;
guint child_watch_id;
};
enum {
PROP_0,
PROP_WINDOW,
N_PROPS
};
GParamSpec *pspecs[N_PROPS] = { NULL };
static void meta_close_dialog_iface_init (MetaCloseDialogInterface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaCloseDialogDefault, meta_close_dialog_default,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (META_TYPE_CLOSE_DIALOG,
meta_close_dialog_iface_init))
static void
dialog_exited (GPid pid,
int status,
gpointer user_data)
{
MetaCloseDialogDefault *dialog = user_data;
dialog->dialog_pid = -1;
/* exit status of 0 means the user pressed "Force Quit" */
if (WIFEXITED (status) && WEXITSTATUS (status) == 0)
g_signal_emit_by_name (dialog, "response", META_CLOSE_DIALOG_RESPONSE_FORCE_CLOSE);
}
static void
present_existing_delete_dialog (MetaCloseDialogDefault *dialog)
{
MetaWindow *window;
GSList *windows;
GSList *tmp;
window = dialog->window;
if (dialog->dialog_pid < 0)
return;
meta_topic (META_DEBUG_PING,
"Presenting existing ping dialog for %s\n",
window->desc);
/* Activate transient for window that belongs to
* mutter-dialog
*/
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
tmp = windows;
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
if (w->transient_for == window && w->res_class &&
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
{
meta_window_activate (w, CLUTTER_CURRENT_TIME);
break;
}
tmp = tmp->next;
}
g_slist_free (windows);
}
static void
meta_close_dialog_default_show (MetaCloseDialog *dialog)
{
MetaCloseDialogDefault *dialog_default = META_CLOSE_DIALOG_DEFAULT (dialog);
MetaWindow *window = dialog_default->window;
gchar *window_title, *window_content, *tmp;
GPid dialog_pid;
if (dialog_default->dialog_pid >= 0)
{
present_existing_delete_dialog (dialog_default);
return;
}
/* This is to get a better string if the title isn't representable
* in the locale encoding; actual conversion to UTF-8 is done inside
* meta_show_dialog */
if (window->title && window->title[0])
{
tmp = g_locale_from_utf8 (window->title, -1, NULL, NULL, NULL);
if (tmp == NULL)
window_title = NULL;
else
window_title = window->title;
g_free (tmp);
}
else
{
window_title = NULL;
}
if (window_title)
/* Translators: %s is a window title */
tmp = g_strdup_printf (_("“%s” is not responding."), window_title);
else
tmp = g_strdup (_("Application is not responding."));
window_content = g_strdup_printf (
"<big><b>%s</b></big>\n\n%s",
tmp,
_("You may choose to wait a short while for it to "
"continue or force the application to quit entirely."));
dialog_pid =
meta_show_dialog ("--question",
window_content, NULL,
window->screen->screen_name,
_("_Force Quit"), _("_Wait"),
"face-sad-symbolic", window->xwindow,
NULL, NULL);
g_free (window_content);
g_free (tmp);
dialog_default->dialog_pid = dialog_pid;
g_child_watch_add (dialog_pid, dialog_exited, dialog);
}
static void
meta_close_dialog_default_hide (MetaCloseDialog *dialog)
{
MetaCloseDialogDefault *dialog_default;
dialog_default = META_CLOSE_DIALOG_DEFAULT (dialog);
if (dialog_default->child_watch_id)
{
g_source_remove (dialog_default->child_watch_id);
dialog_default->child_watch_id = 0;
}
if (dialog_default->dialog_pid > -1)
kill (dialog_default->dialog_pid, SIGTERM);
}
static void
meta_close_dialog_iface_init (MetaCloseDialogInterface *iface)
{
iface->show = meta_close_dialog_default_show;
iface->hide = meta_close_dialog_default_hide;
}
static void
meta_close_dialog_default_finalize (GObject *object)
{
MetaCloseDialogDefault *dialog;
dialog = META_CLOSE_DIALOG_DEFAULT (object);
if (dialog->child_watch_id)
g_source_remove (dialog->child_watch_id);
if (dialog->dialog_pid > -1)
{
kill (dialog->dialog_pid, SIGKILL);
dialog->dialog_pid = -1;
}
G_OBJECT_CLASS (meta_close_dialog_default_parent_class)->finalize (object);
}
static void
meta_close_dialog_default_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaCloseDialogDefault *dialog;
dialog = META_CLOSE_DIALOG_DEFAULT (object);
switch (prop_id)
{
case PROP_WINDOW:
dialog->window = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
meta_close_dialog_default_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaCloseDialogDefault *dialog;
dialog = META_CLOSE_DIALOG_DEFAULT (object);
switch (prop_id)
{
case PROP_WINDOW:
g_value_set_object (value, dialog->window);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
meta_close_dialog_default_class_init (MetaCloseDialogDefaultClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_close_dialog_default_finalize;
object_class->set_property = meta_close_dialog_default_set_property;
object_class->get_property = meta_close_dialog_default_get_property;
g_object_class_override_property (object_class, PROP_WINDOW, "window");
}
static void
meta_close_dialog_default_init (MetaCloseDialogDefault *dialog)
{
dialog->dialog_pid = -1;
}
MetaCloseDialog *
meta_close_dialog_default_new (MetaWindow *window)
{
return g_object_new (META_TYPE_CLOSE_DIALOG_DEFAULT,
"window", window,
NULL);
}

View File

@ -0,0 +1,103 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2016 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, see <http://www.gnu.org/licenses/>.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
#include "config.h"
#include "window-private.h"
#include "meta/meta-close-dialog.h"
#include "meta/meta-enum-types.h"
enum {
RESPONSE,
N_SIGNALS
};
guint dialog_signals[N_SIGNALS] = { 0 };
G_DEFINE_INTERFACE (MetaCloseDialog, meta_close_dialog, G_TYPE_OBJECT)
static void
meta_close_dialog_default_init (MetaCloseDialogInterface *iface)
{
g_object_interface_install_property (iface,
g_param_spec_object ("window",
"Window",
"Window",
META_TYPE_WINDOW,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
dialog_signals[RESPONSE] =
g_signal_new ("response",
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, META_TYPE_CLOSE_DIALOG_RESPONSE);
}
/**
* meta_close_dialog_show:
* @dialog: a #MetaCloseDialog
*
* Shows the close dialog.
**/
void
meta_close_dialog_show (MetaCloseDialog *dialog)
{
MetaCloseDialogInterface *iface;
g_return_if_fail (META_IS_CLOSE_DIALOG (dialog));
iface = META_CLOSE_DIALOG_GET_IFACE (dialog);
iface->show (dialog);
}
/**
* meta_close_dialog_hide:
* @dialog: a #MetaCloseDialog
*
* Hides the close dialog.
**/
void
meta_close_dialog_hide (MetaCloseDialog *dialog)
{
MetaCloseDialogInterface *iface;
g_return_if_fail (META_IS_CLOSE_DIALOG (dialog));
iface = META_CLOSE_DIALOG_GET_IFACE (dialog);
iface->hide (dialog);
}
/**
* meta_close_dialog_response:
* @dialog: a #MetaCloseDialog
* @response: a #MetaCloseDialogResponse
*
* Responds and closes the dialog. To be called by #MetaCloseDialog
* implementations.
**/
void
meta_close_dialog_response (MetaCloseDialog *dialog,
MetaCloseDialogResponse response)
{
g_signal_emit (dialog, dialog_signals[RESPONSE], 0, response);
meta_close_dialog_hide (dialog);
}

View File

@ -1279,6 +1279,37 @@ update_num_workspaces (MetaScreen *screen,
g_object_notify (G_OBJECT (screen), "n-workspaces");
}
static int
find_highest_logical_monitor_scale (MetaBackend *backend,
MetaCursorSprite *cursor_sprite)
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaCursorRenderer *cursor_renderer =
meta_backend_get_cursor_renderer (backend);
MetaRectangle cursor_rect;
GList *logical_monitors;
GList *l;
int highest_scale = 0.0;
cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
cursor_sprite);
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
if (!meta_rectangle_overlap (&cursor_rect, &logical_monitor->rect))
continue;
highest_scale = MAX (highest_scale, logical_monitor->scale);
}
return highest_scale;
}
static void
root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
int x,
@ -1286,16 +1317,35 @@ root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
MetaScreen *screen)
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaLogicalMonitor *logical_monitor;
logical_monitor =
meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
if (meta_is_stage_views_scaled ())
{
int scale;
/* Reload the cursor texture if the scale has changed. */
if (logical_monitor)
meta_cursor_sprite_set_theme_scale (cursor_sprite, logical_monitor->scale);
scale = find_highest_logical_monitor_scale (backend, cursor_sprite);
if (scale != 0.0)
{
meta_cursor_sprite_set_theme_scale (cursor_sprite, scale);
meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0 / scale);
}
}
else
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaLogicalMonitor *logical_monitor;
logical_monitor =
meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
/* Reload the cursor texture if the scale has changed. */
if (logical_monitor)
{
meta_cursor_sprite_set_theme_scale (cursor_sprite,
logical_monitor->scale);
meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0);
}
}
}
static void
@ -2206,6 +2256,9 @@ static void
on_monitors_changed (MetaMonitorManager *manager,
MetaScreen *screen)
{
MetaBackend *backend;
MetaCursorRenderer *cursor_renderer;
meta_monitor_manager_get_screen_size (manager,
&screen->rect.width,
&screen->rect.height);
@ -2237,6 +2290,10 @@ on_monitors_changed (MetaMonitorManager *manager,
meta_screen_queue_check_fullscreen (screen);
backend = meta_get_backend ();
cursor_renderer = meta_backend_get_cursor_renderer (backend);
meta_cursor_renderer_force_update (cursor_renderer);
g_signal_emit (screen, screen_signals[MONITORS_CHANGED], 0);
}

View File

@ -470,7 +470,9 @@ meta_fatal (const char *format, ...)
gchar *str;
FILE *out;
g_return_if_fail (format != NULL);
g_warn_if_fail (format);
if (!format)
meta_exit (META_EXIT_ERROR);
va_start (args, format);
str = g_strdup_vprintf (format, args);

View File

@ -35,6 +35,7 @@
#include <config.h>
#include <meta/compositor.h>
#include <meta/window.h>
#include <meta/meta-close-dialog.h>
#include "screen-private.h"
#include <meta/util.h>
#include "stack.h"
@ -479,7 +480,7 @@ struct _MetaWindow
int stack_position; /* see comment in stack.h */
/* Managed by delete.c */
int dialog_pid;
MetaCloseDialog *close_dialog;
/* maintained by group.c */
MetaGroup *group;

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